dns

DNS client and server implementations using the Go project's dnsmessage package
Log | Files | Refs | README | LICENSE

commit dc137f704dec33e5b5ab4cdb9548bb3b0d5bee3d
parent d5834ac9c24e2b94ddd01468976b08de9bb90ce8
Author: Oliver Lowe <o@olowe.co>
Date:   Sat, 18 Dec 2021 14:21:16 +1100

cmd/recursor: bail out on query loop

Pretty easy fix: just keep track of where we're up to each time we
call resolve().

Fixes: https://todo.sr.ht/~otl/dns/4

Diffstat:
Mcmd/recursor/resolve.go | 12++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/cmd/recursor/resolve.go b/cmd/recursor/resolve.go @@ -51,10 +51,10 @@ func nextServerAddrs(resources []dnsmessage.Resource) []net.IP { } func resolveFromRoot(q dnsmessage.Question) (dnsmessage.Message, error) { - return resolve(q, roots) + return resolve(q, roots, 0) } -func resolve(q dnsmessage.Question, next []net.IP) (dnsmessage.Message, error) { +func resolve(q dnsmessage.Question, next []net.IP, depth int) (dnsmessage.Message, error) { var rmsg dnsmessage.Message var err error if rrs, ok := lookup(q.Name, q.Type); ok { @@ -63,6 +63,10 @@ func resolve(q dnsmessage.Question, next []net.IP) (dnsmessage.Message, error) { } fmt.Fprintln(os.Stderr, "cache miss", q.Name, q.Type) + if depth > 12 { + return dnsmessage.Message{}, fmt.Errorf("query loop") + } + for _, ip := range next { // Aussie Broadband doesn't support IPv6 yet! if isIPv6(ip) { @@ -110,9 +114,9 @@ func resolve(q dnsmessage.Question, next []net.IP) (dnsmessage.Message, error) { continue } if len(rmsg.Answers) > 0 { - return resolve(q, nextServerAddrs(rmsg.Answers)) + return resolve(q, nextServerAddrs(rmsg.Answers), depth+1) } - return resolve(q, nextServerAddrs(rmsg.Additionals)) + return resolve(q, nextServerAddrs(rmsg.Additionals), depth+1) default: return rmsg, fmt.Errorf("unexpected authority resource type %s", a.Header.Type) }