mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
Do not query addresses and configuration.
git-svn-id: file:///svn/unbound/trunk@434 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
9db3f47b98
commit
0b9807d677
18 changed files with 386 additions and 84 deletions
|
|
@ -1,3 +1,6 @@
|
|||
18 July 2007: Wouter
|
||||
- do not query addresses, 127.0.0.1, and ::1 by default.
|
||||
|
||||
17 July 2007: Wouter
|
||||
- forward zone options in config file.
|
||||
- forward per zone in iterator. takes precendence over stubs.
|
||||
|
|
|
|||
1
doc/TODO
1
doc/TODO
|
|
@ -24,3 +24,4 @@ o understand NSEC/NSEC3, aggressive negative caching, so that updates to
|
|||
o fallback without EDNS if result is NOTIMPL, now only on FORMERR like in java.
|
||||
o scrubber has slow pkt_subdomain and pkt_strict_subdomain functions.
|
||||
o get serverselection algorithm out of local optimum.
|
||||
o donotqueryaddresses allow specification of subnets, use trie to store.
|
||||
|
|
|
|||
|
|
@ -122,10 +122,16 @@ server:
|
|||
# target-fetch-policy: "3 2 1 0 0"
|
||||
|
||||
# Harden against very small EDNS buffer sizes.
|
||||
# harden_short_bufsize: no
|
||||
# harden-short-bufsize: no
|
||||
|
||||
# Harden against unseemly large queries.
|
||||
# harden_large_queries: no
|
||||
# harden-large-queries: no
|
||||
|
||||
# Do not query the following addresses. No DNS queries are sent there.
|
||||
# List one address per entry. To block other ports than the default
|
||||
# DNS port, use "1.2.3.4@123" to block port 123 for 1.2.3.4.
|
||||
# do-not-query-address: 127.0.0.1
|
||||
# do-not-query-address: ::1
|
||||
|
||||
# Stub zones.
|
||||
# Create entries like below, to make all queries for 'example.com' and
|
||||
|
|
|
|||
|
|
@ -136,6 +136,10 @@ small answers to these queries, where possible.
|
|||
Very large queries are ignored. Default is off, since it is legal protocol
|
||||
wise to send these, and could be necessary for operation if TSIG or EDNS
|
||||
payload is very large.
|
||||
.It \fBdo-not-query-address:\fR <IP address>
|
||||
Do not query the given IP address. Can be IP4 or IP6. By default the
|
||||
DNS port is blocked for that address. Appending "@portnumber" will block
|
||||
other port numbers.
|
||||
.El
|
||||
|
||||
.Ss Stub Zone Options
|
||||
|
|
|
|||
149
iterator/iter_donotq.c
Normal file
149
iterator/iter_donotq.c
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
* iterator/iter_donotq.c - iterative resolver donotqueryaddresses storage.
|
||||
*
|
||||
* Copyright (c) 2007, 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.
|
||||
* The donotqueryaddresses are stored and looked up. These addresses
|
||||
* (like 127.0.0.1) must not be used to send queries to, and can be
|
||||
* discarded immediately from the server selection.
|
||||
*/
|
||||
#include "config.h"
|
||||
#include "iterator/iter_donotq.h"
|
||||
#include "util/region-allocator.h"
|
||||
#include "util/log.h"
|
||||
#include "util/config_file.h"
|
||||
#include "util/net_help.h"
|
||||
|
||||
/** compare two donotq entries */
|
||||
static 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;
|
||||
return sockaddr_cmp(&n1->addr, n1->addrlen, &n2->addr, n2->addrlen);
|
||||
}
|
||||
|
||||
struct iter_donotq*
|
||||
donotq_create()
|
||||
{
|
||||
struct iter_donotq* dq = (struct iter_donotq*)calloc(1,
|
||||
sizeof(struct iter_donotq));
|
||||
if(!dq)
|
||||
return NULL;
|
||||
dq->region = region_create(malloc, free);
|
||||
if(!dq->region) {
|
||||
donotq_delete(dq);
|
||||
return NULL;
|
||||
}
|
||||
return dq;
|
||||
}
|
||||
|
||||
void
|
||||
donotq_delete(struct iter_donotq* dq)
|
||||
{
|
||||
if(!dq)
|
||||
return;
|
||||
region_destroy(dq->region);
|
||||
free(dq->tree);
|
||||
free(dq);
|
||||
}
|
||||
|
||||
/** insert new address into donotq structure */
|
||||
static int
|
||||
donotq_insert(struct iter_donotq* dq, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen)
|
||||
{
|
||||
struct iter_donotq_addr* node = region_alloc(dq->region,
|
||||
sizeof(struct iter_donotq_addr));
|
||||
if(!node)
|
||||
return 0;
|
||||
node->node.key = node;
|
||||
memcpy(&node->addr, addr, addrlen);
|
||||
node->addrlen = addrlen;
|
||||
if(!rbtree_insert(dq->tree, &node->node)) {
|
||||
log_warn("duplicate donotquery address ignored.");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** read donotq config */
|
||||
static int
|
||||
read_donotq(struct iter_donotq* dq, struct config_file* cfg)
|
||||
{
|
||||
struct config_strlist* p;
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addrlen;
|
||||
for(p = cfg->donotqueryaddrs; p; p = p->next) {
|
||||
log_assert(p->str);
|
||||
if(!extstrtoaddr(p->str, &addr, &addrlen)) {
|
||||
log_err("cannot parse donotquery ip address: '%s'",
|
||||
p->str);
|
||||
return 0;
|
||||
}
|
||||
if(!donotq_insert(dq, &addr, addrlen)) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
donotq_apply_cfg(struct iter_donotq* dq, struct config_file* cfg)
|
||||
{
|
||||
free(dq->tree);
|
||||
dq->tree = rbtree_create(donotq_cmp);
|
||||
if(!dq->tree)
|
||||
return 0;
|
||||
if(!read_donotq(dq, cfg))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
donotq_lookup(struct iter_donotq* donotq, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen)
|
||||
{
|
||||
/* lookup in the tree */
|
||||
struct iter_donotq_addr key;
|
||||
key.node.key = &key;
|
||||
memcpy(&key.addr, addr, addrlen);
|
||||
key.addrlen = addrlen;
|
||||
if(rbtree_search(donotq->tree, &key))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
106
iterator/iter_donotq.h
Normal file
106
iterator/iter_donotq.h
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* iterator/iter_donotq.h - iterative resolver donotqueryaddresses storage.
|
||||
*
|
||||
* Copyright (c) 2007, 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 donotquery addresses and lookup fast.
|
||||
*/
|
||||
|
||||
#ifndef ITERATOR_ITER_DONOTQ_H
|
||||
#define ITERATOR_ITER_DONOTQ_H
|
||||
#include "util/rbtree.h"
|
||||
struct iter_env;
|
||||
struct config_file;
|
||||
struct region;
|
||||
|
||||
/**
|
||||
* Iterator donotqueryaddresses structure
|
||||
*/
|
||||
struct iter_donotq {
|
||||
/** region for allocation */
|
||||
struct region* region;
|
||||
/**
|
||||
* Tree of the single addresses that are blocked.
|
||||
* contents of type iter_donotq_addr.
|
||||
*/
|
||||
rbtree_t* tree;
|
||||
};
|
||||
|
||||
/**
|
||||
* Iterator donotquery address.
|
||||
* A single address that must not be used to send queries to.
|
||||
*/
|
||||
struct iter_donotq_addr {
|
||||
/** redblacktree node, key is this structure: addr and addrlen */
|
||||
rbnode_t node;
|
||||
/** address */
|
||||
struct sockaddr_storage addr;
|
||||
/** length of addr */
|
||||
socklen_t addrlen;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create donotqueryaddresses structure
|
||||
* @return new structure or NULL on error.
|
||||
*/
|
||||
struct iter_donotq* donotq_create();
|
||||
|
||||
/**
|
||||
* Delete donotqueryaddresses structure.
|
||||
* @param donotq: to delete.
|
||||
*/
|
||||
void donotq_delete(struct iter_donotq* donotq);
|
||||
|
||||
/**
|
||||
* Process donotqueryaddresses config.
|
||||
* @param donotq: where to store.
|
||||
* @param cfg: config options.
|
||||
* @return 0 on error.
|
||||
*/
|
||||
int donotq_apply_cfg(struct iter_donotq* donotq, struct config_file* cfg);
|
||||
|
||||
/**
|
||||
* See if an address is blocked.
|
||||
* @param donotq: 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 donotq_lookup(struct iter_donotq* donotq, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen);
|
||||
|
||||
#endif /* ITERATOR_ITER_DONOTQ_H */
|
||||
|
|
@ -105,7 +105,7 @@ void forwards_delete(struct iter_forwards* fwd);
|
|||
int forwards_apply_cfg(struct iter_forwards* fwd, struct config_file* cfg);
|
||||
|
||||
/**
|
||||
* Find a forward zone information
|
||||
* Find forward zone information
|
||||
* For this qname/qclass find forward zone information, returns delegation
|
||||
* point with server names and addresses, or NULL if no forwarding is needed.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@
|
|||
#include "iterator/iterator.h"
|
||||
#include "iterator/iter_hints.h"
|
||||
#include "iterator/iter_fwd.h"
|
||||
#include "iterator/iter_donotq.h"
|
||||
#include "iterator/iter_delegpt.h"
|
||||
#include "services/cache/infra.h"
|
||||
#include "services/cache/dns.h"
|
||||
|
|
@ -138,6 +139,12 @@ iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg)
|
|||
log_err("Could not set forward zones");
|
||||
return 0;
|
||||
}
|
||||
if(!iter_env->donotq)
|
||||
iter_env->donotq = donotq_create();
|
||||
if(!iter_env->donotq || !donotq_apply_cfg(iter_env->donotq, cfg)) {
|
||||
log_err("Could not set donotqueryaddresses");
|
||||
return 0;
|
||||
}
|
||||
iter_env->supports_ipv6 = cfg->do_ip6;
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -149,9 +156,11 @@ iter_filter_unsuitable(struct iter_env* iter_env, struct module_env* env,
|
|||
{
|
||||
int rtt;
|
||||
int lame;
|
||||
/* TODO: check ie->donotqueryaddrs for a */
|
||||
if(donotq_lookup(iter_env->donotq, &a->addr, a->addrlen)) {
|
||||
return -1; /* server is on the donotquery list */
|
||||
}
|
||||
if(!iter_env->supports_ipv6 && addr_is_ip6(&a->addr)) {
|
||||
return -1;
|
||||
return -1; /* there is no ip6 available */
|
||||
}
|
||||
/* check lameness - need zone , class info */
|
||||
if(infra_get_lame_rtt(env->infra_cache, &a->addr, a->addrlen,
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@
|
|||
#include "iterator/iter_utils.h"
|
||||
#include "iterator/iter_hints.h"
|
||||
#include "iterator/iter_fwd.h"
|
||||
#include "iterator/iter_donotq.h"
|
||||
#include "iterator/iter_delegpt.h"
|
||||
#include "iterator/iter_resptype.h"
|
||||
#include "iterator/iter_scrub.h"
|
||||
|
|
@ -86,6 +87,7 @@ iter_deinit(struct module_env* env, int id)
|
|||
free(iter_env->target_fetch_policy);
|
||||
hints_delete(iter_env->hints);
|
||||
forwards_delete(iter_env->fwds);
|
||||
donotq_delete(iter_env->donotq);
|
||||
if(iter_env)
|
||||
free(iter_env);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ struct module_func_block;
|
|||
struct delegpt;
|
||||
struct iter_hints;
|
||||
struct iter_forwards;
|
||||
struct iter_donotq;
|
||||
struct iter_prep_list;
|
||||
|
||||
/** max number of query restarts. Determines max number of CNAME chain. */
|
||||
|
|
@ -83,7 +84,7 @@ struct iter_env {
|
|||
struct iter_forwards* fwds;
|
||||
|
||||
/** A set of inetaddrs that should never be queried. */
|
||||
/* struct bla donotquery_addrs TODO */
|
||||
struct iter_donotq* donotq;
|
||||
|
||||
/** The maximum dependency depth that this resolver will pursue. */
|
||||
int max_dependency_depth;
|
||||
|
|
|
|||
7
services/cache/infra.c
vendored
7
services/cache/infra.c
vendored
|
|
@ -61,12 +61,7 @@ infra_host_compfunc(void* key1, void* key2)
|
|||
{
|
||||
struct infra_host_key* k1 = (struct infra_host_key*)key1;
|
||||
struct infra_host_key* k2 = (struct infra_host_key*)key2;
|
||||
if(k1->addrlen != k2->addrlen) {
|
||||
if(k1->addrlen < k2->addrlen)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
return memcmp(&k1->addr, &k2->addr, k1->addrlen);
|
||||
return sockaddr_cmp(&k1->addr, k1->addrlen, &k2->addr, k2->addrlen);
|
||||
}
|
||||
|
||||
/** delete key, and destroy the lock */
|
||||
|
|
|
|||
|
|
@ -69,49 +69,6 @@ static int serviced_udp_callback(struct comm_point* c, void* arg, int error,
|
|||
static void serviced_tcp_initiate(struct outside_network* outnet,
|
||||
struct serviced_query* sq, ldns_buffer* buff);
|
||||
|
||||
/** compare sockaddr */
|
||||
static int
|
||||
sockaddr_cmp(struct sockaddr_storage* addr1, socklen_t len1,
|
||||
struct sockaddr_storage* addr2, socklen_t len2)
|
||||
{
|
||||
struct sockaddr_in* p1_in = (struct sockaddr_in*)addr1;
|
||||
struct sockaddr_in* p2_in = (struct sockaddr_in*)addr2;
|
||||
struct sockaddr_in6* p1_in6 = (struct sockaddr_in6*)addr1;
|
||||
struct sockaddr_in6* p2_in6 = (struct sockaddr_in6*)addr2;
|
||||
if(len1 < len2)
|
||||
return -1;
|
||||
if(len1 > len2)
|
||||
return 1;
|
||||
log_assert(len1 == len2);
|
||||
if( p1_in->sin_family < p2_in->sin_family)
|
||||
return -1;
|
||||
if( p1_in->sin_family > p2_in->sin_family)
|
||||
return 1;
|
||||
log_assert( p1_in->sin_family == p2_in->sin_family );
|
||||
/* compare ip4 */
|
||||
if( p1_in->sin_family == AF_INET ) {
|
||||
/* just order it, ntohs not required */
|
||||
if(p1_in->sin_port < p2_in->sin_port)
|
||||
return -1;
|
||||
if(p1_in->sin_port > p2_in->sin_port)
|
||||
return 1;
|
||||
log_assert(p1_in->sin_port == p2_in->sin_port);
|
||||
return memcmp(&p1_in->sin_addr, &p2_in->sin_addr, INET_SIZE);
|
||||
} else if (p1_in6->sin6_family == AF_INET6) {
|
||||
/* just order it, ntohs not required */
|
||||
if(p1_in6->sin6_port < p2_in6->sin6_port)
|
||||
return -1;
|
||||
if(p1_in6->sin6_port > p2_in6->sin6_port)
|
||||
return 1;
|
||||
log_assert(p1_in6->sin6_port == p2_in6->sin6_port);
|
||||
return memcmp(&p1_in6->sin6_addr, &p2_in6->sin6_addr,
|
||||
INET6_SIZE);
|
||||
} else {
|
||||
/* eek unknown type, perform this comparison for sanity. */
|
||||
return memcmp(addr1, addr2, len1);
|
||||
}
|
||||
}
|
||||
|
||||
/** compare function of pending rbtree */
|
||||
static int
|
||||
pending_cmp(const void* key1, const void* key2)
|
||||
|
|
|
|||
|
|
@ -94,6 +94,11 @@ config_create()
|
|||
if(!(cfg->logfile = strdup(""))) goto error_exit;
|
||||
if(!(cfg->pidfile = strdup("unbound.pid"))) goto error_exit;
|
||||
if(!(cfg->target_fetch_policy = strdup("3 2 1 0 0"))) goto error_exit;
|
||||
cfg->donotqueryaddrs = NULL;
|
||||
if(!cfg_strlist_insert(&cfg->donotqueryaddrs, strdup("127.0.0.1")))
|
||||
goto error_exit;
|
||||
if(!cfg_strlist_insert(&cfg->donotqueryaddrs, strdup("::1")))
|
||||
goto error_exit;
|
||||
cfg->do_daemonize = 1;
|
||||
cfg->num_ifs = 0;
|
||||
cfg->ifs = NULL;
|
||||
|
|
@ -190,6 +195,7 @@ config_delete(struct config_file* cfg)
|
|||
}
|
||||
config_delstubs(cfg->stubs);
|
||||
config_delstubs(cfg->forwards);
|
||||
config_delstrlist(cfg->donotqueryaddrs);
|
||||
free(cfg);
|
||||
}
|
||||
|
||||
|
|
@ -224,3 +230,17 @@ int ub_c_wrap()
|
|||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
cfg_strlist_insert(struct config_strlist** head, char* item)
|
||||
{
|
||||
struct config_strlist *s;
|
||||
if(!item || !head)
|
||||
return 0;
|
||||
s = (struct config_strlist*)calloc(1, sizeof(struct config_strlist));
|
||||
if(!s)
|
||||
return 0;
|
||||
s->str = item;
|
||||
s->next = *head;
|
||||
*head = s;
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -106,6 +106,8 @@ struct config_file {
|
|||
struct config_stub* stubs;
|
||||
/** the forward zone definitions, linked list */
|
||||
struct config_stub* forwards;
|
||||
/** list of donotquery addresses, linked list */
|
||||
struct config_strlist* donotqueryaddrs;
|
||||
|
||||
/** harden against very small edns buffer sizes */
|
||||
int harden_short_bufsize;
|
||||
|
|
@ -171,6 +173,14 @@ int config_read(struct config_file* config, const char* filename);
|
|||
*/
|
||||
void config_delete(struct config_file* config);
|
||||
|
||||
/**
|
||||
* Insert string into strlist.
|
||||
* @param head: pointer to strlist head variable.
|
||||
* @param item: new item. malloced by caller. If NULL the insertion fails.
|
||||
* @return: true on success.
|
||||
*/
|
||||
int cfg_strlist_insert(struct config_strlist** head, char* item);
|
||||
|
||||
/**
|
||||
* Used during options parsing
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -135,6 +135,7 @@ stub-host{COLON} { YDOUT; return VAR_STUB_HOST;}
|
|||
forward-zone{COLON} { YDOUT; return VAR_FORWARD_ZONE;}
|
||||
forward-addr{COLON} { YDOUT; return VAR_FORWARD_ADDR;}
|
||||
forward-host{COLON} { YDOUT; return VAR_FORWARD_HOST;}
|
||||
do-not-query-address{COLON} { YDOUT; return VAR_DO_NOT_QUERY_ADDRESS;}
|
||||
{NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++;}
|
||||
|
||||
/* Quoted strings. Strip leading and ending quotes */
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ extern struct config_parser_state* cfg_parser;
|
|||
%token VAR_STUB_ZONE VAR_STUB_HOST VAR_STUB_ADDR VAR_TARGET_FETCH_POLICY
|
||||
%token VAR_HARDEN_SHORT_BUFSIZE VAR_HARDEN_LARGE_QUERIES
|
||||
%token VAR_FORWARD_ZONE VAR_FORWARD_HOST VAR_FORWARD_ADDR
|
||||
%token VAR_DO_NOT_QUERY_ADDRESS
|
||||
|
||||
%%
|
||||
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
|
||||
|
|
@ -107,7 +108,8 @@ content_server: server_num_threads | server_verbosity | server_port |
|
|||
server_infra_host_ttl | server_infra_lame_ttl |
|
||||
server_infra_cache_slabs | server_infra_cache_numhosts |
|
||||
server_infra_cache_numlame | server_target_fetch_policy |
|
||||
server_harden_short_bufsize | server_harden_large_queries
|
||||
server_harden_short_bufsize | server_harden_large_queries |
|
||||
server_do_not_query_address
|
||||
;
|
||||
stubstart: VAR_STUB_ZONE
|
||||
{
|
||||
|
|
@ -408,6 +410,13 @@ server_harden_large_queries: VAR_HARDEN_LARGE_QUERIES STRING
|
|||
free($2);
|
||||
}
|
||||
;
|
||||
server_do_not_query_address: VAR_DO_NOT_QUERY_ADDRESS STRING
|
||||
{
|
||||
OUTYY(("P(server_do_not_query_address:%s)\n", $2));
|
||||
if(!cfg_strlist_insert(&cfg_parser->cfg->donotqueryaddrs, $2))
|
||||
yyerror("out of memory");
|
||||
}
|
||||
;
|
||||
stub_name: VAR_NAME STRING
|
||||
{
|
||||
OUTYY(("P(name:%s)\n", $2));
|
||||
|
|
@ -417,27 +426,15 @@ stub_name: VAR_NAME STRING
|
|||
;
|
||||
stub_host: VAR_STUB_HOST STRING
|
||||
{
|
||||
struct config_strlist *s = (struct config_strlist*)calloc(1,
|
||||
sizeof(struct config_strlist));
|
||||
OUTYY(("P(stub-host:%s)\n", $2));
|
||||
if(s) {
|
||||
s->str = $2;
|
||||
s->next = cfg_parser->cfg->stubs->hosts;
|
||||
cfg_parser->cfg->stubs->hosts = s;
|
||||
} else
|
||||
if(!cfg_strlist_insert(&cfg_parser->cfg->stubs->hosts, $2))
|
||||
yyerror("out of memory");
|
||||
}
|
||||
;
|
||||
stub_addr: VAR_STUB_ADDR STRING
|
||||
{
|
||||
struct config_strlist *s = (struct config_strlist*)calloc(1,
|
||||
sizeof(struct config_strlist));
|
||||
OUTYY(("P(stub-addr:%s)\n", $2));
|
||||
if(s) {
|
||||
s->str = $2;
|
||||
s->next = cfg_parser->cfg->stubs->addrs;
|
||||
cfg_parser->cfg->stubs->addrs = s;
|
||||
} else
|
||||
if(!cfg_strlist_insert(&cfg_parser->cfg->stubs->addrs, $2))
|
||||
yyerror("out of memory");
|
||||
}
|
||||
;
|
||||
|
|
@ -450,27 +447,15 @@ forward_name: VAR_NAME STRING
|
|||
;
|
||||
forward_host: VAR_FORWARD_HOST STRING
|
||||
{
|
||||
struct config_strlist *s = (struct config_strlist*)calloc(1,
|
||||
sizeof(struct config_strlist));
|
||||
OUTYY(("P(forward-host:%s)\n", $2));
|
||||
if(s) {
|
||||
s->str = $2;
|
||||
s->next = cfg_parser->cfg->forwards->hosts;
|
||||
cfg_parser->cfg->forwards->hosts = s;
|
||||
} else
|
||||
if(!cfg_strlist_insert(&cfg_parser->cfg->forwards->hosts, $2))
|
||||
yyerror("out of memory");
|
||||
}
|
||||
;
|
||||
forward_addr: VAR_FORWARD_ADDR STRING
|
||||
{
|
||||
struct config_strlist *s = (struct config_strlist*)calloc(1,
|
||||
sizeof(struct config_strlist));
|
||||
OUTYY(("P(forward-addr:%s)\n", $2));
|
||||
if(s) {
|
||||
s->str = $2;
|
||||
s->next = cfg_parser->cfg->forwards->addrs;
|
||||
cfg_parser->cfg->forwards->addrs = s;
|
||||
} else
|
||||
if(!cfg_strlist_insert(&cfg_parser->cfg->forwards->addrs, $2))
|
||||
yyerror("out of memory");
|
||||
}
|
||||
;
|
||||
|
|
|
|||
|
|
@ -263,6 +263,48 @@ void log_name_addr(enum verbosity_value v, const char* str, uint8_t* zone,
|
|||
str, namebuf, family, dest, (int)port);
|
||||
}
|
||||
|
||||
int
|
||||
sockaddr_cmp(struct sockaddr_storage* addr1, socklen_t len1,
|
||||
struct sockaddr_storage* addr2, socklen_t len2)
|
||||
{
|
||||
struct sockaddr_in* p1_in = (struct sockaddr_in*)addr1;
|
||||
struct sockaddr_in* p2_in = (struct sockaddr_in*)addr2;
|
||||
struct sockaddr_in6* p1_in6 = (struct sockaddr_in6*)addr1;
|
||||
struct sockaddr_in6* p2_in6 = (struct sockaddr_in6*)addr2;
|
||||
if(len1 < len2)
|
||||
return -1;
|
||||
if(len1 > len2)
|
||||
return 1;
|
||||
log_assert(len1 == len2);
|
||||
if( p1_in->sin_family < p2_in->sin_family)
|
||||
return -1;
|
||||
if( p1_in->sin_family > p2_in->sin_family)
|
||||
return 1;
|
||||
log_assert( p1_in->sin_family == p2_in->sin_family );
|
||||
/* compare ip4 */
|
||||
if( p1_in->sin_family == AF_INET ) {
|
||||
/* just order it, ntohs not required */
|
||||
if(p1_in->sin_port < p2_in->sin_port)
|
||||
return -1;
|
||||
if(p1_in->sin_port > p2_in->sin_port)
|
||||
return 1;
|
||||
log_assert(p1_in->sin_port == p2_in->sin_port);
|
||||
return memcmp(&p1_in->sin_addr, &p2_in->sin_addr, INET_SIZE);
|
||||
} else if (p1_in6->sin6_family == AF_INET6) {
|
||||
/* just order it, ntohs not required */
|
||||
if(p1_in6->sin6_port < p2_in6->sin6_port)
|
||||
return -1;
|
||||
if(p1_in6->sin6_port > p2_in6->sin6_port)
|
||||
return 1;
|
||||
log_assert(p1_in6->sin6_port == p2_in6->sin6_port);
|
||||
return memcmp(&p1_in6->sin6_addr, &p2_in6->sin6_addr,
|
||||
INET6_SIZE);
|
||||
} else {
|
||||
/* eek unknown type, perform this comparison for sanity. */
|
||||
return memcmp(addr1, addr2, len1);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
addr_is_ip6(struct sockaddr_storage* addr)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -172,6 +172,17 @@ int ipstrtoaddr(const char* ip, int port, struct sockaddr_storage* addr,
|
|||
void log_nametypeclass(enum verbosity_value v, const char* str,
|
||||
uint8_t* name, uint16_t type, uint16_t dclass);
|
||||
|
||||
/**
|
||||
* Compare two sockaddrs. Imposes an ordering on the addresses.
|
||||
* @param addr1: address 1.
|
||||
* @param len1: lengths of addr1.
|
||||
* @param addr2: address 2.
|
||||
* @param len2: lengths of addr2.
|
||||
* @return: 0 if addr1 == addr2. -1 if addr1 is smaller, +1 if larger.
|
||||
*/
|
||||
int sockaddr_cmp(struct sockaddr_storage* addr1, socklen_t len1,
|
||||
struct sockaddr_storage* addr2, socklen_t len2);
|
||||
|
||||
/**
|
||||
* Checkout address family.
|
||||
* @param addr: the sockaddr to examine.
|
||||
|
|
|
|||
Loading…
Reference in a new issue