Commit f4a9bd87 authored by Dan Peterson's avatar Dan Peterson Committed by Matthew Dempsky

net: don't require recursion be available in DNS responses

Fixes #12778

Change-Id: I2ca53180d46180b951749abe453fd560d0f1d9d6
Reviewed-on: https://go-review.googlesource.com/16950Reviewed-by: 's avatarMatthew Dempsky <mdempsky@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent a29113f6
......@@ -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 {
......
......@@ -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())
}
}
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment