[9.20] 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.20' into 'bind-9.20'

See merge request isc-projects/bind9!9438
This commit is contained in:
Mark Andrews 2024-08-29 22:37:35 +00:00
commit a348077718
5 changed files with 29 additions and 8 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

@ -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,
};
/*

View file

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

View file

@ -1095,7 +1095,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

@ -11216,6 +11216,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;
/*
@ -11225,10 +11226,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.