From 69f3cb5abcb38f105c653c7b3df7cec33b87b292 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Wed, 19 Sep 2007 03:03:29 +0000 Subject: [PATCH] Part 3 of: 2233. [func] Add support for O(1) ACL processing, based on radix tree code originally written by kevin brintnall. [RT #16288] --- lib/dns/acl.c | 28 +++++++++++++++++++++++----- lib/isc/include/isc/radix.h | 9 +++++---- lib/isc/radix.c | 20 ++++++++++---------- 3 files changed, 38 insertions(+), 19 deletions(-) diff --git a/lib/dns/acl.c b/lib/dns/acl.c index 9e446f5177..6bb169c795 100644 --- a/lib/dns/acl.c +++ b/lib/dns/acl.c @@ -15,13 +15,14 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: acl.c,v 1.34 2007/09/14 01:46:05 marka Exp $ */ +/* $Id: acl.c,v 1.35 2007/09/19 03:03:29 marka Exp $ */ /*! \file */ #include #include +#include #include #include @@ -430,16 +431,26 @@ dns_acl_detach(dns_acl_t **aclp) { *aclp = NULL; } -static isc_boolean_t insecure_prefix_found; + +static isc_once_t insecure_prefix_once = ISC_ONCE_INIT; +static isc_mutex_t insecure_prefix_lock; +static isc_boolean_t insecure_prefix_found; + +static void +initialize_action(void) { + RUNTIME_CHECK(isc_mutex_init(&insecure_prefix_lock) == ISC_R_SUCCESS); +} /* * Called via isc_radix_walk() to find IP table nodes that are * insecure. */ static void -is_insecure(isc_prefix_t *prefix, isc_boolean_t *data) { +is_insecure(isc_prefix_t *prefix, void *data) { + isc_boolean_t secure = * (isc_boolean_t *)data; + /* Negated entries are always secure */ - if(* (isc_boolean_t *)data == ISC_FALSE) { + if (!secure) { return; } @@ -475,14 +486,21 @@ is_insecure(isc_prefix_t *prefix, isc_boolean_t *data) { isc_boolean_t dns_acl_isinsecure(const dns_acl_t *a) { unsigned int i; + isc_boolean_t insecure; + + RUNTIME_CHECK(isc_once_do(&insecure_prefix_once, + initialize_action) == ISC_R_SUCCESS); /* * Walk radix tree to find out if there are any non-negated, * non-loopback prefixes. */ + LOCK(&insecure_prefix_lock); insecure_prefix_found = ISC_FALSE; isc_radix_process(a->iptable->radix, is_insecure); - if(insecure_prefix_found) + insecure = insecure_prefix_found; + UNLOCK(&insecure_prefix_lock); + if (insecure) return(ISC_TRUE); /* Now check non-radix elements */ diff --git a/lib/isc/include/isc/radix.h b/lib/isc/include/isc/radix.h index 2f2be5436e..8cc072c7b0 100644 --- a/lib/isc/include/isc/radix.h +++ b/lib/isc/include/isc/radix.h @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: radix.h,v 1.3 2007/09/12 23:46:47 tbox Exp $ */ +/* $Id: radix.h,v 1.4 2007/09/19 03:03:29 marka Exp $ */ /* * This source was adapted from MRT's RCS Ids: @@ -56,7 +56,8 @@ typedef struct isc_prefix { } add; } isc_prefix_t; -typedef void (*void_fn_t)(); +typedef void (*isc_radix_destroyfunc_t)(void *); +typedef void (*isc_radix_processfunc_t)(isc_prefix_t *, void *); #define isc_prefix_tochar(prefix) ((char *)&(prefix)->add.sin) #define isc_prefix_touchar(prefix) ((u_char *)&(prefix)->add.sin) @@ -108,10 +109,10 @@ isc_result_t isc_radix_create(isc_mem_t *mctx, isc_radix_tree_t **target, int maxbits); void -isc_destroy_radix(isc_radix_tree_t *radix, void_fn_t func); +isc_destroy_radix(isc_radix_tree_t *radix, isc_radix_destroyfunc_t func); void -isc_radix_process(isc_radix_tree_t *radix, void_fn_t func); +isc_radix_process(isc_radix_tree_t *radix, isc_radix_processfunc_t func); #define RADIX_MAXBITS 128 diff --git a/lib/isc/radix.c b/lib/isc/radix.c index 20d992b3c7..a5f2166197 100644 --- a/lib/isc/radix.c +++ b/lib/isc/radix.c @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: radix.c,v 1.4 2007/09/14 01:46:05 marka Exp $ */ +/* $Id: radix.c,v 1.5 2007/09/19 03:03:29 marka Exp $ */ /* * This source was adapted from MRT's RCS Ids: @@ -41,7 +41,7 @@ static int _comp_with_mask(void *addr, void *dest, u_int mask); static void -_clear_radix(isc_radix_tree_t *radix, void_fn_t func); +_clear_radix(isc_radix_tree_t *radix, isc_radix_destroyfunc_t func); static isc_result_t _new_prefix(isc_mem_t *mctx, isc_prefix_t **target, int family, void *dest, @@ -153,11 +153,11 @@ isc_radix_create(isc_mem_t *mctx, isc_radix_tree_t **target, int maxbits) { */ static void -_clear_radix(isc_radix_tree_t *radix, void_fn_t func) { +_clear_radix(isc_radix_tree_t *radix, isc_radix_destroyfunc_t func) { - REQUIRE(radix); + REQUIRE(radix != NULL); - if (radix->head) { + if (radix->head != NULL) { isc_radix_node_t *Xstack[RADIX_MAXBITS+1]; isc_radix_node_t **Xsp = Xstack; @@ -167,9 +167,9 @@ _clear_radix(isc_radix_tree_t *radix, void_fn_t func) { isc_radix_node_t *l = Xrn->l; isc_radix_node_t *r = Xrn->r; - if (Xrn->prefix) { + if (Xrn->prefix != NULL) { _deref_prefix(radix->mctx, Xrn->prefix); - if (Xrn->data && func) + if (Xrn->data != NULL && func != NULL) func(Xrn->data); } else { INSIST(Xrn->data == NULL); @@ -197,7 +197,7 @@ _clear_radix(isc_radix_tree_t *radix, void_fn_t func) { void -isc_destroy_radix(isc_radix_tree_t *radix, void_fn_t func) +isc_destroy_radix(isc_radix_tree_t *radix, isc_radix_destroyfunc_t func) { REQUIRE(radix != NULL); _clear_radix(radix, func); @@ -209,11 +209,11 @@ isc_destroy_radix(isc_radix_tree_t *radix, void_fn_t func) * func will be called as func(node->prefix, node->data) */ void -isc_radix_process(isc_radix_tree_t *radix, void_fn_t func) +isc_radix_process(isc_radix_tree_t *radix, isc_radix_processfunc_t func) { isc_radix_node_t *node; - REQUIRE(func); + REQUIRE(func != NULL); RADIX_WALK(radix->head, node) { func(node->prefix, node->data);