]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Part 2 of:
authorMark Andrews <marka@isc.org>
Fri, 14 Sep 2007 01:46:06 +0000 (01:46 +0000)
committerMark Andrews <marka@isc.org>
Fri, 14 Sep 2007 01:46:06 +0000 (01:46 +0000)
2233.   [func]          Add support for O(1) ACL processing, based on
                        radix tree code originally written by kevin
                        brintnall. [RT #16288]

bin/named/sortlist.c
bin/tests/system/sortlist/tests.sh
lib/dns/acl.c
lib/dns/include/dns/iptable.h
lib/dns/iptable.c
lib/isc/radix.c
lib/isccfg/aclconf.c
lib/isccfg/include/isccfg/cfg.h
lib/isccfg/parser.c

index 8004b175f34b603882c049f461114bfc0630b9ca..daefa0772e9313ad23521d20db7608fad5e12978 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: sortlist.c,v 1.16 2007/09/12 01:09:07 each Exp $ */
+/* $Id: sortlist.c,v 1.17 2007/09/14 01:46:05 marka Exp $ */
 
 /*! \file */
 
@@ -53,13 +53,17 @@ ns_sortlist_setup(dns_acl_t *acl, isc_netaddr_t *clientaddr,
                if (e->type == dns_aclelementtype_nestedacl) {
                        dns_acl_t *inner = e->nestedacl;
 
-                       if (inner->length < 1 || inner->length > 2)
+                       if (inner->length == 0)
+                               try_elt = e;
+                       else if (inner->length > 2)
                                goto dont_sort;
-                       if (inner->elements[0].negative)
+                       else if (inner->elements[0].negative)
                                goto dont_sort;
-                       try_elt = &inner->elements[0];
-                       if (inner->length == 2)
-                               order_elt = &inner->elements[1];
+                       else {
+                               try_elt = &inner->elements[0];
+                               if (inner->length == 2)
+                                       order_elt = &inner->elements[1];
+                       }
                } else {
                        /*
                         * BIND 8 allows bare elements at the top level
index 87fdfb190d6efa64c4b2af5bd880a400e39d2a6d..06f175a05cf04aaea85fa2401f85c980f4197464 100644 (file)
@@ -15,7 +15,7 @@
 # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 # PERFORMANCE OF THIS SOFTWARE.
 
-# $Id: tests.sh,v 1.8 2007/06/19 23:47:05 tbox Exp $
+# $Id: tests.sh,v 1.9 2007/09/14 01:46:05 marka Exp $
 
 SYSTEMTESTTOP=..
 . $SYSTEMTESTTOP/conf.sh
@@ -39,16 +39,22 @@ $DIG +tcp +noadd +nosea +nostat +noquest +noauth +nocomm +nocmd a.example. \
 diff test1.dig test1.good || status=1
 
 echo "I:test 1-element sortlist statement and undocumented BIND 8 features"
-for n in 2 3 4 5
-do
        cat <<EOF >test2.good
 b.example.             300     IN      A       10.53.0.$n
 EOF
-       $DIG +tcp +noadd +nosea +nostat +noquest +noauth +nocomm +nocmd \
-               b.example. \
-               @10.53.0.1 -b 10.53.0.$n -p 5300 | sed 1q >test2.dig
-       diff test2.dig test2.good || status=1
-done           
+
+$DIG +tcp +noadd +nosea +nostat +noquest +noauth +nocomm +nocmd \
+       b.example. @10.53.0.1 -b 10.53.0.2 -p 5300 | sed 1q | \
+        egrep '10.53.0.(2|3)$' > test2.out &&
+$DIG +tcp +noadd +nosea +nostat +noquest +noauth +nocomm +nocmd \
+       b.example. @10.53.0.1 -b 10.53.0.3 -p 5300 | sed 1q | \
+        egrep '10.53.0.(2|3)$' >> test2.out &&
+$DIG +tcp +noadd +nosea +nostat +noquest +noauth +nocomm +nocmd \
+       b.example. @10.53.0.1 -b 10.53.0.4 -p 5300 | sed 1q | \
+        egrep '10.53.0.4$' >> test2.out &&
+$DIG +tcp +noadd +nosea +nostat +noquest +noauth +nocomm +nocmd \
+       b.example. @10.53.0.1 -b 10.53.0.5 -p 5300 | sed 1q | \
+        egrep '10.53.0.5$' >> test2.out || status=1
 
 echo "I:exit status: $status"
 exit $status
index f43ccba0beb77df981f5bb04dbfcbb3e703f80c7..9e446f51776a605b75a7cdde63dcd000cab3ee47 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: acl.c,v 1.33 2007/09/12 01:09:08 each Exp $ */
+/* $Id: acl.c,v 1.34 2007/09/14 01:46:05 marka Exp $ */
 
 /*! \file */
 
@@ -249,6 +249,7 @@ dns_acl_match(const isc_netaddr_t *reqaddr,
 isc_result_t
 dns_acl_merge(dns_acl_t *dest, dns_acl_t *source, isc_boolean_t pos)
 {
+       isc_result_t result;
         unsigned int newalloc, nelem, i;
         int max_node = 0, nodes;
 
@@ -299,7 +300,9 @@ dns_acl_merge(dns_acl_t *dest, dns_acl_t *source, isc_boolean_t pos)
          * node_count value is set correctly afterward.
          */
         nodes = max_node + dest->node_count;
-        dns_iptable_merge(dest->iptable, source->iptable, pos);
+        result = dns_iptable_merge(dest->iptable, source->iptable, pos);
+        if (result != ISC_R_SUCCESS)
+                return (result);
         if (nodes > dest->node_count)
                 dest->node_count = nodes;
 
@@ -400,6 +403,8 @@ destroy(dns_acl_t *dacl) {
                dns_aclelement_t *de = &dacl->elements[i];
                if (de->type == dns_aclelementtype_keyname) {
                        dns_name_free(&de->keyname, dacl->mctx);
+               } else if (de->type == dns_aclelementtype_nestedacl) {
+                       dns_acl_detach(&de->nestedacl);
                }
        }
        if (dacl->elements != NULL)
index 30feee8441bfc85434a01cc52343eea591c75244..d7eb140dc057a25f6c4c23a28388ceb9196fc58f 100644 (file)
@@ -14,7 +14,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: iptable.h,v 1.3 2007/09/12 23:46:47 tbox Exp $ */
+/* $Id: iptable.h,v 1.4 2007/09/14 01:46:05 marka Exp $ */
 
 #ifndef DNS_IPTABLE_H
 #define DNS_IPTABLE_H 1
@@ -53,7 +53,7 @@ dns_iptable_addprefix(dns_iptable_t *tab, isc_netaddr_t *addr,
  * Add an IP prefix to an existing IP table
  */
 
-void
+isc_result_t
 dns_iptable_merge(dns_iptable_t *tab, dns_iptable_t *source, isc_boolean_t pos);
 /*
  * Merge one IP table into another one.
index 5ea749782ea896b62ce6dd319c6c7bc25451f621..c2b9e19af91c2df81349c714c80162a5b697cf0c 100644 (file)
@@ -14,7 +14,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: iptable.c,v 1.3 2007/09/12 23:46:47 tbox Exp $ */
+/* $Id: iptable.c,v 1.4 2007/09/14 01:46:05 marka Exp $ */
 
 #include <isc/mem.h>
 #include <isc/radix.h>
@@ -67,7 +67,6 @@ dns_iptable_addprefix(dns_iptable_t *tab, isc_netaddr_t *addr,
        INSIST(DNS_IPTABLE_VALID(tab));
        INSIST(tab->radix);
 
-
        NETADDR_TO_PREFIX_T(addr, pfx, bitlen);
 
        result = isc_radix_insert(tab->radix, &node, NULL, &pfx);
@@ -89,14 +88,18 @@ dns_iptable_addprefix(dns_iptable_t *tab, isc_netaddr_t *addr,
 /*
  * Merge one IP table into another one.
  */
-void
+isc_result_t
 dns_iptable_merge(dns_iptable_t *tab, dns_iptable_t *source, isc_boolean_t pos)
 {
+       isc_result_t result;
        isc_radix_node_t *node, *new_node;
         int max_node = 0;
 
        RADIX_WALK (source->radix->head, node) {
-               isc_radix_insert (tab->radix, &new_node, node, NULL);
+               result = isc_radix_insert (tab->radix, &new_node, node, NULL);
+
+               if (result != ISC_R_SUCCESS)
+                       return(result);
 
                 /*
                  * If we're negating a nested ACL, then we should
@@ -105,7 +108,6 @@ dns_iptable_merge(dns_iptable_t *tab, dns_iptable_t *source, isc_boolean_t pos)
                  * becoming a positive match in the parent, which
                  * could be a security risk.  To prevent this, we
                  * just leave the negative nodes negative.
-                 * (XXX: does this still need to be documented?)
                  */
                 if (!pos &&
                     node->data &&
@@ -119,6 +121,7 @@ dns_iptable_merge(dns_iptable_t *tab, dns_iptable_t *source, isc_boolean_t pos)
        } RADIX_WALK_END;
 
         tab->radix->num_added_node += max_node;
+        return (ISC_R_SUCCESS);
 }
 
 void
index eb318cd9148bd77c583bd23a36db488d8245c6b2..20d992b3c7b42e745a489a310441a2fbf73ae643 100644 (file)
@@ -14,7 +14,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: radix.c,v 1.3 2007/09/12 23:46:47 tbox Exp $ */
+/* $Id: radix.c,v 1.4 2007/09/14 01:46:05 marka Exp $ */
 
 /*
  * This source was adapted from MRT's RCS Ids:
@@ -49,6 +49,8 @@ _new_prefix(isc_mem_t *mctx, isc_prefix_t **target, int family, void *dest,
 {
        isc_prefix_t *prefix;
 
+       REQUIRE(target != NULL);
+
        if (family != AF_INET6 && family != AF_INET)
                return (ISC_R_NOTIMPLEMENTED);
 
@@ -74,7 +76,6 @@ _new_prefix(isc_mem_t *mctx, isc_prefix_t **target, int family, void *dest,
 
 static void 
 _deref_prefix(isc_mem_t *mctx, isc_prefix_t *prefix) {
-       size_t size;
        int refs;
 
        if (prefix == NULL)
@@ -84,32 +85,29 @@ _deref_prefix(isc_mem_t *mctx, isc_prefix_t *prefix) {
 
        if (refs <= 0) {
                isc_refcount_destroy(&prefix->refcount);
-
-               if (prefix->family == AF_INET6)
-                       size = sizeof(isc_prefix_t);
-               else
-                       size = sizeof(isc_prefix_t);
-
-               isc_mem_put(mctx, prefix, size);
+               isc_mem_put(mctx, prefix, sizeof(isc_prefix_t));
        }
 }
 
 static isc_result_t
 _ref_prefix(isc_mem_t *mctx, isc_prefix_t **target, isc_prefix_t *prefix) {
-
-        INSIST((prefix->family == AF_INET && prefix->bitlen <= 32) ||
-               (prefix->family == AF_INET6 && prefix->bitlen <= 128));
-
-       if (prefix != NULL) {   
-               if (isc_refcount_current(&prefix->refcount) == 0) {
-                       /* Make a copy in case of a static prefix. */
-                       return (_new_prefix(mctx, target, prefix->family,
-                                           &prefix->add, prefix->bitlen));
-               }
-
-               isc_refcount_increment(&prefix->refcount, NULL);
+       INSIST(prefix != NULL);
+       INSIST((prefix->family == AF_INET && prefix->bitlen <= 32) ||
+              (prefix->family == AF_INET6 && prefix->bitlen <= 128));
+       REQUIRE(target != NULL);
+
+       /* If this prefix is a static allocation, copy it into new memory */
+       if (isc_refcount_current(&prefix->refcount) == 0) {
+               isc_result_t ret;
+               ret = _new_prefix(mctx, target, prefix->family,
+                                 &prefix->add, prefix->bitlen);
+               if (ret == ISC_R_SUCCESS)
+                       isc_refcount_destroy(&prefix->refcount);
+               return ret;
        }
 
+       isc_refcount_increment(&prefix->refcount, NULL);
+
        *target = prefix;
        return (ISC_R_SUCCESS);
 }
@@ -132,6 +130,8 @@ isc_result_t
 isc_radix_create(isc_mem_t *mctx, isc_radix_tree_t **target, int maxbits) {
        isc_radix_tree_t *radix;
 
+       REQUIRE(target != NULL);
+
        radix = isc_mem_get(mctx, sizeof(isc_radix_tree_t));
        if (radix == NULL)
                return (ISC_R_NOMEMORY);
@@ -143,7 +143,6 @@ isc_radix_create(isc_mem_t *mctx, isc_radix_tree_t **target, int maxbits) {
        radix->num_added_node = 0;
        RUNTIME_CHECK(maxbits <= RADIX_MAXBITS); /* XXX */
        radix->magic = RADIX_TREE_MAGIC;
-
        *target = radix;
        return (ISC_R_SUCCESS);
 }
@@ -200,6 +199,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)
 {
+       REQUIRE(radix != NULL);
        _clear_radix(radix, func);
        isc_mem_put(radix->mctx, radix, sizeof(*radix));
 }
@@ -266,9 +266,9 @@ isc_radix_search(isc_radix_tree_t *radix, isc_radix_node_t **target,
                if (_comp_with_mask(isc_prefix_tochar(node->prefix), 
                                    isc_prefix_tochar(prefix),
                                    node->prefix->bitlen)) {
-                       if ((*target == NULL) ||
-                           (*target)->node_num > node->node_num) 
-                               *target = node;
+                       if ((*target == NULL) ||
+                           (*target)->node_num > node->node_num) 
+                               *target = node;
                }
        }
 
@@ -293,8 +293,8 @@ isc_radix_insert(isc_radix_tree_t *radix, isc_radix_node_t **target,
        REQUIRE(prefix || (source && source->prefix));
        RUNTIME_CHECK(prefix->bitlen <= radix->maxbits);
 
-        if (!prefix && source && source->prefix)
-                prefix = source->prefix;
+       if (!prefix && source && source->prefix)
+               prefix = source->prefix;
 
        if (radix->head == NULL) {
                node = isc_mem_get(radix->mctx, sizeof(isc_radix_node_t));
@@ -406,24 +406,24 @@ isc_radix_insert(isc_radix_tree_t *radix, isc_radix_node_t **target,
        new_node->l = new_node->r = NULL;
        radix->num_active_node++;
 
-        if (source) {
-                /*
-                 * If source is non-NULL, then we're merging in a node
-                 * from an existing radix tree.  Node_num values have to
-                 * remain consistent; they can't just be added in whatever
-                 * order came from walking the tree.  So we don't increment
-                 * num_added_node here; instead, we add it to the node-num
-                 * values for each node from the nested tree, and then when
-                 * the whole tree is done, the calling function will bump
-                 * num_added_node by the highest value of node_num in the
-                 * tree.
-                 */
-                new_node->node_num = radix->num_added_node + source->node_num;
-                new_node->data = source->data;
-        } else {
-                new_node->node_num = ++radix->num_added_node;
-               new_node->data = NULL;
-        }
+       if (source) {
+               /*
+                * If source is non-NULL, then we're merging in a node
+                * from an existing radix tree.  Node_num values have to
+                * remain consistent; they can't just be added in whatever
+                * order came from walking the tree.  So we don't increment
+                * num_added_node here; instead, we add it to the node-num
+                * values for each node from the nested tree, and then when
+                * the whole tree is done, the calling function will bump
+                * num_added_node by the highest value of node_num in the
+                * tree.
+                */
+               new_node->node_num = radix->num_added_node + source->node_num;
+               new_node->data = source->data;
+       } else {
+               new_node->node_num = ++radix->num_added_node;
+               new_node->data = NULL;
+       }
 
        if (node->bit == differ_bit) {
                INSIST(glue == NULL);
index c5e451f6a96819c4b843c60a09d8cd1baf47f994..616ec1a8102453c8673fb056f102cfd117403a8b 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: aclconf.c,v 1.10 2007/09/12 01:09:08 each Exp $ */
+/* $Id: aclconf.c,v 1.11 2007/09/14 01:46:05 marka Exp $ */
 
 #include <config.h>
 
@@ -40,7 +40,7 @@ cfg_aclconfctx_init(cfg_aclconfctx_t *ctx) {
 
 void
 cfg_aclconfctx_destroy(cfg_aclconfctx_t *ctx) {
-       dns_acl_t *dacl, *next;
+       dns_acl_t *dacl, *next;
 
        for (dacl = ISC_LIST_HEAD(ctx->named_acl_cache);
             dacl != NULL;
@@ -82,7 +82,7 @@ static isc_result_t
 convert_named_acl(const cfg_obj_t *nameobj, const cfg_obj_t *cctx,
                  isc_log_t *lctx, cfg_aclconfctx_t *ctx,
                  isc_mem_t *mctx, int nest_level,
-                  dns_acl_t **target)
+                 dns_acl_t **target)
 {
        isc_result_t result;
        const cfg_obj_t *cacl = NULL;
@@ -121,7 +121,7 @@ convert_named_acl(const cfg_obj_t *nameobj, const cfg_obj_t *cctx,
        loop.magic = LOOP_MAGIC;
        ISC_LIST_APPEND(ctx->named_acl_cache, &loop, nextincache);
        result = cfg_acl_fromconfig(cacl, cctx, lctx, ctx, mctx,
-                                    nest_level, &dacl);
+                                   nest_level, &dacl);
        ISC_LIST_UNLINK(ctx->named_acl_cache, &loop, nextincache);
        loop.magic = 0;
        loop.name = NULL;
@@ -163,50 +163,40 @@ convert_keyname(const cfg_obj_t *keyobj, isc_log_t *lctx, isc_mem_t *mctx,
 isc_result_t
 cfg_acl_fromconfig(const cfg_obj_t *caml,
                   const cfg_obj_t *cctx,
-                  isc_log_t *lctx,
+                  isc_log_t *lctx,
                   cfg_aclconfctx_t *ctx,
                   isc_mem_t *mctx,
-                   int nest_level,
+                  int nest_level,
                   dns_acl_t **target)
 {
        isc_result_t result;
        dns_acl_t *dacl = NULL, *inneracl = NULL;
        dns_aclelement_t *de;
        const cfg_listelt_t *elt;
-        dns_iptable_t *iptab;
+       dns_iptable_t *iptab;
 
        REQUIRE(target != NULL);
-        REQUIRE(*target == NULL || ISC_MAGIC_VALID(target, DNS_ACL_MAGIC));
+       REQUIRE(*target == NULL || DNS_ACL_VALID(*target));
 
-        if (*target != NULL) {
-                /*
-                 * If target already points to an ACL, then we're being
-                 * called recursively to configure a nested ACL.  The
-                 * nested ACL's contents should just be absorbed into its
-                 * parent ACL.
-                 */
-                dacl = *target;
-        } else {
-                /*
-                 * Need to allocate a new ACL structure.  Count the items
-                 * in the ACL definition and allocate space for that many
-                 * elements (even though some or all of them may end up in
-                 * the iptable instead of the element array).
-                 */
-                unsigned int element_count = 0;
-                for (elt = cfg_list_first(caml);
-                     elt != NULL;
-                     elt = cfg_list_next(elt)) {
-                        const cfg_obj_t *ce = cfg_listelt_value(elt);
-                        if (cfg_obj_istuple(ce))
-                                ce = cfg_tuple_get(ce, "value");
-                        if (cfg_obj_isnetprefix(ce))
-                                element_count++;
-                }
-               result = dns_acl_create(mctx, element_count, &dacl);
-               if (result != ISC_R_SUCCESS)
-                       return (result);
-        }
+       if (*target != NULL) {
+               /*
+                * If target already points to an ACL, then we're being
+                * called recursively to configure a nested ACL.  The
+                * nested ACL's contents should just be absorbed into its
+                * parent ACL.
+                */
+               dacl = *target;
+       } else {
+               /*
+                * Need to allocate a new ACL structure.  Count the items
+                * in the ACL definition and allocate space for that many
+                * elements (even though some or all of them may end up in
+                * the iptable instead of the element array).
+                */
+               result = dns_acl_create(mctx, cfg_list_length(caml), &dacl);
+               if (result != ISC_R_SUCCESS)
+                       return (result);
+       }
 
        de = dacl->elements;
        for (elt = cfg_list_first(caml);
@@ -223,105 +213,115 @@ cfg_acl_fromconfig(const cfg_obj_t *caml,
                } else
                        neg = ISC_FALSE;
 
-                /*
-                 * If nest_level is nonzero, then every element is
-                 * to be stored as a separate, nested ACL rather than
-                 * merged into the main iptable.
-                 */
-                iptab = dacl->iptable;
-               if (nest_level) {
-                        result = dns_acl_create(mctx, 0, &de->nestedacl);
-                        if (result != ISC_R_SUCCESS)
-                               goto cleanup;
-                        iptab = de->nestedacl->iptable;
-                }
+               /*
+                * If nest_level is nonzero, then every element is
+                * to be stored as a separate, nested ACL rather than
+                * merged into the main iptable.
+                */
+               iptab = dacl->iptable;
+               if (nest_level > 0) {
+                       result = dns_acl_create(mctx, cfg_list_length(ce),
+                                               &de->nestedacl);
+                       if (result != ISC_R_SUCCESS)
+                               goto cleanup;
+                       iptab = de->nestedacl->iptable;
+               }
 
                if (cfg_obj_isnetprefix(ce)) {
                        /* Network prefix */
-                       isc_netaddr_t   addr;
-                       unsigned int    bitlen;
+                       isc_netaddr_t   addr;
+                       unsigned int    bitlen;
 
-                        cfg_obj_asnetprefix(ce, &addr, &bitlen);
-                       result = dns_iptable_addprefix(iptab, &addr, bitlen,
-                                                       ISC_TF(!neg));
+                       cfg_obj_asnetprefix(ce, &addr, &bitlen);
+                       result = dns_iptable_addprefix(iptab, &addr, bitlen,
+                                                      ISC_TF(!neg));
                        if (result != ISC_R_SUCCESS)
                                goto cleanup;
-                        continue;
+
+                       if (nest_level > 0) {
+                               /* This prefix is going into a nested acl */
+                               de->type = dns_aclelementtype_nestedacl;
+                               de->negative = neg;
+                       } else
+                               continue;
                } else if (cfg_obj_islist(ce)) {
-                        /*
-                         * If we're nesting ACLs, put the nested
-                         * ACL onto the elements list; otherwise
-                         * merge it into *this* ACL.
-                         */
-                        if (nest_level == 0) {
-                               result = cfg_acl_fromconfig(ce,
-                                                 cctx, lctx, ctx, mctx, 0,
-                                                 &dacl);
-                        } else {
+                       /*
+                        * If we're nesting ACLs, put the nested
+                        * ACL onto the elements list; otherwise
+                        * merge it into *this* ACL.
+                        */
+                       if (nest_level == 0) {
+                               result = cfg_acl_fromconfig(ce,
+                                                cctx, lctx, ctx, mctx, 0,
+                                                &dacl);
+                               if (result != ISC_R_SUCCESS)
+                                       goto cleanup;
+                               continue;
+                       } else {
                                de->type = dns_aclelementtype_nestedacl;
-                               de->negative = neg;
-                               result = cfg_acl_fromconfig(ce,
-                                                 cctx, lctx, ctx, mctx,
-                                                 nest_level - 1,
-                                                 &de->nestedacl);
-                        }
+                               de->negative = neg;
+                               result = cfg_acl_fromconfig(ce,
+                                                cctx, lctx, ctx, mctx,
+                                                nest_level - 1,
+                                                &de->nestedacl);
+                               if (result != ISC_R_SUCCESS)
+                                       goto cleanup;
+                               /* Fall through */
+                       }
+               } else if (cfg_obj_istype(ce, &cfg_type_keyref)) {
+                       /* Key name */
+                       de->type = dns_aclelementtype_keyname;
+                       de->negative = neg;
+                       dns_name_init(&de->keyname, NULL);
+                       result = convert_keyname(ce, lctx, mctx,
+                                                &de->keyname);
                        if (result != ISC_R_SUCCESS)
-                               goto cleanup;
-                        continue;
+                               goto cleanup;
                } else if (cfg_obj_isstring(ce)) {
                        /* ACL name */
                        const char *name = cfg_obj_asstring(ce);
-                        if (strcasecmp(name, "any") == 0) {
-                                /* iptable entry with zero bit length */
-                                dns_iptable_addprefix(iptab, NULL, 0,
-                                                      ISC_TRUE);
-                                continue;
+                       if (strcasecmp(name, "any") == 0) {
+                               /* iptable entry with zero bit length */
+                               dns_iptable_addprefix(iptab, NULL, 0,
+                                                     ISC_TRUE);
+                               continue;
                        } else if (strcasecmp(name, "none") == 0) {
-                                /* negated "any" */
-                                dns_iptable_addprefix(iptab, NULL, 0,
-                                                      ISC_FALSE);
-                                continue;
+                               /* negated "any" */
+                               dns_iptable_addprefix(iptab, NULL, 0,
+                                                     ISC_FALSE);
+                               continue;
                        } else if (strcasecmp(name, "localhost") == 0) {
                                de->type = dns_aclelementtype_localhost;
-                               de->negative = neg;
+                               de->negative = neg;
                        } else if (strcasecmp(name, "localnets") == 0) {
                                de->type = dns_aclelementtype_localnets;
-                               de->negative = neg;
+                               de->negative = neg;
                        } else {
                                result = get_acl_def(cctx, name, NULL);
                                if (result == ISC_R_SUCCESS) {
                                        /* found it in acl definitions */
-                                        inneracl = NULL;
+                                       inneracl = NULL;
                                        result = convert_named_acl(ce, cctx,
                                                        lctx, ctx, mctx,
-                                                        nest_level
-                                                          ?  (nest_level - 1)
-                                                          : 0,
-                                                        &inneracl);
+                                                       (nest_level > 0)
+                                                         ?  (nest_level - 1)
+                                                         : 0,
+                                                       &inneracl);
                                }
                                if (result != ISC_R_SUCCESS)
                                        goto cleanup;
 
-                                if (nest_level) {
-                                        de->type = dns_aclelementtype_nestedacl,
-                                        de->negative = neg;
-                                        de->nestedacl = inneracl;
-                                } else {
-                                        dns_acl_merge(dacl, inneracl,
-                                                      ISC_TF(!neg));
-                                        dns_acl_detach(&inneracl);
-                                }
-                                continue;
+                               if (nest_level) {
+                                       de->type = dns_aclelementtype_nestedacl,
+                                       de->negative = neg;
+                                       de->nestedacl = inneracl;
+                               } else {
+                                       dns_acl_merge(dacl, inneracl,
+                                                     ISC_TF(!neg));
+                                       dns_acl_detach(&inneracl);
+                               }
+                               continue;
                        }
-               } else if (cfg_obj_istype(ce, &cfg_type_keyref)) {
-                       /* Key name */
-                       de->type = dns_aclelementtype_keyname;
-                       de->negative = neg;
-                       dns_name_init(&de->keyname, NULL);
-                       result = convert_keyname(ce, lctx, mctx,
-                                                &de->keyname);
-                       if (result != ISC_R_SUCCESS)
-                               goto cleanup;
                } else {
                        cfg_obj_log(ce, lctx, ISC_LOG_WARNING,
                                    "address match list contains "
@@ -330,17 +330,20 @@ cfg_acl_fromconfig(const cfg_obj_t *caml,
                        goto cleanup;
                }
 
-                /*
-                 * XXX each: This should only be reached for localhost,
-                 * localnets and keyname elements -- probably should
-                 * be refactored for clearer flow
-                 */
-                if (nest_level && de->type != dns_aclelementtype_nestedacl)
-                        dns_acl_detach(&de->nestedacl);
+               /*
+                * This should only be reached for localhost, localnets
+                * and keyname elements, and nested ACLs if nest_level is
+                * nonzero (i.e., in sortlists). 
+                */
+               if (nest_level > 0 && de->type != dns_aclelementtype_nestedacl)
+                       dns_acl_detach(&de->nestedacl);
+
+               dacl->node_count++;
+               de->node_num = dacl->node_count;
 
-                de->node_num = dacl->node_count++;
                de++;
                dacl->length++;
+               INSIST(dacl->length <= dacl->alloc);
        }
 
        *target = dacl;
index eb9924738bd912280503096361d9fff85666ffaa..79133931cf79ed679948f41f162ef5ddb5be0803 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: cfg.h,v 1.42 2007/06/19 23:47:22 tbox Exp $ */
+/* $Id: cfg.h,v 1.43 2007/09/14 01:46:06 marka Exp $ */
 
 #ifndef ISCCFG_CFG_H
 #define ISCCFG_CFG_H 1
@@ -347,6 +347,13 @@ cfg_list_next(const cfg_listelt_t *elt);
  *     or NULL if there are no more elements.
  */
 
+unsigned int
+cfg_list_length(const cfg_obj_t *obj);
+/*%<
+ * Returns the length of a list of configure objects.  If obj is
+ * not a list, returns 0.
+ */
+
 const cfg_obj_t *
 cfg_listelt_value(const cfg_listelt_t *elt);
 /*%<
index 6a7d1f25851d1505ccd55e6d2ec7a28e2a8056a9..a22307eecd19e569ce32301af0cd9e130cb4a863 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: parser.c,v 1.125 2007/06/19 23:47:22 tbox Exp $ */
+/* $Id: parser.c,v 1.126 2007/09/14 01:46:05 marka Exp $ */
 
 /*! \file */
 
@@ -1109,6 +1109,25 @@ cfg_list_next(const cfg_listelt_t *elt) {
        return (ISC_LIST_NEXT(elt, link));
 }
 
+/*
+ * Return the length of a list object.  If obj is NULL or is not
+ * a list, return 0.
+ */
+unsigned int
+cfg_list_length(const cfg_obj_t *obj) {
+       const cfg_listelt_t *elt;
+       unsigned int count = 0;
+
+       if (obj == NULL || ! cfg_obj_islist(obj))
+               return (0U);
+       for (elt = cfg_list_first(obj);
+            elt != NULL;
+            elt = cfg_list_next(elt)) {
+               count++;
+       }
+       return (count);
+}
+
 const cfg_obj_t *
 cfg_listelt_value(const cfg_listelt_t *elt) {
        REQUIRE(elt != NULL);