]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Remove prefix refcounting from radix tree
authorOndřej Surý <ondrej@sury.org>
Sat, 21 Mar 2026 16:12:15 +0000 (17:12 +0100)
committerOndřej Surý <ondrej@sury.org>
Wed, 1 Jul 2026 04:05:52 +0000 (06:05 +0200)
Radix tree prefixes were reference-counted to allow sharing between
nodes, with refcount==0 used as a sentinel for stack-allocated
prefixes. Since the radix tree is only modified during config
parsing (single-threaded) and read-only during query processing,
the sharing optimization is unnecessary. Always copy prefixes
instead, eliminating the refcount field and the sentinel hack.

lib/dns/acl.c
lib/dns/iptable.c
lib/isc/include/isc/radix.h
lib/isc/radix.c
tests/isc/radix_test.c

index 9c9faa35354006828be0eadf0e25ad79526f2fe8..72197da36206d884f736e0828326b952323d94b6 100644 (file)
@@ -191,8 +191,6 @@ dns_acl_match(const isc_netaddr_t *reqaddr, const dns_name_t *reqsigner,
                }
        }
 
-       isc_refcount_destroy(&pfx.refcount);
-
        /* Now search non-radix elements for a match with a lower node_num. */
        for (i = 0; i < acl->length; i++) {
                dns_aclelement_t *e = &acl->elements[i];
index 3b2884dded358bdcc5b87d454dc854a5da444ee8..9c00664bff1f0d51523fa74da121624613a33499 100644 (file)
@@ -58,7 +58,6 @@ dns_iptable_addprefix(dns_iptable_t *tab, const isc_netaddr_t *addr,
 
        result = isc_radix_insert(tab->radix, &node, NULL, &pfx);
        if (result != ISC_R_SUCCESS) {
-               isc_refcount_destroy(&pfx.refcount);
                return result;
        }
 
@@ -81,7 +80,6 @@ dns_iptable_addprefix(dns_iptable_t *tab, const isc_netaddr_t *addr,
                }
        }
 
-       isc_refcount_destroy(&pfx.refcount);
        return ISC_R_SUCCESS;
 }
 
index 22d05af116a2a1b3ab36bd99d0166bbbc8eec3b9..666bcbeca00f78ee1b3b17a7e489bd6bc1ec38e8 100644 (file)
@@ -19,7 +19,6 @@
 #include <isc/magic.h>
 #include <isc/mutex.h>
 #include <isc/net.h>
-#include <isc/refcount.h>
 #include <isc/types.h>
 
 #define NETADDR_TO_PREFIX_T(na, pt, bits)                                \
                        (pt).family = AF_UNSPEC;                         \
                        (pt).bitlen = 0;                                 \
                }                                                        \
-               isc_refcount_init(&(pt).refcount, 0);                    \
        } while (0)
 
 typedef struct isc_prefix {
        isc_mem_t   *mctx;
        unsigned int family;   /* AF_INET | AF_INET6, or AF_UNSPEC for
                                * "any" */
-       unsigned int   bitlen; /* 0 for "any" */
-       isc_refcount_t refcount;
+       unsigned int bitlen;   /* 0 for "any" */
        union {
                struct in_addr  sin;
                struct in6_addr sin6;
index 659cf433d18f4d6204aae85e36168cc389f674cf..09cb160d0cb490422e4f31b25c52e8146e998c3a 100644 (file)
@@ -68,8 +68,6 @@ _new_prefix(isc_mem_t *mctx, isc_prefix_t **target, int family, void *dest,
        prefix->mctx = NULL;
        isc_mem_attach(mctx, &prefix->mctx);
 
-       isc_refcount_init(&prefix->refcount, 1);
-
        *target = prefix;
        return ISC_R_SUCCESS;
 }
@@ -77,11 +75,8 @@ _new_prefix(isc_mem_t *mctx, isc_prefix_t **target, int family, void *dest,
 static void
 _deref_prefix(isc_prefix_t *prefix) {
        if (prefix != NULL) {
-               if (isc_refcount_decrement(&prefix->refcount) == 1) {
-                       isc_refcount_destroy(&prefix->refcount);
-                       isc_mem_putanddetach(&prefix->mctx, prefix,
-                                            sizeof(isc_prefix_t));
-               }
+               isc_mem_putanddetach(&prefix->mctx, prefix,
+                                    sizeof(isc_prefix_t));
        }
 }
 
@@ -93,22 +88,8 @@ _ref_prefix(isc_mem_t *mctx, isc_prefix_t **target, isc_prefix_t *prefix) {
               (prefix->family == AF_UNSPEC && prefix->bitlen == 0));
        REQUIRE(target != NULL && *target == NULL);
 
-       /*
-        * If this prefix is a static allocation, copy it into new memory.
-        * (Note, the refcount still has to be destroyed by the calling
-        * routine.)
-        */
-       if (isc_refcount_current(&prefix->refcount) == 0) {
-               isc_result_t ret;
-               ret = _new_prefix(mctx, target, prefix->family, &prefix->add,
-                                 prefix->bitlen);
-               return ret;
-       }
-
-       isc_refcount_increment(&prefix->refcount);
-
-       *target = prefix;
-       return ISC_R_SUCCESS;
+       return _new_prefix(mctx, target, prefix->family, &prefix->add,
+                          prefix->bitlen);
 }
 
 static int
index ca3cae0ea4d606b2778d54569fac74de8364e56e..27d39ce54900d9490dfc8e6d42a077e3ab82a987 100644 (file)
@@ -52,7 +52,6 @@ ISC_RUN_TEST_IMPL(isc_radix_remove) {
        result = isc_radix_insert(radix, &node, NULL, &prefix);
        assert_int_equal(result, ISC_R_SUCCESS);
        node->data[0] = (void *)32;
-       isc_refcount_destroy(&prefix.refcount);
 
        in_addr.s_addr = inet_addr("1.0.0.0");
        isc_netaddr_fromin(&netaddr, &in_addr);
@@ -62,7 +61,6 @@ ISC_RUN_TEST_IMPL(isc_radix_remove) {
        result = isc_radix_insert(radix, &node, NULL, &prefix);
        assert_int_equal(result, ISC_R_SUCCESS);
        node->data[0] = (void *)8;
-       isc_refcount_destroy(&prefix.refcount);
 
        in_addr.s_addr = inet_addr("1.1.1.0");
        isc_netaddr_fromin(&netaddr, &in_addr);
@@ -72,7 +70,6 @@ ISC_RUN_TEST_IMPL(isc_radix_remove) {
        result = isc_radix_insert(radix, &node, NULL, &prefix);
        assert_int_equal(result, ISC_R_SUCCESS);
        node->data[0] = (void *)24;
-       isc_refcount_destroy(&prefix.refcount);
 
        isc_radix_remove(radix, node);
 
@@ -100,7 +97,6 @@ ISC_RUN_TEST_IMPL(isc_radix_search) {
        result = isc_radix_insert(radix, &node, NULL, &prefix);
        assert_int_equal(result, ISC_R_SUCCESS);
        node->data[0] = (void *)1;
-       isc_refcount_destroy(&prefix.refcount);
 
        in_addr.s_addr = inet_addr("3.3.0.0");
        isc_netaddr_fromin(&netaddr, &in_addr);
@@ -110,7 +106,6 @@ ISC_RUN_TEST_IMPL(isc_radix_search) {
        result = isc_radix_insert(radix, &node, NULL, &prefix);
        assert_int_equal(result, ISC_R_SUCCESS);
        node->data[0] = (void *)2;
-       isc_refcount_destroy(&prefix.refcount);
 
        in_addr.s_addr = inet_addr("3.3.3.3");
        isc_netaddr_fromin(&netaddr, &in_addr);
@@ -121,8 +116,6 @@ ISC_RUN_TEST_IMPL(isc_radix_search) {
        assert_int_equal(result, ISC_R_SUCCESS);
        assert_ptr_equal(node->data[0], (void *)2);
 
-       isc_refcount_destroy(&prefix.refcount);
-
        isc_radix_destroy(radix, NULL);
 }