]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Return partial match when requested
authorMark Andrews <marka@isc.org>
Mon, 4 Dec 2023 06:15:41 +0000 (17:15 +1100)
committerMark Andrews <marka@isc.org>
Thu, 29 Aug 2024 12:48:20 +0000 (12:48 +0000)
Return partial match from dns_db_find/dns_db_find when requested
to short circuit the closest encloser discover process.  Most of the
time this will be the actual closest encloser but may not be when
there yet to be committed / cleaned up versions of the zone with
names below the actual closest encloser.

bin/tests/system/dnssec/tests.sh
lib/dns/include/dns/db.h
lib/dns/qpzone.c
lib/dns/rbt-zonedb.c
lib/ns/query.c

index f2b7b766855f3f6baa1394af5011bbdb19d909b8..881548c80e69e28f8ce28afdb1980b3543c807e7 100644 (file)
@@ -386,9 +386,9 @@ status=$((status + ret))
 
 echo_i "checking negative validation NXDOMAIN NSEC3 ($n)"
 ret=0
-dig_with_opts +noauth q.nsec3.example. \
+dig_with_opts +noauth a.b.c.d.e.f.g.h.i.j.nsec3.example. \
   @10.53.0.3 a >dig.out.ns3.test$n || ret=1
-dig_with_opts +noauth q.nsec3.example. \
+dig_with_opts +noauth a.b.c.d.e.f.g.h.i.j.nsec3.example. \
   @10.53.0.4 a >dig.out.ns4.test$n || ret=1
 digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n >/dev/null || ret=1
index e38f4a3acac3c8f695d350600e2b3ebcc46f65a4..cb689c4a014c8cdb2c426f925c473455317edce8 100644 (file)
@@ -258,6 +258,7 @@ enum {
        DNS_DBFIND_FORCENSEC3 = 1 << 5,
        DNS_DBFIND_ADDITIONALOK = 1 << 6,
        DNS_DBFIND_NOZONECUT = 1 << 7,
+       DNS_DBFIND_WANTPARTIAL = 1 << 8,
 };
 
 /*
index 0e6d0eb23d10fee9a138d6901a6fb20f64c95840..5343f50562876a3e8aeca95ecc7ec0f1a0426d37 100644 (file)
@@ -3412,7 +3412,11 @@ find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version,
                                                : DNS_R_NXDOMAIN;
                        }
                } else {
-                       result = active ? DNS_R_EMPTYNAME : DNS_R_NXDOMAIN;
+                       bool wantpartial = (options & DNS_DBFIND_WANTPARTIAL) !=
+                                          0;
+                       result = active        ? DNS_R_EMPTYNAME
+                                : wantpartial ? DNS_R_PARTIALMATCH
+                                              : DNS_R_NXDOMAIN;
                }
                goto tree_exit;
        } else if (result != ISC_R_SUCCESS) {
index 16636375a2be77426a96f6563a0ee4d88994e648..7ac52225db8cfe0f84a9e27dc30b5dcd9b98524e 100644 (file)
@@ -1094,7 +1094,11 @@ zone_find(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version,
                                                : DNS_R_NXDOMAIN;
                        }
                } else {
-                       result = active ? DNS_R_EMPTYNAME : DNS_R_NXDOMAIN;
+                       bool wantpartial = (options & DNS_DBFIND_WANTPARTIAL) !=
+                                          0;
+                       result = active        ? DNS_R_EMPTYNAME
+                                : wantpartial ? DNS_R_PARTIALMATCH
+                                              : DNS_R_NXDOMAIN;
                }
                goto tree_exit;
        } else if (result != ISC_R_SUCCESS) {
index e7fce1b10176af831d00c5f3e67da3d649f488bc..0abe64764373acd2625c462aca3ce1e83f30ed6a 100644 (file)
@@ -11214,6 +11214,7 @@ again:
                 * Find the closest encloser.
                 */
                dns_name_copy(name, cname);
+               bool once = true;
                while (result == DNS_R_NXDOMAIN) {
                        labels = dns_name_countlabels(cname) - 1;
                        /*
@@ -11223,10 +11224,21 @@ again:
                                goto cleanup;
                        }
                        dns_name_split(cname, labels, NULL, cname);
-                       result = dns_db_findext(qctx->db, cname, qctx->version,
-                                               dns_rdatatype_nsec, options, 0,
-                                               NULL, fname, &cm, &ci, NULL,
-                                               NULL);
+                       result = dns_db_findext(
+                               qctx->db, cname, qctx->version,
+                               dns_rdatatype_nsec,
+                               options | (once ? DNS_DBFIND_WANTPARTIAL : 0),
+                               0, NULL, fname, &cm, &ci, NULL, NULL);
+                       if (result == DNS_R_PARTIALMATCH && once) {
+                               unsigned int flabels =
+                                       dns_name_countlabels(fname);
+                               if (labels > flabels + 1) {
+                                       dns_name_split(cname, flabels + 1, NULL,
+                                                      cname);
+                               }
+                               result = DNS_R_NXDOMAIN;
+                       }
+                       once = false;
                }
                /*
                 * Add closest (provable) encloser NSEC3.