[9.18] fix: chg: Improve performance when looking for the closest encloser when returning NSEC3 proofs

Use the fact that the database returns the longest matching part of the requested name to find the required NSEC3 record. If there are multiple versions present in the database we may have to search further.

Closes #4460

Backport of MR !9436

Merge branch 'backport-4460-auth-nsec3-many-labels-9.18' into 'bind-9.18'

See merge request isc-projects/bind9!9439
This commit is contained in:
Mark Andrews 2024-08-29 21:38:37 +00:00
commit 7f6e092c05
4 changed files with 24 additions and 7 deletions

View 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

View file

@ -244,6 +244,7 @@ struct dns_dbonupdatelistener {
#define DNS_DBFIND_FORCENSEC3 0x0080
#define DNS_DBFIND_ADDITIONALOK 0x0100
#define DNS_DBFIND_NOZONECUT 0x0200
#define DNS_DBFIND_WANTPARTIAL 0x0400
/*
* DNS_DBFIND_STALEOK: This flag is set when BIND fails to refresh a RRset due

View file

@ -4134,7 +4134,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) {

View file

@ -11569,6 +11569,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;
/*
@ -11578,10 +11579,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.