#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()
{
if(!acl)
return;
regional_destroy(acl->region);
- free(acl->tree);
free(acl);
}
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.");
}
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 */
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;
}
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;
}
#ifndef DAEMON_ACL_LIST_H
#define DAEMON_ACL_LIST_H
-#include "util/rbtree.h"
+#include "util/storage/dnstree.h"
struct config_file;
struct regional;
* Tree of the addresses that are allowed/blocked.
* contents of type acl_addr.
*/
- rbtree_t* tree;
+ rbtree_t tree;
};
/**
* 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;
};
*/
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 */
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
+ 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.
#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()
{
if(!dq)
return;
regional_destroy(dq->region);
- free(dq->tree);
free(dq);
}
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;
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) {
return 0;
}
}
- donotq_init_parents(dq);
+ addr_tree_init_parents(&dq->tree);
return 1;
}
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
#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;
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;
};
/**
*/
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 */
#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()
{
if(!hints)
return;
regional_destroy(hints->region);
- free(hints->tree);
free(hints);
}
{
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,
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))
return 0;
}
- init_parents(hints);
+ name_tree_init_parents(&hints->tree);
return 1;
}
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;
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;
}
#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;
* 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;
};
/**
*/
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 */
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);
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),
#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"
#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"
{
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;
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)
node->len = len;
node->labs = labs;
node->dclass = dclass;
+ node->parent = NULL;
return rbtree_insert(tree, &node->node) != NULL;
}
memcpy(&node->addr, addr, addrlen);
node->addrlen = addrlen;
node->net = net;
+ node->parent = NULL;
return rbtree_insert(tree, &node->node) != NULL;
}