Compare commits

..
Author SHA1 Message Date
Wouter Wijngaards e12d274954 fixup for duplication of NSECs / NSEC3s after following CNAMEs
(esp. wildcard CNAMEs and in-zone CNAMEs that then include nodata or
nxdomain proofs) where the CNAME is followed again to include more NSECs.


git-svn-id: file:///svn/unbound/trunk@787 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-28 13:41:31 +00:00
Wouter Wijngaards 9ade3e4811 nonRD fix.
git-svn-id: file:///svn/unbound/trunk@786 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-28 12:06:32 +00:00
Wouter Wijngaards 2c2eaecc6c nonRD fix.
git-svn-id: file:///svn/unbound/trunk@785 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-28 11:02:01 +00:00
Wouter Wijngaards 16906c53e6 log verbosity
git-svn-id: file:///svn/unbound/trunk@784 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-28 09:34:06 +00:00
Wouter Wijngaards b6d9b4bfcc CNAME chain marked as NXDOMAIN normalized to unbound preferred format.
git-svn-id: file:///svn/unbound/trunk@783 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-28 09:13:56 +00:00
Wouter Wijngaards 6bb12a5776 show it.
git-svn-id: file:///svn/unbound/trunk@782 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-28 08:41:41 +00:00
Wouter Wijngaards bce6c3405b nodefault test.
git-svn-id: file:///svn/unbound/trunk@781 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-28 08:26:57 +00:00
Wouter Wijngaards aa0c26ddec - tests for localdata multiple RR, and implicit zones.
- can specify TXT records for local data.



git-svn-id: file:///svn/unbound/trunk@780 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-28 08:10:45 +00:00
Wouter Wijngaards a1cbd214a5 Reduced operation sensitivity of message.
git-svn-id: file:///svn/unbound/trunk@779 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-27 16:18:09 +00:00
Wouter Wijngaards f64778a893 memory footprint improvements.
git-svn-id: file:///svn/unbound/trunk@778 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-27 15:52:41 +00:00
Wouter Wijngaards 9d3b5fa30d rfc2308 compliance.
git-svn-id: file:///svn/unbound/trunk@777 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-27 13:25:11 +00:00
Wouter Wijngaards 99590f93bd test and fixes.
git-svn-id: file:///svn/unbound/trunk@776 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-22 16:13:16 +00:00
Wouter Wijngaards b72563dcb7 local zone answers.
git-svn-id: file:///svn/unbound/trunk@775 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-22 13:48:58 +00:00
Wouter Wijngaards 6b0cf42b32 defaults.
git-svn-id: file:///svn/unbound/trunk@774 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-22 09:30:44 +00:00
Wouter Wijngaards 8df2959959 localzone internal data structures.
git-svn-id: file:///svn/unbound/trunk@773 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-21 16:19:31 +00:00
Wouter Wijngaards 1cda904545 localzon setup.
git-svn-id: file:///svn/unbound/trunk@772 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-20 16:38:41 +00:00
Wouter Wijngaards 416129dedb localzone and localdata configuration setup.
git-svn-id: file:///svn/unbound/trunk@771 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-20 14:48:33 +00:00
Wouter Wijngaards b9c417481b keep tcp address around for acl.
git-svn-id: file:///svn/unbound/trunk@770 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-19 16:31:22 +00:00
Wouter Wijngaards eda6528c14 access-control
git-svn-id: file:///svn/unbound/trunk@769 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-19 15:32:55 +00:00
Wouter Wijngaards fc8657c421 unit test for addr_in_common.
git-svn-id: file:///svn/unbound/trunk@767 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-19 13:21:30 +00:00
Wouter Wijngaards 5f50f5d2b4 unit test for addr_mask.
git-svn-id: file:///svn/unbound/trunk@766 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-19 13:02:15 +00:00
Wouter Wijngaards 31f803201d port from beta-0.7.1
git-svn-id: file:///svn/unbound/trunk@763 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-19 11:04:05 +00:00
Wouter Wijngaards ff975871ab fixup leaking unbound daemons.
git-svn-id: file:///svn/unbound/trunk@755 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-19 09:06:56 +00:00
Wouter Wijngaards 99a9914605 No downcasing for NSEC and RRSIG
git-svn-id: file:///svn/unbound/trunk@754 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-19 08:55:19 +00:00
Wouter Wijngaards 435fbd1794 acl list setup. 8 to tab in net_help.
git-svn-id: file:///svn/unbound/trunk@753 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-16 16:25:37 +00:00
Wouter Wijngaards fe09abe4e6 0.8 in trunk for auth features development.
git-svn-id: file:///svn/unbound/trunk@752 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-16 13:03:04 +00:00
Wouter Wijngaards e900e44f9f todo item is not needed at this time.
git-svn-id: file:///svn/unbound/trunk@750 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-16 12:53:57 +00:00
Wouter Wijngaards bfbac6bb36 Jakob in Credits.
git-svn-id: file:///svn/unbound/trunk@749 be551aaa-1e26-0410-a405-d3ace91eadb9
2007-11-15 15:42:10 +00:00
65 changed files with 4403 additions and 1170 deletions
+2 -2
View File
@@ -71,8 +71,8 @@ DAEMON_OBJ=$(addprefix $(BUILD),$(DAEMON_SRC:.c=.o)) $(COMPAT_OBJ)
CHECKCONF_SRC=checkconf/unbound-checkconf.c checkconf/worker_cb.c $(COMMON_SRC)
CHECKCONF_OBJ=$(addprefix $(BUILD),$(CHECKCONF_SRC:.c=.o)) $(COMPAT_OBJ)
TESTBOUND_SRC=testcode/testbound.c testcode/ldns-testpkts.c \
daemon/worker.c daemon/daemon.c daemon/stats.c testcode/replay.c \
testcode/fake_event.c $(filter-out util/netevent.c \
daemon/worker.c daemon/acl_list.c daemon/daemon.c daemon/stats.c \
testcode/replay.c testcode/fake_event.c $(filter-out util/netevent.c \
services/listen_dnsport.c services/outside_network.c, $(COMMON_SRC))
TESTBOUND_OBJ=$(addprefix $(BUILD),$(TESTBOUND_SRC:.c=.o)) $(COMPAT_OBJ)
LOCKVERIFY_SRC=testcode/lock_verify.c checkconf/worker_cb.c $(COMMON_SRC)
+10
View File
@@ -0,0 +1,10 @@
Unbound README
* ./configure && make && make install
* on BSDs and Solaris use gmake (GNU make).
* If it complains that no libevent can be found; libevent is useful when
using many (10000) outgoing ports. By default 16 ports are used and the
builtin alternative is equally capable.
* More detailed README, README.svn, README.tests in doc directory
* manual pages can be found in doc directory, and are installed, unbound(8).
* example configuration file doc/example.conf
+18 -1
View File
@@ -50,6 +50,7 @@
#include "util/regional.h"
#include "iterator/iterator.h"
#include "validator/validator.h"
#include "services/localzone.h"
#include <pwd.h>
/** Give checkconf usage, and exit (1). */
@@ -92,6 +93,8 @@ morechecks(struct config_file* cfg)
int i;
struct sockaddr_storage a;
socklen_t alen;
struct config_str2list* acl;
struct local_zones* zs;
for(i=0; i<cfg->num_ifs; i++) {
if(!ipstrtoaddr(cfg->ifs[i], UNBOUND_DNS_PORT, &a, &alen)) {
fatal_exit("cannot parse interface specified as '%s'",
@@ -105,6 +108,13 @@ morechecks(struct config_file* cfg)
"specified as '%s'", cfg->out_ifs[i]);
}
}
for(acl=cfg->acls; acl; acl = acl->next) {
if(!netblockstrtoaddr(acl->str, UNBOUND_DNS_PORT, &a, &alen,
&i)) {
fatal_exit("cannot parse access control address %s %s",
acl->str, acl->str2);
}
}
if(cfg->verbosity < 0)
fatal_exit("verbosity value < 0");
@@ -132,7 +142,7 @@ morechecks(struct config_file* cfg)
if(strcmp(cfg->module_conf, "iterator") != 0 &&
strcmp(cfg->module_conf, "validator iterator") != 0) {
fatal_exit("module conf %s is not known to work",
fatal_exit("module conf '%s' is not known to work",
cfg->module_conf);
}
@@ -142,6 +152,13 @@ morechecks(struct config_file* cfg)
fatal_exit("user '%s' does not exist.", cfg->username);
endpwent();
}
if(!(zs = local_zones_create()))
fatal_exit("out of memory");
if(!local_zones_apply_cfg(zs, cfg))
fatal_exit("failed local-zone, local-data configuration");
local_zones_print(zs); /* @@@ DEBUG */
local_zones_delete(zs);
}
/** check config file */
+7
View File
@@ -107,3 +107,10 @@ worker_alloc_cleanup(void* ATTR_UNUSED(arg))
{
log_assert(0);
}
int
acl_list_cmp(const void* ATTR_UNUSED(k1), const void* ATTR_UNUSED(k2))
{
log_assert(0);
return 0;
}
Vendored
+11 -11
View File
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.61 for unbound 0.6.
# Generated by GNU Autoconf 2.61 for unbound 0.8.
#
# Report bugs to <unbound-bugs@nlnetlabs.nl>.
#
@@ -724,8 +724,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
# Identity of this package.
PACKAGE_NAME='unbound'
PACKAGE_TARNAME='unbound'
PACKAGE_VERSION='0.6'
PACKAGE_STRING='unbound 0.6'
PACKAGE_VERSION='0.8'
PACKAGE_STRING='unbound 0.8'
PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl'
# Factoring default headers for most tests.
@@ -1358,7 +1358,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures unbound 0.6 to adapt to many kinds of systems.
\`configure' configures unbound 0.8 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1423,7 +1423,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of unbound 0.6:";;
short | recursive ) echo "Configuration of unbound 0.8:";;
esac
cat <<\_ACEOF
@@ -1544,7 +1544,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
unbound configure 0.6
unbound configure 0.8
generated by GNU Autoconf 2.61
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -1558,7 +1558,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by unbound $as_me 0.6, which was
It was created by unbound $as_me 0.8, which was
generated by GNU Autoconf 2.61. Invocation command line was
$ $0 $@
@@ -21692,11 +21692,11 @@ echo "${ECHO_T}found in $thedir" >&6; }
LDFLAGS="$thedir/.libs/*.o $LDFLAGS";
else
{ { echo "$as_me:$LINENO: error: Cannot find the libevent library in $withval
You can restart configure with --with-libevent=no to use a builtin alternative.
You can restart ./configure --with-libevent=no to use a builtin alternative.
Please note that this alternative is not as capable as libevent when using
many outgoing ports. " >&5
echo "$as_me: error: Cannot find the libevent library in $withval
You can restart configure with --with-libevent=no to use a builtin alternative.
You can restart ./configure --with-libevent=no to use a builtin alternative.
Please note that this alternative is not as capable as libevent when using
many outgoing ports. " >&2;}
{ (exit 1); exit 1; }; }
@@ -24974,7 +24974,7 @@ exec 6>&1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by unbound $as_me 0.6, which was
This file was extended by unbound $as_me 0.8, which was
generated by GNU Autoconf 2.61. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -25023,7 +25023,7 @@ Report bugs to <bug-autoconf@gnu.org>."
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF
ac_cs_version="\\
unbound config.status 0.6
unbound config.status 0.8
configured by $0, generated by GNU Autoconf 2.61,
with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
+2 -2
View File
@@ -2,7 +2,7 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.57)
AC_INIT(unbound, 0.7, unbound-bugs@nlnetlabs.nl, unbound)
AC_INIT(unbound, 0.8, unbound-bugs@nlnetlabs.nl, unbound)
CFLAGS=
AC_AIX
@@ -503,7 +503,7 @@ if test x_$withval != x_no; then
LDFLAGS="$thedir/.libs/*.o $LDFLAGS";
else
AC_MSG_ERROR([Cannot find the libevent library in $withval
You can restart configure with --with-libevent=no to use a builtin alternative.
You can restart ./configure --with-libevent=no to use a builtin alternative.
Please note that this alternative is not as capable as libevent when using
many outgoing ports. ])
fi
+246
View File
@@ -0,0 +1,246 @@
/*
* daemon/acl_list.h - client access control storage for the server.
*
* 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 helps the server keep out queries from outside sources, that
* should not be answered.
*/
#include "config.h"
#include "daemon/acl_list.h"
#include "util/regional.h"
#include "util/log.h"
#include "util/config_file.h"
#include "util/net_help.h"
int
acl_list_cmp(const void* k1, const void* k2)
{
struct acl_addr* n1 = (struct acl_addr*)k1;
struct acl_addr* n2 = (struct acl_addr*)k2;
int r = sockaddr_cmp_addr(&n1->addr, n1->addrlen, &n2->addr,
n2->addrlen);
if(r != 0) return r;
if(n1->net < n2->net)
return -1;
if(n1->net > n2->net)
return 1;
return 0;
}
struct acl_list*
acl_list_create()
{
struct acl_list* acl = (struct acl_list*)calloc(1,
sizeof(struct acl_list));
if(!acl)
return NULL;
acl->region = regional_create();
if(!acl->region) {
acl_list_delete(acl);
return NULL;
}
return acl;
}
void
acl_list_delete(struct acl_list* acl)
{
if(!acl)
return;
regional_destroy(acl->region);
free(acl->tree);
free(acl);
}
/** insert new address into acl_list structure */
static int
acl_list_insert(struct acl_list* acl, struct sockaddr_storage* addr,
socklen_t addrlen, int net, enum acl_access control,
int complain_duplicates)
{
struct acl_addr* node = regional_alloc(acl->region,
sizeof(struct acl_addr));
if(!node)
return 0;
node->node.key = node;
memcpy(&node->addr, addr, addrlen);
node->addrlen = addrlen;
node->net = net;
node->parent = NULL;
node->control = control;
if(!rbtree_insert(acl->tree, &node->node)) {
if(complain_duplicates)
verbose(VERB_DETAIL, "duplicate acl address ignored.");
}
return 1;
}
/** apply acl_list string */
static int
acl_list_str_cfg(struct acl_list* acl, const char* str, const char* s2,
int complain_duplicates)
{
struct sockaddr_storage addr;
int net;
socklen_t addrlen;
enum acl_access control;
if(strcmp(s2, "allow") == 0)
control = acl_allow;
else if(strcmp(s2, "deny") == 0)
control = acl_deny;
else if(strcmp(s2, "refuse") == 0)
control = acl_refuse;
else {
log_err("access control type %s unknown", str);
return 0;
}
if(!netblockstrtoaddr(str, UNBOUND_DNS_PORT, &addr, &addrlen, &net)) {
log_err("cannot parse access control: %s %s", str, s2);
return 0;
}
if(!acl_list_insert(acl, &addr, addrlen, net, control,
complain_duplicates)) {
log_err("out of memory");
return 0;
}
return 1;
}
/** read acl_list config */
static int
read_acl_list(struct acl_list* acl, struct config_file* cfg)
{
struct config_str2list* p;
for(p = cfg->acls; p; p = p->next) {
log_assert(p->str && p->str2);
if(!acl_list_str_cfg(acl, p->str, p->str2, 1))
return 0;
}
return 1;
}
/** initialise parent pointers in the tree */
static void
acl_list_init_parents(struct acl_list* acl)
{
struct acl_addr* node, *prev = NULL, *p;
int m;
RBTREE_FOR(node, struct acl_addr*, acl->tree) {
node->parent = NULL;
if(!prev || prev->addrlen != node->addrlen) {
prev = node;
continue;
}
m = addr_in_common(&prev->addr, prev->net, &node->addr,
node->net, node->addrlen);
/* sort order like: ::/0, 1::/2, 1::/4, ... 2::/2 */
/* find the previous, or parent-parent-parent */
for(p = prev; p; p = p->parent)
if(p->net <= m) {
/* ==: since prev matched m, this is closest*/
/* <: prev matches more, but is not a parent,
* this one is a (grand)parent */
node->parent = p;
break;
}
prev = node;
}
}
int
acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg)
{
regional_free_all(acl->region);
free(acl->tree);
acl->tree = rbtree_create(acl_list_cmp);
if(!acl->tree)
return 0;
if(!read_acl_list(acl, cfg))
return 0;
/* insert defaults, with '0' to ignore them if they are duplicates */
if(!acl_list_str_cfg(acl, "0.0.0.0/0", "refuse", 0))
return 0;
if(!acl_list_str_cfg(acl, "::0/0", "refuse", 0))
return 0;
if(!acl_list_str_cfg(acl, "127.0.0.0/8", "allow", 0))
return 0;
if(!acl_list_str_cfg(acl, "::1", "allow", 0))
return 0;
acl_list_init_parents(acl);
return 1;
}
enum acl_access
acl_list_lookup(struct acl_list* acl, struct sockaddr_storage* addr,
socklen_t addrlen)
{
/* lookup in the tree */
rbnode_t* res = NULL;
struct acl_addr* result;
struct acl_addr key;
key.node.key = &key;
memcpy(&key.addr, addr, addrlen);
key.addrlen = addrlen;
key.net = (addr_is_ip6(addr, addrlen)?128:32);
if(rbtree_find_less_equal(acl->tree, &key, &res)) {
/* exact */
result = (struct acl_addr*)res;
return result->control;
} else {
/* smaller element (or no element) */
int m;
result = (struct acl_addr*)res;
if(!result || result->addrlen != addrlen)
return acl_deny;
/* count number of bits matched */
m = addr_in_common(&result->addr, result->net, addr,
key.net, addrlen);
while(result) { /* go up until addr is inside netblock */
if(result->net <= m)
return result->control;
result = result->parent;
}
}
return acl_deny;
}
size_t
acl_list_get_mem(struct acl_list* acl)
{
if(!acl) return 0;
return sizeof(*acl) + regional_get_mem(acl->region);
}
+134
View File
@@ -0,0 +1,134 @@
/*
* daemon/acl_list.h - client access control storage for the server.
*
* 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 keeps track of the list of clients that are allowed to
* access the server.
*/
#ifndef DAEMON_ACL_LIST_H
#define DAEMON_ACL_LIST_H
#include "util/rbtree.h"
struct config_file;
struct regional;
/**
* Enumeration of access control options for an address range.
* Allow or deny access.
*/
enum acl_access {
/** disallow any access whatsoever, drop it */
acl_deny = 0,
/** disallow access, send a polite 'REFUSED' reply */
acl_refuse,
/** allow full access */
acl_allow
};
/**
* Access control storage structure
*/
struct acl_list {
/** regional for allocation */
struct regional* region;
/**
* Tree of the addresses that are allowed/blocked.
* contents of type acl_addr.
*/
rbtree_t* tree;
};
/**
*
* An address span with access control information
*/
struct acl_addr {
/** redblacktree node, key is this structure: addr and addrlen, net */
rbnode_t node;
/** address */
struct sockaddr_storage addr;
/** length of addr */
socklen_t addrlen;
/** netblock size */
int net;
/** parent node in acl tree that encompasses this entry */
struct acl_addr* parent;
/** access control on this netblock */
enum acl_access control;
};
/**
* Create acl structure
* @return new structure or NULL on error.
*/
struct acl_list* acl_list_create();
/**
* Delete acl structure.
* @param acl: to delete.
*/
void acl_list_delete(struct acl_list* acl);
/**
* Process access control config.
* @param acl: where to store.
* @param cfg: config options.
* @return 0 on error.
*/
int acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg);
/**
* Lookup address to see its access control status.
* @param acl: structure for address storage.
* @param addr: address to check
* @param addrlen: length of addr.
* @return: what to do with message from this address.
*/
enum acl_access acl_list_lookup(struct acl_list* acl,
struct sockaddr_storage* addr, socklen_t addrlen);
/**
* Get memory used by acl structure.
* @param acl: structure for address storage.
* @return bytes in use.
*/
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 */
+20 -1
View File
@@ -42,6 +42,7 @@
#include "config.h"
#include "daemon/daemon.h"
#include "daemon/worker.h"
#include "daemon/acl_list.h"
#include "util/log.h"
#include "util/config_file.h"
#include "util/data/msgreply.h"
@@ -49,6 +50,7 @@
#include "services/listen_dnsport.h"
#include "services/cache/rrset.h"
#include "services/cache/infra.h"
#include "services/localzone.h"
#include "util/module.h"
#include "iterator/iterator.h"
#include "validator/validator.h"
@@ -134,6 +136,12 @@ daemon_init()
return NULL;
}
alloc_init(&daemon->superalloc, NULL, 0);
daemon->acl = acl_list_create();
if(!daemon->acl) {
free(daemon->env);
free(daemon);
return NULL;
}
return daemon;
}
@@ -273,7 +281,8 @@ static void daemon_setup_modules(struct daemon* daemon)
daemon->env->worker = NULL;
daemon->env->need_to_validate = 0; /* set by module init below */
for(i=0; i<daemon->num_modules; i++) {
log_info("init module %d: %s", i, daemon->modfunc[i]->name);
verbose(VERB_OPS, "init module %d: %s",
i, daemon->modfunc[i]->name);
log_assert(fptr_whitelist_mod_init(daemon->modfunc[i]->init));
if(!(*daemon->modfunc[i]->init)(daemon->env, i)) {
fatal_exit("module init for module %s failed",
@@ -397,6 +406,12 @@ void
daemon_fork(struct daemon* daemon)
{
log_assert(daemon);
if(!acl_list_apply_cfg(daemon->acl, daemon->cfg))
fatal_exit("Could not setup access control list");
if(!(daemon->local_zones = local_zones_create()))
fatal_exit("Could not create local zones: out of memory");
if(!local_zones_apply_cfg(daemon->local_zones, daemon->cfg))
fatal_exit("Could not set up local zones");
/* setup modules */
daemon_setup_modules(daemon);
@@ -421,6 +436,7 @@ daemon_fork(struct daemon* daemon)
/* Start resolver service on main thread. */
log_info("start of service (%s).", PACKAGE_STRING);
worker_work(daemon->workers[0]);
log_info("service stopped (%s).", PACKAGE_STRING);
/* we exited! a signal happened! Stop other threads */
daemon_stop_others(daemon);
@@ -443,6 +459,8 @@ daemon_cleanup(struct daemon* daemon)
* The infra cache is kept, the timing and edns info is still valid */
slabhash_clear(&daemon->env->rrset_cache->table);
slabhash_clear(daemon->env->msg_cache);
local_zones_delete(daemon->local_zones);
daemon->local_zones = NULL;
/* key cache is cleared by module desetup during next daemon_init() */
for(i=0; i<daemon->num; i++)
worker_delete(daemon->workers[i]);
@@ -465,6 +483,7 @@ daemon_delete(struct daemon* daemon)
infra_delete(daemon->env->infra_cache);
}
alloc_clear(&daemon->superalloc);
acl_list_delete(daemon->acl);
free(daemon->pidfile);
free(daemon->env);
free(daemon);
+6
View File
@@ -50,6 +50,8 @@ struct listen_port;
struct slabhash;
struct module_env;
struct rrset_cache;
struct acl_list;
struct local_zones;
/**
* Structure holding worker list.
@@ -78,6 +80,10 @@ struct daemon {
int num_modules;
/** the module callbacks, array of num_modules length */
struct module_func_block** modfunc;
/** access control, which client IPs are allowed to connect */
struct acl_list* acl;
/** local authority zones */
struct local_zones* local_zones;
};
/**
+2 -2
View File
@@ -339,8 +339,8 @@ run_daemon(char* cfgfile, int cmdline_verbose, int debug_mode)
fatal_exit("alloc failure");
while(!daemon->need_to_exit) {
if(done_chroot)
log_info("Restart of %s.", PACKAGE_STRING);
else log_info("Start of %s.", PACKAGE_STRING);
verbose(VERB_OPS, "Restart of %s.", PACKAGE_STRING);
else verbose(VERB_OPS, "Start of %s.", PACKAGE_STRING);
/* config stuff */
if(!(cfg = config_create()))
+26 -3
View File
@@ -45,6 +45,7 @@
#include "util/random.h"
#include "daemon/worker.h"
#include "daemon/daemon.h"
#include "daemon/acl_list.h"
#include "util/netevent.h"
#include "util/config_file.h"
#include "util/module.h"
@@ -57,6 +58,7 @@
#include "services/cache/infra.h"
#include "services/cache/dns.h"
#include "services/mesh.h"
#include "services/localzone.h"
#include "util/data/msgparse.h"
#include "util/data/msgencode.h"
#include "util/data/dname.h"
@@ -663,12 +665,28 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
struct lruhash_entry* e;
struct query_info qinfo;
struct edns_data edns;
enum acl_access acl;
if(error != NETEVENT_NOERROR) {
/* some bad tcp query DNS formats give these error calls */
verbose(VERB_ALGO, "handle request called with err=%d", error);
return 0;
}
acl = acl_list_lookup(worker->daemon->acl, &repinfo->addr,
repinfo->addrlen);
if(acl == acl_deny) {
comm_point_drop_reply(repinfo);
return 0;
} else if(acl == acl_refuse) {
ldns_buffer_set_limit(c->buffer, LDNS_HEADER_SIZE);
ldns_buffer_write_at(c->buffer, 4,
(uint8_t*)"\0\0\0\0\0\0\0\0", 8);
LDNS_QR_SET(ldns_buffer_begin(c->buffer));
LDNS_RCODE_SET(ldns_buffer_begin(c->buffer),
LDNS_RCODE_REFUSED);
log_buf(VERB_ALGO, "refuse", c->buffer);
return 1;
}
if((ret=worker_check_request(c->buffer, worker)) != 0) {
verbose(VERB_ALGO, "worker check request: bad query.");
if(ret != -1) {
@@ -738,6 +756,10 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
&edns, c->buffer)) {
return 1;
}
if(local_zones_answer(worker->daemon->local_zones, &qinfo, &edns,
c->buffer, worker->scratchpad)) {
return (ldns_buffer_limit(c->buffer) != 0);
}
h = query_info_hash(&qinfo);
if((e=slabhash_lookup(worker->env.msg_cache, h, &qinfo, 0))) {
/* answer from cache - we have acquired a readlock on it */
@@ -971,10 +993,11 @@ worker_delete(struct worker* worker)
{
if(!worker)
return;
if(worker->env.mesh)
if(worker->env.mesh && verbosity >= VERB_OPS) {
mesh_stats(worker->env.mesh, "mesh has");
server_stats_log(&worker->stats, worker->thread_num);
worker_mem_report(worker, NULL);
server_stats_log(&worker->stats, worker->thread_num);
worker_mem_report(worker, NULL);
}
mesh_delete(worker->env.mesh);
ldns_buffer_free(worker->env.scratch_buffer);
listen_delete(worker->front);
+2
View File
@@ -5,3 +5,5 @@ from the University of California and from Verisign. The Java prototype
was made in further cooperation with Geoff Sisson and Roy Arends from Nominet.
At NLnet Labs, Jelte Jansen and Mark Santcroos reviewed the unbound C sources.
Jakob Schlyter - for advice on secure settings, random numbers and blacklists.
+74
View File
@@ -1,3 +1,77 @@
28 November 2007: Wouter
- Changeup plan for 0.8 - no complication needed, a simple solution
has been chosen for authoritative features.
- you can use single quotes in the config file, so it is possible
to specify TXT records in local data.
- fixup small memory problem in implicit transparent zone creation.
- test for implicit zone creation and multiple RR RRsets local data.
- local-zone nodefault test.
- show testbound testlist on commit.
- iterator normalizer changes CNAME chains ending in NXDOMAIN where
the packet got rcode NXDOMAIN into rcode NOERROR. (since the initial
domain exists).
- nicer verbosity: 0 and 1 levels.
- lower nonRDquery chance of eliciting wrongly typed validation
requiring message from the cache.
- fix for nonRDquery validation typing; nodata is detected when
SOA record in auth section (all validation-requiring nodata messages
have a SOA record in authority, so this is OK for the validator),
and NS record is needed to be a referral.
- duplicate checking when adding NSECs for a CNAME, and test.
27 November 2007: Wouter
- per suggestion in rfc2308, replaced default max-ttl value with 1 day.
- set size of msgparse lookup table to 32, from 1024, so that its size
is below the 2048 regional large size threshold, and does not cause
a call to malloc when a message is parsed.
- update of memstats tool to print number of allocation calls.
This is what is taking time (not space) and indicates the avg size
of the allocations as well. region_alloc stat is removed.
22 November 2007: Wouter
- noted EDNS in-the-middle dropping trouble as a TODO.
At this point theoretical, no user trouble has been reported.
- added all default AS112 zones.
- answers from local zone content.
* positive answer, the rrset in question
* nodata answer (exist, but not that type).
* nxdomain answer (domain does not exist).
* empty-nonterminal answer.
* But not: wildcard, nsec, referral, rrsig, cname/dname,
or additional section processing, NS put in auth.
- test for correct working of static and transparent and couple
of important defaults (localhost, as112, reverses).
Also checks deny and refuse settings.
- fixup implicit zone generation and AA bit for NXDOMAIN on localdata.
21 November 2007: Wouter
- local zone internal data setup.
20 November 2007: Wouter
- 0.8 - str2list config support for double string config options.
- local-zone and local-data options, config storage and documentation.
19 November 2007: Wouter
- do not downcase NSEC and RRSIG for verification. Follows
draft-ietf-dnsext-dnssec-bis-updates-06.txt.
- fixup leaking unbound daemons at end of tests.
- README file updated.
- nice libevent not found error.
- README talks about gnu make.
- 0.8: unit test for addr_mask and fixups for it.
and unit test for addr_in_common().
- 0.8: access-control config file element.
and unit test rpl replay file.
- 0.8: fixup address reporting from netevent.
16 November 2007: Wouter
- privilege separation is not needed in unbound at this time.
TODO item marked as such.
- created beta-0.7 branch for support.
- tagged 0.7 for beta release.
- moved trunk to 0.8 for 0.8(auth features) development.
- 0.8: access control list setup.
15 November 2007: Wouter
- review fixups from Jelte.
+4
View File
@@ -18,6 +18,7 @@ This software is under BSD license, see LICENSE for details.
* autoreconf (autoheader && autoconf), if ./configure is missing.
* Make and install: ./configure; make; make install
* Use GNU make; default on linux, often called 'gmake' on BSD and Solaris.
* --with-ldns=/path/to/ldns
If ldns is not detected on the system, a prepackaged tarball
of the ldns library is used to compile and statically link against.
@@ -25,6 +26,9 @@ This software is under BSD license, see LICENSE for details.
* --with-libevent=/path/to/libevent
Can be set to either the system install or the build directory.
--with-libevent=no gives a builtin alternative implementation.
libevent is useful when having many (thousands) of outgoing ports.
This improves randomization and spoof resistance. For the default
of 16 ports the builtin alternative works well.
* --without-pthreads
This disables pthreads, and uses Solaris thr library or no threading.
Without this option the pthreads library is detected automatically.
+3
View File
@@ -53,5 +53,8 @@ o inspect date on executable, then warn user in log if its more than 1 year.
o proactively prime root, stubs and trust anchors, feature.
early failure, faster on first query, but more traffic.
o use privilege separation, to change privilege options during reload securely
not needed.
o check if for PowerDNS(2.9.21) CNAME in Answer section & rcode=NXDOMAIN needs
to be fixed up to be rcode=NOERROR?
o On Windows use CryptGenRandom() to get random seed for arc4random.
o Think about intermediate firewalls dropping EDNS UDP & handling that.
+40 -1
View File
@@ -81,7 +81,7 @@ server:
# the time to live (TTL) value cap for RRsets and messages in the
# cache. Items are not cached for longer. In seconds.
# cache-max-ttl: 864000
# cache-max-ttl: 86400
# the time to live (TTL) value for cached roundtrip times and
# EDNS version information for hosts. In seconds.
@@ -113,6 +113,15 @@ server:
# Enable TCP, "yes" or "no".
# do-tcp: yes
# control which clients are allowed to make (recursive) queries
# to this server. Specify classless netblocks with /size and action.
# By default everything is refused, except for localhost.
# Choose deny (drop message), refuse (polite error reply), allow.
# access-control: 0.0.0.0/0 refuse
# access-control: 127.0.0.0/8 allow
# access-control: ::0/0 refuse
# access-control: ::1 allow
# if given, a chroot(2) is done to the given directory.
# i.e. you can chroot to the working directory, for example,
# for extra security, but make sure all files are in that directory.
@@ -246,6 +255,36 @@ server:
# more slabs reduce lock contention, but fragment memory usage.
# key-cache-slabs: 4
# a number of locally served zones can be configured.
# local-zone: <zone> <type>
# local-data: "<resource record string>"
# o deny serves local data (if any), else, drops queries.
# o refuse serves local data (if any), else, replies with error.
# o static serves local data, else, nxdomain or nodata answer.
# o transparent serves local data, else, resolves normally .
# o redirect serves the zone data for any subdomain in the zone.
# o nodefault can be used to normally resolve AS112 zones.
#
# defaults are localhost address, reverse for 127.0.0.1 and ::1
# and nxdomain for AS112 zones. If you configure one of these zones
# the default content is omitted, or you can omit it with 'nodefault'.
#
# If you configure local-data without specifying local-zone, by
# default a transparent local-zone is created for the data.
#
# You can add locally served data with
# local-zone: "local." static
# local-data: "mycomputer.local. IN A 192.0.2.51"
# local-data: 'mytext.local TXT "content of text record"'
#
# You can override certain queries with
# local-data: "adserver.example.com A 127.0.0.1"
#
# You can redirect a domain to a fixed address with
# (this makes example.com, www.example.com, etc, all go to 192.0.2.3)
# local-zone: "example.com" redirect
# local-data: "example.com A 192.0.2.3"
# Stub zones.
# Create entries like below, to make all queries for 'example.com' and
+7 -5
View File
@@ -203,14 +203,18 @@ X make overload mode work; phase 0 all ok, phase 1 some threads close ports,
can be used to block AS112 traffic, option to unblock a zone.
* after checking acl, do iter: static, blacklist, forwards, recurse.
* Forward-local-zone to NSD.
- include in package, autoforkexec on localhost to do so.
- in package, autoforkexec on localhost to do so.
- not included. Not necessary for localhost and AS112 service.
* forward local zone to remote server.
- not included. Not necessary for localhost and AS112 service.
* stub zones - send queries for a zone to configged nameserver.
- Can be used for complicated setups. So, run auth server on a
different port or pc, and stub it on the resolver. Resolver is
not auth for zones, but resolution works. This enforces the split
of recursive and auth servers.
* test local zones
* for speed
* for correctness on corner cases
* for validation
* in case you get data on localzone in an answer (from rootserver).
*** Library use
* Create library that can do:
@@ -240,8 +244,6 @@ X make overload mode work; phase 0 all ok, phase 1 some threads close ports,
*** Features features
* aggressive negative caching for NSEC, NSEC3.
* multiple queries per question, server exploration, server selection.
* option to use real entropy for randomness (mix it in once in a while).
* check query, enforce qdsection, checking for forgery-resilience.
* NSID support.
* support TSIG on queries, for validating resolver deployment.
* Nicer statistics
+25
View File
@@ -175,3 +175,28 @@ o authority features.
You can put authority data on a separate server, and set the server in
unbound.conf as stub for those zones, this allows clients to access data
from the server without making unbound authoritative for the zones.
o the access control denies queries before any other processing.
This denies queries that are not authoritative, or version.bind, or any.
And thus prevents cache-snooping (denied hosts cannot make non-recursive
queries and get answers from the cache).
o If a client makes a query without RD bit, in the case of a returned
message from cache which is:
answer section: empty
auth section: NS record present, no SOA record, no DS record,
maybe NSEC or NSEC3 records present.
additional: A records or other relevant records.
A SOA record would indicate that this was a NODATA answer.
A DS records would indicate a referral.
Absence of NS record would indicate a NODATA answer as well.
Then the receiver does not know whether this was a referral
with attempt at no-DS proof) or a nodata answer with attempt
at no-data proof. It could be determined by attempting to prove
either condition; and looking if only one is valid, but both
proofs could be valid, or neither could be valid, which creates
doubt. This case is validated by unbound as a 'referral' which
ascertains that RRSIGs are OK (and not omitted), but does not
check NSEC/NSEC3.
+110 -1
View File
@@ -48,6 +48,12 @@ server:
# logfile: "/etc/unbound/unbound.log" #uncomment to use logfile.
pidfile: "/etc/unbound/unbound.pid"
# verbosity: 1 # uncomment and increase to get more logging.
# listen on all interfaces, answer queries from the local subnet.
interface: 0.0.0.0
interface: ::0
access-control: 10.0.0.0/8 allow
access-control: 2001:DB8::/64 allow
.fi
.Sh FILE FORMAT
There must be whitespace between keywords. Attribute keywords end with a colon ':'. An attribute
@@ -128,7 +134,7 @@ Number of slabs in the RRset cache. Slabs reduce lock contention by threads.
Must be set to a power of 2.
.It \fBcache-max-ttl:\fR <seconds>
Time to live maximum for RRsets and messages in the cache. Default is
864000 seconds (10 days). If the maximum kicks in, responses to clients
86400 seconds (1 day). If the maximum kicks in, responses to clients
still get decrementing TTLs based on the original (larger) values.
When the internal TTL expires, the cache item has expired.
Can be set lower to force the resolver to query for data often, and not
@@ -155,6 +161,13 @@ Enable or disable whether ip6 queries are answered. Default is yes.
Enable or disable whether UDP queries are answered. Default is yes.
.It \fBdo-tcp:\fR <yes or no>
Enable or disable whether TCP queries are answered. Default is yes.
.It \fBaccess-control:\fR <IP netblock> <action>
The netblock is given as an IP4 or IP6 address with /size appended for a
classless network block. The action can be deny, refuse or allow.
Deny stops queries from hosts from that netblock.
Refuse stops queries too, but sends a DNS rcode REFUSED error message back.
Allow gives access to clients from that netblock.
By default only localhost is allowed, the rest is refused.
.It \fBchroot:\fR <directory>
If given a chroot is done to the given directory. The default is
"/etc/unbound". If you give "" no chroot is performed.
@@ -308,6 +321,102 @@ Number of bytes size of the key cache. Default is 4 megabytes.
Number of slabs in the key cache. Slabs reduce lock contention by threads.
Must be set to a power of 2. Setting (close) to the number of cpus is a
reasonable guess.
.It \fBlocal-zone:\fR <zone> <type>
Configure a local zone. The type determines the answer to give if there is
no match from local-data. The types are deny, refuse, static, transparent,
redirect, nodefault, and are explained below. After that the default settings
are listed. Use local-data: to enter data into the local zone. Answers for
local zones are authoritative DNS answers. By default the zones are class IN.
.Bl -tag -width indent
.It \fIdeny\fR
Do not send an answer, drop the query.
If there is a match from local data, the query is answered.
.It \fIrefuse\fR
Send an error message reply, with rcode REFUSED.
If there is a match from local data, the query is answered.
.It \fIstatic\fR
If there is a match from local data, the query is answered.
Otherwise, the query is answered with nodata or nxdomain.
For a negative answer a SOA is included in the answer if present
as local-data for the zone apex domain.
.It \fItransparent\fR
If there is a match from local data, the query is answered.
Otherwise, the query is resolved normally.
If no local-zone is given local-data causes a transparent zone
to be created by default.
.It \fIredirect\fR
The query is answered from the local data for the zone name.
There may be no local data beneath the zone name.
This answers queries for the zone, and all subdomains of the zone
with the local data for the zone.
It can be used to redirect a domain to a different address, with
local-zone: "example.com." redirect and
local-data: "example.com. A 127.0.0.1"
queries for www.example.com and www.foo.example.com are redirected.
.It \fInodefault\fR
Used to turn off default contents for AS112 zones. The other types
also turn off default contents for the zone. The 'nodefault' option
has no other effect than turning off default contents for the
given zone.
.El
The default zones are localhost, reverse 127.0.0.1 and ::1, and the AS112
zones. The AS112 zones are reverse DNS zones for private use and reserved
IP addresses for which the servers on the internet cannot provide correct
answers. They are configured by default to give nxdomain (no reverse
information) answers. The defaults can be turned off by specifying your
own local-zone of that name, or using the 'nodefault' type. Below is a
list of the default zone contents.
.Bl -tag -width indent
.It \fIlocalhost\fR
The IP4 and IP6 localhost information is given. NS and SOA records are provided
for completeness and to satisfy some DNS update tools. Default content:
.nf
local-zone: "localhost." static
local-data: "localhost. 10800 IN NS localhost."
local-data: "localhost. 10800 IN SOA localhost. nobody.invalid. 1 3600 1200 604800 10800"
local-data: "localhost. 10800 IN A 127.0.0.1"
local-data: "localhost. 10800 IN AAAA ::1"
.fi
.It \fIreverse IPv4 loopback\fR
Default content:
.nf
local-zone: "127.in-addr.arpa." static
local-data: "127.in-addr.arpa. 10800 IN NS localhost."
local-data: "127.in-addr.arpa. 10800 IN SOA localhost. nobody.invalid. 1 3600 1200 604800 10800"
local-data: "1.0.0.127.in-addr.arpa. 10800 IN PTR localhost."
.fi
.It \fIreverse IPv6 loopback\fR
Default content:
.nf
local-zone: "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa." static
local-data: "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. 10800 IN NS localhost."
local-data: "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. 10800 IN SOA localhost. nobody.invalid. 1 3600 1200 604800 10800"
local-data: "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. 10800 IN PTR localhost."
.fi
.It \fIreverse RFC1918 local use zones\fR
Reverse data for zones 10.in-addr.arpa, 16.172.in-addr.arpa to
31.172.in-addr.arpa, 168.192.in-addr.arpa.
The \fBlocal-zone:\fR is set static and as \fBlocal-data:\fR SOA and NS
records are provided.
.It \fIreverse RFC3330 IP4 this, link-local, testnet and broadcast\fR
Reverse data for zones 0.in-addr.arpa, 254.169.in-addr.arpa,
2.0.192.in-addr.arpa, 255.255.255.255.in-addr.arpa.
.It \fIreverse RFC4291 IP6 unspecified\fR
Reverse data for zone 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.
.It \fIreverse RFC4193 IPv6 Locally Assigned Local Addresses\fR
Reverse data for zone D.F.ip6.arpa.
.It \fIreverse RFC4291 IPv6 Link Local Addresses\fR
Reverse data for zones 8.E.F.ip6.arpa to B.E.F.ip6.arpa.
.El
.\" End of local-zone listing.
.It \fBlocal-data:\fR "<resource record string>"
Configure local data, which is served in reply to queries for it.
The query has to match exactly unless you configure the local-zone as
redirect. If not matched exactly, the local-zone type determines
further processing. If local-data is configured that is not a subdomain of
a local-zone, a transparent local-zone is configured.
For record types such as TXT, use single quotes, as in
local-data: 'example. TXT "text"'.
.El
.Ss Stub Zone Options
There may be multiple
+2 -84
View File
@@ -108,63 +108,17 @@ donotq_insert(struct iter_donotq* dq, struct sockaddr_storage* addr,
return 1;
}
/** make sure the netblock ends in zeroes for compare in tree */
static void
mask_block(int ip6, struct sockaddr_storage* addr, int net)
{
uint8_t mask[8] = {0x0, 0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f};
int i, max;
uint8_t* s;
if(ip6) {
s = (uint8_t*)&((struct sockaddr_in6*)addr)->sin6_addr;
max = 128;
} else {
s = (uint8_t*)&((struct sockaddr_in*)addr)->sin_addr;
max = 32;
}
if(net >= max)
return;
for(i=net/8+1; i<max/8; i++) {
s[i] = 0;
}
s[net/8] &= mask[net&0x7];
}
/** apply donotq string */
static int
donotq_str_cfg(struct iter_donotq* dq, const char* str)
{
struct sockaddr_storage addr;
int net;
char* s = NULL;
socklen_t addrlen;
net = (str_is_ip6(str)?128:32);
if((s=strchr(str, '/'))) {
if(atoi(s+1) > net) {
log_err("netblock too large: %s", str);
return 0;
}
net = atoi(s+1);
if(net == 0 && strcmp(s+1, "0") != 0) {
log_err("cannot parse donotquery netblock:"
" '%s'", str);
return 0;
}
if(!(s = strdup(str))) {
log_err("out of memory");
return 0;
}
*strchr(s, '/') = '\0';
}
if(!ipstrtoaddr(s?s:str, UNBOUND_DNS_PORT, &addr, &addrlen)) {
free(s);
log_err("cannot parse donotquery ip address: '%s'", str);
if(!netblockstrtoaddr(str, UNBOUND_DNS_PORT, &addr, &addrlen, &net)) {
log_err("cannot parse donotquery netblock: %s", str);
return 0;
}
if(s) {
free(s);
mask_block(str_is_ip6(str), &addr, net);
}
if(!donotq_insert(dq, &addr, addrlen, net)) {
log_err("out of memory");
return 0;
@@ -185,42 +139,6 @@ read_donotq(struct iter_donotq* dq, struct config_file* cfg)
return 1;
}
/** number of bits that two addrs share (are equal) */
static int
addr_in_common(struct sockaddr_storage* addr1, int net1,
struct sockaddr_storage* addr2, int net2, socklen_t addrlen)
{
int min = (net1<net2)?net1:net2;
int i, to;
int match = 0;
uint8_t* s1, *s2;
if(addr_is_ip6(addr1, addrlen)) {
s1 = (uint8_t*)&((struct sockaddr_in6*)addr1)->sin6_addr;
s2 = (uint8_t*)&((struct sockaddr_in6*)addr2)->sin6_addr;
to = 16;
} else {
s1 = (uint8_t*)&((struct sockaddr_in*)addr1)->sin_addr;
s2 = (uint8_t*)&((struct sockaddr_in*)addr2)->sin_addr;
to = 4;
}
/* match = bits_in_common(s1, s2, to); */
for(i=0; i<to; i++) {
if(s1[i] == s2[i]) {
match += 8;
} else {
uint8_t z = s1[i]^s2[i];
log_assert(z);
while(!(z&0x80)) {
match++;
z<<=1;
}
break;
}
}
if(match > min) match = min;
return match;
}
/** initialise parent pointers in the tree */
static void
donotq_init_parents(struct iter_donotq* donotq)
+3 -3
View File
@@ -54,7 +54,7 @@ struct iter_donotq {
/** regional for allocation */
struct regional* region;
/**
* Tree of the single addresses that are blocked.
* Tree of the address spans that are blocked.
* contents of type iter_donotq_addr.
*/
rbtree_t* tree;
@@ -62,10 +62,10 @@ struct iter_donotq {
/**
* Iterator donotquery address.
* A single address that must not be used to send queries to.
* 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 */
/** redblacktree node, key is this structure: addr and addrlen, net */
rbnode_t node;
/** address */
struct sockaddr_storage addr;
+8
View File
@@ -350,6 +350,10 @@ scrub_normalize(ldns_buffer* pkt, struct msg_parse* msg,
"too long");
return 0;
}
/* internally we have CNAME'd/DNAME'd chains ending
* in nxdomain with NOERROR rcode, change rcode
* to reflect this (if needed) */
FLAGS_SET_RCODE(msg->flags, LDNS_RCODE_NOERROR);
if(nx && nx->type == LDNS_RR_TYPE_CNAME &&
dname_pkt_compare(pkt, sname, nx->dname) == 0) {
/* check next cname */
@@ -392,6 +396,10 @@ scrub_normalize(ldns_buffer* pkt, struct msg_parse* msg,
return 0;
prev = rrset;
rrset = rrset->rrset_all_next;
/* internally we have CNAME'd/DNAME'd chains ending
* in nxdomain with NOERROR rcode, change rcode
* to reflect this (if needed) */
FLAGS_SET_RCODE(msg->flags, LDNS_RCODE_NOERROR);
continue;
}
+23 -1
View File
@@ -224,6 +224,23 @@ error_response(struct module_qstate* qstate, int id, int rcode)
return 0;
}
/** check if prepend item is duplicate item */
static int
prepend_is_duplicate(struct ub_packed_rrset_key** sets, size_t to,
struct ub_packed_rrset_key* dup)
{
size_t i;
for(i=0; i<to; i++) {
if(sets[i]->rk.type == dup->rk.type &&
sets[i]->rk.rrset_class == dup->rk.rrset_class &&
sets[i]->rk.dname_len == dup->rk.dname_len &&
query_dname_compare(sets[i]->rk.dname, dup->rk.dname)
== 0)
return 1;
}
return 0;
}
/** prepend the prepend list in the answer and authority section of dns_msg */
static int
iter_prepend(struct iter_qstate* iq, struct dns_msg* msg,
@@ -253,6 +270,11 @@ iter_prepend(struct iter_qstate* iq, struct dns_msg* msg,
/* AUTH section */
num_ns = 0;
for(p = iq->ns_prepend_list; p; p = p->next) {
if(prepend_is_duplicate(sets+msg->rep->an_numrrsets+num_an,
num_ns, p->rrset) || prepend_is_duplicate(
msg->rep->rrsets+msg->rep->an_numrrsets,
msg->rep->ns_numrrsets, p->rrset))
continue;
sets[msg->rep->an_numrrsets + num_an + num_ns++] = p->rrset;
}
memcpy(sets + num_an + msg->rep->an_numrrsets + num_ns,
@@ -769,7 +791,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
if(iter_dp_is_useless(qstate, iq->dp)) {
if(dname_is_root(iq->dp->name)) {
/* use safety belt */
verbose(VERB_OPS, "Priming problem: NS but "
verbose(VERB_DETAIL, "Cache has root NS but "
"no addresses. Fallback to the safety belt.");
iq->dp = hints_lookup_root(ie->hints,
iq->qchase.qclass);
-2
View File
@@ -137,6 +137,4 @@ struct dns_msg* dns_cache_lookup(struct module_env* env,
int cache_fill_missing(struct module_env* env, uint16_t qclass,
struct regional* region, struct delegpt* dp);
/** Find covering DNAME */
#endif /* SERVICES_CACHE_DNS_H */
+1030
View File
File diff suppressed because it is too large Load Diff
+215
View File
@@ -0,0 +1,215 @@
/*
* services/localzone.h - local zones authority service.
*
* 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 enable local zone authority service.
*/
#ifndef SERVICES_LOCALZONE_H
#define SERVICES_LOCALZONE_H
#include "util/rbtree.h"
struct ub_packed_rrset_key;
struct regional;
struct config_file;
struct edns_data;
struct query_info;
/**
* Local zone type
* This type determines processing for queries that did not match
* local-data directly.
*/
enum localzone_type {
/** drop query */
local_zone_deny = 0,
/** answer with error */
local_zone_refuse,
/** answer nxdomain or nodata */
local_zone_static,
/** resolve normally */
local_zone_transparent,
/** answer with data at zone apex */
local_zone_redirect,
/** remove default AS112 blocking contents for zone
* nodefault is used in config not during service. */
local_zone_nodefault
};
/**
* Authoritative local zones storage, shared.
* This tree is fixed at startup, so, readonly, no locks or mutexes necessary.
*/
struct local_zones {
/** rbtree of struct local_zone */
rbtree_t ztree;
};
/**
* Local zone. A locally served authoritative zone.
*/
struct local_zone {
/** rbtree node, key is name and class */
rbnode_t node;
/** parent zone, if any. */
struct local_zone* parent;
/** zone name, in uncompressed wireformat */
uint8_t* name;
/** length of zone name */
size_t namelen;
/** number of labels in zone name */
int namelabs;
/** the class of this zone.
* uses 'dclass' to not conflict with c++ keyword class. */
uint16_t dclass;
/** how to process zone */
enum localzone_type type;
/** in this region the zone's data is allocated.
* the struct local_zone itself is malloced. */
struct regional* region;
/** local data for this zone
* rbtree of struct local_data */
rbtree_t data;
/** if data contains zone apex SOA data, this is a ptr to it. */
struct ub_packed_rrset_key* soa;
};
/**
* Local data. One domain name, and the RRs to go with it.
*/
struct local_data {
/** rbtree node, key is name only */
rbnode_t node;
/** domain name */
uint8_t* name;
/** length of name */
size_t namelen;
/** number of labels in name */
int namelabs;
/** the data rrsets, with different types, linked list.
* If this list is NULL, the node is an empty non-terminal. */
struct local_rrset* rrsets;
};
/**
* A local data RRset
*/
struct local_rrset {
/** next in list */
struct local_rrset* next;
/** RRset data item */
struct ub_packed_rrset_key* rrset;
};
/**
* Create local zones storage
* @return new struct or NULL on error.
*/
struct local_zones* local_zones_create();
/**
* Delete local zones storage
* @param zones: to delete.
*/
void local_zones_delete(struct local_zones* zones);
/**
* Apply config settings; setup the local authoritative data.
* @param zones: is set up.
* @param cfg: config data.
* @return false on error.
*/
int local_zones_apply_cfg(struct local_zones* zones, struct config_file* cfg);
/**
* Compare two local_zone entries in rbtree. Sort hierarchical but not
* canonical
* @param z1: zone 1
* @param z2: zone 2
* @return: -1, 0, +1 comparison value.
*/
int local_zone_cmp(const void* z1, const void* z2);
/**
* Compare two local_data entries in rbtree. Sort canonical.
* @param d1: data 1
* @param d2: data 2
* @return: -1, 0, +1 comparison value.
*/
int local_data_cmp(const void* d1, const void* d2);
/**
* Delete one zone
* @param z: to delete.
*/
void local_zone_delete(struct local_zone* z);
/**
* Lookup zone that contains the given name, class.
* @param zones: the zones tree
* @param name: dname to lookup
* @param len: length of name.
* @param labs: labelcount of name.
* @param dclass: class to lookup.
* @return closest local_zone or NULL if no covering zone is found.
*/
struct local_zone* local_zones_lookup(struct local_zones* zones,
uint8_t* name, size_t len, int labs, uint16_t dclass);
/**
* Debug helper. Print all zones
* @param zones: the zones tree
*/
void local_zones_print(struct local_zones* zones);
/**
* Answer authoritatively for local zones.
* @param zones: the stored zones (shared, read only).
* @param qinfo: query info (parsed).
* @param edns: edns info (parsed).
* @param buf: buffer with query ID and flags, also for reply.
* @param temp: temporary storage region.
* @return true if answer is in buffer. false if query is not answered
* by authority data. If the reply should be dropped altogether, the return
* value is true, but the buffer is cleared (empty).
*/
int local_zones_answer(struct local_zones* zones, struct query_info* qinfo,
struct edns_data* edns, ldns_buffer* buf, struct regional* temp);
#endif /* SERVICES_LOCALZONE_H */
+2
View File
@@ -150,6 +150,8 @@ outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len)
w->outnet->tcp_free = pend->next_free;
pend->next_free = NULL;
pend->query = w;
pend->c->repinfo.addrlen = w->addrlen;
memcpy(&pend->c->repinfo.addr, &w->addr, w->addrlen);
ldns_buffer_clear(pend->c->buffer);
ldns_buffer_write(pend->c->buffer, pkt, pkt_len);
ldns_buffer_flip(pend->c->buffer);
+14 -35
View File
@@ -60,14 +60,8 @@ struct codeline {
uint64_t alloc;
/** number of bytes freed */
uint64_t free;
};
/**
* Other allocation stats
*/
struct alloc_misc {
/** number of region allocs */
uint64_t region_alloc;
/** number allocations and frees */
uint64_t calls;
};
/** print usage and exit */
@@ -101,18 +95,6 @@ match(char* line)
return 0;
}
/** read up the region stats */
static void
read_region_stat(char* line, struct alloc_misc* misc)
{
long num = 0;
if(sscanf(line+50, "%ld", &num) != 1) {
printf("%s\n%s\n", line, line+50);
fatal_exit("unhandled region");
}
misc->region_alloc += num;
}
/** find or alloc codeline in tree */
static struct codeline*
get_codeline(rbtree_t* tree, char* key, char* func)
@@ -153,6 +135,7 @@ read_malloc_stat(char* line, rbtree_t* tree)
if(!cl)
fatal_exit("alloc failure");
cl->alloc += num;
cl->calls ++;
}
/** read up the calloc stats */
@@ -177,6 +160,7 @@ read_calloc_stat(char* line, rbtree_t* tree)
if(!cl)
fatal_exit("alloc failure");
cl->alloc += num*sz;
cl->calls ++;
}
/** get size of file */
@@ -192,7 +176,7 @@ get_file_size(const char* fname)
/** read the logfile */
static void
readfile(rbtree_t* tree, const char* fname, struct alloc_misc* misc)
readfile(rbtree_t* tree, const char* fname)
{
off_t total = get_file_size(fname);
off_t done = (off_t)0;
@@ -213,8 +197,6 @@ readfile(rbtree_t* tree, const char* fname, struct alloc_misc* misc)
if(!match(buf))
continue;
if(strncmp(buf+36, "region ", 7) == 0)
read_region_stat(buf, misc);
else if(strstr(buf+36, "malloc("))
read_malloc_stat(buf, tree);
else if(strstr(buf+36, "calloc("))
@@ -230,20 +212,19 @@ readfile(rbtree_t* tree, const char* fname, struct alloc_misc* misc)
/** print memory stats */
static void
printstats(rbtree_t* tree, struct alloc_misc* misc)
printstats(rbtree_t* tree)
{
struct codeline* cl;
uint64_t total = 0;
printf("%12lld in region alloc\n", (long long)misc->region_alloc);
total += misc->region_alloc;
uint64_t total = 0, tcalls = 0;
RBTREE_FOR(cl, struct codeline*, tree) {
printf("%12lld in %s %s\n", (long long)cl->alloc,
cl->codeline, cl->func);
printf("%12lld / %8lld in %s %s\n", (long long)cl->alloc,
(long long)cl->calls, cl->codeline, cl->func);
total += cl->alloc;
tcalls += cl->calls;
}
printf("------------\n");
printf("%12lld total in %ld code lines\n", (long long)total,
(long)tree->count);
printf("%12lld / %8lld total in %ld code lines\n", (long long)total,
(long long)tcalls, (long)tree->count);
printf("\n");
}
@@ -251,15 +232,13 @@ printstats(rbtree_t* tree, struct alloc_misc* misc)
int main(int argc, const char* argv[])
{
rbtree_t* tree = 0;
struct alloc_misc misc;
if(argc != 2) {
usage();
}
tree = rbtree_create(codeline_cmp);
if(!tree)
fatal_exit("alloc failure");
memset(&misc, 0, sizeof(misc));
readfile(tree, argv[1], &misc);
printstats(tree, &misc);
readfile(tree, argv[1]);
printstats(tree);
return 0;
}
+8 -1
View File
@@ -208,6 +208,8 @@ replay_moment_read(char* remain, FILE* in, const char* name, int* lineno,
} else if(parse_keyword(&remain, "QUERY")) {
mom->evt_type = repevt_front_query;
readentry = 1;
if(!extstrtoaddr("127.0.0.1", &mom->addr, &mom->addrlen))
fatal_exit("internal error");
} else if(parse_keyword(&remain, "CHECK_ANSWER")) {
mom->evt_type = repevt_front_reply;
readentry = 1;
@@ -229,13 +231,18 @@ replay_moment_read(char* remain, FILE* in, const char* name, int* lineno,
while(isspace((int)*remain))
remain++;
if(parse_keyword(&remain, "ADDRESS")) {
while(isspace((int)*remain))
remain++;
if(strlen(remain) > 0) /* remove \n */
remain[strlen(remain)-1] = 0;
printf("remain '%s'\n", remain);
if(!extstrtoaddr(remain, &mom->addr, &mom->addrlen)) {
log_err("line %d: could not parse ADDRESS: %s",
*lineno, remain);
free(mom);
return NULL;
}
}
}
if(readentry) {
mom->match = read_entry(in, name, lineno, ttl, or, prev);
+121
View File
@@ -89,6 +89,42 @@ alloc_test() {
static void
net_test()
{
char* t4[] = {"\000\000\000\000",
"\200\000\000\000",
"\300\000\000\000",
"\340\000\000\000",
"\360\000\000\000",
"\370\000\000\000",
"\374\000\000\000",
"\376\000\000\000",
"\377\000\000\000",
"\377\200\000\000",
"\377\300\000\000",
"\377\340\000\000",
"\377\360\000\000",
"\377\370\000\000",
"\377\374\000\000",
"\377\376\000\000",
"\377\377\000\000",
"\377\377\200\000",
"\377\377\300\000",
"\377\377\340\000",
"\377\377\360\000",
"\377\377\370\000",
"\377\377\374\000",
"\377\377\376\000",
"\377\377\377\000",
"\377\377\377\200",
"\377\377\377\300",
"\377\377\377\340",
"\377\377\377\360",
"\377\377\377\370",
"\377\377\377\374",
"\377\377\377\376",
"\377\377\377\377",
"\377\377\377\377",
"\377\377\377\377",
};
unit_assert( str_is_ip6("::") );
unit_assert( str_is_ip6("::1") );
unit_assert( str_is_ip6("2001:7b8:206:1:240:f4ff:fe37:8810") );
@@ -117,6 +153,91 @@ net_test()
unit_assert( !is_pow2(23) );
unit_assert( !is_pow2(257) );
unit_assert( !is_pow2(259) );
/* test addr_mask */
if(1) {
struct sockaddr_in a4;
struct sockaddr_in6 a6;
socklen_t l4 = (socklen_t)sizeof(a4);
socklen_t l6 = (socklen_t)sizeof(a6);
int i;
a4.sin_family = AF_INET;
a6.sin6_family = AF_INET6;
for(i=0; i<35; i++) {
/* address 255.255.255.255 */
memcpy(&a4.sin_addr, "\377\377\377\377", 4);
addr_mask((struct sockaddr_storage*)&a4, l4, i);
unit_assert(memcmp(&a4.sin_addr, t4[i], 4) == 0);
}
memcpy(&a6.sin6_addr, "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377", 16);
addr_mask((struct sockaddr_storage*)&a6, l6, 128);
unit_assert(memcmp(&a6.sin6_addr, "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377", 16) == 0);
addr_mask((struct sockaddr_storage*)&a6, l6, 122);
unit_assert(memcmp(&a6.sin6_addr, "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\300", 16) == 0);
addr_mask((struct sockaddr_storage*)&a6, l6, 120);
unit_assert(memcmp(&a6.sin6_addr, "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\000", 16) == 0);
addr_mask((struct sockaddr_storage*)&a6, l6, 64);
unit_assert(memcmp(&a6.sin6_addr, "\377\377\377\377\377\377\377\377\000\000\000\000\000\000\000\000", 16) == 0);
addr_mask((struct sockaddr_storage*)&a6, l6, 0);
unit_assert(memcmp(&a6.sin6_addr, "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000", 16) == 0);
}
/* test addr_in_common */
if(1) {
struct sockaddr_in a4, b4;
struct sockaddr_in6 a6, b6;
socklen_t l4 = (socklen_t)sizeof(a4);
socklen_t l6 = (socklen_t)sizeof(a6);
int i;
a4.sin_family = AF_INET;
b4.sin_family = AF_INET;
a6.sin6_family = AF_INET6;
b6.sin6_family = AF_INET6;
memcpy(&a4.sin_addr, "abcd", 4);
memcpy(&b4.sin_addr, "abcd", 4);
unit_assert(addr_in_common((struct sockaddr_storage*)&a4, 32,
(struct sockaddr_storage*)&b4, 32, l4) == 32);
unit_assert(addr_in_common((struct sockaddr_storage*)&a4, 34,
(struct sockaddr_storage*)&b4, 32, l4) == 32);
for(i=0; i<=32; i++) {
unit_assert(addr_in_common(
(struct sockaddr_storage*)&a4, 32,
(struct sockaddr_storage*)&b4, i, l4) == i);
unit_assert(addr_in_common(
(struct sockaddr_storage*)&a4, i,
(struct sockaddr_storage*)&b4, 32, l4) == i);
unit_assert(addr_in_common(
(struct sockaddr_storage*)&a4, i,
(struct sockaddr_storage*)&b4, i, l4) == i);
}
for(i=0; i<=32; i++) {
memcpy(&a4.sin_addr, "\377\377\377\377", 4);
memcpy(&b4.sin_addr, t4[i], 4);
unit_assert(addr_in_common(
(struct sockaddr_storage*)&a4, 32,
(struct sockaddr_storage*)&b4, 32, l4) == i);
unit_assert(addr_in_common(
(struct sockaddr_storage*)&b4, 32,
(struct sockaddr_storage*)&a4, 32, l4) == i);
}
memcpy(&a6.sin6_addr, "abcdefghabcdefgh", 16);
memcpy(&b6.sin6_addr, "abcdefghabcdefgh", 16);
unit_assert(addr_in_common((struct sockaddr_storage*)&a6, 128,
(struct sockaddr_storage*)&b6, 128, l6) == 128);
unit_assert(addr_in_common((struct sockaddr_storage*)&a6, 129,
(struct sockaddr_storage*)&b6, 128, l6) == 128);
for(i=0; i<=128; i++) {
unit_assert(addr_in_common(
(struct sockaddr_storage*)&a6, 128,
(struct sockaddr_storage*)&b6, i, l6) == i);
unit_assert(addr_in_common(
(struct sockaddr_storage*)&a6, i,
(struct sockaddr_storage*)&b6, 128, l6) == i);
unit_assert(addr_in_common(
(struct sockaddr_storage*)&a6, i,
(struct sockaddr_storage*)&b6, i, l6) == i);
}
}
}
#include "util/rtt.h"
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+52
View File
@@ -0,0 +1,52 @@
; config options
server:
hide-identity: no
hide-version: no
identity: "test-identity"
version: "test-version"
access-control: 20.0.0.0/8 allow
access-control: 20.40.0.0/16 refuse
access-control: 20.40.80.0/24 deny
CONFIG_END
SCENARIO_BEGIN Test access control list
; version.bind.
; allow
STEP 1 QUERY ADDRESS 20.1.2.3
ENTRY_BEGIN
SECTION QUESTION
version.bind. CH TXT
ENTRY_END
STEP 2 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RA
SECTION QUESTION
version.bind. CH TXT
SECTION ANSWER
version.bind. 0 CH TXT "test-version"
ENTRY_END
; refuse
STEP 3 QUERY ADDRESS 20.40.2.3
ENTRY_BEGIN
SECTION QUESTION
version.bind. CH TXT
ENTRY_END
STEP 4 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR REFUSED
ENTRY_END
; deny (drop)
STEP 5 QUERY ADDRESS 20.40.80.3
ENTRY_BEGIN
SECTION QUESTION
version.bind. CH TXT
ENTRY_END
; no answer must be pending
SCENARIO_END
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+60
View File
@@ -0,0 +1,60 @@
; config options
; The island of trust is at example.com
server:
local-zone: "10.in-addr.arpa" nodefault
stub-zone:
name: "."
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
CONFIG_END
SCENARIO_BEGIN Test local data with nodefault for as112 zone.
; K.ROOT-SERVERS.NET.
RANGE_BEGIN 0 100
ADDRESS 193.0.14.129
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
. IN NS
SECTION ANSWER
. IN NS K.ROOT-SERVERS.NET.
SECTION ADDITIONAL
K.ROOT-SERVERS.NET. IN A 193.0.14.129
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NXDOMAIN
SECTION QUESTION
40.30.20.10.in-addr-arpa. IN PTR
SECTION ANSWER
SECTION AUTHORITY
. IN SOA invalid. invalid. 1 2 3 4 5
ENTRY_END
RANGE_END
STEP 1 QUERY
ENTRY_BEGIN
REPLY RD DO
SECTION QUESTION
40.30.20.10.in-addr-arpa. IN PTR
ENTRY_END
; not blocked!
; recursion happens here.
STEP 10 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NXDOMAIN
SECTION QUESTION
40.30.20.10.in-addr-arpa. IN PTR
SECTION ANSWER
SECTION AUTHORITY
. IN SOA invalid. invalid. 1 2 3 4 5
ENTRY_END
SCENARIO_END
+321
View File
@@ -0,0 +1,321 @@
; config options
server:
hide-identity: no
hide-version: no
identity: "test-identity"
version: "test-version"
; implicit transparent zone should not block id.server
local-data: "mydata.server. CH A 10.11.12.13"
local-data: "myd2.server. CH A 10.11.12.14"
local-data: 'myd3.server. CH TXT "a text record"'
; together implicit CH top domain .server is created transparent.
; static zone
local-zone: "local" static
local-data: "local SOA nobody nobody 1 2 3 4 5"
local-data: "serv.local. A 20.30.40.50"
; multiple RRs in this RRset.
local-data: "bla.bla.local. A 20.30.40.51"
local-data: "bla.bla.local. A 20.30.40.52"
local-data: "bla.bla.local. A 20.30.40.53"
; static zone (no soa)
local-zone: "noso.local" static
local-data: "bla.bla.noso.local AAAA 2001::2"
; deny zone (no answer)
local-zone: "deny.top." deny
; refuse zone (error)
local-zone: "refuse.top." refuse
; create implicit data in the IN domain as well
local-data: "a.a.implicit. A 20.30.41.50"
local-data: "b.a.implicit. A 20.30.42.50"
local-data: "b.b.implicit. A 20.30.43.50"
local-data: "b.c.implicit. A 20.30.45.50"
local-data: "c.c.implicit. A 20.30.44.50"
CONFIG_END
SCENARIO_BEGIN Test local data queries
; id.server.
STEP 1 QUERY
ENTRY_BEGIN
SECTION QUESTION
id.server. CH TXT
ENTRY_END
STEP 2 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RA
SECTION QUESTION
id.server. CH TXT
SECTION ANSWER
id.server. 0 CH TXT "test-identity"
ENTRY_END
; mydata.server.
STEP 3 QUERY
ENTRY_BEGIN
SECTION QUESTION
mydata.server. CH A
ENTRY_END
STEP 4 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RA AA
SECTION QUESTION
mydata.server. CH A
SECTION ANSWER
mydata.server. 3600 CH A 10.11.12.13
ENTRY_END
; nodata with SOA
STEP 5 QUERY
ENTRY_BEGIN
SECTION QUESTION
local. IN A
ENTRY_END
STEP 6 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RA AA
SECTION QUESTION
local. IN A
SECTION AUTHORITY
local. 3600 IN SOA nobody nobody 1 2 3 4 5
ENTRY_END
; positive SOA
STEP 7 QUERY
ENTRY_BEGIN
SECTION QUESTION
local. IN SOA
ENTRY_END
STEP 8 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RA AA
SECTION QUESTION
local. IN SOA
SECTION ANSWER
local. 3600 IN SOA nobody nobody 1 2 3 4 5
ENTRY_END
; positive subdomain
STEP 9 QUERY
ENTRY_BEGIN
SECTION QUESTION
serv.local. IN A
ENTRY_END
STEP 10 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RA AA
SECTION QUESTION
serv.local. IN A
SECTION ANSWER
serv.local. IN A 20.30.40.50
ENTRY_END
; no such type
STEP 11 QUERY
ENTRY_BEGIN
SECTION QUESTION
serv.local. IN MX
ENTRY_END
STEP 12 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RA AA
SECTION QUESTION
serv.local. IN MX
SECTION AUTHORITY
local. 3600 IN SOA nobody nobody 1 2 3 4 5
ENTRY_END
; no such type, empty nonterminal
STEP 13 QUERY
ENTRY_BEGIN
SECTION QUESTION
bla.local. IN MX
ENTRY_END
STEP 14 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RA AA
SECTION QUESTION
bla.local. IN MX
SECTION AUTHORITY
local. 3600 IN SOA nobody nobody 1 2 3 4 5
ENTRY_END
; nxdomain with SOA
STEP 15 QUERY
ENTRY_BEGIN
SECTION QUESTION
doing.local. IN MX
ENTRY_END
STEP 16 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RA AA NXDOMAIN
SECTION QUESTION
doing.local. IN MX
SECTION AUTHORITY
local. 3600 IN SOA nobody nobody 1 2 3 4 5
ENTRY_END
; nxdomain without SOA
STEP 17 QUERY
ENTRY_BEGIN
SECTION QUESTION
doing.noso.local. IN MX
ENTRY_END
STEP 18 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RA AA NXDOMAIN
SECTION QUESTION
doing.noso.local. IN MX
ENTRY_END
; positive multiple RR
STEP 19 QUERY
ENTRY_BEGIN
SECTION QUESTION
bla.bla.local. IN A
ENTRY_END
STEP 20 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RA AA
SECTION QUESTION
bla.bla.local. IN A
SECTION ANSWER
bla.bla.local. IN A 20.30.40.51
bla.bla.local. IN A 20.30.40.52
bla.bla.local. IN A 20.30.40.53
ENTRY_END
; second implicit transparent zone.
STEP 21 QUERY
ENTRY_BEGIN
SECTION QUESTION
b.b.implicit. IN A
ENTRY_END
STEP 22 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RA AA
SECTION QUESTION
b.b.implicit. IN A
SECTION ANSWER
b.b.implicit. 3600 IN A 20.30.43.50
ENTRY_END
; localhost A default
STEP 30 QUERY
ENTRY_BEGIN
SECTION QUESTION
localhost. IN A
ENTRY_END
STEP 31 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RA AA
SECTION QUESTION
localhost. IN A
SECTION ANSWER
localhost. 10800 IN A 127.0.0.1
ENTRY_END
; localhost AAAA default
STEP 32 QUERY
ENTRY_BEGIN
SECTION QUESTION
localhost. IN AAAA
ENTRY_END
STEP 33 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RA AA
SECTION QUESTION
localhost. IN AAAA
SECTION ANSWER
localhost. 10800 IN AAAA ::1
ENTRY_END
; localhost A reverse default
STEP 34 QUERY
ENTRY_BEGIN
SECTION QUESTION
1.0.0.127.in-addr.arpa. IN PTR
ENTRY_END
STEP 35 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RA AA
SECTION QUESTION
1.0.0.127.in-addr.arpa. IN PTR
SECTION ANSWER
1.0.0.127.in-addr.arpa. 10800 IN PTR localhost.
ENTRY_END
; localhost AAAA reverse default
STEP 36 QUERY
ENTRY_BEGIN
SECTION QUESTION
1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. IN PTR
ENTRY_END
STEP 37 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RA AA
SECTION QUESTION
1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. IN PTR
SECTION ANSWER
1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. 10800 IN PTR localhost.
ENTRY_END
; blocked AS112 reverse default
STEP 38 QUERY
ENTRY_BEGIN
SECTION QUESTION
1.0.0.10.in-addr.arpa. IN PTR
ENTRY_END
STEP 39 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RA AA NXDOMAIN
SECTION QUESTION
1.0.0.10.in-addr.arpa. IN PTR
SECTION AUTHORITY
10.in-addr.arpa. 10800 IN SOA localhost. nobody.invalid. 1 3600 1200 604800 10800
ENTRY_END
; refuse zone
STEP 40 QUERY
ENTRY_BEGIN
SECTION QUESTION
www.refuse.top. IN A
ENTRY_END
STEP 41 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RA AA REFUSED
SECTION QUESTION
www.refuse.top. IN A
ENTRY_END
; deny zone
STEP 42 QUERY
ENTRY_BEGIN
SECTION QUESTION
www.deny.top. IN A
ENTRY_END
; no answer is checked at exit of testbound.
SCENARIO_END
+150
View File
@@ -0,0 +1,150 @@
; config options
; The island of trust is at example.com
server:
trust-anchor: "example.com. 3600 IN DS 2854 3 1 46e4ffc6e9a4793b488954bd3f0cc6af0dfb201b"
val-override-date: "20070916134226"
stub-zone:
name: "."
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
CONFIG_END
SCENARIO_BEGIN Test validator with cname-nxdomain for duplicate NSEC detection
; K.ROOT-SERVERS.NET.
RANGE_BEGIN 0 100
ADDRESS 193.0.14.129
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
. IN NS
SECTION ANSWER
. IN NS K.ROOT-SERVERS.NET.
SECTION ADDITIONAL
K.ROOT-SERVERS.NET. IN A 193.0.14.129
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
cname.example.com. IN A
SECTION AUTHORITY
com. IN NS a.gtld-servers.net.
SECTION ADDITIONAL
a.gtld-servers.net. IN A 192.5.6.30
ENTRY_END
RANGE_END
; a.gtld-servers.net.
RANGE_BEGIN 0 100
ADDRESS 192.5.6.30
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
cname.example.com. IN A
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
RANGE_END
; ns.example.com.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.4
; response to DNSKEY priming query
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
example.com. IN DNSKEY
SECTION ANSWER
example.com. 3600 IN DNSKEY 256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
example.com. 3600 IN RRSIG DNSKEY 3 2 3600 20070926134802 20070829134802 2854 example.com. MCwCFG1yhRNtTEa3Eno2zhVVuy2EJX3wAhQeLyUp6+UXcpC5qGNu9tkrTEgPUg== ;{id = 2854}
SECTION AUTHORITY
example.com. IN NS ns.example.com.
example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
ENTRY_END
; response to query of interest
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NXDOMAIN
SECTION QUESTION
cname.example.com. IN A
SECTION ANSWER
cname.example.com. 3600 IN CNAME www.example.com.
cname.example.com. 3600 IN RRSIG CNAME 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFBhJC8qi+g+EOYqzT2q6RxE8Im09AhUAotz8NFnpY+cpEDNBKjM940a74/E= ;{id = 2854}
SECTION AUTHORITY
; already includes the necessary NSECs
example.com. IN SOA ns.example.com. hostmaster.example.com. 2007090400 28800 7200 604800 18000
example.com. 3600 IN RRSIG SOA 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFCNGZ+/OfElYQMCZ77O9Lw9rhk7PAhUAmDcvTAst6Bq83qPq3r6c/Dm1nFc= ;{id = 2854}
; wildcard denial
example.com. IN NSEC abc.example.com. SOA NS DNSKEY NSEC RRSIG
example.com. 3600 IN RRSIG NSEC 3 2 3600 20070926134150 20070829134150 2854 example.com. MCwCFHV2IBWyTmDJvZ+sT+WsGrJX0op/AhQkAijjnjPAtx/tNub2FAGqcexJSg== ;{id = 2854}
; qname denial
wab.example.com. IN NSEC wzz.example.com. A NSEC RRSIG
wab.example.com. 3600 IN RRSIG NSEC 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFG5DZSEIZC088rjcB1e6sQx8nQz4AhUAtQ09tP1YYLJkhL/Wg1KV2pW4Ivk= ;{id = 2854}
SECTIO ADDITIONAL
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NXDOMAIN
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
SECTION AUTHORITY
example.com. IN SOA ns.example.com. hostmaster.example.com. 2007090400 28800 7200 604800 18000
example.com. 3600 IN RRSIG SOA 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFCNGZ+/OfElYQMCZ77O9Lw9rhk7PAhUAmDcvTAst6Bq83qPq3r6c/Dm1nFc= ;{id = 2854}
; wildcard denial
example.com. IN NSEC abc.example.com. SOA NS DNSKEY NSEC RRSIG
example.com. 3600 IN RRSIG NSEC 3 2 3600 20070926134150 20070829134150 2854 example.com. MCwCFHV2IBWyTmDJvZ+sT+WsGrJX0op/AhQkAijjnjPAtx/tNub2FAGqcexJSg== ;{id = 2854}
; qname denial
wab.example.com. IN NSEC wzz.example.com. A NSEC RRSIG
wab.example.com. 3600 IN RRSIG NSEC 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFG5DZSEIZC088rjcB1e6sQx8nQz4AhUAtQ09tP1YYLJkhL/Wg1KV2pW4Ivk= ;{id = 2854}
SECTIO ADDITIONAL
ENTRY_END
RANGE_END
STEP 1 QUERY
ENTRY_BEGIN
REPLY RD DO
SECTION QUESTION
cname.example.com. IN A
ENTRY_END
; recursion happens here.
STEP 10 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AD NOERROR
SECTION QUESTION
cname.example.com. IN A
SECTION ANSWER
cname.example.com. 3600 IN CNAME www.example.com.
cname.example.com. 3600 IN RRSIG CNAME 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFBhJC8qi+g+EOYqzT2q6RxE8Im09AhUAotz8NFnpY+cpEDNBKjM940a74/E= ;{id = 2854}
SECTION AUTHORITY
example.com. IN SOA ns.example.com. hostmaster.example.com. 2007090400 28800 7200 604800 18000
example.com. 3600 IN RRSIG SOA 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFCNGZ+/OfElYQMCZ77O9Lw9rhk7PAhUAmDcvTAst6Bq83qPq3r6c/Dm1nFc= ;{id = 2854}
example.com. IN NSEC abc.example.com. SOA NS DNSKEY NSEC RRSIG
example.com. 3600 IN RRSIG NSEC 3 2 3600 20070926134150 20070829134150 2854 example.com. MCwCFHV2IBWyTmDJvZ+sT+WsGrJX0op/AhQkAijjnjPAtx/tNub2FAGqcexJSg== ;{id = 2854}
wab.example.com. IN NSEC wzz.example.com. A NSEC RRSIG
wab.example.com. 3600 IN RRSIG NSEC 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFG5DZSEIZC088rjcB1e6sQx8nQz4AhUAtQ09tP1YYLJkhL/Wg1KV2pW4Ivk= ;{id = 2854}
SECTION ADDITIONAL
ENTRY_END
SCENARIO_END
+183
View File
@@ -0,0 +1,183 @@
; config options
; The island of trust is at example.com
server:
trust-anchor: "example.com. 3600 IN DS 2854 3 1 46e4ffc6e9a4793b488954bd3f0cc6af0dfb201b"
trust-anchor: "example.net. 3600 IN DNSKEY 256 3 5 AQPQ41chR9DEHt/aIzIFAqanbDlRflJoRs5yz1jFsoRIT7dWf0r+PeDuewdxkszNH6wnU4QL8pfKFRh5PIYVBLK3 ;{id = 30899 (zsk), size = 512b}"
val-override-date: "20070916134226"
stub-zone:
name: "."
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
CONFIG_END
SCENARIO_BEGIN Test validator with cname-nxdomain with rcode nxdomain
; K.ROOT-SERVERS.NET.
RANGE_BEGIN 0 100
ADDRESS 193.0.14.129
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
. IN NS
SECTION ANSWER
. IN NS K.ROOT-SERVERS.NET.
SECTION ADDITIONAL
K.ROOT-SERVERS.NET. IN A 193.0.14.129
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION AUTHORITY
com. IN NS a.gtld-servers.net.
SECTION ADDITIONAL
a.gtld-servers.net. IN A 192.5.6.30
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www.example.net. IN A
SECTION AUTHORITY
net. IN NS a.gtld-servers.net.
SECTION ADDITIONAL
a.gtld-servers.net. IN A 192.5.6.30
ENTRY_END
RANGE_END
; a.gtld-servers.net.
RANGE_BEGIN 0 100
ADDRESS 192.5.6.30
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www.example.net. IN A
SECTION AUTHORITY
example.net. IN NS ns.example.net.
SECTION ADDITIONAL
ns.example.net. IN A 1.2.3.5
ENTRY_END
RANGE_END
; ns.example.com.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.4
; response to DNSKEY priming query
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
example.com. IN DNSKEY
SECTION ANSWER
example.com. 3600 IN DNSKEY 256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
example.com. 3600 IN RRSIG DNSKEY DSA 2 3600 20070926134150 20070829134150 2854 example.com. MCwCFBQRtlR4BEv9ohi+PGFjp+AHsJuHAhRCvz0shggvnvI88DFnBDCczHUcVA== ;{id = 2854}
SECTION AUTHORITY
example.com. IN NS ns.example.com.
example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
ENTRY_END
; response to query of interest
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NXDOMAIN
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 3600 IN CNAME www.example.net.
www.example.com. 3600 IN RRSIG CNAME 3 3 3600 20070926134150 20070829134150 2854 example.com. MCwCFGtYzScyRnHV8U/jOIPYwrlI9t3oAhRF0PIf+IthUR7uCWIvskWp5CfReQ== ;{id = 2854}
SECTION AUTHORITY
SECTION ADDITIONAL
ENTRY_END
RANGE_END
; ns.example.net.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.5
; response to DNSKEY priming query
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
example.net. IN DNSKEY
SECTION ANSWER
example.net. 3600 IN DNSKEY 256 3 5 AQPQ41chR9DEHt/aIzIFAqanbDlRflJoRs5yz1jFsoRIT7dWf0r+PeDuewdxkszNH6wnU4QL8pfKFRh5PIYVBLK3 ;{id = 30899 (zsk), size = 512b}
example.net. 3600 IN RRSIG DNSKEY RSASHA1 2 3600 20070926134150 20070829134150 30899 example.net. hiFzlQ8VoYgCuvIsfVuxC3mfJDqsTh0yc6abs5xMx5uEcIjb0dndFQx7INOM+imlzveEN73Hqp4OLFpFhsWLlw== ;{id = 30899}
SECTION AUTHORITY
example.net. IN NS ns.example.net.
example.net. 3600 IN RRSIG NS RSASHA1 2 3600 20070926134150 20070829134150 30899 example.net. E8JX0l4B+cSR5bkHQwOJy1pBmlLMTYCJ8EwfNMU/eCv0YhKwo26rHhn52FGisgv+Nwp7/NbhHqQ+kJgoZC94XA== ;{id = 30899}
SECTION ADDITIONAL
ns.example.net. IN A 1.2.3.5
ns.example.net. 3600 IN RRSIG A RSASHA1 3 3600 20070926134150 20070829134150 30899 example.net. x+tQMC9FhzT7Fcy1pM5NrOC7E8nLd7THPI3C6ie4EwL8PrxllqlR3q/DKB0d/m0qCOPcgN6HFOYURV1s4uAcsw== ;{id = 30899}
ENTRY_END
; response to query of interest
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NXDOMAIN
SECTION QUESTION
www.example.net. IN A
SECTION ANSWER
SECTION AUTHORITY
example.net. IN NSEC abc.example.net. SOA NS DNSKEY NSEC RRSIG
example.net. 3600 IN RRSIG NSEC 5 2 3600 20070926134150 20070829134150 30899 example.net. SEHthmjHyqGlzaOp3Dx6Jn5Fnvvtknw/IF6YSFY8NZLe+YSh1oRJbdEkQ8G92IT08n1jSN6jvKRsFBOUoFOQAw== ;{id = 30899}
wab.example.net. IN NSEC wzz.example.net. A NSEC RRSIG
wab.example.net. 3600 IN RRSIG NSEC 5 3 3600 20070926134150 20070829134150 30899 example.net. gl8vkI3xfSWx4Pyv5OdOthiewE6u/13kclY7UG9ptuFBddamdJO3RQqyxM6Xcmq+ToO4kMCCyaKijp01gTDoGg== ;{id = 30899}
SECTION ADDITIONAL
ENTRY_END
RANGE_END
STEP 1 QUERY
ENTRY_BEGIN
REPLY RD DO
SECTION QUESTION
www.example.com. IN A
ENTRY_END
; recursion happens here.
STEP 10 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA AD NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. IN CNAME www.example.net.
www.example.com. 3600 IN RRSIG CNAME 3 3 3600 20070926134150 20070829134150 2854 example.com. MCwCFGtYzScyRnHV8U/jOIPYwrlI9t3oAhRF0PIf+IthUR7uCWIvskWp5CfReQ== ;{id = 2854}
SECTION AUTHORITY
example.net. IN NSEC abc.example.net. SOA NS DNSKEY NSEC RRSIG
example.net. 3600 IN RRSIG NSEC 5 2 3600 20070926134150 20070829134150 30899 example.net. SEHthmjHyqGlzaOp3Dx6Jn5Fnvvtknw/IF6YSFY8NZLe+YSh1oRJbdEkQ8G92IT08n1jSN6jvKRsFBOUoFOQAw== ;{id = 30899}
wab.example.net. IN NSEC wzz.example.net. A NSEC RRSIG
wab.example.net. 3600 IN RRSIG NSEC 5 3 3600 20070926134150 20070829134150 30899 example.net. gl8vkI3xfSWx4Pyv5OdOthiewE6u/13kclY7UG9ptuFBddamdJO3RQqyxM6Xcmq+ToO4kMCCyaKijp01gTDoGg== ;{id = 30899}
SECTION ADDITIONAL
ENTRY_END
SCENARIO_END
+39 -3
View File
@@ -89,7 +89,7 @@ config_create()
cfg->host_ttl = 900;
cfg->lame_ttl = 900;
cfg->bogus_ttl = 900;
cfg->max_ttl = 3600 * 24 * 10;
cfg->max_ttl = 3600 * 24;
cfg->infra_cache_slabs = 4;
cfg->infra_cache_numhosts = 10000;
cfg->infra_cache_lame_size = 10240; /* easily 40 or more entries */
@@ -110,6 +110,7 @@ config_create()
cfg->out_ifs = NULL;
cfg->stubs = NULL;
cfg->forwards = NULL;
cfg->acls = NULL;
cfg->harden_short_bufsize = 0;
cfg->harden_large_queries = 0;
cfg->harden_glue = 1;
@@ -126,6 +127,9 @@ config_create()
cfg->val_permissive_mode = 0;
cfg->key_cache_size = 4 * 1024 * 1024;
cfg->key_cache_slabs = 4;
cfg->local_zones = NULL;
cfg->local_zones_nodefault = NULL;
cfg->local_data = NULL;
if(!(cfg->module_conf = strdup("validator iterator"))) goto error_exit;
if(!(cfg->val_nsec3_key_iterations =
strdup("1024 150 2048 500 4096 2500"))) goto error_exit;
@@ -171,8 +175,7 @@ config_read(struct config_file* cfg, char* filename)
return 1;
}
/** delete config strlist */
static void
void
config_delstrlist(struct config_strlist* p)
{
struct config_strlist *np;
@@ -184,6 +187,19 @@ config_delstrlist(struct config_strlist* p)
}
}
void
config_deldblstrlist(struct config_str2list* p)
{
struct config_str2list *np;
while(p) {
np = p->next;
free(p->str);
free(p->str2);
free(p);
p = np;
}
}
/** delete config stublist */
static void
config_delstubs(struct config_stub* p)
@@ -231,7 +247,11 @@ config_delete(struct config_file* cfg)
config_delstrlist(cfg->trust_anchor_file_list);
config_delstrlist(cfg->trusted_keys_file_list);
config_delstrlist(cfg->trust_anchor_list);
config_deldblstrlist(cfg->acls);
free(cfg->val_nsec3_key_iterations);
config_deldblstrlist(cfg->local_zones);
config_delstrlist(cfg->local_zones_nodefault);
config_delstrlist(cfg->local_data);
free(cfg);
}
@@ -281,6 +301,22 @@ cfg_strlist_insert(struct config_strlist** head, char* item)
return 1;
}
int
cfg_str2list_insert(struct config_str2list** head, char* item, char* i2)
{
struct config_str2list *s;
if(!item || !i2 || !head)
return 0;
s = (struct config_str2list*)calloc(1, sizeof(struct config_str2list));
if(!s)
return 0;
s->str = item;
s->str2 = i2;
s->next = *head;
*head = s;
return 1;
}
uint32_t
cfg_convert_timeval(const char* str)
{
+43
View File
@@ -43,6 +43,7 @@
#define UTIL_CONFIG_FILE_H
struct config_stub;
struct config_strlist;
struct config_str2list;
/**
* The configuration options.
@@ -120,6 +121,8 @@ struct config_file {
struct config_stub* forwards;
/** list of donotquery addresses, linked list */
struct config_strlist* donotqueryaddrs;
/** list of access control entries, linked list */
struct config_str2list* acls;
/** use default localhost donotqueryaddr entries */
int donotquery_localhost;
@@ -183,6 +186,13 @@ struct config_file {
/** slabs in the key cache. */
size_t key_cache_slabs;
/** local zones config */
struct config_str2list* local_zones;
/** local zones nodefault list */
struct config_strlist* local_zones_nodefault;
/** local data RRs configged */
struct config_strlist* local_data;
/** daemonize, i.e. fork into the background. */
int do_daemonize;
};
@@ -211,6 +221,18 @@ struct config_strlist {
char* str;
};
/**
* List of two strings for config options
*/
struct config_str2list {
/** next item in list */
struct config_str2list* next;
/** first string */
char* str;
/** second string */
char* str2;
};
/**
* Create config file structure. Filled with default values.
* @return: the new structure or NULL on memory error.
@@ -245,6 +267,27 @@ void config_apply(struct config_file* config);
*/
int cfg_strlist_insert(struct config_strlist** head, char* item);
/**
* Insert string into str2list.
* @param head: pointer to str2list head variable.
* @param item: new item. malloced by caller. If NULL the insertion fails.
* @param i2: 2nd string, malloced by caller. If NULL the insertion fails.
* @return: true on success.
*/
int cfg_str2list_insert(struct config_str2list** head, char* item, char* i2);
/**
* Delete items in config string list.
* @param list: list.
*/
void config_delstrlist(struct config_strlist* list);
/**
* Delete items in config double string list.
* @param list: list.
*/
void config_deldblstrlist(struct config_str2list* list);
/**
* Convert 14digit to time value
* @param str: string of 14 digits
+735 -646
View File
File diff suppressed because it is too large Load Diff
+27 -5
View File
@@ -87,13 +87,14 @@ static void config_end_include(void)
SPACE [ \t]
LETTER [a-zA-Z]
UNQUOTEDLETTER [^\"\n\r \t\\]|\\.
UNQUOTEDLETTER [^\'\"\n\r \t\\]|\\.
NEWLINE [\r\n]
COMMENT \#
COLON \:
ANY [^\"\n\r\\]|\\.
DQANY [^\"\n\r\\]|\\.
SQANY [^\'\n\r\\]|\\.
%x quotedstring include include_quoted
%x quotedstring singlequotedstr include include_quoted
%%
{SPACE}* { LEXOUT(("SP ")); /* ignore */ }
@@ -144,6 +145,7 @@ 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;}
do-not-query-localhost{COLON} { YDOUT; return VAR_DO_NOT_QUERY_LOCALHOST;}
access-control{COLON} { YDOUT; return VAR_ACCESS_CONTROL;}
hide-identity{COLON} { YDOUT; return VAR_HIDE_IDENTITY;}
hide-version{COLON} { YDOUT; return VAR_HIDE_VERSION;}
identity{COLON} { YDOUT; return VAR_IDENTITY;}
@@ -160,6 +162,8 @@ key-cache-size{COLON} { YDOUT; return VAR_KEY_CACHE_SIZE;}
key-cache-slabs{COLON} { YDOUT; return VAR_KEY_CACHE_SLABS;}
val-nsec3-keysize-iterations{COLON} { YDOUT; return VAR_VAL_NSEC3_KEYSIZE_ITERATIONS;}
use-syslog{COLON} { YDOUT; return VAR_USE_SYSLOG;}
local-zone{COLON} { YDOUT; return VAR_LOCAL_ZONE;}
local-data{COLON} { YDOUT; return VAR_LOCAL_DATA;}
{NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++;}
/* Quoted strings. Strip leading and ending quotes */
@@ -168,7 +172,7 @@ use-syslog{COLON} { YDOUT; return VAR_USE_SYSLOG;}
yyerror("EOF inside quoted string");
BEGIN(INITIAL);
}
<quotedstring>{ANY}* { LEXOUT(("STR(%s) ", yytext)); yymore(); }
<quotedstring>{DQANY}* { LEXOUT(("STR(%s) ", yytext)); yymore(); }
<quotedstring>\n { cfg_parser->line++; yymore(); }
<quotedstring>\" {
LEXOUT(("QE "));
@@ -180,6 +184,24 @@ use-syslog{COLON} { YDOUT; return VAR_USE_SYSLOG;}
return STRING;
}
/* Single Quoted strings. Strip leading and ending quotes */
\' { BEGIN(singlequotedstr); LEXOUT(("SQS ")); }
<singlequotedstr><<EOF>> {
yyerror("EOF inside quoted string");
BEGIN(INITIAL);
}
<singlequotedstr>{SQANY}* { LEXOUT(("STR(%s) ", yytext)); yymore(); }
<singlequotedstr>\n { cfg_parser->line++; yymore(); }
<singlequotedstr>\' {
LEXOUT(("SQE "));
BEGIN(INITIAL);
yytext[yyleng - 1] = '\0';
yylval.str = strdup(yytext);
if(!yylval.str)
yyerror("out of memory");
return STRING;
}
/* include: directive */
include{COLON} { LEXOUT(("v(%s) ", yytext)); BEGIN(include); }
<include><<EOF>> {
@@ -198,7 +220,7 @@ include{COLON} { LEXOUT(("v(%s) ", yytext)); BEGIN(include); }
yyerror("EOF inside quoted string");
BEGIN(INITIAL);
}
<include_quoted>{ANY}* { LEXOUT(("ISTR(%s) ", yytext)); yymore(); }
<include_quoted>{DQANY}* { LEXOUT(("ISTR(%s) ", yytext)); yymore(); }
<include_quoted>{NEWLINE} { cfg_parser->line++; yymore(); }
<include_quoted>\" {
LEXOUT(("IQE "));
+338 -272
View File
File diff suppressed because it is too large Load Diff
+8 -2
View File
@@ -108,7 +108,10 @@
VAR_ROOT_HINTS = 324,
VAR_DO_NOT_QUERY_LOCALHOST = 325,
VAR_CACHE_MAX_TTL = 326,
VAR_HARDEN_DNNSEC_STRIPPED = 327
VAR_HARDEN_DNNSEC_STRIPPED = 327,
VAR_ACCESS_CONTROL = 328,
VAR_LOCAL_ZONE = 329,
VAR_LOCAL_DATA = 330
};
#endif
/* Tokens. */
@@ -182,6 +185,9 @@
#define VAR_DO_NOT_QUERY_LOCALHOST 325
#define VAR_CACHE_MAX_TTL 326
#define VAR_HARDEN_DNNSEC_STRIPPED 327
#define VAR_ACCESS_CONTROL 328
#define VAR_LOCAL_ZONE 329
#define VAR_LOCAL_DATA 330
@@ -193,7 +199,7 @@ typedef union YYSTYPE
char* str;
}
/* Line 1489 of yacc.c. */
#line 197 "util/configparser.h"
#line 203 "util/configparser.h"
YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
+43 -2
View File
@@ -86,7 +86,8 @@ extern struct config_parser_state* cfg_parser;
%token VAR_KEY_CACHE_SLABS VAR_TRUSTED_KEYS_FILE
%token VAR_VAL_NSEC3_KEYSIZE_ITERATIONS VAR_USE_SYSLOG
%token VAR_OUTGOING_INTERFACE VAR_ROOT_HINTS VAR_DO_NOT_QUERY_LOCALHOST
%token VAR_CACHE_MAX_TTL VAR_HARDEN_DNNSEC_STRIPPED
%token VAR_CACHE_MAX_TTL VAR_HARDEN_DNNSEC_STRIPPED VAR_ACCESS_CONTROL
%token VAR_LOCAL_ZONE VAR_LOCAL_DATA
%%
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
@@ -124,7 +125,8 @@ content_server: server_num_threads | server_verbosity | server_port |
server_trusted_keys_file | server_val_nsec3_keysize_iterations |
server_use_syslog | server_outgoing_interface | server_root_hints |
server_do_not_query_localhost | server_cache_max_ttl |
server_harden_dnssec_stripped
server_harden_dnssec_stripped | server_access_control |
server_local_zone | server_local_data
;
stubstart: VAR_STUB_ZONE
{
@@ -574,6 +576,19 @@ server_do_not_query_localhost: VAR_DO_NOT_QUERY_LOCALHOST STRING
free($2);
}
;
server_access_control: VAR_ACCESS_CONTROL STRING STRING
{
OUTYY(("P(server_access_control:%s %s)\n", $2, $3));
if(strcmp($3, "deny")!=0 && strcmp($3, "refuse")!=0 &&
strcmp($3, "allow")!=0) {
yyerror("expected deny, refuse or allow in "
"access control action");
} else {
if(!cfg_str2list_insert(&cfg_parser->cfg->acls, $2, $3))
fatal_exit("out of memory adding acl");
}
}
;
server_module_conf: VAR_MODULE_CONF STRING
{
OUTYY(("P(server_module_conf:%s)\n", $2));
@@ -666,6 +681,32 @@ server_key_cache_slabs: VAR_KEY_CACHE_SLABS STRING
free($2);
}
;
server_local_zone: VAR_LOCAL_ZONE STRING STRING
{
OUTYY(("P(server_local_zone:%s %s)\n", $2, $3));
if(strcmp($3, "static")!=0 && strcmp($3, "deny")!=0 &&
strcmp($3, "refuse")!=0 && strcmp($3, "redirect")!=0 &&
strcmp($3, "transparent")!=0 && strcmp($3, "nodefault")!=0)
yyerror("local-zone type: expected static, deny, "
"refuse, redirect, transparent or nodefault");
else if(strcmp($3, "nodefault")==0) {
if(!cfg_strlist_insert(&cfg_parser->cfg->
local_zones_nodefault, $2))
fatal_exit("out of memory adding local-zone");
} else {
if(!cfg_str2list_insert(&cfg_parser->cfg->local_zones,
$2, $3))
fatal_exit("out of memory adding local-zone");
}
}
;
server_local_data: VAR_LOCAL_DATA STRING
{
OUTYY(("P(server_local_data:%s)\n", $2));
if(!cfg_strlist_insert(&cfg_parser->cfg->local_data, $2))
fatal_exit("out of memory adding local-data");
}
;
stub_name: VAR_NAME STRING
{
OUTYY(("P(name:%s)\n", $2));
+1 -1
View File
@@ -68,7 +68,7 @@ struct rr_parse;
struct regional;
/** number of buckets in parse rrset hash table. Must be power of 2. */
#define PARSE_TABLE_SIZE 1024
#define PARSE_TABLE_SIZE 32
/** Maximum TTL that is allowed. */
extern uint32_t MAX_TTL;
/** Negative cache time (for entries without any RRs.) */
+5
View File
@@ -49,6 +49,7 @@
#include "daemon/worker.h"
#include "services/outside_network.h"
#include "services/mesh.h"
#include "services/localzone.h"
#include "services/cache/infra.h"
#include "iterator/iterator.h"
#include "iterator/iter_donotq.h"
@@ -64,6 +65,7 @@
#include "util/storage/slabhash.h"
#include "util/locks.h"
#include "testcode/checklocks.h"
#include "daemon/acl_list.h"
int
fptr_whitelist_comm_point(comm_point_callback_t *fptr)
@@ -130,6 +132,9 @@ fptr_whitelist_rbtree_cmp(int (*fptr) (const void *, const void *))
{
if(fptr == &mesh_state_compare) return 1;
else if(fptr == &mesh_state_ref_compare) return 1;
else if(fptr == &acl_list_cmp) return 1;
else if(fptr == &local_zone_cmp) return 1;
else if(fptr == &local_data_cmp) return 1;
else if(fptr == &donotq_cmp) return 1;
else if(fptr == &fwd_cmp) return 1;
else if(fptr == &stub_cmp) return 1;
+140 -51
View File
@@ -58,25 +58,25 @@ str_is_ip6(const char* str)
int
write_socket(int s, const void *buf, size_t size)
{
const char* data = (const char*)buf;
size_t total_count = 0;
const char* data = (const char*)buf;
size_t total_count = 0;
fd_set_block(s);
while (total_count < size) {
ssize_t count
= write(s, data + total_count, size - total_count);
if (count == -1) {
if (errno != EAGAIN && errno != EINTR) {
while (total_count < size) {
ssize_t count
= write(s, data + total_count, size - total_count);
if (count == -1) {
if (errno != EAGAIN && errno != EINTR) {
fd_set_nonblock(s);
return 0;
} else {
continue;
}
}
total_count += count;
}
return 0;
} else {
continue;
}
}
total_count += count;
}
fd_set_nonblock(s);
return 1;
return 1;
}
int
@@ -149,27 +149,27 @@ void
log_addr(enum verbosity_value v, const char* str,
struct sockaddr_storage* addr, socklen_t addrlen)
{
uint16_t port;
const char* family = "unknown";
char dest[100];
int af = (int)((struct sockaddr_in*)addr)->sin_family;
void* sinaddr = &((struct sockaddr_in*)addr)->sin_addr;
uint16_t port;
const char* family = "unknown";
char dest[100];
int af = (int)((struct sockaddr_in*)addr)->sin_family;
void* sinaddr = &((struct sockaddr_in*)addr)->sin_addr;
if(verbosity < v)
return;
switch(af) {
case AF_INET: family="ip4"; break;
case AF_INET6: family="ip6";
sinaddr = &((struct sockaddr_in6*)addr)->sin6_addr;
break;
case AF_UNIX: family="unix"; break;
default: break;
}
if(inet_ntop(af, sinaddr, dest, (socklen_t)sizeof(dest)) == 0) {
strncpy(dest, "(inet_ntop error)", sizeof(dest));
}
switch(af) {
case AF_INET: family="ip4"; break;
case AF_INET6: family="ip6";
sinaddr = &((struct sockaddr_in6*)addr)->sin6_addr;
break;
case AF_UNIX: family="unix"; break;
default: break;
}
if(inet_ntop(af, sinaddr, dest, (socklen_t)sizeof(dest)) == 0) {
strncpy(dest, "(inet_ntop error)", sizeof(dest));
}
dest[sizeof(dest)-1] = 0;
port = ntohs(((struct sockaddr_in*)addr)->sin_port);
log_info("%s %s %s %d (len %d)", str, family, dest, (int)port,
port = ntohs(((struct sockaddr_in*)addr)->sin_port);
log_info("%s %s %s %d (len %d)", str, family, dest, (int)port,
(int)addrlen);
}
@@ -229,6 +229,39 @@ ipstrtoaddr(const char* ip, int port, struct sockaddr_storage* addr,
return 1;
}
int netblockstrtoaddr(const char* str, int port, struct sockaddr_storage* addr,
socklen_t* addrlen, int* net)
{
char* s = NULL;
*net = (str_is_ip6(str)?128:32);
if((s=strchr(str, '/'))) {
if(atoi(s+1) > *net) {
log_err("netblock too large: %s", str);
return 0;
}
*net = atoi(s+1);
if(net == 0 && strcmp(s+1, "0") != 0) {
log_err("cannot parse netblock: '%s'", str);
return 0;
}
if(!(s = strdup(str))) {
log_err("out of memory");
return 0;
}
*strchr(s, '/') = '\0';
}
if(!ipstrtoaddr(s?s:str, port, addr, addrlen)) {
free(s);
log_err("cannot parse ip address: '%s'", str);
return 0;
}
if(s) {
free(s);
addr_mask(addr, *addrlen, *net);
}
return 1;
}
void
log_nametypeclass(enum verbosity_value v, const char* str, uint8_t* name,
uint16_t type, uint16_t dclass)
@@ -264,32 +297,32 @@ log_nametypeclass(enum verbosity_value v, const char* str, uint8_t* name,
void log_name_addr(enum verbosity_value v, const char* str, uint8_t* zone,
struct sockaddr_storage* addr, socklen_t addrlen)
{
uint16_t port;
const char* family = "unknown_family ";
uint16_t port;
const char* family = "unknown_family ";
char namebuf[LDNS_MAX_DOMAINLEN+1];
char dest[100];
int af = (int)((struct sockaddr_in*)addr)->sin_family;
void* sinaddr = &((struct sockaddr_in*)addr)->sin_addr;
char dest[100];
int af = (int)((struct sockaddr_in*)addr)->sin_family;
void* sinaddr = &((struct sockaddr_in*)addr)->sin_addr;
if(verbosity < v)
return;
switch(af) {
case AF_INET: family=""; break;
case AF_INET6: family="";
sinaddr = &((struct sockaddr_in6*)addr)->sin6_addr;
break;
case AF_UNIX: family="unix_family "; break;
default: break;
}
if(inet_ntop(af, sinaddr, dest, (socklen_t)sizeof(dest)) == 0) {
strncpy(dest, "(inet_ntop error)", sizeof(dest));
}
switch(af) {
case AF_INET: family=""; break;
case AF_INET6: family="";
sinaddr = &((struct sockaddr_in6*)addr)->sin6_addr;
break;
case AF_UNIX: family="unix_family "; break;
default: break;
}
if(inet_ntop(af, sinaddr, dest, (socklen_t)sizeof(dest)) == 0) {
strncpy(dest, "(inet_ntop error)", sizeof(dest));
}
dest[sizeof(dest)-1] = 0;
port = ntohs(((struct sockaddr_in*)addr)->sin_port);
port = ntohs(((struct sockaddr_in*)addr)->sin_port);
dname_str(zone, namebuf);
if(af != AF_INET && af != AF_INET6)
verbose(VERB_DETAIL, "%s <%s> %s%s#%d (addrlen %d)",
str, namebuf, family, dest, (int)port, (int)addrlen);
else verbose(VERB_DETAIL, "%s <%s> %s%s#%d",
else verbose(VERB_DETAIL, "%s <%s> %s%s#%d",
str, namebuf, family, dest, (int)port);
}
@@ -373,3 +406,59 @@ addr_is_ip6(struct sockaddr_storage* addr, socklen_t len)
return 1;
else return 0;
}
void
addr_mask(struct sockaddr_storage* addr, socklen_t len, int net)
{
uint8_t mask[8] = {0x0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe};
int i, max;
uint8_t* s;
if(addr_is_ip6(addr, len)) {
s = (uint8_t*)&((struct sockaddr_in6*)addr)->sin6_addr;
max = 128;
} else {
s = (uint8_t*)&((struct sockaddr_in*)addr)->sin_addr;
max = 32;
}
if(net >= max)
return;
for(i=net/8+1; i<max/8; i++) {
s[i] = 0;
}
s[net/8] &= mask[net&0x7];
}
int
addr_in_common(struct sockaddr_storage* addr1, int net1,
struct sockaddr_storage* addr2, int net2, socklen_t addrlen)
{
int min = (net1<net2)?net1:net2;
int i, to;
int match = 0;
uint8_t* s1, *s2;
if(addr_is_ip6(addr1, addrlen)) {
s1 = (uint8_t*)&((struct sockaddr_in6*)addr1)->sin6_addr;
s2 = (uint8_t*)&((struct sockaddr_in6*)addr2)->sin6_addr;
to = 16;
} else {
s1 = (uint8_t*)&((struct sockaddr_in*)addr1)->sin_addr;
s2 = (uint8_t*)&((struct sockaddr_in*)addr2)->sin_addr;
to = 4;
}
/* match = bits_in_common(s1, s2, to); */
for(i=0; i<to; i++) {
if(s1[i] == s2[i]) {
match += 8;
} else {
uint8_t z = s1[i]^s2[i];
log_assert(z);
while(!(z&0x80)) {
match++;
z<<=1;
}
break;
}
}
if(match > min) match = min;
return match;
}
+36
View File
@@ -186,6 +186,19 @@ int extstrtoaddr(const char* str, struct sockaddr_storage* addr,
int ipstrtoaddr(const char* ip, int port, struct sockaddr_storage* addr,
socklen_t* addrlen);
/**
* Convert ip netblock (ip/netsize) string and port to sockaddr.
* *SLOW*, does a malloc internally to avoid writing over 'ip' string.
* @param ip: ip4 or ip6 address string.
* @param port: port number, host format.
* @param addr: where to store sockaddr.
* @param addrlen: length of stored sockaddr is returned.
* @param net: netblock size is returned.
* @return 0 on error.
*/
int netblockstrtoaddr(const char* ip, int port, struct sockaddr_storage* addr,
socklen_t* addrlen, int* net);
/**
* Print string with neat domain name, type and class.
* @param v: at what verbosity level to print this.
@@ -228,4 +241,27 @@ int sockaddr_cmp_addr(struct sockaddr_storage* addr1, socklen_t len1,
*/
int addr_is_ip6(struct sockaddr_storage* addr, socklen_t len);
/**
* Make sure the sockaddr ends in zeroes. For tree insertion and subsequent
* comparison.
* @param addr: the ip4 or ip6 addr.
* @Param len: lentgh of addr.
* @param net: number of bits to leave untouched, the rest of the netblock
* address is zeroed.
*/
void addr_mask(struct sockaddr_storage* addr, socklen_t len, int net);
/**
* See how many bits are shared, equal, between two addrs.
* @param addr1: first addr.
* @param net1: netblock size of first addr.
* @param addr2: second addr.
* @param net2: netblock size of second addr.
* @param addrlen: length of first addr and of second addr.
* They must be of the same length (i.e. same type IP4, IP6).
* @return: number of bits the same.
*/
int addr_in_common(struct sockaddr_storage* addr1, int net1,
struct sockaddr_storage* addr2, int net2, socklen_t addrlen);
#endif /* NET_HELP_H */
+13 -16
View File
@@ -229,18 +229,23 @@ void
comm_point_tcp_accept_callback(int fd, short event, void* arg)
{
struct comm_point* c = (struct comm_point*)arg, *c_hdl;
struct comm_reply rep;
int new_fd;
log_assert(c->type == comm_tcp_accept);
if(!(event & EV_READ)) {
log_info("ignoring tcp accept event %d", (int)event);
return;
}
/* find free tcp handler. */
if(!c->tcp_free) {
log_warn("accepted too many tcp, connections full");
return;
}
/* accept incoming connection. */
rep.c = NULL;
rep.addrlen = (socklen_t)sizeof(rep.addr);
c_hdl = c->tcp_free;
c_hdl->repinfo.addrlen = (socklen_t)sizeof(c_hdl->repinfo.addr);
log_assert(fd != -1);
new_fd = accept(fd, (struct sockaddr*)&rep.addr, &rep.addrlen);
new_fd = accept(fd, (struct sockaddr*)&c_hdl->repinfo.addr,
&c_hdl->repinfo.addrlen);
if(new_fd == -1) {
/* EINTR is signal interrupt. others are closed connection. */
if( errno != EINTR
@@ -254,14 +259,7 @@ comm_point_tcp_accept_callback(int fd, short event, void* arg)
log_err("accept failed: %s", strerror(errno));
return;
}
/* find free tcp handler. */
if(!c->tcp_free) {
log_err("accepted too many tcp, connections full");
close(new_fd);
return;
}
/* grab it */
c_hdl = c->tcp_free;
/* grab the tcp handler buffers */
c->tcp_free = c_hdl->tcp_free;
if(!c->tcp_free) {
/* stop accepting incoming queries for now. */
@@ -307,7 +305,6 @@ tcp_callback_writer(struct comm_point* c)
static void
tcp_callback_reader(struct comm_point* c)
{
struct comm_reply rep;
log_assert(c->type == comm_tcp || c->type == comm_local);
ldns_buffer_flip(c->buffer);
if(c->tcp_do_toggle_rw)
@@ -315,10 +312,8 @@ tcp_callback_reader(struct comm_point* c)
c->tcp_byte_count = 0;
if(c->type == comm_tcp)
comm_point_stop_listening(c);
rep.c = c;
rep.addrlen = 0;
log_assert(fptr_whitelist_comm_point(c->callback));
if( (*c->callback)(c, c->cb_arg, NETEVENT_NOERROR, &rep) ) {
if( (*c->callback)(c, c->cb_arg, NETEVENT_NOERROR, &c->repinfo) ) {
comm_point_start_listening(c, -1, TCP_QUERY_TIMEOUT);
}
}
@@ -608,6 +603,7 @@ comm_point_create_tcp_handler(struct comm_base *base,
c->do_not_close = 0;
c->tcp_do_toggle_rw = 1;
c->tcp_check_nb_connect = 0;
c->repinfo.c = c;
c->callback = callback;
c->cb_arg = callback_arg;
/* add to parent free list */
@@ -724,6 +720,7 @@ comm_point_create_tcp_out(struct comm_base *base, size_t bufsize,
c->do_not_close = 0;
c->tcp_do_toggle_rw = 1;
c->tcp_check_nb_connect = 1;
c->repinfo.c = c;
c->callback = callback;
c->cb_arg = callback_arg;
evbits = EV_PERSIST | EV_WRITE;
+14 -12
View File
@@ -88,6 +88,18 @@ struct comm_base {
struct internal_base* eb;
};
/**
* Reply information for a communication point.
*/
struct comm_reply {
/** the comm_point with fd to send reply on to. */
struct comm_point* c;
/** the address (for UDP based communication) */
struct sockaddr_storage addr;
/** length of address */
socklen_t addrlen;
};
/**
* Communication point to the network
* These behaviours can be accomplished by setting the flags
@@ -117,6 +129,8 @@ struct comm_point {
size_t tcp_byte_count;
/** parent communication point (for TCP sockets) */
struct comm_point* tcp_parent;
/** sockaddr from peer, for TCP handlers */
struct comm_reply repinfo;
/* -------- TCP Accept -------- */
/** the number of TCP handlers for this tcp-accept socket */
@@ -187,18 +201,6 @@ struct comm_point {
void *cb_arg;
};
/**
* Reply information for a communication point.
*/
struct comm_reply {
/** the comm_point with fd to send reply on to. */
struct comm_point* c;
/** the address (for UDP based communication) */
struct sockaddr_storage addr;
/** length of address */
socklen_t addrlen;
};
/**
* Structure only for making timeout events.
*/
+2 -2
View File
@@ -748,7 +748,6 @@ canonical_compare(struct ub_packed_rrset_key* rrset, size_t i, size_t j)
*/
/* type starts with the name; remainder is binary compared */
case LDNS_RR_TYPE_NXT:
case LDNS_RR_TYPE_NSEC:
/* use rdata field formats */
case LDNS_RR_TYPE_MINFO:
case LDNS_RR_TYPE_RP:
@@ -758,7 +757,6 @@ canonical_compare(struct ub_packed_rrset_key* rrset, size_t i, size_t j)
case LDNS_RR_TYPE_KX:
case LDNS_RR_TYPE_MX:
case LDNS_RR_TYPE_SIG:
case LDNS_RR_TYPE_RRSIG:
case LDNS_RR_TYPE_PX:
case LDNS_RR_TYPE_NAPTR:
case LDNS_RR_TYPE_SRV:
@@ -773,6 +771,8 @@ canonical_compare(struct ub_packed_rrset_key* rrset, size_t i, size_t j)
case LDNS_RR_TYPE_HINFO:
return canonical_compare_hinfo(d, i, j);
case LDNS_RR_TYPE_NSEC:
case LDNS_RR_TYPE_RRSIG:
default:
/* For unknown RR types, or types not listed above,
* no canonicalization is needed, do binary compare */
+18 -3
View File
@@ -64,9 +64,24 @@ val_classify_response(uint16_t query_flags, struct query_info* qinf,
if(rcode == LDNS_RCODE_NXDOMAIN && rep->an_numrrsets == 0)
return VAL_CLASS_NAMEERROR;
/* check for referral: nonRD query */
if(!(query_flags&BIT_RD))
return VAL_CLASS_REFERRAL;
/* check for referral: nonRD query and it looks like a nodata */
if(!(query_flags&BIT_RD) && rep->an_numrrsets == 0 &&
rcode == LDNS_RCODE_NOERROR) {
/* SOA record in auth indicates it is NODATA instead.
* All validation requiring NODATA messages have SOA in
* authority section. */
/* uses fact that answer section is empty */
int saw_ns = 0;
for(i=0; i<rep->ns_numrrsets; i++) {
if(ntohs(rep->rrsets[i]->rk.type) == LDNS_RR_TYPE_SOA)
return VAL_CLASS_NODATA;
if(ntohs(rep->rrsets[i]->rk.type) == LDNS_RR_TYPE_DS)
return VAL_CLASS_REFERRAL;
if(ntohs(rep->rrsets[i]->rk.type) == LDNS_RR_TYPE_NS)
saw_ns = 1;
}
return saw_ns?VAL_CLASS_REFERRAL:VAL_CLASS_NODATA;
}
/* dump bad messages */
if(rcode != LDNS_RCODE_NOERROR)