mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-08-17 21:25:50 +02:00
Compare commits
31
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e12d274954 | ||
|
|
9ade3e4811 | ||
|
|
2c2eaecc6c | ||
|
|
16906c53e6 | ||
|
|
b6d9b4bfcc | ||
|
|
6bb12a5776 | ||
|
|
bce6c3405b | ||
|
|
aa0c26ddec | ||
|
|
a1cbd214a5 | ||
|
|
f64778a893 | ||
|
|
9d3b5fa30d | ||
|
|
99590f93bd | ||
|
|
b72563dcb7 | ||
|
|
6b0cf42b32 | ||
|
|
8df2959959 | ||
|
|
1cda904545 | ||
|
|
416129dedb | ||
|
|
b9c417481b | ||
|
|
eda6528c14 | ||
|
|
fc8657c421 | ||
|
|
5f50f5d2b4 | ||
|
|
31f803201d | ||
|
|
ff975871ab | ||
|
|
99a9914605 | ||
|
|
435fbd1794 | ||
|
|
fe09abe4e6 | ||
|
|
e900e44f9f | ||
|
|
bfbac6bb36 | ||
|
|
cc21a1ca9a | ||
|
|
919b1ab1b6 | ||
|
|
ad69492495 |
+2
-2
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -2,7 +2,7 @@
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
AC_PREREQ(2.57)
|
||||
|
||||
AC_INIT(unbound, 0.6, 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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
+7
-5
@@ -67,7 +67,7 @@ static void usage()
|
||||
printf("-c file config file to read instead of %s\n", CONFIGFILE);
|
||||
printf(" file format is described in unbound.conf(5).\n");
|
||||
printf("-d do not fork into the background.\n");
|
||||
printf("-v verbose (multiple times increase verbosity)\n");
|
||||
printf("-v verbose (more times to increase verbosity)\n");
|
||||
printf("Version %s\n", PACKAGE_VERSION);
|
||||
printf("BSD licensed, see LICENSE in source package for details.\n");
|
||||
printf("Report bugs to %s\n", PACKAGE_BUGREPORT);
|
||||
@@ -292,9 +292,11 @@ do_chroot(struct daemon* daemon, struct config_file* cfg, int debug_mode)
|
||||
}
|
||||
if(cfg->username && cfg->username[0]) {
|
||||
if(setgid(gid) != 0)
|
||||
fatal_exit("unable to set group id: %s", strerror(errno));
|
||||
fatal_exit("unable to set group id of %s: %s",
|
||||
cfg->username, strerror(errno));
|
||||
if(setuid(uid) != 0)
|
||||
fatal_exit("unable to set user id: %s", strerror(errno));
|
||||
fatal_exit("unable to set user id of %s: %s",
|
||||
cfg->username, strerror(errno));
|
||||
verbose(VERB_DETAIL, "drop user privileges, run as %s",
|
||||
cfg->username);
|
||||
}
|
||||
@@ -337,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
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -1,7 +1,85 @@
|
||||
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.
|
||||
|
||||
14 November 2007: Wouter
|
||||
- testbed script does not recreate configure, since its in svn now.
|
||||
- fixup checkconf test so that it does not test
|
||||
/etc/unbound/unbound.conf.
|
||||
- tag 0.6.
|
||||
|
||||
13 November 2007: Wouter
|
||||
- remove debug print.
|
||||
|
||||
+5
-1
@@ -18,13 +18,17 @@ 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 incuded tarball
|
||||
If ldns is not detected on the system, a prepackaged tarball
|
||||
of the ldns library is used to compile and statically link against.
|
||||
If detected on the system, it will dynamically link against it.
|
||||
* --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.
|
||||
|
||||
@@ -53,3 +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
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -159,3 +159,44 @@ o The method by which dnssec-lameness is detected is not secure. DNSSEC lame
|
||||
on a server, dnssec-lameness detection does not work - no dnssec-lameness
|
||||
is detected. Instead the zone that is dnssec-lame becomes bogus.
|
||||
|
||||
o authority features.
|
||||
This is a recursive server, and authority features are out of scope.
|
||||
However, some authority features are expected in a recursor. Things like
|
||||
localhost, reverse lookup for 127.0.0.1, or blocking AS112 traffic.
|
||||
Also redirection of domain names with fixed data is needed by service
|
||||
providers. Limited support is added specifically to address this.
|
||||
|
||||
Adding full authority support, requires much more code, and more complex
|
||||
maintenance.
|
||||
|
||||
The limited support allows adding some static data (for localhost and so),
|
||||
and to respond with a fixed rcode (NXDOMAIN) for domains (such as AS112).
|
||||
|
||||
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
@@ -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
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
Vendored
-2
@@ -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 */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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 */
|
||||
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
@@ -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"
|
||||
|
||||
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
+52
@@ -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
|
||||
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
BIN
Binary file not shown.
Vendored
+60
@@ -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
|
||||
Vendored
+321
@@ -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
|
||||
Vendored
+150
@@ -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
|
||||
Vendored
+183
@@ -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
@@ -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,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
File diff suppressed because it is too large
Load Diff
+27
-5
@@ -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
File diff suppressed because it is too large
Load Diff
+8
-2
@@ -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
@@ -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));
|
||||
|
||||
@@ -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.) */
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user