From: Mark Andrews Date: Mon, 4 Dec 2023 06:15:41 +0000 (+1100) Subject: Return partial match when requested X-Git-Tag: v9.21.1~7^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d42ea08f16bc6fc4b401f6b6f45a387cfb7f5d73;p=thirdparty%2Fbind9.git Return partial match when requested 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. --- diff --git a/bin/tests/system/dnssec/tests.sh b/bin/tests/system/dnssec/tests.sh index f2b7b766855..881548c80e6 100644 --- a/bin/tests/system/dnssec/tests.sh +++ b/bin/tests/system/dnssec/tests.sh @@ -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 diff --git a/lib/dns/include/dns/db.h b/lib/dns/include/dns/db.h index e38f4a3acac..cb689c4a014 100644 --- a/lib/dns/include/dns/db.h +++ b/lib/dns/include/dns/db.h @@ -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, }; /* diff --git a/lib/dns/qpzone.c b/lib/dns/qpzone.c index 0e6d0eb23d1..5343f505628 100644 --- a/lib/dns/qpzone.c +++ b/lib/dns/qpzone.c @@ -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) { diff --git a/lib/dns/rbt-zonedb.c b/lib/dns/rbt-zonedb.c index 16636375a2b..7ac52225db8 100644 --- a/lib/dns/rbt-zonedb.c +++ b/lib/dns/rbt-zonedb.c @@ -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) { diff --git a/lib/ns/query.c b/lib/ns/query.c index e7fce1b1017..0abe6476437 100644 --- a/lib/ns/query.c +++ b/lib/ns/query.c @@ -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.