From: Mark Andrews Date: Thu, 10 Oct 2024 05:39:10 +0000 (+1100) Subject: Use a binary search to find the NSEC3 closest encloser X-Git-Tag: v9.21.3~84^2~1 X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=67f31c504679dfcd9f1231037afa56da01e40d36;p=thirdparty%2Fbind9.git Use a binary search to find the NSEC3 closest encloser maxlabels is the suffix length that corresponds to the latest NXDOMAIN response. minlabels is the suffix length that corresponds to longest found existing name. --- diff --git a/lib/ns/query.c b/lib/ns/query.c index 7f900de9eb9..94d0859afa8 100644 --- a/lib/ns/query.c +++ b/lib/ns/query.c @@ -10956,24 +10956,33 @@ again: * No NSEC proof available, return NSEC3 proofs instead. */ cname = dns_fixedname_initname(&cfixed); + /* - * Find the closest encloser. + * Find the closest encloser using a binary search. + * maxlabels: suffix length of NXDOMAIN result + * minlabels: suffix length of non NXDOMAIN result */ + unsigned int maxlabels = dns_name_countlabels(name); + unsigned int minlabels = dns_name_countlabels(fname); + bool search = result == DNS_R_NXDOMAIN; dns_name_copy(name, cname); - while (result == DNS_R_NXDOMAIN) { - labels = dns_name_countlabels(cname) - 1; - /* - * Sanity check. - */ - if (labels == 0U) { - goto cleanup; + while (search) { + labels = (maxlabels + minlabels) / 2; + dns_name_split(name, labels, NULL, cname); + if (labels == minlabels) { + break; } - 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); + if (result == DNS_R_NXDOMAIN) { + maxlabels = labels; + } else { + minlabels = labels; + } } + /* * Add closest (provable) encloser NSEC3. */