mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
private address and private domain config option read and store.
git-svn-id: file:///svn/unbound/trunk@1223 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
05cd134de9
commit
ff1a7ec42e
18 changed files with 1868 additions and 1024 deletions
|
|
@ -1,3 +1,9 @@
|
||||||
|
3 September 2008: Wouter
|
||||||
|
- options for 'DNS Rebinding' protection: private-address and
|
||||||
|
private-domain.
|
||||||
|
- dnstree for reuse of routines that help with domain, addr lookups.
|
||||||
|
- private-address and private-domain config option read, stored.
|
||||||
|
|
||||||
2 September 2008: Wouter
|
2 September 2008: Wouter
|
||||||
- DoS protection features. Queries are jostled out to make room.
|
- DoS protection features. Queries are jostled out to make room.
|
||||||
- testbound can pass time, increasing the internal timer.
|
- testbound can pass time, increasing the internal timer.
|
||||||
|
|
|
||||||
|
|
@ -141,7 +141,7 @@ server:
|
||||||
# access-control: ::0/0 refuse
|
# access-control: ::0/0 refuse
|
||||||
# access-control: ::1 allow
|
# access-control: ::1 allow
|
||||||
# access-control: ::ffff:127.0.0.1 allow
|
# access-control: ::ffff:127.0.0.1 allow
|
||||||
|
|
||||||
# if given, a chroot(2) is done to the given directory.
|
# if given, a chroot(2) is done to the given directory.
|
||||||
# i.e. you can chroot to the working directory, for example,
|
# i.e. you can chroot to the working directory, for example,
|
||||||
# for extra security, but make sure all files are in that directory.
|
# for extra security, but make sure all files are in that directory.
|
||||||
|
|
@ -243,6 +243,22 @@ server:
|
||||||
# resolution will fail for them. A solution is on the TODO list.
|
# resolution will fail for them. A solution is on the TODO list.
|
||||||
# use-caps-for-id: no
|
# use-caps-for-id: no
|
||||||
|
|
||||||
|
# Enforce privacy of these addresses. Strips them away from answers.
|
||||||
|
# It may cause DNSSEC validation to additionally mark it as bogus.
|
||||||
|
# Protects against 'DNS Rebinding' (uses browser as network proxy).
|
||||||
|
# Only 'private-domain' and 'local-data' names are allowed to have
|
||||||
|
# these private addresses. No default.
|
||||||
|
# private-address: 10.0.0.0/8
|
||||||
|
# private-address: 172.16.0.0/12
|
||||||
|
# private-address: 192.168.0.0/16
|
||||||
|
# private-address: 192.254.0.0/16
|
||||||
|
# private-address: fd00::/8
|
||||||
|
# private-address: fe80::/10
|
||||||
|
|
||||||
|
# Allow the domain (and its subdomains) to contain private addresses.
|
||||||
|
# local-data statements are allowed to contain private addresses too.
|
||||||
|
# private-domain: "example.com"
|
||||||
|
|
||||||
# Do not query the following addresses. No DNS queries are sent there.
|
# Do not query the following addresses. No DNS queries are sent there.
|
||||||
# List one address per entry. List classless netblocks with /size,
|
# List one address per entry. List classless netblocks with /size,
|
||||||
# do-not-query-address: 127.0.0.1/8
|
# do-not-query-address: 127.0.0.1/8
|
||||||
|
|
|
||||||
1
doc/plan
1
doc/plan
|
|
@ -70,6 +70,7 @@ like dnswall does. Allow certain subdomains to do it, config options.
|
||||||
* IPv6 reverse, IP4 reverse local-data shorthand for PTR records (?).
|
* IPv6 reverse, IP4 reverse local-data shorthand for PTR records (?).
|
||||||
cumbersome to reverse notate by hand for the operator. For local-data.
|
cumbersome to reverse notate by hand for the operator. For local-data.
|
||||||
local-reverse-data: "1.2.3.4 mypc.example.com"
|
local-reverse-data: "1.2.3.4 mypc.example.com"
|
||||||
|
* dns-0x20 fallback TODO item. Consider.
|
||||||
|
|
||||||
*** from draft resolver-mitigation
|
*** from draft resolver-mitigation
|
||||||
* Should be an option? (Not right now)
|
* Should be an option? (Not right now)
|
||||||
|
|
|
||||||
|
|
@ -172,6 +172,7 @@ 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);
|
free(dq->tree);
|
||||||
|
regional_free_all(dq->region);
|
||||||
dq->tree = rbtree_create(donotq_cmp);
|
dq->tree = rbtree_create(donotq_cmp);
|
||||||
if(!dq->tree)
|
if(!dq->tree)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
182
iterator/iter_priv.c
Normal file
182
iterator/iter_priv.c
Normal file
|
|
@ -0,0 +1,182 @@
|
||||||
|
/*
|
||||||
|
* iterator/iter_priv.c - iterative resolver private address and domain store
|
||||||
|
*
|
||||||
|
* Copyright (c) 2008, NLnet Labs. All rights reserved.
|
||||||
|
*
|
||||||
|
* This software is open source.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of the NLNET LABS nor the names of its contributors may
|
||||||
|
* be used to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file
|
||||||
|
*
|
||||||
|
* This file contains functions to assist the iterator module.
|
||||||
|
* Keep track of the private addresses and lookup fast.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "iterator/iter_priv.h"
|
||||||
|
#include "util/regional.h"
|
||||||
|
#include "util/log.h"
|
||||||
|
#include "util/config_file.h"
|
||||||
|
#include "util/data/dname.h"
|
||||||
|
#include "util/net_help.h"
|
||||||
|
#include "util/storage/dnstree.h"
|
||||||
|
|
||||||
|
struct iter_priv* priv_create()
|
||||||
|
{
|
||||||
|
struct iter_priv* priv = (struct iter_priv*)calloc(1, sizeof(*priv));
|
||||||
|
if(!priv)
|
||||||
|
return NULL;
|
||||||
|
priv->region = regional_create();
|
||||||
|
if(!priv->region) {
|
||||||
|
priv_delete(priv);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
addr_tree_init(&priv->a);
|
||||||
|
name_tree_init(&priv->n);
|
||||||
|
return priv;
|
||||||
|
}
|
||||||
|
|
||||||
|
void priv_delete(struct iter_priv* priv)
|
||||||
|
{
|
||||||
|
if(!priv) return;
|
||||||
|
regional_destroy(priv->region);
|
||||||
|
free(priv);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Read private-addr declarations from config */
|
||||||
|
static int read_addrs(struct iter_priv* priv, struct config_file* cfg)
|
||||||
|
{
|
||||||
|
/* parse addresses, report errors, insert into tree */
|
||||||
|
struct config_strlist* p;
|
||||||
|
struct addr_tree_node* n;
|
||||||
|
struct sockaddr_storage addr;
|
||||||
|
int net;
|
||||||
|
socklen_t addrlen;
|
||||||
|
|
||||||
|
for(p = cfg->private_address; p; p = p->next) {
|
||||||
|
log_assert(p->str);
|
||||||
|
if(!netblockstrtoaddr(p->str, UNBOUND_DNS_PORT, &addr,
|
||||||
|
&addrlen, &net)) {
|
||||||
|
log_err("cannot parse private-address: %s", p->str);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
n = (struct addr_tree_node*)regional_alloc(priv->region,
|
||||||
|
sizeof(*n));
|
||||||
|
if(!n) {
|
||||||
|
log_err("out of memory");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(!addr_tree_insert(&priv->a, n, &addr, addrlen, net)) {
|
||||||
|
verbose(VERB_QUERY, "ignoring duplicate "
|
||||||
|
"private-address: %s", p->str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Read private-domain declarations from config */
|
||||||
|
static int read_names(struct iter_priv* priv, struct config_file* cfg)
|
||||||
|
{
|
||||||
|
/* parse names, report errors, insert into tree */
|
||||||
|
struct config_strlist* p;
|
||||||
|
struct name_tree_node* n;
|
||||||
|
uint8_t* nm;
|
||||||
|
size_t nm_len;
|
||||||
|
int nm_labs;
|
||||||
|
ldns_rdf* rdf;
|
||||||
|
|
||||||
|
for(p = cfg->private_address; p; p = p->next) {
|
||||||
|
log_assert(p->str);
|
||||||
|
rdf = ldns_dname_new_frm_str(p->str);
|
||||||
|
if(!rdf) {
|
||||||
|
log_err("cannot parse private-domain: %s", p->str);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
nm = ldns_rdf_data(rdf);
|
||||||
|
nm_labs = dname_count_size_labels(nm, &nm_len);
|
||||||
|
nm = (uint8_t*)regional_alloc_init(priv->region, nm, nm_len);
|
||||||
|
ldns_rdf_deep_free(rdf);
|
||||||
|
if(!nm) {
|
||||||
|
log_err("out of memory");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
n = (struct name_tree_node*)regional_alloc(priv->region,
|
||||||
|
sizeof(*n));
|
||||||
|
if(!n) {
|
||||||
|
log_err("out of memory");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(!name_tree_insert(&priv->n, n, nm, nm_len, nm_labs,
|
||||||
|
LDNS_RR_CLASS_IN)) {
|
||||||
|
verbose(VERB_QUERY, "ignoring duplicate "
|
||||||
|
"private-domain: %s", p->str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int priv_apply_cfg(struct iter_priv* priv, struct config_file* cfg)
|
||||||
|
{
|
||||||
|
/* empty the current contents */
|
||||||
|
regional_free_all(priv->region);
|
||||||
|
addr_tree_init(&priv->a);
|
||||||
|
name_tree_init(&priv->n);
|
||||||
|
|
||||||
|
/* read new contents */
|
||||||
|
if(!read_addrs(priv, cfg))
|
||||||
|
return 0;
|
||||||
|
if(!read_names(priv, cfg))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* prepare for lookups */
|
||||||
|
addr_tree_init_parents(&priv->a);
|
||||||
|
name_tree_init_parents(&priv->n);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int priv_lookup_addr(struct iter_priv* priv, struct sockaddr_storage* addr,
|
||||||
|
socklen_t addrlen)
|
||||||
|
{
|
||||||
|
return addr_tree_lookup(&priv->a, addr, addrlen) != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int priv_lookup_name(struct iter_priv* priv, uint8_t* name, uint16_t dclass)
|
||||||
|
{
|
||||||
|
size_t len;
|
||||||
|
int labs = dname_count_size_labels(name, &len);
|
||||||
|
return name_tree_lookup(&priv->n, name, len, labs, dclass) != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t priv_get_mem(struct iter_priv* priv)
|
||||||
|
{
|
||||||
|
if(!priv) return 0;
|
||||||
|
return sizeof(*priv) + regional_get_mem(priv->region);
|
||||||
|
}
|
||||||
117
iterator/iter_priv.h
Normal file
117
iterator/iter_priv.h
Normal file
|
|
@ -0,0 +1,117 @@
|
||||||
|
/*
|
||||||
|
* iterator/iter_priv.h - iterative resolver private address and domain store
|
||||||
|
*
|
||||||
|
* Copyright (c) 2008, NLnet Labs. All rights reserved.
|
||||||
|
*
|
||||||
|
* This software is open source.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of the NLNET LABS nor the names of its contributors may
|
||||||
|
* be used to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file
|
||||||
|
*
|
||||||
|
* This file contains functions to assist the iterator module.
|
||||||
|
* Keep track of the private addresses and lookup fast.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ITERATOR_ITER_PRIV_H
|
||||||
|
#define ITERATOR_ITER_PRIV_H
|
||||||
|
#include "util/rbtree.h"
|
||||||
|
struct iter_env;
|
||||||
|
struct config_file;
|
||||||
|
struct regional;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Iterator priv structure
|
||||||
|
*/
|
||||||
|
struct iter_priv {
|
||||||
|
/** regional for allocation */
|
||||||
|
struct regional* region;
|
||||||
|
/**
|
||||||
|
* Tree of the address spans that are blocked.
|
||||||
|
* contents of type addr_tree_node.
|
||||||
|
* No further data need, only presence or absence.
|
||||||
|
*/
|
||||||
|
rbtree_t a;
|
||||||
|
/**
|
||||||
|
* Tree of the domains spans that are allowed to contain
|
||||||
|
* the blocked address spans.
|
||||||
|
* contents of type name_tree_node.
|
||||||
|
* No further data need, only presence or absence.
|
||||||
|
*/
|
||||||
|
rbtree_t n;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create priv structure
|
||||||
|
* @return new structure or NULL on error.
|
||||||
|
*/
|
||||||
|
struct iter_priv* priv_create();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete priv structure.
|
||||||
|
* @param priv: to delete.
|
||||||
|
*/
|
||||||
|
void priv_delete(struct iter_priv* priv);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process priv config.
|
||||||
|
* @param priv: where to store.
|
||||||
|
* @param cfg: config options.
|
||||||
|
* @return 0 on error.
|
||||||
|
*/
|
||||||
|
int priv_apply_cfg(struct iter_priv* priv, struct config_file* cfg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See if an address is blocked.
|
||||||
|
* @param priv: structure for address storage.
|
||||||
|
* @param addr: address to check
|
||||||
|
* @param addrlen: length of addr.
|
||||||
|
* @return: true if the address must not be queried. false if unlisted.
|
||||||
|
*/
|
||||||
|
int priv_lookup_addr(struct iter_priv* priv, struct sockaddr_storage* addr,
|
||||||
|
socklen_t addrlen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See if a name is whitelisted.
|
||||||
|
* @param priv: structure for address storage.
|
||||||
|
* @param name: name to check.
|
||||||
|
* @param dclass: class to check.
|
||||||
|
* @return: true if the name is OK. false if unlisted.
|
||||||
|
*/
|
||||||
|
int priv_lookup_name(struct iter_priv* priv, uint8_t* name, uint16_t dclass);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get memory used by priv structure.
|
||||||
|
* @param priv: structure for address storage.
|
||||||
|
* @return bytes in use.
|
||||||
|
*/
|
||||||
|
size_t priv_get_mem(struct iter_priv* priv);
|
||||||
|
|
||||||
|
#endif /* ITERATOR_ITER_PRIV_H */
|
||||||
|
|
@ -46,6 +46,7 @@
|
||||||
#include "iterator/iter_fwd.h"
|
#include "iterator/iter_fwd.h"
|
||||||
#include "iterator/iter_donotq.h"
|
#include "iterator/iter_donotq.h"
|
||||||
#include "iterator/iter_delegpt.h"
|
#include "iterator/iter_delegpt.h"
|
||||||
|
#include "iterator/iter_priv.h"
|
||||||
#include "services/cache/infra.h"
|
#include "services/cache/infra.h"
|
||||||
#include "services/cache/dns.h"
|
#include "services/cache/dns.h"
|
||||||
#include "services/cache/rrset.h"
|
#include "services/cache/rrset.h"
|
||||||
|
|
@ -123,6 +124,12 @@ iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg)
|
||||||
log_err("Could not set donotqueryaddresses");
|
log_err("Could not set donotqueryaddresses");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if(!iter_env->priv)
|
||||||
|
iter_env->priv = priv_create();
|
||||||
|
if(!iter_env->priv || !priv_apply_cfg(iter_env->priv, cfg)) {
|
||||||
|
log_err("Could not set private addresses");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
iter_env->supports_ipv6 = cfg->do_ip6;
|
iter_env->supports_ipv6 = cfg->do_ip6;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ struct iter_hints;
|
||||||
struct iter_forwards;
|
struct iter_forwards;
|
||||||
struct iter_donotq;
|
struct iter_donotq;
|
||||||
struct iter_prep_list;
|
struct iter_prep_list;
|
||||||
|
struct iter_priv;
|
||||||
|
|
||||||
/** max number of query restarts. Determines max number of CNAME chain. */
|
/** max number of query restarts. Determines max number of CNAME chain. */
|
||||||
#define MAX_RESTART_COUNT 8
|
#define MAX_RESTART_COUNT 8
|
||||||
|
|
@ -92,6 +93,9 @@ struct iter_env {
|
||||||
/** A set of inetaddrs that should never be queried. */
|
/** A set of inetaddrs that should never be queried. */
|
||||||
struct iter_donotq* donotq;
|
struct iter_donotq* donotq;
|
||||||
|
|
||||||
|
/** private address space and private domains */
|
||||||
|
struct iter_priv* priv;
|
||||||
|
|
||||||
/** The maximum dependency depth that this resolver will pursue. */
|
/** The maximum dependency depth that this resolver will pursue. */
|
||||||
int max_dependency_depth;
|
int max_dependency_depth;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -131,6 +131,8 @@ config_create()
|
||||||
cfg->harden_dnssec_stripped = 1;
|
cfg->harden_dnssec_stripped = 1;
|
||||||
cfg->harden_referral_path = 0;
|
cfg->harden_referral_path = 0;
|
||||||
cfg->use_caps_bits_for_id = 0;
|
cfg->use_caps_bits_for_id = 0;
|
||||||
|
cfg->private_address = NULL;
|
||||||
|
cfg->private_domain = NULL;
|
||||||
cfg->hide_identity = 0;
|
cfg->hide_identity = 0;
|
||||||
cfg->hide_version = 0;
|
cfg->hide_version = 0;
|
||||||
cfg->identity = NULL;
|
cfg->identity = NULL;
|
||||||
|
|
@ -295,6 +297,13 @@ int config_set_option(struct config_file* cfg, const char* opt,
|
||||||
} else if(strcmp(opt, "harden-dnssec-stripped:") == 0) {
|
} else if(strcmp(opt, "harden-dnssec-stripped:") == 0) {
|
||||||
IS_YES_OR_NO;
|
IS_YES_OR_NO;
|
||||||
cfg->harden_dnssec_stripped = (strcmp(val, "yes") == 0);
|
cfg->harden_dnssec_stripped = (strcmp(val, "yes") == 0);
|
||||||
|
} else if(strcmp(opt, "harden-referral-path:") == 0) {
|
||||||
|
IS_YES_OR_NO;
|
||||||
|
cfg->harden_referral_path = (strcmp(val, "yes") == 0);
|
||||||
|
} else if(strcmp(opt, "private-address:") == 0) {
|
||||||
|
return cfg_strlist_insert(&cfg->private_address, strdup(val));
|
||||||
|
} else if(strcmp(opt, "private-domain:") == 0) {
|
||||||
|
return cfg_strlist_insert(&cfg->private_domain, strdup(val));
|
||||||
} else if(strcmp(opt, "do-not-query-localhost:") == 0) {
|
} else if(strcmp(opt, "do-not-query-localhost:") == 0) {
|
||||||
IS_YES_OR_NO;
|
IS_YES_OR_NO;
|
||||||
cfg->donotquery_localhost = (strcmp(val, "yes") == 0);
|
cfg->donotquery_localhost = (strcmp(val, "yes") == 0);
|
||||||
|
|
@ -462,6 +471,8 @@ config_delete(struct config_file* cfg)
|
||||||
free(cfg->version);
|
free(cfg->version);
|
||||||
free(cfg->module_conf);
|
free(cfg->module_conf);
|
||||||
free(cfg->outgoing_avail_ports);
|
free(cfg->outgoing_avail_ports);
|
||||||
|
config_delstrlist(cfg->private_address);
|
||||||
|
config_delstrlist(cfg->private_domain);
|
||||||
config_delstrlist(cfg->trust_anchor_file_list);
|
config_delstrlist(cfg->trust_anchor_file_list);
|
||||||
config_delstrlist(cfg->trusted_keys_file_list);
|
config_delstrlist(cfg->trusted_keys_file_list);
|
||||||
config_delstrlist(cfg->trust_anchor_list);
|
config_delstrlist(cfg->trust_anchor_list);
|
||||||
|
|
|
||||||
|
|
@ -147,6 +147,10 @@ struct config_file {
|
||||||
int harden_referral_path;
|
int harden_referral_path;
|
||||||
/** use 0x20 bits in query as random ID bits */
|
/** use 0x20 bits in query as random ID bits */
|
||||||
int use_caps_bits_for_id;
|
int use_caps_bits_for_id;
|
||||||
|
/** strip away these private addrs from answers, no DNS Rebinding */
|
||||||
|
struct config_strlist* private_address;
|
||||||
|
/** allow domain (and subdomains) to use private address space */
|
||||||
|
struct config_strlist* private_domain;
|
||||||
|
|
||||||
/** chrootdir, if not "" or chroot will be done */
|
/** chrootdir, if not "" or chroot will be done */
|
||||||
char* chrootdir;
|
char* chrootdir;
|
||||||
|
|
|
||||||
1435
util/configlexer.c
1435
util/configlexer.c
File diff suppressed because it is too large
Load diff
|
|
@ -149,6 +149,8 @@ harden-glue{COLON} { YDOUT; return VAR_HARDEN_GLUE;}
|
||||||
harden-dnssec-stripped{COLON} { YDOUT; return VAR_HARDEN_DNNSEC_STRIPPED;}
|
harden-dnssec-stripped{COLON} { YDOUT; return VAR_HARDEN_DNNSEC_STRIPPED;}
|
||||||
harden-referral-path{COLON} { YDOUT; return VAR_HARDEN_REFERRAL_PATH;}
|
harden-referral-path{COLON} { YDOUT; return VAR_HARDEN_REFERRAL_PATH;}
|
||||||
use-caps-for-id{COLON} { YDOUT; return VAR_USE_CAPS_FOR_ID;}
|
use-caps-for-id{COLON} { YDOUT; return VAR_USE_CAPS_FOR_ID;}
|
||||||
|
private-address{COLON} { YDOUT; return VAR_PRIVATE_ADDRESS;}
|
||||||
|
private-domain{COLON} { YDOUT; return VAR_PRIVATE_DOMAIN;}
|
||||||
stub-zone{COLON} { YDOUT; return VAR_STUB_ZONE;}
|
stub-zone{COLON} { YDOUT; return VAR_STUB_ZONE;}
|
||||||
name{COLON} { YDOUT; return VAR_NAME;}
|
name{COLON} { YDOUT; return VAR_NAME;}
|
||||||
stub-addr{COLON} { YDOUT; return VAR_STUB_ADDR;}
|
stub-addr{COLON} { YDOUT; return VAR_STUB_ADDR;}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -121,7 +121,9 @@
|
||||||
VAR_DLV_ANCHOR_FILE = 337,
|
VAR_DLV_ANCHOR_FILE = 337,
|
||||||
VAR_DLV_ANCHOR = 338,
|
VAR_DLV_ANCHOR = 338,
|
||||||
VAR_NEG_CACHE_SIZE = 339,
|
VAR_NEG_CACHE_SIZE = 339,
|
||||||
VAR_HARDEN_REFERRAL_PATH = 340
|
VAR_HARDEN_REFERRAL_PATH = 340,
|
||||||
|
VAR_PRIVATE_ADDRESS = 341,
|
||||||
|
VAR_PRIVATE_DOMAIN = 342
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
/* Tokens. */
|
/* Tokens. */
|
||||||
|
|
@ -208,6 +210,8 @@
|
||||||
#define VAR_DLV_ANCHOR 338
|
#define VAR_DLV_ANCHOR 338
|
||||||
#define VAR_NEG_CACHE_SIZE 339
|
#define VAR_NEG_CACHE_SIZE 339
|
||||||
#define VAR_HARDEN_REFERRAL_PATH 340
|
#define VAR_HARDEN_REFERRAL_PATH 340
|
||||||
|
#define VAR_PRIVATE_ADDRESS 341
|
||||||
|
#define VAR_PRIVATE_DOMAIN 342
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -219,7 +223,7 @@ typedef union YYSTYPE
|
||||||
char* str;
|
char* str;
|
||||||
}
|
}
|
||||||
/* Line 1489 of yacc.c. */
|
/* Line 1489 of yacc.c. */
|
||||||
#line 223 "util/configparser.h"
|
#line 227 "util/configparser.h"
|
||||||
YYSTYPE;
|
YYSTYPE;
|
||||||
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
||||||
# define YYSTYPE_IS_DECLARED 1
|
# define YYSTYPE_IS_DECLARED 1
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,8 @@ extern struct config_parser_state* cfg_parser;
|
||||||
%token VAR_STATISTICS_INTERVAL VAR_DO_DAEMONIZE VAR_USE_CAPS_FOR_ID
|
%token VAR_STATISTICS_INTERVAL VAR_DO_DAEMONIZE VAR_USE_CAPS_FOR_ID
|
||||||
%token VAR_STATISTICS_CUMULATIVE VAR_OUTGOING_PORT_PERMIT
|
%token VAR_STATISTICS_CUMULATIVE VAR_OUTGOING_PORT_PERMIT
|
||||||
%token VAR_OUTGOING_PORT_AVOID VAR_DLV_ANCHOR_FILE VAR_DLV_ANCHOR
|
%token VAR_OUTGOING_PORT_AVOID VAR_DLV_ANCHOR_FILE VAR_DLV_ANCHOR
|
||||||
%token VAR_NEG_CACHE_SIZE VAR_HARDEN_REFERRAL_PATH
|
%token VAR_NEG_CACHE_SIZE VAR_HARDEN_REFERRAL_PATH VAR_PRIVATE_ADDRESS
|
||||||
|
%token VAR_PRIVATE_DOMAIN
|
||||||
|
|
||||||
%%
|
%%
|
||||||
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
|
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
|
||||||
|
|
@ -135,7 +136,8 @@ content_server: server_num_threads | server_verbosity | server_port |
|
||||||
server_use_caps_for_id | server_statistics_cumulative |
|
server_use_caps_for_id | server_statistics_cumulative |
|
||||||
server_outgoing_port_permit | server_outgoing_port_avoid |
|
server_outgoing_port_permit | server_outgoing_port_avoid |
|
||||||
server_dlv_anchor_file | server_dlv_anchor | server_neg_cache_size |
|
server_dlv_anchor_file | server_dlv_anchor | server_neg_cache_size |
|
||||||
server_harden_referral_path
|
server_harden_referral_path | server_private_address |
|
||||||
|
server_private_domain
|
||||||
;
|
;
|
||||||
stubstart: VAR_STUB_ZONE
|
stubstart: VAR_STUB_ZONE
|
||||||
{
|
{
|
||||||
|
|
@ -647,6 +649,20 @@ server_use_caps_for_id: VAR_USE_CAPS_FOR_ID STRING
|
||||||
free($2);
|
free($2);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
server_private_address: VAR_PRIVATE_ADDRESS STRING
|
||||||
|
{
|
||||||
|
OUTYY(("P(server_private_address:%s)\n", $2));
|
||||||
|
if(!cfg_strlist_insert(&cfg_parser->cfg->private_address, $2))
|
||||||
|
yyerror("out of memory");
|
||||||
|
}
|
||||||
|
;
|
||||||
|
server_private_domain: VAR_PRIVATE_DOMAIN STRING
|
||||||
|
{
|
||||||
|
OUTYY(("P(server_private_domain:%s)\n", $2));
|
||||||
|
if(!cfg_strlist_insert(&cfg_parser->cfg->private_domain, $2))
|
||||||
|
yyerror("out of memory");
|
||||||
|
}
|
||||||
|
;
|
||||||
server_do_not_query_address: VAR_DO_NOT_QUERY_ADDRESS STRING
|
server_do_not_query_address: VAR_DO_NOT_QUERY_ADDRESS STRING
|
||||||
{
|
{
|
||||||
OUTYY(("P(server_do_not_query_address:%s)\n", $2));
|
OUTYY(("P(server_do_not_query_address:%s)\n", $2));
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,7 @@
|
||||||
#include "util/data/msgreply.h"
|
#include "util/data/msgreply.h"
|
||||||
#include "util/data/packed_rrset.h"
|
#include "util/data/packed_rrset.h"
|
||||||
#include "util/storage/slabhash.h"
|
#include "util/storage/slabhash.h"
|
||||||
|
#include "util/storage/dnstree.h"
|
||||||
#include "util/locks.h"
|
#include "util/locks.h"
|
||||||
#include "daemon/acl_list.h"
|
#include "daemon/acl_list.h"
|
||||||
#include "libunbound/libworker.h"
|
#include "libunbound/libworker.h"
|
||||||
|
|
@ -159,6 +160,8 @@ fptr_whitelist_rbtree_cmp(int (*fptr) (const void *, const void *))
|
||||||
else if(fptr == &stub_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 == &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;
|
||||||
|
|
|
||||||
230
util/storage/dnstree.c
Normal file
230
util/storage/dnstree.c
Normal file
|
|
@ -0,0 +1,230 @@
|
||||||
|
/*
|
||||||
|
* util/storage/dnstree.c - support for rbtree types suitable for DNS code.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2008, NLnet Labs. All rights reserved.
|
||||||
|
*
|
||||||
|
* This software is open source.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of the NLNET LABS nor the names of its contributors may
|
||||||
|
* be used to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file
|
||||||
|
*
|
||||||
|
* This file contains structures combining types and functions to
|
||||||
|
* manipulate those structures that help building DNS lookup trees.
|
||||||
|
*/
|
||||||
|
#include "config.h"
|
||||||
|
#include "util/storage/dnstree.h"
|
||||||
|
#include "util/data/dname.h"
|
||||||
|
#include "util/net_help.h"
|
||||||
|
|
||||||
|
int name_tree_compare(const void* k1, const void* k2)
|
||||||
|
{
|
||||||
|
struct name_tree_node* x = (struct name_tree_node*)k1;
|
||||||
|
struct name_tree_node* y = (struct name_tree_node*)k2;
|
||||||
|
int m;
|
||||||
|
if(x->dclass != y->dclass) {
|
||||||
|
if(x->dclass < y->dclass)
|
||||||
|
return -1;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return dname_canon_lab_cmp(x->name, x->labs, y->name, y->labs, &m);
|
||||||
|
}
|
||||||
|
|
||||||
|
int addr_tree_compare(const void* k1, const void* k2)
|
||||||
|
{
|
||||||
|
struct addr_tree_node* n1 = (struct addr_tree_node*)k1;
|
||||||
|
struct addr_tree_node* n2 = (struct addr_tree_node*)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;
|
||||||
|
}
|
||||||
|
|
||||||
|
void name_tree_init(rbtree_t* tree)
|
||||||
|
{
|
||||||
|
rbtree_init(tree, &name_tree_compare);
|
||||||
|
}
|
||||||
|
|
||||||
|
void addr_tree_init(rbtree_t* tree)
|
||||||
|
{
|
||||||
|
rbtree_init(tree, &addr_tree_compare);
|
||||||
|
}
|
||||||
|
|
||||||
|
int name_tree_insert(rbtree_t* tree, struct name_tree_node* node,
|
||||||
|
uint8_t* name, size_t len, int labs, uint16_t dclass)
|
||||||
|
{
|
||||||
|
node->node.key = node;
|
||||||
|
node->name = name;
|
||||||
|
node->len = len;
|
||||||
|
node->labs = labs;
|
||||||
|
node->dclass = dclass;
|
||||||
|
return rbtree_insert(tree, &node->node) != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int addr_tree_insert(rbtree_t* tree, struct addr_tree_node* node,
|
||||||
|
struct sockaddr_storage* addr, socklen_t addrlen, int net)
|
||||||
|
{
|
||||||
|
node->node.key = node;
|
||||||
|
memcpy(&node->addr, addr, addrlen);
|
||||||
|
node->addrlen = addrlen;
|
||||||
|
node->net = net;
|
||||||
|
return rbtree_insert(tree, &node->node) != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addr_tree_init_parents(rbtree_t* tree)
|
||||||
|
{
|
||||||
|
struct addr_tree_node* node, *prev = NULL, *p;
|
||||||
|
int m;
|
||||||
|
RBTREE_FOR(node, struct addr_tree_node*, 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void name_tree_init_parents(rbtree_t* tree)
|
||||||
|
{
|
||||||
|
struct name_tree_node* node, *prev = NULL, *p;
|
||||||
|
int m;
|
||||||
|
RBTREE_FOR(node, struct name_tree_node*, tree) {
|
||||||
|
node->parent = NULL;
|
||||||
|
if(!prev || prev->dclass != node->dclass) {
|
||||||
|
prev = node;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
(void)dname_lab_cmp(prev->name, prev->labs, node->name,
|
||||||
|
node->labs, &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)
|
||||||
|
if(p->labs <= 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct name_tree_node* name_tree_find(rbtree_t* tree, uint8_t* name,
|
||||||
|
size_t len, int labs, uint16_t dclass)
|
||||||
|
{
|
||||||
|
struct name_tree_node key;
|
||||||
|
key.node.key = &key;
|
||||||
|
key.name = name;
|
||||||
|
key.len = len;
|
||||||
|
key.labs = labs;
|
||||||
|
key.dclass = dclass;
|
||||||
|
return (struct name_tree_node*)rbtree_search(tree, &key);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct name_tree_node* name_tree_lookup(rbtree_t* tree, uint8_t* name,
|
||||||
|
size_t len, int labs, uint16_t dclass)
|
||||||
|
{
|
||||||
|
rbnode_t* res = NULL;
|
||||||
|
struct name_tree_node *result;
|
||||||
|
struct name_tree_node key;
|
||||||
|
key.node.key = &key;
|
||||||
|
key.name = name;
|
||||||
|
key.len = len;
|
||||||
|
key.labs = labs;
|
||||||
|
key.dclass = dclass;
|
||||||
|
if(rbtree_find_less_equal(tree, &key, &res)) {
|
||||||
|
/* exact */
|
||||||
|
result = (struct name_tree_node*)res;
|
||||||
|
} else {
|
||||||
|
/* smaller element (or no element) */
|
||||||
|
int m;
|
||||||
|
result = (struct name_tree_node*)res;
|
||||||
|
if(!result || result->dclass != dclass)
|
||||||
|
return NULL;
|
||||||
|
/* count number of labels matched */
|
||||||
|
(void)dname_lab_cmp(result->name, result->labs, key.name,
|
||||||
|
key.labs, &m);
|
||||||
|
while(result) { /* go up until qname is subdomain of stub */
|
||||||
|
if(result->labs <= m)
|
||||||
|
break;
|
||||||
|
result = result->parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct addr_tree_node* addr_tree_lookup(rbtree_t* tree,
|
||||||
|
struct sockaddr_storage* addr, socklen_t addrlen)
|
||||||
|
{
|
||||||
|
rbnode_t* res = NULL;
|
||||||
|
struct addr_tree_node* result;
|
||||||
|
struct addr_tree_node 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(tree, &key, &res)) {
|
||||||
|
/* exact */
|
||||||
|
return (struct addr_tree_node*)res;
|
||||||
|
} else {
|
||||||
|
/* smaller element (or no element) */
|
||||||
|
int m;
|
||||||
|
result = (struct addr_tree_node*)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)
|
||||||
|
break;
|
||||||
|
result = result->parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
184
util/storage/dnstree.h
Normal file
184
util/storage/dnstree.h
Normal file
|
|
@ -0,0 +1,184 @@
|
||||||
|
/*
|
||||||
|
* util/storage/dnstree.h - support for rbtree types suitable for DNS code.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2008, NLnet Labs. All rights reserved.
|
||||||
|
*
|
||||||
|
* This software is open source.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of the NLNET LABS nor the names of its contributors may
|
||||||
|
* be used to endorse or promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file
|
||||||
|
*
|
||||||
|
* This file contains structures combining types and functions to
|
||||||
|
* manipulate those structures that help building DNS lookup trees.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef UTIL_STORAGE_DNSTREE_H
|
||||||
|
#define UTIL_STORAGE_DNSTREE_H
|
||||||
|
#include "util/rbtree.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tree of domain names. Sorted first by class then by name.
|
||||||
|
* This is not sorted canonically, but fast.
|
||||||
|
* This can be looked up to obtain a closest encloser parent name.
|
||||||
|
*
|
||||||
|
* The tree itself is a rbtree_t.
|
||||||
|
* This is the element node put as first entry in the client structure.
|
||||||
|
*/
|
||||||
|
struct name_tree_node {
|
||||||
|
/** rbtree node, key is this struct : dclass and name */
|
||||||
|
rbnode_t node;
|
||||||
|
/** parent in tree */
|
||||||
|
struct name_tree_node* parent;
|
||||||
|
/** name in uncompressed wireformat */
|
||||||
|
uint8_t* name;
|
||||||
|
/** length of name */
|
||||||
|
size_t len;
|
||||||
|
/** labels in name */
|
||||||
|
int labs;
|
||||||
|
/** the class of the name (host order) */
|
||||||
|
uint16_t dclass;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tree of IP addresses. Sorted first by protocol, then by bits.
|
||||||
|
* This can be looked up to obtain the enclosing subnet.
|
||||||
|
*
|
||||||
|
* The tree itself is a rbtree_t.
|
||||||
|
* This is the element node put as first entry in the client structure.
|
||||||
|
*/
|
||||||
|
struct addr_tree_node {
|
||||||
|
/** rbtree node, key is this struct : proto and subnet */
|
||||||
|
rbnode_t node;
|
||||||
|
/** parent in tree */
|
||||||
|
struct addr_tree_node* parent;
|
||||||
|
/** address */
|
||||||
|
struct sockaddr_storage addr;
|
||||||
|
/** length of addr */
|
||||||
|
socklen_t addrlen;
|
||||||
|
/** netblock size */
|
||||||
|
int net;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Init a name tree to be empty
|
||||||
|
* @param tree: to init.
|
||||||
|
*/
|
||||||
|
void name_tree_init(rbtree_t* tree);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* insert element into name tree.
|
||||||
|
* @param tree: name tree
|
||||||
|
* @param node: node element (at start of a structure that caller
|
||||||
|
* has allocated).
|
||||||
|
* @param name: name to insert (wireformat)
|
||||||
|
* this node has been allocated by the caller and it itself inserted.
|
||||||
|
* @param len: length of name
|
||||||
|
* @param labs: labels in name
|
||||||
|
* @param dclass: class of name
|
||||||
|
* @return false on error (duplicate element).
|
||||||
|
*/
|
||||||
|
int name_tree_insert(rbtree_t* tree, struct name_tree_node* node,
|
||||||
|
uint8_t* name, size_t len, int labs, uint16_t dclass);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize parent pointers in name tree.
|
||||||
|
* Should be performed after insertions are done, before lookups
|
||||||
|
* @param tree: name tree
|
||||||
|
*/
|
||||||
|
void name_tree_init_parents(rbtree_t* tree);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lookup exact match in name tree
|
||||||
|
* @param tree: name tree
|
||||||
|
* @param name: wireformat name
|
||||||
|
* @param len: length of name
|
||||||
|
* @param labs: labels in name
|
||||||
|
* @param dclass: class of name
|
||||||
|
* @return node or NULL if not found.
|
||||||
|
*/
|
||||||
|
struct name_tree_node* name_tree_find(rbtree_t* tree, uint8_t* name,
|
||||||
|
size_t len, int labs, uint16_t dclass);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lookup closest encloser in name tree.
|
||||||
|
* @param tree: name tree
|
||||||
|
* @param name: wireformat name
|
||||||
|
* @param len: length of name
|
||||||
|
* @param labs: labels in name
|
||||||
|
* @param dclass: class of name
|
||||||
|
* @return closest enclosing node (could be equal) or NULL if not found.
|
||||||
|
*/
|
||||||
|
struct name_tree_node* name_tree_lookup(rbtree_t* tree, uint8_t* name,
|
||||||
|
size_t len, int labs, uint16_t dclass);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Init addr tree to be empty.
|
||||||
|
* @param tree: to init.
|
||||||
|
*/
|
||||||
|
void addr_tree_init(rbtree_t* tree);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* insert element into addr tree.
|
||||||
|
* @param tree: addr tree
|
||||||
|
* @param node: node element (at start of a structure that caller
|
||||||
|
* has allocated).
|
||||||
|
* @param addr: to insert (copied).
|
||||||
|
* @param addrlen: length of addr
|
||||||
|
* @param net: size of subnet.
|
||||||
|
* @return false on error (duplicate element).
|
||||||
|
*/
|
||||||
|
int addr_tree_insert(rbtree_t* tree, struct addr_tree_node* node,
|
||||||
|
struct sockaddr_storage* addr, socklen_t addrlen, int net);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize parent pointers in addr tree.
|
||||||
|
* Should be performed after insertions are done, before lookups
|
||||||
|
* @param tree: addr tree
|
||||||
|
*/
|
||||||
|
void addr_tree_init_parents(rbtree_t* tree);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lookup closest encloser in addr tree.
|
||||||
|
* @param tree: addr tree
|
||||||
|
* @param addr: to lookup.
|
||||||
|
* @param addrlen: length of addr
|
||||||
|
* @return closest enclosing node (could be equal) or NULL if not found.
|
||||||
|
*/
|
||||||
|
struct addr_tree_node* addr_tree_lookup(rbtree_t* tree,
|
||||||
|
struct sockaddr_storage* addr, socklen_t addrlen);
|
||||||
|
|
||||||
|
/** compare name tree nodes */
|
||||||
|
int name_tree_compare(const void* k1, const void* k2);
|
||||||
|
|
||||||
|
/** compare addr tree nodes */
|
||||||
|
int addr_tree_compare(const void* k1, const void* k2);
|
||||||
|
|
||||||
|
#endif /* UTIL_STORAGE_DNSTREE_H */
|
||||||
Loading…
Reference in a new issue