diff --git a/internal/resolver/iterative.go b/internal/resolver/iterative.go index c2cd4d4..ebabe72 100644 --- a/internal/resolver/iterative.go +++ b/internal/resolver/iterative.go @@ -480,6 +480,7 @@ type queryState struct { gotNXDomain bool gotSERVFAIL bool gotTimeout bool + gotError bool hasRecords bool } @@ -517,7 +518,12 @@ func (r *Resolver) querySingleType( ) { msg, err := r.queryDNS(ctx, nsIP, hostname, qtype) if err != nil { - state.gotTimeout = true + var netErr net.Error + if errors.As(err, &netErr) && netErr.Timeout() { + state.gotTimeout = true + } else { + state.gotError = true + } return } @@ -563,14 +569,22 @@ func classifyResponse(resp *NameserverResponse, state queryState) { case state.gotTimeout && !state.hasRecords: resp.Status = StatusTimeout resp.Error = "all queries timed out" - case state.gotSERVFAIL && !state.hasRecords: + case (state.gotError || state.gotSERVFAIL) && !state.hasRecords: resp.Status = StatusError - resp.Error = "server returned SERVFAIL" + resp.Error = errorMessageForState(state) case !state.hasRecords && !state.gotNXDomain: resp.Status = StatusNoData } } +func errorMessageForState(state queryState) string { + if state.gotSERVFAIL { + return "server returned SERVFAIL" + } + + return "query failed due to non-timeout error" +} + // extractRecordValue formats a DNS RR value as a string. func extractRecordValue(rr dns.RR) string { switch r := rr.(type) {