From: Ondřej Surý Date: Sat, 21 Mar 2026 16:12:15 +0000 (+0100) Subject: Remove prefix refcounting from radix tree X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=db9d9313c2373b2cc650e6aea4933a39efc6ad3f;p=thirdparty%2Fbind9.git Remove prefix refcounting from radix tree 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. --- diff --git a/lib/dns/acl.c b/lib/dns/acl.c index 9c9faa35354..72197da3620 100644 --- a/lib/dns/acl.c +++ b/lib/dns/acl.c @@ -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]; diff --git a/lib/dns/iptable.c b/lib/dns/iptable.c index 3b2884dded3..9c00664bff1 100644 --- a/lib/dns/iptable.c +++ b/lib/dns/iptable.c @@ -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; } diff --git a/lib/isc/include/isc/radix.h b/lib/isc/include/isc/radix.h index 22d05af116a..666bcbeca00 100644 --- a/lib/isc/include/isc/radix.h +++ b/lib/isc/include/isc/radix.h @@ -19,7 +19,6 @@ #include #include #include -#include #include #define NETADDR_TO_PREFIX_T(na, pt, bits) \ @@ -39,15 +38,13 @@ (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; diff --git a/lib/isc/radix.c b/lib/isc/radix.c index 659cf433d18..09cb160d0cb 100644 --- a/lib/isc/radix.c +++ b/lib/isc/radix.c @@ -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 diff --git a/tests/isc/radix_test.c b/tests/isc/radix_test.c index ca3cae0ea4d..27d39ce5490 100644 --- a/tests/isc/radix_test.c +++ b/tests/isc/radix_test.c @@ -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); }