Why golang Lookup*** function can't provide a server parameter?

后端 未结 5 1267
心在旅途
心在旅途 2020-12-14 18:11

For nslookup command, it has nslookup somewhere.com some.dns.server.

However, it seems that golang dnsclient only load config from /

相关标签:
5条回答
  • 2020-12-14 18:52

    @holys

    "github.com/miekg/dns is too heavy for me"

    It's not that heavy:

    package main
    
    import (
        "log"
    
        "github.com/miekg/dns"
    )
    
    func main() {
    
        target := "microsoft.com"
        server := "8.8.8.8"
    
        c := dns.Client{}
        m := dns.Msg{}
        m.SetQuestion(target+".", dns.TypeA)
        r, t, err := c.Exchange(&m, server+":53")
        if err != nil {
            log.Fatal(err)
        }
        log.Printf("Took %v", t)
        if len(r.Answer) == 0 {
            log.Fatal("No results")
        }
        for _, ans := range r.Answer {
            Arecord := ans.(*dns.A)
            log.Printf("%s", Arecord.A)
        }
    }
    

    When run, you should see:

    $ go run dns.go
    2015/07/26 00:24:46 Took 16.138928ms
    2015/07/26 00:24:46 134.170.188.221
    2015/07/26 00:24:46 134.170.185.46
    
    0 讨论(0)
  • 2020-12-14 18:57

    The net.Lookup* functions provide access to the local resolver. While many requests will be answered with information from a DNS server, this is not always the case.

    For instance, LookupHost may return a name from the /etc/hosts file. Or it might use mDNS to resolve a .local name.

    If you want to talk to an arbitrary DNS server rather than the local resolver, then you should use a general purpose DNS client library. As suggested in the comments, https://github.com/miekg/dns might fit your needs.

    0 讨论(0)
  • 2020-12-14 18:59

    Since Go 1.9 this is possible by overriding the Dial function on a Resolver. For example, to ignore the request for the local resolver over UDP and connect to 9.9.9.9 via TCP we might do something like this:

    r := &net.Resolver{
        Dial: func(ctx context.Context, _, _ string) (net.Conn, error) {
            return net.Dial("tcp", "9.9.9.9")
        },
    }
    addrs, err := r.LookupIPAddr(context.TODO(), "example.net")
    
    0 讨论(0)
  • 2020-12-14 19:01

    @holys

    You can use this simple dns_resolver based on miekg/dns

    go get github.com/bogdanovich/dns_resolver
    
    package main
    
    import (
        "log"
        "github.com/bogdanovich/dns_resolver"
    )
    
    func main() {
        resolver := dns_resolver.New([]string{"8.8.8.8", "8.8.4.4"})
    
        // In case of i/o timeout
        resolver.RetryTimes = 5
    
        ip, err := resolver.LookupHost("google.com")
        if err != nil {
            log.Fatal(err.Error())
        }
        log.Println(ip)
        // Output [216.58.192.46]
    }
    
    0 讨论(0)
  • 2020-12-14 19:03

    Since a little while you can set the Dial for the Resolver, where you can define your nameserver in the DialContext

    var resolver *net.Resolver
    
    if nameserver != "" {
        resolver = &net.Resolver{
            PreferGo: true,
            Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
                d := net.Dialer{}
                return d.DialContext(ctx, "udp", net.JoinHostPort(nameserver, "53"))
            },
        }
    } else {
        resolver = net.DefaultResolver
    }
    

    After that you can go as you're used to:

    ips, err := resolver.LookupIPAddr(context.Background(), "www.example.com")
    
    0 讨论(0)
提交回复
热议问题