aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDan Peterson <dpiddy@gmail.com>2015-11-16 11:43:22 -0400
committerMatthew Dempsky <mdempsky@google.com>2015-11-17 20:11:22 +0000
commitf4a9bd87ba84ce900dd2ba97974c48a0f4a01047 (patch)
tree3d044a61d1d845446d139c1ece9d44c623d17b83 /src
parenta29113f609302f933d6e1d3ad62af17e0f41e1dc (diff)
downloadgo-f4a9bd87ba84ce900dd2ba97974c48a0f4a01047.tar.xz
net: don't require recursion be available in DNS responses
Fixes #12778 Change-Id: I2ca53180d46180b951749abe453fd560d0f1d9d6 Reviewed-on: https://go-review.googlesource.com/16950 Reviewed-by: Matthew Dempsky <mdempsky@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
Diffstat (limited to 'src')
-rw-r--r--src/net/dnsclient.go2
-rw-r--r--src/net/dnsclient_test.go23
-rw-r--r--src/net/dnsclient_unix.go6
3 files changed, 29 insertions, 2 deletions
diff --git a/src/net/dnsclient.go b/src/net/dnsclient.go
index a2f5986603..b44c06dce4 100644
--- a/src/net/dnsclient.go
+++ b/src/net/dnsclient.go
@@ -40,7 +40,7 @@ func reverseaddr(addr string) (arpa string, err error) {
func answer(name, server string, dns *dnsMsg, qtype uint16) (cname string, addrs []dnsRR, err error) {
addrs = make([]dnsRR, 0, len(dns.answer))
- if dns.rcode == dnsRcodeNameError && dns.recursion_available {
+ if dns.rcode == dnsRcodeNameError {
return "", nil, &DNSError{Err: errNoSuchHost.Error(), Name: name, Server: server}
}
if dns.rcode != dnsRcodeSuccess {
diff --git a/src/net/dnsclient_test.go b/src/net/dnsclient_test.go
index 42b536c3f3..7308fb03fa 100644
--- a/src/net/dnsclient_test.go
+++ b/src/net/dnsclient_test.go
@@ -92,3 +92,26 @@ func TestIssue8434(t *testing.T) {
t.Fatalf("IsTemporary = false for err = %#v; want IsTemporary == true", err)
}
}
+
+// Issue 12778: verify that NXDOMAIN without RA bit errors as
+// "no such host" and not "server misbehaving"
+func TestIssue12778(t *testing.T) {
+ msg := &dnsMsg{
+ dnsMsgHdr: dnsMsgHdr{
+ rcode: dnsRcodeNameError,
+ recursion_available: false,
+ },
+ }
+
+ _, _, err := answer("golang.org", "foo:53", msg, uint16(dnsTypeSRV))
+ if err == nil {
+ t.Fatal("expected an error")
+ }
+ de, ok := err.(*DNSError)
+ if !ok {
+ t.Fatalf("err = %#v; wanted a *net.DNSError", err)
+ }
+ if de.Err != errNoSuchHost.Error() {
+ t.Fatalf("Err = %#v; wanted %q", de.Err, errNoSuchHost.Error())
+ }
+}
diff --git a/src/net/dnsclient_unix.go b/src/net/dnsclient_unix.go
index 94282ee79e..ffea828c32 100644
--- a/src/net/dnsclient_unix.go
+++ b/src/net/dnsclient_unix.go
@@ -182,7 +182,11 @@ func tryOneName(cfg *dnsConfig, name string, qtype uint16) (string, []dnsRR, err
continue
}
cname, rrs, err := answer(name, server, msg, qtype)
- if err == nil || msg.rcode == dnsRcodeSuccess || msg.rcode == dnsRcodeNameError && msg.recursion_available {
+ // If answer errored for rcodes dnsRcodeSuccess or dnsRcodeNameError,
+ // it means the response in msg was not useful and trying another
+ // server probably won't help. Return now in those cases.
+ // TODO: indicate this in a more obvious way, such as a field on DNSError?
+ if err == nil || msg.rcode == dnsRcodeSuccess || msg.rcode == dnsRcodeNameError {
return cname, rrs, err
}
lastErr = err