From ae718fab5366465a4c928e4d8d89717431f78547 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Thu, 10 Oct 2024 16:39:10 +1100 Subject: [PATCH] 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. (cherry picked from commit 67f31c504679dfcd9f1231037afa56da01e40d36) --- lib/ns/query.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/lib/ns/query.c b/lib/ns/query.c index 9d2214573d..fe00defd30 100644 --- a/lib/ns/query.c +++ b/lib/ns/query.c @@ -11342,24 +11342,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. */