]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Look for covering NSEC under two more conditions
authorMark Andrews <marka@isc.org>
Sat, 27 Nov 2021 22:46:01 +0000 (09:46 +1100)
committerPetr Špaček <pspacek@isc.org>
Thu, 2 Dec 2021 13:24:37 +0000 (14:24 +0100)
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

index 4b954597dd81fac44032079428deba060425d97b..40f8eb9e40934bbb4ee43aca264a905a18939372 100644 (file)
@@ -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.