From: Mark Andrews Date: Sat, 27 Nov 2021 22:46:01 +0000 (+1100) Subject: Look for covering NSEC under two more conditions X-Git-Tag: v9.17.21~5^2~10 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5252985a2117a93038ddcf4c9ab09c0f3b03e883;p=thirdparty%2Fbind9.git Look for covering NSEC under two more conditions 1) when after processing a node there where no headers that contained active records. When if (check_stale_header(node, header, &locktype, lock, &search, &header_prev); succeeds or if (EXISTS(header) && !ANCIENT(header)) fails for all entries in the list leading to 'empty_node' remaining true. If there is are no active records we know nothing about the current state of the name so we treat is as ISC_R_NOTFOUND. 2) when there was a covering NOQNAME proof found or all the active headers where negative. When if (header->noqname != NULL && header->trust == dns_trust_secure) succeeds or if (!NEGATIVE(header)) never succeeds. Under these conditions there could (should be for found_noqname) be a covering NSEC earlier in the tree. --- diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c index 4b954597dd8..40f8eb9e409 100644 --- a/lib/dns/rbtdb.c +++ b/lib/dns/rbtdb.c @@ -4887,6 +4887,8 @@ cache_find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version, isc_result_t result; rbtdb_search_t search; bool cname_ok = true; + bool found_noqname = false; + bool all_negative = true; bool empty_node; nodelock_t *lock; isc_rwlocktype_t locktype; @@ -4997,6 +4999,13 @@ cache_find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version, * non-stale rdataset at this node. */ empty_node = false; + if (header->noqname != NULL && + header->trust == dns_trust_secure) { + found_noqname = true; + } + if (!NEGATIVE(header)) { + all_negative = false; + } /* * If we found a type we were looking for, remember @@ -5069,6 +5078,14 @@ cache_find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version, * meaningfully exist, and that we really have a partial match. */ NODE_UNLOCK(lock, locktype); + if ((search.options & DNS_DBFIND_COVERINGNSEC) != 0) { + result = find_coveringnsec(&search, name, nodep, now, + foundname, rdataset, + sigrdataset); + if (result == DNS_R_COVERINGNSEC) { + goto tree_exit; + } + } goto find_ns; } @@ -5109,6 +5126,22 @@ cache_find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version, goto node_exit; } + /* + * This name was from a wild card. Look for a covering NSEC. + */ + if (found == NULL && (found_noqname || all_negative) && + (search.options & DNS_DBFIND_COVERINGNSEC) != 0) + { + NODE_UNLOCK(lock, locktype); + result = find_coveringnsec(&search, name, nodep, now, + foundname, rdataset, + sigrdataset); + if (result == DNS_R_COVERINGNSEC) { + goto tree_exit; + } + goto find_ns; + } + /* * If there is an NS rdataset at this node, then this is the * deepest zone cut.