Handle NXDOMAIN, REFUSED and log errors
- NXDOMAIN is an authoritive answer, so when receiving an NXDOMAIN, we're done. From RFC 1035: Name Error - Meaningful only for responses from an authoritative name server, this code signifies that the domain name referenced in the query does not exist. FROM RFC 8020: When an iterative caching DNS resolver receives an NXDOMAIN response, it SHOULD store it in its cache and then all names and resource record sets (RRsets) at or below that node SHOULD be considered unreachable. Subsequent queries for such names SHOULD elicit an NXDOMAIN response. - REFUSED can be a transitional status: (https://www.ietf.org/rfc/rfc1035.txt) The name server refuses to perform the specified operation for policy reasons. For example, a name server may not wish to provide the information to the particular requester, or a name server may not wish to perform a particular operation (e.g., zone) Other errors are now logged as debug-message, which can be useful for troubleshooting. Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
parent
a72bff0da3
commit
6dd3f45248
1 changed files with 25 additions and 3 deletions
|
@ -495,9 +495,24 @@ func (r *resolver) ServeDNS(w dns.ResponseWriter, query *dns.Msg) {
|
|||
logrus.Debugf("[resolver] external DNS %s:%s returned empty response for %q", proto, extDNS.IPStr, name)
|
||||
break
|
||||
}
|
||||
if resp.Rcode == dns.RcodeServerFailure {
|
||||
// for Server Failure response, continue to the next external DNS server
|
||||
logrus.Debugf("[resolver] external DNS %s:%s responded with ServFail for %q", proto, extDNS.IPStr, name)
|
||||
switch resp.Rcode {
|
||||
case dns.RcodeServerFailure, dns.RcodeRefused:
|
||||
// Server returned FAILURE: continue with the next external DNS server
|
||||
// Server returned REFUSED: this can be a transitional status, so continue with the next external DNS server
|
||||
logrus.Debugf("[resolver] external DNS %s:%s responded with %s for %q", proto, extDNS.IPStr, statusString(resp.Rcode), name)
|
||||
continue
|
||||
case dns.RcodeNameError:
|
||||
// Server returned NXDOMAIN. Stop resolution if it's an authoritative answer (see RFC 8020: https://tools.ietf.org/html/rfc8020#section-2)
|
||||
logrus.Debugf("[resolver] external DNS %s:%s responded with %s for %q", proto, extDNS.IPStr, statusString(resp.Rcode), name)
|
||||
if resp.Authoritative {
|
||||
break
|
||||
}
|
||||
continue
|
||||
case dns.RcodeSuccess:
|
||||
// All is well
|
||||
default:
|
||||
// Server gave some error. Log the error, and continue with the next external DNS server
|
||||
logrus.Debugf("[resolver] external DNS %s:%s responded with %s (code %d) for %q", proto, extDNS.IPStr, statusString(resp.Rcode), resp.Rcode, name)
|
||||
continue
|
||||
}
|
||||
answers := 0
|
||||
|
@ -532,6 +547,13 @@ func (r *resolver) ServeDNS(w dns.ResponseWriter, query *dns.Msg) {
|
|||
}
|
||||
}
|
||||
|
||||
func statusString(responseCode int) string {
|
||||
if s, ok := dns.RcodeToString[responseCode]; ok {
|
||||
return s
|
||||
}
|
||||
return "UNKNOWN"
|
||||
}
|
||||
|
||||
func (r *resolver) forwardQueryStart() bool {
|
||||
r.queryLock.Lock()
|
||||
defer r.queryLock.Unlock()
|
||||
|
|
Loading…
Add table
Reference in a new issue