]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Use a binary search to find the NSEC3 closest encloser
authorMark Andrews <marka@isc.org>
Thu, 10 Oct 2024 05:39:10 +0000 (16:39 +1100)
committerMark Andrews <marka@isc.org>
Mon, 14 Oct 2024 23:19:34 +0000 (23:19 +0000)
maxlabels is the suffix length that corresponds to the latest
NXDOMAIN response.  minlabels is the suffix length that corresponds
to longest found existing name.

lib/ns/query.c

index 7f900de9eb9e3567033b7ec8ee27051dc2c07bb9..94d0859afa8f54779efacca3ba33981e2594c421 100644 (file)
@@ -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.
                 */