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_test.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_test.go')
-rw-r--r-- | src/net/dnsclient_unix_test.go | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/src/net/dnsclient_unix_test.go b/src/net/dnsclient_unix_test.go index 66ca4cf8ab..95c14df52e 100644 --- a/src/net/dnsclient_unix_test.go +++ b/src/net/dnsclient_unix_test.go @@ -424,6 +424,57 @@ func TestGoLookupIPOrderFallbackToFile(t *testing.T) { defer conf.teardown() } +// Issue 12712. +// When using search domains, return the error encountered +// querying the original name instead of an error encountered +// querying a generated name. +func TestErrorForOriginalNameWhenSearching(t *testing.T) { + const fqdn = "doesnotexist.domain" + + origTestHookDNSDialer := testHookDNSDialer + defer func() { testHookDNSDialer = origTestHookDNSDialer }() + + conf, err := newResolvConfTest() + if err != nil { + t.Fatal(err) + } + defer conf.teardown() + + if err := conf.writeAndUpdate([]string{"search servfail"}); err != nil { + t.Fatal(err) + } + + d := &fakeDNSConn{} + testHookDNSDialer = func(time.Duration) dnsDialer { return d } + + d.rh = func(q *dnsMsg) (*dnsMsg, error) { + r := &dnsMsg{ + dnsMsgHdr: dnsMsgHdr{ + id: q.id, + }, + } + + switch q.question[0].Name { + case fqdn + ".servfail.": + r.rcode = dnsRcodeServerFailure + default: + r.rcode = dnsRcodeNameError + } + + return r, nil + } + + _, err = goLookupIP(fqdn) + if err == nil { + t.Fatal("expected an error") + } + + want := &DNSError{Name: fqdn, Err: errNoSuchHost.Error()} + if err, ok := err.(*DNSError); !ok || err.Name != want.Name || err.Err != want.Err { + t.Errorf("got %v; want %v", err, want) + } +} + func BenchmarkGoLookupIP(b *testing.B) { testHookUninstaller.Do(uninstallTestHooks) @@ -461,3 +512,31 @@ func BenchmarkGoLookupIPWithBrokenNameServer(b *testing.B) { goLookupIP("www.example.com") } } + +type fakeDNSConn struct { + // last query + q *dnsMsg + // reply handler + rh func(*dnsMsg) (*dnsMsg, error) +} + +func (f *fakeDNSConn) dialDNS(n, s string) (dnsConn, error) { + return f, nil +} + +func (f *fakeDNSConn) Close() error { + return nil +} + +func (f *fakeDNSConn) SetDeadline(time.Time) error { + return nil +} + +func (f *fakeDNSConn) writeDNSQuery(q *dnsMsg) error { + f.q = q + return nil +} + +func (f *fakeDNSConn) readDNSResponse() (*dnsMsg, error) { + return f.rh(f.q) +} |