commit 60703b621feba1f8aff3879589ef37a0b466801a from: Oliver Lowe date: Sat Dec 18 07:22:45 2021 UTC cmd/recursor: return error when no more servers to ask So we eturn SERVFAIL correctly to clients, the same way that Cloudflare, quad9 et al. do. commit - 2cf560f78905b6f035e5eb06dfeae712d2346370 commit + 60703b621feba1f8aff3879589ef37a0b466801a blob - 2cf269043af39ad5bc96455d62d39b1003a85d18 blob + 488d1259cf272dbd1ab4b106310b589b3a37e1e4 --- cmd/recursor/resolve.go +++ cmd/recursor/resolve.go @@ -37,19 +37,6 @@ func filterRRs(rrs []dnsmessage.Resource, n dnsmessage return matches } -func nextServerAddrs(resources []dnsmessage.Resource) []net.IP { - var next []net.IP - for _, r := range resources { - switch b := r.Body.(type) { - case *dnsmessage.AResource: - next = append(next, net.IP(b.A[:])) - case *dnsmessage.AAAAResource: - next = append(next, net.IP(b.AAAA[:])) - } - } - return next -} - func resolveFromRoot(q dnsmessage.Question) (dnsmessage.Message, error) { return resolve(q, roots, 0) } @@ -116,15 +103,15 @@ func resolve(q dnsmessage.Question, next []net.IP, dep continue } if len(rmsg.Answers) > 0 { - return resolve(q, nextServerAddrs(rmsg.Answers), depth+1) + return resolve(q, dns.ExtractIPs(rmsg.Answers), depth+1) } - return resolve(q, nextServerAddrs(rmsg.Additionals), depth+1) + return resolve(q, dns.ExtractIPs(rmsg.Additionals), depth+1) default: return rmsg, fmt.Errorf("unexpected authority resource type %s", a.Header.Type) } } } - // No real answer, no more servers to ask; return our best guess - return rmsg, nil + // return our best guess anyway + return rmsg, fmt.Errorf("resolve %s: no more nameservers to ask", q.Name) } blob - c94e6c8eed57383a0421ce6130875cbda6a3c033 blob + 14d4fe846cd63d5fbe3031e0e11446a2b4242c0c --- server.go +++ server.go @@ -148,3 +148,18 @@ func DefaultHandler(w ResponseWriter, msg *dnsmessage. rmsg.Header.RCode = dnsmessage.RCodeNotImplemented w.WriteMsg(rmsg) } + +// ExtractIPs extracts any IP addresses from resources. An empty slice is +// returned if there are no addresses. +func ExtractIPs(resources []dnsmessage.Resource) []net.IP { + var ips []net.IP + for _, r := range resources { + switch b := r.Body.(type) { + case *dnsmessage.AResource: + ips = append(ips, net.IP(b.A[:])) + case *dnsmessage.AAAAResource: + ips = append(ips, net.IP(b.AAAA[:])) + } + } + return ips +}