Part 3 of:

2233.   [func]          Add support for O(1) ACL processing, based on
                        radix tree code originally written by kevin
                        brintnall. [RT #16288]
This commit is contained in:
Mark Andrews 2007-09-19 03:03:29 +00:00
parent dc271ec7b2
commit 69f3cb5abc
3 changed files with 38 additions and 19 deletions

View file

@ -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 <config.h>
#include <isc/mem.h>
#include <isc/once.h>
#include <isc/string.h>
#include <isc/util.h>
@ -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 */

View file

@ -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

View file

@ -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);