From: Colin Vidal Date: Mon, 22 Jun 2026 11:27:09 +0000 (+0200) Subject: Disambiguate `query_cname()` and `query_dname()` usage X-Git-Tag: v9.21.24~10^2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d05195e8e690a2957ec95e4886713906fd9bbc02;p=thirdparty%2Fbind9.git Disambiguate `query_cname()` and `query_dname()` usage Make explicit the fact that `query_cname()` and `query_dname()` must be called only from a context where the resolver is answering a question which is _not_ respectively `CNAME` or `DNAME`. --- diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index a094eeb430b..f27a8a63c1e 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -5480,6 +5480,23 @@ has_000_label(dns_rdataset_t *nsecset) { return false; } +/* + * After a (non-error) negative-cache add, 'rdataset' is bound to whatever + * rdataset the cache authoritatively holds for the queried name and type. + * Map that to the result code the fetch should report: + * + * - A negative cache entry (the one we just added, or a pre-existing one): + * DNS_R_NCACHENXDOMAIN or DNS_R_NCACHENXRRSET, depending on NXDOMAIN vs + * NODATA. + * + * - A positive rdataset that was already cached at higher trust, which + * caused our negative entry to be discarded (e.g. a CNAME or DNAME cached + * by a concurrent query): ISC_R_SUCCESS, because that cached positive + * answer is what gets returned. Note the specific case for CNAME and + * DNAME *if* the query type is not the same as the rdataset type. There + * is a chain to follow *only* if the query type doesn't ask for the CNAME + * or the DNAME. + */ static void fctx_setresult(fetchctx_t *fctx) { isc_result_t result = ISC_R_SUCCESS; diff --git a/lib/ns/query.c b/lib/ns/query.c index 2a68906ae9f..615f3b8e05c 100644 --- a/lib/ns/query.c +++ b/lib/ns/query.c @@ -9811,7 +9811,7 @@ cleanup: } /* - * Handle CNAME responses. + * Handle CNAME responses of a query which its type is _not_ CNAME. */ static isc_result_t query_cname(query_ctx_t *qctx) { @@ -9826,6 +9826,8 @@ query_cname(query_ctx_t *qctx) { CALL_HOOK(NS_QUERY_CNAME_BEGIN, qctx); + REQUIRE(qctx->result != DNS_R_CNAME); + result = query_zerottl_refetch(qctx); if (result != ISC_R_COMPLETE) { goto cleanup; @@ -9913,7 +9915,7 @@ cleanup: } /* - * Handle DNAME responses. + * Handle DNAME responses of a query which its type is _not_ DNAME. */ static isc_result_t query_dname(query_ctx_t *qctx) { @@ -9933,6 +9935,8 @@ query_dname(query_ctx_t *qctx) { CALL_HOOK(NS_QUERY_DNAME_BEGIN, qctx); + REQUIRE(qctx->result != DNS_R_DNAME); + /* * Compare the current qname to the found name. We need * to know how many labels and bits are in common because