mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
refactored code.
git-svn-id: file:///svn/unbound/trunk@1225 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
72904a3366
commit
26429c9457
12 changed files with 53 additions and 337 deletions
|
|
@ -46,21 +46,6 @@
|
||||||
#include "util/config_file.h"
|
#include "util/config_file.h"
|
||||||
#include "util/net_help.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*
|
struct acl_list*
|
||||||
acl_list_create()
|
acl_list_create()
|
||||||
{
|
{
|
||||||
|
|
@ -82,7 +67,6 @@ acl_list_delete(struct acl_list* acl)
|
||||||
if(!acl)
|
if(!acl)
|
||||||
return;
|
return;
|
||||||
regional_destroy(acl->region);
|
regional_destroy(acl->region);
|
||||||
free(acl->tree);
|
|
||||||
free(acl);
|
free(acl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -96,13 +80,8 @@ acl_list_insert(struct acl_list* acl, struct sockaddr_storage* addr,
|
||||||
sizeof(struct acl_addr));
|
sizeof(struct acl_addr));
|
||||||
if(!node)
|
if(!node)
|
||||||
return 0;
|
return 0;
|
||||||
node->node.key = node;
|
|
||||||
memcpy(&node->addr, addr, addrlen);
|
|
||||||
node->addrlen = addrlen;
|
|
||||||
node->net = net;
|
|
||||||
node->parent = NULL;
|
|
||||||
node->control = control;
|
node->control = control;
|
||||||
if(!rbtree_insert(acl->tree, &node->node)) {
|
if(!addr_tree_insert(&acl->tree, &node->node, addr, addrlen, net)) {
|
||||||
if(complain_duplicates)
|
if(complain_duplicates)
|
||||||
verbose(VERB_QUERY, "duplicate acl address ignored.");
|
verbose(VERB_QUERY, "duplicate acl address ignored.");
|
||||||
}
|
}
|
||||||
|
|
@ -155,42 +134,11 @@ read_acl_list(struct acl_list* acl, struct config_file* cfg)
|
||||||
return 1;
|
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
|
int
|
||||||
acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg)
|
acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg)
|
||||||
{
|
{
|
||||||
regional_free_all(acl->region);
|
regional_free_all(acl->region);
|
||||||
free(acl->tree);
|
addr_tree_init(&acl->tree);
|
||||||
acl->tree = rbtree_create(acl_list_cmp);
|
|
||||||
if(!acl->tree)
|
|
||||||
return 0;
|
|
||||||
if(!read_acl_list(acl, cfg))
|
if(!read_acl_list(acl, cfg))
|
||||||
return 0;
|
return 0;
|
||||||
/* insert defaults, with '0' to ignore them if they are duplicates */
|
/* 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))
|
if(!acl_list_str_cfg(acl, "::ffff:127.0.0.1", "allow", 0))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
acl_list_init_parents(acl);
|
addr_tree_init_parents(&acl->tree);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -214,33 +162,9 @@ enum acl_access
|
||||||
acl_list_lookup(struct acl_list* acl, struct sockaddr_storage* addr,
|
acl_list_lookup(struct acl_list* acl, struct sockaddr_storage* addr,
|
||||||
socklen_t addrlen)
|
socklen_t addrlen)
|
||||||
{
|
{
|
||||||
/* lookup in the tree */
|
struct acl_addr* r = (struct acl_addr*)addr_tree_lookup(&acl->tree,
|
||||||
rbnode_t* res = NULL;
|
addr, addrlen);
|
||||||
struct acl_addr* result;
|
if(r) return r->control;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return acl_deny;
|
return acl_deny;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@
|
||||||
|
|
||||||
#ifndef DAEMON_ACL_LIST_H
|
#ifndef DAEMON_ACL_LIST_H
|
||||||
#define DAEMON_ACL_LIST_H
|
#define DAEMON_ACL_LIST_H
|
||||||
#include "util/rbtree.h"
|
#include "util/storage/dnstree.h"
|
||||||
struct config_file;
|
struct config_file;
|
||||||
struct regional;
|
struct regional;
|
||||||
|
|
||||||
|
|
@ -71,7 +71,7 @@ struct acl_list {
|
||||||
* Tree of the addresses that are allowed/blocked.
|
* Tree of the addresses that are allowed/blocked.
|
||||||
* contents of type acl_addr.
|
* 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
|
* An address span with access control information
|
||||||
*/
|
*/
|
||||||
struct acl_addr {
|
struct acl_addr {
|
||||||
/** redblacktree node, key is this structure: addr and addrlen, net */
|
/** node in address tree */
|
||||||
rbnode_t node;
|
struct addr_tree_node 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;
|
|
||||||
/** access control on this netblock */
|
/** access control on this netblock */
|
||||||
enum acl_access control;
|
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);
|
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 */
|
#endif /* DAEMON_ACL_LIST_H */
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
4 September 2008: Wouter
|
4 September 2008: Wouter
|
||||||
- scrubber scrubs away private addresses.
|
- scrubber scrubs away private addresses.
|
||||||
- test for private addresses. man page entry.
|
- test for private addresses. man page entry.
|
||||||
|
- code refactored for name and address tree lookups.
|
||||||
|
|
||||||
3 September 2008: Wouter
|
3 September 2008: Wouter
|
||||||
- options for 'DNS Rebinding' protection: private-address and
|
- options for 'DNS Rebinding' protection: private-address and
|
||||||
|
|
|
||||||
2
doc/plan
2
doc/plan
|
|
@ -37,7 +37,7 @@ total 6 of 8 weeks; 2 weeks for maintenance activities.
|
||||||
+ records in the additional section should not be marked bogus
|
+ records in the additional section should not be marked bogus
|
||||||
if they have no signer or a different signed. Validate if you can,
|
if they have no signer or a different signed. Validate if you can,
|
||||||
otherwise leave unchecked.
|
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.
|
like dnswall does. Allow certain subdomains to do it, config options.
|
||||||
one option that controls on/off of all private space.
|
one option that controls on/off of all private space.
|
||||||
note in config/man that we may consider turning on by default.
|
note in config/man that we may consider turning on by default.
|
||||||
|
|
|
||||||
|
|
@ -48,21 +48,6 @@
|
||||||
#include "util/config_file.h"
|
#include "util/config_file.h"
|
||||||
#include "util/net_help.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*
|
struct iter_donotq*
|
||||||
donotq_create()
|
donotq_create()
|
||||||
{
|
{
|
||||||
|
|
@ -84,7 +69,6 @@ donotq_delete(struct iter_donotq* dq)
|
||||||
if(!dq)
|
if(!dq)
|
||||||
return;
|
return;
|
||||||
regional_destroy(dq->region);
|
regional_destroy(dq->region);
|
||||||
free(dq->tree);
|
|
||||||
free(dq);
|
free(dq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -93,16 +77,11 @@ static int
|
||||||
donotq_insert(struct iter_donotq* dq, struct sockaddr_storage* addr,
|
donotq_insert(struct iter_donotq* dq, struct sockaddr_storage* addr,
|
||||||
socklen_t addrlen, int net)
|
socklen_t addrlen, int net)
|
||||||
{
|
{
|
||||||
struct iter_donotq_addr* node = regional_alloc(dq->region,
|
struct addr_tree_node* node = (struct addr_tree_node*)regional_alloc(
|
||||||
sizeof(struct iter_donotq_addr));
|
dq->region, sizeof(*node));
|
||||||
if(!node)
|
if(!node)
|
||||||
return 0;
|
return 0;
|
||||||
node->node.key = node;
|
if(!addr_tree_insert(&dq->tree, node, addr, addrlen, net)) {
|
||||||
memcpy(&node->addr, addr, addrlen);
|
|
||||||
node->addrlen = addrlen;
|
|
||||||
node->net = net;
|
|
||||||
node->parent = NULL;
|
|
||||||
if(!rbtree_insert(dq->tree, &node->node)) {
|
|
||||||
verbose(VERB_QUERY, "duplicate donotquery address ignored.");
|
verbose(VERB_QUERY, "duplicate donotquery address ignored.");
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
|
@ -140,42 +119,11 @@ read_donotq(struct iter_donotq* dq, struct config_file* cfg)
|
||||||
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
|
int
|
||||||
donotq_apply_cfg(struct iter_donotq* dq, struct config_file* cfg)
|
donotq_apply_cfg(struct iter_donotq* dq, struct config_file* cfg)
|
||||||
{
|
{
|
||||||
free(dq->tree);
|
|
||||||
regional_free_all(dq->region);
|
regional_free_all(dq->region);
|
||||||
dq->tree = rbtree_create(donotq_cmp);
|
addr_tree_init(&dq->tree);
|
||||||
if(!dq->tree)
|
|
||||||
return 0;
|
|
||||||
if(!read_donotq(dq, cfg))
|
if(!read_donotq(dq, cfg))
|
||||||
return 0;
|
return 0;
|
||||||
if(cfg->donotquery_localhost) {
|
if(cfg->donotquery_localhost) {
|
||||||
|
|
@ -186,7 +134,7 @@ donotq_apply_cfg(struct iter_donotq* dq, struct config_file* cfg)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
donotq_init_parents(dq);
|
addr_tree_init_parents(&dq->tree);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -194,33 +142,7 @@ int
|
||||||
donotq_lookup(struct iter_donotq* donotq, struct sockaddr_storage* addr,
|
donotq_lookup(struct iter_donotq* donotq, struct sockaddr_storage* addr,
|
||||||
socklen_t addrlen)
|
socklen_t addrlen)
|
||||||
{
|
{
|
||||||
/* lookup in the tree */
|
return addr_tree_lookup(&donotq->tree, addr, addrlen) != NULL;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@
|
||||||
|
|
||||||
#ifndef ITERATOR_ITER_DONOTQ_H
|
#ifndef ITERATOR_ITER_DONOTQ_H
|
||||||
#define ITERATOR_ITER_DONOTQ_H
|
#define ITERATOR_ITER_DONOTQ_H
|
||||||
#include "util/rbtree.h"
|
#include "util/storage/dnstree.h"
|
||||||
struct iter_env;
|
struct iter_env;
|
||||||
struct config_file;
|
struct config_file;
|
||||||
struct regional;
|
struct regional;
|
||||||
|
|
@ -55,26 +55,10 @@ struct iter_donotq {
|
||||||
struct regional* region;
|
struct regional* region;
|
||||||
/**
|
/**
|
||||||
* Tree of the address spans that are blocked.
|
* 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;
|
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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -114,7 +98,4 @@ int donotq_lookup(struct iter_donotq* donotq, struct sockaddr_storage* addr,
|
||||||
*/
|
*/
|
||||||
size_t donotq_get_mem(struct iter_donotq* donotq);
|
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 */
|
#endif /* ITERATOR_ITER_DONOTQ_H */
|
||||||
|
|
|
||||||
|
|
@ -48,21 +48,6 @@
|
||||||
#include "util/net_help.h"
|
#include "util/net_help.h"
|
||||||
#include "util/data/dname.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*
|
struct iter_hints*
|
||||||
hints_create()
|
hints_create()
|
||||||
{
|
{
|
||||||
|
|
@ -84,7 +69,6 @@ hints_delete(struct iter_hints* hints)
|
||||||
if(!hints)
|
if(!hints)
|
||||||
return;
|
return;
|
||||||
regional_destroy(hints->region);
|
regional_destroy(hints->region);
|
||||||
free(hints->tree);
|
|
||||||
free(hints);
|
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,
|
struct iter_hints_stub* node = regional_alloc(hints->region,
|
||||||
sizeof(struct iter_hints_stub));
|
sizeof(struct iter_hints_stub));
|
||||||
|
uint8_t* nm;
|
||||||
if(!node)
|
if(!node)
|
||||||
return 0;
|
return 0;
|
||||||
node->node.key = node;
|
nm = regional_alloc_init(hints->region, dp->name, dp->namelen);
|
||||||
node->hint_class = c;
|
if(!nm)
|
||||||
node->name = regional_alloc_init(hints->region, dp->name, dp->namelen);
|
|
||||||
if(!node->name)
|
|
||||||
return 0;
|
return 0;
|
||||||
node->namelen = dp->namelen;
|
|
||||||
node->namelabs = dp->namelabs;
|
|
||||||
node->dp = dp;
|
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.");
|
log_err("second hints ignored.");
|
||||||
}
|
}
|
||||||
return 1;
|
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 */
|
/** set stub name */
|
||||||
static int
|
static int
|
||||||
read_stubs_name(struct iter_hints* hints, struct config_stub* s,
|
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
|
int
|
||||||
hints_apply_cfg(struct iter_hints* hints, struct config_file* cfg)
|
hints_apply_cfg(struct iter_hints* hints, struct config_file* cfg)
|
||||||
{
|
{
|
||||||
free(hints->tree);
|
regional_free_all(hints->region);
|
||||||
hints->tree = rbtree_create(stub_cmp);
|
name_tree_init(&hints->tree);
|
||||||
if(!hints->tree)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* read root hints */
|
/* read root hints */
|
||||||
if(!read_root_hints_list(hints, cfg))
|
if(!read_root_hints_list(hints, cfg))
|
||||||
|
|
@ -459,7 +410,7 @@ hints_apply_cfg(struct iter_hints* hints, struct config_file* cfg)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
init_parents(hints);
|
name_tree_init_parents(&hints->tree);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -467,13 +418,9 @@ struct delegpt*
|
||||||
hints_lookup_root(struct iter_hints* hints, uint16_t qclass)
|
hints_lookup_root(struct iter_hints* hints, uint16_t qclass)
|
||||||
{
|
{
|
||||||
uint8_t rootlab = 0;
|
uint8_t rootlab = 0;
|
||||||
struct iter_hints_stub key, *stub;
|
struct iter_hints_stub *stub;
|
||||||
key.node.key = &key;
|
stub = (struct iter_hints_stub*)name_tree_find(&hints->tree,
|
||||||
key.hint_class = qclass;
|
&rootlab, 1, 1, qclass);
|
||||||
key.name = &rootlab;
|
|
||||||
key.namelen = 1;
|
|
||||||
key.namelabs = 1;
|
|
||||||
stub = (struct iter_hints_stub*)rbtree_search(hints->tree, &key);
|
|
||||||
if(!stub)
|
if(!stub)
|
||||||
return NULL;
|
return NULL;
|
||||||
return stub->dp;
|
return stub->dp;
|
||||||
|
|
@ -483,40 +430,22 @@ struct delegpt*
|
||||||
hints_lookup_stub(struct iter_hints* hints, uint8_t* qname,
|
hints_lookup_stub(struct iter_hints* hints, uint8_t* qname,
|
||||||
uint16_t qclass, struct delegpt* cache_dp)
|
uint16_t qclass, struct delegpt* cache_dp)
|
||||||
{
|
{
|
||||||
|
size_t len;
|
||||||
|
int labs;
|
||||||
|
struct iter_hints_stub *r;
|
||||||
|
|
||||||
/* first lookup the stub */
|
/* first lookup the stub */
|
||||||
rbnode_t* res = NULL;
|
labs = dname_count_size_labels(qname, &len);
|
||||||
struct iter_hints_stub *result;
|
r = (struct iter_hints_stub*)name_tree_lookup(&hints->tree, qname,
|
||||||
struct iter_hints_stub key;
|
len, labs, qclass);
|
||||||
key.node.key = &key;
|
if(!r) return NULL;
|
||||||
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;
|
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
* If our cached delegation point is above the hint, we need to prime.
|
* 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))
|
cache_dp->name, cache_dp->namelabs))
|
||||||
return result->dp; /* need to prime this stub */
|
return r->dp; /* need to prime this stub */
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@
|
||||||
|
|
||||||
#ifndef ITERATOR_ITER_HINTS_H
|
#ifndef ITERATOR_ITER_HINTS_H
|
||||||
#define ITERATOR_ITER_HINTS_H
|
#define ITERATOR_ITER_HINTS_H
|
||||||
#include "util/rbtree.h"
|
#include "util/storage/dnstree.h"
|
||||||
struct iter_env;
|
struct iter_env;
|
||||||
struct config_file;
|
struct config_file;
|
||||||
struct delegpt;
|
struct delegpt;
|
||||||
|
|
@ -60,28 +60,19 @@ struct iter_hints {
|
||||||
* a lookup on class, name will return an exact match or the closest
|
* a lookup on class, name will return an exact match or the closest
|
||||||
* match which gives the ancestor needed.
|
* match which gives the ancestor needed.
|
||||||
* contents of type iter_hints_stub. The class IN root is in here.
|
* 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.
|
* Iterator hints for a particular stub.
|
||||||
*/
|
*/
|
||||||
struct iter_hints_stub {
|
struct iter_hints_stub {
|
||||||
/** redblacktree node, key is this structure: class and name */
|
/** tree sorted by name, class */
|
||||||
rbnode_t node;
|
struct name_tree_node node;
|
||||||
/** name */
|
|
||||||
uint8_t* name;
|
|
||||||
/** length of name */
|
|
||||||
size_t namelen;
|
|
||||||
/** number of labels in name */
|
|
||||||
int namelabs;
|
|
||||||
/** delegation point with hint information for this stub. */
|
/** delegation point with hint information for this stub. */
|
||||||
struct delegpt* dp;
|
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);
|
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 */
|
#endif /* ITERATOR_ITER_HINTS_H */
|
||||||
|
|
|
||||||
|
|
@ -799,13 +799,6 @@ worker_alloc_cleanup(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;
|
|
||||||
}
|
|
||||||
|
|
||||||
void worker_stat_timer_cb(void* ATTR_UNUSED(arg))
|
void worker_stat_timer_cb(void* ATTR_UNUSED(arg))
|
||||||
{
|
{
|
||||||
log_assert(0);
|
log_assert(0);
|
||||||
|
|
|
||||||
|
|
@ -108,13 +108,6 @@ worker_alloc_cleanup(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),
|
int libworker_send_packet(ldns_buffer* ATTR_UNUSED(pkt),
|
||||||
struct sockaddr_storage* ATTR_UNUSED(addr),
|
struct sockaddr_storage* ATTR_UNUSED(addr),
|
||||||
socklen_t ATTR_UNUSED(addrlen), int ATTR_UNUSED(timeout),
|
socklen_t ATTR_UNUSED(addrlen), int ATTR_UNUSED(timeout),
|
||||||
|
|
|
||||||
|
|
@ -53,9 +53,7 @@
|
||||||
#include "services/cache/infra.h"
|
#include "services/cache/infra.h"
|
||||||
#include "services/cache/rrset.h"
|
#include "services/cache/rrset.h"
|
||||||
#include "iterator/iterator.h"
|
#include "iterator/iterator.h"
|
||||||
#include "iterator/iter_donotq.h"
|
|
||||||
#include "iterator/iter_fwd.h"
|
#include "iterator/iter_fwd.h"
|
||||||
#include "iterator/iter_hints.h"
|
|
||||||
#include "validator/validator.h"
|
#include "validator/validator.h"
|
||||||
#include "validator/val_anchor.h"
|
#include "validator/val_anchor.h"
|
||||||
#include "validator/val_nsec3.h"
|
#include "validator/val_nsec3.h"
|
||||||
|
|
@ -67,7 +65,6 @@
|
||||||
#include "util/storage/slabhash.h"
|
#include "util/storage/slabhash.h"
|
||||||
#include "util/storage/dnstree.h"
|
#include "util/storage/dnstree.h"
|
||||||
#include "util/locks.h"
|
#include "util/locks.h"
|
||||||
#include "daemon/acl_list.h"
|
|
||||||
#include "libunbound/libworker.h"
|
#include "libunbound/libworker.h"
|
||||||
#include "libunbound/context.h"
|
#include "libunbound/context.h"
|
||||||
#include "util/tube.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;
|
if(fptr == &mesh_state_compare) return 1;
|
||||||
else if(fptr == &mesh_state_ref_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_zone_cmp) return 1;
|
||||||
else if(fptr == &local_data_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 == &fwd_cmp) return 1;
|
||||||
else if(fptr == &stub_cmp) return 1;
|
|
||||||
else if(fptr == &pending_cmp) return 1;
|
else if(fptr == &pending_cmp) return 1;
|
||||||
else if(fptr == &serviced_cmp) return 1;
|
else if(fptr == &serviced_cmp) return 1;
|
||||||
else if(fptr == &name_tree_compare) 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 == &order_lock_cmp) return 1;
|
||||||
else if(fptr == &codeline_cmp) return 1;
|
else if(fptr == &codeline_cmp) return 1;
|
||||||
else if(fptr == &nsec3_hash_cmp) return 1;
|
else if(fptr == &nsec3_hash_cmp) return 1;
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ int name_tree_compare(const void* k1, const void* k2)
|
||||||
return -1;
|
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)
|
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->len = len;
|
||||||
node->labs = labs;
|
node->labs = labs;
|
||||||
node->dclass = dclass;
|
node->dclass = dclass;
|
||||||
|
node->parent = NULL;
|
||||||
return rbtree_insert(tree, &node->node) != 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);
|
memcpy(&node->addr, addr, addrlen);
|
||||||
node->addrlen = addrlen;
|
node->addrlen = addrlen;
|
||||||
node->net = net;
|
node->net = net;
|
||||||
|
node->parent = NULL;
|
||||||
return rbtree_insert(tree, &node->node) != NULL;
|
return rbtree_insert(tree, &node->node) != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue