From 5252985a2117a93038ddcf4c9ab09c0f3b03e883 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Sun, 28 Nov 2021 09:46:01 +1100 Subject: [PATCH] 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. --- lib/dns/rbtdb.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c index 4b954597dd..40f8eb9e40 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.