diff options
author | Dan Peterson <dpiddy@gmail.com> | 2015-11-19 15:24:42 -0400 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2015-12-17 15:17:06 +0000 |
commit | 5c0629b503ff9044906a785f360354a5e45cf9ce (patch) | |
tree | 703f9640ab46cb879bddd951e253555af602e596 /src/net/dnsclient_unix.go | |
parent | be7544be237b279e45be73963e84ab59916b8ac2 (diff) | |
download | go-5c0629b503ff9044906a785f360354a5e45cf9ce.tar.gz go-5c0629b503ff9044906a785f360354a5e45cf9ce.zip |
net: prefer error for original name on lookups
With certain names and search domain configurations the
returned error would be one encountered while querying a
generated name instead of the original name. This caused
confusion when a manual check of the same name produced
different results.
Now prefer errors encountered for the original name.
Also makes the low-level DNS connection plumbing swappable
in tests enabling tighter control over responses without
relying on the network.
Fixes #12712
Updates #13295
Change-Id: I780d628a762006bb11899caf20b5f97b462a717f
Reviewed-on: https://go-review.googlesource.com/16953
Reviewed-by: Russ Cox <rsc@golang.org>
Diffstat (limited to 'src/net/dnsclient_unix.go')
-rw-r--r-- | src/net/dnsclient_unix.go | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/src/net/dnsclient_unix.go b/src/net/dnsclient_unix.go index 319011f5f6..15a4081835 100644 --- a/src/net/dnsclient_unix.go +++ b/src/net/dnsclient_unix.go @@ -24,9 +24,16 @@ import ( "time" ) +// A dnsDialer provides dialing suitable for DNS queries. +type dnsDialer interface { + dialDNS(string, string) (dnsConn, error) +} + // A dnsConn represents a DNS transport endpoint. type dnsConn interface { - Conn + io.Closer + + SetDeadline(time.Time) error // readDNSResponse reads a DNS response message from the DNS // transport endpoint and returns the received DNS response @@ -121,7 +128,7 @@ func (d *Dialer) dialDNS(network, server string) (dnsConn, error) { // exchange sends a query on the connection and hopes for a response. func exchange(server, name string, qtype uint16, timeout time.Duration) (*dnsMsg, error) { - d := Dialer{Timeout: timeout} + d := testHookDNSDialer(timeout) out := dnsMsg{ dnsMsgHdr: dnsMsgHdr{ recursion_desired: true, @@ -440,7 +447,8 @@ func goLookupIPOrder(name string, order hostLookupOrder) (addrs []IPAddr, err er conf := resolvConf.dnsConfig resolvConf.mu.RUnlock() type racer struct { - rrs []dnsRR + fqdn string + rrs []dnsRR error } lane := make(chan racer, 1) @@ -450,13 +458,16 @@ func goLookupIPOrder(name string, order hostLookupOrder) (addrs []IPAddr, err er for _, qtype := range qtypes { go func(qtype uint16) { _, rrs, err := tryOneName(conf, fqdn, qtype) - lane <- racer{rrs, err} + lane <- racer{fqdn, rrs, err} }(qtype) } for range qtypes { racer := <-lane if racer.error != nil { - lastErr = racer.error + // Prefer error for original name. + if lastErr == nil || racer.fqdn == name+"." { + lastErr = racer.error + } continue } addrs = append(addrs, addrRecordList(racer.rrs)...) |