diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index 0c8c85ffeb..26eeeafbb9 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -391,6 +391,7 @@ struct fetchctx { bool minimized; unsigned int qmin_labels; isc_result_t qmin_warning; + bool force_qmin_warning; bool ip6arpaskip; bool forwarding; dns_fixedname_t qminfname; @@ -4180,6 +4181,16 @@ resume_qmin(void *arg) { case DNS_R_NCACHENXRRSET: case DNS_R_CNAME: case DNS_R_DNAME: + /* + * We have previously detected a possible error of an + * incorrect NXDOMAIN and now have a response that + * indicates that it was an actual error. + */ + if (fctx->qmin_warning == DNS_R_NCACHENXDOMAIN || + fctx->qmin_warning == DNS_R_NXDOMAIN) + { + fctx->force_qmin_warning = true; + } /* * Any other result will *not* cause a failure in strict * mode, or cause minimization to be disabled in relaxed @@ -5289,6 +5300,19 @@ validated(void *arg) { covers = fctx->type; } + /* + * Don't report qname minimisation NXDOMAIN errors + * when the result is NXDOMAIN except we have already + * confirmed a higher error. + */ + if (!fctx->force_qmin_warning && + message->rcode == dns_rcode_nxdomain && + (fctx->qmin_warning == DNS_R_NXDOMAIN || + fctx->qmin_warning == DNS_R_NCACHENXDOMAIN)) + { + fctx->qmin_warning = ISC_R_SUCCESS; + } + result = dns_db_findnode(fctx->cache, val->name, true, &node); if (result != ISC_R_SUCCESS) { /* fctx->lock unlocked in noanswer_response */ @@ -6430,6 +6454,18 @@ ncache_message(fetchctx_t *fctx, dns_message_t *message, goto unlock; } + /* + * Don't report qname minimisation NXDOMAIN errors + * when the result is NXDOMAIN except we have already + * confirmed a higher error. + */ + if (!fctx->force_qmin_warning && message->rcode == dns_rcode_nxdomain && + (fctx->qmin_warning == DNS_R_NXDOMAIN || + fctx->qmin_warning == DNS_R_NCACHENXDOMAIN)) + { + fctx->qmin_warning = ISC_R_SUCCESS; + } + /* * If we are asking for a SOA record set the cache time * to zero to facilitate locating the containing zone of