]> Cypherpunks repositories - gostls13.git/commitdiff
net: don't require recursion be available in DNS responses
authorDan Peterson <dpiddy@gmail.com>
Mon, 16 Nov 2015 15:43:22 +0000 (11:43 -0400)
committerMatthew Dempsky <mdempsky@google.com>
Tue, 17 Nov 2015 20:11:22 +0000 (20:11 +0000)
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>

src/net/dnsclient.go
src/net/dnsclient_test.go
src/net/dnsclient_unix.go

index a2f5986603ccb9784e2de0bee8c7d01f165b92f5..b44c06dce407cbebdaaeb23a9394c00f81b5d120 100644 (file)
@@ -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 {
index 42b536c3f3a9ab78fe4852d8ccf470859729e962..7308fb03fa108e2c899bf1d630426dc71939c994 100644 (file)
@@ -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())
+       }
+}
index 94282ee79e95397bedd79340a9edcce58541e441..ffea828c32c801f41127d8fb065e3baa3e2cb716 100644 (file)
@@ -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