unbound: Vendor import 1.15.0

This commit is contained in:
Cy Schubert 2022-02-17 14:47:14 -08:00
parent 9b87431a32
commit 3574dc0bd8
87 changed files with 8398 additions and 6549 deletions

View File

@ -11,7 +11,7 @@ have any feedback, we would love to hear from you. Dont hesitate to
[create an issue on Github](https://github.com/NLnetLabs/unbound/issues/new) [create an issue on Github](https://github.com/NLnetLabs/unbound/issues/new)
or post a message on the [Unbound mailing list](https://lists.nlnetlabs.nl/mailman/listinfo/unbound-users). or post a message on the [Unbound mailing list](https://lists.nlnetlabs.nl/mailman/listinfo/unbound-users).
You can learn more about Unbound by reading our You can learn more about Unbound by reading our
[documentation](https://nlnetlabs.nl/documentation/unbound/). [documentation](https://unbound.docs.nlnetlabs.nl/).
## Compiling ## Compiling
@ -33,7 +33,7 @@ support.
All of Unbound's configuration options are described in the man pages, which All of Unbound's configuration options are described in the man pages, which
will be installed and are available on the Unbound will be installed and are available on the Unbound
[documentation page](https://nlnetlabs.nl/documentation/unbound/). [documentation page](https://unbound.docs.nlnetlabs.nl/).
An example configuration file is located in An example configuration file is located in
[doc/example.conf](https://github.com/NLnetLabs/unbound/blob/master/doc/example.conf.in). [doc/example.conf](https://github.com/NLnetLabs/unbound/blob/master/doc/example.conf.in).

16
config.guess vendored
View File

@ -1,14 +1,14 @@
#! /bin/sh #! /bin/sh
# Attempt to guess a canonical system name. # Attempt to guess a canonical system name.
# Copyright 1992-2021 Free Software Foundation, Inc. # Copyright 1992-2022 Free Software Foundation, Inc.
# shellcheck disable=SC2006,SC2268 # see below for rationale # shellcheck disable=SC2006,SC2268 # see below for rationale
timestamp='2021-06-03' timestamp='2022-01-09'
# This file is free software; you can redistribute it and/or modify it # This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by # under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, but # This program is distributed in the hope that it will be useful, but
@ -60,7 +60,7 @@ version="\
GNU config.guess ($timestamp) GNU config.guess ($timestamp)
Originally written by Per Bothner. Originally written by Per Bothner.
Copyright 1992-2021 Free Software Foundation, Inc. Copyright 1992-2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@ -437,7 +437,7 @@ case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in
# This test works for both compilers. # This test works for both compilers.
if test "$CC_FOR_BUILD" != no_compiler_found; then if test "$CC_FOR_BUILD" != no_compiler_found; then
if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
(CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ (CCOPTS="" $CC_FOR_BUILD -m64 -E - 2>/dev/null) | \
grep IS_64BIT_ARCH >/dev/null grep IS_64BIT_ARCH >/dev/null
then then
SUN_ARCH=x86_64 SUN_ARCH=x86_64
@ -929,6 +929,9 @@ EOF
i*:PW*:*) i*:PW*:*)
GUESS=$UNAME_MACHINE-pc-pw32 GUESS=$UNAME_MACHINE-pc-pw32
;; ;;
*:SerenityOS:*:*)
GUESS=$UNAME_MACHINE-pc-serenity
;;
*:Interix*:*) *:Interix*:*)
case $UNAME_MACHINE in case $UNAME_MACHINE in
x86) x86)
@ -1522,6 +1525,9 @@ EOF
i*86:rdos:*:*) i*86:rdos:*:*)
GUESS=$UNAME_MACHINE-pc-rdos GUESS=$UNAME_MACHINE-pc-rdos
;; ;;
i*86:Fiwix:*:*)
GUESS=$UNAME_MACHINE-pc-fiwix
;;
*:AROS:*:*) *:AROS:*:*)
GUESS=$UNAME_MACHINE-unknown-aros GUESS=$UNAME_MACHINE-unknown-aros
;; ;;

View File

@ -381,6 +381,9 @@
/* Define to 1 if you have the <netinet/tcp.h> header file. */ /* Define to 1 if you have the <netinet/tcp.h> header file. */
#undef HAVE_NETINET_TCP_H #undef HAVE_NETINET_TCP_H
/* Define to 1 if you have the <netioapi.h> header file. */
#undef HAVE_NETIOAPI_H
/* Use libnettle for crypto */ /* Use libnettle for crypto */
#undef HAVE_NETTLE #undef HAVE_NETTLE

20
config.sub vendored
View File

@ -1,14 +1,14 @@
#! /bin/sh #! /bin/sh
# Configuration validation subroutine script. # Configuration validation subroutine script.
# Copyright 1992-2021 Free Software Foundation, Inc. # Copyright 1992-2022 Free Software Foundation, Inc.
# shellcheck disable=SC2006,SC2268 # see below for rationale # shellcheck disable=SC2006,SC2268 # see below for rationale
timestamp='2021-08-14' timestamp='2022-01-03'
# This file is free software; you can redistribute it and/or modify it # This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by # under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or # the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version. # (at your option) any later version.
# #
# This program is distributed in the hope that it will be useful, but # This program is distributed in the hope that it will be useful, but
@ -76,7 +76,7 @@ Report bugs and patches to <config-patches@gnu.org>."
version="\ version="\
GNU config.sub ($timestamp) GNU config.sub ($timestamp)
Copyright 1992-2021 Free Software Foundation, Inc. Copyright 1992-2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@ -1020,6 +1020,11 @@ case $cpu-$vendor in
;; ;;
# Here we normalize CPU types with a missing or matching vendor # Here we normalize CPU types with a missing or matching vendor
armh-unknown | armh-alt)
cpu=armv7l
vendor=alt
basic_os=${basic_os:-linux-gnueabihf}
;;
dpx20-unknown | dpx20-bull) dpx20-unknown | dpx20-bull)
cpu=rs6000 cpu=rs6000
vendor=bull vendor=bull
@ -1121,7 +1126,7 @@ case $cpu-$vendor in
xscale-* | xscalee[bl]-*) xscale-* | xscalee[bl]-*)
cpu=`echo "$cpu" | sed 's/^xscale/arm/'` cpu=`echo "$cpu" | sed 's/^xscale/arm/'`
;; ;;
arm64-*) arm64-* | aarch64le-*)
cpu=aarch64 cpu=aarch64
;; ;;
@ -1304,7 +1309,7 @@ esac
if test x$basic_os != x if test x$basic_os != x
then then
# First recognize some ad-hoc caes, or perhaps split kernel-os, or else just # First recognize some ad-hoc cases, or perhaps split kernel-os, or else just
# set os. # set os.
case $basic_os in case $basic_os in
gnu/linux*) gnu/linux*)
@ -1748,7 +1753,8 @@ case $os in
| skyos* | haiku* | rdos* | toppers* | drops* | es* \ | skyos* | haiku* | rdos* | toppers* | drops* | es* \
| onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \ | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \
| midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \ | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \
| nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr*) | nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \
| fiwix* )
;; ;;
# This one is extra strict with allowed versions # This one is extra strict with allowed versions
sco3.2v2 | sco3.2v[4-9]* | sco5v6*) sco3.2v2 | sco3.2v[4-9]* | sco5v6*)

72
configure vendored
View File

@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# Guess values for system-dependent variables and create Makefiles. # Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for unbound 1.14.0. # Generated by GNU Autoconf 2.69 for unbound 1.15.0.
# #
# Report bugs to <unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues>. # Report bugs to <unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues>.
# #
@ -591,8 +591,8 @@ MAKEFLAGS=
# Identity of this package. # Identity of this package.
PACKAGE_NAME='unbound' PACKAGE_NAME='unbound'
PACKAGE_TARNAME='unbound' PACKAGE_TARNAME='unbound'
PACKAGE_VERSION='1.14.0' PACKAGE_VERSION='1.15.0'
PACKAGE_STRING='unbound 1.14.0' PACKAGE_STRING='unbound 1.15.0'
PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues' PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues'
PACKAGE_URL='' PACKAGE_URL=''
@ -1466,7 +1466,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing. # 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. # This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF cat <<_ACEOF
\`configure' configures unbound 1.14.0 to adapt to many kinds of systems. \`configure' configures unbound 1.15.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]... Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1531,7 +1531,7 @@ fi
if test -n "$ac_init_help"; then if test -n "$ac_init_help"; then
case $ac_init_help in case $ac_init_help in
short | recursive ) echo "Configuration of unbound 1.14.0:";; short | recursive ) echo "Configuration of unbound 1.15.0:";;
esac esac
cat <<\_ACEOF cat <<\_ACEOF
@ -1773,7 +1773,7 @@ fi
test -n "$ac_init_help" && exit $ac_status test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then if $ac_init_version; then
cat <<\_ACEOF cat <<\_ACEOF
unbound configure 1.14.0 unbound configure 1.15.0
generated by GNU Autoconf 2.69 generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc. Copyright (C) 2012 Free Software Foundation, Inc.
@ -2482,7 +2482,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake. running configure, to aid debugging if configure makes a mistake.
It was created by unbound $as_me 1.14.0, which was It was created by unbound $as_me 1.15.0, which was
generated by GNU Autoconf 2.69. Invocation command line was generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@ $ $0 $@
@ -2832,13 +2832,13 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
UNBOUND_VERSION_MAJOR=1 UNBOUND_VERSION_MAJOR=1
UNBOUND_VERSION_MINOR=14 UNBOUND_VERSION_MINOR=15
UNBOUND_VERSION_MICRO=0 UNBOUND_VERSION_MICRO=0
LIBUNBOUND_CURRENT=9 LIBUNBOUND_CURRENT=9
LIBUNBOUND_REVISION=14 LIBUNBOUND_REVISION=15
LIBUNBOUND_AGE=1 LIBUNBOUND_AGE=1
# 1.0.0 had 0:12:0 # 1.0.0 had 0:12:0
# 1.0.1 had 0:13:0 # 1.0.1 had 0:13:0
@ -2920,6 +2920,7 @@ LIBUNBOUND_AGE=1
# 1.13.1 had 9:12:1 # 1.13.1 had 9:12:1
# 1.13.2 had 9:13:1 # 1.13.2 had 9:13:1
# 1.14.0 had 9:14:1 # 1.14.0 had 9:14:1
# 1.15.0 had 9:15:1
# Current -- the number of the binary API that we're implementing # Current -- the number of the binary API that we're implementing
# Revision -- which iteration of the implementation of the binary # Revision -- which iteration of the implementation of the binary
@ -14812,6 +14813,51 @@ fi
done done
for ac_header in netioapi.h
do :
ac_fn_c_check_header_compile "$LINENO" "netioapi.h" "ac_cv_header_netioapi_h" "$ac_includes_default
#if HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_SYS_UIO_H
#include <sys/uio.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_NETINET_TCP_H
#include <netinet/tcp.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#ifdef HAVE_WINSOCK2_H
#include <winsock2.h>
#endif
#ifdef HAVE_WS2TCPIP_H
#include <ws2tcpip.h>
#endif
"
if test "x$ac_cv_header_netioapi_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_NETIOAPI_H 1
_ACEOF
fi
done
# check for types. # check for types.
# Using own tests for int64* because autoconf builtin only give 32bit. # Using own tests for int64* because autoconf builtin only give 32bit.
@ -17895,7 +17941,7 @@ if test "`uname`" = "NetBSD"; then
fi fi
if test "`uname -o`" = "GNU/Linux"; then if test "`uname`" = "Linux"; then
# splint cannot parse modern c99 header files # splint cannot parse modern c99 header files
GCC_DOCKER_LINTFLAGS='-syntax' GCC_DOCKER_LINTFLAGS='-syntax'
@ -21840,7 +21886,7 @@ _ACEOF
version=1.14.0 version=1.15.0
date=`date +'%b %e, %Y'` date=`date +'%b %e, %Y'`
@ -22359,7 +22405,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their # report actual input values of CONFIG_FILES etc. instead of their
# values after options handling. # values after options handling.
ac_log=" ac_log="
This file was extended by unbound $as_me 1.14.0, which was This file was extended by unbound $as_me 1.15.0, which was
generated by GNU Autoconf 2.69. Invocation command line was generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES CONFIG_FILES = $CONFIG_FILES
@ -22425,7 +22471,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\ ac_cs_version="\\
unbound config.status 1.14.0 unbound config.status 1.15.0
configured by $0, generated by GNU Autoconf 2.69, configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\" with options \\"\$ac_cs_config\\"

View File

@ -10,7 +10,7 @@ sinclude(dnscrypt/dnscrypt.m4)
# must be numbers. ac_defun because of later processing # must be numbers. ac_defun because of later processing
m4_define([VERSION_MAJOR],[1]) m4_define([VERSION_MAJOR],[1])
m4_define([VERSION_MINOR],[14]) m4_define([VERSION_MINOR],[15])
m4_define([VERSION_MICRO],[0]) m4_define([VERSION_MICRO],[0])
AC_INIT([unbound],m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]),[unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues],[unbound]) AC_INIT([unbound],m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]),[unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues],[unbound])
AC_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR]) AC_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR])
@ -18,7 +18,7 @@ AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR])
AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO]) AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO])
LIBUNBOUND_CURRENT=9 LIBUNBOUND_CURRENT=9
LIBUNBOUND_REVISION=14 LIBUNBOUND_REVISION=15
LIBUNBOUND_AGE=1 LIBUNBOUND_AGE=1
# 1.0.0 had 0:12:0 # 1.0.0 had 0:12:0
# 1.0.1 had 0:13:0 # 1.0.1 had 0:13:0
@ -100,6 +100,7 @@ LIBUNBOUND_AGE=1
# 1.13.1 had 9:12:1 # 1.13.1 had 9:12:1
# 1.13.2 had 9:13:1 # 1.13.2 had 9:13:1
# 1.14.0 had 9:14:1 # 1.14.0 had 9:14:1
# 1.15.0 had 9:15:1
# Current -- the number of the binary API that we're implementing # Current -- the number of the binary API that we're implementing
# Revision -- which iteration of the implementation of the binary # Revision -- which iteration of the implementation of the binary
@ -412,6 +413,39 @@ AC_CHECK_HEADERS([net/if.h],,, [
# Check for Apple header. This uncovers TARGET_OS_IPHONE, TARGET_OS_TV or TARGET_OS_WATCH # Check for Apple header. This uncovers TARGET_OS_IPHONE, TARGET_OS_TV or TARGET_OS_WATCH
AC_CHECK_HEADERS([TargetConditionals.h],,, [AC_INCLUDES_DEFAULT]) AC_CHECK_HEADERS([TargetConditionals.h],,, [AC_INCLUDES_DEFAULT])
AC_CHECK_HEADERS([netioapi.h],,, [AC_INCLUDES_DEFAULT
#if HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_SYS_UIO_H
#include <sys/uio.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_NETINET_TCP_H
#include <netinet/tcp.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#ifdef HAVE_WINSOCK2_H
#include <winsock2.h>
#endif
#ifdef HAVE_WS2TCPIP_H
#include <ws2tcpip.h>
#endif
])
# check for types. # check for types.
# Using own tests for int64* because autoconf builtin only give 32bit. # Using own tests for int64* because autoconf builtin only give 32bit.
@ -782,7 +816,7 @@ if test "`uname`" = "NetBSD"; then
AC_SUBST(NETBSD_LINTFLAGS) AC_SUBST(NETBSD_LINTFLAGS)
fi fi
if test "`uname -o`" = "GNU/Linux"; then if test "`uname`" = "Linux"; then
# splint cannot parse modern c99 header files # splint cannot parse modern c99 header files
GCC_DOCKER_LINTFLAGS='-syntax' GCC_DOCKER_LINTFLAGS='-syntax'
AC_SUBST(GCC_DOCKER_LINTFLAGS) AC_SUBST(GCC_DOCKER_LINTFLAGS)

View File

@ -1,8 +1,8 @@
diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in
index f426ac5f..147fbfa9 100644 index 5a75e319..c6c6dbe2 100644
--- a/doc/unbound.conf.5.in --- a/doc/unbound.conf.5.in
+++ b/doc/unbound.conf.5.in +++ b/doc/unbound.conf.5.in
@@ -872,6 +872,13 @@ potentially broken nameservers. A lot of domains will not be resolvable when @@ -970,6 +970,13 @@ potentially broken nameservers. A lot of domains will not be resolvable when
this option in enabled. Only use if you know what you are doing. this option in enabled. Only use if you know what you are doing.
This option only has effect when qname-minimisation is enabled. Default is no. This option only has effect when qname-minimisation is enabled. Default is no.
.TP .TP
@ -17,10 +17,10 @@ index f426ac5f..147fbfa9 100644
Aggressive NSEC uses the DNSSEC NSEC chain to synthesize NXDOMAIN Aggressive NSEC uses the DNSSEC NSEC chain to synthesize NXDOMAIN
and other denials, using information from previous NXDOMAINs answers. and other denials, using information from previous NXDOMAINs answers.
diff --git a/iterator/iter_scrub.c b/iterator/iter_scrub.c diff --git a/iterator/iter_scrub.c b/iterator/iter_scrub.c
index aae934dd..55c55de0 100644 index f093c1bf..e55a2246 100644
--- a/iterator/iter_scrub.c --- a/iterator/iter_scrub.c
+++ b/iterator/iter_scrub.c +++ b/iterator/iter_scrub.c
@@ -667,6 +667,32 @@ static int sanitize_nsec_is_overreach(struct rrset_parse* rrset, @@ -679,6 +679,32 @@ static int sanitize_nsec_is_overreach(sldns_buffer* pkt,
return 0; return 0;
} }
@ -53,7 +53,7 @@ index aae934dd..55c55de0 100644
/** /**
* Given a response event, remove suspect RRsets from the response. * Given a response event, remove suspect RRsets from the response.
* "Suspect" rrsets are potentially poison. Note that this routine expects * "Suspect" rrsets are potentially poison. Note that this routine expects
@@ -686,6 +712,7 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg, @@ -698,6 +724,7 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg,
struct query_info* qinfo, uint8_t* zonename, struct module_env* env, struct query_info* qinfo, uint8_t* zonename, struct module_env* env,
struct iter_env* ie) struct iter_env* ie)
{ {
@ -61,7 +61,7 @@ index aae934dd..55c55de0 100644
int del_addi = 0; /* if additional-holding rrsets are deleted, we int del_addi = 0; /* if additional-holding rrsets are deleted, we
do not trust the normalized additional-A-AAAA any more */ do not trust the normalized additional-A-AAAA any more */
struct rrset_parse* rrset, *prev; struct rrset_parse* rrset, *prev;
@@ -721,6 +748,13 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg, @@ -733,6 +760,13 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg,
rrset = rrset->rrset_all_next; rrset = rrset->rrset_all_next;
} }
@ -75,7 +75,7 @@ index aae934dd..55c55de0 100644
/* At this point, we brutally remove ALL rrsets that aren't /* At this point, we brutally remove ALL rrsets that aren't
* children of the originating zone. The idea here is that, * children of the originating zone. The idea here is that,
* as far as we know, the server that we contacted is ONLY * as far as we know, the server that we contacted is ONLY
@@ -732,6 +766,24 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg, @@ -744,6 +778,24 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg,
rrset = msg->rrset_first; rrset = msg->rrset_first;
while(rrset) { while(rrset) {
@ -101,22 +101,22 @@ index aae934dd..55c55de0 100644
if( (rrset->type == LDNS_RR_TYPE_A || if( (rrset->type == LDNS_RR_TYPE_A ||
rrset->type == LDNS_RR_TYPE_AAAA)) { rrset->type == LDNS_RR_TYPE_AAAA)) {
diff --git a/iterator/iter_utils.c b/iterator/iter_utils.c diff --git a/iterator/iter_utils.c b/iterator/iter_utils.c
index 7bc67da6..e10f547a 100644 index 2482a1f4..bd5ba243 100644
--- a/iterator/iter_utils.c --- a/iterator/iter_utils.c
+++ b/iterator/iter_utils.c +++ b/iterator/iter_utils.c
@@ -175,6 +175,7 @@ iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg) @@ -177,6 +177,7 @@ iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg)
}
iter_env->supports_ipv6 = cfg->do_ip6; iter_env->supports_ipv6 = cfg->do_ip6;
iter_env->supports_ipv4 = cfg->do_ip4; iter_env->supports_ipv4 = cfg->do_ip4;
iter_env->outbound_msg_retry = cfg->outbound_msg_retry;
+ iter_env->aaaa_filter = cfg->aaaa_filter; + iter_env->aaaa_filter = cfg->aaaa_filter;
return 1; return 1;
} }
diff --git a/iterator/iterator.c b/iterator/iterator.c diff --git a/iterator/iterator.c b/iterator/iterator.c
index 23b07ea9..ca29b48c 100644 index 54006940..768fe202 100644
--- a/iterator/iterator.c --- a/iterator/iterator.c
+++ b/iterator/iterator.c +++ b/iterator/iterator.c
@@ -2127,6 +2127,53 @@ processDSNSFind(struct module_qstate* qstate, struct iter_qstate* iq, int id) @@ -2155,6 +2155,53 @@ processDSNSFind(struct module_qstate* qstate, struct iter_qstate* iq, int id)
return 0; return 0;
} }
@ -170,7 +170,7 @@ index 23b07ea9..ca29b48c 100644
/** /**
* This is the request event state where the request will be sent to one of * This is the request event state where the request will be sent to one of
@@ -2186,6 +2233,13 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, @@ -2216,6 +2263,13 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
return error_response(qstate, id, LDNS_RCODE_SERVFAIL); return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
} }
@ -184,7 +184,7 @@ index 23b07ea9..ca29b48c 100644
/* Make sure we have a delegation point, otherwise priming failed /* Make sure we have a delegation point, otherwise priming failed
* or another failure occurred */ * or another failure occurred */
if(!iq->dp) { if(!iq->dp) {
@@ -3574,6 +3628,61 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq, @@ -3648,6 +3702,61 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
return 0; return 0;
} }
@ -246,7 +246,7 @@ index 23b07ea9..ca29b48c 100644
/* /*
* Return priming query results to interested super querystates. * Return priming query results to interested super querystates.
* *
@@ -3593,6 +3702,9 @@ iter_inform_super(struct module_qstate* qstate, int id, @@ -3667,6 +3776,9 @@ iter_inform_super(struct module_qstate* qstate, int id,
else if(super->qinfo.qtype == LDNS_RR_TYPE_DS && ((struct iter_qstate*) else if(super->qinfo.qtype == LDNS_RR_TYPE_DS && ((struct iter_qstate*)
super->minfo[id])->state == DSNS_FIND_STATE) super->minfo[id])->state == DSNS_FIND_STATE)
processDSNSResponse(qstate, id, super); processDSNSResponse(qstate, id, super);
@ -256,7 +256,7 @@ index 23b07ea9..ca29b48c 100644
else if(qstate->return_rcode != LDNS_RCODE_NOERROR) else if(qstate->return_rcode != LDNS_RCODE_NOERROR)
error_supers(qstate, id, super); error_supers(qstate, id, super);
else if(qstate->is_priming) else if(qstate->is_priming)
@@ -3630,6 +3742,9 @@ iter_handle(struct module_qstate* qstate, struct iter_qstate* iq, @@ -3704,6 +3816,9 @@ iter_handle(struct module_qstate* qstate, struct iter_qstate* iq,
case INIT_REQUEST_3_STATE: case INIT_REQUEST_3_STATE:
cont = processInitRequest3(qstate, iq, id); cont = processInitRequest3(qstate, iq, id);
break; break;
@ -266,7 +266,7 @@ index 23b07ea9..ca29b48c 100644
case QUERYTARGETS_STATE: case QUERYTARGETS_STATE:
cont = processQueryTargets(qstate, iq, ie, id); cont = processQueryTargets(qstate, iq, ie, id);
break; break;
@@ -3961,6 +4076,8 @@ iter_state_to_string(enum iter_state state) @@ -4040,6 +4155,8 @@ iter_state_to_string(enum iter_state state)
return "INIT REQUEST STATE (stage 2)"; return "INIT REQUEST STATE (stage 2)";
case INIT_REQUEST_3_STATE: case INIT_REQUEST_3_STATE:
return "INIT REQUEST STATE (stage 3)"; return "INIT REQUEST STATE (stage 3)";
@ -275,7 +275,7 @@ index 23b07ea9..ca29b48c 100644
case QUERYTARGETS_STATE : case QUERYTARGETS_STATE :
return "QUERY TARGETS STATE"; return "QUERY TARGETS STATE";
case PRIME_RESP_STATE : case PRIME_RESP_STATE :
@@ -3985,6 +4102,7 @@ iter_state_is_responsestate(enum iter_state s) @@ -4064,6 +4181,7 @@ iter_state_is_responsestate(enum iter_state s)
case INIT_REQUEST_STATE : case INIT_REQUEST_STATE :
case INIT_REQUEST_2_STATE : case INIT_REQUEST_2_STATE :
case INIT_REQUEST_3_STATE : case INIT_REQUEST_3_STATE :
@ -284,10 +284,10 @@ index 23b07ea9..ca29b48c 100644
case COLLECT_CLASS_STATE : case COLLECT_CLASS_STATE :
return 0; return 0;
diff --git a/iterator/iterator.h b/iterator/iterator.h diff --git a/iterator/iterator.h b/iterator/iterator.h
index 342ac207..731948d1 100644 index 8b840528..a61c4195 100644
--- a/iterator/iterator.h --- a/iterator/iterator.h
+++ b/iterator/iterator.h +++ b/iterator/iterator.h
@@ -135,6 +135,9 @@ struct iter_env { @@ -133,6 +133,9 @@ struct iter_env {
*/ */
int* target_fetch_policy; int* target_fetch_policy;
@ -297,7 +297,7 @@ index 342ac207..731948d1 100644
/** lock on ratelimit counter */ /** lock on ratelimit counter */
lock_basic_type queries_ratelimit_lock; lock_basic_type queries_ratelimit_lock;
/** number of queries that have been ratelimited */ /** number of queries that have been ratelimited */
@@ -186,6 +189,14 @@ enum iter_state { @@ -187,6 +190,14 @@ enum iter_state {
*/ */
INIT_REQUEST_3_STATE, INIT_REQUEST_3_STATE,
@ -312,7 +312,7 @@ index 342ac207..731948d1 100644
/** /**
* Each time a delegation point changes for a given query or a * Each time a delegation point changes for a given query or a
* query times out and/or wakes up, this state is (re)visited. * query times out and/or wakes up, this state is (re)visited.
@@ -375,6 +386,13 @@ struct iter_qstate { @@ -376,6 +387,13 @@ struct iter_qstate {
*/ */
int refetch_glue; int refetch_glue;
@ -327,10 +327,10 @@ index 342ac207..731948d1 100644
struct outbound_list outlist; struct outbound_list outlist;
diff --git a/pythonmod/interface.i b/pythonmod/interface.i diff --git a/pythonmod/interface.i b/pythonmod/interface.i
index f08b575d..47f1bb2e 100644 index 1ca8686a..d91b19ec 100644
--- a/pythonmod/interface.i --- a/pythonmod/interface.i
+++ b/pythonmod/interface.i +++ b/pythonmod/interface.i
@@ -975,6 +975,7 @@ struct config_file { @@ -995,6 +995,7 @@ struct config_file {
int harden_dnssec_stripped; int harden_dnssec_stripped;
int harden_referral_path; int harden_referral_path;
int use_caps_bits_for_id; int use_caps_bits_for_id;
@ -339,10 +339,10 @@ index f08b575d..47f1bb2e 100644
struct config_strlist* private_domain; struct config_strlist* private_domain;
size_t unwanted_threshold; size_t unwanted_threshold;
diff --git a/util/config_file.c b/util/config_file.c diff --git a/util/config_file.c b/util/config_file.c
index 0ab8614a..729fb147 100644 index 969d664b..8d94b008 100644
--- a/util/config_file.c --- a/util/config_file.c
+++ b/util/config_file.c +++ b/util/config_file.c
@@ -218,6 +218,7 @@ config_create(void) @@ -231,6 +231,7 @@ config_create(void)
cfg->harden_referral_path = 0; cfg->harden_referral_path = 0;
cfg->harden_algo_downgrade = 0; cfg->harden_algo_downgrade = 0;
cfg->use_caps_bits_for_id = 0; cfg->use_caps_bits_for_id = 0;
@ -351,10 +351,10 @@ index 0ab8614a..729fb147 100644
cfg->private_address = NULL; cfg->private_address = NULL;
cfg->private_domain = NULL; cfg->private_domain = NULL;
diff --git a/util/config_file.h b/util/config_file.h diff --git a/util/config_file.h b/util/config_file.h
index e61257a3..dabaa7bb 100644 index c7c9a0a4..e3aa15b0 100644
--- a/util/config_file.h --- a/util/config_file.h
+++ b/util/config_file.h +++ b/util/config_file.h
@@ -260,6 +260,8 @@ struct config_file { @@ -285,6 +285,8 @@ struct config_file {
int harden_algo_downgrade; int harden_algo_downgrade;
/** use 0x20 bits in query as random ID bits */ /** use 0x20 bits in query as random ID bits */
int use_caps_bits_for_id; int use_caps_bits_for_id;
@ -364,19 +364,19 @@ index e61257a3..dabaa7bb 100644
struct config_strlist* caps_whitelist; struct config_strlist* caps_whitelist;
/** strip away these private addrs from answers, no DNS Rebinding */ /** strip away these private addrs from answers, no DNS Rebinding */
diff --git a/util/configlexer.lex b/util/configlexer.lex diff --git a/util/configlexer.lex b/util/configlexer.lex
index 79a0edca..4eaec678 100644 index 34a0e5dd..c890be2a 100644
--- a/util/configlexer.lex --- a/util/configlexer.lex
+++ b/util/configlexer.lex +++ b/util/configlexer.lex
@@ -304,6 +304,7 @@ harden-algo-downgrade{COLON} { YDVAR(1, VAR_HARDEN_ALGO_DOWNGRADE) } @@ -317,6 +317,7 @@ use-caps-for-id{COLON} { YDVAR(1, VAR_USE_CAPS_FOR_ID) }
use-caps-for-id{COLON} { YDVAR(1, VAR_USE_CAPS_FOR_ID) }
caps-whitelist{COLON} { YDVAR(1, VAR_CAPS_WHITELIST) } caps-whitelist{COLON} { YDVAR(1, VAR_CAPS_WHITELIST) }
caps-exempt{COLON} { YDVAR(1, VAR_CAPS_WHITELIST) }
unwanted-reply-threshold{COLON} { YDVAR(1, VAR_UNWANTED_REPLY_THRESHOLD) } unwanted-reply-threshold{COLON} { YDVAR(1, VAR_UNWANTED_REPLY_THRESHOLD) }
+aaaa-filter{COLON} { YDVAR(1, VAR_AAAA_FILTER) } +aaaa-filter{COLON} { YDVAR(1, VAR_AAAA_FILTER) }
private-address{COLON} { YDVAR(1, VAR_PRIVATE_ADDRESS) } private-address{COLON} { YDVAR(1, VAR_PRIVATE_ADDRESS) }
private-domain{COLON} { YDVAR(1, VAR_PRIVATE_DOMAIN) } private-domain{COLON} { YDVAR(1, VAR_PRIVATE_DOMAIN) }
prefetch-key{COLON} { YDVAR(1, VAR_PREFETCH_KEY) } prefetch-key{COLON} { YDVAR(1, VAR_PREFETCH_KEY) }
diff --git a/util/configparser.y b/util/configparser.y diff --git a/util/configparser.y b/util/configparser.y
index 1d0e8658..f284dd43 100644 index d4f965f9..8cc237c6 100644
--- a/util/configparser.y --- a/util/configparser.y
+++ b/util/configparser.y +++ b/util/configparser.y
@@ -97,6 +97,7 @@ extern struct config_parser_state* cfg_parser; @@ -97,6 +97,7 @@ extern struct config_parser_state* cfg_parser;
@ -387,7 +387,7 @@ index 1d0e8658..f284dd43 100644
%token VAR_PRIVATE_DOMAIN VAR_REMOTE_CONTROL VAR_CONTROL_ENABLE %token VAR_PRIVATE_DOMAIN VAR_REMOTE_CONTROL VAR_CONTROL_ENABLE
%token VAR_CONTROL_INTERFACE VAR_CONTROL_PORT VAR_SERVER_KEY_FILE %token VAR_CONTROL_INTERFACE VAR_CONTROL_PORT VAR_SERVER_KEY_FILE
%token VAR_SERVER_CERT_FILE VAR_CONTROL_KEY_FILE VAR_CONTROL_CERT_FILE %token VAR_SERVER_CERT_FILE VAR_CONTROL_KEY_FILE VAR_CONTROL_CERT_FILE
@@ -233,6 +234,7 @@ content_server: server_num_threads | server_verbosity | server_port | @@ -247,6 +248,7 @@ content_server: server_num_threads | server_verbosity | server_port |
server_dlv_anchor_file | server_dlv_anchor | server_neg_cache_size | server_dlv_anchor_file | server_dlv_anchor | server_neg_cache_size |
server_harden_referral_path | server_private_address | server_harden_referral_path | server_private_address |
server_private_domain | server_extended_statistics | server_private_domain | server_extended_statistics |
@ -395,7 +395,7 @@ index 1d0e8658..f284dd43 100644
server_local_data_ptr | server_jostle_timeout | server_local_data_ptr | server_jostle_timeout |
server_unwanted_reply_threshold | server_log_time_ascii | server_unwanted_reply_threshold | server_log_time_ascii |
server_domain_insecure | server_val_sig_skew_min | server_domain_insecure | server_val_sig_skew_min |
@@ -1563,6 +1565,15 @@ server_caps_whitelist: VAR_CAPS_WHITELIST STRING_ARG @@ -1754,6 +1756,15 @@ server_caps_whitelist: VAR_CAPS_WHITELIST STRING_ARG
yyerror("out of memory"); yyerror("out of memory");
} }
; ;

View File

@ -300,6 +300,7 @@ add_open(const char* ip, int nr, struct listen_port** list, int noproto_is_err,
*/ */
if(fd != -1) { if(fd != -1) {
#ifdef HAVE_CHOWN #ifdef HAVE_CHOWN
chmod(ip, (mode_t)(S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP));
if (cfg->username && cfg->username[0] && if (cfg->username && cfg->username[0] &&
cfg_uid != (uid_t)-1) { cfg_uid != (uid_t)-1) {
if(chown(ip, cfg_uid, cfg_gid) == -1) if(chown(ip, cfg_uid, cfg_gid) == -1)
@ -307,7 +308,6 @@ add_open(const char* ip, int nr, struct listen_port** list, int noproto_is_err,
(unsigned)cfg_uid, (unsigned)cfg_gid, (unsigned)cfg_uid, (unsigned)cfg_gid,
ip, strerror(errno)); ip, strerror(errno));
} }
chmod(ip, (mode_t)(S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP));
#else #else
(void)cfg; (void)cfg;
#endif #endif
@ -2015,7 +2015,7 @@ print_root_fwds(RES* ssl, struct iter_forwards* fwds, uint8_t* root)
/** parse args into delegpt */ /** parse args into delegpt */
static struct delegpt* static struct delegpt*
parse_delegpt(RES* ssl, char* args, uint8_t* nm, int allow_names) parse_delegpt(RES* ssl, char* args, uint8_t* nm)
{ {
/* parse args and add in */ /* parse args and add in */
char* p = args; char* p = args;
@ -2037,40 +2037,35 @@ parse_delegpt(RES* ssl, char* args, uint8_t* nm, int allow_names)
} }
/* parse address */ /* parse address */
if(!authextstrtoaddr(todo, &addr, &addrlen, &auth_name)) { if(!authextstrtoaddr(todo, &addr, &addrlen, &auth_name)) {
if(allow_names) { uint8_t* dname= NULL;
uint8_t* n = NULL; int port;
size_t ln; dname = authextstrtodname(todo, &port, &auth_name);
int lb; if(!dname) {
if(!parse_arg_name(ssl, todo, &n, &ln, &lb)) {
(void)ssl_printf(ssl, "error cannot "
"parse IP address or name "
"'%s'\n", todo);
delegpt_free_mlc(dp);
return NULL;
}
if(!delegpt_add_ns_mlc(dp, n, 0)) {
(void)ssl_printf(ssl, "error out of memory\n");
free(n);
delegpt_free_mlc(dp);
return NULL;
}
free(n);
} else {
(void)ssl_printf(ssl, "error cannot parse" (void)ssl_printf(ssl, "error cannot parse"
" IP address '%s'\n", todo); " '%s'\n", todo);
delegpt_free_mlc(dp);
return NULL;
}
#if ! defined(HAVE_SSL_SET1_HOST) && ! defined(HAVE_X509_VERIFY_PARAM_SET1_HOST)
if(auth_name)
log_err("no name verification functionality in "
"ssl library, ignored name for %s", todo);
#endif
if(!delegpt_add_ns_mlc(dp, dname, 0, auth_name, port)) {
(void)ssl_printf(ssl, "error out of memory\n");
free(dname);
delegpt_free_mlc(dp); delegpt_free_mlc(dp);
return NULL; return NULL;
} }
} else { } else {
#if ! defined(HAVE_SSL_SET1_HOST) && ! defined(HAVE_X509_VERIFY_PARAM_SET1_HOST) #if ! defined(HAVE_SSL_SET1_HOST) && ! defined(HAVE_X509_VERIFY_PARAM_SET1_HOST)
if(auth_name) if(auth_name)
log_err("no name verification functionality in " log_err("no name verification functionality in "
"ssl library, ignored name for %s", todo); "ssl library, ignored name for %s", todo);
#endif #endif
/* add address */ /* add address */
if(!delegpt_add_addr_mlc(dp, &addr, addrlen, 0, 0, if(!delegpt_add_addr_mlc(dp, &addr, addrlen, 0, 0,
auth_name)) { auth_name, -1)) {
(void)ssl_printf(ssl, "error out of memory\n"); (void)ssl_printf(ssl, "error out of memory\n");
delegpt_free_mlc(dp); delegpt_free_mlc(dp);
return NULL; return NULL;
@ -2103,7 +2098,7 @@ do_forward(RES* ssl, struct worker* worker, char* args)
forwards_delete_zone(fwd, LDNS_RR_CLASS_IN, root); forwards_delete_zone(fwd, LDNS_RR_CLASS_IN, root);
} else { } else {
struct delegpt* dp; struct delegpt* dp;
if(!(dp = parse_delegpt(ssl, args, root, 0))) if(!(dp = parse_delegpt(ssl, args, root)))
return; return;
if(!forwards_add_zone(fwd, LDNS_RR_CLASS_IN, dp)) { if(!forwards_add_zone(fwd, LDNS_RR_CLASS_IN, dp)) {
(void)ssl_printf(ssl, "error out of memory\n"); (void)ssl_printf(ssl, "error out of memory\n");
@ -2149,7 +2144,7 @@ parse_fs_args(RES* ssl, char* args, uint8_t** nm, struct delegpt** dp,
/* parse dp */ /* parse dp */
if(dp) { if(dp) {
if(!(*dp = parse_delegpt(ssl, args, *nm, 1))) { if(!(*dp = parse_delegpt(ssl, args, *nm))) {
free(*nm); free(*nm);
return 0; return 0;
} }
@ -2865,6 +2860,8 @@ struct ratelimit_list_arg {
int all; int all;
/** current time */ /** current time */
time_t now; time_t now;
/** if backoff is enabled */
int backoff;
}; };
#define ip_ratelimit_list_arg ratelimit_list_arg #define ip_ratelimit_list_arg ratelimit_list_arg
@ -2878,7 +2875,7 @@ rate_list(struct lruhash_entry* e, void* arg)
struct rate_data* d = (struct rate_data*)e->data; struct rate_data* d = (struct rate_data*)e->data;
char buf[257]; char buf[257];
int lim = infra_find_ratelimit(a->infra, k->name, k->namelen); int lim = infra_find_ratelimit(a->infra, k->name, k->namelen);
int max = infra_rate_max(d, a->now); int max = infra_rate_max(d, a->now, a->backoff);
if(a->all == 0) { if(a->all == 0) {
if(max < lim) if(max < lim)
return; return;
@ -2896,7 +2893,7 @@ ip_rate_list(struct lruhash_entry* e, void* arg)
struct ip_rate_key* k = (struct ip_rate_key*)e->key; struct ip_rate_key* k = (struct ip_rate_key*)e->key;
struct ip_rate_data* d = (struct ip_rate_data*)e->data; struct ip_rate_data* d = (struct ip_rate_data*)e->data;
int lim = infra_ip_ratelimit; int lim = infra_ip_ratelimit;
int max = infra_rate_max(d, a->now); int max = infra_rate_max(d, a->now, a->backoff);
if(a->all == 0) { if(a->all == 0) {
if(max < lim) if(max < lim)
return; return;
@ -2914,6 +2911,7 @@ do_ratelimit_list(RES* ssl, struct worker* worker, char* arg)
a.infra = worker->env.infra_cache; a.infra = worker->env.infra_cache;
a.now = *worker->env.now; a.now = *worker->env.now;
a.ssl = ssl; a.ssl = ssl;
a.backoff = worker->env.cfg->ratelimit_backoff;
arg = skipwhite(arg); arg = skipwhite(arg);
if(strcmp(arg, "+a") == 0) if(strcmp(arg, "+a") == 0)
a.all = 1; a.all = 1;
@ -2932,6 +2930,7 @@ do_ip_ratelimit_list(RES* ssl, struct worker* worker, char* arg)
a.infra = worker->env.infra_cache; a.infra = worker->env.infra_cache;
a.now = *worker->env.now; a.now = *worker->env.now;
a.ssl = ssl; a.ssl = ssl;
a.backoff = worker->env.cfg->ip_ratelimit_backoff;
arg = skipwhite(arg); arg = skipwhite(arg);
if(strcmp(arg, "+a") == 0) if(strcmp(arg, "+a") == 0)
a.all = 1; a.all = 1;

View File

@ -1167,7 +1167,8 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
/* check if this query should be dropped based on source ip rate limiting */ /* check if this query should be dropped based on source ip rate limiting */
if(!infra_ip_ratelimit_inc(worker->env.infra_cache, repinfo, if(!infra_ip_ratelimit_inc(worker->env.infra_cache, repinfo,
*worker->env.now, c->buffer)) { *worker->env.now,
worker->env.cfg->ip_ratelimit_backoff, c->buffer)) {
/* See if we are passed through with slip factor */ /* See if we are passed through with slip factor */
if(worker->env.cfg->ip_ratelimit_factor != 0 && if(worker->env.cfg->ip_ratelimit_factor != 0 &&
ub_random_max(worker->env.rnd, ub_random_max(worker->env.rnd,
@ -1967,9 +1968,10 @@ worker_delete(struct worker* worker)
struct outbound_entry* struct outbound_entry*
worker_send_query(struct query_info* qinfo, uint16_t flags, int dnssec, worker_send_query(struct query_info* qinfo, uint16_t flags, int dnssec,
int want_dnssec, int nocaps, struct sockaddr_storage* addr, int want_dnssec, int nocaps, int check_ratelimit,
socklen_t addrlen, uint8_t* zone, size_t zonelen, int tcp_upstream, struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
int ssl_upstream, char* tls_auth_name, struct module_qstate* q) size_t zonelen, int tcp_upstream, int ssl_upstream, char* tls_auth_name,
struct module_qstate* q, int* was_ratelimited)
{ {
struct worker* worker = q->env->worker; struct worker* worker = q->env->worker;
struct outbound_entry* e = (struct outbound_entry*)regional_alloc( struct outbound_entry* e = (struct outbound_entry*)regional_alloc(
@ -1978,9 +1980,10 @@ worker_send_query(struct query_info* qinfo, uint16_t flags, int dnssec,
return NULL; return NULL;
e->qstate = q; e->qstate = q;
e->qsent = outnet_serviced_query(worker->back, qinfo, flags, dnssec, e->qsent = outnet_serviced_query(worker->back, qinfo, flags, dnssec,
want_dnssec, nocaps, tcp_upstream, want_dnssec, nocaps, check_ratelimit, tcp_upstream,
ssl_upstream, tls_auth_name, addr, addrlen, zone, zonelen, q, ssl_upstream, tls_auth_name, addr, addrlen, zone, zonelen, q,
worker_handle_service_reply, e, worker->back->udp_buff, q->env); worker_handle_service_reply, e, worker->back->udp_buff, q->env,
was_ratelimited);
if(!e->qsent) { if(!e->qsent) {
return NULL; return NULL;
} }
@ -2024,10 +2027,11 @@ struct outbound_entry* libworker_send_query(
struct query_info* ATTR_UNUSED(qinfo), struct query_info* ATTR_UNUSED(qinfo),
uint16_t ATTR_UNUSED(flags), int ATTR_UNUSED(dnssec), uint16_t ATTR_UNUSED(flags), int ATTR_UNUSED(dnssec),
int ATTR_UNUSED(want_dnssec), int ATTR_UNUSED(nocaps), int ATTR_UNUSED(want_dnssec), int ATTR_UNUSED(nocaps),
int ATTR_UNUSED(check_ratelimit),
struct sockaddr_storage* ATTR_UNUSED(addr), socklen_t ATTR_UNUSED(addrlen), struct sockaddr_storage* ATTR_UNUSED(addr), socklen_t ATTR_UNUSED(addrlen),
uint8_t* ATTR_UNUSED(zone), size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(tcp_upstream), uint8_t* ATTR_UNUSED(zone), size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(tcp_upstream),
int ATTR_UNUSED(ssl_upstream), char* ATTR_UNUSED(tls_auth_name), int ATTR_UNUSED(ssl_upstream), char* ATTR_UNUSED(tls_auth_name),
struct module_qstate* ATTR_UNUSED(q)) struct module_qstate* ATTR_UNUSED(q), int* ATTR_UNUSED(was_ratelimited))
{ {
log_assert(0); log_assert(0);
return 0; return 0;

View File

@ -188,9 +188,9 @@ mq_wakeup_cb(void* arg)
/** start timer to wakeup dtio because there is content in the queue */ /** start timer to wakeup dtio because there is content in the queue */
static void static void
dt_msg_queue_start_timer(struct dt_msg_queue* mq) dt_msg_queue_start_timer(struct dt_msg_queue* mq, int wakeupnow)
{ {
struct timeval tv; struct timeval tv = {0};
/* Start a timer to process messages to be logged. /* Start a timer to process messages to be logged.
* If we woke up the dtio thread for every message, the wakeup * If we woke up the dtio thread for every message, the wakeup
* messages take up too much processing power. If the queue * messages take up too much processing power. If the queue
@ -204,19 +204,26 @@ dt_msg_queue_start_timer(struct dt_msg_queue* mq)
/* do not start the timer if a timer already exists, perhaps /* do not start the timer if a timer already exists, perhaps
* in another worker. So this variable is protected by a lock in * in another worker. So this variable is protected by a lock in
* dtio */ * dtio. */
/* If we need to wakeupnow, 0 the timer to force the callback. */
lock_basic_lock(&mq->dtio->wakeup_timer_lock); lock_basic_lock(&mq->dtio->wakeup_timer_lock);
if(mq->dtio->wakeup_timer_enabled) { if(mq->dtio->wakeup_timer_enabled) {
if(wakeupnow) {
comm_timer_set(mq->wakeup_timer, &tv);
}
lock_basic_unlock(&mq->dtio->wakeup_timer_lock); lock_basic_unlock(&mq->dtio->wakeup_timer_lock);
return; return;
} }
mq->dtio->wakeup_timer_enabled = 1; /* we are going to start one */ mq->dtio->wakeup_timer_enabled = 1; /* we are going to start one */
lock_basic_unlock(&mq->dtio->wakeup_timer_lock);
/* start the timer, in mq, in the event base of our worker */ /* start the timer, in mq, in the event base of our worker */
tv.tv_sec = 1; if(!wakeupnow) {
tv.tv_usec = 0; tv.tv_sec = 1;
tv.tv_usec = 0;
}
comm_timer_set(mq->wakeup_timer, &tv); comm_timer_set(mq->wakeup_timer, &tv);
lock_basic_unlock(&mq->dtio->wakeup_timer_lock);
} }
void void
@ -283,10 +290,8 @@ dt_msg_queue_submit(struct dt_msg_queue* mq, void* buf, size_t len)
/* release lock */ /* release lock */
lock_basic_unlock(&mq->lock); lock_basic_unlock(&mq->lock);
if(wakeupnow) { if(wakeupnow || wakeupstarttimer) {
dtio_wakeup(mq->dtio); dt_msg_queue_start_timer(mq, wakeupnow);
} else if(wakeupstarttimer) {
dt_msg_queue_start_timer(mq);
} }
} }

View File

@ -1413,11 +1413,12 @@ void worker_sighandler(int ATTR_UNUSED(sig), void* ATTR_UNUSED(arg))
struct outbound_entry* worker_send_query( struct outbound_entry* worker_send_query(
struct query_info* ATTR_UNUSED(qinfo), uint16_t ATTR_UNUSED(flags), struct query_info* ATTR_UNUSED(qinfo), uint16_t ATTR_UNUSED(flags),
int ATTR_UNUSED(dnssec), int ATTR_UNUSED(want_dnssec), int ATTR_UNUSED(dnssec), int ATTR_UNUSED(want_dnssec),
int ATTR_UNUSED(nocaps), struct sockaddr_storage* ATTR_UNUSED(addr), int ATTR_UNUSED(nocaps), int ATTR_UNUSED(check_ratelimit),
struct sockaddr_storage* ATTR_UNUSED(addr),
socklen_t ATTR_UNUSED(addrlen), uint8_t* ATTR_UNUSED(zone), socklen_t ATTR_UNUSED(addrlen), uint8_t* ATTR_UNUSED(zone),
size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(tcp_upstream), size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(tcp_upstream),
int ATTR_UNUSED(ssl_upstream), char* ATTR_UNUSED(tls_auth_name), int ATTR_UNUSED(ssl_upstream), char* ATTR_UNUSED(tls_auth_name),
struct module_qstate* ATTR_UNUSED(q)) struct module_qstate* ATTR_UNUSED(q), int* ATTR_UNUSED(was_ratelimited))
{ {
log_assert(0); log_assert(0);
return 0; return 0;
@ -1446,11 +1447,12 @@ worker_alloc_cleanup(void* ATTR_UNUSED(arg))
struct outbound_entry* libworker_send_query( struct outbound_entry* libworker_send_query(
struct query_info* ATTR_UNUSED(qinfo), uint16_t ATTR_UNUSED(flags), struct query_info* ATTR_UNUSED(qinfo), uint16_t ATTR_UNUSED(flags),
int ATTR_UNUSED(dnssec), int ATTR_UNUSED(want_dnssec), int ATTR_UNUSED(dnssec), int ATTR_UNUSED(want_dnssec),
int ATTR_UNUSED(nocaps), struct sockaddr_storage* ATTR_UNUSED(addr), int ATTR_UNUSED(nocaps), int ATTR_UNUSED(check_ratelimit),
struct sockaddr_storage* ATTR_UNUSED(addr),
socklen_t ATTR_UNUSED(addrlen), uint8_t* ATTR_UNUSED(zone), socklen_t ATTR_UNUSED(addrlen), uint8_t* ATTR_UNUSED(zone),
size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(tcp_upstream), size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(tcp_upstream),
int ATTR_UNUSED(ssl_upstream), char* ATTR_UNUSED(tls_auth_name), int ATTR_UNUSED(ssl_upstream), char* ATTR_UNUSED(tls_auth_name),
struct module_qstate* ATTR_UNUSED(q)) struct module_qstate* ATTR_UNUSED(q), int* ATTR_UNUSED(was_ratelimited))
{ {
log_assert(0); log_assert(0);
return 0; return 0;

View File

@ -1,5 +1,138 @@
3 February 2022: Wouter
- Fix for #611: Integer overflow in sldns_wire2str_pkt_scan.
2 February 2022: George
- Merge PR #532 from Shchelk: Fix: buffer overflow bug.
- Merge PR #616: Update ratelimit logic. It also introduces
ratelimit-backoff and ip-ratelimit-backoff configuration options.
- Change aggressive-nsec default to yes.
- Merge PR #617: Update stub/forward-host notation to accept port and
tls-auth-name.
- Update stream_ssl.tdir test to also use the new forward-host
notation.
2 February 2022: Wouter
- Update version number in repo to 1.15.0 for upcoming release,
since it changes the aggressive-nsec default and the ratelimit change.
- Fix header comment for doxygen for authextstrtoaddr.
- please clang analyzer for loop in test code.
- Fix docker splint test to use more portable uname.
- Update contrib/aaaa-filter-iterator.patch with diff for current
software version.
1 February 2022: George
- Merge PR #603 from fobser: Use OpenSSL 1.1 API to access DSA and RSA
internals.
31 January 2022: George
- Fix review comment for use-after-free when failing to send UDP out.
31 January 2022: Wouter
- iana portlist update.
29 January 2022: George
- Fix tls-* and ssl-* documented alternate syntax to also be available
through remote-control and unbound-checkconf.
- Better cleanup on failed DoT/DoH listening socket creation.
26 January 2022: George
- Fix #599: [FR] RFC 9156 (obsoletes RFC 7816), by noting the new RFC
document.
26 January 2022: Wouter
- Test for NSID in SERVFAIL response due to DNSSEC bogus.
25 January 2022: George
- Fix #588: Unbound 1.13.2 crashes due to p->pc is NULL in
serviced_udp_callback.
- Merge PR #612: TCP race condition.
25 January 2022: Wouter
- Fix #610: Undefine-shift in sldns_str2wire_hip_buf.
19 January 2022: George
- For dnstap, do not wakeupnow right there. Instead zero the timer to
force the wakeup callback asap.
14 January 2022: George
- Merge PR #605:
- Fix EDNS to upstream where the same option could be attached
more than once.
- Add a region to serviced_query for allocations.
14 January 2022: Wouter
- Add rpz: for-downstream: yesno option, where the RPZ zone is
authoritatively answered for, so the RPZ zone contents can be
checked with DNS queries directed at the RPZ zone.
- For #602: Allow the module-config "subnetcache validator cachedb
iterator".
11 January 2022: George
- Fix prematurely terminated TCP queries when a reply has the same ID.
7 January 2022: Wouter
- Merge #600 from pemensik: Change file mode before changing file
owner.
5 January 2022: Wouter
- Fix for #596: fix that rpz return message is returned and not just
the rcode from the iterator return path. This fixes signal unset RA
after a CNAME.
- Fix unit tests for rpz now that the AA flag returns successfully from
the iterator loop.
- Fix for #596: add unit test for nsdname trigger and signal unset RA.
- Fix for #596: add unit test for nsip trigger and signal unset RA.
- Fix #598: Fix unbound-checkconf fatal error: module conf
'respip dns64 validator iterator' is not known to work.
- Fix for #596: Fix rpz-signal-nxdomain-ra to work for clientip
triggered operation.
4 January 2022: Wouter
- Fix #596: unset the RA bit when a query is blocked by an unbound
RPZ nxdomain reply. The option rpz-signal-nxdomain-ra allows to
signal that a domain is externally blocked to clients when it
is blocked with NXDOMAIN by unsetting RA.
- Fix to add test for rpz-signal-nxdomain-ra.
- Fix #596: only unset RA when NXDOMAIN is signalled.
- Fix that RPZ does not set RD flag on replies, it should be copied
from the query.
22 December 2021: George
- contrib/aaaa-filter-iterator.patch file renewed diff content to
apply cleanly to the current coderepo for the current code version.
20 December 2021: George
- Fix #591: Unbound-anchor manpage links to non-existent license file.
13 December 2021: George
- Add missing configure flags for optional features in the
documentation.
- Fix Unbound capitalization in the documentation.
13 December 2021: Wouter
- Fix to pick up other class local zone information before unlock.
10 December 2021: George
- Allow local-data for classes other than IN to inherit a configured
local-zone's type if possible, instead of defaulting to type
transparent as per the implicit rule.
10 December 2021: Wouter
- Add code similar to fix for ldns for tab between strings, for
consistency, the test case was not broken.
6 December 2021: Wouter
- Merge PR #581 from fobser: Fix -Wmissing-prototypes and -Wshadow
warnings in rpz.
- Fix validator debug output about DS support, print correct algorithm.
3 December 2021: Wouter
- Fix compile warning for if_nametoindex on windows 64bit.
1 December 2021: Wouter 1 December 2021: Wouter
- configure is set to 1.14.0, and release branch. - configure is set to 1.14.0, and release branch.
This was released as version 1.14.0 on 9 Dec 2021, with the doxygen
fix below included. The main branch continues as 1.14.1.
- Fix doc/unbound.doxygen to remove obsolete tag warning. - Fix doc/unbound.doxygen to remove obsolete tag warning.
1 December 2021: George 1 December 2021: George

View File

@ -1,4 +1,4 @@
README for Unbound 1.14.0 README for Unbound 1.15.0
Copyright 2007 NLnet Labs Copyright 2007 NLnet Labs
http://unbound.net http://unbound.net

View File

@ -1,7 +1,7 @@
# #
# Example configuration file. # Example configuration file.
# #
# See unbound.conf(5) man page, version 1.14.0. # See unbound.conf(5) man page, version 1.15.0.
# #
# this is a comment. # this is a comment.
@ -82,13 +82,13 @@ server:
# num-queries-per-thread, or, use as many as the OS will allow you. # num-queries-per-thread, or, use as many as the OS will allow you.
# outgoing-range: 4096 # outgoing-range: 4096
# permit unbound to use this port number or port range for # permit Unbound to use this port number or port range for
# making outgoing queries, using an outgoing interface. # making outgoing queries, using an outgoing interface.
# outgoing-port-permit: 32768 # outgoing-port-permit: 32768
# deny unbound the use this of port number or port range for # deny Unbound the use this of port number or port range for
# making outgoing queries, using an outgoing interface. # making outgoing queries, using an outgoing interface.
# Use this to make sure unbound does not grab a UDP port that some # Use this to make sure Unbound does not grab a UDP port that some
# other server on this computer needs. The default is to avoid # other server on this computer needs. The default is to avoid
# IANA-assigned port numbers. # IANA-assigned port numbers.
# If multiple outgoing-port-permit and outgoing-port-avoid options # If multiple outgoing-port-permit and outgoing-port-avoid options
@ -254,7 +254,7 @@ server:
# use-systemd: no # use-systemd: no
# Detach from the terminal, run in background, "yes" or "no". # Detach from the terminal, run in background, "yes" or "no".
# Set the value to "no" when unbound runs as systemd service. # Set the value to "no" when Unbound runs as systemd service.
# do-daemonize: yes # do-daemonize: yes
# control which clients are allowed to make (recursive) queries # control which clients are allowed to make (recursive) queries
@ -307,7 +307,7 @@ server:
# The pid file can be absolute and outside of the chroot, it is # The pid file can be absolute and outside of the chroot, it is
# written just prior to performing the chroot and dropping permissions. # written just prior to performing the chroot and dropping permissions.
# #
# Additionally, unbound may need to access /dev/urandom (for entropy). # Additionally, Unbound may need to access /dev/urandom (for entropy).
# How to do this is specific to your OS. # How to do this is specific to your OS.
# #
# If you give "" no chroot is performed. The path must not end in a /. # If you give "" no chroot is performed. The path must not end in a /.
@ -442,7 +442,7 @@ server:
# Aggressive NSEC uses the DNSSEC NSEC chain to synthesize NXDOMAIN # Aggressive NSEC uses the DNSSEC NSEC chain to synthesize NXDOMAIN
# and other denials, using information from previous NXDOMAINs answers. # and other denials, using information from previous NXDOMAINs answers.
# aggressive-nsec: no # aggressive-nsec: yes
# Use 0x20-encoded random bits in the query to foil spoof attempts. # Use 0x20-encoded random bits in the query to foil spoof attempts.
# This feature is an experimental implementation of draft dns-0x20. # This feature is an experimental implementation of draft dns-0x20.
@ -517,7 +517,7 @@ server:
# Use several entries, one per domain name, to track multiple zones. # Use several entries, one per domain name, to track multiple zones.
# #
# If you want to perform DNSSEC validation, run unbound-anchor before # If you want to perform DNSSEC validation, run unbound-anchor before
# you start unbound (i.e. in the system boot scripts). # you start Unbound (i.e. in the system boot scripts).
# And then enable the auto-trust-anchor-file config item. # And then enable the auto-trust-anchor-file config item.
# Please note usage of unbound-anchor root anchor is at your own risk # Please note usage of unbound-anchor root anchor is at your own risk
# and under the terms of our LICENSE (see that file in the source). # and under the terms of our LICENSE (see that file in the source).
@ -585,7 +585,7 @@ server:
# val-permissive-mode: no # val-permissive-mode: no
# Ignore the CD flag in incoming queries and refuse them bogus data. # Ignore the CD flag in incoming queries and refuse them bogus data.
# Enable it if the only clients of unbound are legacy servers (w2008) # Enable it if the only clients of Unbound are legacy servers (w2008)
# that set CD but cannot validate themselves. # that set CD but cannot validate themselves.
# ignore-cd-flag: no # ignore-cd-flag: no
@ -615,7 +615,7 @@ server:
# Return the original TTL as received from the upstream name server rather # Return the original TTL as received from the upstream name server rather
# than the decrementing TTL as stored in the cache. Enabling this feature # than the decrementing TTL as stored in the cache. Enabling this feature
# does not impact cache expiry, it only changes the TTL unbound embeds in # does not impact cache expiry, it only changes the TTL Unbound embeds in
# responses to queries. Note that enabling this feature implicitly disables # responses to queries. Note that enabling this feature implicitly disables
# enforcement of the configured minimum and maximum TTL. # enforcement of the configured minimum and maximum TTL.
# serve-original-ttl: no # serve-original-ttl: no
@ -709,9 +709,9 @@ server:
# Add example.com into ipset # Add example.com into ipset
# local-zone: "example.com" ipset # local-zone: "example.com" ipset
# If unbound is running service for the local host then it is useful # If Unbound is running service for the local host then it is useful
# to perform lan-wide lookups to the upstream, and unblock the # to perform lan-wide lookups to the upstream, and unblock the
# long list of local-zones above. If this unbound is a dns server # long list of local-zones above. If this Unbound is a dns server
# for a network of computers, disabled is better and stops information # for a network of computers, disabled is better and stops information
# leakage of local lan information. # leakage of local lan information.
# unblock-lan-zones: no # unblock-lan-zones: no
@ -860,6 +860,10 @@ server:
# 0 blocks when ratelimited, otherwise let 1/xth traffic through # 0 blocks when ratelimited, otherwise let 1/xth traffic through
# ratelimit-factor: 10 # ratelimit-factor: 10
# Aggressive rate limit when the limit is reached and until demand has
# decreased in a 2 second rate window.
# ratelimit-backoff: no
# override the ratelimit for a specific domain name. # override the ratelimit for a specific domain name.
# give this setting multiple times to have multiple overrides. # give this setting multiple times to have multiple overrides.
# ratelimit-for-domain: example.com 1000 # ratelimit-for-domain: example.com 1000
@ -880,6 +884,10 @@ server:
# 0 blocks when ip is ratelimited, otherwise let 1/xth traffic through # 0 blocks when ip is ratelimited, otherwise let 1/xth traffic through
# ip-ratelimit-factor: 10 # ip-ratelimit-factor: 10
# Aggressive rate limit when the limit is reached and until demand has
# decreased in a 2 second rate window.
# ip-ratelimit-backoff: no
# Limit the number of connections simultaneous from a netblock # Limit the number of connections simultaneous from a netblock
# tcp-connection-limit: 192.0.2.0/24 12 # tcp-connection-limit: 192.0.2.0/24 12
@ -889,7 +897,7 @@ server:
# the number of servers that will be used in the fast server selection. # the number of servers that will be used in the fast server selection.
# fast-server-num: 3 # fast-server-num: 3
# Specific options for ipsecmod. unbound needs to be configured with # Specific options for ipsecmod. Unbound needs to be configured with
# --enable-ipsecmod for these to take effect. # --enable-ipsecmod for these to take effect.
# #
# Enable or disable ipsecmod (it still needs to be defined in # Enable or disable ipsecmod (it still needs to be defined in
@ -901,7 +909,7 @@ server:
# listed in module-config (above). # listed in module-config (above).
# ipsecmod-hook: "./my_executable" # ipsecmod-hook: "./my_executable"
# #
# When enabled unbound will reply with SERVFAIL if the return value of # When enabled Unbound will reply with SERVFAIL if the return value of
# the ipsecmod-hook is not 0. # the ipsecmod-hook is not 0.
# ipsecmod-strict: no # ipsecmod-strict: no
# #
@ -966,10 +974,10 @@ remote-control:
# For local sockets this option is ignored, and TLS is not used. # For local sockets this option is ignored, and TLS is not used.
# control-use-cert: "yes" # control-use-cert: "yes"
# unbound server key file. # Unbound server key file.
# server-key-file: "@UNBOUND_RUN_DIR@/unbound_server.key" # server-key-file: "@UNBOUND_RUN_DIR@/unbound_server.key"
# unbound server certificate file. # Unbound server certificate file.
# server-cert-file: "@UNBOUND_RUN_DIR@/unbound_server.pem" # server-cert-file: "@UNBOUND_RUN_DIR@/unbound_server.pem"
# unbound-control key file. # unbound-control key file.
@ -1072,8 +1080,9 @@ remote-control:
# local-zone: "example.com" refuse # local-zone: "example.com" refuse
# DNSCrypt # DNSCrypt
# To enable, use --enable-dnscrypt to configure before compiling.
# Caveats: # Caveats:
# 1. the keys/certs cannot be produced by unbound. You can use dnscrypt-wrapper # 1. the keys/certs cannot be produced by Unbound. You can use dnscrypt-wrapper
# for this: https://github.com/cofyc/dnscrypt-wrapper/blob/master/README.md#usage # for this: https://github.com/cofyc/dnscrypt-wrapper/blob/master/README.md#usage
# 2. dnscrypt channel attaches to an interface. you MUST set interfaces to # 2. dnscrypt channel attaches to an interface. you MUST set interfaces to
# listen on `dnscrypt-port` with the follo0wing snippet: # listen on `dnscrypt-port` with the follo0wing snippet:
@ -1092,7 +1101,9 @@ remote-control:
# dnscrypt-provider-cert: /path/unbound-conf/keys2/1.cert # dnscrypt-provider-cert: /path/unbound-conf/keys2/1.cert
# CacheDB # CacheDB
# Enable external backend DB as auxiliary cache. Specify the backend name # External backend DB as auxiliary cache.
# To enable, use --enable-cachedb to configure before compiling.
# Specify the backend name
# (default is "testframe", which has no use other than for debugging and # (default is "testframe", which has no use other than for debugging and
# testing) and backend-specific options. The 'cachedb' module must be # testing) and backend-specific options. The 'cachedb' module must be
# included in module-config, just before the iterator module. # included in module-config, just before the iterator module.
@ -1102,6 +1113,7 @@ remote-control:
# secret-seed: "default" # secret-seed: "default"
# #
# # For "redis" backend: # # For "redis" backend:
# # (to enable, use --with-libhiredis to configure before compiling)
# # redis server's IP address or host name # # redis server's IP address or host name
# redis-server-host: 127.0.0.1 # redis-server-host: 127.0.0.1
# # redis server's TCP port # # redis server's TCP port
@ -1113,7 +1125,9 @@ remote-control:
# IPSet # IPSet
# Add specify domain into set via ipset. # Add specify domain into set via ipset.
# Note: To enable ipset unbound needs to run as root user. # To enable:
# o use --enable-ipset to configure before compiling;
# o Unbound then needs to run as root user.
# ipset: # ipset:
# # set name for ip v4 addresses # # set name for ip v4 addresses
# name-v4: "list-v4" # name-v4: "list-v4"
@ -1121,9 +1135,10 @@ remote-control:
# name-v6: "list-v6" # name-v6: "list-v6"
# #
# Dnstap logging support, if compiled in. To enable, set the dnstap-enable # Dnstap logging support, if compiled in by using --enable-dnstap to configure.
# to yes and also some of dnstap-log-..-messages to yes. And select an # To enable, set the dnstap-enable to yes and also some of
# upstream log destination, by socket path, TCP or TLS destination. # dnstap-log-..-messages to yes. And select an upstream log destination, by
# socket path, TCP or TLS destination.
# dnstap: # dnstap:
# dnstap-enable: no # dnstap-enable: no
# # if set to yes frame streams will be used in bidirectional mode # # if set to yes frame streams will be used in bidirectional mode
@ -1136,7 +1151,7 @@ remote-control:
# dnstap-tls: yes # dnstap-tls: yes
# # name for authenticating the upstream server. or "" disabled. # # name for authenticating the upstream server. or "" disabled.
# dnstap-tls-server-name: "" # dnstap-tls-server-name: ""
# # if "", it uses the cert bundle from the main unbound config. # # if "", it uses the cert bundle from the main Unbound config.
# dnstap-tls-cert-bundle: "" # dnstap-tls-cert-bundle: ""
# # key file for client authentication, or "" disabled. # # key file for client authentication, or "" disabled.
# dnstap-tls-client-key-file: "" # dnstap-tls-client-key-file: ""
@ -1172,4 +1187,6 @@ remote-control:
# rpz-cname-override: www.example.org # rpz-cname-override: www.example.org
# rpz-log: yes # rpz-log: yes
# rpz-log-name: "example policy" # rpz-log-name: "example policy"
# rpz-signal-nxdomain-ra: no
# for-downstream: no
# tags: "example" # tags: "example"

View File

@ -1,4 +1,4 @@
.TH "libunbound" "3" "Dec 9, 2021" "NLnet Labs" "unbound 1.14.0" .TH "libunbound" "3" "Feb 10, 2022" "NLnet Labs" "unbound 1.15.0"
.\" .\"
.\" libunbound.3 -- unbound library functions manual .\" libunbound.3 -- unbound library functions manual
.\" .\"
@ -44,7 +44,7 @@
.B ub_ctx_zone_remove, .B ub_ctx_zone_remove,
.B ub_ctx_data_add, .B ub_ctx_data_add,
.B ub_ctx_data_remove .B ub_ctx_data_remove
\- Unbound DNS validating resolver 1.14.0 functions. \- Unbound DNS validating resolver 1.15.0 functions.
.SH "SYNOPSIS" .SH "SYNOPSIS"
.B #include <unbound.h> .B #include <unbound.h>
.LP .LP

View File

@ -1,4 +1,4 @@
.TH "unbound-anchor" "8" "Dec 9, 2021" "NLnet Labs" "unbound 1.14.0" .TH "unbound-anchor" "8" "Feb 10, 2022" "NLnet Labs" "unbound 1.15.0"
.\" .\"
.\" unbound-anchor.8 -- unbound anchor maintenance utility manual .\" unbound-anchor.8 -- unbound anchor maintenance utility manual
.\" .\"
@ -159,7 +159,7 @@ Or something more suitable for your operational environment.
The root keys and update certificate included in this tool The root keys and update certificate included in this tool
are provided for convenience and under the terms of our are provided for convenience and under the terms of our
license (see the LICENSE file in the source distribution or license (see the LICENSE file in the source distribution or
http://unbound.nlnetlabs.nl/svn/trunk/LICENSE) and might be stale or https://github.com/NLnetLabs/unbound/blob/master/LICENSE) and might be stale or
not suitable to your purpose. not suitable to your purpose.
.P .P
By running "unbound\-anchor \-l" the keys and certificate that are By running "unbound\-anchor \-l" the keys and certificate that are

View File

@ -1,4 +1,4 @@
.TH "unbound-checkconf" "8" "Dec 9, 2021" "NLnet Labs" "unbound 1.14.0" .TH "unbound-checkconf" "8" "Feb 10, 2022" "NLnet Labs" "unbound 1.15.0"
.\" .\"
.\" unbound-checkconf.8 -- unbound configuration checker manual .\" unbound-checkconf.8 -- unbound configuration checker manual
.\" .\"
@ -9,7 +9,7 @@
.\" .\"
.SH "NAME" .SH "NAME"
unbound\-checkconf unbound\-checkconf
\- Check unbound configuration file for errors. \- Check Unbound configuration file for errors.
.SH "SYNOPSIS" .SH "SYNOPSIS"
.B unbound\-checkconf .B unbound\-checkconf
.RB [ \-h ] .RB [ \-h ]
@ -38,7 +38,7 @@ If given, after checking the config file the value of this option is
printed to stdout. For "" (disabled) options an empty line is printed. printed to stdout. For "" (disabled) options an empty line is printed.
.TP .TP
.I cfgfile .I cfgfile
The config file to read with settings for unbound. It is checked. The config file to read with settings for Unbound. It is checked.
If omitted, the config file at the default location is checked. If omitted, the config file at the default location is checked.
.SH "EXIT CODE" .SH "EXIT CODE"
The unbound\-checkconf program exits with status code 1 on error, The unbound\-checkconf program exits with status code 1 on error,
@ -46,7 +46,7 @@ The unbound\-checkconf program exits with status code 1 on error,
.SH "FILES" .SH "FILES"
.TP .TP
.I @ub_conf_file@ .I @ub_conf_file@
unbound configuration file. Unbound configuration file.
.SH "SEE ALSO" .SH "SEE ALSO"
\fIunbound.conf\fR(5), \fIunbound.conf\fR(5),
\fIunbound\fR(8). \fIunbound\fR(8).

View File

@ -1,4 +1,4 @@
.TH "unbound-control" "8" "Dec 9, 2021" "NLnet Labs" "unbound 1.14.0" .TH "unbound-control" "8" "Feb 10, 2022" "NLnet Labs" "unbound 1.15.0"
.\" .\"
.\" unbound-control.8 -- unbound remote control manual .\" unbound-control.8 -- unbound remote control manual
.\" .\"
@ -22,7 +22,7 @@
.SH "DESCRIPTION" .SH "DESCRIPTION"
.B Unbound\-control .B Unbound\-control
performs remote administration on the \fIunbound\fR(8) DNS server. performs remote administration on the \fIunbound\fR(8) DNS server.
It reads the configuration file, contacts the unbound server over SSL It reads the configuration file, contacts the Unbound server over SSL
sends the command and displays the result. sends the command and displays the result.
.P .P
The available options are: The available options are:
@ -44,7 +44,7 @@ quiet, if the option is given it does not print anything if it works ok.
There are several commands that the server understands. There are several commands that the server understands.
.TP .TP
.B start .B start
Start the server. Simply execs \fIunbound\fR(8). The unbound executable Start the server. Simply execs \fIunbound\fR(8). The Unbound executable
is searched for in the \fBPATH\fR set in the environment. It is started is searched for in the \fBPATH\fR set in the environment. It is started
with the config file specified using \fI\-c\fR or the default config file. with the config file specified using \fI\-c\fR or the default config file.
.TP .TP
@ -187,7 +187,7 @@ therefore not flushed. The option must end with a ':' and whitespace
must be between the option and the value. Some values may not have an must be between the option and the value. Some values may not have an
effect if set this way, the new values are not written to the config file, effect if set this way, the new values are not written to the config file,
not all options are supported. This is different from the set_option call not all options are supported. This is different from the set_option call
in libunbound, where all values work because unbound has not been initialized. in libunbound, where all values work because Unbound has not been initialized.
.IP .IP
The values that work are: statistics\-interval, statistics\-cumulative, The values that work are: statistics\-interval, statistics\-cumulative,
do\-not\-query\-localhost, harden\-short\-bufsize, harden\-large\-queries, do\-not\-query\-localhost, harden\-short\-bufsize, harden\-large\-queries,
@ -227,31 +227,31 @@ List the local data RRs in use. The resource records are printed.
.TP .TP
.B insecure_add \fIzone .B insecure_add \fIzone
Add a \fBdomain\-insecure\fR for the given zone, like the statement in unbound.conf. Add a \fBdomain\-insecure\fR for the given zone, like the statement in unbound.conf.
Adds to the running unbound without affecting the cache contents (which may Adds to the running Unbound without affecting the cache contents (which may
still be bogus, use \fBflush_zone\fR to remove it), does not affect the config file. still be bogus, use \fBflush_zone\fR to remove it), does not affect the config file.
.TP .TP
.B insecure_remove \fIzone .B insecure_remove \fIzone
Removes domain\-insecure for the given zone. Removes domain\-insecure for the given zone.
.TP .TP
.B forward_add \fR[\fI+i\fR] \fIzone addr ... .B forward_add \fR[\fI+i\fR] \fIzone addr ...
Add a new forward zone to running unbound. With +i option also adds a Add a new forward zone to running Unbound. With +i option also adds a
\fIdomain\-insecure\fR for the zone (so it can resolve insecurely if you have \fIdomain\-insecure\fR for the zone (so it can resolve insecurely if you have
a DNSSEC root trust anchor configured for other names). a DNSSEC root trust anchor configured for other names).
The addr can be IP4, IP6 or nameserver names, like \fIforward-zone\fR config The addr can be IP4, IP6 or nameserver names, like \fIforward-zone\fR config
in unbound.conf. in unbound.conf.
.TP .TP
.B forward_remove \fR[\fI+i\fR] \fIzone .B forward_remove \fR[\fI+i\fR] \fIzone
Remove a forward zone from running unbound. The +i also removes a Remove a forward zone from running Unbound. The +i also removes a
\fIdomain\-insecure\fR for the zone. \fIdomain\-insecure\fR for the zone.
.TP .TP
.B stub_add \fR[\fI+ip\fR] \fIzone addr ... .B stub_add \fR[\fI+ip\fR] \fIzone addr ...
Add a new stub zone to running unbound. With +i option also adds a Add a new stub zone to running Unbound. With +i option also adds a
\fIdomain\-insecure\fR for the zone. With +p the stub zone is set to prime, \fIdomain\-insecure\fR for the zone. With +p the stub zone is set to prime,
without it it is set to notprime. The addr can be IP4, IP6 or nameserver without it it is set to notprime. The addr can be IP4, IP6 or nameserver
names, like the \fIstub-zone\fR config in unbound.conf. names, like the \fIstub-zone\fR config in unbound.conf.
.TP .TP
.B stub_remove \fR[\fI+i\fR] \fIzone .B stub_remove \fR[\fI+i\fR] \fIzone
Remove a stub zone from running unbound. The +i also removes a Remove a stub zone from running Unbound. The +i also removes a
\fIdomain\-insecure\fR for the zone. \fIdomain\-insecure\fR for the zone.
.TP .TP
.B forward \fR[\fIoff\fR | \fIaddr ...\fR ] .B forward \fR[\fIoff\fR | \fIaddr ...\fR ]
@ -296,7 +296,7 @@ status, indicating if the zone is expired and current serial number.
Reload the auth zone from zonefile. The zonefile is read in overwriting Reload the auth zone from zonefile. The zonefile is read in overwriting
the current contents of the zone in memory. This changes the auth zone the current contents of the zone in memory. This changes the auth zone
contents itself, not the cache contents. Such cache contents exists if contents itself, not the cache contents. Such cache contents exists if
you set unbound to validate with for-upstream yes and that can be cleared you set Unbound to validate with for-upstream yes and that can be cleared
with \fBflush_zone\fR \fIzone\fR. with \fBflush_zone\fR \fIzone\fR.
.TP .TP
.B auth_zone_transfer \fIzone\fR .B auth_zone_transfer \fIzone\fR
@ -544,27 +544,27 @@ The total number of queries over all threads with query opcode QUERY.
Also printed for other opcodes, UPDATE, ... Also printed for other opcodes, UPDATE, ...
.TP .TP
.I num.query.tcp .I num.query.tcp
Number of queries that were made using TCP towards the unbound server. Number of queries that were made using TCP towards the Unbound server.
.TP .TP
.I num.query.tcpout .I num.query.tcpout
Number of queries that the unbound server made using TCP outgoing towards Number of queries that the Unbound server made using TCP outgoing towards
other servers. other servers.
.TP .TP
.I num.query.tls .I num.query.tls
Number of queries that were made using TLS towards the unbound server. Number of queries that were made using TLS towards the Unbound server.
These are also counted in num.query.tcp, because TLS uses TCP. These are also counted in num.query.tcp, because TLS uses TCP.
.TP .TP
.I num.query.tls.resume .I num.query.tls.resume
Number of TLS session resumptions, these are queries over TLS towards Number of TLS session resumptions, these are queries over TLS towards
the unbound server where the client negotiated a TLS session resumption key. the Unbound server where the client negotiated a TLS session resumption key.
.TP .TP
.I num.query.https .I num.query.https
Number of queries that were made using HTTPS towards the unbound server. Number of queries that were made using HTTPS towards the Unbound server.
These are also counted in num.query.tcp and num.query.tls, because HTTPS These are also counted in num.query.tcp and num.query.tls, because HTTPS
uses TLS and TCP. uses TLS and TCP.
.TP .TP
.I num.query.ipv6 .I num.query.ipv6
Number of queries that were made using IPv6 towards the unbound server. Number of queries that were made using IPv6 towards the Unbound server.
.TP .TP
.I num.query.flags.RD .I num.query.flags.RD
The number of queries that had the RD flag set in the header. The number of queries that had the RD flag set in the header.
@ -644,7 +644,7 @@ per delegation point, and their validation status.
.I dnscrypt_shared_secret.cache.count .I dnscrypt_shared_secret.cache.count
The number of items in the shared secret cache. These are precomputed shared The number of items in the shared secret cache. These are precomputed shared
secrets for a given client public key/server secret key pair. Shared secrets secrets for a given client public key/server secret key pair. Shared secrets
are CPU intensive and this cache allows unbound to avoid recomputing the are CPU intensive and this cache allows Unbound to avoid recomputing the
shared secret when multiple dnscrypt queries are sent from the same client. shared secret when multiple dnscrypt queries are sent from the same client.
.TP .TP
.I dnscrypt_nonce.cache.count .I dnscrypt_nonce.cache.count
@ -689,7 +689,7 @@ disabled, and cname\-override.
.SH "FILES" .SH "FILES"
.TP .TP
.I @ub_conf_file@ .I @ub_conf_file@
unbound configuration file. Unbound configuration file.
.TP .TP
.I @UNBOUND_RUN_DIR@ .I @UNBOUND_RUN_DIR@
directory with private keys (unbound_server.key and unbound_control.key) and directory with private keys (unbound_server.key and unbound_control.key) and

View File

@ -1,4 +1,4 @@
.TH "unbound\-host" "1" "Dec 9, 2021" "NLnet Labs" "unbound 1.14.0" .TH "unbound\-host" "1" "Feb 10, 2022" "NLnet Labs" "unbound 1.15.0"
.\" .\"
.\" unbound-host.1 -- unbound DNS lookup utility .\" unbound-host.1 -- unbound DNS lookup utility
.\" .\"
@ -28,12 +28,12 @@
.I hostname .I hostname
.SH "DESCRIPTION" .SH "DESCRIPTION"
.B Unbound\-host .B Unbound\-host
uses the unbound validating resolver to query for the hostname and display uses the Unbound validating resolver to query for the hostname and display
results. With the \fB\-v\fR option it displays validation results. With the \fB\-v\fR option it displays validation
status: secure, insecure, bogus (security failure). status: secure, insecure, bogus (security failure).
.P .P
By default it reads no configuration file whatsoever. It attempts to reach By default it reads no configuration file whatsoever. It attempts to reach
the internet root servers. With \fB\-C\fR an unbound config file and with the internet root servers. With \fB\-C\fR an Unbound config file and with
\fB\-r\fR resolv.conf can be read. \fB\-r\fR resolv.conf can be read.
.P .P
The available options are: The available options are:

View File

@ -1,4 +1,4 @@
.TH "unbound" "8" "Dec 9, 2021" "NLnet Labs" "unbound 1.14.0" .TH "unbound" "8" "Feb 10, 2022" "NLnet Labs" "unbound 1.15.0"
.\" .\"
.\" unbound.8 -- unbound manual .\" unbound.8 -- unbound manual
.\" .\"
@ -9,7 +9,7 @@
.\" .\"
.SH "NAME" .SH "NAME"
.B unbound .B unbound
\- Unbound DNS validating resolver 1.14.0. \- Unbound DNS validating resolver 1.15.0.
.SH "SYNOPSIS" .SH "SYNOPSIS"
.B unbound .B unbound
.RB [ \-h ] .RB [ \-h ]
@ -57,7 +57,7 @@ The available options are:
Show the version number and commandline option help, and exit. Show the version number and commandline option help, and exit.
.TP .TP
.B \-c\fI cfgfile .B \-c\fI cfgfile
Set the config file with settings for unbound to read instead of reading the Set the config file with settings for Unbound to read instead of reading the
file at the default location, @ub_conf_file@. The syntax is file at the default location, @ub_conf_file@. The syntax is
described in \fIunbound.conf\fR(5). described in \fIunbound.conf\fR(5).
.TP .TP
@ -70,7 +70,7 @@ or to syslog, but the log messages are printed to stderr all the time.
.TP .TP
.B \-p .B \-p
Don't use a pidfile. This argument should only be used by supervision Don't use a pidfile. This argument should only be used by supervision
systems which can ensure that only one instance of unbound will run systems which can ensure that only one instance of Unbound will run
concurrently. concurrently.
.TP .TP
.B \-v .B \-v

View File

@ -1,4 +1,4 @@
.TH "unbound.conf" "5" "Dec 9, 2021" "NLnet Labs" "unbound 1.14.0" .TH "unbound.conf" "5" "Feb 10, 2022" "NLnet Labs" "unbound 1.15.0"
.\" .\"
.\" unbound.conf.5 -- unbound.conf manual .\" unbound.conf.5 -- unbound.conf manual
.\" .\"
@ -104,7 +104,7 @@ requestlist statistics are printed for every interval (but can be 0).
This is because the median calculation requires data to be present. This is because the median calculation requires data to be present.
.TP .TP
.B statistics\-cumulative: \fI<yes or no> .B statistics\-cumulative: \fI<yes or no>
If enabled, statistics are cumulative since starting unbound, without clearing If enabled, statistics are cumulative since starting Unbound, without clearing
the statistics counters after logging the statistics. Default is no. the statistics counters after logging the statistics. Default is no.
.TP .TP
.B extended\-statistics: \fI<yes or no> .B extended\-statistics: \fI<yes or no>
@ -136,7 +136,7 @@ Same as interface: (for ease of compatibility with nsd.conf).
Listen on all addresses on all (current and future) interfaces, detect the Listen on all addresses on all (current and future) interfaces, detect the
source interface on UDP queries and copy them to replies. This is a lot like source interface on UDP queries and copy them to replies. This is a lot like
ip\-transparent, but this option services all interfaces whilst with ip\-transparent, but this option services all interfaces whilst with
ip\-transparent you can select which (future) interfaces unbound provides ip\-transparent you can select which (future) interfaces Unbound provides
service on. This feature is experimental, and needs support in your OS for service on. This feature is experimental, and needs support in your OS for
particular socket options. Default value is no. particular socket options. Default value is no.
.TP .TP
@ -154,7 +154,7 @@ sent via a random outgoing interface to counter spoofing.
If an IPv6 netblock is specified instead of an individual IPv6 address, If an IPv6 netblock is specified instead of an individual IPv6 address,
outgoing UDP queries will use a randomised source address taken from the outgoing UDP queries will use a randomised source address taken from the
netblock to counter spoofing. Requires the IPv6 netblock to be routed to the netblock to counter spoofing. Requires the IPv6 netblock to be routed to the
host running unbound, and requires OS support for unprivileged non-local binds host running Unbound, and requires OS support for unprivileged non-local binds
(currently only supported on Linux). Several netblocks may be specified with (currently only supported on Linux). Several netblocks may be specified with
multiple multiple
.B outgoing\-interface: .B outgoing\-interface:
@ -174,7 +174,7 @@ numbers need extra resources from the operating system. For performance a
very large value is best, use libevent to make this possible. very large value is best, use libevent to make this possible.
.TP .TP
.B outgoing\-port\-permit: \fI<port number or range> .B outgoing\-port\-permit: \fI<port number or range>
Permit unbound to open this port or range of ports for use to send queries. Permit Unbound to open this port or range of ports for use to send queries.
A larger number of permitted outgoing ports increases resilience against A larger number of permitted outgoing ports increases resilience against
spoofing attempts. Make sure these ports are not needed by other daemons. spoofing attempts. Make sure these ports are not needed by other daemons.
By default only ports above 1024 that have not been assigned by IANA are used. By default only ports above 1024 that have not been assigned by IANA are used.
@ -187,8 +187,8 @@ processing starts with the non IANA allocated ports above 1024 in the set
of allowed ports. of allowed ports.
.TP .TP
.B outgoing\-port\-avoid: \fI<port number or range> .B outgoing\-port\-avoid: \fI<port number or range>
Do not permit unbound to open this port or range of ports for use to send Do not permit Unbound to open this port or range of ports for use to send
queries. Use this to make sure unbound does not grab a port that another queries. Use this to make sure Unbound does not grab a port that another
daemon needs. The port is avoided on all outgoing interfaces, both IP4 and IP6. daemon needs. The port is avoided on all outgoing interfaces, both IP4 and IP6.
By default only ports above 1024 that have not been assigned by IANA are used. By default only ports above 1024 that have not been assigned by IANA are used.
Give a port number or a range of the form "low\-high", without spaces. Give a port number or a range of the form "low\-high", without spaces.
@ -289,7 +289,7 @@ If not 0, then set the SO_RCVBUF socket option to get more buffer
space on UDP port 53 incoming queries. So that short spikes on busy space on UDP port 53 incoming queries. So that short spikes on busy
servers do not drop packets (see counter in netstat \-su). Default is servers do not drop packets (see counter in netstat \-su). Default is
0 (use system value). Otherwise, the number of bytes to ask for, try 0 (use system value). Otherwise, the number of bytes to ask for, try
"4m" on a busy server. The OS caps it at a maximum, on linux unbound "4m" on a busy server. The OS caps it at a maximum, on linux Unbound
needs root permission to bypass the limit, or the admin can use sysctl needs root permission to bypass the limit, or the admin can use sysctl
net.core.rmem_max. On BSD change kern.ipc.maxsockbuf in /etc/sysctl.conf. net.core.rmem_max. On BSD change kern.ipc.maxsockbuf in /etc/sysctl.conf.
On OpenBSD change header and recompile kernel. On Solaris ndd \-set On OpenBSD change header and recompile kernel. On Solaris ndd \-set
@ -302,7 +302,7 @@ in answer traffic, otherwise 'send: resource temporarily unavailable'
can get logged, the buffer overrun is also visible by netstat \-su. can get logged, the buffer overrun is also visible by netstat \-su.
Default is 0 (use system value). Specify the number of bytes to ask Default is 0 (use system value). Specify the number of bytes to ask
for, try "4m" on a very busy server. The OS caps it at a maximum, on for, try "4m" on a very busy server. The OS caps it at a maximum, on
linux unbound needs root permission to bypass the limit, or the admin linux Unbound needs root permission to bypass the limit, or the admin
can use sysctl net.core.wmem_max. On BSD, Solaris changes are similar can use sysctl net.core.wmem_max. On BSD, Solaris changes are similar
to so\-rcvbuf. to so\-rcvbuf.
.TP .TP
@ -319,18 +319,18 @@ At extreme load it could be better to turn it off to distribute the queries
evenly, reported for Linux systems (4.4.x). evenly, reported for Linux systems (4.4.x).
.TP .TP
.B ip\-transparent: \fI<yes or no> .B ip\-transparent: \fI<yes or no>
If yes, then use IP_TRANSPARENT socket option on sockets where unbound If yes, then use IP_TRANSPARENT socket option on sockets where Unbound
is listening for incoming traffic. Default no. Allows you to bind to is listening for incoming traffic. Default no. Allows you to bind to
non\-local interfaces. For example for non\-existent IP addresses that non\-local interfaces. For example for non\-existent IP addresses that
are going to exist later on, with host failover configuration. This is are going to exist later on, with host failover configuration. This is
a lot like interface\-automatic, but that one services all interfaces a lot like interface\-automatic, but that one services all interfaces
and with this option you can select which (future) interfaces unbound and with this option you can select which (future) interfaces Unbound
provides service on. This option needs unbound to be started with root provides service on. This option needs Unbound to be started with root
permissions on some systems. The option uses IP_BINDANY on FreeBSD systems permissions on some systems. The option uses IP_BINDANY on FreeBSD systems
and SO_BINDANY on OpenBSD systems. and SO_BINDANY on OpenBSD systems.
.TP .TP
.B ip\-freebind: \fI<yes or no> .B ip\-freebind: \fI<yes or no>
If yes, then use IP_FREEBIND socket option on sockets where unbound If yes, then use IP_FREEBIND socket option on sockets where Unbound
is listening to incoming traffic. Default no. Allows you to bind to is listening to incoming traffic. Default no. Allows you to bind to
IP addresses that are nonlocal or do not exist, like when the network IP addresses that are nonlocal or do not exist, like when the network
interface or IP address is down. Exists only on Linux, where the similar interface or IP address is down. Exists only on Linux, where the similar
@ -560,7 +560,7 @@ service. Can list multiple, each on a new statement.
.TP .TP
.B tls-session-ticket-keys: \fI<file> .B tls-session-ticket-keys: \fI<file>
If not "", lists files with 80 bytes of random contents that are used to If not "", lists files with 80 bytes of random contents that are used to
perform TLS session resumption for clients using the unbound server. perform TLS session resumption for clients using the Unbound server.
These files contain the secret key for the TLS session tickets. These files contain the secret key for the TLS session tickets.
First key use to encrypt and decrypt TLS session tickets. First key use to encrypt and decrypt TLS session tickets.
Other keys use to decrypt only. With this you can roll over to new keys, Other keys use to decrypt only. With this you can roll over to new keys,
@ -642,8 +642,8 @@ Enable or disable systemd socket activation.
Default is no. Default is no.
.TP .TP
.B do\-daemonize: \fI<yes or no> .B do\-daemonize: \fI<yes or no>
Enable or disable whether the unbound server forks into the background as Enable or disable whether the Unbound server forks into the background as
a daemon. Set the value to \fIno\fR when unbound runs as systemd service. a daemon. Set the value to \fIno\fR when Unbound runs as systemd service.
Default is yes. Default is yes.
.TP .TP
.B tcp\-connection\-limit: \fI<IP netblock> <limit> .B tcp\-connection\-limit: \fI<IP netblock> <limit>
@ -670,7 +670,7 @@ what almost all clients need). Nonrecursive queries are refused.
.IP .IP
The \fIallow\fR action does allow nonrecursive queries to access the The \fIallow\fR action does allow nonrecursive queries to access the
local\-data that is configured. The reason is that this does not involve local\-data that is configured. The reason is that this does not involve
the unbound server recursive lookup algorithm, and static data is served the Unbound server recursive lookup algorithm, and static data is served
in the reply. This supports normal operations where nonrecursive queries in the reply. This supports normal operations where nonrecursive queries
are made for the authoritative data. For nonrecursive queries any replies are made for the authoritative data. For nonrecursive queries any replies
from the dynamic cache are refused. from the dynamic cache are refused.
@ -742,7 +742,7 @@ to chroot and dropping permissions. This allows the pidfile to be
Unbound is not able to remove the pidfile after termination when it is located Unbound is not able to remove the pidfile after termination when it is located
outside of the chroot directory. outside of the chroot directory.
.IP .IP
Additionally, unbound may need to access /dev/urandom (for entropy) Additionally, Unbound may need to access /dev/urandom (for entropy)
from inside the chroot. from inside the chroot.
.IP .IP
If given a chroot is done to the given directory. By default chroot is If given a chroot is done to the given directory. By default chroot is
@ -776,7 +776,7 @@ The logfile is reopened (for append) when the config file is reread, on
SIGHUP. SIGHUP.
.TP .TP
.B use\-syslog: \fI<yes or no> .B use\-syslog: \fI<yes or no>
Sets unbound to send log messages to the syslogd, using Sets Unbound to send log messages to the syslogd, using
\fIsyslog\fR(3). \fIsyslog\fR(3).
The log facility LOG_DAEMON is used, with identity "unbound". The log facility LOG_DAEMON is used, with identity "unbound".
The logfile setting is overridden when use\-syslog is turned on. The logfile setting is overridden when use\-syslog is turned on.
@ -786,7 +786,7 @@ The default is to log to syslog.
If "" is given (default), then the name of the executable, usually "unbound" If "" is given (default), then the name of the executable, usually "unbound"
is used to report to the log. Enter a string to override it is used to report to the log. Enter a string to override it
with that, which is useful on systems that run more than one instance of with that, which is useful on systems that run more than one instance of
unbound, with different configurations, so that the logs can be easily Unbound, with different configurations, so that the logs can be easily
distinguished against. distinguished against.
.TP .TP
.B log\-time\-ascii: \fI<yes or no> .B log\-time\-ascii: \fI<yes or no>
@ -874,12 +874,12 @@ with ascii_ prefix and then an ascii string.
If enabled trustanchor.unbound queries are refused. If enabled trustanchor.unbound queries are refused.
.TP .TP
.B target\-fetch\-policy: \fI<"list of numbers"> .B target\-fetch\-policy: \fI<"list of numbers">
Set the target fetch policy used by unbound to determine if it should fetch Set the target fetch policy used by Unbound to determine if it should fetch
nameserver target addresses opportunistically. The policy is described per nameserver target addresses opportunistically. The policy is described per
dependency depth. dependency depth.
.IP .IP
The number of values determines the maximum dependency depth The number of values determines the maximum dependency depth
that unbound will pursue in answering a query. that Unbound will pursue in answering a query.
A value of \-1 means to fetch all targets opportunistically for that dependency A value of \-1 means to fetch all targets opportunistically for that dependency
depth. A value of 0 means to fetch on demand only. A positive value fetches depth. A value of 0 means to fetch on demand only. A positive value fetches
that many targets opportunistically. that many targets opportunistically.
@ -973,7 +973,7 @@ This option only has effect when qname-minimisation is enabled. Default is no.
.B aggressive\-nsec: \fI<yes or no> .B aggressive\-nsec: \fI<yes or no>
Aggressive NSEC uses the DNSSEC NSEC chain to synthesize NXDOMAIN Aggressive NSEC uses the DNSSEC NSEC chain to synthesize NXDOMAIN
and other denials, using information from previous NXDOMAINs answers. and other denials, using information from previous NXDOMAINs answers.
Default is no. It helps to reduce the query rate towards targets that get Default is yes. It helps to reduce the query rate towards targets that get
a very high nonexistent name lookup rate. a very high nonexistent name lookup rate.
.TP .TP
.B private\-address: \fI<IP address or subnet> .B private\-address: \fI<IP address or subnet>
@ -1030,7 +1030,7 @@ a little more CPU. Also if the cache is set to 0, it is no use. Default is no.
.TP .TP
.B deny\-any: \fI<yes or no> .B deny\-any: \fI<yes or no>
If yes, deny queries of type ANY with an empty response. Default is no. If yes, deny queries of type ANY with an empty response. Default is no.
If disabled, unbound responds with a short list of resource records if some If disabled, Unbound responds with a short list of resource records if some
can be found in the cache and makes the upstream type ANY query if there can be found in the cache and makes the upstream type ANY query if there
are none. are none.
.TP .TP
@ -1090,7 +1090,7 @@ File with trust anchor for one zone, which is tracked with RFC5011 probes.
The probes are run several times per month, thus the machine must be online The probes are run several times per month, thus the machine must be online
frequently. The initial file can be one with contents as described in frequently. The initial file can be one with contents as described in
\fBtrust\-anchor\-file\fR. The file is written to when the anchor is updated, \fBtrust\-anchor\-file\fR. The file is written to when the anchor is updated,
so the unbound user must have write permission. Write permission to the file, so the Unbound user must have write permission. Write permission to the file,
but also to the directory it is in (to create a temporary file, which is but also to the directory it is in (to create a temporary file, which is
necessary to deal with filesystem full events), it must also be inside the necessary to deal with filesystem full events), it must also be inside the
chroot (if that is used). chroot (if that is used).
@ -1176,7 +1176,7 @@ the verbosity setting. Default is 0, off. At 1, for every user query
that fails a line is printed to the logs. This way you can monitor what that fails a line is printed to the logs. This way you can monitor what
happens with validation. Use a diagnosis tool, such as dig or drill, happens with validation. Use a diagnosis tool, such as dig or drill,
to find out why validation is failing for these queries. At 2, not only to find out why validation is failing for these queries. At 2, not only
the query that failed is printed but also the reason why unbound thought the query that failed is printed but also the reason why Unbound thought
it was wrong and which server sent the faulty data. it was wrong and which server sent the faulty data.
.TP .TP
.B val\-permissive\-mode: \fI<yes or no> .B val\-permissive\-mode: \fI<yes or no>
@ -1188,15 +1188,15 @@ is set in replies. Also logging is performed as for full validation.
The default value is "no". The default value is "no".
.TP .TP
.B ignore\-cd\-flag: \fI<yes or no> .B ignore\-cd\-flag: \fI<yes or no>
Instruct unbound to ignore the CD flag from clients and refuse to Instruct Unbound to ignore the CD flag from clients and refuse to
return bogus answers to them. Thus, the CD (Checking Disabled) flag return bogus answers to them. Thus, the CD (Checking Disabled) flag
does not disable checking any more. This is useful if legacy (w2008) does not disable checking any more. This is useful if legacy (w2008)
servers that set the CD flag but cannot validate DNSSEC themselves are servers that set the CD flag but cannot validate DNSSEC themselves are
the clients, and then unbound provides them with DNSSEC protection. the clients, and then Unbound provides them with DNSSEC protection.
The default value is "no". The default value is "no".
.TP .TP
.B serve\-expired: \fI<yes or no> .B serve\-expired: \fI<yes or no>
If enabled, unbound attempts to serve old responses from cache with a If enabled, Unbound attempts to serve old responses from cache with a
TTL of \fBserve\-expired\-reply\-ttl\fR in the response without waiting for the TTL of \fBserve\-expired\-reply\-ttl\fR in the response without waiting for the
actual resolution to finish. The actual resolution answer ends up in the cache actual resolution to finish. The actual resolution answer ends up in the cache
later on. Default is "no". later on. Default is "no".
@ -1227,14 +1227,14 @@ RFC 8767 is 1800. Setting this to 0 will disable this
behavior. Default is 0. behavior. Default is 0.
.TP .TP
.B serve\-original\-ttl: \fI<yes or no> .B serve\-original\-ttl: \fI<yes or no>
If enabled, unbound will always return the original TTL as received from If enabled, Unbound will always return the original TTL as received from
the upstream name server rather than the decrementing TTL as the upstream name server rather than the decrementing TTL as
stored in the cache. This feature may be useful if unbound serves as a stored in the cache. This feature may be useful if Unbound serves as a
front-end to a hidden authoritative name server. Enabling this feature does front-end to a hidden authoritative name server. Enabling this feature does
not impact cache expiry, it only changes the TTL unbound embeds in responses to not impact cache expiry, it only changes the TTL Unbound embeds in responses to
queries. Note that enabling this feature implicitly disables enforcement of queries. Note that enabling this feature implicitly disables enforcement of
the configured minimum and maximum TTL, as it is assumed users who enable this the configured minimum and maximum TTL, as it is assumed users who enable this
feature do not want unbound to change the TTL obtained from an upstream server. feature do not want Unbound to change the TTL obtained from an upstream server.
Thus, the values set using \fBcache\-min\-ttl\fR and \fBcache\-max\-ttl\fR are Thus, the values set using \fBcache\-min\-ttl\fR and \fBcache\-max\-ttl\fR are
ignored. ignored.
Default is "no". Default is "no".
@ -1295,11 +1295,11 @@ or gigabytes (1024*1024 bytes in a megabyte).
.TP .TP
.B unblock\-lan\-zones: \fI<yes or no> .B unblock\-lan\-zones: \fI<yes or no>
Default is disabled. If enabled, then for private address space, Default is disabled. If enabled, then for private address space,
the reverse lookups are no longer filtered. This allows unbound when the reverse lookups are no longer filtered. This allows Unbound when
running as dns service on a host where it provides service for that host, running as dns service on a host where it provides service for that host,
to put out all of the queries for the 'lan' upstream. When enabled, to put out all of the queries for the 'lan' upstream. When enabled,
only localhost, 127.0.0.1 reverse and ::1 reverse zones are configured only localhost, 127.0.0.1 reverse and ::1 reverse zones are configured
with default local zones. Disable the option when unbound is running with default local zones. Disable the option when Unbound is running
as a (DHCP-) DNS network resolver for a group of machines, where such as a (DHCP-) DNS network resolver for a group of machines, where such
lookups should be filtered (RFC compliance), this also stops potential lookups should be filtered (RFC compliance), this also stops potential
data leakage about the local network to the upstream DNS servers. data leakage about the local network to the upstream DNS servers.
@ -1647,8 +1647,9 @@ query names, but not spoofed reflection floods. Cached responses are not
ratelimited by this setting. The zone of the query is determined by examining ratelimited by this setting. The zone of the query is determined by examining
the nameservers for it, the zone name is used to keep track of the rate. the nameservers for it, the zone name is used to keep track of the rate.
For example, 1000 may be a suitable value to stop the server from being For example, 1000 may be a suitable value to stop the server from being
overloaded with random names, and keeps unbound from sending traffic to the overloaded with random names, and keeps Unbound from sending traffic to the
nameservers for those zones. nameservers for those zones. Configured forwarders are excluded from
ratelimiting.
.TP 5 .TP 5
.B ratelimit\-size: \fI<memory size> .B ratelimit\-size: \fI<memory size>
Give the size of the data structure in which the current ongoing rates are Give the size of the data structure in which the current ongoing rates are
@ -1670,6 +1671,15 @@ This can make ordinary queries complete (if repeatedly queried for),
and enter the cache, whilst also mitigating the traffic flow by the and enter the cache, whilst also mitigating the traffic flow by the
factor given. factor given.
.TP 5 .TP 5
.B ratelimit\-backoff: \fI<yes or no>
If enabled, the ratelimit is treated as a hard failure instead of the default
maximum allowed constant rate. When the limit is reached, traffic is
ratelimited and demand continues to be kept track of for a 2 second rate
window. No traffic is allowed, except for ratelimit\-factor, until demand
decreases below the configured ratelimit for a 2 second rate window. Useful to
set ratelimit to a suspicious rate to aggressively limit unusually high
traffic. Default is off.
.TP 5
.B ratelimit\-for\-domain: \fI<domain> <number qps or 0> .B ratelimit\-for\-domain: \fI<domain> <number qps or 0>
Override the global ratelimit for an exact match domain name with the listed Override the global ratelimit for an exact match domain name with the listed
number. You can give this for any number of names. For example, for number. You can give this for any number of names. For example, for
@ -1686,7 +1696,7 @@ to use different settings for a top\-level\-domain and subdomains.
A value of 0 will disable ratelimiting for domain names that end in this name. A value of 0 will disable ratelimiting for domain names that end in this name.
.TP 5 .TP 5
.B ip\-ratelimit: \fI<number or 0> .B ip\-ratelimit: \fI<number or 0>
Enable global ratelimiting of queries accepted per ip address. Enable global ratelimiting of queries accepted per IP address.
If 0, the default, it is disabled. This option is experimental at this time. If 0, the default, it is disabled. This option is experimental at this time.
The ratelimit is in queries per second that are allowed. More queries are The ratelimit is in queries per second that are allowed. More queries are
completely dropped and will not receive a reply, SERVFAIL or otherwise. completely dropped and will not receive a reply, SERVFAIL or otherwise.
@ -1713,8 +1723,17 @@ This can make ordinary queries complete (if repeatedly queried for),
and enter the cache, whilst also mitigating the traffic flow by the and enter the cache, whilst also mitigating the traffic flow by the
factor given. factor given.
.TP 5 .TP 5
.B ip\-ratelimit\-backoff: \fI<yes or no>
If enabled, the ratelimit is treated as a hard failure instead of the default
maximum allowed constant rate. When the limit is reached, traffic is
ratelimited and demand continues to be kept track of for a 2 second rate
window. No traffic is allowed, except for ip\-ratelimit\-factor, until demand
decreases below the configured ratelimit for a 2 second rate window. Useful to
set ip\-ratelimit to a suspicious rate to aggressively limit unusually high
traffic. Default is off.
.TP 5
.B outbound\-msg\-retry: \fI<number> .B outbound\-msg\-retry: \fI<number>
The number of retries unbound will do in case of a non positive response is The number of retries Unbound will do in case of a non positive response is
received. If a forward nameserver is used, this is the number of retries per received. If a forward nameserver is used, this is the number of retries per
forward nameserver in case of throwaway response. forward nameserver in case of throwaway response.
.TP 5 .TP 5
@ -1747,7 +1766,7 @@ In the
.B remote\-control: .B remote\-control:
clause are the declarations for the remote control facility. If this is clause are the declarations for the remote control facility. If this is
enabled, the \fIunbound\-control\fR(8) utility can be used to send enabled, the \fIunbound\-control\fR(8) utility can be used to send
commands to the running unbound server. The server uses these clauses commands to the running Unbound server. The server uses these clauses
to setup TLSv1 security for the connection. The to setup TLSv1 security for the connection. The
\fIunbound\-control\fR(8) utility also reads the \fBremote\-control\fR \fIunbound\-control\fR(8) utility also reads the \fBremote\-control\fR
section for options. To setup the correct self\-signed certificates use the section for options. To setup the correct self\-signed certificates use the
@ -1767,7 +1786,7 @@ the server for the change to take effect.
.IP .IP
If you set it to an absolute path, a local socket is used. The local socket If you set it to an absolute path, a local socket is used. The local socket
does not use the certificates and keys, so those files need not be present. does not use the certificates and keys, so those files need not be present.
To restrict access, unbound sets permissions on the file to the user and To restrict access, Unbound sets permissions on the file to the user and
group that is configured, the access bits are set to allow the group members group that is configured, the access bits are set to allow the group members
to access the control socket file. Put users that need to access the socket to access the control socket file. Put users that need to access the socket
in the that group. To restrict access further, create a directory to put in the that group. To restrict access further, create a directory to put
@ -1787,12 +1806,12 @@ and the value of this option is ignored.
.B server\-key\-file: \fI<private key file> .B server\-key\-file: \fI<private key file>
Path to the server private key, by default unbound_server.key. Path to the server private key, by default unbound_server.key.
This file is generated by the \fIunbound\-control\-setup\fR utility. This file is generated by the \fIunbound\-control\-setup\fR utility.
This file is used by the unbound server, but not by \fIunbound\-control\fR. This file is used by the Unbound server, but not by \fIunbound\-control\fR.
.TP 5 .TP 5
.B server\-cert\-file: \fI<certificate file.pem> .B server\-cert\-file: \fI<certificate file.pem>
Path to the server self signed certificate, by default unbound_server.pem. Path to the server self signed certificate, by default unbound_server.pem.
This file is generated by the \fIunbound\-control\-setup\fR utility. This file is generated by the \fIunbound\-control\-setup\fR utility.
This file is used by the unbound server, and also by \fIunbound\-control\fR. This file is used by the Unbound server, and also by \fIunbound\-control\fR.
.TP 5 .TP 5
.B control\-key\-file: \fI<private key file> .B control\-key\-file: \fI<private key file>
Path to the control client private key, by default unbound_control.key. Path to the control client private key, by default unbound_control.key.
@ -1810,24 +1829,24 @@ There may be multiple
.B stub\-zone: .B stub\-zone:
clauses. Each with a name: and zero or more hostnames or IP addresses. clauses. Each with a name: and zero or more hostnames or IP addresses.
For the stub zone this list of nameservers is used. Class IN is assumed. For the stub zone this list of nameservers is used. Class IN is assumed.
The servers should be authority servers, not recursors; unbound performs The servers should be authority servers, not recursors; Unbound performs
the recursive processing itself for stub zones. the recursive processing itself for stub zones.
.P .P
The stub zone can be used to configure authoritative data to be used The stub zone can be used to configure authoritative data to be used
by the resolver that cannot be accessed using the public internet servers. by the resolver that cannot be accessed using the public internet servers.
This is useful for company\-local data or private zones. Setup an This is useful for company\-local data or private zones. Setup an
authoritative server on a different host (or different port). Enter a config authoritative server on a different host (or different port). Enter a config
entry for unbound with entry for Unbound with
.B stub\-addr: .B stub\-addr:
<ip address of host[@port]>. <ip address of host[@port]>.
The unbound resolver can then access the data, without referring to the The Unbound resolver can then access the data, without referring to the
public internet for it. public internet for it.
.P .P
This setup allows DNSSEC signed zones to be served by that This setup allows DNSSEC signed zones to be served by that
authoritative server, in which case a trusted key entry with the public key authoritative server, in which case a trusted key entry with the public key
can be put in config, so that unbound can validate the data and set the AD can be put in config, so that Unbound can validate the data and set the AD
bit on replies for the private zone (authoritative servers do not set the bit on replies for the private zone (authoritative servers do not set the
AD bit). This setup makes unbound capable of answering queries for the AD bit). This setup makes Unbound capable of answering queries for the
private zone, and can even set the AD bit ('authentic'), but the AA private zone, and can even set the AD bit ('authentic'), but the AA
('authoritative') bit is not set on these replies. ('authoritative') bit is not set on these replies.
.P .P
@ -1835,20 +1854,26 @@ Consider adding \fBserver:\fR statements for \fBdomain\-insecure:\fR and
for \fBlocal\-zone:\fI name nodefault\fR for the zone if it is a locally for \fBlocal\-zone:\fI name nodefault\fR for the zone if it is a locally
served zone. The insecure clause stops DNSSEC from invalidating the served zone. The insecure clause stops DNSSEC from invalidating the
zone. The local zone nodefault (or \fItransparent\fR) clause makes the zone. The local zone nodefault (or \fItransparent\fR) clause makes the
(reverse\-) zone bypass unbound's filtering of RFC1918 zones. (reverse\-) zone bypass Unbound's filtering of RFC1918 zones.
.TP .TP
.B name: \fI<domain name> .B name: \fI<domain name>
Name of the stub zone. This is the full domain name of the zone. Name of the stub zone. This is the full domain name of the zone.
.TP .TP
.B stub\-host: \fI<domain name> .B stub\-host: \fI<domain name>
Name of stub zone nameserver. Is itself resolved before it is used. Name of stub zone nameserver. Is itself resolved before it is used.
To use a nondefault port for DNS communication append '@' with the port number.
If tls is enabled, then you can append a '#' and a name, then it'll check the
tls authentication certificates with that name. If you combine the '@'
and '#', the '@' comes first. If only '#' is used the default port is the
configured tls\-port.
.TP .TP
.B stub\-addr: \fI<IP address> .B stub\-addr: \fI<IP address>
IP address of stub zone nameserver. Can be IP 4 or IP 6. IP address of stub zone nameserver. Can be IP 4 or IP 6.
To use a nondefault port for DNS communication append '@' with the port number. To use a nondefault port for DNS communication append '@' with the port number.
If tls is enabled, then you can append a '#' and a name, then it'll check If tls is enabled, then you can append a '#' and a name, then it'll check the
the tls authentication certificates with that name. If you combine tls authentication certificates with that name. If you combine the '@'
the '@' and '#', the '@' comes first. and '#', the '@' comes first. If only '#' is used the default port is the
configured tls\-port.
.TP .TP
.B stub\-prime: \fI<yes or no> .B stub\-prime: \fI<yes or no>
This option is by default no. If enabled it performs NS set priming, This option is by default no. If enabled it performs NS set priming,
@ -1884,10 +1909,10 @@ clauses. Each with a \fBname:\fR and zero or more hostnames or IP
addresses. For the forward zone this list of nameservers is used to addresses. For the forward zone this list of nameservers is used to
forward the queries to. The servers listed as \fBforward\-host:\fR and forward the queries to. The servers listed as \fBforward\-host:\fR and
\fBforward\-addr:\fR have to handle further recursion for the query. Thus, \fBforward\-addr:\fR have to handle further recursion for the query. Thus,
those servers are not authority servers, but are (just like unbound is) those servers are not authority servers, but are (just like Unbound is)
recursive servers too; unbound does not perform recursion itself for the recursive servers too; Unbound does not perform recursion itself for the
forward zone, it lets the remote server do it. Class IN is assumed. forward zone, it lets the remote server do it. Class IN is assumed.
CNAMEs are chased by unbound itself, asking the remote server for every CNAMEs are chased by Unbound itself, asking the remote server for every
name in the indirection chain, to protect the local cache from illegal name in the indirection chain, to protect the local cache from illegal
indirect referenced items. indirect referenced items.
A forward\-zone entry with name "." and a forward\-addr target will A forward\-zone entry with name "." and a forward\-addr target will
@ -1899,13 +1924,19 @@ Name of the forward zone. This is the full domain name of the zone.
.TP .TP
.B forward\-host: \fI<domain name> .B forward\-host: \fI<domain name>
Name of server to forward to. Is itself resolved before it is used. Name of server to forward to. Is itself resolved before it is used.
To use a nondefault port for DNS communication append '@' with the port number.
If tls is enabled, then you can append a '#' and a name, then it'll check the
tls authentication certificates with that name. If you combine the '@'
and '#', the '@' comes first. If only '#' is used the default port is the
configured tls\-port.
.TP .TP
.B forward\-addr: \fI<IP address> .B forward\-addr: \fI<IP address>
IP address of server to forward to. Can be IP 4 or IP 6. IP address of server to forward to. Can be IP 4 or IP 6.
To use a nondefault port for DNS communication append '@' with the port number. To use a nondefault port for DNS communication append '@' with the port number.
If tls is enabled, then you can append a '#' and a name, then it'll check If tls is enabled, then you can append a '#' and a name, then it'll check the
the tls authentication certificates with that name. If you combine tls authentication certificates with that name. If you combine the '@'
the '@' and '#', the '@' comes first. and '#', the '@' comes first. If only '#' is used the default port is the
configured tls\-port.
.IP .IP
At high verbosity it logs the TLS certificate, with TLS enabled. At high verbosity it logs the TLS certificate, with TLS enabled.
If you leave out the '#' and auth name from the forward\-addr, any If you leave out the '#' and auth name from the forward\-addr, any
@ -1913,7 +1944,7 @@ name is accepted. The cert must also match a CA from the tls\-cert\-bundle.
.TP .TP
.B forward\-first: \fI<yes or no> .B forward\-first: \fI<yes or no>
If a forwarded query is met with a SERVFAIL error, and this option is If a forwarded query is met with a SERVFAIL error, and this option is
enabled, unbound will fall back to normal recursive resolution for this enabled, Unbound will fall back to normal recursive resolution for this
query as if no query forwarding had been specified. The default is "no". query as if no query forwarding had been specified. The default is "no".
.TP .TP
.B forward\-tls\-upstream: \fI<yes or no> .B forward\-tls\-upstream: \fI<yes or no>
@ -1939,7 +1970,7 @@ have a \fBname:\fR. There can be multiple ones, by listing multiple auth\-zone
The authority zone with the name closest to the name looked up is used. The authority zone with the name closest to the name looked up is used.
Authority zones are processed after \fBlocal\-zones\fR and before Authority zones are processed after \fBlocal\-zones\fR and before
cache (\fBfor\-downstream:\fR \fIyes\fR), and when used in this manner cache (\fBfor\-downstream:\fR \fIyes\fR), and when used in this manner
make unbound respond like an authority server. Authority zones are also make Unbound respond like an authority server. Authority zones are also
processed after cache, just before going to the network to fetch processed after cache, just before going to the network to fetch
information for recursion (\fBfor\-upstream:\fR \fIyes\fR), and when used information for recursion (\fBfor\-upstream:\fR \fIyes\fR), and when used
in this manner provide a local copy of an authority server that speeds up in this manner provide a local copy of an authority server that speeds up
@ -2000,25 +2031,25 @@ file is downloaded when notified. The primaries from primary: statements are
allowed notify by default. allowed notify by default.
.TP .TP
.B fallback\-enabled: \fI<yes or no> .B fallback\-enabled: \fI<yes or no>
Default no. If enabled, unbound falls back to querying the internet as Default no. If enabled, Unbound falls back to querying the internet as
a resolver for this zone when lookups fail. For example for DNSSEC a resolver for this zone when lookups fail. For example for DNSSEC
validation failures. validation failures.
.TP .TP
.B for\-downstream: \fI<yes or no> .B for\-downstream: \fI<yes or no>
Default yes. If enabled, unbound serves authority responses to Default yes. If enabled, Unbound serves authority responses to
downstream clients for this zone. This option makes unbound behave, for downstream clients for this zone. This option makes Unbound behave, for
the queries with names in this zone, like one of the authority servers for the queries with names in this zone, like one of the authority servers for
that zone. Turn it off if you want unbound to provide recursion for the that zone. Turn it off if you want Unbound to provide recursion for the
zone but have a local copy of zone data. If for\-downstream is no and zone but have a local copy of zone data. If for\-downstream is no and
for\-upstream is yes, then unbound will DNSSEC validate the contents of the for\-upstream is yes, then Unbound will DNSSEC validate the contents of the
zone before serving the zone contents to clients and store validation zone before serving the zone contents to clients and store validation
results in the cache. results in the cache.
.TP .TP
.B for\-upstream: \fI<yes or no> .B for\-upstream: \fI<yes or no>
Default yes. If enabled, unbound fetches data from this data collection Default yes. If enabled, Unbound fetches data from this data collection
for answering recursion queries. Instead of sending queries over the internet for answering recursion queries. Instead of sending queries over the internet
to the authority servers for this zone, it'll fetch the data directly from to the authority servers for this zone, it'll fetch the data directly from
the zone data. Turn it on when you want unbound to provide recursion for the zone data. Turn it on when you want Unbound to provide recursion for
downstream clients, and use the zone data as a local copy to speed up lookups. downstream clients, and use the zone data as a local copy to speed up lookups.
.TP .TP
.B zonemd\-check: \fI<yes or no> .B zonemd\-check: \fI<yes or no>
@ -2042,7 +2073,7 @@ a ZONEMD is always a failure, also for nonDNSSEC signed zones.
.TP .TP
.B zonefile: \fI<filename> .B zonefile: \fI<filename>
The filename where the zone is stored. If not given then no zonefile is used. The filename where the zone is stored. If not given then no zonefile is used.
If the file does not exist or is empty, unbound will attempt to fetch zone If the file does not exist or is empty, Unbound will attempt to fetch zone
data (eg. from the primary servers). data (eg. from the primary servers).
.SS "View Options" .SS "View Options"
.LP .LP
@ -2142,9 +2173,9 @@ underneath the name given.
The The
.B dnscrypt: .B dnscrypt:
clause gives the settings of the dnscrypt channel. While those options are clause gives the settings of the dnscrypt channel. While those options are
available, they are only meaningful if unbound was compiled with available, they are only meaningful if Unbound was compiled with
\fB\-\-enable\-dnscrypt\fR. \fB\-\-enable\-dnscrypt\fR.
Currently certificate and secret/public keys cannot be generated by unbound. Currently certificate and secret/public keys cannot be generated by Unbound.
You can use dnscrypt-wrapper to generate those: https://github.com/cofyc/\ You can use dnscrypt-wrapper to generate those: https://github.com/cofyc/\
dnscrypt-wrapper/blob/master/README.md#usage dnscrypt-wrapper/blob/master/README.md#usage
.TP .TP
@ -2276,12 +2307,13 @@ This number applies for each qname/qclass/qtype tuple. Defaults to 100.
.SS "Opportunistic IPsec Support Module Options" .SS "Opportunistic IPsec Support Module Options"
.LP .LP
The IPsec module must be configured in the \fBmodule\-config:\fR "ipsecmod The IPsec module must be configured in the \fBmodule\-config:\fR "ipsecmod
validator iterator" directive and be compiled into the daemon to be validator iterator" directive and be compiled into Unbound by using
enabled. These settings go in the \fBserver:\fR section. \fB\-\-enable\-ipsecmod\fR to be enabled.
These settings go in the \fBserver:\fR section.
.LP .LP
When unbound receives an A/AAAA query that is not in the cache and finds a When Unbound receives an A/AAAA query that is not in the cache and finds a
valid answer, it will withhold returning the answer and instead will generate valid answer, it will withhold returning the answer and instead will generate
an IPSECKEY subquery for the same domain name. If an answer was found, unbound an IPSECKEY subquery for the same domain name. If an answer was found, Unbound
will call an external hook passing the following arguments: will call an external hook passing the following arguments:
.TP 10 .TP 10
\h'5'\fIQNAME\fR \h'5'\fIQNAME\fR
@ -2310,19 +2342,19 @@ relevant for opportunistic IPsec.
.B ipsecmod-enabled: \fI<yes or no>\fR .B ipsecmod-enabled: \fI<yes or no>\fR
Specifies whether the IPsec module is enabled or not. The IPsec module still Specifies whether the IPsec module is enabled or not. The IPsec module still
needs to be defined in the \fBmodule\-config:\fR directive. This option needs to be defined in the \fBmodule\-config:\fR directive. This option
facilitates turning on/off the module without restarting/reloading unbound. facilitates turning on/off the module without restarting/reloading Unbound.
Defaults to yes. Defaults to yes.
.TP .TP
.B ipsecmod\-hook: \fI<filename>\fR .B ipsecmod\-hook: \fI<filename>\fR
Specifies the external hook that unbound will call with \fIsystem\fR(3). The Specifies the external hook that Unbound will call with \fIsystem\fR(3). The
file can be specified as an absolute/relative path. The file needs the proper file can be specified as an absolute/relative path. The file needs the proper
permissions to be able to be executed by the same user that runs unbound. It permissions to be able to be executed by the same user that runs Unbound. It
must be present when the IPsec module is defined in the \fBmodule\-config:\fR must be present when the IPsec module is defined in the \fBmodule\-config:\fR
directive. directive.
.TP .TP
.B ipsecmod-strict: \fI<yes or no>\fR .B ipsecmod-strict: \fI<yes or no>\fR
If enabled unbound requires the external hook to return a success value of 0. If enabled Unbound requires the external hook to return a success value of 0.
Failing to do so unbound will reply with SERVFAIL. The A/AAAA answer will also Failing to do so Unbound will reply with SERVFAIL. The A/AAAA answer will also
not be cached. Defaults to no. not be cached. Defaults to no.
.TP .TP
.B ipsecmod\-max-ttl: \fI<seconds>\fR .B ipsecmod\-max-ttl: \fI<seconds>\fR
@ -2330,7 +2362,7 @@ Time to live maximum for A/AAAA cached records after calling the external hook.
Defaults to 3600. Defaults to 3600.
.TP .TP
.B ipsecmod-ignore-bogus: \fI<yes or no>\fR .B ipsecmod-ignore-bogus: \fI<yes or no>\fR
Specifies the behaviour of unbound when the IPSECKEY answer is bogus. If set Specifies the behaviour of Unbound when the IPSECKEY answer is bogus. If set
to yes, the hook will be called and the A/AAAA answer will be returned to the to yes, the hook will be called and the A/AAAA answer will be returned to the
client. If set to no, the hook will not be called and the answer to the client. If set to no, the hook will not be called and the answer to the
A/AAAA query will be SERVFAIL. Mainly used for testing. Defaults to no. A/AAAA query will be SERVFAIL. Mainly used for testing. Defaults to no.
@ -2357,7 +2389,7 @@ If Unbound cannot even find an answer in the backend, it resolves the
query as usual, and stores the answer in the backend. query as usual, and stores the answer in the backend.
.P .P
This module interacts with the \fBserve\-expired\-*\fR options and will reply This module interacts with the \fBserve\-expired\-*\fR options and will reply
with expired data if unbound is configured for that. Currently the use with expired data if Unbound is configured for that. Currently the use
of \fBserve\-expired\-client\-timeout:\fR and of \fBserve\-expired\-client\-timeout:\fR and
\fBserve\-expired\-reply\-ttl:\fR is not consistent for data originating from \fBserve\-expired\-reply\-ttl:\fR is not consistent for data originating from
the external cache as these will result in a reply with 0 TTL without trying to the external cache as these will result in a reply with 0 TTL without trying to
@ -2436,16 +2468,17 @@ re-establish a new connection later.
This option defaults to 100 milliseconds. This option defaults to 100 milliseconds.
.TP .TP
.B redis-expire-records: \fI<yes or no> .B redis-expire-records: \fI<yes or no>
If Redis record expiration is enabled. If yes, unbound sets timeout for Redis If Redis record expiration is enabled. If yes, Unbound sets timeout for Redis
records so that Redis can evict keys that have expired automatically. If records so that Redis can evict keys that have expired automatically. If
unbound is configured with \fBserve-expired\fR and \fBserve-expired-ttl\fR is 0, Unbound is configured with \fBserve-expired\fR and \fBserve-expired-ttl\fR is 0,
this option is internally reverted to "no". Redis SETEX support is required this option is internally reverted to "no". Redis SETEX support is required
for this option (Redis >= 2.0.0). for this option (Redis >= 2.0.0).
This option defaults to no. This option defaults to no.
.SS DNSTAP Logging Options .SS DNSTAP Logging Options
DNSTAP support, when compiled in, is enabled in the \fBdnstap:\fR section. DNSTAP support, when compiled in by using \fB\-\-enable\-dnstap\fR, is enabled
in the \fBdnstap:\fR section.
This starts an extra thread (when compiled with threading) that writes This starts an extra thread (when compiled with threading) that writes
the log information to the destination. If unbound is compiled without the log information to the destination. If Unbound is compiled without
threading it does not spawn a thread, but connects per-process to the threading it does not spawn a thread, but connects per-process to the
destination. destination.
.TP .TP
@ -2503,19 +2536,19 @@ Default is "".
.TP .TP
.B dnstap-log-resolver-query-messages: \fI<yes or no> .B dnstap-log-resolver-query-messages: \fI<yes or no>
Enable to log resolver query messages. Default is no. Enable to log resolver query messages. Default is no.
These are messages from unbound to upstream servers. These are messages from Unbound to upstream servers.
.TP .TP
.B dnstap-log-resolver-response-messages: \fI<yes or no> .B dnstap-log-resolver-response-messages: \fI<yes or no>
Enable to log resolver response messages. Default is no. Enable to log resolver response messages. Default is no.
These are replies from upstream servers to unbound. These are replies from upstream servers to Unbound.
.TP .TP
.B dnstap-log-client-query-messages: \fI<yes or no> .B dnstap-log-client-query-messages: \fI<yes or no>
Enable to log client query messages. Default is no. Enable to log client query messages. Default is no.
These are client queries to unbound. These are client queries to Unbound.
.TP .TP
.B dnstap-log-client-response-messages: \fI<yes or no> .B dnstap-log-client-response-messages: \fI<yes or no>
Enable to log client response messages. Default is no. Enable to log client response messages. Default is no.
These are responses from unbound to clients. These are responses from Unbound to clients.
.TP .TP
.B dnstap-log-forwarder-query-messages: \fI<yes or no> .B dnstap-log-forwarder-query-messages: \fI<yes or no>
Enable to log forwarder query messages. Default is no. Enable to log forwarder query messages. Default is no.
@ -2614,7 +2647,7 @@ allowed notify by default.
.TP .TP
.B zonefile: \fI<filename> .B zonefile: \fI<filename>
The filename where the zone is stored. If not given then no zonefile is used. The filename where the zone is stored. If not given then no zonefile is used.
If the file does not exist or is empty, unbound will attempt to fetch zone If the file does not exist or is empty, Unbound will attempt to fetch zone
data (eg. from the primary servers). data (eg. from the primary servers).
.TP .TP
.B rpz\-action\-override: \fI<action> .B rpz\-action\-override: \fI<action>
@ -2631,6 +2664,17 @@ Log all applied RPZ actions for this RPZ zone. Default is no.
.B rpz\-log\-name: \fI<name> .B rpz\-log\-name: \fI<name>
Specify a string to be part of the log line, for easy referencing. Specify a string to be part of the log line, for easy referencing.
.TP .TP
.B rpz\-signal\-nxdomain\-ra: \fI<yes or no>
Signal when a query is blocked by the RPZ with NXDOMAIN with an unset RA flag.
This allows certain clients, like dnsmasq, to infer that the domain is
externally blocked. Default is no.
.TP
.B for\-downstream: \fI<yes or no>
If enabled the zone is authoritatively answered for and queries for the RPZ
zone information are answered to downstream clients. This is useful for
monitoring scripts, that can then access the SOA information to check if
the rpz information is up to date. Default is no.
.TP
.B tags: \fI<list of tags> .B tags: \fI<list of tags>
Limit the policies from this RPZ clause to clients with a matching tag. Tags Limit the policies from this RPZ clause to clients with a matching tag. Tags
need to be defined in \fBdefine\-tag\fR and can be assigned to client addresses need to be defined in \fBdefine\-tag\fR and can be assigned to client addresses
@ -2671,7 +2715,7 @@ server:
.SH "FILES" .SH "FILES"
.TP .TP
.I @UNBOUND_RUN_DIR@ .I @UNBOUND_RUN_DIR@
default unbound working directory. default Unbound working directory.
.TP .TP
.I @UNBOUND_CHROOT_DIR@ .I @UNBOUND_CHROOT_DIR@
default default
@ -2679,13 +2723,13 @@ default
location. location.
.TP .TP
.I @ub_conf_file@ .I @ub_conf_file@
unbound configuration file. Unbound configuration file.
.TP .TP
.I @UNBOUND_PIDFILE@ .I @UNBOUND_PIDFILE@
default unbound pidfile with process ID of the running daemon. default Unbound pidfile with process ID of the running daemon.
.TP .TP
.I unbound.log .I unbound.log
unbound log file. default is to log to Unbound log file. default is to log to
\fIsyslog\fR(3). \fIsyslog\fR(3).
.SH "SEE ALSO" .SH "SEE ALSO"
\fIunbound\fR(8), \fIunbound\fR(8),

View File

@ -75,7 +75,8 @@ struct delegpt* delegpt_copy(struct delegpt* dp, struct regional* region)
copy->ssl_upstream = dp->ssl_upstream; copy->ssl_upstream = dp->ssl_upstream;
copy->tcp_upstream = dp->tcp_upstream; copy->tcp_upstream = dp->tcp_upstream;
for(ns = dp->nslist; ns; ns = ns->next) { for(ns = dp->nslist; ns; ns = ns->next) {
if(!delegpt_add_ns(copy, region, ns->name, ns->lame)) if(!delegpt_add_ns(copy, region, ns->name, ns->lame,
ns->tls_auth_name, ns->port))
return NULL; return NULL;
copy->nslist->resolved = ns->resolved; copy->nslist->resolved = ns->resolved;
copy->nslist->got4 = ns->got4; copy->nslist->got4 = ns->got4;
@ -85,7 +86,7 @@ struct delegpt* delegpt_copy(struct delegpt* dp, struct regional* region)
} }
for(a = dp->target_list; a; a = a->next_target) { for(a = dp->target_list; a; a = a->next_target) {
if(!delegpt_add_addr(copy, region, &a->addr, a->addrlen, if(!delegpt_add_addr(copy, region, &a->addr, a->addrlen,
a->bogus, a->lame, a->tls_auth_name, NULL)) a->bogus, a->lame, a->tls_auth_name, -1, NULL))
return NULL; return NULL;
} }
return copy; return copy;
@ -102,7 +103,7 @@ delegpt_set_name(struct delegpt* dp, struct regional* region, uint8_t* name)
int int
delegpt_add_ns(struct delegpt* dp, struct regional* region, uint8_t* name, delegpt_add_ns(struct delegpt* dp, struct regional* region, uint8_t* name,
uint8_t lame) uint8_t lame, char* tls_auth_name, int port)
{ {
struct delegpt_ns* ns; struct delegpt_ns* ns;
size_t len; size_t len;
@ -126,6 +127,14 @@ delegpt_add_ns(struct delegpt* dp, struct regional* region, uint8_t* name,
ns->lame = lame; ns->lame = lame;
ns->done_pside4 = 0; ns->done_pside4 = 0;
ns->done_pside6 = 0; ns->done_pside6 = 0;
ns->port = port;
if(tls_auth_name) {
ns->tls_auth_name = regional_strdup(region, tls_auth_name);
if(!ns->tls_auth_name)
return 0;
} else {
ns->tls_auth_name = NULL;
}
return ns->name != 0; return ns->name != 0;
} }
@ -177,17 +186,22 @@ delegpt_add_target(struct delegpt* dp, struct regional* region,
if(ns->got4 && ns->got6) if(ns->got4 && ns->got6)
ns->resolved = 1; ns->resolved = 1;
} }
return delegpt_add_addr(dp, region, addr, addrlen, bogus, lame, NULL, log_assert(ns->port>0);
additions); return delegpt_add_addr(dp, region, addr, addrlen, bogus, lame,
ns->tls_auth_name, ns->port, additions);
} }
int int
delegpt_add_addr(struct delegpt* dp, struct regional* region, delegpt_add_addr(struct delegpt* dp, struct regional* region,
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t bogus, struct sockaddr_storage* addr, socklen_t addrlen, uint8_t bogus,
uint8_t lame, char* tls_auth_name, int* additions) uint8_t lame, char* tls_auth_name, int port, int* additions)
{ {
struct delegpt_addr* a; struct delegpt_addr* a;
log_assert(!dp->dp_type_mlc); log_assert(!dp->dp_type_mlc);
if(port != -1) {
log_assert(port>0);
sockaddr_store_port(addr, addrlen, port);
}
/* check for duplicates */ /* check for duplicates */
if((a = delegpt_find_addr(dp, addr, addrlen))) { if((a = delegpt_find_addr(dp, addr, addrlen))) {
if(bogus) if(bogus)
@ -412,7 +426,8 @@ delegpt_rrset_add_ns(struct delegpt* dp, struct regional* region,
(size_t)sldns_read_uint16(nsdata->rr_data[i])) (size_t)sldns_read_uint16(nsdata->rr_data[i]))
continue; /* bad format */ continue; /* bad format */
/* add rdata of NS (= wirefmt dname), skip rdatalen bytes */ /* add rdata of NS (= wirefmt dname), skip rdatalen bytes */
if(!delegpt_add_ns(dp, region, nsdata->rr_data[i]+2, lame)) if(!delegpt_add_ns(dp, region, nsdata->rr_data[i]+2, lame,
NULL, UNBOUND_DNS_PORT))
return 0; return 0;
} }
return 1; return 1;
@ -429,7 +444,6 @@ delegpt_add_rrset_A(struct delegpt* dp, struct regional* region,
log_assert(!dp->dp_type_mlc); log_assert(!dp->dp_type_mlc);
memset(&sa, 0, len); memset(&sa, 0, len);
sa.sin_family = AF_INET; sa.sin_family = AF_INET;
sa.sin_port = (in_port_t)htons(UNBOUND_DNS_PORT);
for(i=0; i<d->count; i++) { for(i=0; i<d->count; i++) {
if(d->rr_len[i] != 2 + INET_SIZE) if(d->rr_len[i] != 2 + INET_SIZE)
continue; continue;
@ -453,7 +467,6 @@ delegpt_add_rrset_AAAA(struct delegpt* dp, struct regional* region,
log_assert(!dp->dp_type_mlc); log_assert(!dp->dp_type_mlc);
memset(&sa, 0, len); memset(&sa, 0, len);
sa.sin6_family = AF_INET6; sa.sin6_family = AF_INET6;
sa.sin6_port = (in_port_t)htons(UNBOUND_DNS_PORT);
for(i=0; i<d->count; i++) { for(i=0; i<d->count; i++) {
if(d->rr_len[i] != 2 + INET6_SIZE) /* rdatalen + len of IP6 */ if(d->rr_len[i] != 2 + INET6_SIZE) /* rdatalen + len of IP6 */
continue; continue;
@ -555,6 +568,7 @@ void delegpt_free_mlc(struct delegpt* dp)
while(n) { while(n) {
nn = n->next; nn = n->next;
free(n->name); free(n->name);
free(n->tls_auth_name);
free(n); free(n);
n = nn; n = nn;
} }
@ -577,7 +591,8 @@ int delegpt_set_name_mlc(struct delegpt* dp, uint8_t* name)
return (dp->name != NULL); return (dp->name != NULL);
} }
int delegpt_add_ns_mlc(struct delegpt* dp, uint8_t* name, uint8_t lame) int delegpt_add_ns_mlc(struct delegpt* dp, uint8_t* name, uint8_t lame,
char* tls_auth_name, int port)
{ {
struct delegpt_ns* ns; struct delegpt_ns* ns;
size_t len; size_t len;
@ -604,14 +619,30 @@ int delegpt_add_ns_mlc(struct delegpt* dp, uint8_t* name, uint8_t lame)
ns->lame = (uint8_t)lame; ns->lame = (uint8_t)lame;
ns->done_pside4 = 0; ns->done_pside4 = 0;
ns->done_pside6 = 0; ns->done_pside6 = 0;
ns->port = port;
if(tls_auth_name) {
ns->tls_auth_name = strdup(tls_auth_name);
if(!ns->tls_auth_name) {
free(ns->name);
free(ns);
return 0;
}
} else {
ns->tls_auth_name = NULL;
}
return 1; return 1;
} }
int delegpt_add_addr_mlc(struct delegpt* dp, struct sockaddr_storage* addr, int delegpt_add_addr_mlc(struct delegpt* dp, struct sockaddr_storage* addr,
socklen_t addrlen, uint8_t bogus, uint8_t lame, char* tls_auth_name) socklen_t addrlen, uint8_t bogus, uint8_t lame, char* tls_auth_name,
int port)
{ {
struct delegpt_addr* a; struct delegpt_addr* a;
log_assert(dp->dp_type_mlc); log_assert(dp->dp_type_mlc);
if(port != -1) {
log_assert(port>0);
sockaddr_store_port(addr, addrlen, port);
}
/* check for duplicates */ /* check for duplicates */
if((a = delegpt_find_addr(dp, addr, addrlen))) { if((a = delegpt_find_addr(dp, addr, addrlen))) {
if(bogus) if(bogus)
@ -664,7 +695,9 @@ int delegpt_add_target_mlc(struct delegpt* dp, uint8_t* name, size_t namelen,
if(ns->got4 && ns->got6) if(ns->got4 && ns->got6)
ns->resolved = 1; ns->resolved = 1;
} }
return delegpt_add_addr_mlc(dp, addr, addrlen, bogus, lame, NULL); log_assert(ns->port>0);
return delegpt_add_addr_mlc(dp, addr, addrlen, bogus, lame,
ns->tls_auth_name, ns->port);
} }
size_t delegpt_get_mem(struct delegpt* dp) size_t delegpt_get_mem(struct delegpt* dp)

View File

@ -126,6 +126,11 @@ struct delegpt_ns {
* Also enabled if a parent-side cache entry exists, or a parent-side * Also enabled if a parent-side cache entry exists, or a parent-side
* negative-cache entry exists. */ * negative-cache entry exists. */
uint8_t done_pside6; uint8_t done_pside6;
/** the TLS authentication name, (if not NULL) to use. */
char* tls_auth_name;
/** the port to use; it should mosty be the default 53 but configured
* upstreams can provide nondefault ports. */
int port;
}; };
/** /**
@ -191,10 +196,12 @@ int delegpt_set_name(struct delegpt* dp, struct regional* regional,
* @param regional: where to allocate the info. * @param regional: where to allocate the info.
* @param name: domain name in wire format. * @param name: domain name in wire format.
* @param lame: name is lame, disprefer it. * @param lame: name is lame, disprefer it.
* @param tls_auth_name: TLS authentication name (or NULL).
* @param port: port to use for resolved addresses.
* @return false on error. * @return false on error.
*/ */
int delegpt_add_ns(struct delegpt* dp, struct regional* regional, int delegpt_add_ns(struct delegpt* dp, struct regional* regional,
uint8_t* name, uint8_t lame); uint8_t* name, uint8_t lame, char* tls_auth_name, int port);
/** /**
* Add NS rrset; calls add_ns repeatedly. * Add NS rrset; calls add_ns repeatedly.
@ -271,12 +278,14 @@ int delegpt_add_rrset(struct delegpt* dp, struct regional* regional,
* @param bogus: if address is bogus. * @param bogus: if address is bogus.
* @param lame: if address is lame. * @param lame: if address is lame.
* @param tls_auth_name: TLS authentication name (or NULL). * @param tls_auth_name: TLS authentication name (or NULL).
* @param port: the port to use; if -1 the port is taken from addr.
* @param additions: will be set to 1 if a new address is added * @param additions: will be set to 1 if a new address is added
* @return false on error. * @return false on error.
*/ */
int delegpt_add_addr(struct delegpt* dp, struct regional* regional, int delegpt_add_addr(struct delegpt* dp, struct regional* regional,
struct sockaddr_storage* addr, socklen_t addrlen, struct sockaddr_storage* addr, socklen_t addrlen,
uint8_t bogus, uint8_t lame, char* tls_auth_name, int* additions); uint8_t bogus, uint8_t lame, char* tls_auth_name, int port,
int* additions);
/** /**
* Find NS record in name list of delegation point. * Find NS record in name list of delegation point.
@ -404,9 +413,12 @@ int delegpt_set_name_mlc(struct delegpt* dp, uint8_t* name);
* @param dp: must have been created with delegpt_create_mlc. * @param dp: must have been created with delegpt_create_mlc.
* @param name: the name to add. * @param name: the name to add.
* @param lame: the name is lame, disprefer. * @param lame: the name is lame, disprefer.
* @param tls_auth_name: TLS authentication name (or NULL).
* @param port: port to use for resolved addresses.
* @return false on error. * @return false on error.
*/ */
int delegpt_add_ns_mlc(struct delegpt* dp, uint8_t* name, uint8_t lame); int delegpt_add_ns_mlc(struct delegpt* dp, uint8_t* name, uint8_t lame,
char* tls_auth_name, int port);
/** /**
* add an address to a malloced delegation point. * add an address to a malloced delegation point.
@ -416,10 +428,12 @@ int delegpt_add_ns_mlc(struct delegpt* dp, uint8_t* name, uint8_t lame);
* @param bogus: if address is bogus. * @param bogus: if address is bogus.
* @param lame: if address is lame. * @param lame: if address is lame.
* @param tls_auth_name: TLS authentication name (or NULL). * @param tls_auth_name: TLS authentication name (or NULL).
* @param port: the port to use; if -1 the port is taken from addr.
* @return false on error. * @return false on error.
*/ */
int delegpt_add_addr_mlc(struct delegpt* dp, struct sockaddr_storage* addr, int delegpt_add_addr_mlc(struct delegpt* dp, struct sockaddr_storage* addr,
socklen_t addrlen, uint8_t bogus, uint8_t lame, char* tls_auth_name); socklen_t addrlen, uint8_t bogus, uint8_t lame, char* tls_auth_name,
int port);
/** /**
* Add target address to the delegation point. * Add target address to the delegation point.

View File

@ -205,16 +205,22 @@ read_fwds_host(struct config_stub* s, struct delegpt* dp)
{ {
struct config_strlist* p; struct config_strlist* p;
uint8_t* dname; uint8_t* dname;
size_t dname_len; char* tls_auth_name;
int port;
for(p = s->hosts; p; p = p->next) { for(p = s->hosts; p; p = p->next) {
log_assert(p->str); log_assert(p->str);
dname = sldns_str2wire_dname(p->str, &dname_len); dname = authextstrtodname(p->str, &port, &tls_auth_name);
if(!dname) { if(!dname) {
log_err("cannot parse forward %s server name: '%s'", log_err("cannot parse forward %s server name: '%s'",
s->name, p->str); s->name, p->str);
return 0; return 0;
} }
if(!delegpt_add_ns_mlc(dp, dname, 0)) { #if ! defined(HAVE_SSL_SET1_HOST) && ! defined(HAVE_X509_VERIFY_PARAM_SET1_HOST)
if(tls_auth_name)
log_err("no name verification functionality in "
"ssl library, ignored name for %s", p->str);
#endif
if(!delegpt_add_ns_mlc(dp, dname, 0, tls_auth_name, port)) {
free(dname); free(dname);
log_err("out of memory"); log_err("out of memory");
return 0; return 0;
@ -245,7 +251,7 @@ read_fwds_addr(struct config_stub* s, struct delegpt* dp)
"ssl library, ignored name for %s", p->str); "ssl library, ignored name for %s", p->str);
#endif #endif
if(!delegpt_add_addr_mlc(dp, &addr, addrlen, 0, 0, if(!delegpt_add_addr_mlc(dp, &addr, addrlen, 0, 0,
tls_auth_name)) { tls_auth_name, -1)) {
log_err("out of memory"); log_err("out of memory");
return 0; return 0;
} }

View File

@ -99,7 +99,7 @@ ah(struct delegpt* dp, const char* sv, const char* ip)
log_err("could not parse %s", sv); log_err("could not parse %s", sv);
return 0; return 0;
} }
if(!delegpt_add_ns_mlc(dp, dname, 0) || if(!delegpt_add_ns_mlc(dp, dname, 0, NULL, UNBOUND_DNS_PORT) ||
!extstrtoaddr(ip, &addr, &addrlen) || !extstrtoaddr(ip, &addr, &addrlen) ||
!delegpt_add_target_mlc(dp, dname, dname_len, !delegpt_add_target_mlc(dp, dname, dname_len,
&addr, addrlen, 0, 0)) { &addr, addrlen, 0, 0)) {
@ -217,17 +217,23 @@ static int
read_stubs_host(struct config_stub* s, struct delegpt* dp) read_stubs_host(struct config_stub* s, struct delegpt* dp)
{ {
struct config_strlist* p; struct config_strlist* p;
size_t dname_len;
uint8_t* dname; uint8_t* dname;
char* tls_auth_name;
int port;
for(p = s->hosts; p; p = p->next) { for(p = s->hosts; p; p = p->next) {
log_assert(p->str); log_assert(p->str);
dname = sldns_str2wire_dname(p->str, &dname_len); dname = authextstrtodname(p->str, &port, &tls_auth_name);
if(!dname) { if(!dname) {
log_err("cannot parse stub %s nameserver name: '%s'", log_err("cannot parse stub %s nameserver name: '%s'",
s->name, p->str); s->name, p->str);
return 0; return 0;
} }
if(!delegpt_add_ns_mlc(dp, dname, 0)) { #if ! defined(HAVE_SSL_SET1_HOST) && ! defined(HAVE_X509_VERIFY_PARAM_SET1_HOST)
if(tls_auth_name)
log_err("no name verification functionality in "
"ssl library, ignored name for %s", p->str);
#endif
if(!delegpt_add_ns_mlc(dp, dname, 0, tls_auth_name, port)) {
free(dname); free(dname);
log_err("out of memory"); log_err("out of memory");
return 0; return 0;
@ -258,7 +264,7 @@ read_stubs_addr(struct config_stub* s, struct delegpt* dp)
"ssl library, ignored name for %s", p->str); "ssl library, ignored name for %s", p->str);
#endif #endif
if(!delegpt_add_addr_mlc(dp, &addr, addrlen, 0, 0, if(!delegpt_add_addr_mlc(dp, &addr, addrlen, 0, 0,
auth_name)) { auth_name, -1)) {
log_err("out of memory"); log_err("out of memory");
return 0; return 0;
} }
@ -338,7 +344,7 @@ read_root_hints(struct iter_hints* hints, char* fname)
if(sldns_wirerr_get_type(rr, rr_len, dname_len) if(sldns_wirerr_get_type(rr, rr_len, dname_len)
== LDNS_RR_TYPE_NS) { == LDNS_RR_TYPE_NS) {
if(!delegpt_add_ns_mlc(dp, sldns_wirerr_get_rdata(rr, if(!delegpt_add_ns_mlc(dp, sldns_wirerr_get_rdata(rr,
rr_len, dname_len), 0)) { rr_len, dname_len), 0, NULL, UNBOUND_DNS_PORT)) {
log_err("out of memory reading root hints"); log_err("out of memory reading root hints");
goto stop_read; goto stop_read;
} }

View File

@ -1533,36 +1533,6 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
if(!iq->ratelimit_ok && qstate->prefetch_leeway) if(!iq->ratelimit_ok && qstate->prefetch_leeway)
iq->ratelimit_ok = 1; /* allow prefetches, this keeps iq->ratelimit_ok = 1; /* allow prefetches, this keeps
otherwise valid data in the cache */ otherwise valid data in the cache */
if(!iq->ratelimit_ok && infra_ratelimit_exceeded(
qstate->env->infra_cache, iq->dp->name,
iq->dp->namelen, *qstate->env->now)) {
/* and increment the rate, so that the rate for time
* now will also exceed the rate, keeping cache fresh */
(void)infra_ratelimit_inc(qstate->env->infra_cache,
iq->dp->name, iq->dp->namelen,
*qstate->env->now, &qstate->qinfo,
qstate->reply);
/* see if we are passed through with slip factor */
if(qstate->env->cfg->ratelimit_factor != 0 &&
ub_random_max(qstate->env->rnd,
qstate->env->cfg->ratelimit_factor) == 1) {
iq->ratelimit_ok = 1;
log_nametypeclass(VERB_ALGO, "ratelimit allowed through for "
"delegation point", iq->dp->name,
LDNS_RR_TYPE_NS, LDNS_RR_CLASS_IN);
} else {
lock_basic_lock(&ie->queries_ratelimit_lock);
ie->num_queries_ratelimited++;
lock_basic_unlock(&ie->queries_ratelimit_lock);
log_nametypeclass(VERB_ALGO, "ratelimit exceeded with "
"delegation point", iq->dp->name,
LDNS_RR_TYPE_NS, LDNS_RR_CLASS_IN);
qstate->was_ratelimited = 1;
errinf(qstate, "query was ratelimited");
errinf_dname(qstate, "for zone", iq->dp->name);
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
}
/* see if this dp not useless. /* see if this dp not useless.
* It is useless if: * It is useless if:
@ -1988,12 +1958,13 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
iq->chase_flags &= ~BIT_RD; /* go to authorities */ iq->chase_flags &= ~BIT_RD; /* go to authorities */
for(ns = p->nslist; ns; ns=ns->next) { for(ns = p->nslist; ns; ns=ns->next) {
(void)delegpt_add_ns(iq->dp, qstate->region, (void)delegpt_add_ns(iq->dp, qstate->region,
ns->name, ns->lame); ns->name, ns->lame, ns->tls_auth_name,
ns->port);
} }
for(a = p->target_list; a; a=a->next_target) { for(a = p->target_list; a; a=a->next_target) {
(void)delegpt_add_addr(iq->dp, qstate->region, (void)delegpt_add_addr(iq->dp, qstate->region,
&a->addr, a->addrlen, a->bogus, &a->addr, a->addrlen, a->bogus,
a->lame, a->tls_auth_name, NULL); a->lame, a->tls_auth_name, -1, NULL);
} }
} }
iq->dp->has_parent_side_NS = 1; iq->dp->has_parent_side_NS = 1;
@ -2211,6 +2182,8 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
int auth_fallback = 0; int auth_fallback = 0;
uint8_t* qout_orig = NULL; uint8_t* qout_orig = NULL;
size_t qout_orig_len = 0; size_t qout_orig_len = 0;
int sq_check_ratelimit = 1;
int sq_was_ratelimited = 0;
/* NOTE: a request will encounter this state for each target it /* NOTE: a request will encounter this state for each target it
* needs to send a query to. That is, at least one per referral, * needs to send a query to. That is, at least one per referral,
@ -2534,7 +2507,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
struct dns_msg* forged_response = rpz_callback_from_iterator_module(qstate, iq); struct dns_msg* forged_response = rpz_callback_from_iterator_module(qstate, iq);
if(forged_response != NULL) { if(forged_response != NULL) {
qstate->ext_state[id] = module_finished; qstate->ext_state[id] = module_finished;
qstate->return_rcode = FLAGS_GET_RCODE(forged_response->rep->flags); qstate->return_rcode = LDNS_RCODE_NOERROR;
qstate->return_msg = forged_response; qstate->return_msg = forged_response;
iq->response = forged_response; iq->response = forged_response;
next_state(iq, FINISHED_STATE); next_state(iq, FINISHED_STATE);
@ -2646,22 +2619,9 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
return 0; return 0;
} }
/* if not forwarding, check ratelimits per delegationpoint name */ /* Do not check ratelimit for forwarding queries or if we already got a
if(!(iq->chase_flags & BIT_RD) && !iq->ratelimit_ok) { * pass. */
if(!infra_ratelimit_inc(qstate->env->infra_cache, iq->dp->name, sq_check_ratelimit = (!(iq->chase_flags & BIT_RD) && !iq->ratelimit_ok);
iq->dp->namelen, *qstate->env->now, &qstate->qinfo,
qstate->reply)) {
lock_basic_lock(&ie->queries_ratelimit_lock);
ie->num_queries_ratelimited++;
lock_basic_unlock(&ie->queries_ratelimit_lock);
verbose(VERB_ALGO, "query exceeded ratelimits");
qstate->was_ratelimited = 1;
errinf_dname(qstate, "exceeded ratelimit for zone",
iq->dp->name);
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
}
/* We have a valid target. */ /* We have a valid target. */
if(verbosity >= VERB_QUERY) { if(verbosity >= VERB_QUERY) {
log_query_info(VERB_QUERY, "sending query:", &iq->qinfo_out); log_query_info(VERB_QUERY, "sending query:", &iq->qinfo_out);
@ -2681,17 +2641,24 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
!qstate->blacklist&&(!iter_qname_indicates_dnssec(qstate->env, !qstate->blacklist&&(!iter_qname_indicates_dnssec(qstate->env,
&iq->qinfo_out)||target->attempts==1)?0:BIT_CD), &iq->qinfo_out)||target->attempts==1)?0:BIT_CD),
iq->dnssec_expected, iq->caps_fallback || is_caps_whitelisted( iq->dnssec_expected, iq->caps_fallback || is_caps_whitelisted(
ie, iq), &target->addr, target->addrlen, ie, iq), sq_check_ratelimit, &target->addr, target->addrlen,
iq->dp->name, iq->dp->namelen, iq->dp->name, iq->dp->namelen,
(iq->dp->tcp_upstream || qstate->env->cfg->tcp_upstream), (iq->dp->tcp_upstream || qstate->env->cfg->tcp_upstream),
(iq->dp->ssl_upstream || qstate->env->cfg->ssl_upstream), (iq->dp->ssl_upstream || qstate->env->cfg->ssl_upstream),
target->tls_auth_name, qstate); target->tls_auth_name, qstate, &sq_was_ratelimited);
if(!outq) { if(!outq) {
if(sq_was_ratelimited) {
lock_basic_lock(&ie->queries_ratelimit_lock);
ie->num_queries_ratelimited++;
lock_basic_unlock(&ie->queries_ratelimit_lock);
verbose(VERB_ALGO, "query exceeded ratelimits");
qstate->was_ratelimited = 1;
errinf_dname(qstate, "exceeded ratelimit for zone",
iq->dp->name);
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
log_addr(VERB_QUERY, "error sending query to auth server", log_addr(VERB_QUERY, "error sending query to auth server",
&target->addr, target->addrlen); &target->addr, target->addrlen);
if(!(iq->chase_flags & BIT_RD) && !iq->ratelimit_ok)
infra_ratelimit_dec(qstate->env->infra_cache, iq->dp->name,
iq->dp->namelen, *qstate->env->now);
if(qstate->env->cfg->qname_minimisation) if(qstate->env->cfg->qname_minimisation)
iq->minimisation_state = SKIP_MINIMISE_STATE; iq->minimisation_state = SKIP_MINIMISE_STATE;
return next_state(iq, QUERYTARGETS_STATE); return next_state(iq, QUERYTARGETS_STATE);
@ -2935,14 +2902,6 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
* delegation point, and back to the QUERYTARGETS_STATE. */ * delegation point, and back to the QUERYTARGETS_STATE. */
verbose(VERB_DETAIL, "query response was REFERRAL"); verbose(VERB_DETAIL, "query response was REFERRAL");
if(!(iq->chase_flags & BIT_RD) && !iq->ratelimit_ok) {
/* we have a referral, no ratelimit, we can send
* our queries to the given name */
infra_ratelimit_dec(qstate->env->infra_cache,
iq->dp->name, iq->dp->namelen,
*qstate->env->now);
}
/* if hardened, only store referral if we asked for it */ /* if hardened, only store referral if we asked for it */
if(!qstate->no_cache_store && if(!qstate->no_cache_store &&
(!qstate->env->cfg->harden_referral_path || (!qstate->env->cfg->harden_referral_path ||
@ -3103,7 +3062,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
} }
if(forged_response != NULL) { if(forged_response != NULL) {
qstate->ext_state[id] = module_finished; qstate->ext_state[id] = module_finished;
qstate->return_rcode = FLAGS_GET_RCODE(forged_response->rep->flags); qstate->return_rcode = LDNS_RCODE_NOERROR;
qstate->return_msg = forged_response; qstate->return_msg = forged_response;
iq->response = forged_response; iq->response = forged_response;
next_state(iq, FINISHED_STATE); next_state(iq, FINISHED_STATE);
@ -3398,7 +3357,8 @@ processTargetResponse(struct module_qstate* qstate, int id,
rrset->rk.dname_len)) { rrset->rk.dname_len)) {
/* if dpns->lame then set newcname ns lame too */ /* if dpns->lame then set newcname ns lame too */
if(!delegpt_add_ns(foriq->dp, forq->region, if(!delegpt_add_ns(foriq->dp, forq->region,
rrset->rk.dname, dpns->lame)) rrset->rk.dname, dpns->lame, dpns->tls_auth_name,
dpns->port))
log_err("out of memory adding cnamed-ns"); log_err("out of memory adding cnamed-ns");
} }
/* if dpns->lame then set the address(es) lame too */ /* if dpns->lame then set the address(es) lame too */

View File

@ -80,7 +80,7 @@ struct rbtree_type;
/** /**
* number of labels from QNAME that are always send individually when using * number of labels from QNAME that are always send individually when using
* QNAME minimisation, even when the number of labels of the QNAME is bigger * QNAME minimisation, even when the number of labels of the QNAME is bigger
* tham MAX_MINIMISE_COUNT */ * than MAX_MINIMISE_COUNT */
#define MINIMISE_ONE_LAB 4 #define MINIMISE_ONE_LAB 4
#define MINIMISE_MULTIPLE_LABS (MAX_MINIMISE_COUNT - MINIMISE_ONE_LAB) #define MINIMISE_MULTIPLE_LABS (MAX_MINIMISE_COUNT - MINIMISE_ONE_LAB)
/** at what query-sent-count to stop target fetch policy */ /** at what query-sent-count to stop target fetch policy */
@ -379,7 +379,7 @@ struct iter_qstate {
/** list of pending queries to authoritative servers. */ /** list of pending queries to authoritative servers. */
struct outbound_list outlist; struct outbound_list outlist;
/** QNAME minimisation state, RFC7816 */ /** QNAME minimisation state, RFC9156 */
enum minimisation_state minimisation_state; enum minimisation_state minimisation_state;
/** State for capsfail: QNAME minimisation state for comparisons. */ /** State for capsfail: QNAME minimisation state for comparisons. */

View File

@ -882,9 +882,10 @@ void libworker_alloc_cleanup(void* arg)
struct outbound_entry* libworker_send_query(struct query_info* qinfo, struct outbound_entry* libworker_send_query(struct query_info* qinfo,
uint16_t flags, int dnssec, int want_dnssec, int nocaps, uint16_t flags, int dnssec, int want_dnssec, int nocaps,
int check_ratelimit,
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone, struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
size_t zonelen, int tcp_upstream, int ssl_upstream, char* tls_auth_name, size_t zonelen, int tcp_upstream, int ssl_upstream, char* tls_auth_name,
struct module_qstate* q) struct module_qstate* q, int* was_ratelimited)
{ {
struct libworker* w = (struct libworker*)q->env->worker; struct libworker* w = (struct libworker*)q->env->worker;
struct outbound_entry* e = (struct outbound_entry*)regional_alloc( struct outbound_entry* e = (struct outbound_entry*)regional_alloc(
@ -893,9 +894,10 @@ struct outbound_entry* libworker_send_query(struct query_info* qinfo,
return NULL; return NULL;
e->qstate = q; e->qstate = q;
e->qsent = outnet_serviced_query(w->back, qinfo, flags, dnssec, e->qsent = outnet_serviced_query(w->back, qinfo, flags, dnssec,
want_dnssec, nocaps, tcp_upstream, ssl_upstream, want_dnssec, nocaps, check_ratelimit, tcp_upstream, ssl_upstream,
tls_auth_name, addr, addrlen, zone, zonelen, q, tls_auth_name, addr, addrlen, zone, zonelen, q,
libworker_handle_service_reply, e, w->back->udp_buff, q->env); libworker_handle_service_reply, e, w->back->udp_buff, q->env,
was_ratelimited);
if(!e->qsent) { if(!e->qsent) {
return NULL; return NULL;
} }
@ -976,10 +978,11 @@ void worker_sighandler(int ATTR_UNUSED(sig), void* ATTR_UNUSED(arg))
struct outbound_entry* worker_send_query(struct query_info* ATTR_UNUSED(qinfo), struct outbound_entry* worker_send_query(struct query_info* ATTR_UNUSED(qinfo),
uint16_t ATTR_UNUSED(flags), int ATTR_UNUSED(dnssec), uint16_t ATTR_UNUSED(flags), int ATTR_UNUSED(dnssec),
int ATTR_UNUSED(want_dnssec), int ATTR_UNUSED(nocaps), int ATTR_UNUSED(want_dnssec), int ATTR_UNUSED(nocaps),
int ATTR_UNUSED(check_ratelimit),
struct sockaddr_storage* ATTR_UNUSED(addr), socklen_t ATTR_UNUSED(addrlen), struct sockaddr_storage* ATTR_UNUSED(addr), socklen_t ATTR_UNUSED(addrlen),
uint8_t* ATTR_UNUSED(zone), size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(tcp_upstream), uint8_t* ATTR_UNUSED(zone), size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(tcp_upstream),
int ATTR_UNUSED(ssl_upstream), char* ATTR_UNUSED(tls_auth_name), int ATTR_UNUSED(ssl_upstream), char* ATTR_UNUSED(tls_auth_name),
struct module_qstate* ATTR_UNUSED(q)) struct module_qstate* ATTR_UNUSED(q), int* ATTR_UNUSED(was_ratelimited))
{ {
log_assert(0); log_assert(0);
return 0; return 0;

View File

@ -58,6 +58,7 @@ struct query_info;
* @param dnssec: if set, EDNS record will have DO bit set. * @param dnssec: if set, EDNS record will have DO bit set.
* @param want_dnssec: signatures needed. * @param want_dnssec: signatures needed.
* @param nocaps: ignore capsforid(if in config), do not perturb qname. * @param nocaps: ignore capsforid(if in config), do not perturb qname.
* @param check_ratelimit: if set, will check ratelimit before sending out.
* @param addr: where to. * @param addr: where to.
* @param addrlen: length of addr. * @param addrlen: length of addr.
* @param zone: delegation point name. * @param zone: delegation point name.
@ -67,14 +68,17 @@ struct query_info;
* @param tls_auth_name: if ssl_upstream, use this name with TLS * @param tls_auth_name: if ssl_upstream, use this name with TLS
* authentication. * authentication.
* @param q: which query state to reactivate upon return. * @param q: which query state to reactivate upon return.
* @param was_ratelimited: it will signal back if the query failed to pass the
* ratelimit check.
* @return: false on failure (memory or socket related). no query was * @return: false on failure (memory or socket related). no query was
* sent. * sent.
*/ */
struct outbound_entry* libworker_send_query(struct query_info* qinfo, struct outbound_entry* libworker_send_query(struct query_info* qinfo,
uint16_t flags, int dnssec, int want_dnssec, int nocaps, uint16_t flags, int dnssec, int want_dnssec, int nocaps,
int check_ratelimit,
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone, struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
size_t zonelen, int tcp_upstream, int ssl_upstream, char* tls_auth_name, size_t zonelen, int tcp_upstream, int ssl_upstream, char* tls_auth_name,
struct module_qstate* q); struct module_qstate* q, int* was_ratelimited);
/** process incoming serviced query replies from the network */ /** process incoming serviced query replies from the network */
int libworker_handle_service_reply(struct comm_point* c, void* arg, int error, int libworker_handle_service_reply(struct comm_point* c, void* arg, int error,
@ -110,6 +114,7 @@ void worker_sighandler(int sig, void* arg);
* @param dnssec: if set, EDNS record will have DO bit set. * @param dnssec: if set, EDNS record will have DO bit set.
* @param want_dnssec: signatures needed. * @param want_dnssec: signatures needed.
* @param nocaps: ignore capsforid(if in config), do not perturb qname. * @param nocaps: ignore capsforid(if in config), do not perturb qname.
* @param check_ratelimit: if set, will check ratelimit before sending out.
* @param addr: where to. * @param addr: where to.
* @param addrlen: length of addr. * @param addrlen: length of addr.
* @param zone: wireformat dname of the zone. * @param zone: wireformat dname of the zone.
@ -119,14 +124,17 @@ void worker_sighandler(int sig, void* arg);
* @param tls_auth_name: if ssl_upstream, use this name with TLS * @param tls_auth_name: if ssl_upstream, use this name with TLS
* authentication. * authentication.
* @param q: which query state to reactivate upon return. * @param q: which query state to reactivate upon return.
* @param was_ratelimited: it will signal back if the query failed to pass the
* ratelimit check.
* @return: false on failure (memory or socket related). no query was * @return: false on failure (memory or socket related). no query was
* sent. * sent.
*/ */
struct outbound_entry* worker_send_query(struct query_info* qinfo, struct outbound_entry* worker_send_query(struct query_info* qinfo,
uint16_t flags, int dnssec, int want_dnssec, int nocaps, uint16_t flags, int dnssec, int want_dnssec, int nocaps,
int check_ratelimit,
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone, struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone,
size_t zonelen, int tcp_upstream, int ssl_upstream, char* tls_auth_name, size_t zonelen, int tcp_upstream, int ssl_upstream, char* tls_auth_name,
struct module_qstate* q); struct module_qstate* q, int* was_ratelimited);
/** /**
* process control messages from the main thread. Frees the control * process control messages from the main thread. Frees the control

View File

@ -712,9 +712,10 @@ struct module_env {
/* --- services --- */ /* --- services --- */
struct outbound_entry* (*send_query)(struct query_info* qinfo, struct outbound_entry* (*send_query)(struct query_info* qinfo,
uint16_t flags, int dnssec, int want_dnssec, int nocaps, uint16_t flags, int dnssec, int want_dnssec, int nocaps,
int check_ratelimit,
struct sockaddr_storage* addr, socklen_t addrlen, struct sockaddr_storage* addr, socklen_t addrlen,
uint8_t* zone, size_t zonelen, int tcp_upstream, int ssl_upstream, uint8_t* zone, size_t zonelen, int tcp_upstream, int ssl_upstream,
char* tls_auth_name, struct module_qstate* q); char* tls_auth_name, struct module_qstate* q, int* was_ratelimited);
void (*detach_subs)(struct module_qstate* qstate); void (*detach_subs)(struct module_qstate* qstate);
int (*attach_sub)(struct module_qstate* qstate, int (*attach_sub)(struct module_qstate* qstate,
struct query_info* qinfo, uint16_t qflags, int prime, struct query_info* qinfo, uint16_t qflags, int prime,

View File

@ -898,8 +898,9 @@ static void infra_ip_create_ratedata(struct infra_cache* infra,
slabhash_insert(infra->client_ip_rates, h, &k->entry, d, NULL); slabhash_insert(infra->client_ip_rates, h, &k->entry, d, NULL);
} }
/** find the second and return its rate counter, if none, remove oldest */ /** Find the second and return its rate counter. If none and should_add, remove
static int* infra_rate_find_second(void* data, time_t t) * oldest to accommodate. Else return none. */
static int* infra_rate_find_second_or_none(void* data, time_t t, int should_add)
{ {
struct rate_data* d = (struct rate_data*)data; struct rate_data* d = (struct rate_data*)data;
int i, oldest; int i, oldest;
@ -907,6 +908,7 @@ static int* infra_rate_find_second(void* data, time_t t)
if(d->timestamp[i] == t) if(d->timestamp[i] == t)
return &(d->qps[i]); return &(d->qps[i]);
} }
if(!should_add) return NULL;
/* remove oldest timestamp, and insert it at t with 0 qps */ /* remove oldest timestamp, and insert it at t with 0 qps */
oldest = 0; oldest = 0;
for(i=0; i<RATE_WINDOW; i++) { for(i=0; i<RATE_WINDOW; i++) {
@ -918,21 +920,41 @@ static int* infra_rate_find_second(void* data, time_t t)
return &(d->qps[oldest]); return &(d->qps[oldest]);
} }
int infra_rate_max(void* data, time_t now) /** find the second and return its rate counter, if none, remove oldest to
* accommodate */
static int* infra_rate_give_second(void* data, time_t t)
{
return infra_rate_find_second_or_none(data, t, 1);
}
/** find the second and return its rate counter only if it exists. Caller
* should check for NULL return value */
static int* infra_rate_get_second(void* data, time_t t)
{
return infra_rate_find_second_or_none(data, t, 0);
}
int infra_rate_max(void* data, time_t now, int backoff)
{ {
struct rate_data* d = (struct rate_data*)data; struct rate_data* d = (struct rate_data*)data;
int i, max = 0; int i, max = 0;
for(i=0; i<RATE_WINDOW; i++) { for(i=0; i<RATE_WINDOW; i++) {
if(now-d->timestamp[i] <= RATE_WINDOW) { if(backoff) {
if(d->qps[i] > max) if(now-d->timestamp[i] <= RATE_WINDOW &&
d->qps[i] > max) {
max = d->qps[i]; max = d->qps[i];
}
} else {
if(now == d->timestamp[i]) {
return d->qps[i];
}
} }
} }
return max; return max;
} }
int infra_ratelimit_inc(struct infra_cache* infra, uint8_t* name, int infra_ratelimit_inc(struct infra_cache* infra, uint8_t* name,
size_t namelen, time_t timenow, struct query_info* qinfo, size_t namelen, time_t timenow, int backoff, struct query_info* qinfo,
struct comm_reply* replylist) struct comm_reply* replylist)
{ {
int lim, max; int lim, max;
@ -949,13 +971,13 @@ int infra_ratelimit_inc(struct infra_cache* infra, uint8_t* name,
/* find or insert ratedata */ /* find or insert ratedata */
entry = infra_find_ratedata(infra, name, namelen, 1); entry = infra_find_ratedata(infra, name, namelen, 1);
if(entry) { if(entry) {
int premax = infra_rate_max(entry->data, timenow); int premax = infra_rate_max(entry->data, timenow, backoff);
int* cur = infra_rate_find_second(entry->data, timenow); int* cur = infra_rate_give_second(entry->data, timenow);
(*cur)++; (*cur)++;
max = infra_rate_max(entry->data, timenow); max = infra_rate_max(entry->data, timenow, backoff);
lock_rw_unlock(&entry->lock); lock_rw_unlock(&entry->lock);
if(premax < lim && max >= lim) { if(premax <= lim && max > lim) {
char buf[257], qnm[257], ts[12], cs[12], ip[128]; char buf[257], qnm[257], ts[12], cs[12], ip[128];
dname_str(name, buf); dname_str(name, buf);
dname_str(qinfo->qname, qnm); dname_str(qinfo->qname, qnm);
@ -970,12 +992,12 @@ int infra_ratelimit_inc(struct infra_cache* infra, uint8_t* name,
verbose(VERB_OPS, "ratelimit exceeded %s %d query %s %s %s", buf, lim, qnm, cs, ts); verbose(VERB_OPS, "ratelimit exceeded %s %d query %s %s %s", buf, lim, qnm, cs, ts);
} }
} }
return (max < lim); return (max <= lim);
} }
/* create */ /* create */
infra_create_ratedata(infra, name, namelen, timenow); infra_create_ratedata(infra, name, namelen, timenow);
return (1 < lim); return (1 <= lim);
} }
void infra_ratelimit_dec(struct infra_cache* infra, uint8_t* name, void infra_ratelimit_dec(struct infra_cache* infra, uint8_t* name,
@ -987,14 +1009,19 @@ void infra_ratelimit_dec(struct infra_cache* infra, uint8_t* name,
return; /* not enabled */ return; /* not enabled */
entry = infra_find_ratedata(infra, name, namelen, 1); entry = infra_find_ratedata(infra, name, namelen, 1);
if(!entry) return; /* not cached */ if(!entry) return; /* not cached */
cur = infra_rate_find_second(entry->data, timenow); cur = infra_rate_get_second(entry->data, timenow);
if(cur == NULL) {
/* our timenow is not available anymore; nothing to decrease */
lock_rw_unlock(&entry->lock);
return;
}
if((*cur) > 0) if((*cur) > 0)
(*cur)--; (*cur)--;
lock_rw_unlock(&entry->lock); lock_rw_unlock(&entry->lock);
} }
int infra_ratelimit_exceeded(struct infra_cache* infra, uint8_t* name, int infra_ratelimit_exceeded(struct infra_cache* infra, uint8_t* name,
size_t namelen, time_t timenow) size_t namelen, time_t timenow, int backoff)
{ {
struct lruhash_entry* entry; struct lruhash_entry* entry;
int lim, max; int lim, max;
@ -1010,7 +1037,7 @@ int infra_ratelimit_exceeded(struct infra_cache* infra, uint8_t* name,
entry = infra_find_ratedata(infra, name, namelen, 0); entry = infra_find_ratedata(infra, name, namelen, 0);
if(!entry) if(!entry)
return 0; /* not cached */ return 0; /* not cached */
max = infra_rate_max(entry->data, timenow); max = infra_rate_max(entry->data, timenow, backoff);
lock_rw_unlock(&entry->lock); lock_rw_unlock(&entry->lock);
return (max >= lim); return (max >= lim);
@ -1027,7 +1054,8 @@ infra_get_mem(struct infra_cache* infra)
} }
int infra_ip_ratelimit_inc(struct infra_cache* infra, int infra_ip_ratelimit_inc(struct infra_cache* infra,
struct comm_reply* repinfo, time_t timenow, struct sldns_buffer* buffer) struct comm_reply* repinfo, time_t timenow, int backoff,
struct sldns_buffer* buffer)
{ {
int max; int max;
struct lruhash_entry* entry; struct lruhash_entry* entry;
@ -1039,10 +1067,10 @@ int infra_ip_ratelimit_inc(struct infra_cache* infra,
/* find or insert ratedata */ /* find or insert ratedata */
entry = infra_find_ip_ratedata(infra, repinfo, 1); entry = infra_find_ip_ratedata(infra, repinfo, 1);
if(entry) { if(entry) {
int premax = infra_rate_max(entry->data, timenow); int premax = infra_rate_max(entry->data, timenow, backoff);
int* cur = infra_rate_find_second(entry->data, timenow); int* cur = infra_rate_give_second(entry->data, timenow);
(*cur)++; (*cur)++;
max = infra_rate_max(entry->data, timenow); max = infra_rate_max(entry->data, timenow, backoff);
lock_rw_unlock(&entry->lock); lock_rw_unlock(&entry->lock);
if(premax < infra_ip_ratelimit && max >= infra_ip_ratelimit) { if(premax < infra_ip_ratelimit && max >= infra_ip_ratelimit) {

View File

@ -368,6 +368,7 @@ long long infra_get_host_rto(struct infra_cache* infra,
* @param name: zone name * @param name: zone name
* @param namelen: zone name length * @param namelen: zone name length
* @param timenow: what time it is now. * @param timenow: what time it is now.
* @param backoff: if backoff is enabled.
* @param qinfo: for logging, query name. * @param qinfo: for logging, query name.
* @param replylist: for logging, querier's address (if any). * @param replylist: for logging, querier's address (if any).
* @return 1 if it could be incremented. 0 if the increment overshot the * @return 1 if it could be incremented. 0 if the increment overshot the
@ -375,7 +376,7 @@ long long infra_get_host_rto(struct infra_cache* infra,
* Failures like alloc failures are not returned (probably as 1). * Failures like alloc failures are not returned (probably as 1).
*/ */
int infra_ratelimit_inc(struct infra_cache* infra, uint8_t* name, int infra_ratelimit_inc(struct infra_cache* infra, uint8_t* name,
size_t namelen, time_t timenow, struct query_info* qinfo, size_t namelen, time_t timenow, int backoff, struct query_info* qinfo,
struct comm_reply* replylist); struct comm_reply* replylist);
/** /**
@ -398,13 +399,15 @@ void infra_ratelimit_dec(struct infra_cache* infra, uint8_t* name,
* @param name: zone name * @param name: zone name
* @param namelen: zone name length * @param namelen: zone name length
* @param timenow: what time it is now. * @param timenow: what time it is now.
* @param backoff: if backoff is enabled.
* @return true if exceeded. * @return true if exceeded.
*/ */
int infra_ratelimit_exceeded(struct infra_cache* infra, uint8_t* name, int infra_ratelimit_exceeded(struct infra_cache* infra, uint8_t* name,
size_t namelen, time_t timenow); size_t namelen, time_t timenow, int backoff);
/** find the maximum rate stored, not too old. 0 if no information. */ /** find the maximum rate stored. 0 if no information.
int infra_rate_max(void* data, time_t now); * When backoff is enabled look for the maximum in the whole RATE_WINDOW. */
int infra_rate_max(void* data, time_t now, int backoff);
/** find the ratelimit in qps for a domain. 0 if no limit for domain. */ /** find the ratelimit in qps for a domain. 0 if no limit for domain. */
int infra_find_ratelimit(struct infra_cache* infra, uint8_t* name, int infra_find_ratelimit(struct infra_cache* infra, uint8_t* name,
@ -415,11 +418,12 @@ int infra_find_ratelimit(struct infra_cache* infra, uint8_t* name,
* @param infra: infra cache * @param infra: infra cache
* @param repinfo: information about client * @param repinfo: information about client
* @param timenow: what time it is now. * @param timenow: what time it is now.
* @param backoff: if backoff is enabled.
* @param buffer: with query for logging. * @param buffer: with query for logging.
* @return 1 if it could be incremented. 0 if the increment overshot the * @return 1 if it could be incremented. 0 if the increment overshot the
* ratelimit and the query should be dropped. */ * ratelimit and the query should be dropped. */
int infra_ip_ratelimit_inc(struct infra_cache* infra, int infra_ip_ratelimit_inc(struct infra_cache* infra,
struct comm_reply* repinfo, time_t timenow, struct comm_reply* repinfo, time_t timenow, int backoff,
struct sldns_buffer* buffer); struct sldns_buffer* buffer);
/** /**

View File

@ -1387,22 +1387,21 @@ listen_create(struct comm_base* base, struct listen_port* ports,
http_max_streams, http_endpoint, http_max_streams, http_endpoint,
tcp_conn_limit, bufsize, front->udp_buff, tcp_conn_limit, bufsize, front->udp_buff,
ports->ftype, cb, cb_arg, ports->socket); ports->ftype, cb, cb_arg, ports->socket);
if(http_notls && ports->ftype == listen_type_http)
cp->ssl = NULL;
else
cp->ssl = sslctx;
if(ports->ftype == listen_type_http) { if(ports->ftype == listen_type_http) {
if(!sslctx && !http_notls) { if(!sslctx && !http_notls) {
log_warn("HTTPS port configured, but no TLS " log_warn("HTTPS port configured, but "
"tls-service-key or tls-service-pem " "no TLS tls-service-key or "
"set"); "tls-service-pem set");
} }
#ifndef HAVE_SSL_CTX_SET_ALPN_SELECT_CB #ifndef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
if(!http_notls) if(!http_notls) {
log_warn("Unbound is not compiled with an " log_warn("Unbound is not compiled "
"OpenSSL version supporting ALPN " "with an OpenSSL version "
" (OpenSSL >= 1.0.2). This is required " "supporting ALPN "
"to use DNS-over-HTTPS"); "(OpenSSL >= 1.0.2). This "
"is required to use "
"DNS-over-HTTPS");
}
#endif #endif
#ifndef HAVE_NGHTTP2_NGHTTP2_H #ifndef HAVE_NGHTTP2_NGHTTP2_H
log_warn("Unbound is not compiled with " log_warn("Unbound is not compiled with "
@ -1419,6 +1418,10 @@ listen_create(struct comm_base* base, struct listen_port* ports,
listen_delete(front); listen_delete(front);
return NULL; return NULL;
} }
if(http_notls && ports->ftype == listen_type_http)
cp->ssl = NULL;
else
cp->ssl = sslctx;
cp->dtenv = dtenv; cp->dtenv = dtenv;
cp->do_not_close = 1; cp->do_not_close = 1;
#ifdef USE_DNSCRYPT #ifdef USE_DNSCRYPT

View File

@ -56,6 +56,44 @@
* with 16 bytes for an A record, a 64K packet has about 4000 max */ * with 16 bytes for an A record, a 64K packet has about 4000 max */
#define LOCALZONE_RRSET_COUNT_MAX 4096 #define LOCALZONE_RRSET_COUNT_MAX 4096
/** print all RRsets in local zone */
static void
local_zone_out(struct local_zone* z)
{
struct local_data* d;
struct local_rrset* p;
RBTREE_FOR(d, struct local_data*, &z->data) {
for(p = d->rrsets; p; p = p->next) {
log_nametypeclass(NO_VERBOSE, "rrset", d->name,
ntohs(p->rrset->rk.type),
ntohs(p->rrset->rk.rrset_class));
}
}
}
static void
local_zone_print(struct local_zone* z)
{
char buf[64];
lock_rw_rdlock(&z->lock);
snprintf(buf, sizeof(buf), "%s zone",
local_zone_type2str(z->type));
log_nametypeclass(NO_VERBOSE, buf, z->name, 0, z->dclass);
local_zone_out(z);
lock_rw_unlock(&z->lock);
}
void local_zones_print(struct local_zones* zones)
{
struct local_zone* z;
lock_rw_rdlock(&zones->lock);
log_info("number of auth zones %u", (unsigned)zones->ztree.count);
RBTREE_FOR(z, struct local_zone*, &zones->ztree) {
local_zone_print(z);
}
lock_rw_unlock(&zones->lock);
}
struct local_zones* struct local_zones*
local_zones_create(void) local_zones_create(void)
{ {
@ -1010,6 +1048,38 @@ lz_setup_implicit(struct local_zones* zones, struct config_file* cfg)
lock_rw_rdlock(&zones->lock); lock_rw_rdlock(&zones->lock);
if(!local_zones_lookup(zones, rr_name, len, labs, rr_class, if(!local_zones_lookup(zones, rr_name, len, labs, rr_class,
rr_type)) { rr_type)) {
/* Check if there is a zone that this could go
* under but for different class; created zones are
* always for LDNS_RR_CLASS_IN. Create the zone with
* a different class but the same configured
* local_zone_type. */
struct local_zone* z = local_zones_lookup(zones,
rr_name, len, labs, LDNS_RR_CLASS_IN, rr_type);
if(z) {
uint8_t* name = memdup(z->name, z->namelen);
size_t znamelen = z->namelen;
int znamelabs = z->namelabs;
enum localzone_type ztype = z->type;
lock_rw_unlock(&zones->lock);
if(!name) {
log_err("out of memory");
free(rr_name);
return 0;
}
if(!(
#ifndef THREADS_DISABLED
z =
#endif
lz_enter_zone_dname(zones, name,
znamelen, znamelabs,
ztype, rr_class))) {
free(rr_name);
return 0;
}
lock_rw_unlock(&z->lock);
free(rr_name);
continue;
}
if(!have_name) { if(!have_name) {
dclass = rr_class; dclass = rr_class;
nm = rr_name; nm = rr_name;
@ -1220,38 +1290,6 @@ local_zones_find_le(struct local_zones* zones,
return (struct local_zone*)node; return (struct local_zone*)node;
} }
/** print all RRsets in local zone */
static void
local_zone_out(struct local_zone* z)
{
struct local_data* d;
struct local_rrset* p;
RBTREE_FOR(d, struct local_data*, &z->data) {
for(p = d->rrsets; p; p = p->next) {
log_nametypeclass(NO_VERBOSE, "rrset", d->name,
ntohs(p->rrset->rk.type),
ntohs(p->rrset->rk.rrset_class));
}
}
}
void local_zones_print(struct local_zones* zones)
{
struct local_zone* z;
lock_rw_rdlock(&zones->lock);
log_info("number of auth zones %u", (unsigned)zones->ztree.count);
RBTREE_FOR(z, struct local_zone*, &zones->ztree) {
char buf[64];
lock_rw_rdlock(&z->lock);
snprintf(buf, sizeof(buf), "%s zone",
local_zone_type2str(z->type));
log_nametypeclass(NO_VERBOSE, buf, z->name, 0, z->dclass);
local_zone_out(z);
lock_rw_unlock(&z->lock);
}
lock_rw_unlock(&zones->lock);
}
/** encode answer consisting of 1 rrset */ /** encode answer consisting of 1 rrset */
static int static int
local_encode(struct query_info* qinfo, struct module_env* env, local_encode(struct query_info* qinfo, struct module_env* env,

View File

@ -94,6 +94,16 @@ static void waiting_list_remove(struct outside_network* outnet,
static uint16_t tcp_select_id(struct outside_network* outnet, static uint16_t tcp_select_id(struct outside_network* outnet,
struct reuse_tcp* reuse); struct reuse_tcp* reuse);
/** Perform serviced query UDP sending operation */
static int serviced_udp_send(struct serviced_query* sq, sldns_buffer* buff);
/** Send serviced query over TCP return false on initial failure */
static int serviced_tcp_send(struct serviced_query* sq, sldns_buffer* buff);
/** call the callbacks for a serviced query */
static void serviced_callbacks(struct serviced_query* sq, int error,
struct comm_point* c, struct comm_reply* rep);
int int
pending_cmp(const void* key1, const void* key2) pending_cmp(const void* key1, const void* key2)
{ {
@ -836,6 +846,7 @@ outnet_add_tcp_waiting_first(struct outside_network* outnet,
if(w->on_tcp_waiting_list) if(w->on_tcp_waiting_list)
return; return;
w->next_waiting = outnet->tcp_wait_first; w->next_waiting = outnet->tcp_wait_first;
log_assert(w->next_waiting != w);
if(!outnet->tcp_wait_last) if(!outnet->tcp_wait_last)
outnet->tcp_wait_last = w; outnet->tcp_wait_last = w;
outnet->tcp_wait_first = w; outnet->tcp_wait_first = w;
@ -1136,6 +1147,22 @@ static void reuse_cb_readwait_for_failure(rbtree_type* tree_by_id, int err)
} }
} }
/** mark the entry for being in the cb_and_decommission stage */
static void mark_for_cb_and_decommission(rbnode_type* node,
void* ATTR_UNUSED(arg))
{
struct waiting_tcp* w = (struct waiting_tcp*)node->key;
/* Mark the waiting_tcp to signal later code (serviced_delete) that
* this item is part of the backed up tree_by_id and will be deleted
* later. */
w->in_cb_and_decommission = 1;
/* Mark the serviced_query for deletion so that later code through
* callbacks (iter_clear .. outnet_serviced_query_stop) won't
* prematurely delete it. */
if(w->cb)
((struct serviced_query*)w->cb_arg)->to_be_deleted = 1;
}
/** perform callbacks for failure and also decommission pending tcp. /** perform callbacks for failure and also decommission pending tcp.
* the callbacks remove references in sq->pending to the waiting_tcp * the callbacks remove references in sq->pending to the waiting_tcp
* members of the tree_by_id in the pending tcp. The pending_tcp is * members of the tree_by_id in the pending tcp. The pending_tcp is
@ -1151,6 +1178,9 @@ static void reuse_cb_and_decommission(struct outside_network* outnet,
pend->reuse.write_wait_first = NULL; pend->reuse.write_wait_first = NULL;
pend->reuse.write_wait_last = NULL; pend->reuse.write_wait_last = NULL;
decommission_pending_tcp(outnet, pend); decommission_pending_tcp(outnet, pend);
if(store.root != NULL && store.root != RBTREE_NULL) {
traverse_postorder(&store, &mark_for_cb_and_decommission, NULL);
}
reuse_cb_readwait_for_failure(&store, error); reuse_cb_readwait_for_failure(&store, error);
reuse_del_readwait(&store); reuse_del_readwait(&store);
} }
@ -1248,6 +1278,12 @@ outnet_tcp_cb(struct comm_point* c, void* arg, int error,
c->buffer)); c->buffer));
/* find the query the reply is for */ /* find the query the reply is for */
w = reuse_tcp_by_id_find(&pend->reuse, id); w = reuse_tcp_by_id_find(&pend->reuse, id);
/* Make sure that the reply we got is at least for a
* sent query with the same ID; the waiting_tcp that
* gets a reply is assumed to not be waiting to be
* sent. */
if(w && (w->on_tcp_waiting_list || w->write_wait_queued))
w = NULL;
} }
} }
if(error == NETEVENT_NOERROR && !w) { if(error == NETEVENT_NOERROR && !w) {
@ -1265,6 +1301,8 @@ outnet_tcp_cb(struct comm_point* c, void* arg, int error,
} }
} }
if(w) { if(w) {
log_assert(!w->on_tcp_waiting_list);
log_assert(!w->write_wait_queued);
reuse_tree_by_id_delete(&pend->reuse, w); reuse_tree_by_id_delete(&pend->reuse, w);
verbose(VERB_CLIENT, "outnet tcp callback query err %d buflen %d", verbose(VERB_CLIENT, "outnet tcp callback query err %d buflen %d",
error, (int)sldns_buffer_limit(c->buffer)); error, (int)sldns_buffer_limit(c->buffer));
@ -1335,6 +1373,8 @@ outnet_send_wait_udp(struct outside_network* outnet)
free(pend->pkt); /* freeing now makes get_mem correct */ free(pend->pkt); /* freeing now makes get_mem correct */
pend->pkt = NULL; pend->pkt = NULL;
pend->pkt_len = 0; pend->pkt_len = 0;
log_assert(!pend->sq->busy);
pend->sq->busy = 1;
if(!randomize_and_send_udp(pend, outnet->udp_buff, if(!randomize_and_send_udp(pend, outnet->udp_buff,
pend->timeout)) { pend->timeout)) {
/* callback error on pending */ /* callback error on pending */
@ -1344,6 +1384,8 @@ outnet_send_wait_udp(struct outside_network* outnet)
NETEVENT_CLOSED, NULL); NETEVENT_CLOSED, NULL);
} }
pending_delete(outnet, pend); pending_delete(outnet, pend);
} else {
pend->sq->busy = 0;
} }
} }
} }
@ -1454,7 +1496,6 @@ calc_num46(char** ifs, int num_ifs, int do_ip4, int do_ip6,
(*num_ip4)++; (*num_ip4)++;
} }
} }
} }
void void
@ -1708,16 +1749,9 @@ static void
serviced_node_del(rbnode_type* node, void* ATTR_UNUSED(arg)) serviced_node_del(rbnode_type* node, void* ATTR_UNUSED(arg))
{ {
struct serviced_query* sq = (struct serviced_query*)node; struct serviced_query* sq = (struct serviced_query*)node;
struct service_callback* p = sq->cblist, *np; alloc_reg_release(sq->alloc, sq->region);
free(sq->qbuf); if(sq->timer)
free(sq->zone); comm_timer_delete(sq->timer);
free(sq->tls_auth_name);
edns_opt_list_free(sq->opt_list);
while(p) {
np = p->next;
free(p);
p = np;
}
free(sq); free(sq);
} }
@ -2174,10 +2208,13 @@ pending_udp_query(struct serviced_query* sq, struct sldns_buffer* packet,
sq->outnet->udp_wait_last = pend; sq->outnet->udp_wait_last = pend;
return pend; return pend;
} }
log_assert(!sq->busy);
sq->busy = 1;
if(!randomize_and_send_udp(pend, packet, timeout)) { if(!randomize_and_send_udp(pend, packet, timeout)) {
pending_delete(sq->outnet, pend); pending_delete(sq->outnet, pend);
return NULL; return NULL;
} }
sq->busy = 0;
return pend; return pend;
} }
@ -2247,7 +2284,7 @@ reuse_tcp_select_id(struct reuse_tcp* reuse, struct outside_network* outnet)
} }
/* equally pick a random unused element from the tree that is /* equally pick a random unused element from the tree that is
* not in use. Pick a the n-th index of an ununused number, * not in use. Pick a the n-th index of an unused number,
* then loop over the empty spaces in the tree and find it */ * then loop over the empty spaces in the tree and find it */
log_assert(reuse->tree_by_id.count < 0xffff); log_assert(reuse->tree_by_id.count < 0xffff);
select = ub_random_max(outnet->rnd, 0xffff - reuse->tree_by_id.count); select = ub_random_max(outnet->rnd, 0xffff - reuse->tree_by_id.count);
@ -2360,6 +2397,7 @@ pending_tcp_query(struct serviced_query* sq, sldns_buffer* packet,
#ifdef USE_DNSTAP #ifdef USE_DNSTAP
w->sq = NULL; w->sq = NULL;
#endif #endif
w->in_cb_and_decommission = 0;
if(pend) { if(pend) {
/* we have a buffer available right now */ /* we have a buffer available right now */
if(reuse) { if(reuse) {
@ -2456,30 +2494,62 @@ lookup_serviced(struct outside_network* outnet, sldns_buffer* buff, int dnssec,
return (struct serviced_query*)rbtree_search(outnet->serviced, &key); return (struct serviced_query*)rbtree_search(outnet->serviced, &key);
} }
void
serviced_timer_cb(void* arg)
{
struct serviced_query* sq = (struct serviced_query*)arg;
struct outside_network* outnet = sq->outnet;
verbose(VERB_ALGO, "serviced send timer");
/* By the time this cb is called, if we don't have any registered
* callbacks for this serviced_query anymore; do not send. */
if(!sq->cblist)
goto delete;
/* perform first network action */
if(outnet->do_udp && !(sq->tcp_upstream || sq->ssl_upstream)) {
if(!serviced_udp_send(sq, outnet->udp_buff))
goto delete;
} else {
if(!serviced_tcp_send(sq, outnet->udp_buff))
goto delete;
}
/* Maybe by this time we don't have callbacks attached anymore. Don't
* proactively try to delete; let it run and maybe another callback
* will get attached by the time we get an answer. */
return;
delete:
serviced_callbacks(sq, NETEVENT_CLOSED, NULL, NULL);
}
/** Create new serviced entry */ /** Create new serviced entry */
static struct serviced_query* static struct serviced_query*
serviced_create(struct outside_network* outnet, sldns_buffer* buff, int dnssec, serviced_create(struct outside_network* outnet, sldns_buffer* buff, int dnssec,
int want_dnssec, int nocaps, int tcp_upstream, int ssl_upstream, int want_dnssec, int nocaps, int tcp_upstream, int ssl_upstream,
char* tls_auth_name, struct sockaddr_storage* addr, socklen_t addrlen, char* tls_auth_name, struct sockaddr_storage* addr, socklen_t addrlen,
uint8_t* zone, size_t zonelen, int qtype, struct edns_option* opt_list, uint8_t* zone, size_t zonelen, int qtype, struct edns_option* opt_list,
size_t pad_queries_block_size) size_t pad_queries_block_size, struct alloc_cache* alloc,
struct regional* region)
{ {
struct serviced_query* sq = (struct serviced_query*)malloc(sizeof(*sq)); struct serviced_query* sq = (struct serviced_query*)malloc(sizeof(*sq));
struct timeval t;
#ifdef UNBOUND_DEBUG #ifdef UNBOUND_DEBUG
rbnode_type* ins; rbnode_type* ins;
#endif #endif
if(!sq) if(!sq)
return NULL; return NULL;
sq->node.key = sq; sq->node.key = sq;
sq->qbuf = memdup(sldns_buffer_begin(buff), sldns_buffer_limit(buff)); sq->alloc = alloc;
sq->region = region;
sq->qbuf = regional_alloc_init(region, sldns_buffer_begin(buff),
sldns_buffer_limit(buff));
if(!sq->qbuf) { if(!sq->qbuf) {
alloc_reg_release(alloc, region);
free(sq); free(sq);
return NULL; return NULL;
} }
sq->qbuflen = sldns_buffer_limit(buff); sq->qbuflen = sldns_buffer_limit(buff);
sq->zone = memdup(zone, zonelen); sq->zone = regional_alloc_init(region, zone, zonelen);
if(!sq->zone) { if(!sq->zone) {
free(sq->qbuf); alloc_reg_release(alloc, region);
free(sq); free(sq);
return NULL; return NULL;
} }
@ -2491,10 +2561,9 @@ serviced_create(struct outside_network* outnet, sldns_buffer* buff, int dnssec,
sq->tcp_upstream = tcp_upstream; sq->tcp_upstream = tcp_upstream;
sq->ssl_upstream = ssl_upstream; sq->ssl_upstream = ssl_upstream;
if(tls_auth_name) { if(tls_auth_name) {
sq->tls_auth_name = strdup(tls_auth_name); sq->tls_auth_name = regional_strdup(region, tls_auth_name);
if(!sq->tls_auth_name) { if(!sq->tls_auth_name) {
free(sq->zone); alloc_reg_release(alloc, region);
free(sq->qbuf);
free(sq); free(sq);
return NULL; return NULL;
} }
@ -2503,17 +2572,16 @@ serviced_create(struct outside_network* outnet, sldns_buffer* buff, int dnssec,
} }
memcpy(&sq->addr, addr, addrlen); memcpy(&sq->addr, addr, addrlen);
sq->addrlen = addrlen; sq->addrlen = addrlen;
sq->opt_list = NULL; sq->opt_list = opt_list;
if(opt_list) { sq->busy = 0;
sq->opt_list = edns_opt_copy_alloc(opt_list); sq->timer = comm_timer_create(outnet->base, serviced_timer_cb, sq);
if(!sq->opt_list) { if(!sq->timer) {
free(sq->tls_auth_name); alloc_reg_release(alloc, region);
free(sq->zone); free(sq);
free(sq->qbuf); return NULL;
free(sq);
return NULL;
}
} }
memset(&t, 0, sizeof(t));
comm_timer_set(sq->timer, &t);
sq->outnet = outnet; sq->outnet = outnet;
sq->cblist = NULL; sq->cblist = NULL;
sq->pending = NULL; sq->pending = NULL;
@ -2620,29 +2688,38 @@ serviced_delete(struct serviced_query* sq)
struct waiting_tcp* w = (struct waiting_tcp*) struct waiting_tcp* w = (struct waiting_tcp*)
sq->pending; sq->pending;
verbose(VERB_CLIENT, "serviced_delete: TCP"); verbose(VERB_CLIENT, "serviced_delete: TCP");
log_assert(!(w->write_wait_queued && w->on_tcp_waiting_list));
/* if on stream-write-waiting list then /* if on stream-write-waiting list then
* remove from waiting list and waiting_tcp_delete */ * remove from waiting list and waiting_tcp_delete */
if(w->write_wait_queued) { if(w->write_wait_queued) {
struct pending_tcp* pend = struct pending_tcp* pend =
(struct pending_tcp*)w->next_waiting; (struct pending_tcp*)w->next_waiting;
verbose(VERB_CLIENT, "serviced_delete: writewait"); verbose(VERB_CLIENT, "serviced_delete: writewait");
reuse_tree_by_id_delete(&pend->reuse, w); if(!w->in_cb_and_decommission)
reuse_tree_by_id_delete(&pend->reuse, w);
reuse_write_wait_remove(&pend->reuse, w); reuse_write_wait_remove(&pend->reuse, w);
waiting_tcp_delete(w); if(!w->in_cb_and_decommission)
waiting_tcp_delete(w);
} else if(!w->on_tcp_waiting_list) { } else if(!w->on_tcp_waiting_list) {
struct pending_tcp* pend = struct pending_tcp* pend =
(struct pending_tcp*)w->next_waiting; (struct pending_tcp*)w->next_waiting;
verbose(VERB_CLIENT, "serviced_delete: tcpreusekeep"); verbose(VERB_CLIENT, "serviced_delete: tcpreusekeep");
/* w needs to stay on tree_by_id to not assign
* the same ID; remove the callback since its
* serviced_query will be gone. */
w->cb = NULL;
if(!reuse_tcp_remove_serviced_keep(w, sq)) { if(!reuse_tcp_remove_serviced_keep(w, sq)) {
reuse_cb_and_decommission(sq->outnet, if(!w->in_cb_and_decommission)
pend, NETEVENT_CLOSED); reuse_cb_and_decommission(sq->outnet,
pend, NETEVENT_CLOSED);
use_free_buffer(sq->outnet); use_free_buffer(sq->outnet);
} }
sq->pending = NULL; sq->pending = NULL;
} else { } else {
verbose(VERB_CLIENT, "serviced_delete: tcpwait"); verbose(VERB_CLIENT, "serviced_delete: tcpwait");
waiting_list_remove(sq->outnet, w); waiting_list_remove(sq->outnet, w);
waiting_tcp_delete(w); if(!w->in_cb_and_decommission)
waiting_tcp_delete(w);
} }
} }
} }
@ -2892,7 +2969,8 @@ serviced_callbacks(struct serviced_query* sq, int error, struct comm_point* c,
* use secondary buffer to store the query. * use secondary buffer to store the query.
* This is a data copy, but faster than packet to server */ * This is a data copy, but faster than packet to server */
backlen = sldns_buffer_limit(c->buffer); backlen = sldns_buffer_limit(c->buffer);
backup_p = memdup(sldns_buffer_begin(c->buffer), backlen); backup_p = regional_alloc_init(sq->region,
sldns_buffer_begin(c->buffer), backlen);
if(!backup_p) { if(!backup_p) {
log_err("malloc failure in serviced query callbacks"); log_err("malloc failure in serviced query callbacks");
error = NETEVENT_CLOSED; error = NETEVENT_CLOSED;
@ -2910,10 +2988,8 @@ serviced_callbacks(struct serviced_query* sq, int error, struct comm_point* c,
} }
fptr_ok(fptr_whitelist_serviced_query(p->cb)); fptr_ok(fptr_whitelist_serviced_query(p->cb));
(void)(*p->cb)(c, p->cb_arg, error, rep); (void)(*p->cb)(c, p->cb_arg, error, rep);
free(p);
} }
if(backup_p) { if(backup_p) {
free(backup_p);
sq->outnet->svcd_overhead = 0; sq->outnet->svcd_overhead = 0;
} }
verbose(VERB_ALGO, "svcd callbacks end"); verbose(VERB_ALGO, "svcd callbacks end");
@ -2931,7 +3007,7 @@ serviced_tcp_callback(struct comm_point* c, void* arg, int error,
struct waiting_tcp* w = (struct waiting_tcp*)sq->pending; struct waiting_tcp* w = (struct waiting_tcp*)sq->pending;
struct pending_tcp* pend_tcp = NULL; struct pending_tcp* pend_tcp = NULL;
struct port_if* pi = NULL; struct port_if* pi = NULL;
if(!w->on_tcp_waiting_list && w->next_waiting) { if(w && !w->on_tcp_waiting_list && w->next_waiting) {
pend_tcp = (struct pending_tcp*)w->next_waiting; pend_tcp = (struct pending_tcp*)w->next_waiting;
pi = pend_tcp->pi; pi = pend_tcp->pi;
} }
@ -3027,8 +3103,11 @@ serviced_tcp_initiate(struct serviced_query* sq, sldns_buffer* buff)
sq->status==serviced_query_TCP_EDNS?"EDNS":""); sq->status==serviced_query_TCP_EDNS?"EDNS":"");
serviced_encode(sq, buff, sq->status == serviced_query_TCP_EDNS); serviced_encode(sq, buff, sq->status == serviced_query_TCP_EDNS);
sq->last_sent_time = *sq->outnet->now_tv; sq->last_sent_time = *sq->outnet->now_tv;
log_assert(!sq->busy);
sq->busy = 1;
sq->pending = pending_tcp_query(sq, buff, sq->outnet->tcp_auth_query_timeout, sq->pending = pending_tcp_query(sq, buff, sq->outnet->tcp_auth_query_timeout,
serviced_tcp_callback, sq); serviced_tcp_callback, sq);
sq->busy = 0;
if(!sq->pending) { if(!sq->pending) {
/* delete from tree so that a retry by above layer does not /* delete from tree so that a retry by above layer does not
* clash with this entry */ * clash with this entry */
@ -3060,8 +3139,11 @@ serviced_tcp_send(struct serviced_query* sq, sldns_buffer* buff)
} else { } else {
timeout = sq->outnet->tcp_auth_query_timeout; timeout = sq->outnet->tcp_auth_query_timeout;
} }
log_assert(!sq->busy);
sq->busy = 1;
sq->pending = pending_tcp_query(sq, buff, timeout, sq->pending = pending_tcp_query(sq, buff, timeout,
serviced_tcp_callback, sq); serviced_tcp_callback, sq);
sq->busy = 0;
return sq->pending != NULL; return sq->pending != NULL;
} }
@ -3112,7 +3194,6 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
struct timeval now = *sq->outnet->now_tv; struct timeval now = *sq->outnet->now_tv;
#ifdef USE_DNSTAP #ifdef USE_DNSTAP
struct pending* p = (struct pending*)sq->pending; struct pending* p = (struct pending*)sq->pending;
struct port_if* pi = p->pc->pif;
#endif #endif
sq->pending = NULL; /* removed after callback */ sq->pending = NULL; /* removed after callback */
@ -3154,14 +3235,16 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
/* /*
* sending src (local service)/dst (upstream) addresses over DNSTAP * sending src (local service)/dst (upstream) addresses over DNSTAP
*/ */
if(error == NETEVENT_NOERROR && outnet->dtenv && if(error == NETEVENT_NOERROR && outnet->dtenv && p->pc &&
(outnet->dtenv->log_resolver_response_messages || (outnet->dtenv->log_resolver_response_messages ||
outnet->dtenv->log_forwarder_response_messages)) { outnet->dtenv->log_forwarder_response_messages)) {
log_addr(VERB_ALGO, "response from upstream", &sq->addr, sq->addrlen); log_addr(VERB_ALGO, "response from upstream", &sq->addr, sq->addrlen);
log_addr(VERB_ALGO, "to local addr", &pi->addr, pi->addrlen); log_addr(VERB_ALGO, "to local addr", &p->pc->pif->addr,
dt_msg_send_outside_response(outnet->dtenv, &sq->addr, &pi->addr, c->type, p->pc->pif->addrlen);
sq->zone, sq->zonelen, sq->qbuf, sq->qbuflen, dt_msg_send_outside_response(outnet->dtenv, &sq->addr,
&sq->last_sent_time, sq->outnet->now_tv, c->buffer); &p->pc->pif->addr, c->type, sq->zone, sq->zonelen,
sq->qbuf, sq->qbuflen, &sq->last_sent_time,
sq->outnet->now_tv, c->buffer);
} }
#endif #endif
if( (sq->status == serviced_query_UDP_EDNS if( (sq->status == serviced_query_UDP_EDNS
@ -3251,64 +3334,117 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error,
struct serviced_query* struct serviced_query*
outnet_serviced_query(struct outside_network* outnet, outnet_serviced_query(struct outside_network* outnet,
struct query_info* qinfo, uint16_t flags, int dnssec, int want_dnssec, struct query_info* qinfo, uint16_t flags, int dnssec, int want_dnssec,
int nocaps, int tcp_upstream, int ssl_upstream, char* tls_auth_name, int nocaps, int check_ratelimit, int tcp_upstream, int ssl_upstream,
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone, char* tls_auth_name, struct sockaddr_storage* addr, socklen_t addrlen,
size_t zonelen, struct module_qstate* qstate, uint8_t* zone, size_t zonelen, struct module_qstate* qstate,
comm_point_callback_type* callback, void* callback_arg, sldns_buffer* buff, comm_point_callback_type* callback, void* callback_arg,
struct module_env* env) sldns_buffer* buff, struct module_env* env, int* was_ratelimited)
{ {
struct serviced_query* sq; struct serviced_query* sq;
struct service_callback* cb; struct service_callback* cb;
struct edns_string_addr* client_string_addr; struct edns_string_addr* client_string_addr;
struct regional* region;
struct edns_option* backed_up_opt_list = qstate->edns_opts_back_out;
struct edns_option* per_upstream_opt_list = NULL;
time_t timenow = 0;
if(!inplace_cb_query_call(env, qinfo, flags, addr, addrlen, zone, zonelen, /* If we have an already populated EDNS option list make a copy since
qstate, qstate->region)) * we may now add upstream specific EDNS options. */
/* Use a region that could be attached to a serviced_query, if it needs
* to be created. If an existing one is found then this region will be
* destroyed here. */
region = alloc_reg_obtain(env->alloc);
if(!region) return NULL;
if(qstate->edns_opts_back_out) {
per_upstream_opt_list = edns_opt_copy_region(
qstate->edns_opts_back_out, region);
if(!per_upstream_opt_list) {
alloc_reg_release(env->alloc, region);
return NULL; return NULL;
}
qstate->edns_opts_back_out = per_upstream_opt_list;
}
if(!inplace_cb_query_call(env, qinfo, flags, addr, addrlen, zone,
zonelen, qstate, region)) {
alloc_reg_release(env->alloc, region);
return NULL;
}
/* Restore the option list; we can explicitly use the copied one from
* now on. */
per_upstream_opt_list = qstate->edns_opts_back_out;
qstate->edns_opts_back_out = backed_up_opt_list;
if((client_string_addr = edns_string_addr_lookup( if((client_string_addr = edns_string_addr_lookup(
&env->edns_strings->client_strings, addr, addrlen))) { &env->edns_strings->client_strings, addr, addrlen))) {
edns_opt_list_append(&qstate->edns_opts_back_out, edns_opt_list_append(&per_upstream_opt_list,
env->edns_strings->client_string_opcode, env->edns_strings->client_string_opcode,
client_string_addr->string_len, client_string_addr->string_len,
client_string_addr->string, qstate->region); client_string_addr->string, region);
} }
serviced_gen_query(buff, qinfo->qname, qinfo->qname_len, qinfo->qtype, serviced_gen_query(buff, qinfo->qname, qinfo->qname_len, qinfo->qtype,
qinfo->qclass, flags); qinfo->qclass, flags);
sq = lookup_serviced(outnet, buff, dnssec, addr, addrlen, sq = lookup_serviced(outnet, buff, dnssec, addr, addrlen,
qstate->edns_opts_back_out); per_upstream_opt_list);
/* duplicate entries are included in the callback list, because
* there is a counterpart registration by our caller that needs to
* be doubly-removed (with callbacks perhaps). */
if(!(cb = (struct service_callback*)malloc(sizeof(*cb))))
return NULL;
if(!sq) { if(!sq) {
/* Check ratelimit only for new serviced_query */
if(check_ratelimit) {
timenow = *env->now;
if(!infra_ratelimit_inc(env->infra_cache, zone,
zonelen, timenow, env->cfg->ratelimit_backoff,
&qstate->qinfo, qstate->reply)) {
/* Can we pass through with slip factor? */
if(env->cfg->ratelimit_factor == 0 ||
ub_random_max(env->rnd,
env->cfg->ratelimit_factor) != 1) {
*was_ratelimited = 1;
alloc_reg_release(env->alloc, region);
return NULL;
}
log_nametypeclass(VERB_ALGO,
"ratelimit allowed through for "
"delegation point", zone,
LDNS_RR_TYPE_NS, LDNS_RR_CLASS_IN);
}
}
/* make new serviced query entry */ /* make new serviced query entry */
sq = serviced_create(outnet, buff, dnssec, want_dnssec, nocaps, sq = serviced_create(outnet, buff, dnssec, want_dnssec, nocaps,
tcp_upstream, ssl_upstream, tls_auth_name, addr, tcp_upstream, ssl_upstream, tls_auth_name, addr,
addrlen, zone, zonelen, (int)qinfo->qtype, addrlen, zone, zonelen, (int)qinfo->qtype,
qstate->edns_opts_back_out, per_upstream_opt_list,
( ssl_upstream && env->cfg->pad_queries ( ssl_upstream && env->cfg->pad_queries
? env->cfg->pad_queries_block_size : 0 )); ? env->cfg->pad_queries_block_size : 0 ),
env->alloc, region);
if(!sq) { if(!sq) {
free(cb); if(check_ratelimit) {
infra_ratelimit_dec(env->infra_cache,
zone, zonelen, timenow);
}
alloc_reg_release(env->alloc, region);
return NULL; return NULL;
} }
/* perform first network action */ if(!(cb = (struct service_callback*)regional_alloc(
if(outnet->do_udp && !(tcp_upstream || ssl_upstream)) { sq->region, sizeof(*cb)))) {
if(!serviced_udp_send(sq, buff)) { if(check_ratelimit) {
(void)rbtree_delete(outnet->serviced, sq); infra_ratelimit_dec(env->infra_cache,
serviced_node_del(&sq->node, NULL); zone, zonelen, timenow);
free(cb);
return NULL;
}
} else {
if(!serviced_tcp_send(sq, buff)) {
(void)rbtree_delete(outnet->serviced, sq);
serviced_node_del(&sq->node, NULL);
free(cb);
return NULL;
} }
(void)rbtree_delete(outnet->serviced, sq);
serviced_node_del(&sq->node, NULL);
return NULL;
}
/* No network action at this point; it will be invoked with the
* serviced_query timer instead to run outside of the mesh. */
} else {
/* We don't need this region anymore. */
alloc_reg_release(env->alloc, region);
/* duplicate entries are included in the callback list, because
* there is a counterpart registration by our caller that needs
* to be doubly-removed (with callbacks perhaps). */
if(!(cb = (struct service_callback*)regional_alloc(
sq->region, sizeof(*cb)))) {
return NULL;
} }
} }
/* add callback to list of callbacks */ /* add callback to list of callbacks */
@ -3328,7 +3464,6 @@ callback_list_remove(struct serviced_query* sq, void* cb_arg)
if((*pp)->cb_arg == cb_arg) { if((*pp)->cb_arg == cb_arg) {
struct service_callback* del = *pp; struct service_callback* del = *pp;
*pp = del->next; *pp = del->next;
free(del);
return; return;
} }
pp = &(*pp)->next; pp = &(*pp)->next;
@ -3341,7 +3476,7 @@ void outnet_serviced_query_stop(struct serviced_query* sq, void* cb_arg)
return; return;
callback_list_remove(sq, cb_arg); callback_list_remove(sq, cb_arg);
/* if callbacks() routine scheduled deletion, let it do that */ /* if callbacks() routine scheduled deletion, let it do that */
if(!sq->cblist && !sq->to_be_deleted) { if(!sq->cblist && !sq->busy && !sq->to_be_deleted) {
(void)rbtree_delete(sq->outnet->serviced, sq); (void)rbtree_delete(sq->outnet->serviced, sq);
serviced_delete(sq); serviced_delete(sq);
} }

View File

@ -43,7 +43,9 @@
#ifndef OUTSIDE_NETWORK_H #ifndef OUTSIDE_NETWORK_H
#define OUTSIDE_NETWORK_H #define OUTSIDE_NETWORK_H
#include "util/alloc.h"
#include "util/rbtree.h" #include "util/rbtree.h"
#include "util/regional.h"
#include "util/netevent.h" #include "util/netevent.h"
#include "dnstap/dnstap_config.h" #include "dnstap/dnstap_config.h"
struct pending; struct pending;
@ -412,6 +414,8 @@ struct waiting_tcp {
char* tls_auth_name; char* tls_auth_name;
/** the packet was involved in an error, to stop looping errors */ /** the packet was involved in an error, to stop looping errors */
int error_count; int error_count;
/** if true, the item is at the cb_and_decommission stage */
int in_cb_and_decommission;
#ifdef USE_DNSTAP #ifdef USE_DNSTAP
/** serviced query pointer for dnstap to get logging info, if nonNULL*/ /** serviced query pointer for dnstap to get logging info, if nonNULL*/
struct serviced_query* sq; struct serviced_query* sq;
@ -512,6 +516,15 @@ struct serviced_query {
void* pending; void* pending;
/** block size with which to pad encrypted queries (default: 128) */ /** block size with which to pad encrypted queries (default: 128) */
size_t padding_block_size; size_t padding_block_size;
/** region for this serviced query. Will be cleared when this
* serviced_query will be deleted */
struct regional* region;
/** allocation service for the region */
struct alloc_cache* alloc;
/** flash timer to start the net I/O as a separate event */
struct comm_timer* timer;
/** true if serviced_query is currently doing net I/O and may block */
int busy;
}; };
/** /**
@ -619,6 +632,7 @@ void pending_delete(struct outside_network* outnet, struct pending* p);
* @param want_dnssec: signatures are needed, without EDNS the answer is * @param want_dnssec: signatures are needed, without EDNS the answer is
* likely to be useless. * likely to be useless.
* @param nocaps: ignore use_caps_for_id and use unperturbed qname. * @param nocaps: ignore use_caps_for_id and use unperturbed qname.
* @param check_ratelimit: if set, will check ratelimit before sending out.
* @param tcp_upstream: use TCP for upstream queries. * @param tcp_upstream: use TCP for upstream queries.
* @param ssl_upstream: use SSL for upstream queries. * @param ssl_upstream: use SSL for upstream queries.
* @param tls_auth_name: when ssl_upstream is true, use this name to check * @param tls_auth_name: when ssl_upstream is true, use this name to check
@ -635,16 +649,18 @@ void pending_delete(struct outside_network* outnet, struct pending* p);
* @param callback_arg: user argument to callback function. * @param callback_arg: user argument to callback function.
* @param buff: scratch buffer to create query contents in. Empty on exit. * @param buff: scratch buffer to create query contents in. Empty on exit.
* @param env: the module environment. * @param env: the module environment.
* @param was_ratelimited: it will signal back if the query failed to pass the
* ratelimit check.
* @return 0 on error, or pointer to serviced query that is used to answer * @return 0 on error, or pointer to serviced query that is used to answer
* this serviced query may be shared with other callbacks as well. * this serviced query may be shared with other callbacks as well.
*/ */
struct serviced_query* outnet_serviced_query(struct outside_network* outnet, struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
struct query_info* qinfo, uint16_t flags, int dnssec, int want_dnssec, struct query_info* qinfo, uint16_t flags, int dnssec, int want_dnssec,
int nocaps, int tcp_upstream, int ssl_upstream, char* tls_auth_name, int nocaps, int check_ratelimit, int tcp_upstream, int ssl_upstream,
struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone, char* tls_auth_name, struct sockaddr_storage* addr, socklen_t addrlen,
size_t zonelen, struct module_qstate* qstate, uint8_t* zone, size_t zonelen, struct module_qstate* qstate,
comm_point_callback_type* callback, void* callback_arg, comm_point_callback_type* callback, void* callback_arg,
struct sldns_buffer* buff, struct module_env* env); struct sldns_buffer* buff, struct module_env* env, int* was_ratelimited);
/** /**
* Remove service query callback. * Remove service query callback.
@ -785,6 +801,9 @@ void pending_udp_timer_delay_cb(void *arg);
/** callback for outgoing TCP timer event */ /** callback for outgoing TCP timer event */
void outnet_tcptimer(void* arg); void outnet_tcptimer(void* arg);
/** callback to send serviced queries */
void serviced_timer_cb(void *arg);
/** callback for serviced query UDP answers */ /** callback for serviced query UDP answers */
int serviced_udp_callback(struct comm_point* c, void* arg, int error, int serviced_udp_callback(struct comm_point* c, void* arg, int error,
struct comm_reply* rep); struct comm_reply* rep);

View File

@ -542,6 +542,7 @@ rpz_create(struct config_auth* p)
} }
} }
r->log = p->rpz_log; r->log = p->rpz_log;
r->signal_nxdomain_ra = p->rpz_signal_nxdomain_ra;
if(p->rpz_log_name) { if(p->rpz_log_name) {
if(!(r->log_name = strdup(p->rpz_log_name))) { if(!(r->log_name = strdup(p->rpz_log_name))) {
log_err("malloc failure on RPZ log_name strdup"); log_err("malloc failure on RPZ log_name strdup");
@ -836,7 +837,7 @@ rpz_report_rrset_error(const char* msg, uint8_t* rr, size_t rr_len) {
} }
/* from localzone.c; difference is we don't have a dname */ /* from localzone.c; difference is we don't have a dname */
struct local_rrset* static struct local_rrset*
rpz_clientip_new_rrset(struct regional* region, rpz_clientip_new_rrset(struct regional* region,
struct clientip_synthesized_rr* raddr, uint16_t rrtype, uint16_t rrclass) struct clientip_synthesized_rr* raddr, uint16_t rrtype, uint16_t rrclass)
{ {
@ -1384,9 +1385,9 @@ log_rpz_apply(char* trigger, uint8_t* dname, struct addr_tree_node* addrnode,
if(dname) { if(dname) {
dname_str(dname, dnamestr); dname_str(dname, dnamestr);
} else if(addrnode) { } else if(addrnode) {
char a[128]; char addrbuf[128];
addr_to_str(&addrnode->addr, addrnode->addrlen, a, sizeof(a)); addr_to_str(&addrnode->addr, addrnode->addrlen, addrbuf, sizeof(addrbuf));
snprintf(dnamestr, sizeof(dnamestr), "%s/%d", a, addrnode->net); snprintf(dnamestr, sizeof(dnamestr), "%s/%d", addrbuf, addrnode->net);
} else { } else {
dnamestr[0]=0; dnamestr[0]=0;
} }
@ -1697,7 +1698,7 @@ rpz_synthesize_nodata(struct rpz* ATTR_UNUSED(r), struct module_qstate* ms,
if(msg == NULL) { return msg; } if(msg == NULL) { return msg; }
msg->qinfo = *qinfo; msg->qinfo = *qinfo;
msg->rep = construct_reply_info_base(ms->region, msg->rep = construct_reply_info_base(ms->region,
LDNS_RCODE_NOERROR | BIT_RD | BIT_QR | BIT_AA | BIT_RA, LDNS_RCODE_NOERROR | BIT_QR | BIT_AA | BIT_RA,
1, /* qd */ 1, /* qd */
0, /* ttl */ 0, /* ttl */
0, /* prettl */ 0, /* prettl */
@ -1715,14 +1716,18 @@ rpz_synthesize_nodata(struct rpz* ATTR_UNUSED(r), struct module_qstate* ms,
} }
static inline struct dns_msg* static inline struct dns_msg*
rpz_synthesize_nxdomain(struct rpz* ATTR_UNUSED(r), struct module_qstate* ms, rpz_synthesize_nxdomain(struct rpz* r, struct module_qstate* ms,
struct query_info* qinfo, struct auth_zone* az) struct query_info* qinfo, struct auth_zone* az)
{ {
struct dns_msg* msg = rpz_dns_msg_new(ms->region); struct dns_msg* msg = rpz_dns_msg_new(ms->region);
uint16_t flags;
if(msg == NULL) { return msg; } if(msg == NULL) { return msg; }
msg->qinfo = *qinfo; msg->qinfo = *qinfo;
flags = LDNS_RCODE_NXDOMAIN | BIT_QR | BIT_AA | BIT_RA;
if(r->signal_nxdomain_ra)
flags &= ~BIT_RA;
msg->rep = construct_reply_info_base(ms->region, msg->rep = construct_reply_info_base(ms->region,
LDNS_RCODE_NXDOMAIN | BIT_RD | BIT_QR | BIT_AA | BIT_RA, flags,
1, /* qd */ 1, /* qd */
0, /* ttl */ 0, /* ttl */
0, /* prettl */ 0, /* prettl */
@ -1752,7 +1757,7 @@ rpz_synthesize_localdata_from_rrset(struct rpz* ATTR_UNUSED(r), struct module_qs
if(msg == NULL) { return NULL; } if(msg == NULL) { return NULL; }
new_reply_info = construct_reply_info_base(ms->region, new_reply_info = construct_reply_info_base(ms->region,
LDNS_RCODE_NOERROR | BIT_RD | BIT_QR | BIT_AA | BIT_RA, LDNS_RCODE_NOERROR | BIT_QR | BIT_AA | BIT_RA,
1, /* qd */ 1, /* qd */
0, /* ttl */ 0, /* ttl */
0, /* prettl */ 0, /* prettl */
@ -1922,6 +1927,9 @@ rpz_synthesize_qname_localdata(struct module_env* env, struct rpz* r,
ret = local_zones_zone_answer(z, env, qinfo, edns, repinfo, buf, temp, ret = local_zones_zone_answer(z, env, qinfo, edns, repinfo, buf, temp,
0 /* no local data used */, lzt); 0 /* no local data used */, lzt);
if(r->signal_nxdomain_ra && LDNS_RCODE_WIRE(sldns_buffer_begin(buf))
== LDNS_RCODE_NXDOMAIN)
LDNS_RA_CLR(sldns_buffer_begin(buf));
if(r->log) { if(r->log) {
log_rpz_apply("qname", z->name, NULL, localzone_type_to_rpz_action(lzt), log_rpz_apply("qname", z->name, NULL, localzone_type_to_rpz_action(lzt),
qinfo, repinfo, NULL, r->log_name); qinfo, repinfo, NULL, r->log_name);
@ -1930,7 +1938,7 @@ rpz_synthesize_qname_localdata(struct module_env* env, struct rpz* r,
return ret; return ret;
} }
struct clientip_synthesized_rr* static struct clientip_synthesized_rr*
rpz_delegation_point_ipbased_trigger_lookup(struct rpz* rpz, struct iter_qstate* is) rpz_delegation_point_ipbased_trigger_lookup(struct rpz* rpz, struct iter_qstate* is)
{ {
struct delegpt_addr* cursor; struct delegpt_addr* cursor;
@ -1947,7 +1955,7 @@ rpz_delegation_point_ipbased_trigger_lookup(struct rpz* rpz, struct iter_qstate*
return NULL; return NULL;
} }
struct dns_msg* static struct dns_msg*
rpz_apply_nsip_trigger(struct module_qstate* ms, struct rpz* r, rpz_apply_nsip_trigger(struct module_qstate* ms, struct rpz* r,
struct clientip_synthesized_rr* raddr, struct auth_zone* az) struct clientip_synthesized_rr* raddr, struct auth_zone* az)
{ {
@ -2006,7 +2014,7 @@ rpz_apply_nsip_trigger(struct module_qstate* ms, struct rpz* r,
return ret; return ret;
} }
struct dns_msg* static struct dns_msg*
rpz_apply_nsdname_trigger(struct module_qstate* ms, struct rpz* r, rpz_apply_nsdname_trigger(struct module_qstate* ms, struct rpz* r,
struct local_zone* z, struct matched_delegation_point const* match, struct local_zone* z, struct matched_delegation_point const* match,
struct auth_zone* az) struct auth_zone* az)
@ -2295,6 +2303,10 @@ rpz_apply_maybe_clientip_trigger(struct auth_zones* az, struct module_env* env,
local_zones_zone_answer(*z_out /*likely NULL, no zone*/, env, qinfo, edns, local_zones_zone_answer(*z_out /*likely NULL, no zone*/, env, qinfo, edns,
repinfo, buf, temp, 0 /* no local data used */, repinfo, buf, temp, 0 /* no local data used */,
rpz_action_to_localzone_type(client_action)); rpz_action_to_localzone_type(client_action));
if(*r_out && (*r_out)->signal_nxdomain_ra &&
LDNS_RCODE_WIRE(sldns_buffer_begin(buf))
== LDNS_RCODE_NXDOMAIN)
LDNS_RA_CLR(sldns_buffer_begin(buf));
} }
ret = 1; ret = 1;
goto done; goto done;

View File

@ -123,6 +123,8 @@ struct rpz {
struct ub_packed_rrset_key* cname_override; struct ub_packed_rrset_key* cname_override;
int log; int log;
char* log_name; char* log_name;
/** signal NXDOMAIN blocked with unset RA flag */
int signal_nxdomain_ra;
struct regional* region; struct regional* region;
int disabled; int disabled;
}; };

View File

@ -250,7 +250,8 @@ sldns_key_buf2dsa_raw(unsigned char* key, size_t len)
if(!(dsa = DSA_new())) { if(!(dsa = DSA_new())) {
return NULL; return NULL;
} }
#if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL) #if OPENSSL_VERSION_NUMBER < 0x10100000 || \
(defined(HAVE_LIBRESSL) && LIBRESSL_VERSION_NUMBER < 0x02070000f)
#ifndef S_SPLINT_S #ifndef S_SPLINT_S
dsa->p = P; dsa->p = P;
dsa->q = Q; dsa->q = Q;
@ -428,7 +429,8 @@ sldns_key_buf2rsa_raw(unsigned char* key, size_t len)
BN_free(modulus); BN_free(modulus);
return NULL; return NULL;
} }
#if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL) #if OPENSSL_VERSION_NUMBER < 0x10100000 || \
(defined(HAVE_LIBRESSL) && LIBRESSL_VERSION_NUMBER < 0x02070000f)
#ifndef S_SPLINT_S #ifndef S_SPLINT_S
rsa->n = modulus; rsa->n = modulus;
rsa->e = exponent; rsa->e = exponent;

View File

@ -25,8 +25,10 @@
#include <netdb.h> #include <netdb.h>
#endif #endif
/** bits for the offset */
#define RET_OFFSET_MASK (((unsigned)(~LDNS_WIREPARSE_MASK))>>LDNS_WIREPARSE_SHIFT)
/** return an error */ /** return an error */
#define RET_ERR(e, off) ((int)((e)|((off)<<LDNS_WIREPARSE_SHIFT))) #define RET_ERR(e, off) ((int)(((e)&LDNS_WIREPARSE_MASK)|(((off)&RET_OFFSET_MASK)<<LDNS_WIREPARSE_SHIFT)))
/** Move parse error but keep its ID */ /** Move parse error but keep its ID */
#define RET_ERR_SHIFT(e, move) RET_ERR(LDNS_WIREPARSE_ERROR(e), LDNS_WIREPARSE_OFFSET(e)+(move)); #define RET_ERR_SHIFT(e, move) RET_ERR(LDNS_WIREPARSE_ERROR(e), LDNS_WIREPARSE_OFFSET(e)+(move));
@ -543,9 +545,10 @@ sldns_parse_rdf_token(sldns_buffer* strbuf, char* token, size_t token_len,
{ {
size_t slen; size_t slen;
/* skip spaces */ /* skip spaces and tabs */
while(sldns_buffer_remaining(strbuf) > 0 && !*quoted && while(sldns_buffer_remaining(strbuf) > 0 && !*quoted &&
*(sldns_buffer_current(strbuf)) == ' ') { (*(sldns_buffer_current(strbuf)) == ' ' ||
*(sldns_buffer_current(strbuf)) == '\t')) {
sldns_buffer_skip(strbuf, 1); sldns_buffer_skip(strbuf, 1);
} }
@ -601,7 +604,10 @@ sldns_affix_token(sldns_buffer* strbuf, char* token, size_t* token_len,
size_t addstrlen = 0; size_t addstrlen = 0;
/* add space */ /* add space */
if(addlen < 1) return 0; /* when addlen < 2, the token buffer is full considering the NULL byte
* from strlen and will lead to buffer overflow with the second
* assignement below. */
if(addlen < 2) return 0;
token[*token_strlen] = ' '; token[*token_strlen] = ' ';
token[++(*token_strlen)] = 0; token[++(*token_strlen)] = 0;

View File

@ -187,7 +187,7 @@ uint8_t* sldns_wirerr_get_rdatawl(uint8_t* rr, size_t len, size_t dname_len);
#define LDNS_WIREPARSE_MASK 0x0fff #define LDNS_WIREPARSE_MASK 0x0fff
#define LDNS_WIREPARSE_SHIFT 12 #define LDNS_WIREPARSE_SHIFT 12
#define LDNS_WIREPARSE_ERROR(e) ((e)&LDNS_WIREPARSE_MASK) #define LDNS_WIREPARSE_ERROR(e) ((e)&LDNS_WIREPARSE_MASK)
#define LDNS_WIREPARSE_OFFSET(e) (((e)&~LDNS_WIREPARSE_MASK)>>LDNS_WIREPARSE_SHIFT) #define LDNS_WIREPARSE_OFFSET(e) ((((unsigned)(e))&~LDNS_WIREPARSE_MASK)>>LDNS_WIREPARSE_SHIFT)
/* use lookuptable to get error string, sldns_wireparse_errors */ /* use lookuptable to get error string, sldns_wireparse_errors */
#define LDNS_WIREPARSE_ERR_OK 0 #define LDNS_WIREPARSE_ERR_OK 0
#define LDNS_WIREPARSE_ERR_GENERAL 342 #define LDNS_WIREPARSE_ERR_GENERAL 342

View File

@ -817,6 +817,7 @@ int sldns_wire2str_dname_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen,
unsigned i, counter=0; unsigned i, counter=0;
unsigned maxcompr = MAX_COMPRESS_PTRS; /* loop detection, max compr ptrs */ unsigned maxcompr = MAX_COMPRESS_PTRS; /* loop detection, max compr ptrs */
int in_buf = 1; int in_buf = 1;
size_t dname_len = 0;
if(comprloop) { if(comprloop) {
if(*comprloop != 0) if(*comprloop != 0)
maxcompr = 30; /* for like ipv6 reverse name, per label */ maxcompr = 30; /* for like ipv6 reverse name, per label */
@ -872,6 +873,16 @@ int sldns_wire2str_dname_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen,
labellen = (uint8_t)*dlen; labellen = (uint8_t)*dlen;
else if(!in_buf && pos+(size_t)labellen > pkt+pktlen) else if(!in_buf && pos+(size_t)labellen > pkt+pktlen)
labellen = (uint8_t)(pkt + pktlen - pos); labellen = (uint8_t)(pkt + pktlen - pos);
dname_len += ((size_t)labellen)+1;
if(dname_len > LDNS_MAX_DOMAINLEN) {
/* dname_len counts the uncompressed length we have
* seen so far, and the domain name has become too
* long, prevent the loop from printing overly long
* content. */
w += sldns_str_print(s, slen,
"ErrorDomainNameTooLong");
return w;
}
for(i=0; i<(unsigned)labellen; i++) { for(i=0; i<(unsigned)labellen; i++) {
w += dname_char_print(s, slen, *pos++); w += dname_char_print(s, slen, *pos++);
} }

View File

@ -691,6 +691,8 @@ morechecks(struct config_file* cfg)
&& strcmp(cfg->module_conf, "dns64 iterator") != 0 && strcmp(cfg->module_conf, "dns64 iterator") != 0
&& strcmp(cfg->module_conf, "respip iterator") != 0 && strcmp(cfg->module_conf, "respip iterator") != 0
&& strcmp(cfg->module_conf, "respip validator iterator") != 0 && strcmp(cfg->module_conf, "respip validator iterator") != 0
&& strcmp(cfg->module_conf, "respip dns64 validator iterator") != 0
&& strcmp(cfg->module_conf, "respip dns64 iterator") != 0
#ifdef WITH_PYTHONMODULE #ifdef WITH_PYTHONMODULE
&& strcmp(cfg->module_conf, "python iterator") != 0 && strcmp(cfg->module_conf, "python iterator") != 0
&& strcmp(cfg->module_conf, "python respip iterator") != 0 && strcmp(cfg->module_conf, "python respip iterator") != 0
@ -785,6 +787,10 @@ morechecks(struct config_file* cfg)
&& strcmp(cfg->module_conf, "validator python cachedb iterator") != 0 && strcmp(cfg->module_conf, "validator python cachedb iterator") != 0
&& strcmp(cfg->module_conf, "respip validator python cachedb iterator") != 0 && strcmp(cfg->module_conf, "respip validator python cachedb iterator") != 0
#endif #endif
#if defined(CLIENT_SUBNET) && defined(USE_CACHEDB)
&& strcmp(cfg->module_conf, "respip subnetcache validator cachedb iterator") != 0
&& strcmp(cfg->module_conf, "subnetcache validator cachedb iterator") != 0
#endif
#ifdef CLIENT_SUBNET #ifdef CLIENT_SUBNET
&& strcmp(cfg->module_conf, "subnetcache iterator") != 0 && strcmp(cfg->module_conf, "subnetcache iterator") != 0
&& strcmp(cfg->module_conf, "respip subnetcache iterator") != 0 && strcmp(cfg->module_conf, "respip subnetcache iterator") != 0

View File

@ -97,10 +97,12 @@ void worker_sighandler(int ATTR_UNUSED(sig), void* ATTR_UNUSED(arg))
struct outbound_entry* worker_send_query( struct outbound_entry* worker_send_query(
struct query_info* ATTR_UNUSED(qinfo), uint16_t ATTR_UNUSED(flags), struct query_info* ATTR_UNUSED(qinfo), uint16_t ATTR_UNUSED(flags),
int ATTR_UNUSED(dnssec), int ATTR_UNUSED(want_dnssec), int ATTR_UNUSED(dnssec), int ATTR_UNUSED(want_dnssec),
int ATTR_UNUSED(nocaps), struct sockaddr_storage* ATTR_UNUSED(addr), int ATTR_UNUSED(nocaps), int ATTR_UNUSED(check_ratelimit),
struct sockaddr_storage* ATTR_UNUSED(addr),
socklen_t ATTR_UNUSED(addrlen), uint8_t* ATTR_UNUSED(zone), socklen_t ATTR_UNUSED(addrlen), uint8_t* ATTR_UNUSED(zone),
size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(tcp_upstream), int ATTR_UNUSED(ssl_upstream), size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(tcp_upstream), int ATTR_UNUSED(ssl_upstream),
char* ATTR_UNUSED(tls_auth_name), struct module_qstate* ATTR_UNUSED(q)) char* ATTR_UNUSED(tls_auth_name), struct module_qstate* ATTR_UNUSED(q),
int* ATTR_UNUSED(was_ratelimited))
{ {
log_assert(0); log_assert(0);
return 0; return 0;
@ -129,10 +131,12 @@ worker_alloc_cleanup(void* ATTR_UNUSED(arg))
struct outbound_entry* libworker_send_query( struct outbound_entry* libworker_send_query(
struct query_info* ATTR_UNUSED(qinfo), uint16_t ATTR_UNUSED(flags), struct query_info* ATTR_UNUSED(qinfo), uint16_t ATTR_UNUSED(flags),
int ATTR_UNUSED(dnssec), int ATTR_UNUSED(want_dnssec), int ATTR_UNUSED(dnssec), int ATTR_UNUSED(want_dnssec),
int ATTR_UNUSED(nocaps), struct sockaddr_storage* ATTR_UNUSED(addr), int ATTR_UNUSED(nocaps), int ATTR_UNUSED(check_ratelimit),
struct sockaddr_storage* ATTR_UNUSED(addr),
socklen_t ATTR_UNUSED(addrlen), uint8_t* ATTR_UNUSED(zone), socklen_t ATTR_UNUSED(addrlen), uint8_t* ATTR_UNUSED(zone),
size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(tcp_upstream), int ATTR_UNUSED(ssl_upstream), size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(tcp_upstream), int ATTR_UNUSED(ssl_upstream),
char* ATTR_UNUSED(tls_auth_name), struct module_qstate* ATTR_UNUSED(q)) char* ATTR_UNUSED(tls_auth_name), struct module_qstate* ATTR_UNUSED(q),
int* ATTR_UNUSED(was_ratelimited))
{ {
log_assert(0); log_assert(0);
return 0; return 0;

View File

@ -1187,12 +1187,13 @@ pending_tcp_query(struct serviced_query* sq, sldns_buffer* packet,
struct serviced_query* outnet_serviced_query(struct outside_network* outnet, struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
struct query_info* qinfo, uint16_t flags, int dnssec, struct query_info* qinfo, uint16_t flags, int dnssec,
int ATTR_UNUSED(want_dnssec), int ATTR_UNUSED(nocaps), int ATTR_UNUSED(want_dnssec), int ATTR_UNUSED(nocaps),
int ATTR_UNUSED(check_ratelimit),
int ATTR_UNUSED(tcp_upstream), int ATTR_UNUSED(ssl_upstream), int ATTR_UNUSED(tcp_upstream), int ATTR_UNUSED(ssl_upstream),
char* ATTR_UNUSED(tls_auth_name), struct sockaddr_storage* addr, char* ATTR_UNUSED(tls_auth_name), struct sockaddr_storage* addr,
socklen_t addrlen, uint8_t* zone, size_t zonelen, socklen_t addrlen, uint8_t* zone, size_t zonelen,
struct module_qstate* qstate, comm_point_callback_type* callback, struct module_qstate* qstate, comm_point_callback_type* callback,
void* callback_arg, sldns_buffer* ATTR_UNUSED(buff), void* callback_arg, sldns_buffer* ATTR_UNUSED(buff),
struct module_env* env) struct module_env* env, int* ATTR_UNUSED(was_ratelimited))
{ {
struct replay_runtime* runtime = (struct replay_runtime*)outnet->base; struct replay_runtime* runtime = (struct replay_runtime*)outnet->base;
struct fake_pending* pend = (struct fake_pending*)calloc(1, struct fake_pending* pend = (struct fake_pending*)calloc(1,
@ -1222,11 +1223,37 @@ struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
if(1) { if(1) {
struct edns_data edns; struct edns_data edns;
struct edns_string_addr* client_string_addr; struct edns_string_addr* client_string_addr;
struct edns_option* backed_up_opt_list =
qstate->edns_opts_back_out;
struct edns_option* per_upstream_opt_list = NULL;
/* If we have an already populated EDNS option list make a copy
* since we may now add upstream specific EDNS options. */
if(qstate->edns_opts_back_out) {
per_upstream_opt_list = edns_opt_copy_region(
qstate->edns_opts_back_out, qstate->region);
if(!per_upstream_opt_list) {
free(pend);
fatal_exit("out of memory");
}
qstate->edns_opts_back_out = per_upstream_opt_list;
}
if(!inplace_cb_query_call(env, qinfo, flags, addr, addrlen, if(!inplace_cb_query_call(env, qinfo, flags, addr, addrlen,
zone, zonelen, qstate, qstate->region)) { zone, zonelen, qstate, qstate->region)) {
free(pend); free(pend);
return NULL; return NULL;
} }
/* Restore the option list; we can explicitly use the copied
* one from now on. */
per_upstream_opt_list = qstate->edns_opts_back_out;
qstate->edns_opts_back_out = backed_up_opt_list;
if((client_string_addr = edns_string_addr_lookup(
&env->edns_strings->client_strings,
addr, addrlen))) {
edns_opt_list_append(&per_upstream_opt_list,
env->edns_strings->client_string_opcode,
client_string_addr->string_len,
client_string_addr->string, qstate->region);
}
/* add edns */ /* add edns */
edns.edns_present = 1; edns.edns_present = 1;
edns.ext_rcode = 0; edns.ext_rcode = 0;
@ -1236,16 +1263,8 @@ struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
if(dnssec) if(dnssec)
edns.bits = EDNS_DO; edns.bits = EDNS_DO;
edns.padding_block_size = 0; edns.padding_block_size = 0;
if((client_string_addr = edns_string_addr_lookup(
&env->edns_strings->client_strings,
addr, addrlen))) {
edns_opt_list_append(&qstate->edns_opts_back_out,
env->edns_strings->client_string_opcode,
client_string_addr->string_len,
client_string_addr->string, qstate->region);
}
edns.opt_list_in = NULL; edns.opt_list_in = NULL;
edns.opt_list_out = qstate->edns_opts_back_out; edns.opt_list_out = per_upstream_opt_list;
edns.opt_list_inplace_cb_out = NULL; edns.opt_list_inplace_cb_out = NULL;
attach_edns_record(pend->buffer, &edns); attach_edns_record(pend->buffer, &edns);
} }
@ -1424,6 +1443,11 @@ void pending_udp_timer_cb(void *ATTR_UNUSED(arg))
log_assert(0); log_assert(0);
} }
void serviced_timer_cb(void *ATTR_UNUSED(arg))
{
log_assert(0);
}
void pending_udp_timer_delay_cb(void *ATTR_UNUSED(arg)) void pending_udp_timer_delay_cb(void *ATTR_UNUSED(arg))
{ {
log_assert(0); log_assert(0);

View File

@ -582,10 +582,9 @@ do_service(char* addr, int port, char* key, char* cert)
{ {
SSL_CTX* sslctx = setup_ctx(key, cert); SSL_CTX* sslctx = setup_ctx(key, cert);
int fd = setup_fd(addr, port); int fd = setup_fd(addr, port);
int go = 1;
if(fd == -1) print_exit("could not setup sockets"); if(fd == -1) print_exit("could not setup sockets");
if(verb) {printf("petal start\n"); fflush(stdout);} if(verb) {printf("petal start\n"); fflush(stdout);}
while(go) { while(1) {
struct sockaddr_storage from; struct sockaddr_storage from;
socklen_t flen = (socklen_t)sizeof(from); socklen_t flen = (socklen_t)sizeof(from);
int s; int s;

View File

@ -0,0 +1,90 @@
; config options
server:
edns-client-string: 10.0.0.0/24 "abc d"
outbound-msg-retry: 1
stub-zone:
name: "edns-string-abc."
stub-addr: 10.0.0.3
stub-first: yes
forward-zone:
name: "."
forward-addr: 10.0.0.1
CONFIG_END
SCENARIO_BEGIN Test that upstream specific EDNS is attached once; uses string tag option
RANGE_BEGIN 0 1000
ADDRESS 10.0.0.3
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR SERVFAIL
SECTION QUESTION
edns-string-abc. IN A
ENTRY_END
RANGE_END
RANGE_BEGIN 0 1000
ADDRESS 10.0.0.1
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
edns-string-abc. IN A
SECTION ANSWER
edns-string-abc. IN A 10.20.30.40
SECTION ADDITIONAL
ENTRY_END
RANGE_END
STEP 10 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
edns-string-abc. IN A
ENTRY_END
; This will receive SERVFAIL and the next address will be queried
STEP 20 CHECK_OUT_QUERY ADDRESS 10.0.0.3
ENTRY_BEGIN
MATCH qname qtype opcode ednsdata
SECTION QUESTION
edns-string-abc. IN A
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
fd e9 ; Opcode 65001
00 05 ; Length 5
61 62 63 20 64 ; "abc d"
HEX_EDNSDATA_END
ENTRY_END
; This will receive the answer; makes sure that EDNS is attached once
STEP 22 CHECK_OUT_QUERY ADDRESS 10.0.0.1
ENTRY_BEGIN
MATCH qname qtype opcode ednsdata
SECTION QUESTION
edns-string-abc. IN A
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
fd e9 ; Opcode 65001
00 05 ; Length 5
61 62 63 20 64 ; "abc d"
HEX_EDNSDATA_END
ENTRY_END
STEP 30 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
edns-string-abc. IN A
SECTION ANSWER
edns-string-abc. IN A 10.20.30.40
ENTRY_END
SCENARIO_END

View File

@ -45,9 +45,32 @@ server:
local-data: "b.c.implicit. A 20.30.45.50" local-data: "b.c.implicit. A 20.30.45.50"
local-data: "c.c.implicit. A 20.30.44.50" local-data: "c.c.implicit. A 20.30.44.50"
; create implicit data in the ANY domain
; this should inherit the local_zone_type of the already configured
; zone 'refuse.top.' and not be transparent
local-data: "refuse.top. ANY TXT implicit_non_transparent"
stub-zone:
name: "refuse.top"
stub-addr: 1.2.3.4
CONFIG_END CONFIG_END
SCENARIO_BEGIN Test local data queries SCENARIO_BEGIN Test local data queries
RANGE_BEGIN 0 100
ADDRESS 1.2.3.4
; This entry should never be queried
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www.refuse.top. IN A
SECTION ANSWER
www.refuse.top. IN A 5.5.5.5
ENTRY_END
RANGE_END
; id.server. ; id.server.
STEP 1 QUERY STEP 1 QUERY
ENTRY_BEGIN ENTRY_BEGIN
@ -390,4 +413,35 @@ SECTION ANSWER
foo.null.top. IN AAAA ::0 foo.null.top. IN AAAA ::0
ENTRY_END ENTRY_END
; refuse zone for implicit local-data with CLASS != IN
STEP 64 QUERY
ENTRY_BEGIN
SECTION QUESTION
refuse.top. ANY TXT
ENTRY_END
STEP 65 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RA AA NOERROR
SECTION QUESTION
refuse.top. ANY TXT
SECTION ANSWER
refuse.top. ANY TXT implicit_non_transparent
ENTRY_END
; refuse zone for implicit local-data with CLASS != IN
STEP 66 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.refuse.top. ANY A
ENTRY_END
STEP 67 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RA RD AA REFUSED
SECTION QUESTION
www.refuse.top. ANY A
ENTRY_END
SCENARIO_END SCENARIO_END

174
testdata/nsid_bogus.rpl vendored Normal file
View File

@ -0,0 +1,174 @@
; 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"
target-fetch-policy: "0 0 0 0 0"
qname-minimisation: "no"
fake-sha1: yes
trust-anchor-signaling: no
minimal-responses: no
nsid: "ascii_hopsa kidee"
stub-zone:
name: "."
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
CONFIG_END
SCENARIO_BEGIN Test for NSID in SERVFAIL response due to DNSSEC bogus
; 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
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
com. IN NS
SECTION ANSWER
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.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
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
example.com. IN NS
SECTION ANSWER
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 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
; nodata for ns.example.com AAAA
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA NOERROR
SECTION QUESTION
ns.example.com. IN AAAA
SECTION ANSWER
SECTION ADDITIONAL
ENTRY_END
; response to query of interest
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. IN A 10.20.30.40
;good signature
;www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
;missing
www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2855 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4=
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 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
ENTRY_END
RANGE_END
STEP 1 QUERY
ENTRY_BEGIN
REPLY RD DO
SECTION QUESTION
www.example.com. IN A
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
00 03 ; Opcode NSID (3)
00 00 ; Length 0
HEX_EDNSDATA_END
ENTRY_END
; recursion happens here.
STEP 10 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA DO SERVFAIL
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
00 03 ; Opcode NSID (3)
00 0b ; Length 11
68 6F 70 73 61 20 ; "hopsa "
6B 69 64 65 65 ; "kidee"
HEX_EDNSDATA_END
ENTRY_END
SCENARIO_END

View File

@ -11,4 +11,4 @@ server:
stub-zone: stub-zone:
name: "example.com." name: "example.com."
stub-addr: "127.0.0.1@@TOPORT@" stub-addr: "127.0.0.1@@TOPORT@"
stub-no-cache: yes

View File

@ -9,9 +9,11 @@
import unbound import unbound
qname = "www.example.com" qname = "www.example.com"
qname2 = "www2.example.com"
qtype = unbound.RR_TYPE_A qtype = unbound.RR_TYPE_A
qclass = unbound.RR_CLASS_IN qclass = unbound.RR_CLASS_IN
def create_context(config_file="ub.lookup.conf", asyncflag=False): def create_context(config_file="ub.lookup.conf", asyncflag=False):
""" """
Create an unbound context to use for testing. Create an unbound context to use for testing.
@ -69,32 +71,6 @@ def test_async_resolve(ctx):
print("Failed async resolve with: {}".format(retval)) print("Failed async resolve with: {}".format(retval))
def test_ratelimit_fg_on(ctx):
"""
Test resolving a ratelimited domain with a foreground worker.
"""
ctx.set_option("ratelimit:", "1")
ctx.set_option("ratelimit-factor:", "0")
status, result = ctx.resolve(qname, qtype, qclass)
if status == 0 and result.was_ratelimited:
print("Ratelimit-fg-on: pass")
else:
print("Failed ratelimit-fg-on with: {}".format(status))
def test_ratelimit_fg_off(ctx):
"""
Test resolving a non-ratelimited domain with a foreground worker.
"""
status, result = ctx.resolve(qname, qtype, qclass)
if status == 0 and result.havedata:
print("Ratelimit-fg-off: {}".format(result.data.address_list))
else:
print("Failed ratelimit-fg-off with: {}".format(status))
def test_ratelimit_bg_on(ctx): def test_ratelimit_bg_on(ctx):
""" """
Test resolving a ratelimited domain with a background worker. Test resolving a ratelimited domain with a background worker.
@ -102,40 +78,32 @@ def test_ratelimit_bg_on(ctx):
""" """
ctx.set_option("ratelimit:", "1") ctx.set_option("ratelimit:", "1")
ctx.set_option("ratelimit-factor:", "0") ctx.set_option("ratelimit-factor:", "0")
cb_data = dict(done=False) total_runs = 6
retval, async_id = ctx.resolve_async(qname, cb_data, callback, qtype, qclass) success_threshold = 4 # 2/3*total_runs
while retval == 0 and not cb_data['done']: successes = 0
time.sleep(0.1) for i in range(total_runs):
retval = ctx.process() cb_data = dict(done=False)
cb_data2 = dict(done=False)
retval, async_id = ctx.resolve_async(qname, cb_data, callback, qtype, qclass)
retval, async_id = ctx.resolve_async(qname2, cb_data2, callback, qtype, qclass)
if cb_data.get('was_ratelimited'): while retval == 0 and not (cb_data['done'] and cb_data['done']):
time.sleep(0.1)
retval = ctx.process()
if bool(cb_data.get('was_ratelimited')) ^ bool(cb_data2.get('was_ratelimited')):
successes += 1
if successes >= success_threshold:
break
time.sleep(1)
if successes >= success_threshold:
print("Ratelimit-bg-on: pass") print("Ratelimit-bg-on: pass")
else: else:
print("Failed ratelimit-bg-on with: {}".format(status)) print("Failed ratelimit-bg-on")
def test_ratelimit_bg_off(ctx):
"""
Test resolving a non-ratelimited domain with a background worker.
"""
cb_data = dict(done=False)
retval, async_id = ctx.resolve_async(qname, cb_data, callback, qtype, qclass)
while retval == 0 and not cb_data['done']:
time.sleep(0.1)
retval = ctx.process()
if cb_data.get('data'):
print("Ratelimit-bg-off: {}".format(cb_data['data'].address_list))
else:
print("Failed ratelimit-bg-off with: {}".format(status))
test_resolve(create_context()) test_resolve(create_context())
test_async_resolve(create_context(asyncflag=True)) test_async_resolve(create_context(asyncflag=True))
test_ratelimit_fg_on(create_context())
test_ratelimit_fg_off(create_context())
test_ratelimit_bg_on(create_context(asyncflag=True)) test_ratelimit_bg_on(create_context(asyncflag=True))
test_ratelimit_bg_off(create_context(asyncflag=True))
sys.exit(0) sys.exit(0)

View File

@ -42,30 +42,12 @@ else
echo "Not OK (async resolve)" echo "Not OK (async resolve)"
exit 1 exit 1
fi fi
if grep "Ratelimit-fg-on: pass" outfile; then
:
else
echo "Not OK (ratelimit-fg-on)"
exit 1
fi
if grep "Ratelimit-fg-off: \[.\?10.20.30.40.\?\]" outfile; then
:
else
echo "Not OK (ratelimit-fg-off)"
exit 1
fi
if grep "Ratelimit-bg-on: pass" outfile; then if grep "Ratelimit-bg-on: pass" outfile; then
: :
else else
echo "Not OK (ratelimit-bg-on)" echo "Not OK (ratelimit-bg-on)"
exit 1 exit 1
fi fi
if grep "Ratelimit-bg-off: \[.\?10.20.30.40.\?\]" outfile; then
:
else
echo "Not OK (ratelimit-bg-off)"
exit 1
fi
echo "OK" echo "OK"

View File

@ -12,3 +12,12 @@ SECTION ANSWER
www IN A 10.20.30.40 www IN A 10.20.30.40
ENTRY_END ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
REPLY QR AA NOERROR
ADJUST copy_id
SECTION QUESTION
www2 IN A
SECTION ANSWER
www2 IN A 10.20.30.40
ENTRY_END

29
testdata/ratelimit.tdir/ratelimit.conf vendored Normal file
View File

@ -0,0 +1,29 @@
server:
verbosity: 5
# num-threads: 1
interface: 127.0.0.1
port: @PORT@
use-syslog: no
directory: .
pidfile: "unbound.pid"
chroot: ""
username: ""
do-not-query-localhost: no
ratelimit: 1
ratelimit-factor: 0
stub-zone:
name: "example.com."
stub-addr: "127.0.0.1@@TOPORT@"
stub-no-cache: yes
remote-control:
control-enable: yes
control-interface: 127.0.0.1
# control-interface: ::1
control-port: @CONTROL_PORT@
server-key-file: "unbound_server.key"
server-cert-file: "unbound_server.pem"
control-key-file: "unbound_control.key"
control-cert-file: "unbound_control.pem"

16
testdata/ratelimit.tdir/ratelimit.dsc vendored Normal file
View File

@ -0,0 +1,16 @@
BaseName: ratelimit
Version: 1.0
Description: Test ratelimit.
CreationDate: Sun Jan 30 00:40:00 CET 2022
Maintainer: Yorgos Thessalonikefs
Category:
Component:
CmdDepends:
Depends:
Help:
Pre: ratelimit.pre
Post: ratelimit.post
Test: ratelimit.test
AuxFiles:
Passed:
Failure:

14
testdata/ratelimit.tdir/ratelimit.post vendored Normal file
View File

@ -0,0 +1,14 @@
# #-- ratelimit.post --#
# source the master var file when it's there
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
# source the test var file when it's there
[ -f .tpkg.var.test ] && source .tpkg.var.test
#
# do your teardown here
. ../common.sh
kill_pid $STUB_PID
kill_pid $UNBOUND_PID
if test -f unbound.log; then
echo ">>> unbound log"
cat unbound.log
fi

33
testdata/ratelimit.tdir/ratelimit.pre vendored Normal file
View File

@ -0,0 +1,33 @@
# #-- ratelimit.pre--#
# source the master var file when it's there
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
# use .tpkg.var.test for in test variable passing
[ -f .tpkg.var.test ] && source .tpkg.var.test
PRE="../.."
. ../common.sh
get_random_port 2
UNBOUND_PORT=$RND_PORT
STUB_PORT=$(($RND_PORT + 1))
CONTROL_PORT=$(($RND_PORT + 2))
echo "UNBOUND_PORT=$UNBOUND_PORT" >> .tpkg.var.test
echo "STUB_PORT=$STUB_PORT" >> .tpkg.var.test
echo "CONTROL_PORT=$CONTROL_PORT" >> .tpkg.var.test
# start ldns-testns
get_ldns_testns
$LDNS_TESTNS -v -p $STUB_PORT ratelimit.testns >stub.log 2>&1 &
STUB_PID=$!
echo "STUB_PID=$STUB_PID" >> .tpkg.var.test
# make config file
sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@TOPORT\@/'$STUB_PORT'/' -e 's/@CONTROL_PORT\@/'$CONTROL_PORT'/' < ratelimit.conf > ub.conf
# start unbound in the background
$PRE/unbound -d -c ub.conf >unbound.log 2>&1 &
UNBOUND_PID=$!
echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test
wait_ldns_testns_up stub.log
wait_unbound_up unbound.log
cat .tpkg.var.test

183
testdata/ratelimit.tdir/ratelimit.test vendored Normal file
View File

@ -0,0 +1,183 @@
# #-- ratelimit.test --#
# source the master var file when it's there
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
# use .tpkg.var.test for in test variable passing
[ -f .tpkg.var.test ] && source .tpkg.var.test
PRE="../.."
. ../common.sh
get_make
(cd $PRE; $MAKE streamtcp)
# These tests rely on second time precision. To combat false negatives the
# tests run multiple times and we allow 1/3 of the runs to fail.
total_runs=6
success_threshold=4 # 2/3*total_runs
successes=0
echo "> Three parallel queries"
# For this test we send three parallel queries and we expect only one of them
# to be allowed through each second.
for i in $(seq 1 $total_runs); do
$PRE/streamtcp -na -f 127.0.0.1@$UNBOUND_PORT www1.example.com. A IN www2.example.com. A IN www3.example.com. A IN >outfile 2>&1
if test "$?" -ne 0; then
echo "exit status not OK"
echo "> cat logfiles"
cat outfile
cat unbound.log
echo "Not OK"
exit 1
fi
cat outfile
if test `grep "rcode: SERVFAIL" outfile | wc -l` -eq 2; then
((successes++))
fi
# We don't have to wait for all the runs to complete if we know
# we passed the threshold.
if test $successes -ge $success_threshold; then
break
fi
sleep 1
done
if test $successes -ge $success_threshold; then
echo "Number of ratelimited queries OK for three parallel queries"
else
echo "Number of ratelimited queries not OK for three parallel queries"
echo "> cat logfiles"
cat outfile
cat unbound.log
echo "Number of ratelimited queries not OK for three parallel queries"
exit 1
fi
echo "> Activating ratelimit-factor"
echo "$PRE/unbound-control -c ub.conf set_option ratelimit-factor: 3"
$PRE/unbound-control -c ub.conf set_option ratelimit-factor: 3
if test $? -ne 0; then
echo "wrong exit value after success"
exit 1
fi
slipped_through=0
echo "> Three parallel queries with ratelimit-factor"
# For this test we send three parallel queries and we expect at least two of
# them to be allowed through at a given second; one from the ratelimit itself
# and one from the ratelimit-factor.
for i in {1..10}; do
$PRE/streamtcp -na -f 127.0.0.1@$UNBOUND_PORT www1.example.com. A IN www2.example.com. A IN www3.example.com. A IN >outfile 2>&1
if test "$?" -ne 0; then
echo "exit status not OK"
echo "> cat logfiles"
cat outfile
cat unbound.log
echo "Not OK"
exit 1
fi
cat outfile
if test `grep "rcode: SERVFAIL" outfile | wc -l` -lt 2; then
slipped_through=1
break
fi
sleep 2
done
if test $slipped_through -eq 0; then
echo "ratelimit-factor did not work"
echo "> cat logfiles"
cat outfile
cat unbound.log
echo "ratelimit-factor did not work"
exit 1
fi
echo "ratelimit-factor OK"
echo "> Disabling ratelimit-factor"
echo "$PRE/unbound-control -c ub.conf set_option ratelimit-factor: 0"
$PRE/unbound-control -c ub.conf set_option ratelimit-factor: 0
if test $? -ne 0; then
echo "wrong exit value after success"
exit 1
fi
echo "> Activating ratelimit-backoff"
echo "$PRE/unbound-control -c ub.conf set_option ratelimit-backoff: yes"
$PRE/unbound-control -c ub.conf set_option ratelimit-backoff: yes
if test $? -ne 0; then
echo "wrong exit value after success"
exit 1
fi
successes=0
echo "> Three parallel queries with backoff"
# For this test we send three parallel queries. The ratelimit should be reached
# for that second. Then for the next second we again send three parallel
# queries and we expect none of them to be allowed through because of the
# backoff logic that keeps rolling the RATE_WINDOW based on demand.
for i in $(seq 1 $total_runs); do
$PRE/streamtcp -na -f 127.0.0.1@$UNBOUND_PORT www1.example.com. A IN www2.example.com. A IN www3.example.com. A IN >outfile 2>&1
if test "$?" -ne 0; then
echo "exit status not OK"
echo "> cat logfiles"
cat outfile
cat unbound.log
echo "Not OK"
exit 1
fi
sleep 1 # Limit is reached; it should also be active for the next second
$PRE/streamtcp -na -f 127.0.0.1@$UNBOUND_PORT www1.example.com. A IN www2.example.com. A IN www3.example.com. A IN >outfile 2>&1
if test "$?" -ne 0; then
echo "exit status not OK"
echo "> cat logfiles"
cat outfile
cat unbound.log
echo "Not OK"
exit 1
fi
cat outfile
if test `grep "rcode: SERVFAIL" outfile | wc -l` -eq 3; then
((successes++))
fi
# We don't have to wait for all the runs to complete if we know
# we passed the threshold.
if test $successes -ge $success_threshold; then
break
fi
done
if test $successes -ge $success_threshold; then
echo "three parallel queries with backoff OK"
else
echo "Number of ratelimited queries not OK for three parallel queries with backoff"
echo "> cat logfiles"
cat outfile
cat unbound.log
echo "Number of ratelimited queries not OK for three parallel queries with backoff"
exit 1
fi
echo "> Three parallel queries after backoff RATE_WINDOW"
sleep 3 # Make sure the RATE_WINDOW is renewed
# For this test we make three parallel queries after the RATE_WINDOW has passed
# without any new demand and we expect at least one query to pass through. This
# is to check that the backoff logic does not insist on past (outside of
# RATE_WINDOW) limits.
$PRE/streamtcp -na -f 127.0.0.1@$UNBOUND_PORT www1.example.com. A IN www2.example.com. A IN www3.example.com. A IN >outfile 2>&1
if test "$?" -ne 0; then
echo "exit status not OK"
echo "> cat logfiles"
cat outfile
cat unbound.log
echo "Not OK"
exit 1
fi
cat outfile
if test `grep "rcode: NOERROR" outfile | wc -l` -gt 0; then
echo "Number of ratelimited queries OK for three parallel queries after backoff RATE_WINDOW"
else
echo "Number of ratelimited queries not OK for three parallel queries after backoff RATE_WINDOW"
echo "> cat logfiles"
cat outfile
cat unbound.log
echo "Number of ratelimited queries not OK for three parallel queries after backoff RATE_WINDOW"
exit 1
fi
exit 0

View File

@ -0,0 +1,13 @@
; nameserver test file
$ORIGIN example.com.
$TTL 3600
ENTRY_BEGIN
MATCH opcode qtype
REPLY QR AA NOERROR
ADJUST copy_id copy_query
SECTION QUESTION
wild IN A
SECTION ANSWER
wild IN A 10.20.30.40
ENTRY_END

View File

@ -0,0 +1,39 @@
-----BEGIN RSA PRIVATE KEY-----
MIIG4gIBAAKCAYEAstEp+Pyh8XGrtZ77A4FhYjvbeB3dMa7Q2rGWxobzlA9przhA
1aChAvUtCOAuM+rB6NTNB8YWfZJbQHawyMNpmC77cg6vXLYCGUQHZyAqidN049RJ
F5T7j4N8Vniv17LiRdr0S6swy4PRvEnIPPV43EQHZqC5jVvHsKkhIfmBF/Dj5TXR
ypeawWV/m5jeU6/4HRYMfytBZdO1mPXuWLh0lgbQ4SCbgrOUVD3rniMk1yZIbQOm
vlDHYqekjDb/vOW2KxUQLG04aZMJ1mWfdbwG0CKQkSjISEDZ1l76vhM6mTM0fwXb
IvyFZ9yPPCle1mF5aSlxS2cmGuGVSRQaw8XF9fe3a9ACJJTr33HdSpyaZkKRAUzL
cKqLCl323daKv3NwwAT03Tj4iQM416ASMoiyfFa/2GWTKQVjddu8Crar7tGaf5xr
lig4DBmrBvdYA3njy72/RD71hLwmlRoCGU7dRuDr9O6KASUm1Ri91ONZ/qdjMvov
15l2vj4GV+KXR00dAgMBAAECggGAHepIL1N0dEQkCdpy+/8lH54L9WhpnOo2HqAf
LU9eaKK7d4jdr9+TkD8cLaPzltPrZNxVALvu/0sA4SP6J1wpyj/x6P7z73qzly5+
Xo5PD4fEwmi9YaiW/UduAblnEZrnp/AddptJKoL/D5T4XtpiQddPtael4zQ7kB57
YIexRSQTvEDovA/o3/nvA0TrzOxfgd4ycQP3iOWGN/TMzyLsvjydrUwbOB567iz9
whL3Etdgvnwh5Sz2blbFfH+nAR8ctvFFz+osPvuIVR21VMEI6wm7kTpSNnQ6sh/c
lrLb/bTADn4g7z/LpIZJ+MrLvyEcoqValrLYeFBhM9CV8woPxvkO2P3pU47HVGax
tC7GV6a/kt5RoKFd/TNdiA3OC7NGZtaeXv9VkPf4fVwBtSO9d5ZZXTGEynDD/rUQ
U4KFJe6OD23APjse08HiiKqTPhsOneOONU67iqoaTdIkT2R4EdlkVEDpXVtWb+G9
Q+IqYzVljlzuyHrhWXLJw/FMa2aBAoHBAOnZbi4gGpH+P6886WDWVgIlTccuXoyc
Mg9QQYk9UDeXxL0AizR5bZy49Sduegz9vkHpAiZARQsUnizHjZ8YlRcrmn4t6tx3
ahTIKAjdprnxJfYINM580j8CGbXvX5LhIlm3O267D0Op+co3+7Ujy+cjsIuFQrP+
1MqMgXSeBjzC1APivmps7HeFE+4w0k2PfN5wSMDNCzLo99PZuUG5XZ93OVOS5dpN
b+WskdcD8NOoJy/X/5A08veEI/jYO/DyqQKBwQDDwUQCOWf41ecvJLtBHKmEnHDz
ftzHino9DRKG8a9XaN4rmetnoWEaM2vHGX3pf3mwH+dAe8vJdAQueDhBKYeEpm6C
TYNOpou1+Zs5s99BilCTNYo8fkMOAyqwRwmz9zgHS6QxXuPwsghKefLJGt6o6RFF
tfWVTfLlYJ+I3GQe3ySsk3wjVz4oUTKiyiq5+KzD+HhEkS7u+RQ7Z0ZI2xd2cF8Y
aN2hjKDpcOiFf3CDoqka5D1qMNLgIHO52AHww1UCgcA1h7o7AMpURRka6hyaODY0
A4oMYEbwdQjYjIyT998W+rzkbu1us6UtzQEBZ760npkgyU/epbOoV63lnkCC/MOU
LD0PST+L/CHiY/cWIHb79YG1EifUZKpUFg0Aoq0EGFkepF0MefGCkbRGYA5UZr9U
R80wAu9D+L+JJiS0J0BSRF74DL196zUuHt5zFeXuLzxsRtPAnq9DliS08BACRYZy
7H3I7cWD9Vn5/0jbKWHFcaaWwyETR6uekTcSzZzbCRECgcBeoE3/xUA9SSk34Mmj
7/cB4522Ft0imA3+9RK/qJTZ7Bd5fC4PKjOGNtUiqW/0L2rjeIiQ40bfWvWqgPKw
jSK1PL6uvkl6+4cNsFsYyZpiVDoe7wKju2UuoNlB3RUTqa2r2STFuNj2wRjA57I1
BIgdnox65jqQsd14g/yaa+75/WP9CE45xzKEyrtvdcqxm0Pod3OrsYK+gikFjiar
kT0GQ8u0QPzh2tjt/2ZnIfOBrl+QYERP0MofDZDjhUdq2wECgcB0Lu841+yP5cdR
qbJhXO4zJNh7oWNcJlOuQp3ZMNFrA1oHpe9pmLukiROOy01k9WxIMQDzU5GSqRv3
VLkYOIcbhJ3kClKAcM3j95SkKbU2H5/RENb3Ck52xtl4pNU1x/3PnVFZfDVuuHO9
MZ9YBcIeK98MyP2jr5JtFKnOyPE7xKq0IHIhXadpbc2wjje5FtZ1cUtMyEECCXNa
C1TpXebHGyXGpY9WdWXhjdE/1jPvfS+uO5WyuDpYPr339gsdq1g=
-----END RSA PRIVATE KEY-----

View File

@ -0,0 +1,22 @@
-----BEGIN CERTIFICATE-----
MIIDszCCAhsCFGD5193whHQ2bVdzbaQfdf1gc4SkMA0GCSqGSIb3DQEBCwUAMBIx
EDAOBgNVBAMMB3VuYm91bmQwHhcNMjAwNzA4MTMzMjMwWhcNNDAwMzI1MTMzMjMw
WjAaMRgwFgYDVQQDDA91bmJvdW5kLWNvbnRyb2wwggGiMA0GCSqGSIb3DQEBAQUA
A4IBjwAwggGKAoIBgQCy0Sn4/KHxcau1nvsDgWFiO9t4Hd0xrtDasZbGhvOUD2mv
OEDVoKEC9S0I4C4z6sHo1M0HxhZ9kltAdrDIw2mYLvtyDq9ctgIZRAdnICqJ03Tj
1EkXlPuPg3xWeK/XsuJF2vRLqzDLg9G8Scg89XjcRAdmoLmNW8ewqSEh+YEX8OPl
NdHKl5rBZX+bmN5Tr/gdFgx/K0Fl07WY9e5YuHSWBtDhIJuCs5RUPeueIyTXJkht
A6a+UMdip6SMNv+85bYrFRAsbThpkwnWZZ91vAbQIpCRKMhIQNnWXvq+EzqZMzR/
Bdsi/IVn3I88KV7WYXlpKXFLZyYa4ZVJFBrDxcX197dr0AIklOvfcd1KnJpmQpEB
TMtwqosKXfbd1oq/c3DABPTdOPiJAzjXoBIyiLJ8Vr/YZZMpBWN127wKtqvu0Zp/
nGuWKDgMGasG91gDeePLvb9EPvWEvCaVGgIZTt1G4Ov07ooBJSbVGL3U41n+p2My
+i/XmXa+PgZX4pdHTR0CAwEAATANBgkqhkiG9w0BAQsFAAOCAYEAd++Wen6l8Ifj
4h3p/y16PhSsWJWuJ4wdNYy3/GM84S26wGjzlEEwiW76HpH6VJzPOiBAeWnFKE83
hFyetEIxgJeIPbcs9ZP/Uoh8GZH9tRISBSN9Hgk2Slr9llo4t1H0g/XTgA5HqMQU
9YydlBh43G7Vw3FVwh09OM6poNOGQKNc/tq2/QdKeUMtyBbLWpRmjH5XcCT35fbn
ZiVOUldqSHD4kKrFO4nJYXZyipRbcXybsLiX9GP0GLemc3IgIvOXyJ2RPp06o/SJ
pzlMlkcAfLJaSuEW57xRakhuNK7m051TKKzJzIEX+NFYOVdafFHS8VwGrYsdrFvD
72tMfu+Fu55y3awdWWGc6YlaGogZiuMnJkvQphwgn+5qE/7CGEckoKEsH601rqIZ
muaIc85+nEcHJeijd/ZlBN9zeltjFoMuqTUENgmv8+tUAdVm/UMY9Vjme6b43ydP
uv6DS02+k9z8toxXworLiPr94BGaiGV1NxgwZKLZigYJt/Fi2Qte
-----END CERTIFICATE-----

View File

@ -0,0 +1,39 @@
-----BEGIN RSA PRIVATE KEY-----
MIIG5AIBAAKCAYEAvjSVSN2QMXudpzukdLCqgg/IOhCX8KYkD0FFFfWcQjgKq5wI
0x41iG32a6wbGanre4IX7VxaSPu9kkHfnGgynCk5nwDRedE/FLFhAU78PoT0+Nqq
GRS7XVQ24vLmIz9Hqc2Ozx1um1BXBTmIT0UfN2e22I0LWQ6a3seZlEDRj45gnk7Z
uh9MDgotaBdm+v1JAbupSf6Zis4VEH3JNdvVGE3O1DHEIeuuz/3BDhpf6WBDH+8K
WaBe1ca4TZHr9ThL2gEMEfAQl0wXDwRWRoi3NjNMH+mw0L1rjwThI5GXqNIee7o5
FzUReSXZuTdFMyGe3Owcx+XoYnwi6cplSNoGsDBu4B9bKKglR9YleJVw4L4Xi8xP
q6O9UPj4+nypHk/DOoC7DIM3ufN0yxPBsFo5TVowxfhdjZXJbbftd2TZv7AH8+XL
A5UoZgRzXgzECelXSCTBFlMTnT48LfA9pMLydyjAz2UdPHs5Iv+TK5nnI+aJoeaP
7kFZSngxdy1+A/bNAgMBAAECggGBALpTOIqQwVg4CFBylL/a8K1IWJTI/I65sklf
XxYL7G7SB2HlEJ//z+E+F0+S4Vlao1vyLQ5QkgE82pAUB8FoMWvY1qF0Y8A5wtm6
iZSGk4OLK488ZbT8Ii9i+AGKgPe2XbVxsJwj8N4k7Zooqec9hz73Up8ATEWJkRz7
2u7oMGG4z91E0PULA64dOi3l/vOQe5w/Aa+CwVbAWtI05o7kMvQEBMDJn6C7CByo
MB5op9wueJMnz7PM7hns+U7Dy6oE4ljuolJUy51bDzFWwoM54cRoQqLFNHd8JVQj
WxldCkbfF43iyprlsEcUrTyUjtdA+ZeiG39vg/mtdmgNpGmdupHJZQvSuG8IcVlz
O+eMSeQS1QXPD6Ik8UK4SU0h+zOl8xIWtRrsxQuh4fnTN40udm/YUWl/6gOebsBI
IrVLlKGqJSfB3tMjpCRqdTzJ0dA9keVpkqm2ugZkxEf1+/efq/rFIQ2pUBLCqNTN
qpNqruK8y8FphP30I2uI4Ej2UIB8AQKBwQDd2Yptj2FyDyaXCycsyde0wYkNyzGU
dRnzdibfHnMZwjgTjwAwgIUBVIS8H0/z7ZJQKN7osJfddMrtjJtYYUk9g/dCpHXs
bNh2QSoWah3FdzNGuWd0iRf9+LFxhjAAMo/FS8zFJAJKrFsBdCGTfFUMdsLC0bjr
YjiWBuvV72uKf8XIZX5KIZruKdWBBcWukcb21R1UDyFYyXRBsly5XHaIYKZql3km
7pV7MKWO0IYgHbHIqGUqPQlzZ/lkunS1jKECgcEA23wHffD6Ou9/x3okPx2AWpTr
gh8rgqbyo6hQkBW5Y90Wz824cqaYebZDaBR/xlVx/YwjKkohv8Bde2lpH/ZxRZ1Z
5Sk2s6GJ/vU0L9RsJZgCgj4L6Coal1NMxuZtCXAlnOpiCdxSZgfqbshbTVz30KsG
ZJG361Cua1ScdAHxlZBxT52/1Sm0zRC2hnxL7h4qo7Idmtzs40LAJvYOKekR0pPN
oWeJfra7vgx/jVNvMFWoOoSLpidVO4g+ot4ery6tAoHAdW3rCic1C2zdnmH28Iw+
s50l8Lk3mz+I5wgJd1zkzCO0DxZIoWPGA3g7cmCYr6N3KRsZMs4W9NAXgjpFGDkW
zYsG3K21BdpvkdjYcFjnPVjlOXB2RIc0vehf9Jl02wXoeCSxVUDEPcaRvWk9RJYx
ZpGOchUU7vNkxHURbIJ4yCzuAi9G8/Jp0dsu+kaV5tufF5SjG5WOrzKjaQsCbdN1
oqaWMCHRrTvov/Z2C+xwsptFOdN5CSyZzg6hQiI4GMlBAoHAXyb6KINcOEi0YMp3
BFXJ23tMTnEs78tozcKeipigcsbaqORK3omS+NEnj+uzKUzJyl4CsMbKstK2tFYS
mSTCHqgE3PBtIpsZtEqhgUraR8IK9GPpzZDTTl9ynZgwFTNlWw3RyuyVXF56J+T8
kCGJ3hEHCHqT/ZRQyX85BKIDFhA0z4tYKxWVqIFiYBNq56R0X9tMMmMs36mEnF93
7Ht6mowxTZQRa7nU0qOgeKh/P7ki4Zus3y+WJ+T9IqahLtlRAoHBAIhqMrcxSAB8
RpB9jukJlAnidw2jCMPgrFE8tP0khhVvGrXMldxAUsMKntDIo8dGCnG1KTcWDI0O
jepvSPHSsxVLFugL79h0eVIS5z4huW48i9xgU8VlHdgAcgEPIAOFcOw2BCu/s0Vp
O+MM/EyUOdo3NsibB3qc/GJI6iNBYS7AljYEVo6rXo5V/MZvZUF4vClen6Obzsre
MTTb+4sJjfqleWuvr1XNMeu2mBfXBQkWGZP1byBK0MvD/aQ2PWq92A==
-----END RSA PRIVATE KEY-----

View File

@ -0,0 +1,22 @@
-----BEGIN CERTIFICATE-----
MIIDqzCCAhMCFBHWXeQ6ZIa9QcQbXLFfC6tj+KA+MA0GCSqGSIb3DQEBCwUAMBIx
EDAOBgNVBAMMB3VuYm91bmQwHhcNMjAwNzA4MTMzMjI5WhcNNDAwMzI1MTMzMjI5
WjASMRAwDgYDVQQDDAd1bmJvdW5kMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIB
igKCAYEAvjSVSN2QMXudpzukdLCqgg/IOhCX8KYkD0FFFfWcQjgKq5wI0x41iG32
a6wbGanre4IX7VxaSPu9kkHfnGgynCk5nwDRedE/FLFhAU78PoT0+NqqGRS7XVQ2
4vLmIz9Hqc2Ozx1um1BXBTmIT0UfN2e22I0LWQ6a3seZlEDRj45gnk7Zuh9MDgot
aBdm+v1JAbupSf6Zis4VEH3JNdvVGE3O1DHEIeuuz/3BDhpf6WBDH+8KWaBe1ca4
TZHr9ThL2gEMEfAQl0wXDwRWRoi3NjNMH+mw0L1rjwThI5GXqNIee7o5FzUReSXZ
uTdFMyGe3Owcx+XoYnwi6cplSNoGsDBu4B9bKKglR9YleJVw4L4Xi8xPq6O9UPj4
+nypHk/DOoC7DIM3ufN0yxPBsFo5TVowxfhdjZXJbbftd2TZv7AH8+XLA5UoZgRz
XgzECelXSCTBFlMTnT48LfA9pMLydyjAz2UdPHs5Iv+TK5nnI+aJoeaP7kFZSngx
dy1+A/bNAgMBAAEwDQYJKoZIhvcNAQELBQADggGBABunf93MKaCUHiZgnoOTinsW
84/EgInrgtKzAyH+BhnKkJOhhR0kkIAx5d9BpDlaSiRTACFon9moWCgDIIsK/Ar7
JE0Kln9cV//wiiNoFU0O4mnzyGUIMvlaEX6QHMJJQYvL05+w/3AAcf5XmMJtR5ca
fJ8FqvGC34b2WxX9lTQoyT52sRt+1KnQikiMEnEyAdKktMG+MwKsFDdOwDXyZhZg
XZhRrfX3/NVJolqB6EahjWIGXDeKuSSKZVtCyib6LskyeMzN5lcRfvubKDdlqFVF
qlD7rHBsKhQUWK/IO64mGf7y/de+CgHtED5vDvr/p2uj/9sABATfbrOQR3W/Of25
sLBj4OEfrJ7lX8hQgFaxkMI3x6VFT3W8dTCp7xnQgb6bgROWB5fNEZ9jk/gjSRmD
yIU+r0UbKe5kBk/CmZVFXL2TyJ92V5NYEQh8V4DGy19qZ6u/XKYyNJL4ocs35GGe
CA8SBuyrmdhx38h1RHErR2Skzadi1S7MwGf1y431fQ==
-----END CERTIFICATE-----

View File

@ -175,11 +175,11 @@ REPLY QR RD RA AD DO NXDOMAIN
SECTION QUESTION SECTION QUESTION
root-key-sentinel-not-ta-20326. IN A root-key-sentinel-not-ta-20326. IN A
SECTION AUTHORITY SECTION AUTHORITY
. 86400 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018042300 1800 900 604800 86400
. 86400 IN RRSIG SOA 8 0 86400 20180506050000 20180423040000 39570 . LboVfcSRUSuBcZPpkkOO1N6KpGO6DBzOGL6UtSVUssycPzGIZctcIM0s Kb71iBf3rxFjNVlgCuNFb74WpCyRQ2coB2uUQXVA81A+P4Qb62/s3Nr2 pRGxayA1Y0Uq2M4CRkh3bjgn/cEcEFSWTl+xDVjZO8hX98JdQjYmrVui 4zEQhsMM03sqkmjkH88owibWK7HDl6O0n6Imer2hCsVTlFv7PSrBHlXP KntkIMDtbGHZW/BkKnA6P1jfAVfgXr70bRVaDRddLqJp3EX6EuR83osg 8q46170NgCMCKK3ePItJYF16SEADFKdOQs19CMTXAN7M1p4cnGk2yRG/ 68BmCg==
. 86400 IN NSEC aaa. NS SOA RRSIG NSEC DNSKEY . 86400 IN NSEC aaa. NS SOA RRSIG NSEC DNSKEY
. 86400 IN RRSIG NSEC 8 0 86400 20180506050000 20180423040000 39570 . E1FeP4/GvcPksKXgas9pslduWU6+cqqSoJpgtCeymd6t7MORbnsQJdUo rjqbRtxvOOnv5g4uVZdv0krSc/eqw8HWEiCW0oZWYLcz+h8eI4htt4uv 8LciVgQn3Aspic2b8uWdPTJUPuc94esn5AJZDMK9VOTwZD2UVqbv/k9U 4LG0o56yRQshYTG2hiutFXLYmzFe2YmKct6G7W50O7s5hwxTqqRwv9av 1Q3UZUj/ZARNt9z53pygJsDPDX+L2q4lowtiHJCRPjijm8K3Bwb8uFsG 3YB20K9d3krack9c6gAMJzpgeuFQ/b2HxiZMJPvJ3tHqIhDn0U5qoZdT Xq0WTw== . 86400 IN RRSIG NSEC 8 0 86400 20180506050000 20180423040000 39570 . E1FeP4/GvcPksKXgas9pslduWU6+cqqSoJpgtCeymd6t7MORbnsQJdUo rjqbRtxvOOnv5g4uVZdv0krSc/eqw8HWEiCW0oZWYLcz+h8eI4htt4uv 8LciVgQn3Aspic2b8uWdPTJUPuc94esn5AJZDMK9VOTwZD2UVqbv/k9U 4LG0o56yRQshYTG2hiutFXLYmzFe2YmKct6G7W50O7s5hwxTqqRwv9av 1Q3UZUj/ZARNt9z53pygJsDPDX+L2q4lowtiHJCRPjijm8K3Bwb8uFsG 3YB20K9d3krack9c6gAMJzpgeuFQ/b2HxiZMJPvJ3tHqIhDn0U5qoZdT Xq0WTw==
room. 86400 IN NSEC rs. NS DS RRSIG NSEC room. 86400 IN NSEC rs. NS DS RRSIG NSEC
room. 86400 IN RRSIG NSEC 8 1 86400 20180506050000 20180423040000 39570 . Fmhf8s0yVixynVdO6VWLEctcvb7+3UK9gu+9BhUPBS0SNedhMwfyiYaR MzWU9P99gVYUT1G/vXRqbAabtD3Ccnt/ydUBguZq3pV5GL+7czeEbZ5z 8/LlS+wyw2OTe4DOKzBZ7oZAA/r/Tz2bhVA6kNyIKFXAmBXuh7I5Ty7H elbIWh7Lq7QjZwN9LL4M1kSNePH2cmS3Lu/scRf3m3fN/70sgoYzKNB7 +Hbi/YjXBbRIcj7tHA6iMoZLGPXRMJdb6NqJNIaDIDtOA95cFa4oRx2P usBW9lpXG0YY+KDm1J6UjxUP7TIn0yXt+c0vy2cz7zu++ZEkdU29WtBG dUQEaA== room. 86400 IN RRSIG NSEC 8 1 86400 20180506050000 20180423040000 39570 . Fmhf8s0yVixynVdO6VWLEctcvb7+3UK9gu+9BhUPBS0SNedhMwfyiYaR MzWU9P99gVYUT1G/vXRqbAabtD3Ccnt/ydUBguZq3pV5GL+7czeEbZ5z 8/LlS+wyw2OTe4DOKzBZ7oZAA/r/Tz2bhVA6kNyIKFXAmBXuh7I5Ty7H elbIWh7Lq7QjZwN9LL4M1kSNePH2cmS3Lu/scRf3m3fN/70sgoYzKNB7 +Hbi/YjXBbRIcj7tHA6iMoZLGPXRMJdb6NqJNIaDIDtOA95cFa4oRx2P usBW9lpXG0YY+KDm1J6UjxUP7TIn0yXt+c0vy2cz7zu++ZEkdU29WtBG dUQEaA==
. 86400 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2018042300 1800 900 604800 86400
. 86400 IN RRSIG SOA 8 0 86400 20180506050000 20180423040000 39570 . LboVfcSRUSuBcZPpkkOO1N6KpGO6DBzOGL6UtSVUssycPzGIZctcIM0s Kb71iBf3rxFjNVlgCuNFb74WpCyRQ2coB2uUQXVA81A+P4Qb62/s3Nr2 pRGxayA1Y0Uq2M4CRkh3bjgn/cEcEFSWTl+xDVjZO8hX98JdQjYmrVui 4zEQhsMM03sqkmjkH88owibWK7HDl6O0n6Imer2hCsVTlFv7PSrBHlXP KntkIMDtbGHZW/BkKnA6P1jfAVfgXr70bRVaDRddLqJp3EX6EuR83osg 8q46170NgCMCKK3ePItJYF16SEADFKdOQs19CMTXAN7M1p4cnGk2yRG/ 68BmCg==
ENTRY_END ENTRY_END
SCENARIO_END SCENARIO_END

View File

@ -348,7 +348,7 @@ ENTRY_END
STEP 11 CHECK_ANSWER STEP 11 CHECK_ANSWER
ENTRY_BEGIN ENTRY_BEGIN
MATCH all MATCH all
REPLY QR RD RA NXDOMAIN REPLY QR AA RD RA NXDOMAIN
SECTION QUESTION SECTION QUESTION
gotham.aa. IN A gotham.aa. IN A
SECTION ANSWER SECTION ANSWER

View File

@ -348,7 +348,7 @@ ENTRY_END
STEP 11 CHECK_ANSWER STEP 11 CHECK_ANSWER
ENTRY_BEGIN ENTRY_BEGIN
MATCH all MATCH all
REPLY QR RD RA NXDOMAIN REPLY QR AA RD RA NXDOMAIN
SECTION QUESTION SECTION QUESTION
gotham.aa. IN A gotham.aa. IN A
SECTION ANSWER SECTION ANSWER

254
testdata/rpz_signal_nxdomain_ra.rpl vendored Normal file
View File

@ -0,0 +1,254 @@
; config options
server:
module-config: "respip validator iterator"
target-fetch-policy: "0 0 0 0 0"
qname-minimisation: no
access-control: 192.0.0.0/8 allow
rpz:
name: "rpz.example.com."
rpz-signal-nxdomain-ra: yes
zonefile:
TEMPFILE_NAME rpz.example.com
TEMPFILE_CONTENTS rpz.example.com
$ORIGIN example.com.
rpz 3600 IN SOA ns1.rpz.example.com. hostmaster.rpz.example.com. (
1379078166 28800 7200 604800 7200 )
3600 IN NS ns1.rpz.example.com.
3600 IN NS ns2.rpz.example.com.
$ORIGIN rpz.example.com.
a.a CNAME .
b.a CNAME .
ns1.a.rpz-nsdname CNAME .
24.0.0.0.192.rpz-nsip CNAME .
24.0.3.0.192.rpz-client-ip CNAME .
TEMPFILE_END
stub-zone:
name: "a."
stub-addr: 10.20.30.40
CONFIG_END
SCENARIO_BEGIN Test RPZ qname trigger and signal NXDOMAIN with unset RA.
RANGE_BEGIN 0 100
ADDRESS 10.20.30.40
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
a. IN NS
SECTION ANSWER
a. IN NS ns.a.
SECTION ADDITIONAL
ns.a IN A 10.20.30.40
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
a.a. IN TXT
SECTION ANSWER
a.a. IN TXT "upstream txt rr a.a."
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
b.a. IN TXT
SECTION ANSWER
b.a. IN TXT "upstream txt rr b.a."
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
c.a. IN TXT
SECTION ANSWER
c.a. IN CNAME b.a
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
d.a. IN NS
SECTION ANSWER
SECTION AUTHORITY
d.a. IN NS ns1.a.
SECTION ADDITIONAL
ns1.a. IN A 10.20.30.50
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
e.a. IN NS
SECTION ANSWER
SECTION AUTHORITY
e.a. IN NS ns2.a.
SECTION ADDITIONAL
ns2.a. IN A 192.0.0.5
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
f.a. IN TXT
SECTION ANSWER
f.a. IN TXT "upstream txt rr f.a."
ENTRY_END
RANGE_END
RANGE_BEGIN 0 100
ADDRESS 10.20.30.50
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
d.a. IN NS
SECTION ANSWER
d.a. IN NS ns1.a.
SECTION ADDITIONAL
ns1.a. IN A 10.20.30.50
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
d.d.a. IN TXT
SECTION ANSWER
d.d.a. IN TXT "upstream answer for d.d.a"
ENTRY_END
RANGE_END
RANGE_BEGIN 0 100
ADDRESS 192.0.0.5
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
e.a. IN NS
SECTION ANSWER
e.a. IN NS ns2.a.
SECTION ADDITIONAL
ns2.a. IN A 192.0.0.5
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
e.e.a. IN TXT
SECTION ANSWER
e.e.a. IN TXT "upstream answer for e.e.a"
ENTRY_END
RANGE_END
; qname trigger
STEP 10 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
a.a. IN TXT
ENTRY_END
STEP 11 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD AA NXDOMAIN
SECTION QUESTION
a.a. IN TXT
SECTION ANSWER
ENTRY_END
; qname trigger after cname
STEP 20 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
c.a. IN TXT
ENTRY_END
STEP 21 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD AA NXDOMAIN
SECTION QUESTION
c.a. IN TXT
SECTION ANSWER
c.a. IN CNAME b.a
ENTRY_END
; nsdname trigger
STEP 30 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
d.d.a. IN TXT
ENTRY_END
STEP 31 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD AA NXDOMAIN
SECTION QUESTION
d.d.a. IN TXT
SECTION ANSWER
ENTRY_END
; nsip trigger
STEP 40 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
e.e.a. IN TXT
ENTRY_END
STEP 41 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD AA NXDOMAIN
SECTION QUESTION
e.e.a. IN TXT
SECTION ANSWER
ENTRY_END
; clientip trigger
STEP 50 QUERY ADDRESS 192.0.3.1
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
f.a. IN TXT
ENTRY_END
STEP 51 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR AA RD NXDOMAIN
SECTION QUESTION
f.a. IN TXT
SECTION ANSWER
ENTRY_END
SCENARIO_END

View File

@ -16,3 +16,7 @@ server:
forward-zone: forward-zone:
name: "." name: "."
forward-addr: "127.0.0.1@@SERVPORT@#unbound" forward-addr: "127.0.0.1@@SERVPORT@#unbound"
forward-zone:
name: "test.host."
forward-host: "unbound.server@@SERVPORT@#unbound"

View File

@ -10,6 +10,8 @@ server:
username: "" username: ""
do-not-query-localhost: yes do-not-query-localhost: yes
local-data: "www.example.com. IN A 10.20.30.40" local-data: "www.example.com. IN A 10.20.30.40"
local-data: "unbound.server. IN A 127.0.0.1"
local-data: "test.host. IN A 1.2.3.4"
ssl-port: @SERVPORT@ ssl-port: @SERVPORT@
ssl-service-key: "unbound_server.key" ssl-service-key: "unbound_server.key"
ssl-service-pem: "unbound_server.pem" ssl-service-pem: "unbound_server.pem"

View File

@ -73,4 +73,38 @@ else
exit 1 exit 1
fi fi
rm -f outfile
# test client unbound (no SSL towards it, but it does SSL to the SSL service)
# test that forward-host notation also works.
echo "> dig test.host. A IN"
dig @127.0.0.1 -p $CLIE_PORT test.host. >outfile 2>&1
if test "$?" -ne 0; then
echo "exit status not OK"
echo "> cat logfiles"
cat outfile
echo "SSLSERVICE"
cat unboundserv.log
echo "SSLCLIENT"
cat unboundclie.log
echo "Not OK"
exit 1
else
echo "exit status OK"
fi
echo "> cat logfiles"
cat outfile
echo "SSLSERVICE"
cat unboundserv.log
echo "SSLCLIENT"
cat unboundclie.log
echo "> check answer"
if grep "1.2.3.4" outfile; then
echo "OK"
else
echo "Not OK"
exit 1
fi
rm -f outfile
exit 0 exit 0

View File

@ -172,3 +172,5 @@ uri.arpa. 3600 IN ZONEMD 2018100702 1 1 ( 1291b78ddf7669b1a39d014
root-servers.net. 3600000 IN ZONEMD 2018091100 1 1 ( f1ca0ccd91bd5573d9f431c00ee0101b2545c97602be0a97 8a3b11dbfc1c776d5b3e86ae3d973d6b5349ba7f04340f79 ) root-servers.net. 3600000 IN ZONEMD 2018091100 1 1 ( f1ca0ccd91bd5573d9f431c00ee0101b2545c97602be0a97 8a3b11dbfc1c776d5b3e86ae3d973d6b5349ba7f04340f79 )
; from ldns issue #121, 0.10m was parsed as 0.01m. ; from ldns issue #121, 0.10m was parsed as 0.01m.
foo. 12345 IN LOC 12 45 52.333 N 105 40 33.452 W -24m 0.1m 0.1m 0.1m foo. 12345 IN LOC 12 45 52.333 N 105 40 33.452 W -24m 0.1m 0.1m 0.1m
; from ldns issue #147, fix #148, tab between quoted strings.
foo 12345 IN HINFO "hohum" "weirdo"

View File

@ -212,3 +212,5 @@ uri.arpa. 3600 IN ZONEMD 2018100702 1 1 1291B78DDF7669B1A39D014D87626B709B55774C
root-servers.net. 3600000 IN ZONEMD 2018091100 1 1 F1CA0CCD91BD5573D9F431C00EE0101B2545C97602BE0A978A3B11DBFC1C776D5B3E86AE3D973D6B5349BA7F04340F79 root-servers.net. 3600000 IN ZONEMD 2018091100 1 1 F1CA0CCD91BD5573D9F431C00EE0101B2545C97602BE0A978A3B11DBFC1C776D5B3E86AE3D973D6B5349BA7F04340F79
03666F6F00001D00010000303900100011111182BD2D4D69530BD400988D20 03666F6F00001D00010000303900100011111182BD2D4D69530BD400988D20
foo. 12345 IN LOC 12 45 52.333 N 105 40 33.452 W -24m 0.10m 0.10m 0.10m foo. 12345 IN LOC 12 45 52.333 N 105 40 33.452 W -24m 0.10m 0.10m 0.10m
03666F6F00000D000100003039000D05686F68756D0677656972646F
foo. 12345 IN HINFO "hohum" "weirdo"

View File

@ -260,7 +260,7 @@ config_create(void)
cfg->val_log_level = 0; cfg->val_log_level = 0;
cfg->val_log_squelch = 0; cfg->val_log_squelch = 0;
cfg->val_permissive_mode = 0; cfg->val_permissive_mode = 0;
cfg->aggressive_nsec = 0; cfg->aggressive_nsec = 1;
cfg->ignore_cd = 0; cfg->ignore_cd = 0;
cfg->serve_expired = 0; cfg->serve_expired = 0;
cfg->serve_expired_ttl = 0; cfg->serve_expired_ttl = 0;
@ -328,9 +328,11 @@ config_create(void)
cfg->ratelimit_size = 4*1024*1024; cfg->ratelimit_size = 4*1024*1024;
cfg->ratelimit_for_domain = NULL; cfg->ratelimit_for_domain = NULL;
cfg->ratelimit_below_domain = NULL; cfg->ratelimit_below_domain = NULL;
cfg->outbound_msg_retry = 5;
cfg->ip_ratelimit_factor = 10; cfg->ip_ratelimit_factor = 10;
cfg->ratelimit_factor = 10; cfg->ratelimit_factor = 10;
cfg->ip_ratelimit_backoff = 0;
cfg->ratelimit_backoff = 0;
cfg->outbound_msg_retry = 5;
cfg->qname_minimisation = 1; cfg->qname_minimisation = 1;
cfg->qname_minimisation_strict = 0; cfg->qname_minimisation_strict = 0;
cfg->shm_enable = 0; cfg->shm_enable = 0;
@ -531,11 +533,17 @@ int config_set_option(struct config_file* cfg, const char* opt,
else S_YNO("edns-tcp-keepalive:", do_tcp_keepalive) else S_YNO("edns-tcp-keepalive:", do_tcp_keepalive)
else S_NUMBER_NONZERO("edns-tcp-keepalive-timeout:", tcp_keepalive_timeout) else S_NUMBER_NONZERO("edns-tcp-keepalive-timeout:", tcp_keepalive_timeout)
else S_YNO("ssl-upstream:", ssl_upstream) else S_YNO("ssl-upstream:", ssl_upstream)
else S_YNO("tls-upstream:", ssl_upstream)
else S_STR("ssl-service-key:", ssl_service_key) else S_STR("ssl-service-key:", ssl_service_key)
else S_STR("tls-service-key:", ssl_service_key)
else S_STR("ssl-service-pem:", ssl_service_pem) else S_STR("ssl-service-pem:", ssl_service_pem)
else S_STR("tls-service-pem:", ssl_service_pem)
else S_NUMBER_NONZERO("ssl-port:", ssl_port) else S_NUMBER_NONZERO("ssl-port:", ssl_port)
else S_NUMBER_NONZERO("tls-port:", ssl_port)
else S_STR("ssl-cert-bundle:", tls_cert_bundle)
else S_STR("tls-cert-bundle:", tls_cert_bundle) else S_STR("tls-cert-bundle:", tls_cert_bundle)
else S_YNO("tls-win-cert:", tls_win_cert) else S_YNO("tls-win-cert:", tls_win_cert)
else S_STRLIST("additional-ssl-port:", tls_additional_port)
else S_STRLIST("additional-tls-port:", tls_additional_port) else S_STRLIST("additional-tls-port:", tls_additional_port)
else S_STRLIST("tls-additional-ports:", tls_additional_port) else S_STRLIST("tls-additional-ports:", tls_additional_port)
else S_STRLIST("tls-additional-port:", tls_additional_port) else S_STRLIST("tls-additional-port:", tls_additional_port)
@ -753,6 +761,8 @@ int config_set_option(struct config_file* cfg, const char* opt,
else S_POW2("ratelimit-slabs:", ratelimit_slabs) else S_POW2("ratelimit-slabs:", ratelimit_slabs)
else S_NUMBER_OR_ZERO("ip-ratelimit-factor:", ip_ratelimit_factor) else S_NUMBER_OR_ZERO("ip-ratelimit-factor:", ip_ratelimit_factor)
else S_NUMBER_OR_ZERO("ratelimit-factor:", ratelimit_factor) else S_NUMBER_OR_ZERO("ratelimit-factor:", ratelimit_factor)
else S_YNO("ip-ratelimit-backoff:", ip_ratelimit_backoff)
else S_YNO("ratelimit-backoff:", ratelimit_backoff)
else S_NUMBER_NONZERO("outbound-msg-retry:", outbound_msg_retry) else S_NUMBER_NONZERO("outbound-msg-retry:", outbound_msg_retry)
else S_SIZET_NONZERO("fast-server-num:", fast_server_num) else S_SIZET_NONZERO("fast-server-num:", fast_server_num)
else S_NUMBER_OR_ZERO("fast-server-permil:", fast_server_permil) else S_NUMBER_OR_ZERO("fast-server-permil:", fast_server_permil)
@ -1029,11 +1039,19 @@ config_get_option(struct config_file* cfg, const char* opt,
else O_YNO(opt, "edns-tcp-keepalive", do_tcp_keepalive) else O_YNO(opt, "edns-tcp-keepalive", do_tcp_keepalive)
else O_DEC(opt, "edns-tcp-keepalive-timeout", tcp_keepalive_timeout) else O_DEC(opt, "edns-tcp-keepalive-timeout", tcp_keepalive_timeout)
else O_YNO(opt, "ssl-upstream", ssl_upstream) else O_YNO(opt, "ssl-upstream", ssl_upstream)
else O_YNO(opt, "tls-upstream", ssl_upstream)
else O_STR(opt, "ssl-service-key", ssl_service_key) else O_STR(opt, "ssl-service-key", ssl_service_key)
else O_STR(opt, "tls-service-key", ssl_service_key)
else O_STR(opt, "ssl-service-pem", ssl_service_pem) else O_STR(opt, "ssl-service-pem", ssl_service_pem)
else O_STR(opt, "tls-service-pem", ssl_service_pem)
else O_DEC(opt, "ssl-port", ssl_port) else O_DEC(opt, "ssl-port", ssl_port)
else O_DEC(opt, "tls-port", ssl_port)
else O_STR(opt, "ssl-cert-bundle", tls_cert_bundle)
else O_STR(opt, "tls-cert-bundle", tls_cert_bundle) else O_STR(opt, "tls-cert-bundle", tls_cert_bundle)
else O_YNO(opt, "tls-win-cert", tls_win_cert) else O_YNO(opt, "tls-win-cert", tls_win_cert)
else O_LST(opt, "additional-ssl-port", tls_additional_port)
else O_LST(opt, "additional-tls-port", tls_additional_port)
else O_LST(opt, "tls-additional-ports", tls_additional_port)
else O_LST(opt, "tls-additional-port", tls_additional_port) else O_LST(opt, "tls-additional-port", tls_additional_port)
else O_LST(opt, "tls-session-ticket-keys", tls_session_ticket_keys.first) else O_LST(opt, "tls-session-ticket-keys", tls_session_ticket_keys.first)
else O_STR(opt, "tls-ciphers", tls_ciphers) else O_STR(opt, "tls-ciphers", tls_ciphers)
@ -1197,6 +1215,8 @@ config_get_option(struct config_file* cfg, const char* opt,
else O_LS2(opt, "ratelimit-below-domain", ratelimit_below_domain) else O_LS2(opt, "ratelimit-below-domain", ratelimit_below_domain)
else O_DEC(opt, "ip-ratelimit-factor", ip_ratelimit_factor) else O_DEC(opt, "ip-ratelimit-factor", ip_ratelimit_factor)
else O_DEC(opt, "ratelimit-factor", ratelimit_factor) else O_DEC(opt, "ratelimit-factor", ratelimit_factor)
else O_YNO(opt, "ip-ratelimit-backoff", ip_ratelimit_backoff)
else O_YNO(opt, "ratelimit-backoff", ratelimit_backoff)
else O_UNS(opt, "outbound-msg-retry", outbound_msg_retry) else O_UNS(opt, "outbound-msg-retry", outbound_msg_retry)
else O_DEC(opt, "fast-server-num", fast_server_num) else O_DEC(opt, "fast-server-num", fast_server_num)
else O_DEC(opt, "fast-server-permil", fast_server_permil) else O_DEC(opt, "fast-server-permil", fast_server_permil)

View File

@ -565,6 +565,10 @@ struct config_file {
size_t ip_ratelimit_size; size_t ip_ratelimit_size;
/** ip_ratelimit factor, 0 blocks all, 10 allows 1/10 of traffic */ /** ip_ratelimit factor, 0 blocks all, 10 allows 1/10 of traffic */
int ip_ratelimit_factor; int ip_ratelimit_factor;
/** ratelimit backoff, when on, if the limit is reached it is
* considered an attack and it backs off until 'demand' decreases over
* the RATE_WINDOW. */
int ip_ratelimit_backoff;
/** ratelimit for domains. 0 is off, otherwise qps (unless overridden) */ /** ratelimit for domains. 0 is off, otherwise qps (unless overridden) */
int ratelimit; int ratelimit;
@ -578,6 +582,11 @@ struct config_file {
struct config_str2list* ratelimit_below_domain; struct config_str2list* ratelimit_below_domain;
/** ratelimit factor, 0 blocks all, 10 allows 1/10 of traffic */ /** ratelimit factor, 0 blocks all, 10 allows 1/10 of traffic */
int ratelimit_factor; int ratelimit_factor;
/** ratelimit backoff, when on, if the limit is reached it is
* considered an attack and it backs off until 'demand' decreases over
* the RATE_WINDOW. */
int ratelimit_backoff;
/** number of retries on outgoing queries */ /** number of retries on outgoing queries */
int outbound_msg_retry; int outbound_msg_retry;
/** minimise outgoing QNAME and hide original QTYPE if possible */ /** minimise outgoing QNAME and hide original QTYPE if possible */
@ -745,6 +754,8 @@ struct config_auth {
/** Always reply with this CNAME target if the cname override action is /** Always reply with this CNAME target if the cname override action is
* used */ * used */
char* rpz_cname; char* rpz_cname;
/** signal nxdomain block with unset RA */
int rpz_signal_nxdomain_ra;
/** Check ZONEMD records for this zone */ /** Check ZONEMD records for this zone */
int zonemd_check; int zonemd_check;
/** Reject absence of ZONEMD records, zone must have one */ /** Reject absence of ZONEMD records, zone must have one */

File diff suppressed because it is too large Load Diff

View File

@ -347,6 +347,7 @@ rpz-action-override{COLON} { YDVAR(1, VAR_RPZ_ACTION_OVERRIDE) }
rpz-cname-override{COLON} { YDVAR(1, VAR_RPZ_CNAME_OVERRIDE) } rpz-cname-override{COLON} { YDVAR(1, VAR_RPZ_CNAME_OVERRIDE) }
rpz-log{COLON} { YDVAR(1, VAR_RPZ_LOG) } rpz-log{COLON} { YDVAR(1, VAR_RPZ_LOG) }
rpz-log-name{COLON} { YDVAR(1, VAR_RPZ_LOG_NAME) } rpz-log-name{COLON} { YDVAR(1, VAR_RPZ_LOG_NAME) }
rpz-signal-nxdomain-ra{COLON} { YDVAR(1, VAR_RPZ_SIGNAL_NXDOMAIN_RA) }
zonefile{COLON} { YDVAR(1, VAR_ZONEFILE) } zonefile{COLON} { YDVAR(1, VAR_ZONEFILE) }
master{COLON} { YDVAR(1, VAR_MASTER) } master{COLON} { YDVAR(1, VAR_MASTER) }
primary{COLON} { YDVAR(1, VAR_MASTER) } primary{COLON} { YDVAR(1, VAR_MASTER) }
@ -501,6 +502,8 @@ ratelimit-for-domain{COLON} { YDVAR(2, VAR_RATELIMIT_FOR_DOMAIN) }
ratelimit-below-domain{COLON} { YDVAR(2, VAR_RATELIMIT_BELOW_DOMAIN) } ratelimit-below-domain{COLON} { YDVAR(2, VAR_RATELIMIT_BELOW_DOMAIN) }
ip-ratelimit-factor{COLON} { YDVAR(1, VAR_IP_RATELIMIT_FACTOR) } ip-ratelimit-factor{COLON} { YDVAR(1, VAR_IP_RATELIMIT_FACTOR) }
ratelimit-factor{COLON} { YDVAR(1, VAR_RATELIMIT_FACTOR) } ratelimit-factor{COLON} { YDVAR(1, VAR_RATELIMIT_FACTOR) }
ip-ratelimit-backoff{COLON} { YDVAR(1, VAR_IP_RATELIMIT_BACKOFF) }
ratelimit-backoff{COLON} { YDVAR(1, VAR_RATELIMIT_BACKOFF) }
outbound-msg-retry{COLON} { YDVAR(1, VAR_OUTBOUND_MSG_RETRY) } outbound-msg-retry{COLON} { YDVAR(1, VAR_OUTBOUND_MSG_RETRY) }
low-rtt{COLON} { YDVAR(1, VAR_LOW_RTT) } low-rtt{COLON} { YDVAR(1, VAR_LOW_RTT) }
fast-server-num{COLON} { YDVAR(1, VAR_FAST_SERVER_NUM) } fast-server-num{COLON} { YDVAR(1, VAR_FAST_SERVER_NUM) }

File diff suppressed because it is too large Load Diff

View File

@ -257,121 +257,124 @@ extern int yydebug;
VAR_RATELIMIT_BELOW_DOMAIN = 458, /* VAR_RATELIMIT_BELOW_DOMAIN */ VAR_RATELIMIT_BELOW_DOMAIN = 458, /* VAR_RATELIMIT_BELOW_DOMAIN */
VAR_IP_RATELIMIT_FACTOR = 459, /* VAR_IP_RATELIMIT_FACTOR */ VAR_IP_RATELIMIT_FACTOR = 459, /* VAR_IP_RATELIMIT_FACTOR */
VAR_RATELIMIT_FACTOR = 460, /* VAR_RATELIMIT_FACTOR */ VAR_RATELIMIT_FACTOR = 460, /* VAR_RATELIMIT_FACTOR */
VAR_SEND_CLIENT_SUBNET = 461, /* VAR_SEND_CLIENT_SUBNET */ VAR_IP_RATELIMIT_BACKOFF = 461, /* VAR_IP_RATELIMIT_BACKOFF */
VAR_CLIENT_SUBNET_ZONE = 462, /* VAR_CLIENT_SUBNET_ZONE */ VAR_RATELIMIT_BACKOFF = 462, /* VAR_RATELIMIT_BACKOFF */
VAR_CLIENT_SUBNET_ALWAYS_FORWARD = 463, /* VAR_CLIENT_SUBNET_ALWAYS_FORWARD */ VAR_SEND_CLIENT_SUBNET = 463, /* VAR_SEND_CLIENT_SUBNET */
VAR_CLIENT_SUBNET_OPCODE = 464, /* VAR_CLIENT_SUBNET_OPCODE */ VAR_CLIENT_SUBNET_ZONE = 464, /* VAR_CLIENT_SUBNET_ZONE */
VAR_MAX_CLIENT_SUBNET_IPV4 = 465, /* VAR_MAX_CLIENT_SUBNET_IPV4 */ VAR_CLIENT_SUBNET_ALWAYS_FORWARD = 465, /* VAR_CLIENT_SUBNET_ALWAYS_FORWARD */
VAR_MAX_CLIENT_SUBNET_IPV6 = 466, /* VAR_MAX_CLIENT_SUBNET_IPV6 */ VAR_CLIENT_SUBNET_OPCODE = 466, /* VAR_CLIENT_SUBNET_OPCODE */
VAR_MIN_CLIENT_SUBNET_IPV4 = 467, /* VAR_MIN_CLIENT_SUBNET_IPV4 */ VAR_MAX_CLIENT_SUBNET_IPV4 = 467, /* VAR_MAX_CLIENT_SUBNET_IPV4 */
VAR_MIN_CLIENT_SUBNET_IPV6 = 468, /* VAR_MIN_CLIENT_SUBNET_IPV6 */ VAR_MAX_CLIENT_SUBNET_IPV6 = 468, /* VAR_MAX_CLIENT_SUBNET_IPV6 */
VAR_MAX_ECS_TREE_SIZE_IPV4 = 469, /* VAR_MAX_ECS_TREE_SIZE_IPV4 */ VAR_MIN_CLIENT_SUBNET_IPV4 = 469, /* VAR_MIN_CLIENT_SUBNET_IPV4 */
VAR_MAX_ECS_TREE_SIZE_IPV6 = 470, /* VAR_MAX_ECS_TREE_SIZE_IPV6 */ VAR_MIN_CLIENT_SUBNET_IPV6 = 470, /* VAR_MIN_CLIENT_SUBNET_IPV6 */
VAR_CAPS_WHITELIST = 471, /* VAR_CAPS_WHITELIST */ VAR_MAX_ECS_TREE_SIZE_IPV4 = 471, /* VAR_MAX_ECS_TREE_SIZE_IPV4 */
VAR_CACHE_MAX_NEGATIVE_TTL = 472, /* VAR_CACHE_MAX_NEGATIVE_TTL */ VAR_MAX_ECS_TREE_SIZE_IPV6 = 472, /* VAR_MAX_ECS_TREE_SIZE_IPV6 */
VAR_PERMIT_SMALL_HOLDDOWN = 473, /* VAR_PERMIT_SMALL_HOLDDOWN */ VAR_CAPS_WHITELIST = 473, /* VAR_CAPS_WHITELIST */
VAR_QNAME_MINIMISATION = 474, /* VAR_QNAME_MINIMISATION */ VAR_CACHE_MAX_NEGATIVE_TTL = 474, /* VAR_CACHE_MAX_NEGATIVE_TTL */
VAR_QNAME_MINIMISATION_STRICT = 475, /* VAR_QNAME_MINIMISATION_STRICT */ VAR_PERMIT_SMALL_HOLDDOWN = 475, /* VAR_PERMIT_SMALL_HOLDDOWN */
VAR_IP_FREEBIND = 476, /* VAR_IP_FREEBIND */ VAR_QNAME_MINIMISATION = 476, /* VAR_QNAME_MINIMISATION */
VAR_DEFINE_TAG = 477, /* VAR_DEFINE_TAG */ VAR_QNAME_MINIMISATION_STRICT = 477, /* VAR_QNAME_MINIMISATION_STRICT */
VAR_LOCAL_ZONE_TAG = 478, /* VAR_LOCAL_ZONE_TAG */ VAR_IP_FREEBIND = 478, /* VAR_IP_FREEBIND */
VAR_ACCESS_CONTROL_TAG = 479, /* VAR_ACCESS_CONTROL_TAG */ VAR_DEFINE_TAG = 479, /* VAR_DEFINE_TAG */
VAR_LOCAL_ZONE_OVERRIDE = 480, /* VAR_LOCAL_ZONE_OVERRIDE */ VAR_LOCAL_ZONE_TAG = 480, /* VAR_LOCAL_ZONE_TAG */
VAR_ACCESS_CONTROL_TAG_ACTION = 481, /* VAR_ACCESS_CONTROL_TAG_ACTION */ VAR_ACCESS_CONTROL_TAG = 481, /* VAR_ACCESS_CONTROL_TAG */
VAR_ACCESS_CONTROL_TAG_DATA = 482, /* VAR_ACCESS_CONTROL_TAG_DATA */ VAR_LOCAL_ZONE_OVERRIDE = 482, /* VAR_LOCAL_ZONE_OVERRIDE */
VAR_VIEW = 483, /* VAR_VIEW */ VAR_ACCESS_CONTROL_TAG_ACTION = 483, /* VAR_ACCESS_CONTROL_TAG_ACTION */
VAR_ACCESS_CONTROL_VIEW = 484, /* VAR_ACCESS_CONTROL_VIEW */ VAR_ACCESS_CONTROL_TAG_DATA = 484, /* VAR_ACCESS_CONTROL_TAG_DATA */
VAR_VIEW_FIRST = 485, /* VAR_VIEW_FIRST */ VAR_VIEW = 485, /* VAR_VIEW */
VAR_SERVE_EXPIRED = 486, /* VAR_SERVE_EXPIRED */ VAR_ACCESS_CONTROL_VIEW = 486, /* VAR_ACCESS_CONTROL_VIEW */
VAR_SERVE_EXPIRED_TTL = 487, /* VAR_SERVE_EXPIRED_TTL */ VAR_VIEW_FIRST = 487, /* VAR_VIEW_FIRST */
VAR_SERVE_EXPIRED_TTL_RESET = 488, /* VAR_SERVE_EXPIRED_TTL_RESET */ VAR_SERVE_EXPIRED = 488, /* VAR_SERVE_EXPIRED */
VAR_SERVE_EXPIRED_REPLY_TTL = 489, /* VAR_SERVE_EXPIRED_REPLY_TTL */ VAR_SERVE_EXPIRED_TTL = 489, /* VAR_SERVE_EXPIRED_TTL */
VAR_SERVE_EXPIRED_CLIENT_TIMEOUT = 490, /* VAR_SERVE_EXPIRED_CLIENT_TIMEOUT */ VAR_SERVE_EXPIRED_TTL_RESET = 490, /* VAR_SERVE_EXPIRED_TTL_RESET */
VAR_SERVE_ORIGINAL_TTL = 491, /* VAR_SERVE_ORIGINAL_TTL */ VAR_SERVE_EXPIRED_REPLY_TTL = 491, /* VAR_SERVE_EXPIRED_REPLY_TTL */
VAR_FAKE_DSA = 492, /* VAR_FAKE_DSA */ VAR_SERVE_EXPIRED_CLIENT_TIMEOUT = 492, /* VAR_SERVE_EXPIRED_CLIENT_TIMEOUT */
VAR_FAKE_SHA1 = 493, /* VAR_FAKE_SHA1 */ VAR_SERVE_ORIGINAL_TTL = 493, /* VAR_SERVE_ORIGINAL_TTL */
VAR_LOG_IDENTITY = 494, /* VAR_LOG_IDENTITY */ VAR_FAKE_DSA = 494, /* VAR_FAKE_DSA */
VAR_HIDE_TRUSTANCHOR = 495, /* VAR_HIDE_TRUSTANCHOR */ VAR_FAKE_SHA1 = 495, /* VAR_FAKE_SHA1 */
VAR_HIDE_HTTP_USER_AGENT = 496, /* VAR_HIDE_HTTP_USER_AGENT */ VAR_LOG_IDENTITY = 496, /* VAR_LOG_IDENTITY */
VAR_HTTP_USER_AGENT = 497, /* VAR_HTTP_USER_AGENT */ VAR_HIDE_TRUSTANCHOR = 497, /* VAR_HIDE_TRUSTANCHOR */
VAR_TRUST_ANCHOR_SIGNALING = 498, /* VAR_TRUST_ANCHOR_SIGNALING */ VAR_HIDE_HTTP_USER_AGENT = 498, /* VAR_HIDE_HTTP_USER_AGENT */
VAR_AGGRESSIVE_NSEC = 499, /* VAR_AGGRESSIVE_NSEC */ VAR_HTTP_USER_AGENT = 499, /* VAR_HTTP_USER_AGENT */
VAR_USE_SYSTEMD = 500, /* VAR_USE_SYSTEMD */ VAR_TRUST_ANCHOR_SIGNALING = 500, /* VAR_TRUST_ANCHOR_SIGNALING */
VAR_SHM_ENABLE = 501, /* VAR_SHM_ENABLE */ VAR_AGGRESSIVE_NSEC = 501, /* VAR_AGGRESSIVE_NSEC */
VAR_SHM_KEY = 502, /* VAR_SHM_KEY */ VAR_USE_SYSTEMD = 502, /* VAR_USE_SYSTEMD */
VAR_ROOT_KEY_SENTINEL = 503, /* VAR_ROOT_KEY_SENTINEL */ VAR_SHM_ENABLE = 503, /* VAR_SHM_ENABLE */
VAR_DNSCRYPT = 504, /* VAR_DNSCRYPT */ VAR_SHM_KEY = 504, /* VAR_SHM_KEY */
VAR_DNSCRYPT_ENABLE = 505, /* VAR_DNSCRYPT_ENABLE */ VAR_ROOT_KEY_SENTINEL = 505, /* VAR_ROOT_KEY_SENTINEL */
VAR_DNSCRYPT_PORT = 506, /* VAR_DNSCRYPT_PORT */ VAR_DNSCRYPT = 506, /* VAR_DNSCRYPT */
VAR_DNSCRYPT_PROVIDER = 507, /* VAR_DNSCRYPT_PROVIDER */ VAR_DNSCRYPT_ENABLE = 507, /* VAR_DNSCRYPT_ENABLE */
VAR_DNSCRYPT_SECRET_KEY = 508, /* VAR_DNSCRYPT_SECRET_KEY */ VAR_DNSCRYPT_PORT = 508, /* VAR_DNSCRYPT_PORT */
VAR_DNSCRYPT_PROVIDER_CERT = 509, /* VAR_DNSCRYPT_PROVIDER_CERT */ VAR_DNSCRYPT_PROVIDER = 509, /* VAR_DNSCRYPT_PROVIDER */
VAR_DNSCRYPT_PROVIDER_CERT_ROTATED = 510, /* VAR_DNSCRYPT_PROVIDER_CERT_ROTATED */ VAR_DNSCRYPT_SECRET_KEY = 510, /* VAR_DNSCRYPT_SECRET_KEY */
VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE = 511, /* VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE */ VAR_DNSCRYPT_PROVIDER_CERT = 511, /* VAR_DNSCRYPT_PROVIDER_CERT */
VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS = 512, /* VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS */ VAR_DNSCRYPT_PROVIDER_CERT_ROTATED = 512, /* VAR_DNSCRYPT_PROVIDER_CERT_ROTATED */
VAR_DNSCRYPT_NONCE_CACHE_SIZE = 513, /* VAR_DNSCRYPT_NONCE_CACHE_SIZE */ VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE = 513, /* VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE */
VAR_DNSCRYPT_NONCE_CACHE_SLABS = 514, /* VAR_DNSCRYPT_NONCE_CACHE_SLABS */ VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS = 514, /* VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS */
VAR_PAD_RESPONSES = 515, /* VAR_PAD_RESPONSES */ VAR_DNSCRYPT_NONCE_CACHE_SIZE = 515, /* VAR_DNSCRYPT_NONCE_CACHE_SIZE */
VAR_PAD_RESPONSES_BLOCK_SIZE = 516, /* VAR_PAD_RESPONSES_BLOCK_SIZE */ VAR_DNSCRYPT_NONCE_CACHE_SLABS = 516, /* VAR_DNSCRYPT_NONCE_CACHE_SLABS */
VAR_PAD_QUERIES = 517, /* VAR_PAD_QUERIES */ VAR_PAD_RESPONSES = 517, /* VAR_PAD_RESPONSES */
VAR_PAD_QUERIES_BLOCK_SIZE = 518, /* VAR_PAD_QUERIES_BLOCK_SIZE */ VAR_PAD_RESPONSES_BLOCK_SIZE = 518, /* VAR_PAD_RESPONSES_BLOCK_SIZE */
VAR_IPSECMOD_ENABLED = 519, /* VAR_IPSECMOD_ENABLED */ VAR_PAD_QUERIES = 519, /* VAR_PAD_QUERIES */
VAR_IPSECMOD_HOOK = 520, /* VAR_IPSECMOD_HOOK */ VAR_PAD_QUERIES_BLOCK_SIZE = 520, /* VAR_PAD_QUERIES_BLOCK_SIZE */
VAR_IPSECMOD_IGNORE_BOGUS = 521, /* VAR_IPSECMOD_IGNORE_BOGUS */ VAR_IPSECMOD_ENABLED = 521, /* VAR_IPSECMOD_ENABLED */
VAR_IPSECMOD_MAX_TTL = 522, /* VAR_IPSECMOD_MAX_TTL */ VAR_IPSECMOD_HOOK = 522, /* VAR_IPSECMOD_HOOK */
VAR_IPSECMOD_WHITELIST = 523, /* VAR_IPSECMOD_WHITELIST */ VAR_IPSECMOD_IGNORE_BOGUS = 523, /* VAR_IPSECMOD_IGNORE_BOGUS */
VAR_IPSECMOD_STRICT = 524, /* VAR_IPSECMOD_STRICT */ VAR_IPSECMOD_MAX_TTL = 524, /* VAR_IPSECMOD_MAX_TTL */
VAR_CACHEDB = 525, /* VAR_CACHEDB */ VAR_IPSECMOD_WHITELIST = 525, /* VAR_IPSECMOD_WHITELIST */
VAR_CACHEDB_BACKEND = 526, /* VAR_CACHEDB_BACKEND */ VAR_IPSECMOD_STRICT = 526, /* VAR_IPSECMOD_STRICT */
VAR_CACHEDB_SECRETSEED = 527, /* VAR_CACHEDB_SECRETSEED */ VAR_CACHEDB = 527, /* VAR_CACHEDB */
VAR_CACHEDB_REDISHOST = 528, /* VAR_CACHEDB_REDISHOST */ VAR_CACHEDB_BACKEND = 528, /* VAR_CACHEDB_BACKEND */
VAR_CACHEDB_REDISPORT = 529, /* VAR_CACHEDB_REDISPORT */ VAR_CACHEDB_SECRETSEED = 529, /* VAR_CACHEDB_SECRETSEED */
VAR_CACHEDB_REDISTIMEOUT = 530, /* VAR_CACHEDB_REDISTIMEOUT */ VAR_CACHEDB_REDISHOST = 530, /* VAR_CACHEDB_REDISHOST */
VAR_CACHEDB_REDISEXPIRERECORDS = 531, /* VAR_CACHEDB_REDISEXPIRERECORDS */ VAR_CACHEDB_REDISPORT = 531, /* VAR_CACHEDB_REDISPORT */
VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM = 532, /* VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM */ VAR_CACHEDB_REDISTIMEOUT = 532, /* VAR_CACHEDB_REDISTIMEOUT */
VAR_FOR_UPSTREAM = 533, /* VAR_FOR_UPSTREAM */ VAR_CACHEDB_REDISEXPIRERECORDS = 533, /* VAR_CACHEDB_REDISEXPIRERECORDS */
VAR_AUTH_ZONE = 534, /* VAR_AUTH_ZONE */ VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM = 534, /* VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM */
VAR_ZONEFILE = 535, /* VAR_ZONEFILE */ VAR_FOR_UPSTREAM = 535, /* VAR_FOR_UPSTREAM */
VAR_MASTER = 536, /* VAR_MASTER */ VAR_AUTH_ZONE = 536, /* VAR_AUTH_ZONE */
VAR_URL = 537, /* VAR_URL */ VAR_ZONEFILE = 537, /* VAR_ZONEFILE */
VAR_FOR_DOWNSTREAM = 538, /* VAR_FOR_DOWNSTREAM */ VAR_MASTER = 538, /* VAR_MASTER */
VAR_FALLBACK_ENABLED = 539, /* VAR_FALLBACK_ENABLED */ VAR_URL = 539, /* VAR_URL */
VAR_TLS_ADDITIONAL_PORT = 540, /* VAR_TLS_ADDITIONAL_PORT */ VAR_FOR_DOWNSTREAM = 540, /* VAR_FOR_DOWNSTREAM */
VAR_LOW_RTT = 541, /* VAR_LOW_RTT */ VAR_FALLBACK_ENABLED = 541, /* VAR_FALLBACK_ENABLED */
VAR_LOW_RTT_PERMIL = 542, /* VAR_LOW_RTT_PERMIL */ VAR_TLS_ADDITIONAL_PORT = 542, /* VAR_TLS_ADDITIONAL_PORT */
VAR_FAST_SERVER_PERMIL = 543, /* VAR_FAST_SERVER_PERMIL */ VAR_LOW_RTT = 543, /* VAR_LOW_RTT */
VAR_FAST_SERVER_NUM = 544, /* VAR_FAST_SERVER_NUM */ VAR_LOW_RTT_PERMIL = 544, /* VAR_LOW_RTT_PERMIL */
VAR_ALLOW_NOTIFY = 545, /* VAR_ALLOW_NOTIFY */ VAR_FAST_SERVER_PERMIL = 545, /* VAR_FAST_SERVER_PERMIL */
VAR_TLS_WIN_CERT = 546, /* VAR_TLS_WIN_CERT */ VAR_FAST_SERVER_NUM = 546, /* VAR_FAST_SERVER_NUM */
VAR_TCP_CONNECTION_LIMIT = 547, /* VAR_TCP_CONNECTION_LIMIT */ VAR_ALLOW_NOTIFY = 547, /* VAR_ALLOW_NOTIFY */
VAR_FORWARD_NO_CACHE = 548, /* VAR_FORWARD_NO_CACHE */ VAR_TLS_WIN_CERT = 548, /* VAR_TLS_WIN_CERT */
VAR_STUB_NO_CACHE = 549, /* VAR_STUB_NO_CACHE */ VAR_TCP_CONNECTION_LIMIT = 549, /* VAR_TCP_CONNECTION_LIMIT */
VAR_LOG_SERVFAIL = 550, /* VAR_LOG_SERVFAIL */ VAR_FORWARD_NO_CACHE = 550, /* VAR_FORWARD_NO_CACHE */
VAR_DENY_ANY = 551, /* VAR_DENY_ANY */ VAR_STUB_NO_CACHE = 551, /* VAR_STUB_NO_CACHE */
VAR_UNKNOWN_SERVER_TIME_LIMIT = 552, /* VAR_UNKNOWN_SERVER_TIME_LIMIT */ VAR_LOG_SERVFAIL = 552, /* VAR_LOG_SERVFAIL */
VAR_LOG_TAG_QUERYREPLY = 553, /* VAR_LOG_TAG_QUERYREPLY */ VAR_DENY_ANY = 553, /* VAR_DENY_ANY */
VAR_STREAM_WAIT_SIZE = 554, /* VAR_STREAM_WAIT_SIZE */ VAR_UNKNOWN_SERVER_TIME_LIMIT = 554, /* VAR_UNKNOWN_SERVER_TIME_LIMIT */
VAR_TLS_CIPHERS = 555, /* VAR_TLS_CIPHERS */ VAR_LOG_TAG_QUERYREPLY = 555, /* VAR_LOG_TAG_QUERYREPLY */
VAR_TLS_CIPHERSUITES = 556, /* VAR_TLS_CIPHERSUITES */ VAR_STREAM_WAIT_SIZE = 556, /* VAR_STREAM_WAIT_SIZE */
VAR_TLS_USE_SNI = 557, /* VAR_TLS_USE_SNI */ VAR_TLS_CIPHERS = 557, /* VAR_TLS_CIPHERS */
VAR_IPSET = 558, /* VAR_IPSET */ VAR_TLS_CIPHERSUITES = 558, /* VAR_TLS_CIPHERSUITES */
VAR_IPSET_NAME_V4 = 559, /* VAR_IPSET_NAME_V4 */ VAR_TLS_USE_SNI = 559, /* VAR_TLS_USE_SNI */
VAR_IPSET_NAME_V6 = 560, /* VAR_IPSET_NAME_V6 */ VAR_IPSET = 560, /* VAR_IPSET */
VAR_TLS_SESSION_TICKET_KEYS = 561, /* VAR_TLS_SESSION_TICKET_KEYS */ VAR_IPSET_NAME_V4 = 561, /* VAR_IPSET_NAME_V4 */
VAR_RPZ = 562, /* VAR_RPZ */ VAR_IPSET_NAME_V6 = 562, /* VAR_IPSET_NAME_V6 */
VAR_TAGS = 563, /* VAR_TAGS */ VAR_TLS_SESSION_TICKET_KEYS = 563, /* VAR_TLS_SESSION_TICKET_KEYS */
VAR_RPZ_ACTION_OVERRIDE = 564, /* VAR_RPZ_ACTION_OVERRIDE */ VAR_RPZ = 564, /* VAR_RPZ */
VAR_RPZ_CNAME_OVERRIDE = 565, /* VAR_RPZ_CNAME_OVERRIDE */ VAR_TAGS = 565, /* VAR_TAGS */
VAR_RPZ_LOG = 566, /* VAR_RPZ_LOG */ VAR_RPZ_ACTION_OVERRIDE = 566, /* VAR_RPZ_ACTION_OVERRIDE */
VAR_RPZ_LOG_NAME = 567, /* VAR_RPZ_LOG_NAME */ VAR_RPZ_CNAME_OVERRIDE = 567, /* VAR_RPZ_CNAME_OVERRIDE */
VAR_DYNLIB = 568, /* VAR_DYNLIB */ VAR_RPZ_LOG = 568, /* VAR_RPZ_LOG */
VAR_DYNLIB_FILE = 569, /* VAR_DYNLIB_FILE */ VAR_RPZ_LOG_NAME = 569, /* VAR_RPZ_LOG_NAME */
VAR_EDNS_CLIENT_STRING = 570, /* VAR_EDNS_CLIENT_STRING */ VAR_DYNLIB = 570, /* VAR_DYNLIB */
VAR_EDNS_CLIENT_STRING_OPCODE = 571, /* VAR_EDNS_CLIENT_STRING_OPCODE */ VAR_DYNLIB_FILE = 571, /* VAR_DYNLIB_FILE */
VAR_NSID = 572, /* VAR_NSID */ VAR_EDNS_CLIENT_STRING = 572, /* VAR_EDNS_CLIENT_STRING */
VAR_ZONEMD_PERMISSIVE_MODE = 573, /* VAR_ZONEMD_PERMISSIVE_MODE */ VAR_EDNS_CLIENT_STRING_OPCODE = 573, /* VAR_EDNS_CLIENT_STRING_OPCODE */
VAR_ZONEMD_CHECK = 574, /* VAR_ZONEMD_CHECK */ VAR_NSID = 574, /* VAR_NSID */
VAR_ZONEMD_REJECT_ABSENCE = 575 /* VAR_ZONEMD_REJECT_ABSENCE */ VAR_ZONEMD_PERMISSIVE_MODE = 575, /* VAR_ZONEMD_PERMISSIVE_MODE */
VAR_ZONEMD_CHECK = 576, /* VAR_ZONEMD_CHECK */
VAR_ZONEMD_REJECT_ABSENCE = 577, /* VAR_ZONEMD_REJECT_ABSENCE */
VAR_RPZ_SIGNAL_NXDOMAIN_RA = 578 /* VAR_RPZ_SIGNAL_NXDOMAIN_RA */
}; };
typedef enum yytokentype yytoken_kind_t; typedef enum yytokentype yytoken_kind_t;
#endif #endif
@ -582,121 +585,124 @@ extern int yydebug;
#define VAR_RATELIMIT_BELOW_DOMAIN 458 #define VAR_RATELIMIT_BELOW_DOMAIN 458
#define VAR_IP_RATELIMIT_FACTOR 459 #define VAR_IP_RATELIMIT_FACTOR 459
#define VAR_RATELIMIT_FACTOR 460 #define VAR_RATELIMIT_FACTOR 460
#define VAR_SEND_CLIENT_SUBNET 461 #define VAR_IP_RATELIMIT_BACKOFF 461
#define VAR_CLIENT_SUBNET_ZONE 462 #define VAR_RATELIMIT_BACKOFF 462
#define VAR_CLIENT_SUBNET_ALWAYS_FORWARD 463 #define VAR_SEND_CLIENT_SUBNET 463
#define VAR_CLIENT_SUBNET_OPCODE 464 #define VAR_CLIENT_SUBNET_ZONE 464
#define VAR_MAX_CLIENT_SUBNET_IPV4 465 #define VAR_CLIENT_SUBNET_ALWAYS_FORWARD 465
#define VAR_MAX_CLIENT_SUBNET_IPV6 466 #define VAR_CLIENT_SUBNET_OPCODE 466
#define VAR_MIN_CLIENT_SUBNET_IPV4 467 #define VAR_MAX_CLIENT_SUBNET_IPV4 467
#define VAR_MIN_CLIENT_SUBNET_IPV6 468 #define VAR_MAX_CLIENT_SUBNET_IPV6 468
#define VAR_MAX_ECS_TREE_SIZE_IPV4 469 #define VAR_MIN_CLIENT_SUBNET_IPV4 469
#define VAR_MAX_ECS_TREE_SIZE_IPV6 470 #define VAR_MIN_CLIENT_SUBNET_IPV6 470
#define VAR_CAPS_WHITELIST 471 #define VAR_MAX_ECS_TREE_SIZE_IPV4 471
#define VAR_CACHE_MAX_NEGATIVE_TTL 472 #define VAR_MAX_ECS_TREE_SIZE_IPV6 472
#define VAR_PERMIT_SMALL_HOLDDOWN 473 #define VAR_CAPS_WHITELIST 473
#define VAR_QNAME_MINIMISATION 474 #define VAR_CACHE_MAX_NEGATIVE_TTL 474
#define VAR_QNAME_MINIMISATION_STRICT 475 #define VAR_PERMIT_SMALL_HOLDDOWN 475
#define VAR_IP_FREEBIND 476 #define VAR_QNAME_MINIMISATION 476
#define VAR_DEFINE_TAG 477 #define VAR_QNAME_MINIMISATION_STRICT 477
#define VAR_LOCAL_ZONE_TAG 478 #define VAR_IP_FREEBIND 478
#define VAR_ACCESS_CONTROL_TAG 479 #define VAR_DEFINE_TAG 479
#define VAR_LOCAL_ZONE_OVERRIDE 480 #define VAR_LOCAL_ZONE_TAG 480
#define VAR_ACCESS_CONTROL_TAG_ACTION 481 #define VAR_ACCESS_CONTROL_TAG 481
#define VAR_ACCESS_CONTROL_TAG_DATA 482 #define VAR_LOCAL_ZONE_OVERRIDE 482
#define VAR_VIEW 483 #define VAR_ACCESS_CONTROL_TAG_ACTION 483
#define VAR_ACCESS_CONTROL_VIEW 484 #define VAR_ACCESS_CONTROL_TAG_DATA 484
#define VAR_VIEW_FIRST 485 #define VAR_VIEW 485
#define VAR_SERVE_EXPIRED 486 #define VAR_ACCESS_CONTROL_VIEW 486
#define VAR_SERVE_EXPIRED_TTL 487 #define VAR_VIEW_FIRST 487
#define VAR_SERVE_EXPIRED_TTL_RESET 488 #define VAR_SERVE_EXPIRED 488
#define VAR_SERVE_EXPIRED_REPLY_TTL 489 #define VAR_SERVE_EXPIRED_TTL 489
#define VAR_SERVE_EXPIRED_CLIENT_TIMEOUT 490 #define VAR_SERVE_EXPIRED_TTL_RESET 490
#define VAR_SERVE_ORIGINAL_TTL 491 #define VAR_SERVE_EXPIRED_REPLY_TTL 491
#define VAR_FAKE_DSA 492 #define VAR_SERVE_EXPIRED_CLIENT_TIMEOUT 492
#define VAR_FAKE_SHA1 493 #define VAR_SERVE_ORIGINAL_TTL 493
#define VAR_LOG_IDENTITY 494 #define VAR_FAKE_DSA 494
#define VAR_HIDE_TRUSTANCHOR 495 #define VAR_FAKE_SHA1 495
#define VAR_HIDE_HTTP_USER_AGENT 496 #define VAR_LOG_IDENTITY 496
#define VAR_HTTP_USER_AGENT 497 #define VAR_HIDE_TRUSTANCHOR 497
#define VAR_TRUST_ANCHOR_SIGNALING 498 #define VAR_HIDE_HTTP_USER_AGENT 498
#define VAR_AGGRESSIVE_NSEC 499 #define VAR_HTTP_USER_AGENT 499
#define VAR_USE_SYSTEMD 500 #define VAR_TRUST_ANCHOR_SIGNALING 500
#define VAR_SHM_ENABLE 501 #define VAR_AGGRESSIVE_NSEC 501
#define VAR_SHM_KEY 502 #define VAR_USE_SYSTEMD 502
#define VAR_ROOT_KEY_SENTINEL 503 #define VAR_SHM_ENABLE 503
#define VAR_DNSCRYPT 504 #define VAR_SHM_KEY 504
#define VAR_DNSCRYPT_ENABLE 505 #define VAR_ROOT_KEY_SENTINEL 505
#define VAR_DNSCRYPT_PORT 506 #define VAR_DNSCRYPT 506
#define VAR_DNSCRYPT_PROVIDER 507 #define VAR_DNSCRYPT_ENABLE 507
#define VAR_DNSCRYPT_SECRET_KEY 508 #define VAR_DNSCRYPT_PORT 508
#define VAR_DNSCRYPT_PROVIDER_CERT 509 #define VAR_DNSCRYPT_PROVIDER 509
#define VAR_DNSCRYPT_PROVIDER_CERT_ROTATED 510 #define VAR_DNSCRYPT_SECRET_KEY 510
#define VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE 511 #define VAR_DNSCRYPT_PROVIDER_CERT 511
#define VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS 512 #define VAR_DNSCRYPT_PROVIDER_CERT_ROTATED 512
#define VAR_DNSCRYPT_NONCE_CACHE_SIZE 513 #define VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE 513
#define VAR_DNSCRYPT_NONCE_CACHE_SLABS 514 #define VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS 514
#define VAR_PAD_RESPONSES 515 #define VAR_DNSCRYPT_NONCE_CACHE_SIZE 515
#define VAR_PAD_RESPONSES_BLOCK_SIZE 516 #define VAR_DNSCRYPT_NONCE_CACHE_SLABS 516
#define VAR_PAD_QUERIES 517 #define VAR_PAD_RESPONSES 517
#define VAR_PAD_QUERIES_BLOCK_SIZE 518 #define VAR_PAD_RESPONSES_BLOCK_SIZE 518
#define VAR_IPSECMOD_ENABLED 519 #define VAR_PAD_QUERIES 519
#define VAR_IPSECMOD_HOOK 520 #define VAR_PAD_QUERIES_BLOCK_SIZE 520
#define VAR_IPSECMOD_IGNORE_BOGUS 521 #define VAR_IPSECMOD_ENABLED 521
#define VAR_IPSECMOD_MAX_TTL 522 #define VAR_IPSECMOD_HOOK 522
#define VAR_IPSECMOD_WHITELIST 523 #define VAR_IPSECMOD_IGNORE_BOGUS 523
#define VAR_IPSECMOD_STRICT 524 #define VAR_IPSECMOD_MAX_TTL 524
#define VAR_CACHEDB 525 #define VAR_IPSECMOD_WHITELIST 525
#define VAR_CACHEDB_BACKEND 526 #define VAR_IPSECMOD_STRICT 526
#define VAR_CACHEDB_SECRETSEED 527 #define VAR_CACHEDB 527
#define VAR_CACHEDB_REDISHOST 528 #define VAR_CACHEDB_BACKEND 528
#define VAR_CACHEDB_REDISPORT 529 #define VAR_CACHEDB_SECRETSEED 529
#define VAR_CACHEDB_REDISTIMEOUT 530 #define VAR_CACHEDB_REDISHOST 530
#define VAR_CACHEDB_REDISEXPIRERECORDS 531 #define VAR_CACHEDB_REDISPORT 531
#define VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM 532 #define VAR_CACHEDB_REDISTIMEOUT 532
#define VAR_FOR_UPSTREAM 533 #define VAR_CACHEDB_REDISEXPIRERECORDS 533
#define VAR_AUTH_ZONE 534 #define VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM 534
#define VAR_ZONEFILE 535 #define VAR_FOR_UPSTREAM 535
#define VAR_MASTER 536 #define VAR_AUTH_ZONE 536
#define VAR_URL 537 #define VAR_ZONEFILE 537
#define VAR_FOR_DOWNSTREAM 538 #define VAR_MASTER 538
#define VAR_FALLBACK_ENABLED 539 #define VAR_URL 539
#define VAR_TLS_ADDITIONAL_PORT 540 #define VAR_FOR_DOWNSTREAM 540
#define VAR_LOW_RTT 541 #define VAR_FALLBACK_ENABLED 541
#define VAR_LOW_RTT_PERMIL 542 #define VAR_TLS_ADDITIONAL_PORT 542
#define VAR_FAST_SERVER_PERMIL 543 #define VAR_LOW_RTT 543
#define VAR_FAST_SERVER_NUM 544 #define VAR_LOW_RTT_PERMIL 544
#define VAR_ALLOW_NOTIFY 545 #define VAR_FAST_SERVER_PERMIL 545
#define VAR_TLS_WIN_CERT 546 #define VAR_FAST_SERVER_NUM 546
#define VAR_TCP_CONNECTION_LIMIT 547 #define VAR_ALLOW_NOTIFY 547
#define VAR_FORWARD_NO_CACHE 548 #define VAR_TLS_WIN_CERT 548
#define VAR_STUB_NO_CACHE 549 #define VAR_TCP_CONNECTION_LIMIT 549
#define VAR_LOG_SERVFAIL 550 #define VAR_FORWARD_NO_CACHE 550
#define VAR_DENY_ANY 551 #define VAR_STUB_NO_CACHE 551
#define VAR_UNKNOWN_SERVER_TIME_LIMIT 552 #define VAR_LOG_SERVFAIL 552
#define VAR_LOG_TAG_QUERYREPLY 553 #define VAR_DENY_ANY 553
#define VAR_STREAM_WAIT_SIZE 554 #define VAR_UNKNOWN_SERVER_TIME_LIMIT 554
#define VAR_TLS_CIPHERS 555 #define VAR_LOG_TAG_QUERYREPLY 555
#define VAR_TLS_CIPHERSUITES 556 #define VAR_STREAM_WAIT_SIZE 556
#define VAR_TLS_USE_SNI 557 #define VAR_TLS_CIPHERS 557
#define VAR_IPSET 558 #define VAR_TLS_CIPHERSUITES 558
#define VAR_IPSET_NAME_V4 559 #define VAR_TLS_USE_SNI 559
#define VAR_IPSET_NAME_V6 560 #define VAR_IPSET 560
#define VAR_TLS_SESSION_TICKET_KEYS 561 #define VAR_IPSET_NAME_V4 561
#define VAR_RPZ 562 #define VAR_IPSET_NAME_V6 562
#define VAR_TAGS 563 #define VAR_TLS_SESSION_TICKET_KEYS 563
#define VAR_RPZ_ACTION_OVERRIDE 564 #define VAR_RPZ 564
#define VAR_RPZ_CNAME_OVERRIDE 565 #define VAR_TAGS 565
#define VAR_RPZ_LOG 566 #define VAR_RPZ_ACTION_OVERRIDE 566
#define VAR_RPZ_LOG_NAME 567 #define VAR_RPZ_CNAME_OVERRIDE 567
#define VAR_DYNLIB 568 #define VAR_RPZ_LOG 568
#define VAR_DYNLIB_FILE 569 #define VAR_RPZ_LOG_NAME 569
#define VAR_EDNS_CLIENT_STRING 570 #define VAR_DYNLIB 570
#define VAR_EDNS_CLIENT_STRING_OPCODE 571 #define VAR_DYNLIB_FILE 571
#define VAR_NSID 572 #define VAR_EDNS_CLIENT_STRING 572
#define VAR_ZONEMD_PERMISSIVE_MODE 573 #define VAR_EDNS_CLIENT_STRING_OPCODE 573
#define VAR_ZONEMD_CHECK 574 #define VAR_NSID 574
#define VAR_ZONEMD_REJECT_ABSENCE 575 #define VAR_ZONEMD_PERMISSIVE_MODE 575
#define VAR_ZONEMD_CHECK 576
#define VAR_ZONEMD_REJECT_ABSENCE 577
#define VAR_RPZ_SIGNAL_NXDOMAIN_RA 578
/* Value type. */ /* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
@ -706,7 +712,7 @@ union YYSTYPE
char* str; char* str;
#line 710 "util/configparser.h" #line 716 "util/configparser.h"
}; };
typedef union YYSTYPE YYSTYPE; typedef union YYSTYPE YYSTYPE;

View File

@ -142,6 +142,7 @@ extern struct config_parser_state* cfg_parser;
%token VAR_OUTBOUND_MSG_RETRY %token VAR_OUTBOUND_MSG_RETRY
%token VAR_RATELIMIT_FOR_DOMAIN VAR_RATELIMIT_BELOW_DOMAIN %token VAR_RATELIMIT_FOR_DOMAIN VAR_RATELIMIT_BELOW_DOMAIN
%token VAR_IP_RATELIMIT_FACTOR VAR_RATELIMIT_FACTOR %token VAR_IP_RATELIMIT_FACTOR VAR_RATELIMIT_FACTOR
%token VAR_IP_RATELIMIT_BACKOFF VAR_RATELIMIT_BACKOFF
%token VAR_SEND_CLIENT_SUBNET VAR_CLIENT_SUBNET_ZONE %token VAR_SEND_CLIENT_SUBNET VAR_CLIENT_SUBNET_ZONE
%token VAR_CLIENT_SUBNET_ALWAYS_FORWARD VAR_CLIENT_SUBNET_OPCODE %token VAR_CLIENT_SUBNET_ALWAYS_FORWARD VAR_CLIENT_SUBNET_OPCODE
%token VAR_MAX_CLIENT_SUBNET_IPV4 VAR_MAX_CLIENT_SUBNET_IPV6 %token VAR_MAX_CLIENT_SUBNET_IPV4 VAR_MAX_CLIENT_SUBNET_IPV6
@ -187,6 +188,7 @@ extern struct config_parser_state* cfg_parser;
%token VAR_DYNLIB VAR_DYNLIB_FILE VAR_EDNS_CLIENT_STRING %token VAR_DYNLIB VAR_DYNLIB_FILE VAR_EDNS_CLIENT_STRING
%token VAR_EDNS_CLIENT_STRING_OPCODE VAR_NSID %token VAR_EDNS_CLIENT_STRING_OPCODE VAR_NSID
%token VAR_ZONEMD_PERMISSIVE_MODE VAR_ZONEMD_CHECK VAR_ZONEMD_REJECT_ABSENCE %token VAR_ZONEMD_PERMISSIVE_MODE VAR_ZONEMD_CHECK VAR_ZONEMD_REJECT_ABSENCE
%token VAR_RPZ_SIGNAL_NXDOMAIN_RA
%% %%
toplevelvars: /* empty */ | toplevelvars toplevelvar ; toplevelvars: /* empty */ | toplevelvars toplevelvar ;
@ -271,7 +273,8 @@ content_server: server_num_threads | server_verbosity | server_port |
server_ip_ratelimit_size | server_ratelimit_size | server_ip_ratelimit_size | server_ratelimit_size |
server_ratelimit_for_domain | server_ratelimit_for_domain |
server_ratelimit_below_domain | server_ratelimit_factor | server_ratelimit_below_domain | server_ratelimit_factor |
server_ip_ratelimit_factor | server_outbound_msg_retry | server_ip_ratelimit_factor | server_ratelimit_backoff |
server_ip_ratelimit_backoff | server_outbound_msg_retry |
server_send_client_subnet | server_client_subnet_zone | server_send_client_subnet | server_client_subnet_zone |
server_client_subnet_always_forward | server_client_subnet_opcode | server_client_subnet_always_forward | server_client_subnet_opcode |
server_max_client_subnet_ipv4 | server_max_client_subnet_ipv6 | server_max_client_subnet_ipv4 | server_max_client_subnet_ipv6 |
@ -455,6 +458,15 @@ rpz_log_name: VAR_RPZ_LOG_NAME STRING_ARG
cfg_parser->cfg->auths->rpz_log_name = $2; cfg_parser->cfg->auths->rpz_log_name = $2;
} }
; ;
rpz_signal_nxdomain_ra: VAR_RPZ_SIGNAL_NXDOMAIN_RA STRING_ARG
{
OUTYY(("P(rpz_signal_nxdomain_ra:%s)\n", $2));
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
yyerror("expected yes or no.");
else cfg_parser->cfg->auths->rpz_signal_nxdomain_ra = (strcmp($2, "yes")==0);
free($2);
}
;
rpzstart: VAR_RPZ rpzstart: VAR_RPZ
{ {
@ -478,7 +490,7 @@ contents_rpz: contents_rpz content_rpz
| ; | ;
content_rpz: auth_name | auth_zonefile | rpz_tag | auth_master | auth_url | content_rpz: auth_name | auth_zonefile | rpz_tag | auth_master | auth_url |
auth_allow_notify | rpz_action_override | rpz_cname_override | auth_allow_notify | rpz_action_override | rpz_cname_override |
rpz_log | rpz_log_name rpz_log | rpz_log_name | rpz_signal_nxdomain_ra | auth_for_downstream
; ;
server_num_threads: VAR_NUM_THREADS STRING_ARG server_num_threads: VAR_NUM_THREADS STRING_ARG
{ {
@ -2494,6 +2506,26 @@ server_ratelimit_factor: VAR_RATELIMIT_FACTOR STRING_ARG
free($2); free($2);
} }
; ;
server_ip_ratelimit_backoff: VAR_IP_RATELIMIT_BACKOFF STRING_ARG
{
OUTYY(("P(server_ip_ratelimit_backoff:%s)\n", $2));
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
yyerror("expected yes or no.");
else cfg_parser->cfg->ip_ratelimit_backoff =
(strcmp($2, "yes")==0);
free($2);
}
;
server_ratelimit_backoff: VAR_RATELIMIT_BACKOFF STRING_ARG
{
OUTYY(("P(server_ratelimit_backoff:%s)\n", $2));
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
yyerror("expected yes or no.");
else cfg_parser->cfg->ratelimit_backoff =
(strcmp($2, "yes")==0);
free($2);
}
;
server_outbound_msg_retry: VAR_OUTBOUND_MSG_RETRY STRING_ARG server_outbound_msg_retry: VAR_OUTBOUND_MSG_RETRY STRING_ARG
{ {
OUTYY(("P(server_outbound_msg_retry:%s)\n", $2)); OUTYY(("P(server_outbound_msg_retry:%s)\n", $2));

View File

@ -138,6 +138,7 @@ fptr_whitelist_comm_timer(void (*fptr)(void*))
else if(fptr == &auth_xfer_probe_timer_callback) return 1; else if(fptr == &auth_xfer_probe_timer_callback) return 1;
else if(fptr == &auth_xfer_transfer_timer_callback) return 1; else if(fptr == &auth_xfer_transfer_timer_callback) return 1;
else if(fptr == &mesh_serve_expired_callback) return 1; else if(fptr == &mesh_serve_expired_callback) return 1;
else if(fptr == &serviced_timer_cb) return 1;
#ifdef USE_DNSTAP #ifdef USE_DNSTAP
else if(fptr == &mq_wakeup_cb) return 1; else if(fptr == &mq_wakeup_cb) return 1;
#endif #endif
@ -334,9 +335,10 @@ fptr_whitelist_hash_markdelfunc(lruhash_markdelfunc_type fptr)
int int
fptr_whitelist_modenv_send_query(struct outbound_entry* (*fptr)( fptr_whitelist_modenv_send_query(struct outbound_entry* (*fptr)(
struct query_info* qinfo, uint16_t flags, int dnssec, int want_dnssec, struct query_info* qinfo, uint16_t flags, int dnssec, int want_dnssec,
int nocaps, struct sockaddr_storage* addr, socklen_t addrlen, int nocaps, int check_ratelimit, struct sockaddr_storage* addr,
uint8_t* zone, size_t zonelen, int tcp_upstream, int ssl_upstream, char* tls_auth_name, socklen_t addrlen, uint8_t* zone, size_t zonelen, int tcp_upstream,
struct module_qstate* q)) int ssl_upstream, char* tls_auth_name, struct module_qstate* q,
int* was_ratelimited))
{ {
if(fptr == &worker_send_query) return 1; if(fptr == &worker_send_query) return 1;
else if(fptr == &libworker_send_query) return 1; else if(fptr == &libworker_send_query) return 1;

View File

@ -211,9 +211,10 @@ int fptr_whitelist_hash_markdelfunc(lruhash_markdelfunc_type fptr);
*/ */
int fptr_whitelist_modenv_send_query(struct outbound_entry* (*fptr)( int fptr_whitelist_modenv_send_query(struct outbound_entry* (*fptr)(
struct query_info* qinfo, uint16_t flags, int dnssec, int want_dnssec, struct query_info* qinfo, uint16_t flags, int dnssec, int want_dnssec,
int nocaps, struct sockaddr_storage* addr, socklen_t addrlen, int nocaps, int check_ratelimit, struct sockaddr_storage* addr,
uint8_t* zone, size_t zonelen, int tcp_upstream, int ssl_upstream, char* tls_auth_name, socklen_t addrlen, uint8_t* zone, size_t zonelen, int tcp_upstream,
struct module_qstate* q)); int ssl_upstream, char* tls_auth_name, struct module_qstate* q,
int* was_ratelimited));
/** /**
* Check function pointer whitelist for module_env detach_subs callback values. * Check function pointer whitelist for module_env detach_subs callback values.

View File

@ -3784,6 +3784,7 @@
4308, 4308,
4309, 4309,
4310, 4310,
4319,
4320, 4320,
4321, 4321,
4322, 4322,
@ -4054,7 +4055,6 @@
5026, 5026,
5027, 5027,
5029, 5029,
5030,
5031, 5031,
5042, 5042,
5043, 5043,

View File

@ -350,6 +350,7 @@ struct module_env {
* EDNS, the answer is likely to be useless for this domain. * EDNS, the answer is likely to be useless for this domain.
* @param nocaps: do not use caps_for_id, use the qname as given. * @param nocaps: do not use caps_for_id, use the qname as given.
* (ignored if caps_for_id is disabled). * (ignored if caps_for_id is disabled).
* @param check_ratelimit: if set, will check ratelimit before sending out.
* @param addr: where to. * @param addr: where to.
* @param addrlen: length of addr. * @param addrlen: length of addr.
* @param zone: delegation point name. * @param zone: delegation point name.
@ -359,6 +360,8 @@ struct module_env {
* @param tls_auth_name: if ssl_upstream, use this name with TLS * @param tls_auth_name: if ssl_upstream, use this name with TLS
* authentication. * authentication.
* @param q: which query state to reactivate upon return. * @param q: which query state to reactivate upon return.
* @param was_ratelimited: it will signal back if the query failed to pass the
* ratelimit check.
* @return: false on failure (memory or socket related). no query was * @return: false on failure (memory or socket related). no query was
* sent. Or returns an outbound entry with qsent and qstate set. * sent. Or returns an outbound entry with qsent and qstate set.
* This outbound_entry will be used on later module invocations * This outbound_entry will be used on later module invocations
@ -366,9 +369,10 @@ struct module_env {
*/ */
struct outbound_entry* (*send_query)(struct query_info* qinfo, struct outbound_entry* (*send_query)(struct query_info* qinfo,
uint16_t flags, int dnssec, int want_dnssec, int nocaps, uint16_t flags, int dnssec, int want_dnssec, int nocaps,
int check_ratelimit,
struct sockaddr_storage* addr, socklen_t addrlen, struct sockaddr_storage* addr, socklen_t addrlen,
uint8_t* zone, size_t zonelen, int tcp_upstream, int ssl_upstream, uint8_t* zone, size_t zonelen, int tcp_upstream, int ssl_upstream,
char* tls_auth_name, struct module_qstate* q); char* tls_auth_name, struct module_qstate* q, int* was_ratelimited);
/** /**
* Detach-subqueries. * Detach-subqueries.

View File

@ -44,6 +44,9 @@
#ifdef HAVE_NET_IF_H #ifdef HAVE_NET_IF_H
#include <net/if.h> #include <net/if.h>
#endif #endif
#ifdef HAVE_NETIOAPI_H
#include <netioapi.h>
#endif
#include "util/net_help.h" #include "util/net_help.h"
#include "util/log.h" #include "util/log.h"
#include "util/data/dname.h" #include "util/data/dname.h"
@ -52,6 +55,7 @@
#include "util/config_file.h" #include "util/config_file.h"
#include "sldns/parseutil.h" #include "sldns/parseutil.h"
#include "sldns/wire2str.h" #include "sldns/wire2str.h"
#include "sldns/str2wire.h"
#include <fcntl.h> #include <fcntl.h>
#ifdef HAVE_OPENSSL_SSL_H #ifdef HAVE_OPENSSL_SSL_H
#include <openssl/ssl.h> #include <openssl/ssl.h>
@ -476,6 +480,42 @@ int authextstrtoaddr(char* str, struct sockaddr_storage* addr,
return ipstrtoaddr(str, port, addr, addrlen); return ipstrtoaddr(str, port, addr, addrlen);
} }
uint8_t* authextstrtodname(char* str, int* port, char** auth_name)
{
char* s;
uint8_t* dname;
size_t dname_len;
*port = UNBOUND_DNS_PORT;
*auth_name = NULL;
if((s=strchr(str, '@'))) {
char* hash = strchr(s+1, '#');
if(hash) {
*auth_name = hash+1;
} else {
*auth_name = NULL;
}
*port = atoi(s+1);
if(*port == 0) {
if(!hash && strcmp(s+1,"0")!=0)
return 0;
if(hash && strncmp(s+1,"0#",2)!=0)
return 0;
}
*s = 0;
dname = sldns_str2wire_dname(str, &dname_len);
*s = '@';
} else if((s=strchr(str, '#'))) {
*port = UNBOUND_DNS_OVER_TLS_PORT;
*auth_name = s+1;
*s = 0;
dname = sldns_str2wire_dname(str, &dname_len);
*s = '#';
} else {
dname = sldns_str2wire_dname(str, &dname_len);
}
return dname;
}
/** store port number into sockaddr structure */ /** store port number into sockaddr structure */
void void
sockaddr_store_port(struct sockaddr_storage* addr, socklen_t addrlen, int port) sockaddr_store_port(struct sockaddr_storage* addr, socklen_t addrlen, int port)

View File

@ -210,8 +210,8 @@ int netblockstrtoaddr(const char* ip, int port, struct sockaddr_storage* addr,
/** /**
* Convert address string, with "@port" appendix, to sockaddr. * Convert address string, with "@port" appendix, to sockaddr.
* It can also have an "#tls-auth-name" appendix (after the port). * It can also have an "#tls-auth-name" appendix (after the port).
* The returned tls-auth-name string is a pointer into the input string. * The returned auth_name string is a pointer into the input string.
* Uses DNS port by default. * Uses DNS port by default; TLS port when a "#tls-auth-name" is configured.
* @param str: the string * @param str: the string
* @param addr: where to store sockaddr. * @param addr: where to store sockaddr.
* @param addrlen: length of stored sockaddr is returned. * @param addrlen: length of stored sockaddr is returned.
@ -221,6 +221,19 @@ int netblockstrtoaddr(const char* ip, int port, struct sockaddr_storage* addr,
int authextstrtoaddr(char* str, struct sockaddr_storage* addr, int authextstrtoaddr(char* str, struct sockaddr_storage* addr,
socklen_t* addrlen, char** auth_name); socklen_t* addrlen, char** auth_name);
/**
* Convert domain string, with "@port" appendix, to dname.
* It can also have an "#tls-auth-name" appendix (after the port).
* The return port is the parsed port.
* Uses DNS port by default; TLS port when a "#tls-auth-name" is configured.
* The returned auth_name string is a pointer into the input string.
* @param str: the string
* @param port: pointer to be assigned the parsed port value.
* @param auth_name: returned pointer to tls_auth_name, or NULL if none.
* @return pointer to the dname.
*/
uint8_t* authextstrtodname(char* str, int* port, char** auth_name);
/** /**
* Store port number into sockaddr structure * Store port number into sockaddr structure
* @param addr: sockaddr structure, ip4 or ip6. * @param addr: sockaddr structure, ip4 or ip6.

View File

@ -1146,6 +1146,8 @@ reclaim_tcp_handler(struct comm_point* c)
} }
c->tcp_more_read_again = NULL; c->tcp_more_read_again = NULL;
c->tcp_more_write_again = NULL; c->tcp_more_write_again = NULL;
c->tcp_byte_count = 0;
sldns_buffer_clear(c->buffer);
} }
/** do the callback when writing is done */ /** do the callback when writing is done */

View File

@ -767,15 +767,15 @@ val_dsset_isusable(struct ub_packed_rrset_key* ds_rrset)
sldns_lookup_table *lt; sldns_lookup_table *lt;
char herr[64], aerr[64]; char herr[64], aerr[64];
lt = sldns_lookup_by_id(sldns_hashes, lt = sldns_lookup_by_id(sldns_hashes,
(int)ds_get_digest_algo(ds_rrset, i)); (int)ds_get_digest_algo(ds_rrset, 0));
if(lt) snprintf(herr, sizeof(herr), "%s", lt->name); if(lt) snprintf(herr, sizeof(herr), "%s", lt->name);
else snprintf(herr, sizeof(herr), "%d", else snprintf(herr, sizeof(herr), "%d",
(int)ds_get_digest_algo(ds_rrset, i)); (int)ds_get_digest_algo(ds_rrset, 0));
lt = sldns_lookup_by_id(sldns_algorithms, lt = sldns_lookup_by_id(sldns_algorithms,
(int)ds_get_key_algo(ds_rrset, i)); (int)ds_get_key_algo(ds_rrset, 0));
if(lt) snprintf(aerr, sizeof(aerr), "%s", lt->name); if(lt) snprintf(aerr, sizeof(aerr), "%s", lt->name);
else snprintf(aerr, sizeof(aerr), "%d", else snprintf(aerr, sizeof(aerr), "%d",
(int)ds_get_key_algo(ds_rrset, i)); (int)ds_get_key_algo(ds_rrset, 0));
verbose(VERB_ALGO, "DS unsupported, hash %s %s, " verbose(VERB_ALGO, "DS unsupported, hash %s %s, "
"key algorithm %s %s", herr, "key algorithm %s %s", herr,
(ds_digest_algo_is_supported(ds_rrset, 0)? (ds_digest_algo_is_supported(ds_rrset, 0)?