diff --git a/CHANGES b/CHANGES index 52166468d9..b39242ca69 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +2456. [bug] In ACLs, ::/0 and 0.0.0.0/0 would both match any + address, regardless of family. They now correctly + distinguish IPv4 from IPv6. [RT #18559] + --- 9.6.0a1 released --- 2455. [bug] Stop metadata being transfered via axfr/ixfr. diff --git a/lib/dns/acl.c b/lib/dns/acl.c index edd35f90b7..6cfdcf0f22 100644 --- a/lib/dns/acl.c +++ b/lib/dns/acl.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: acl.c,v 1.48 2008/09/26 16:44:49 each Exp $ */ +/* $Id: acl.c,v 1.49 2008/09/26 21:12:02 each Exp $ */ /*! \file */ @@ -223,8 +223,6 @@ dns_acl_match(const isc_netaddr_t *reqaddr, /* Found a match. */ if (result == ISC_R_SUCCESS && node != NULL) { - if (node->bit == 0) - family = AF_INET; match_num = node->node_num[ISC_IS6(family)]; if (*(isc_boolean_t *) node->data[ISC_IS6(family)] == ISC_TRUE) *match = match_num; @@ -498,9 +496,8 @@ is_insecure(isc_prefix_t *prefix, void **data) { isc_boolean_t secure; int bitlen, family; - /* Bitlen 0 means "any" or "none", which is always treated as IPv4 */ bitlen = prefix->bitlen; - family = bitlen ? prefix->family : AF_INET; + family = prefix->family; /* Negated entries are always secure. */ secure = * (isc_boolean_t *)data[ISC_IS6(family)]; diff --git a/lib/dns/iptable.c b/lib/dns/iptable.c index 475357a54d..5e9c63f2a1 100644 --- a/lib/dns/iptable.c +++ b/lib/dns/iptable.c @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: iptable.c,v 1.11 2008/09/10 21:52:49 each Exp $ */ +/* $Id: iptable.c,v 1.12 2008/09/26 21:12:02 each Exp $ */ #include #include @@ -70,22 +70,36 @@ dns_iptable_addprefix(dns_iptable_t *tab, isc_netaddr_t *addr, NETADDR_TO_PREFIX_T(addr, pfx, bitlen); - /* Bitlen 0 means "any" or "none", which is always treated as IPv4 */ - family = bitlen ? pfx.family : AF_INET; - result = isc_radix_insert(tab->radix, &node, NULL, &pfx); - if (result != ISC_R_SUCCESS) { isc_refcount_destroy(&pfx.refcount); return(result); } - /* If the node already contains data, don't overwrite it */ - if (node->data[ISC_IS6(family)] == NULL) { - if (pos) - node->data[ISC_IS6(family)] = &dns_iptable_pos; - else - node->data[ISC_IS6(family)] = &dns_iptable_neg; + /* If a node already contains data, don't overwrite it */ + family = pfx.family; + if (family == AF_UNSPEC) { + /* "any" or "none" */ + INSIST(pfx.bitlen == 0); + if (pos) { + if (node->data[0] == NULL) + node->data[0] = &dns_iptable_pos; + if (node->data[1] == NULL) + node->data[1] = &dns_iptable_pos; + } else { + if (node->data[0] == NULL) + node->data[0] = &dns_iptable_neg; + if (node->data[1] == NULL) + node->data[1] = &dns_iptable_neg; + } + } else { + /* any other prefix */ + if (node->data[ISC_IS6(family)] == NULL) { + if (pos) + node->data[ISC_IS6(family)] = &dns_iptable_pos; + else + node->data[ISC_IS6(family)] = &dns_iptable_neg; + } } isc_refcount_destroy(&pfx.refcount); diff --git a/lib/isc/include/isc/radix.h b/lib/isc/include/isc/radix.h index a95c2b77fb..7a62ee59ce 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.10 2008/01/21 23:46:56 tbox Exp $ */ +/* $Id: radix.h,v 1.11 2008/09/26 21:12:02 each Exp $ */ /* * This source was adapted from MRT's RCS Ids: @@ -37,7 +37,7 @@ #define NETADDR_TO_PREFIX_T(na,pt,bits) \ do { \ memset(&(pt), 0, sizeof(pt)); \ - if((bits) && (na) != NULL) { \ + if((na) != NULL) { \ (pt).family = (na)->family; \ (pt).bitlen = (bits); \ if ((pt).family == AF_INET6) { \ @@ -46,14 +46,16 @@ } else \ memcpy(&(pt).add.sin, &(na)->type.in, \ ((bits)+7)/8); \ - } else \ - (pt).family = AF_INET; \ + } else { \ + (pt).family = AF_UNSPEC; \ + (pt).bitlen = 0; \ + } \ isc_refcount_init(&(pt).refcount, 0); \ } while(0) typedef struct isc_prefix { - unsigned int family; /* AF_INET | AF_INET6 */ - unsigned int bitlen; + unsigned int family; /* AF_INET | AF_INET6, or AF_UNSPEC for "any" */ + unsigned int bitlen; /* 0 for "any" */ isc_refcount_t refcount; union { struct in_addr sin; diff --git a/lib/isc/radix.c b/lib/isc/radix.c index 3671386398..754a9cdda4 100644 --- a/lib/isc/radix.c +++ b/lib/isc/radix.c @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: radix.c,v 1.18 2008/09/14 04:54:49 marka Exp $ */ +/* $Id: radix.c,v 1.19 2008/09/26 21:12:02 each Exp $ */ /* * This source was adapted from MRT's RCS Ids: @@ -53,7 +53,7 @@ _new_prefix(isc_mem_t *mctx, isc_prefix_t **target, int family, void *dest, REQUIRE(target != NULL); - if (family != AF_INET6 && family != AF_INET) + if (family != AF_INET6 && family != AF_INET && family != AF_UNSPEC) return (ISC_R_NOTIMPLEMENTED); prefix = isc_mem_get(mctx, sizeof(isc_prefix_t)); @@ -64,6 +64,7 @@ _new_prefix(isc_mem_t *mctx, isc_prefix_t **target, int family, void *dest, prefix->bitlen = (bitlen >= 0) ? bitlen : 128; memcpy(&prefix->add.sin6, dest, 16); } else { + /* AF_UNSPEC is "any" or "none"--treat it as AF_INET */ prefix->bitlen = (bitlen >= 0) ? bitlen : 32; memcpy(&prefix->add.sin, dest, 4); } @@ -95,7 +96,8 @@ static isc_result_t _ref_prefix(isc_mem_t *mctx, isc_prefix_t **target, isc_prefix_t *prefix) { INSIST(prefix != NULL); INSIST((prefix->family == AF_INET && prefix->bitlen <= 32) || - (prefix->family == AF_INET6 && prefix->bitlen <= 128)); + (prefix->family == AF_INET6 && prefix->bitlen <= 128) || + (prefix->family == AF_UNSPEC && prefix->bitlen == 0)); REQUIRE(target != NULL); /* @@ -238,7 +240,7 @@ isc_radix_search(isc_radix_tree_t *radix, isc_radix_node_t **target, isc_radix_node_t *stack[RADIX_MAXBITS + 1]; u_char *addr; isc_uint32_t bitlen; - int family, tfamily = -1; + int tfamily = -1; int cnt = 0; REQUIRE(radix != NULL); @@ -278,16 +280,12 @@ 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)) { - /* Bitlen 0 means "any" or "none", - which is always treated as IPv4 */ - family = node->prefix->bitlen ? - prefix->family : AF_INET; - if (node->node_num[ISC_IS6(family)] != -1 && + if (node->node_num[ISC_IS6(prefix->family)] != -1 && ((*target == NULL) || (*target)->node_num[ISC_IS6(tfamily)] > - node->node_num[ISC_IS6(family)])) { + node->node_num[ISC_IS6(prefix->family)])) { *target = node; - tfamily = family; + tfamily = prefix->family; } } } @@ -305,7 +303,7 @@ isc_radix_insert(isc_radix_tree_t *radix, isc_radix_node_t **target, { isc_radix_node_t *node, *new_node, *parent, *glue = NULL; u_char *addr, *test_addr; - isc_uint32_t bitlen, family, check_bit, differ_bit; + isc_uint32_t bitlen, fam, check_bit, differ_bit; isc_uint32_t i, j, r; isc_result_t result; @@ -319,9 +317,7 @@ isc_radix_insert(isc_radix_tree_t *radix, isc_radix_node_t **target, INSIST(prefix != NULL); bitlen = prefix->bitlen; - - /* Bitlen 0 means "any" or "none", which is always treated as IPv4 */ - family = bitlen ? prefix->family : AF_INET; + fam = prefix->family; if (radix->head == NULL) { node = isc_mem_get(radix->mctx, sizeof(isc_radix_node_t)); @@ -355,8 +351,14 @@ isc_radix_insert(isc_radix_tree_t *radix, isc_radix_node_t **target, node->data[0] = source->data[0]; node->data[1] = source->data[1]; } else { - node->node_num[ISC_IS6(family)] = - ++radix->num_added_node; + if (fam == AF_UNSPEC) { + /* "any" or "none" */ + node->node_num[0] = node->node_num[1] = + ++radix->num_added_node; + } else { + node->node_num[ISC_IS6(fam)] = + ++radix->num_added_node; + } node->data[0] = NULL; node->data[1] = NULL; } @@ -436,9 +438,22 @@ isc_radix_insert(isc_radix_tree_t *radix, isc_radix_node_t **target, node->data[1] = source->data[1]; } } else { - if (node->node_num[ISC_IS6(family)] == -1) - node->node_num[ISC_IS6(family)] = - ++radix->num_added_node; + if (fam == AF_UNSPEC) { + /* "any" or "none" */ + int next = radix->num_added_node + 1; + if (node->node_num[0] == -1) { + node->node_num[0] = next; + radix->num_added_node = next; + } + if (node->node_num[1] == -1) { + node->node_num[2] = next; + radix->num_added_node = next; + } + } else { + if (node->node_num[ISC_IS6(fam)] == -1) + node->node_num[ISC_IS6(fam)] + = ++radix->num_added_node; + } } *target = node; return (ISC_R_SUCCESS); @@ -463,8 +478,14 @@ isc_radix_insert(isc_radix_tree_t *radix, isc_radix_node_t **target, node->data[1] = source->data[1]; } } else { - node->node_num[ISC_IS6(family)] = - ++radix->num_added_node; + if (fam == AF_UNSPEC) { + /* "any" or "none" */ + node->node_num[0] = node->node_num[1] = + ++radix->num_added_node; + } else { + node->node_num[ISC_IS6(fam)] = + ++radix->num_added_node; + } } *target = node; return (ISC_R_SUCCESS); @@ -506,7 +527,14 @@ isc_radix_insert(isc_radix_tree_t *radix, isc_radix_node_t **target, new_node->data[0] = source->data[0]; new_node->data[1] = source->data[1]; } else { - new_node->node_num[ISC_IS6(family)] = ++radix->num_added_node; + if (fam == AF_UNSPEC) { + /* "any" or "none" */ + new_node->node_num[0] = new_node->node_num[1] = + ++radix->num_added_node; + } else { + new_node->node_num[ISC_IS6(fam)] = + ++radix->num_added_node; + } new_node->data[0] = NULL; new_node->data[1] = NULL; } @@ -554,7 +582,7 @@ isc_radix_insert(isc_radix_tree_t *radix, isc_radix_node_t **target, glue->node_num[0] = glue->node_num[1] = -1; radix->num_active_node++; if (differ_bit < radix->maxbits && - BIT_TEST(addr[differ_bit >> 3], 0x80 >> (differ_bit & 0x07))) { + BIT_TEST(addr[differ_bit>>3], 0x80 >> (differ_bit & 07))) { glue->r = new_node; glue->l = node; } else {