refactored code.

git-svn-id: file:///svn/unbound/trunk@1225 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2008-09-04 14:29:05 +00:00
parent 72904a3366
commit 26429c9457
12 changed files with 53 additions and 337 deletions

View file

@ -46,21 +46,6 @@
#include "util/config_file.h"
#include "util/net_help.h"
int
acl_list_cmp(const void* k1, const void* k2)
{
struct acl_addr* n1 = (struct acl_addr*)k1;
struct acl_addr* n2 = (struct acl_addr*)k2;
int r = sockaddr_cmp_addr(&n1->addr, n1->addrlen, &n2->addr,
n2->addrlen);
if(r != 0) return r;
if(n1->net < n2->net)
return -1;
if(n1->net > n2->net)
return 1;
return 0;
}
struct acl_list*
acl_list_create()
{
@ -82,7 +67,6 @@ acl_list_delete(struct acl_list* acl)
if(!acl)
return;
regional_destroy(acl->region);
free(acl->tree);
free(acl);
}
@ -96,13 +80,8 @@ acl_list_insert(struct acl_list* acl, struct sockaddr_storage* addr,
sizeof(struct acl_addr));
if(!node)
return 0;
node->node.key = node;
memcpy(&node->addr, addr, addrlen);
node->addrlen = addrlen;
node->net = net;
node->parent = NULL;
node->control = control;
if(!rbtree_insert(acl->tree, &node->node)) {
if(!addr_tree_insert(&acl->tree, &node->node, addr, addrlen, net)) {
if(complain_duplicates)
verbose(VERB_QUERY, "duplicate acl address ignored.");
}
@ -155,42 +134,11 @@ read_acl_list(struct acl_list* acl, struct config_file* cfg)
return 1;
}
/** initialise parent pointers in the tree */
static void
acl_list_init_parents(struct acl_list* acl)
{
struct acl_addr* node, *prev = NULL, *p;
int m;
RBTREE_FOR(node, struct acl_addr*, acl->tree) {
node->parent = NULL;
if(!prev || prev->addrlen != node->addrlen) {
prev = node;
continue;
}
m = addr_in_common(&prev->addr, prev->net, &node->addr,
node->net, node->addrlen);
/* sort order like: ::/0, 1::/2, 1::/4, ... 2::/2 */
/* find the previous, or parent-parent-parent */
for(p = prev; p; p = p->parent)
if(p->net <= m) {
/* ==: since prev matched m, this is closest*/
/* <: prev matches more, but is not a parent,
* this one is a (grand)parent */
node->parent = p;
break;
}
prev = node;
}
}
int
acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg)
{
regional_free_all(acl->region);
free(acl->tree);
acl->tree = rbtree_create(acl_list_cmp);
if(!acl->tree)
return 0;
addr_tree_init(&acl->tree);
if(!read_acl_list(acl, cfg))
return 0;
/* insert defaults, with '0' to ignore them if they are duplicates */
@ -206,7 +154,7 @@ acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg)
if(!acl_list_str_cfg(acl, "::ffff:127.0.0.1", "allow", 0))
return 0;
}
acl_list_init_parents(acl);
addr_tree_init_parents(&acl->tree);
return 1;
}
@ -214,33 +162,9 @@ enum acl_access
acl_list_lookup(struct acl_list* acl, struct sockaddr_storage* addr,
socklen_t addrlen)
{
/* lookup in the tree */
rbnode_t* res = NULL;
struct acl_addr* result;
struct acl_addr key;
key.node.key = &key;
memcpy(&key.addr, addr, addrlen);
key.addrlen = addrlen;
key.net = (addr_is_ip6(addr, addrlen)?128:32);
if(rbtree_find_less_equal(acl->tree, &key, &res)) {
/* exact */
result = (struct acl_addr*)res;
return result->control;
} else {
/* smaller element (or no element) */
int m;
result = (struct acl_addr*)res;
if(!result || result->addrlen != addrlen)
return acl_deny;
/* count number of bits matched */
m = addr_in_common(&result->addr, result->net, addr,
key.net, addrlen);
while(result) { /* go up until addr is inside netblock */
if(result->net <= m)
return result->control;
result = result->parent;
}
}
struct acl_addr* r = (struct acl_addr*)addr_tree_lookup(&acl->tree,
addr, addrlen);
if(r) return r->control;
return acl_deny;
}

View file

@ -42,7 +42,7 @@
#ifndef DAEMON_ACL_LIST_H
#define DAEMON_ACL_LIST_H
#include "util/rbtree.h"
#include "util/storage/dnstree.h"
struct config_file;
struct regional;
@ -71,7 +71,7 @@ struct acl_list {
* Tree of the addresses that are allowed/blocked.
* contents of type acl_addr.
*/
rbtree_t* tree;
rbtree_t tree;
};
/**
@ -79,16 +79,8 @@ struct acl_list {
* An address span with access control information
*/
struct acl_addr {
/** redblacktree node, key is this structure: addr and addrlen, net */
rbnode_t node;
/** parent node in acl tree that encompasses this entry */
struct acl_addr* parent;
/** address */
struct sockaddr_storage addr;
/** length of addr */
socklen_t addrlen;
/** netblock size */
int net;
/** node in address tree */
struct addr_tree_node node;
/** access control on this netblock */
enum acl_access control;
};
@ -130,7 +122,4 @@ enum acl_access acl_list_lookup(struct acl_list* acl,
*/
size_t acl_list_get_mem(struct acl_list* acl);
/** compare two acl list entries */
int acl_list_cmp(const void* k1, const void* k2);
#endif /* DAEMON_ACL_LIST_H */

View file

@ -1,6 +1,7 @@
4 September 2008: Wouter
- scrubber scrubs away private addresses.
- test for private addresses. man page entry.
- code refactored for name and address tree lookups.
3 September 2008: Wouter
- options for 'DNS Rebinding' protection: private-address and

View file

@ -37,7 +37,7 @@ total 6 of 8 weeks; 2 weeks for maintenance activities.
+ records in the additional section should not be marked bogus
if they have no signer or a different signed. Validate if you can,
otherwise leave unchecked.
* block DNS rebinding attacks, block all A records from 1918 IP blocks,
+ block DNS rebinding attacks, block all A records from 1918 IP blocks,
like dnswall does. Allow certain subdomains to do it, config options.
one option that controls on/off of all private space.
note in config/man that we may consider turning on by default.

View file

@ -48,21 +48,6 @@
#include "util/config_file.h"
#include "util/net_help.h"
int
donotq_cmp(const void* k1, const void* k2)
{
struct iter_donotq_addr* n1 = (struct iter_donotq_addr*)k1;
struct iter_donotq_addr* n2 = (struct iter_donotq_addr*)k2;
int r = sockaddr_cmp_addr(&n1->addr, n1->addrlen, &n2->addr,
n2->addrlen);
if(r != 0) return r;
if(n1->net < n2->net)
return -1;
if(n1->net > n2->net)
return 1;
return 0;
}
struct iter_donotq*
donotq_create()
{
@ -84,7 +69,6 @@ donotq_delete(struct iter_donotq* dq)
if(!dq)
return;
regional_destroy(dq->region);
free(dq->tree);
free(dq);
}
@ -93,16 +77,11 @@ static int
donotq_insert(struct iter_donotq* dq, struct sockaddr_storage* addr,
socklen_t addrlen, int net)
{
struct iter_donotq_addr* node = regional_alloc(dq->region,
sizeof(struct iter_donotq_addr));
struct addr_tree_node* node = (struct addr_tree_node*)regional_alloc(
dq->region, sizeof(*node));
if(!node)
return 0;
node->node.key = node;
memcpy(&node->addr, addr, addrlen);
node->addrlen = addrlen;
node->net = net;
node->parent = NULL;
if(!rbtree_insert(dq->tree, &node->node)) {
if(!addr_tree_insert(&dq->tree, node, addr, addrlen, net)) {
verbose(VERB_QUERY, "duplicate donotquery address ignored.");
}
return 1;
@ -140,42 +119,11 @@ read_donotq(struct iter_donotq* dq, struct config_file* cfg)
return 1;
}
/** initialise parent pointers in the tree */
static void
donotq_init_parents(struct iter_donotq* donotq)
{
struct iter_donotq_addr* node, *prev = NULL, *p;
int m;
RBTREE_FOR(node, struct iter_donotq_addr*, donotq->tree) {
node->parent = NULL;
if(!prev || prev->addrlen != node->addrlen) {
prev = node;
continue;
}
m = addr_in_common(&prev->addr, prev->net, &node->addr,
node->net, node->addrlen);
/* sort order like: ::/0, 1::/2, 1::/4, ... 2::/2 */
/* find the previous, or parent-parent-parent */
for(p = prev; p; p = p->parent)
if(p->net <= m) {
/* ==: since prev matched m, this is closest*/
/* <: prev matches more, but is not a parent,
* this one is a (grand)parent */
node->parent = p;
break;
}
prev = node;
}
}
int
donotq_apply_cfg(struct iter_donotq* dq, struct config_file* cfg)
{
free(dq->tree);
regional_free_all(dq->region);
dq->tree = rbtree_create(donotq_cmp);
if(!dq->tree)
return 0;
addr_tree_init(&dq->tree);
if(!read_donotq(dq, cfg))
return 0;
if(cfg->donotquery_localhost) {
@ -186,7 +134,7 @@ donotq_apply_cfg(struct iter_donotq* dq, struct config_file* cfg)
return 0;
}
}
donotq_init_parents(dq);
addr_tree_init_parents(&dq->tree);
return 1;
}
@ -194,33 +142,7 @@ int
donotq_lookup(struct iter_donotq* donotq, struct sockaddr_storage* addr,
socklen_t addrlen)
{
/* lookup in the tree */
rbnode_t* res = NULL;
struct iter_donotq_addr* result;
struct iter_donotq_addr key;
key.node.key = &key;
memcpy(&key.addr, addr, addrlen);
key.addrlen = addrlen;
key.net = (addr_is_ip6(addr, addrlen)?128:32);
if(rbtree_find_less_equal(donotq->tree, &key, &res)) {
/* exact */
return 1;
} else {
/* smaller element (or no element) */
int m;
result = (struct iter_donotq_addr*)res;
if(!result || result->addrlen != addrlen)
return 0;
/* count number of bits matched */
m = addr_in_common(&result->addr, result->net, addr,
key.net, addrlen);
while(result) { /* go up until addr is inside netblock */
if(result->net <= m)
return 1;
result = result->parent;
}
}
return 0;
return addr_tree_lookup(&donotq->tree, addr, addrlen) != NULL;
}
size_t

View file

@ -42,7 +42,7 @@
#ifndef ITERATOR_ITER_DONOTQ_H
#define ITERATOR_ITER_DONOTQ_H
#include "util/rbtree.h"
#include "util/storage/dnstree.h"
struct iter_env;
struct config_file;
struct regional;
@ -55,26 +55,10 @@ struct iter_donotq {
struct regional* region;
/**
* Tree of the address spans that are blocked.
* contents of type iter_donotq_addr.
* contents of type addr_tree_node. Each node is an address span
* that must not be used to send queries to.
*/
rbtree_t* tree;
};
/**
* Iterator donotquery address.
* An address span that must not be used to send queries to.
*/
struct iter_donotq_addr {
/** redblacktree node, key is this structure: addr and addrlen, net */
rbnode_t node;
/** address */
struct sockaddr_storage addr;
/** length of addr */
socklen_t addrlen;
/** netblock size */
int net;
/** parent node in donotq tree that encompasses this entry */
struct iter_donotq_addr* parent;
rbtree_t tree;
};
/**
@ -114,7 +98,4 @@ int donotq_lookup(struct iter_donotq* donotq, struct sockaddr_storage* addr,
*/
size_t donotq_get_mem(struct iter_donotq* donotq);
/** compare two donotq entries */
int donotq_cmp(const void* k1, const void* k2);
#endif /* ITERATOR_ITER_DONOTQ_H */

View file

@ -48,21 +48,6 @@
#include "util/net_help.h"
#include "util/data/dname.h"
int
stub_cmp(const void* k1, const void* k2)
{
int m;
struct iter_hints_stub* n1 = (struct iter_hints_stub*)k1;
struct iter_hints_stub* n2 = (struct iter_hints_stub*)k2;
if(n1->hint_class != n2->hint_class) {
if(n1->hint_class < n2->hint_class)
return -1;
return 1;
}
return dname_lab_cmp(n1->name, n1->namelabs, n2->name, n2->namelabs,
&m);
}
struct iter_hints*
hints_create()
{
@ -84,7 +69,6 @@ hints_delete(struct iter_hints* hints)
if(!hints)
return;
regional_destroy(hints->region);
free(hints->tree);
free(hints);
}
@ -160,51 +144,20 @@ hints_insert(struct iter_hints* hints, uint16_t c, struct delegpt* dp)
{
struct iter_hints_stub* node = regional_alloc(hints->region,
sizeof(struct iter_hints_stub));
uint8_t* nm;
if(!node)
return 0;
node->node.key = node;
node->hint_class = c;
node->name = regional_alloc_init(hints->region, dp->name, dp->namelen);
if(!node->name)
nm = regional_alloc_init(hints->region, dp->name, dp->namelen);
if(!nm)
return 0;
node->namelen = dp->namelen;
node->namelabs = dp->namelabs;
node->dp = dp;
if(!rbtree_insert(hints->tree, &node->node)) {
if(!name_tree_insert(&hints->tree, &node->node, nm, dp->namelen,
dp->namelabs, c)) {
log_err("second hints ignored.");
}
return 1;
}
/** initialise parent pointers in the tree */
static void
init_parents(struct iter_hints* hints)
{
struct iter_hints_stub* node, *prev = NULL, *p;
int m;
RBTREE_FOR(node, struct iter_hints_stub*, hints->tree) {
node->parent = NULL;
if(!prev || prev->hint_class != node->hint_class) {
prev = node;
continue;
}
(void)dname_lab_cmp(prev->name, prev->namelabs, node->name,
node->namelabs, &m); /* we know prev is smaller */
/* sort order like: . com. bla.com. zwb.com. net. */
/* find the previous, or parent-parent-parent */
for(p = prev; p; p = p->parent)
/* looking for name with few labels, a parent */
if(p->namelabs <= m) {
/* ==: since prev matched m, this is closest*/
/* <: prev matches more, but is not a parent,
* this one is a (grand)parent */
node->parent = p;
break;
}
prev = node;
}
}
/** set stub name */
static int
read_stubs_name(struct iter_hints* hints, struct config_stub* s,
@ -435,10 +388,8 @@ read_root_hints_list(struct iter_hints* hints, struct config_file* cfg)
int
hints_apply_cfg(struct iter_hints* hints, struct config_file* cfg)
{
free(hints->tree);
hints->tree = rbtree_create(stub_cmp);
if(!hints->tree)
return 0;
regional_free_all(hints->region);
name_tree_init(&hints->tree);
/* read root hints */
if(!read_root_hints_list(hints, cfg))
@ -459,7 +410,7 @@ hints_apply_cfg(struct iter_hints* hints, struct config_file* cfg)
return 0;
}
init_parents(hints);
name_tree_init_parents(&hints->tree);
return 1;
}
@ -467,13 +418,9 @@ struct delegpt*
hints_lookup_root(struct iter_hints* hints, uint16_t qclass)
{
uint8_t rootlab = 0;
struct iter_hints_stub key, *stub;
key.node.key = &key;
key.hint_class = qclass;
key.name = &rootlab;
key.namelen = 1;
key.namelabs = 1;
stub = (struct iter_hints_stub*)rbtree_search(hints->tree, &key);
struct iter_hints_stub *stub;
stub = (struct iter_hints_stub*)name_tree_find(&hints->tree,
&rootlab, 1, 1, qclass);
if(!stub)
return NULL;
return stub->dp;
@ -483,40 +430,22 @@ struct delegpt*
hints_lookup_stub(struct iter_hints* hints, uint8_t* qname,
uint16_t qclass, struct delegpt* cache_dp)
{
size_t len;
int labs;
struct iter_hints_stub *r;
/* first lookup the stub */
rbnode_t* res = NULL;
struct iter_hints_stub *result;
struct iter_hints_stub key;
key.node.key = &key;
key.hint_class = qclass;
key.name = qname;
key.namelabs = dname_count_size_labels(qname, &key.namelen);
if(rbtree_find_less_equal(hints->tree, &key, &res)) {
/* exact */
result = (struct iter_hints_stub*)res;
} else {
/* smaller element (or no element) */
int m;
result = (struct iter_hints_stub*)res;
if(!result || result->hint_class != qclass)
return NULL;
/* count number of labels matched */
(void)dname_lab_cmp(result->name, result->namelabs, key.name,
key.namelabs, &m);
while(result) { /* go up until qname is subdomain of stub */
if(result->namelabs <= m)
break;
result = result->parent;
}
if(!result)
return NULL;
}
labs = dname_count_size_labels(qname, &len);
r = (struct iter_hints_stub*)name_tree_lookup(&hints->tree, qname,
len, labs, qclass);
if(!r) return NULL;
/*
* If our cached delegation point is above the hint, we need to prime.
*/
if(dname_strict_subdomain(result->dp->name, result->dp->namelabs,
if(dname_strict_subdomain(r->dp->name, r->dp->namelabs,
cache_dp->name, cache_dp->namelabs))
return result->dp; /* need to prime this stub */
return r->dp; /* need to prime this stub */
return NULL;
}

View file

@ -42,7 +42,7 @@
#ifndef ITERATOR_ITER_HINTS_H
#define ITERATOR_ITER_HINTS_H
#include "util/rbtree.h"
#include "util/storage/dnstree.h"
struct iter_env;
struct config_file;
struct delegpt;
@ -60,28 +60,19 @@ struct iter_hints {
* a lookup on class, name will return an exact match or the closest
* match which gives the ancestor needed.
* contents of type iter_hints_stub. The class IN root is in here.
* uses name_tree_node from dnstree.h.
*/
rbtree_t* tree;
rbtree_t tree;
};
/**
* Iterator hints for a particular stub.
*/
struct iter_hints_stub {
/** redblacktree node, key is this structure: class and name */
rbnode_t node;
/** name */
uint8_t* name;
/** length of name */
size_t namelen;
/** number of labels in name */
int namelabs;
/** tree sorted by name, class */
struct name_tree_node node;
/** delegation point with hint information for this stub. */
struct delegpt* dp;
/** pointer to parent in stub hint tree (or NULL if none) */
struct iter_hints_stub* parent;
/** class of hints. host order. */
uint16_t hint_class;
};
/**
@ -134,7 +125,4 @@ struct delegpt* hints_lookup_stub(struct iter_hints* hints,
*/
size_t hints_get_mem(struct iter_hints* hints);
/** compare two hint entries */
int stub_cmp(const void* k1, const void* k2);
#endif /* ITERATOR_ITER_HINTS_H */

View file

@ -799,13 +799,6 @@ worker_alloc_cleanup(void* ATTR_UNUSED(arg))
log_assert(0);
}
int
acl_list_cmp(const void* ATTR_UNUSED(k1), const void* ATTR_UNUSED(k2))
{
log_assert(0);
return 0;
}
void worker_stat_timer_cb(void* ATTR_UNUSED(arg))
{
log_assert(0);

View file

@ -108,13 +108,6 @@ worker_alloc_cleanup(void* ATTR_UNUSED(arg))
log_assert(0);
}
int
acl_list_cmp(const void* ATTR_UNUSED(k1), const void* ATTR_UNUSED(k2))
{
log_assert(0);
return 0;
}
int libworker_send_packet(ldns_buffer* ATTR_UNUSED(pkt),
struct sockaddr_storage* ATTR_UNUSED(addr),
socklen_t ATTR_UNUSED(addrlen), int ATTR_UNUSED(timeout),

View file

@ -53,9 +53,7 @@
#include "services/cache/infra.h"
#include "services/cache/rrset.h"
#include "iterator/iterator.h"
#include "iterator/iter_donotq.h"
#include "iterator/iter_fwd.h"
#include "iterator/iter_hints.h"
#include "validator/validator.h"
#include "validator/val_anchor.h"
#include "validator/val_nsec3.h"
@ -67,7 +65,6 @@
#include "util/storage/slabhash.h"
#include "util/storage/dnstree.h"
#include "util/locks.h"
#include "daemon/acl_list.h"
#include "libunbound/libworker.h"
#include "libunbound/context.h"
#include "util/tube.h"
@ -152,16 +149,13 @@ fptr_whitelist_rbtree_cmp(int (*fptr) (const void *, const void *))
{
if(fptr == &mesh_state_compare) return 1;
else if(fptr == &mesh_state_ref_compare) return 1;
else if(fptr == &acl_list_cmp) return 1;
else if(fptr == &addr_tree_compare) return 1;
else if(fptr == &local_zone_cmp) return 1;
else if(fptr == &local_data_cmp) return 1;
else if(fptr == &donotq_cmp) return 1;
else if(fptr == &fwd_cmp) return 1;
else if(fptr == &stub_cmp) return 1;
else if(fptr == &pending_cmp) return 1;
else if(fptr == &serviced_cmp) return 1;
else if(fptr == &name_tree_compare) return 1;
else if(fptr == &addr_tree_compare) return 1;
else if(fptr == &order_lock_cmp) return 1;
else if(fptr == &codeline_cmp) return 1;
else if(fptr == &nsec3_hash_cmp) return 1;

View file

@ -54,7 +54,7 @@ int name_tree_compare(const void* k1, const void* k2)
return -1;
return 1;
}
return dname_canon_lab_cmp(x->name, x->labs, y->name, y->labs, &m);
return dname_lab_cmp(x->name, x->labs, y->name, y->labs, &m);
}
int addr_tree_compare(const void* k1, const void* k2)
@ -89,6 +89,7 @@ int name_tree_insert(rbtree_t* tree, struct name_tree_node* node,
node->len = len;
node->labs = labs;
node->dclass = dclass;
node->parent = NULL;
return rbtree_insert(tree, &node->node) != NULL;
}
@ -99,6 +100,7 @@ int addr_tree_insert(rbtree_t* tree, struct addr_tree_node* node,
memcpy(&node->addr, addr, addrlen);
node->addrlen = addrlen;
node->net = net;
node->parent = NULL;
return rbtree_insert(tree, &node->node) != NULL;
}