unbound: Vendor import 1.16.0

This commit is contained in:
Cy Schubert 2022-06-08 07:43:13 -07:00
parent 3574dc0bd8
commit 5f9f82264b
148 changed files with 10312 additions and 7374 deletions

View File

@ -57,7 +57,7 @@ LEX=@LEX@
STRIP=@STRIP@
CC=@CC@
CPPFLAGS=-I. @CPPFLAGS@
PYTHON_CPPFLAGS=-I. @PYTHON_CPPFLAGS@
PYTHON_CPPFLAGS=-I. -I$(srcdir) @PYTHON_CPPFLAGS@
CFLAGS=-DSRCDIR=$(srcdir) @CFLAGS@
LDFLAGS=@LDFLAGS@
LIBS=@LIBS@
@ -344,7 +344,18 @@ longcheck: longtest
test: unittest$(EXEEXT) testbound$(EXEEXT)
./unittest$(EXEEXT)
./testbound$(EXEEXT) -s
for x in $(srcdir)/testdata/*.rpl; do printf "%s" "$$x "; if ./testbound$(EXEEXT) -p $$x >/dev/null 2>&1; then echo OK; else echo failed; exit 1; fi done
for x in $(srcdir)/testdata/*.rpl; do \
printf "%s" "$$x "; \
if ./testbound$(EXEEXT) -p $$x >/dev/null 2>&1; then \
echo OK; \
else \
echo failed; \
./testbound$(EXEEXT) -p $$x -o -vvvvv; \
printf "%s" "$$x "; \
echo failed; \
exit 1; \
fi; \
done
@echo test OK
longtest: tests
@ -556,7 +567,7 @@ pythonmod-install:
pyunbound-install:
$(INSTALL) -m 755 -d $(DESTDIR)$(PYTHON_SITE_PKG)
$(INSTALL) -c -m 644 $(srcdir)/libunbound/python/unbound.py $(DESTDIR)$(PYTHON_SITE_PKG)/unbound.py
$(INSTALL) -c -m 644 libunbound/python/unbound.py $(DESTDIR)$(PYTHON_SITE_PKG)/unbound.py
$(LIBTOOL) --mode=install cp _unbound.la $(DESTDIR)$(PYTHON_SITE_PKG)
$(LIBTOOL) --mode=finish $(DESTDIR)$(PYTHON_SITE_PKG)
@ -583,6 +594,8 @@ install-lib: lib $(UNBOUND_EVENT_INSTALL)
echo ".so man3/libunbound.3" > $(DESTDIR)$(mandir)/man3/$$mpage.3 ; \
done
$(LIBTOOL) --mode=install cp unbound.h $(DESTDIR)$(includedir)/unbound.h
$(INSTALL) -m 755 -d $(DESTDIR)$(libdir)/pkgconfig
$(INSTALL) -m 644 contrib/libunbound.pc $(DESTDIR)$(libdir)/pkgconfig
$(LIBTOOL) --mode=install cp libunbound.la $(DESTDIR)$(libdir)
$(LIBTOOL) --mode=finish $(DESTDIR)$(libdir)
@ -592,8 +605,6 @@ install-all: all $(PYTHONMOD_INSTALL) $(PYUNBOUND_INSTALL) $(UNBOUND_EVENT_INSTA
$(INSTALL) -m 755 -d $(DESTDIR)$(mandir)/man8
$(INSTALL) -m 755 -d $(DESTDIR)$(mandir)/man5
$(INSTALL) -m 755 -d $(DESTDIR)$(mandir)/man1
$(INSTALL) -m 755 -d $(DESTDIR)$(libdir)/pkgconfig
$(INSTALL) -m 644 contrib/libunbound.pc $(DESTDIR)$(libdir)/pkgconfig
$(LIBTOOL) --mode=install cp -f unbound$(EXEEXT) $(DESTDIR)$(sbindir)/unbound$(EXEEXT)
$(LIBTOOL) --mode=install cp -f unbound-checkconf$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-checkconf$(EXEEXT)
$(LIBTOOL) --mode=install cp -f unbound-control$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-control$(EXEEXT)
@ -1248,7 +1259,7 @@ cachedump.lo cachedump.o: $(srcdir)/daemon/cachedump.c config.h $(srcdir)/daemon
$(srcdir)/util/regional.h $(srcdir)/util/net_help.h $(srcdir)/util/data/dname.h $(srcdir)/iterator/iterator.h \
$(srcdir)/services/outbound_list.h $(srcdir)/iterator/iter_delegpt.h $(srcdir)/iterator/iter_utils.h \
$(srcdir)/iterator/iter_resptype.h $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h \
$(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h
$(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h $(srcdir)/util/config_file.h $(srcdir)/services/outside_network.h
daemon.lo daemon.o: $(srcdir)/daemon/daemon.c config.h $(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h \
$(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
$(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h \

View File

@ -18,27 +18,45 @@ AC_DEFUN([AC_PYTHON_DEVEL],[
print(sys.version.split()[[0]])"`
fi
#
# Check if you have distutils, else fail
#
AC_MSG_CHECKING([for the distutils Python package])
if ac_distutils_result=`$PYTHON -c "import distutils" 2>&1`; then
# Check if you have sysconfig
AC_MSG_CHECKING([for the sysconfig Python module])
if ac_sysconfig_result=`$PYTHON -c "import sysconfig" 2>&1`; then
AC_MSG_RESULT([yes])
else
sysconfig_module="sysconfig"
# if yes, use sysconfig, because distutils is deprecated.
else
AC_MSG_RESULT([no])
AC_MSG_ERROR([cannot import Python module "distutils".
Please check your Python installation. The error was:
$ac_distutils_result])
PYTHON_VERSION=""
fi
# if no, try to use distutils
#
# Check if you have distutils, else fail
#
AC_MSG_CHECKING([for the distutils Python package])
if ac_distutils_result=`$PYTHON -c "import distutils" 2>&1`; then
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
AC_MSG_ERROR([cannot import Python module "distutils".
Please check your Python installation. The error was:
$ac_distutils_result])
PYTHON_VERSION=""
fi
sysconfig_module="distutils.sysconfig"
fi
#
# Check for Python include path
#
AC_MSG_CHECKING([for Python include path])
if test -z "$PYTHON_CPPFLAGS"; then
python_path=`$PYTHON -c "import distutils.sysconfig; \
print(distutils.sysconfig.get_python_inc());"`
if test "$sysconfig_module" = "sysconfig"; then
python_path=`$PYTHON -c 'import sysconfig; \
print(sysconfig.get_path("include"));'`
else
python_path=`$PYTHON -c "import distutils.sysconfig; \
print(distutils.sysconfig.get_python_inc());"`
fi
if test -n "${python_path}"; then
python_path="-I$python_path"
fi
@ -52,14 +70,14 @@ $ac_distutils_result])
#
AC_MSG_CHECKING([for Python library path])
if test -z "$PYTHON_LDFLAGS"; then
PYTHON_LDFLAGS=`$PYTHON -c "from distutils.sysconfig import *; \
PYTHON_LDFLAGS=`$PYTHON -c "from $sysconfig_module import *; \
print('-L'+get_config_var('LIBDIR')+' -L'+get_config_var('LIBDEST')+' '+get_config_var('BLDLIBRARY'));"`
fi
AC_MSG_RESULT([$PYTHON_LDFLAGS])
AC_SUBST([PYTHON_LDFLAGS])
if test -z "$PYTHON_LIBDIR"; then
PYTHON_LIBDIR=`$PYTHON -c "from distutils.sysconfig import *; \
PYTHON_LIBDIR=`$PYTHON -c "from $sysconfig_module import *; \
print(get_config_var('LIBDIR'));"`
fi
@ -68,8 +86,13 @@ $ac_distutils_result])
#
AC_MSG_CHECKING([for Python site-packages path])
if test -z "$PYTHON_SITE_PKG"; then
PYTHON_SITE_PKG=`$PYTHON -c "import distutils.sysconfig; \
print(distutils.sysconfig.get_python_lib(1,0));"`
if test "$sysconfig_module" = "sysconfig"; then
PYTHON_SITE_PKG=`$PYTHON -c 'import sysconfig; \
print(sysconfig.get_path("platlib"));'`
else
PYTHON_SITE_PKG=`$PYTHON -c "import distutils.sysconfig; \
print(distutils.sysconfig.get_python_lib(1,0));"`
fi
fi
AC_MSG_RESULT([$PYTHON_SITE_PKG])
AC_SUBST([PYTHON_SITE_PKG])

34
config.guess vendored
View File

@ -4,7 +4,7 @@
# shellcheck disable=SC2006,SC2268 # see below for rationale
timestamp='2022-01-09'
timestamp='2022-05-25'
# 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
@ -1151,16 +1151,27 @@ EOF
;;
x86_64:Linux:*:*)
set_cc_for_build
CPU=$UNAME_MACHINE
LIBCABI=$LIBC
if test "$CC_FOR_BUILD" != no_compiler_found; then
if (echo '#ifdef __ILP32__'; echo IS_X32; echo '#endif') | \
(CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
grep IS_X32 >/dev/null
then
LIBCABI=${LIBC}x32
fi
ABI=64
sed 's/^ //' << EOF > "$dummy.c"
#ifdef __i386__
ABI=x86
#else
#ifdef __ILP32__
ABI=x32
#endif
#endif
EOF
cc_set_abi=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^ABI' | sed 's, ,,g'`
eval "$cc_set_abi"
case $ABI in
x86) CPU=i686 ;;
x32) LIBCABI=${LIBC}x32 ;;
esac
fi
GUESS=$UNAME_MACHINE-pc-linux-$LIBCABI
GUESS=$CPU-pc-linux-$LIBCABI
;;
xtensa*:Linux:*:*)
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
@ -1367,8 +1378,11 @@ EOF
BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
GUESS=i586-pc-haiku
;;
x86_64:Haiku:*:*)
GUESS=x86_64-unknown-haiku
ppc:Haiku:*:*) # Haiku running on Apple PowerPC
GUESS=powerpc-apple-haiku
;;
*:Haiku:*:*) # Haiku modern gcc (not bound by BeOS compat)
GUESS=$UNAME_MACHINE-unknown-haiku
;;
SX-4:SUPER-UX:*:*)
GUESS=sx4-nec-superux$UNAME_RELEASE

View File

@ -971,6 +971,10 @@
/* Define to 1 if you need to in order for `stat' and other things to work. */
#undef _POSIX_SOURCE
/* defined to use gcc ansi snprintf and sscanf that understands %lld when
compiled for windows. */
#undef __USE_MINGW_ANSI_STDIO
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
@ -1150,7 +1154,7 @@
#include <ws2tcpip.h>
#endif
#ifndef USE_WINSOCK
#if !defined(USE_WINSOCK) || !defined(HAVE_SNPRINTF) || defined(SNPRINTF_RET_BROKEN) || defined(__USE_MINGW_ANSI_STDIO)
#define ARG_LL "%ll"
#else
#define ARG_LL "%I64"

116
configure vendored
View File

@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for unbound 1.15.0.
# Generated by GNU Autoconf 2.69 for unbound 1.16.0.
#
# Report bugs to <unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues>.
#
@ -591,8 +591,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='unbound'
PACKAGE_TARNAME='unbound'
PACKAGE_VERSION='1.15.0'
PACKAGE_STRING='unbound 1.15.0'
PACKAGE_VERSION='1.16.0'
PACKAGE_STRING='unbound 1.16.0'
PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues'
PACKAGE_URL=''
@ -813,6 +813,7 @@ infodir
docdir
oldincludedir
includedir
runstatedir
localstatedir
sharedstatedir
sysconfdir
@ -964,6 +965,7 @@ datadir='${datarootdir}'
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
runstatedir='${localstatedir}/run'
includedir='${prefix}/include'
oldincludedir='/usr/include'
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
@ -1216,6 +1218,15 @@ do
| -silent | --silent | --silen | --sile | --sil)
silent=yes ;;
-runstatedir | --runstatedir | --runstatedi | --runstated \
| --runstate | --runstat | --runsta | --runst | --runs \
| --run | --ru | --r)
ac_prev=runstatedir ;;
-runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
| --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
| --run=* | --ru=* | --r=*)
runstatedir=$ac_optarg ;;
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
ac_prev=sbindir ;;
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@ -1353,7 +1364,7 @@ fi
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
datadir sysconfdir sharedstatedir localstatedir includedir \
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
libdir localedir mandir
libdir localedir mandir runstatedir
do
eval ac_val=\$$ac_var
# Remove trailing slashes.
@ -1466,7 +1477,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures unbound 1.15.0 to adapt to many kinds of systems.
\`configure' configures unbound 1.16.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1506,6 +1517,7 @@ Fine tuning of the installation directories:
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
--runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
--libdir=DIR object code libraries [EPREFIX/lib]
--includedir=DIR C header files [PREFIX/include]
--oldincludedir=DIR C header files for non-gcc [/usr/include]
@ -1531,7 +1543,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of unbound 1.15.0:";;
short | recursive ) echo "Configuration of unbound 1.16.0:";;
esac
cat <<\_ACEOF
@ -1773,7 +1785,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
unbound configure 1.15.0
unbound configure 1.16.0
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@ -2482,7 +2494,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by unbound $as_me 1.15.0, which was
It was created by unbound $as_me 1.16.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@ -2832,13 +2844,13 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
UNBOUND_VERSION_MAJOR=1
UNBOUND_VERSION_MINOR=15
UNBOUND_VERSION_MINOR=16
UNBOUND_VERSION_MICRO=0
LIBUNBOUND_CURRENT=9
LIBUNBOUND_REVISION=15
LIBUNBOUND_REVISION=16
LIBUNBOUND_AGE=1
# 1.0.0 had 0:12:0
# 1.0.1 had 0:13:0
@ -2921,6 +2933,7 @@ LIBUNBOUND_AGE=1
# 1.13.2 had 9:13:1
# 1.14.0 had 9:14:1
# 1.15.0 had 9:15:1
# 1.16.0 had 9:16:1
# Current -- the number of the binary API that we're implementing
# Revision -- which iteration of the implementation of the binary
@ -17455,22 +17468,38 @@ fi
print(sys.version.split()[0])"`
fi
#
# Check if you have distutils, else fail
#
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for the distutils Python package" >&5
$as_echo_n "checking for the distutils Python package... " >&6; }
if ac_distutils_result=`$PYTHON -c "import distutils" 2>&1`; then
# Check if you have sysconfig
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for the sysconfig Python module" >&5
$as_echo_n "checking for the sysconfig Python module... " >&6; }
if ac_sysconfig_result=`$PYTHON -c "import sysconfig" 2>&1`; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
else
sysconfig_module="sysconfig"
# if yes, use sysconfig, because distutils is deprecated.
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
as_fn_error $? "cannot import Python module \"distutils\".
Please check your Python installation. The error was:
$ac_distutils_result" "$LINENO" 5
PYTHON_VERSION=""
fi
# if no, try to use distutils
#
# Check if you have distutils, else fail
#
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for the distutils Python package" >&5
$as_echo_n "checking for the distutils Python package... " >&6; }
if ac_distutils_result=`$PYTHON -c "import distutils" 2>&1`; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
as_fn_error $? "cannot import Python module \"distutils\".
Please check your Python installation. The error was:
$ac_distutils_result" "$LINENO" 5
PYTHON_VERSION=""
fi
sysconfig_module="distutils.sysconfig"
fi
#
# Check for Python include path
@ -17478,8 +17507,13 @@ $ac_distutils_result" "$LINENO" 5
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Python include path" >&5
$as_echo_n "checking for Python include path... " >&6; }
if test -z "$PYTHON_CPPFLAGS"; then
python_path=`$PYTHON -c "import distutils.sysconfig; \
print(distutils.sysconfig.get_python_inc());"`
if test "$sysconfig_module" = "sysconfig"; then
python_path=`$PYTHON -c 'import sysconfig; \
print(sysconfig.get_path("include"));'`
else
python_path=`$PYTHON -c "import distutils.sysconfig; \
print(distutils.sysconfig.get_python_inc());"`
fi
if test -n "${python_path}"; then
python_path="-I$python_path"
fi
@ -17495,7 +17529,7 @@ $as_echo "$PYTHON_CPPFLAGS" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Python library path" >&5
$as_echo_n "checking for Python library path... " >&6; }
if test -z "$PYTHON_LDFLAGS"; then
PYTHON_LDFLAGS=`$PYTHON -c "from distutils.sysconfig import *; \
PYTHON_LDFLAGS=`$PYTHON -c "from $sysconfig_module import *; \
print('-L'+get_config_var('LIBDIR')+' -L'+get_config_var('LIBDEST')+' '+get_config_var('BLDLIBRARY'));"`
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON_LDFLAGS" >&5
@ -17503,7 +17537,7 @@ $as_echo "$PYTHON_LDFLAGS" >&6; }
if test -z "$PYTHON_LIBDIR"; then
PYTHON_LIBDIR=`$PYTHON -c "from distutils.sysconfig import *; \
PYTHON_LIBDIR=`$PYTHON -c "from $sysconfig_module import *; \
print(get_config_var('LIBDIR'));"`
fi
@ -17513,8 +17547,13 @@ $as_echo "$PYTHON_LDFLAGS" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Python site-packages path" >&5
$as_echo_n "checking for Python site-packages path... " >&6; }
if test -z "$PYTHON_SITE_PKG"; then
PYTHON_SITE_PKG=`$PYTHON -c "import distutils.sysconfig; \
print(distutils.sysconfig.get_python_lib(1,0));"`
if test "$sysconfig_module" = "sysconfig"; then
PYTHON_SITE_PKG=`$PYTHON -c 'import sysconfig; \
print(sysconfig.get_path("platlib"));'`
else
PYTHON_SITE_PKG=`$PYTHON -c "import distutils.sysconfig; \
print(distutils.sysconfig.get_python_lib(1,0));"`
fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON_SITE_PKG" >&5
$as_echo "$PYTHON_SITE_PKG" >&6; }
@ -20181,6 +20220,9 @@ fi
WIN_CHECKCONF_OBJ_LINK="rsrc_unbound_checkconf.o"
$as_echo "#define __USE_MINGW_ANSI_STDIO 1" >>confdefs.h
fi
if test $ac_cv_func_getaddrinfo = no; then
case " $LIBOBJS " in
@ -21678,10 +21720,16 @@ $as_echo_n "checking for libmnl... " >&6; }
withval="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr"
fi
for dir in $withval ; do
if test -f "$dir/include/libmnl/libmnl.h"; then
if test -f "$dir/include/libmnl/libmnl.h" -o -f "$dir/include/libmnl/libmnl/libmnl.h"; then
found_libmnl="yes"
if test "$dir" != "/usr"; then
CPPFLAGS="$CPPFLAGS -I$dir/include"
extralibmnl=""
if test -f "$dir/include/libmnl/libmnl/libmnl.h"; then
extralibmnl="/libmnl"
fi
if test "$dir" != "/usr" -o -n "$extralibmnl"; then
CPPFLAGS="$CPPFLAGS -I$dir/include$extralibmnl"
fi
if test "$dir" != "/usr"; then
LDFLAGS="$LDFLAGS -L$dir/lib"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: found in $dir" >&5
@ -21886,7 +21934,7 @@ _ACEOF
version=1.15.0
version=1.16.0
date=`date +'%b %e, %Y'`
@ -22405,7 +22453,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by unbound $as_me 1.15.0, which was
This file was extended by unbound $as_me 1.16.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@ -22471,7 +22519,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
unbound config.status 1.15.0
unbound config.status 1.16.0
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"

View File

@ -10,7 +10,7 @@ sinclude(dnscrypt/dnscrypt.m4)
# must be numbers. ac_defun because of later processing
m4_define([VERSION_MAJOR],[1])
m4_define([VERSION_MINOR],[15])
m4_define([VERSION_MINOR],[16])
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_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR])
@ -18,7 +18,7 @@ AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR])
AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO])
LIBUNBOUND_CURRENT=9
LIBUNBOUND_REVISION=15
LIBUNBOUND_REVISION=16
LIBUNBOUND_AGE=1
# 1.0.0 had 0:12:0
# 1.0.1 had 0:13:0
@ -101,6 +101,7 @@ LIBUNBOUND_AGE=1
# 1.13.2 had 9:13:1
# 1.14.0 had 9:14:1
# 1.15.0 had 9:15:1
# 1.16.0 had 9:16:1
# Current -- the number of the binary API that we're implementing
# Revision -- which iteration of the implementation of the binary
@ -1553,6 +1554,7 @@ if test "$USE_WINSOCK" = 1; then
AC_SUBST(WIN_CONTROL_OBJ_LINK)
WIN_CHECKCONF_OBJ_LINK="rsrc_unbound_checkconf.o"
AC_SUBST(WIN_CHECKCONF_OBJ_LINK)
AC_DEFINE(__USE_MINGW_ANSI_STDIO, 1, [defined to use gcc ansi snprintf and sscanf that understands %lld when compiled for windows.])
fi
if test $ac_cv_func_getaddrinfo = no; then
AC_LIBOBJ([fake-rfc2553])
@ -1878,11 +1880,17 @@ case "$enable_ipset" in
withval="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr"
fi
for dir in $withval ; do
if test -f "$dir/include/libmnl/libmnl.h"; then
if test -f "$dir/include/libmnl/libmnl.h" -o -f "$dir/include/libmnl/libmnl/libmnl.h"; then
found_libmnl="yes"
dnl assume /usr is in default path.
extralibmnl=""
if test -f "$dir/include/libmnl/libmnl/libmnl.h"; then
extralibmnl="/libmnl"
fi
if test "$dir" != "/usr" -o -n "$extralibmnl"; then
CPPFLAGS="$CPPFLAGS -I$dir/include$extralibmnl"
fi
if test "$dir" != "/usr"; then
CPPFLAGS="$CPPFLAGS -I$dir/include"
LDFLAGS="$LDFLAGS -L$dir/lib"
fi
AC_MSG_RESULT(found in $dir)
@ -2060,7 +2068,7 @@ dnl includes
#include <ws2tcpip.h>
#endif
#ifndef USE_WINSOCK
#if !defined(USE_WINSOCK) || !defined(HAVE_SNPRINTF) || defined(SNPRINTF_RET_BROKEN) || defined(__USE_MINGW_ANSI_STDIO)
#define ARG_LL "%ll"
#else
#define ARG_LL "%I64"

View File

@ -487,3 +487,38 @@ acl_list_get_mem(struct acl_list* acl)
if(!acl) return 0;
return sizeof(*acl) + regional_get_mem(acl->region);
}
const char* acl_access_to_str(enum acl_access acl)
{
switch(acl) {
case acl_deny: return "deny";
case acl_refuse: return "refuse";
case acl_deny_non_local: return "deny_non_local";
case acl_refuse_non_local: return "refuse_non_local";
case acl_allow: return "allow";
case acl_allow_snoop: return "allow_snoop";
case acl_allow_setrd: return "allow_setrd";
default: break;
}
return "unknown";
}
void
log_acl_action(const char* action, struct sockaddr_storage* addr,
socklen_t addrlen, enum acl_access acl, struct acl_addr* acladdr)
{
char a[128], n[128];
uint16_t port;
addr_to_str(addr, addrlen, a, sizeof(a));
port = ntohs(((struct sockaddr_in*)addr)->sin_port);
if(acladdr) {
addr_to_str(&acladdr->node.addr, acladdr->node.addrlen,
n, sizeof(n));
verbose(VERB_ALGO, "%s query from %s port %d because of "
"%s/%d %s", action, a, (int)port, n, acladdr->node.net,
acl_access_to_str(acl));
} else {
verbose(VERB_ALGO, "%s query from %s port %d", action, a,
(int)port);
}
}

View File

@ -154,4 +154,15 @@ acl_addr_lookup(struct acl_list* acl, struct sockaddr_storage* addr,
*/
size_t acl_list_get_mem(struct acl_list* acl);
/*
* Get string for acl access specification
* @param acl: access type value
* @return string
*/
const char* acl_access_to_str(enum acl_access acl);
/* log acl and addr for action */
void log_acl_action(const char* action, struct sockaddr_storage* addr,
socklen_t addrlen, enum acl_access acl, struct acl_addr* acladdr);
#endif /* DAEMON_ACL_LIST_H */

View File

@ -47,10 +47,12 @@
#include "services/cache/rrset.h"
#include "services/cache/dns.h"
#include "services/cache/infra.h"
#include "services/outside_network.h"
#include "util/data/msgreply.h"
#include "util/regional.h"
#include "util/net_help.h"
#include "util/data/dname.h"
#include "util/config_file.h"
#include "iterator/iterator.h"
#include "iterator/iter_delegpt.h"
#include "iterator/iter_utils.h"
@ -854,7 +856,9 @@ int print_deleg_lookup(RES* ssl, struct worker* worker, uint8_t* nm,
"cache; goes to configured roots\n");
}
/* go up? */
if(iter_dp_is_useless(&qinfo, BIT_RD, dp)) {
if(iter_dp_is_useless(&qinfo, BIT_RD, dp,
(worker->env.cfg->do_ip4 && worker->back->num_ip4 != 0),
(worker->env.cfg->do_ip6 && worker->back->num_ip6 != 0))) {
print_dp_main(ssl, dp, msg);
print_dp_details(ssl, worker, dp);
if(!ssl_printf(ssl, "cache delegation was "

View File

@ -98,7 +98,7 @@
/** ratelimit for error responses */
#define ERROR_RATELIMIT 100 /* qps */
/**
/**
* seconds to add to prefetch leeway. This is a TTL that expires old rrsets
* earlier than they should in order to put the new update into the cache.
* This additional value is to make sure that if not all TTLs are equal in
@ -484,6 +484,12 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
msg->rep, LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad,
worker->env.now_tv))
return 0;
/* TODO store the reason for the bogus reply in cache
* and implement in here instead of the hardcoded EDE */
if (worker->env.cfg->ede) {
EDNS_OPT_LIST_APPEND_EDE(&edns->opt_list_out,
worker->scratchpad, LDNS_EDE_DNSSEC_BOGUS, "");
}
error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
&msg->qinfo, id, flags, edns);
if(worker->stats.extended) {
@ -553,7 +559,7 @@ apply_respip_action(struct worker* worker, const struct query_info* qinfo,
return 1;
if(!respip_rewrite_reply(qinfo, cinfo, rep, encode_repp, &actinfo,
alias_rrset, 0, worker->scratchpad, az))
alias_rrset, 0, worker->scratchpad, az, NULL))
return 0;
/* xxx_deny actions mean dropping the reply, unless the original reply
@ -654,6 +660,12 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad,
worker->env.now_tv))
goto bail_out;
/* TODO store the reason for the bogus reply in cache
* and implement in here instead of the hardcoded EDE */
if (worker->env.cfg->ede) {
EDNS_OPT_LIST_APPEND_EDE(&edns->opt_list_out,
worker->scratchpad, LDNS_EDE_DNSSEC_BOGUS, "");
}
error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
qinfo, id, flags, edns);
rrset_array_unlock_touch(worker->env.rrset_cache,
@ -716,15 +728,25 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
if(!*partial_repp)
goto bail_out;
}
} else if(!reply_info_answer_encode(qinfo, encode_rep, id, flags,
repinfo->c->buffer, timenow, 1, worker->scratchpad,
udpsize, edns, (int)(edns->bits & EDNS_DO), *is_secure_answer)) {
if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, NULL,
LDNS_RCODE_SERVFAIL, edns, repinfo, worker->scratchpad,
worker->env.now_tv))
edns->opt_list_inplace_cb_out = NULL;
error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
qinfo, id, flags, edns);
} else {
/* We don't check the global ede as this is a warning, not
* an error */
if (*is_expired_answer == 1 &&
worker->env.cfg->ede_serve_expired && worker->env.cfg->ede) {
EDNS_OPT_LIST_APPEND_EDE(&edns->opt_list_out,
worker->scratchpad, LDNS_EDE_STALE_ANSWER, "");
}
if(!reply_info_answer_encode(qinfo, encode_rep, id, flags,
repinfo->c->buffer, timenow, 1, worker->scratchpad,
udpsize, edns, (int)(edns->bits & EDNS_DO),
*is_secure_answer)) {
if(!inplace_cb_reply_servfail_call(&worker->env, qinfo,
NULL, NULL, LDNS_RCODE_SERVFAIL, edns, repinfo,
worker->scratchpad, worker->env.now_tv))
edns->opt_list_inplace_cb_out = NULL;
error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
qinfo, id, flags, edns);
}
}
/* cannot send the reply right now, because blocking network syscall
* is bad while holding locks. */
@ -741,10 +763,12 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
/** Reply to client and perform prefetch to keep cache up to date. */
static void
reply_and_prefetch(struct worker* worker, struct query_info* qinfo,
uint16_t flags, struct comm_reply* repinfo, time_t leeway, int noreply)
reply_and_prefetch(struct worker* worker, struct query_info* qinfo,
uint16_t flags, struct comm_reply* repinfo, time_t leeway, int noreply,
int rpz_passthru, struct edns_option* opt_list)
{
/* first send answer to client to keep its latency
(void)opt_list;
/* first send answer to client to keep its latency
* as small as a cachereply */
if(!noreply) {
if(repinfo->c->tcp_req_info) {
@ -755,13 +779,23 @@ reply_and_prefetch(struct worker* worker, struct query_info* qinfo,
comm_point_send_reply(repinfo);
}
server_stats_prefetch(&worker->stats, worker);
#ifdef CLIENT_SUBNET
/* Check if the subnet module is enabled. In that case pass over the
* comm_reply information for ECS generation later. The mesh states are
* unique when subnet is enabled. */
if(modstack_find(&worker->env.mesh->mods, "subnetcache") != -1
&& worker->env.unique_mesh) {
mesh_new_prefetch(worker->env.mesh, qinfo, flags, leeway +
PREFETCH_EXPIRY_ADD, rpz_passthru, repinfo, opt_list);
return;
}
#endif
/* create the prefetch in the mesh as a normal lookup without
* client addrs waiting, which has the cache blacklisted (to bypass
* the cache and go to the network for the data). */
/* this (potentially) runs the mesh for the new query */
mesh_new_prefetch(worker->env.mesh, qinfo, flags, leeway +
PREFETCH_EXPIRY_ADD);
mesh_new_prefetch(worker->env.mesh, qinfo, flags, leeway +
PREFETCH_EXPIRY_ADD, rpz_passthru, NULL, NULL);
}
/**
@ -1012,32 +1046,178 @@ answer_notify(struct worker* w, struct query_info* qinfo,
static int
deny_refuse(struct comm_point* c, enum acl_access acl,
enum acl_access deny, enum acl_access refuse,
struct worker* worker, struct comm_reply* repinfo)
struct worker* worker, struct comm_reply* repinfo,
struct acl_addr* acladdr, int ede)
{
if(acl == deny) {
if(verbosity >= VERB_ALGO) {
log_acl_action("dropped", &repinfo->addr,
repinfo->addrlen, acl, acladdr);
log_buf(VERB_ALGO, "dropped", c->buffer);
}
comm_point_drop_reply(repinfo);
if(worker->stats.extended)
worker->stats.unwanted_queries++;
return 0;
} else if(acl == refuse) {
log_addr(VERB_ALGO, "refused query from",
&repinfo->addr, repinfo->addrlen);
log_buf(VERB_ALGO, "refuse", c->buffer);
size_t opt_rr_mark;
if(verbosity >= VERB_ALGO) {
log_acl_action("refused", &repinfo->addr,
repinfo->addrlen, acl, acladdr);
log_buf(VERB_ALGO, "refuse", c->buffer);
}
if(worker->stats.extended)
worker->stats.unwanted_queries++;
if(worker_check_request(c->buffer, worker) == -1) {
comm_point_drop_reply(repinfo);
return 0; /* discard this */
}
sldns_buffer_set_limit(c->buffer, LDNS_HEADER_SIZE);
sldns_buffer_write_at(c->buffer, 4,
(uint8_t*)"\0\0\0\0\0\0\0\0", 8);
/* worker_check_request() above guarantees that the buffer contains at
* least a header and that qdcount == 1
*/
log_assert(sldns_buffer_limit(c->buffer) >= LDNS_HEADER_SIZE
&& LDNS_QDCOUNT(sldns_buffer_begin(c->buffer)) == 1);
sldns_buffer_skip(c->buffer, LDNS_HEADER_SIZE); /* skip header */
/* check additional section is present and that we respond with EDEs */
if(LDNS_ARCOUNT(sldns_buffer_begin(c->buffer)) != 1
|| !ede) {
LDNS_QDCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
LDNS_RCODE_REFUSED);
sldns_buffer_flip(c->buffer);
return 1;
}
if (!query_dname_len(c->buffer)) {
LDNS_QDCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
LDNS_RCODE_FORMERR);
sldns_buffer_set_position(c->buffer, LDNS_HEADER_SIZE);
sldns_buffer_flip(c->buffer);
return 1;
}
/* space available for query type and class? */
if (sldns_buffer_remaining(c->buffer) < 2 * sizeof(uint16_t)) {
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
LDNS_RCODE_FORMERR);
LDNS_QDCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
sldns_buffer_set_position(c->buffer, LDNS_HEADER_SIZE);
sldns_buffer_flip(c->buffer);
return 1;
}
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
LDNS_RCODE_REFUSED);
sldns_buffer_set_position(c->buffer, LDNS_HEADER_SIZE);
sldns_buffer_skip(c->buffer, (ssize_t)sizeof(uint16_t)); /* skip qtype */
sldns_buffer_skip(c->buffer, (ssize_t)sizeof(uint16_t)); /* skip qclass */
/* The OPT RR to be returned should come directly after
* the query, so mark this spot.
*/
opt_rr_mark = sldns_buffer_position(c->buffer);
/* Skip through the RR records */
if(LDNS_ANCOUNT(sldns_buffer_begin(c->buffer)) != 0 ||
LDNS_NSCOUNT(sldns_buffer_begin(c->buffer)) != 0) {
if(!skip_pkt_rrs(c->buffer,
((int)LDNS_ANCOUNT(sldns_buffer_begin(c->buffer)))+
((int)LDNS_NSCOUNT(sldns_buffer_begin(c->buffer))))) {
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
LDNS_RCODE_FORMERR);
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
sldns_buffer_set_position(c->buffer, opt_rr_mark);
sldns_buffer_flip(c->buffer);
return 1;
}
}
/* Do we have a valid OPT RR here? If not return REFUSED (could be a valid TSIG or something so no FORMERR) */
/* domain name must be the root of length 1. */
if(sldns_buffer_remaining(c->buffer) < 1 || *sldns_buffer_current(c->buffer) != 0) {
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
sldns_buffer_set_position(c->buffer, opt_rr_mark);
sldns_buffer_flip(c->buffer);
return 1;
} else {
sldns_buffer_skip(c->buffer, 1); /* skip root label */
}
if(sldns_buffer_remaining(c->buffer) < 2 ||
sldns_buffer_read_u16(c->buffer) != LDNS_RR_TYPE_OPT) {
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
sldns_buffer_set_position(c->buffer, opt_rr_mark);
sldns_buffer_flip(c->buffer);
return 1;
}
/* Write OPT RR directly after the query,
* so without the (possibly skipped) Answer and NS RRs
*/
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
sldns_buffer_clear(c->buffer); /* reset write limit */
sldns_buffer_set_position(c->buffer, opt_rr_mark);
/* Check if OPT record can be written
* 17 == root label (1) + RR type (2) + UDP Size (2)
* + Fields (4) + rdata len (2) + EDE Option code (2)
* + EDE Option length (2) + EDE info-code (2)
*/
if (sldns_buffer_available(c->buffer, 17) == 0) {
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
sldns_buffer_flip(c->buffer);
return 1;
}
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 1);
/* root label */
sldns_buffer_write_u8(c->buffer, 0);
sldns_buffer_write_u16(c->buffer, LDNS_RR_TYPE_OPT);
sldns_buffer_write_u16(c->buffer, EDNS_ADVERTISED_SIZE);
/* write OPT Record TTL Field */
sldns_buffer_write_u32(c->buffer, 0);
/* write rdata len: EDE option + length + info-code */
sldns_buffer_write_u16(c->buffer, 6);
/* write OPTIONS; add EDE option code */
sldns_buffer_write_u16(c->buffer, LDNS_EDNS_EDE);
/* write single EDE option length (for just 1 info-code) */
sldns_buffer_write_u16(c->buffer, 2);
/* write single EDE info-code */
sldns_buffer_write_u16(c->buffer, LDNS_EDE_PROHIBITED);
sldns_buffer_flip(c->buffer);
verbose(VERB_ALGO, "attached EDE code: %d", LDNS_EDE_PROHIBITED);
return 1;
}
return -1;
@ -1045,16 +1225,20 @@ deny_refuse(struct comm_point* c, enum acl_access acl,
static int
deny_refuse_all(struct comm_point* c, enum acl_access acl,
struct worker* worker, struct comm_reply* repinfo)
struct worker* worker, struct comm_reply* repinfo,
struct acl_addr* acladdr, int ede)
{
return deny_refuse(c, acl, acl_deny, acl_refuse, worker, repinfo);
return deny_refuse(c, acl, acl_deny, acl_refuse, worker, repinfo,
acladdr, ede);
}
static int
deny_refuse_non_local(struct comm_point* c, enum acl_access acl,
struct worker* worker, struct comm_reply* repinfo)
struct worker* worker, struct comm_reply* repinfo,
struct acl_addr* acladdr, int ede)
{
return deny_refuse(c, acl, acl_deny_non_local, acl_refuse_non_local, worker, repinfo);
return deny_refuse(c, acl, acl_deny_non_local, acl_refuse_non_local,
worker, repinfo, acladdr, ede);
}
int
@ -1067,12 +1251,14 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
struct lruhash_entry* e;
struct query_info qinfo;
struct edns_data edns;
struct edns_option* original_edns_list = NULL;
enum acl_access acl;
struct acl_addr* acladdr;
int rc = 0;
int need_drop = 0;
int is_expired_answer = 0;
int is_secure_answer = 0;
int rpz_passthru = 0;
/* We might have to chase a CNAME chain internally, in which case
* we'll have up to two replies and combine them to build a complete
* answer. These variables control this case. */
@ -1145,7 +1331,9 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
acladdr = acl_addr_lookup(worker->daemon->acl, &repinfo->addr,
repinfo->addrlen);
acl = acl_get_control(acladdr);
if((ret=deny_refuse_all(c, acl, worker, repinfo)) != -1)
if((ret=deny_refuse_all(c, acl, worker, repinfo, acladdr,
worker->env.cfg->ede)) != -1)
{
if(ret == 1)
goto send_reply;
@ -1338,7 +1526,8 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
if(worker->env.auth_zones &&
rpz_callback_from_worker_request(worker->env.auth_zones,
&worker->env, &qinfo, &edns, c->buffer, worker->scratchpad,
repinfo, acladdr->taglist, acladdr->taglen, &worker->stats)) {
repinfo, acladdr->taglist, acladdr->taglen, &worker->stats,
&rpz_passthru)) {
regional_free_all(worker->scratchpad);
if(sldns_buffer_limit(c->buffer) == 0) {
comm_point_drop_reply(repinfo);
@ -1364,7 +1553,8 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
/* We've looked in our local zones. If the answer isn't there, we
* might need to bail out based on ACLs now. */
if((ret=deny_refuse_non_local(c, acl, worker, repinfo)) != -1)
if((ret=deny_refuse_non_local(c, acl, worker, repinfo, acladdr,
worker->env.cfg->ede)) != -1)
{
regional_free_all(worker->scratchpad);
if(ret == 1)
@ -1383,12 +1573,17 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
* ACLs allow the snooping. */
if(!(LDNS_RD_WIRE(sldns_buffer_begin(c->buffer))) &&
acl != acl_allow_snoop ) {
if (worker->env.cfg->ede) {
EDNS_OPT_LIST_APPEND_EDE(&edns.opt_list_out,
worker->scratchpad, LDNS_EDE_NOT_AUTHORITATIVE, "");
}
error_encode(c->buffer, LDNS_RCODE_REFUSED, &qinfo,
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
sldns_buffer_read_u16_at(c->buffer, 2), NULL);
sldns_buffer_read_u16_at(c->buffer, 2), &edns);
regional_free_all(worker->scratchpad);
log_addr(VERB_ALGO, "refused nonrec (cache snoop) query from",
&repinfo->addr, repinfo->addrlen);
goto send_reply;
}
@ -1429,6 +1624,11 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
cinfo = &cinfo_tmp;
}
/* Keep the original edns list around. The pointer could change if there is
* a cached answer (through the inplace callback function there).
* No need to actually copy the contents as they shouldn't change.
* Used while prefetching and subnet is enabled. */
original_edns_list = edns.opt_list_in;
lookup_cache:
/* Lookup the cache. In case we chase an intermediate CNAME chain
* this is a two-pass operation, and lookup_qinfo is different for
@ -1461,10 +1661,13 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
< *worker->env.now)
leeway = 0;
lock_rw_unlock(&e->lock);
reply_and_prefetch(worker, lookup_qinfo,
sldns_buffer_read_u16_at(c->buffer, 2),
repinfo, leeway,
(partial_rep || need_drop));
(partial_rep || need_drop),
rpz_passthru,
original_edns_list);
if(!partial_rep) {
rc = 0;
regional_free_all(worker->scratchpad);
@ -1501,6 +1704,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
verbose(VERB_ALGO, "answer from the cache failed");
lock_rw_unlock(&e->lock);
}
if(!LDNS_RD_WIRE(sldns_buffer_begin(c->buffer))) {
if(answer_norec_from_cache(worker, &qinfo,
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
@ -1527,7 +1731,8 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
/* grab a work request structure for this new request */
mesh_new_client(worker->env.mesh, &qinfo, cinfo,
sldns_buffer_read_u16_at(c->buffer, 2),
&edns, repinfo, *(uint16_t*)(void *)sldns_buffer_begin(c->buffer));
&edns, repinfo, *(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
rpz_passthru);
regional_free_all(worker->scratchpad);
worker_mem_report(worker, NULL);
return 0;
@ -1591,6 +1796,9 @@ worker_sighandler(int sig, void* arg)
case SIGHUP:
comm_base_exit(worker->base);
break;
#endif
#ifdef SIGBREAK
case SIGBREAK:
#endif
case SIGINT:
worker->need_to_exit = 1;
@ -1709,6 +1917,9 @@ worker_init(struct worker* worker, struct config_file *cfg,
if(do_sigs) {
#ifdef SIGHUP
ub_thread_sig_unblock(SIGHUP);
#endif
#ifdef SIGBREAK
ub_thread_sig_unblock(SIGBREAK);
#endif
ub_thread_sig_unblock(SIGINT);
#ifdef SIGQUIT
@ -1726,6 +1937,9 @@ worker_init(struct worker* worker, struct config_file *cfg,
|| !comm_signal_bind(worker->comsig, SIGQUIT)
#endif
|| !comm_signal_bind(worker->comsig, SIGTERM)
#ifdef SIGBREAK
|| !comm_signal_bind(worker->comsig, SIGBREAK)
#endif
|| !comm_signal_bind(worker->comsig, SIGINT)) {
log_err("could not create signal handlers");
worker_delete(worker);

View File

@ -1,5 +1,146 @@
27 May 2022: Wouter
- Fix #684: [FTBS] configure script error with libmnl on openSUSE 15.3 (and possibly other distributions)
- Version is set to 1.16.0 for release. Release tag 1.16.0rc1.
20 May 2022: Wouter
- Fix to silence test for ede error output to the console from the
test setup script.
- Fix ede test to not use default pidfile, and use local interface.
- Fix some lint type warnings.
18 May 2022: George
- Fix typos in config_set_option for the 'num-threads' and
'ede-serve-expired' options.
15 May 2022: George
- Fix #678: [FR] modify behaviour of unbound-control rpz_enable zone,
by updating unbound-control's documentation.
12 May 2022: George
- Fix #417: prefetch and ECS causing cache corruption when used
together.
12 May 2022: Wouter
- Merge #677: Allow using system certificates not only on Windows,
from pemensik.
- For #677: Added tls-system-cert to config parser and documentation.
11 May 2022: Wouter
- Fix #673: DNS over TLS: error: SSL_handshake syscall: No route to
host.
10 May 2022: George
- Fix Python build in non-source directory; based on patch by
Michael Tokarev.
6 May 2022: Tom
- Merge PR #604: Add basic support for EDE (RFC8914).
28 April 2022: Wouter
- Fix #670: SERVFAIL problems with unbound 1.15.0 running on
OpenBSD 7.1.
8 April 2022: Wouter
- Fix zonemd check to allow unsupported algorithms to load.
If there are only unsupported algorithms, or unsupported schemes,
and no failed or successful other ZONEMD records, or malformed
or bad ZONEMD records, the unsupported records allow the zone load.
- Fix zonemd unsupported algo check.
- Fix zonemd unsupported algo check reason to not copy to next record,
and check for success for debug printout.
- Fix zonemd unsupported algo check to print unsupported reason before
zeroing it.
- Fix zonemd unsupported algo check to set reason to NULL before the
check routine, but after malformed checks, to get the correct NULL
output when the digest matches.
25 March 2022: Wouter
- Fix spelling error in comment in sldns_str2wire_svcparam_key_lookup.
23 March 2022: Wouter
- Fix #651: [FR] Better logging for refused queries.
18 March 2022: George
- Merge PR #648 from eaglegai: fix -q doesn't work when use with
'unbound-control stats_shm'.
17 March 2022: Wouter
- Fix to describe auth-zone and other configuration at the local-zone
configuration option, to allow for more broadly view of the options.
16 March 2022: Wouter
- Fix to ensure uniform handling of spaces and tabs when parsing RRs.
9 March 2022: Wouter
- Merge #644: Make `install-lib` make target install the pkg-config
file.
7 March 2022: Wouter
- Fix configure for python to use sysutils, because distutils is
deprecated. It uses sysutils when available, distutils otherwise.
3 March 2022: Wouter
- Fix #637: Integer Overflow in sldns_str2period function.
- Fix for #637: fix integer overflow checks in sldns_str2period.
2 March 2022: George
- Merge PR #632 from scottrw93: Match cnames in ipset.
- Various fixes for #632: variable initialisation, convert the qinfo
to str once, accept trailing dot in the local-zone ipset option.
2 March 2022: Wouter
- Fix compile warnings for printf ll format on mingw compile.
1 March 2022: Wouter
- Fix pythonmod for change in iter_dp_is_useless function prototype.
28 February 2022: George
- Fix #630: Unify the RPZ log messages.
- Merge #623 from rex4539: Fix typos.
28 February 2022: Wouter
- Fix #633: Document unix domain socket support for unbound-control.
- Fix for #633: updated fix with new text.
- Fix edns client subnet to add the option based on the option list,
so that it is not state dependent, after the state fix of #605 for
double EDNS options.
- Fix for edns client subnet option add fix in removal code, from review.
25 February 2022: Wouter
- Fix to detect that no IPv6 support means that IPv6 addresses are
useless for delegation point lookups.
- update Makefile dependencies.
- Fix check interface existence for support detection in remote lookup.
18 February 2022: Wouter
- Fix that address not available is squelched from the logs for
udp connect failures. It is visible on verbosity 4 and more.
- Merge #631 from mollyim: Replace OpenSSL's ERR_PACK with
ERR_GET_REASON.
16 February 2022: Wouter
- Fix for #628: fix rpz-passthru for qname trigger by localzone type.
15 February 2022: Wouter
- Fix #628: A rpz-passthru action is not ending RPZ zone processing.
11 February 2022: Wouter
- Fix #624: Unable to stop Unbound in Windows console (does not
respond to CTRL+C command).
- Fix #618: enabling interface-automatic disables DNS-over-TLS.
Adds the option to list interface-automatic-ports.
- Remove debug info from #618 fix.
7 February 2022: Wouter
- Fix that TCP interface does not use TLS when TLS is also configured.
4 February 2022: Wouter
- Fix #412: cache invalidation issue with CNAME+A.
3 February 2022: Wouter
- Fix for #611: Integer overflow in sldns_wire2str_pkt_scan.
- Tag for 1.15.0rc1 created. That became 1.15.0 on 10 feb 2022.
The repository continues with version 1.15.1.
2 February 2022: George
- Merge PR #532 from Shchelk: Fix: buffer overflow bug.

View File

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

View File

@ -1,7 +1,7 @@
#
# Example configuration file.
#
# See unbound.conf(5) man page, version 1.15.0.
# See unbound.conf(5) man page, version 1.16.0.
#
# this is a comment.
@ -55,6 +55,10 @@ server:
# Socket options are not supported on all platforms. experimental.
# interface-automatic: no
# instead of the default port, open additional ports separated by
# spaces when interface-automatic is enabled, by listing them here.
# interface-automatic-ports: ""
# port to answer queries from
# port: 53
@ -811,6 +815,8 @@ server:
# Add system certs to the cert bundle, from the Windows Cert Store
# tls-win-cert: no
# and on other systems, the default openssl certificates
# tls-system-cert: no
# Pad queries over TLS upstreams
# pad-queries: yes
@ -897,6 +903,14 @@ server:
# the number of servers that will be used in the fast server selection.
# fast-server-num: 3
# Enable to attach Extended DNS Error codes (RFC8914) to responses.
# ede: no
# Enable to attach an Extended DNS Error (RFC8914) Code 3 - Stale
# Answer as EDNS0 option to expired responses.
# Note that the ede option above needs to be enabled for this to work.
# ede-serve-expired: no
# Specific options for ipsecmod. Unbound needs to be configured with
# --enable-ipsecmod for these to take effect.
#

View File

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

View File

@ -1,4 +1,4 @@
.TH "unbound-anchor" "8" "Feb 10, 2022" "NLnet Labs" "unbound 1.15.0"
.TH "unbound-anchor" "8" "Jun 2, 2022" "NLnet Labs" "unbound 1.16.0"
.\"
.\" unbound-anchor.8 -- unbound anchor maintenance utility manual
.\"

View File

@ -1,4 +1,4 @@
.TH "unbound-checkconf" "8" "Feb 10, 2022" "NLnet Labs" "unbound 1.15.0"
.TH "unbound-checkconf" "8" "Jun 2, 2022" "NLnet Labs" "unbound 1.16.0"
.\"
.\" unbound-checkconf.8 -- unbound configuration checker manual
.\"

View File

@ -1,4 +1,4 @@
.TH "unbound-control" "8" "Feb 10, 2022" "NLnet Labs" "unbound 1.15.0"
.TH "unbound-control" "8" "Jun 2, 2022" "NLnet Labs" "unbound 1.16.0"
.\"
.\" unbound-control.8 -- unbound remote control manual
.\"
@ -289,20 +289,22 @@ just the ratelimited ips, with their estimated qps. The ratelimited
ips are dropped before checking the cache.
.TP
.B list_auth_zones
List the auth zones that are configured. Printed one per line with a
status, indicating if the zone is expired and current serial number.
List the auth zones that are configured. Printed one per line with a status,
indicating if the zone is expired and current serial number. Configured RPZ
zones are included.
.TP
.B auth_zone_reload \fIzone\fR
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
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
with \fBflush_zone\fR \fIzone\fR.
Reload the auth zone (or RPZ zone) from zonefile. The zonefile is read in
overwriting the current contents of the zone in memory. This changes the auth
zone 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 with
\fBflush_zone\fR \fIzone\fR.
.TP
.B auth_zone_transfer \fIzone\fR
Transfer the auth zone from master. The auth zone probe sequence is started,
where the masters are probed to see if they have an updated zone (with the SOA
serial check). And then the zone is transferred for a newer zone version.
Transfer the auth zone (or RPZ zone) from master. The auth zone probe sequence
is started, where the masters are probed to see if they have an updated zone
(with the SOA serial check). And then the zone is transferred for a newer zone
version.
.TP
.B rpz_enable \fIzone\fR
Enable the RPZ zone if it had previously been disabled.

View File

@ -1,4 +1,4 @@
.TH "unbound\-host" "1" "Feb 10, 2022" "NLnet Labs" "unbound 1.15.0"
.TH "unbound\-host" "1" "Jun 2, 2022" "NLnet Labs" "unbound 1.16.0"
.\"
.\" unbound-host.1 -- unbound DNS lookup utility
.\"

View File

@ -1,4 +1,4 @@
.TH "unbound" "8" "Feb 10, 2022" "NLnet Labs" "unbound 1.15.0"
.TH "unbound" "8" "Jun 2, 2022" "NLnet Labs" "unbound 1.16.0"
.\"
.\" unbound.8 -- unbound manual
.\"
@ -9,7 +9,7 @@
.\"
.SH "NAME"
.B unbound
\- Unbound DNS validating resolver 1.15.0.
\- Unbound DNS validating resolver 1.16.0.
.SH "SYNOPSIS"
.B unbound
.RB [ \-h ]

View File

@ -1,4 +1,4 @@
.TH "unbound.conf" "5" "Feb 10, 2022" "NLnet Labs" "unbound 1.15.0"
.TH "unbound.conf" "5" "Jun 2, 2022" "NLnet Labs" "unbound 1.16.0"
.\"
.\" unbound.conf.5 -- unbound.conf manual
.\"
@ -140,6 +140,15 @@ ip\-transparent you can select which (future) interfaces Unbound provides
service on. This feature is experimental, and needs support in your OS for
particular socket options. Default value is no.
.TP
.B interface\-automatic\-ports: \fI<string>
List the port numbers that interface-automatic listens on. If empty, the
default port is listened on. The port numbers are separated by spaces in the
string. Default is "".
.IP
This can be used to have interface automatic to deal with the interface,
and listen on the normal port number, by including it in the list, and
also https or dns over tls port numbers by putting them in the list as well.
.TP
.B outgoing\-interface: \fI<ip address or ip6 netblock>
Interface to use to connect to the network. This interface is used to send
queries to authoritative servers and receive their replies. Can be given
@ -499,10 +508,11 @@ Enabled or disable whether the upstream queries use TLS only for transport.
Default is no. Useful in tunneling scenarios. The TLS contains plain DNS in
TCP wireformat. The other server must support this (see
\fBtls\-service\-key\fR).
If you enable this, also configure a tls\-cert\-bundle or use tls\-win\-cert to
load CA certs, otherwise the connections cannot be authenticated.
This option enables TLS for all of them, but if you do not set this you can
configure TLS specifically for some forward zones with forward\-tls\-upstream. And also with stub\-tls\-upstream.
If you enable this, also configure a tls\-cert\-bundle or use tls\-win\-cert or
tls\-system\-cert to load CA certs, otherwise the connections cannot be
authenticated. This option enables TLS for all of them, but if you do not set
this you can configure TLS specifically for some forward zones with
forward\-tls\-upstream. And also with stub\-tls\-upstream.
.TP
.B ssl\-upstream: \fI<yes or no>
Alternate syntax for \fBtls\-upstream\fR. If both are present in the config
@ -551,7 +561,12 @@ Alternate syntax for \fBtls\-cert\-bundle\fR.
Add the system certificates to the cert bundle certificates for authentication.
If no cert bundle, it uses only these certificates. Default is no.
On windows this option uses the certificates from the cert store. Use
the tls\-cert\-bundle option on other systems.
the tls\-cert\-bundle option on other systems. On other systems, this option
enables the system certificates.
.TP
.B tls\-system\-cert: \fI<yes or no>
This the same setting as the tls\-win\-cert setting, under a different name.
Because it is not windows specific.
.TP
.B tls\-additional\-port: \fI<portnr>
List portnumbers as tls\-additional\-port, and when interfaces are defined,
@ -1320,7 +1335,17 @@ are authoritative DNS answers. By default the zones are class IN.
.IP
If you need more complicated authoritative data, with referrals, wildcards,
CNAME/DNAME support, or DNSSEC authoritative service, setup a stub\-zone for
it as detailed in the stub zone section below.
it as detailed in the stub zone section below. A stub\-zone can be used to
have unbound send queries to another server, an authoritative server, to
fetch the information. With a forward\-zone, unbound sends queries to a server
that is a recursive server to fetch the information. With an auth\-zone a
zone can be loaded from file and used, it can be used like a local\-zone
for users downstream, or the auth\-zone information can be used to fetch
information from when resolving like it is an upstream server. The
forward\-zone and auth\-zone options are described in their sections below.
If you want to perform filtering of the information that the users can fetch,
the local\-zone and local\-data statements allow for this, but also the
rpz functionality can be used, described in the RPZ section.
.TP 10
\h'5'\fIdeny\fR
Do not send an answer, drop the query.
@ -1761,6 +1786,21 @@ option can be used multiple times. The most specific match will be used.
EDNS0 option code for the \fIedns\-client\-string\fR option, from 0 to 65535.
A value from the `Reserved for Local/Experimental` range (65001-65534) should
be used. Default is 65001.
.TP 5
.B ede: \fI<yes or no>
If enabled, Unbound will respond with Extended DNS Error codes (RFC8914).
These EDEs attach informative error messages to a response for various
errors. Default is "no".
When the \fBval-log-level\fR option is also set to \fB2\fR, responses with
Extended DNS Errors concerning DNSSEC failures that are not served from cache,
will also contain a descriptive text message about the reason for the failure.
.TP
.B ede\-serve\-expired: \fI<yes or no>
If enabled, Unbound will attach an Extended DNS Error (RFC8914) Code 3 - Stale
Answer as EDNS0 option to the expired response. Note that this will not attach
the EDE code without setting the global \fBede\fR option to "yes" as well.
Default is "no".
.SS "Remote Control Options"
In the
.B remote\-control:
@ -1784,7 +1824,7 @@ Use 0.0.0.0 and ::0 to listen to all interfaces.
If you change this and permissions have been dropped, you must restart
the server for the change to take effect.
.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 unix domain socket is used. This socket
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
group that is configured, the access bits are set to allow the group members

View File

@ -97,8 +97,8 @@ subnet_new_qstate(struct module_qstate *qstate, int id)
}
/** Add ecs struct to edns list, after parsing it to wire format. */
static void
ecs_opt_list_append(struct ecs_data* ecs, struct edns_option** list,
void
subnet_ecs_opt_list_append(struct ecs_data* ecs, struct edns_option** list,
struct module_qstate *qstate)
{
size_t sn_octs, sn_octs_remainder;
@ -162,17 +162,21 @@ int ecs_whitelist_check(struct query_info* qinfo,
/* Address on whitelist or client query contains ECS option, we
* want to sent out ECS. Only add option if it is not already
* set. */
if(!(sq->subnet_sent)) {
ecs_opt_list_append(&sq->ecs_server_out,
if(!edns_opt_list_find(qstate->edns_opts_back_out,
qstate->env->cfg->client_subnet_opcode)) {
subnet_ecs_opt_list_append(&sq->ecs_server_out,
&qstate->edns_opts_back_out, qstate);
sq->subnet_sent = 1;
}
sq->subnet_sent = 1;
}
else if(sq->subnet_sent) {
else {
/* Outgoing ECS option is set, but we don't want to sent it to
* this address, remove option. */
edns_opt_list_remove(&qstate->edns_opts_back_out,
qstate->env->cfg->client_subnet_opcode);
if(edns_opt_list_find(qstate->edns_opts_back_out,
qstate->env->cfg->client_subnet_opcode)) {
edns_opt_list_remove(&qstate->edns_opts_back_out,
qstate->env->cfg->client_subnet_opcode);
}
sq->subnet_sent = 0;
}
return 1;
@ -227,7 +231,7 @@ subnetmod_init(struct module_env *env, int id)
env->unique_mesh = 1;
if(!edns_register_option(env->cfg->client_subnet_opcode,
env->cfg->client_subnet_always_forward /* bypass cache */,
0 /* no aggregation */, env)) {
1 /* no aggregation */, env)) {
log_err("subnetcache: could not register opcode");
ecs_whitelist_delete(sn_env->whitelist);
slabhash_delete(sn_env->subnet_msg_cache);
@ -598,7 +602,7 @@ parse_subnet_option(struct edns_option* ecs_option, struct ecs_data* ecs)
return 1;
}
static void
void
subnet_option_from_ss(struct sockaddr_storage *ss, struct ecs_data* ecs,
struct config_file* cfg)
{
@ -761,7 +765,7 @@ subnetmod_operate(struct module_qstate *qstate, enum module_ev event,
verbose(VERB_QUERY, "subnetcache: answered from cache");
qstate->ext_state[id] = module_finished;
ecs_opt_list_append(&sq->ecs_client_out,
subnet_ecs_opt_list_append(&sq->ecs_client_out,
&qstate->edns_opts_front_out, qstate);
return;
}
@ -783,7 +787,7 @@ subnetmod_operate(struct module_qstate *qstate, enum module_ev event,
sq->ecs_server_out.subnet_source_mask =
qstate->env->cfg->max_client_subnet_ipv6;
/* Safe to copy completely, even if the source is limited by the
* configuration. ecs_opt_list_append() will limit the address.
* configuration. subnet_ecs_opt_list_append() will limit the address.
* */
memcpy(&sq->ecs_server_out.subnet_addr,
sq->ecs_client_in.subnet_addr, INET6_SIZE);
@ -807,7 +811,7 @@ subnetmod_operate(struct module_qstate *qstate, enum module_ev event,
qstate->ext_state[id] = eval_response(qstate, id, sq);
if(qstate->ext_state[id] == module_finished &&
qstate->return_msg) {
ecs_opt_list_append(&sq->ecs_client_out,
subnet_ecs_opt_list_append(&sq->ecs_client_out,
&qstate->edns_opts_front_out, qstate);
}
qstate->no_cache_store = sq->started_no_cache_store;

View File

@ -143,4 +143,11 @@ int ecs_query_response(struct module_qstate* qstate, struct dns_msg* response,
/** mark subnet msg to be deleted */
void subnet_markdel(void* key);
/** Add ecs struct to edns list, after parsing it to wire format. */
void subnet_ecs_opt_list_append(struct ecs_data* ecs, struct edns_option** list,
struct module_qstate *qstate);
/** Create ecs_data from the sockaddr_storage information. */
void subnet_option_from_ss(struct sockaddr_storage *ss, struct ecs_data* ecs,
struct config_file* cfg);
#endif /* SUBNETMOD_H */

View File

@ -138,10 +138,10 @@ ipset_add_rrset_data(struct ipset_env *ie, struct mnl_socket *mnl,
static int
ipset_check_zones_for_rrset(struct module_env *env, struct ipset_env *ie,
struct mnl_socket *mnl, struct ub_packed_rrset_key *rrset,
const char *setname, int af)
const char *qname, const int qlen, const char *setname, int af)
{
static char dname[BUFF_LEN];
const char *s;
const char *ds, *qs;
int dlen, plen;
struct config_strlist *p;
@ -152,70 +152,73 @@ ipset_check_zones_for_rrset(struct module_env *env, struct ipset_env *ie,
log_err("bad domain name");
return -1;
}
if (dname[dlen - 1] == '.') {
dlen--;
}
for (p = env->cfg->local_zones_ipset; p; p = p->next) {
ds = NULL;
qs = NULL;
plen = strlen(p->str);
if (dlen >= plen) {
s = dname + (dlen - plen);
if (strncasecmp(p->str, s, plen) == 0) {
d = (struct packed_rrset_data*)rrset->entry.data;
ipset_add_rrset_data(ie, mnl, d, setname,
af, dname);
break;
}
ds = dname + (dlen - plen);
}
if (qlen >= plen) {
qs = qname + (qlen - plen);
}
if ((ds && strncasecmp(p->str, ds, plen) == 0)
|| (qs && strncasecmp(p->str, qs, plen) == 0)) {
d = (struct packed_rrset_data*)rrset->entry.data;
ipset_add_rrset_data(ie, mnl, d, setname,
af, dname);
break;
}
}
return 0;
}
static int ipset_update(struct module_env *env, struct dns_msg *return_msg, struct ipset_env *ie) {
static int ipset_update(struct module_env *env, struct dns_msg *return_msg,
struct query_info qinfo, struct ipset_env *ie)
{
struct mnl_socket *mnl;
size_t i;
const char *setname;
struct ub_packed_rrset_key *rrset;
int af;
static char qname[BUFF_LEN];
int qlen;
mnl = (struct mnl_socket *)ie->mnl;
if (!mnl) {
// retry to create mnl socket
/* retry to create mnl socket */
mnl = open_mnl_socket();
if (!mnl) {
return -1;
}
ie->mnl = mnl;
}
for (i = 0; i < return_msg->rep->rrset_count; ++i) {
qlen = sldns_wire2str_dname_buf(qinfo.qname, qinfo.qname_len,
qname, BUFF_LEN);
if(qlen == 0) {
log_err("bad domain name");
return -1;
}
for(i = 0; i < return_msg->rep->rrset_count; i++) {
setname = NULL;
rrset = return_msg->rep->rrsets[i];
if (rrset->rk.type == htons(LDNS_RR_TYPE_A)) {
if(ntohs(rrset->rk.type) == LDNS_RR_TYPE_A &&
ie->v4_enabled == 1) {
af = AF_INET;
if ((ie->v4_enabled == 1)) {
setname = ie->name_v4;
}
} else {
setname = ie->name_v4;
} else if(ntohs(rrset->rk.type) == LDNS_RR_TYPE_AAAA &&
ie->v6_enabled == 1) {
af = AF_INET6;
if ((ie->v6_enabled == 1)) {
setname = ie->name_v6;
}
setname = ie->name_v6;
}
if (setname) {
if(ipset_check_zones_for_rrset(env, ie, mnl, rrset,
setname, af) == -1)
qname, qlen, setname, af) == -1)
return -1;
}
}
@ -311,7 +314,7 @@ void ipset_operate(struct module_qstate *qstate, enum module_ev event, int id,
if (iq && (event == module_event_moddone)) {
if (qstate->return_msg && qstate->return_msg->rep) {
ipset_update(qstate->env, qstate->return_msg, ie);
ipset_update(qstate->env, qstate->return_msg, qstate->qinfo, ie);
}
qstate->ext_state[id] = module_finished;
return;

View File

@ -128,7 +128,7 @@ struct delegpt_ns {
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
/** the port to use; it should mostly be the default 53 but configured
* upstreams can provide nondefault ports. */
int port;
};

View File

@ -743,9 +743,10 @@ iter_mark_pside_cycle_targets(struct module_qstate* qstate, struct delegpt* dp)
int
iter_dp_is_useless(struct query_info* qinfo, uint16_t qflags,
struct delegpt* dp)
struct delegpt* dp, int supports_ipv4, int supports_ipv6)
{
struct delegpt_ns* ns;
struct delegpt_addr* a;
/* check:
* o RD qflag is on.
* o no addresses are provided.
@ -758,13 +759,24 @@ iter_dp_is_useless(struct query_info* qinfo, uint16_t qflags,
*/
if(!(qflags&BIT_RD))
return 0;
/* either available or unused targets */
if(dp->usable_list || dp->result_list)
return 0;
/* either available or unused targets,
* if they exist, the dp is not useless. */
for(a = dp->usable_list; a; a = a->next_usable) {
if(!addr_is_ip6(&a->addr, a->addrlen) && supports_ipv4)
return 0;
else if(addr_is_ip6(&a->addr, a->addrlen) && supports_ipv6)
return 0;
}
for(a = dp->result_list; a; a = a->next_result) {
if(!addr_is_ip6(&a->addr, a->addrlen) && supports_ipv4)
return 0;
else if(addr_is_ip6(&a->addr, a->addrlen) && supports_ipv6)
return 0;
}
/* see if query is for one of the nameservers, which is glue */
if( (qinfo->qtype == LDNS_RR_TYPE_A ||
qinfo->qtype == LDNS_RR_TYPE_AAAA) &&
if( ((qinfo->qtype == LDNS_RR_TYPE_A && supports_ipv4) ||
(qinfo->qtype == LDNS_RR_TYPE_AAAA && supports_ipv6)) &&
dname_subdomain_c(qinfo->qname, dp->name) &&
delegpt_find_ns(dp, qinfo->qname, qinfo->qname_len))
return 1;

View File

@ -175,10 +175,14 @@ void iter_mark_pside_cycle_targets(struct module_qstate* qstate,
* @param qinfo: query name and type
* @param qflags: query flags with RD flag
* @param dp: delegpt to check.
* @param supports_ipv4: if we support ipv4 for lookups to the target.
* if not, then the IPv4 addresses are useless.
* @param supports_ipv6: if we support ipv6 for lookups to the target.
* if not, then the IPv6 addresses are useless.
* @return true if dp is useless.
*/
int iter_dp_is_useless(struct query_info* qinfo, uint16_t qflags,
struct delegpt* dp);
struct delegpt* dp, int supports_ipv4, int supports_ipv6);
/**
* See if qname has DNSSEC needs. This is true if there is a trust anchor above

View File

@ -1547,7 +1547,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
* same server reply) if useless-checked.
*/
if(iter_dp_is_useless(&qstate->qinfo, qstate->query_flags,
iq->dp)) {
iq->dp, ie->supports_ipv4, ie->supports_ipv6)) {
struct delegpt* retdp = NULL;
if(!can_have_last_resort(qstate->env, iq->dp->name, iq->dp->namelen, iq->qchase.qclass, &retdp)) {
if(retdp) {
@ -1831,6 +1831,23 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq,
int missing;
int toget = 0;
iter_mark_cycle_targets(qstate, iq->dp);
missing = (int)delegpt_count_missing_targets(iq->dp);
log_assert(maxtargets != 0); /* that would not be useful */
/* Generate target requests. Basically, any missing targets
* are queried for here, regardless if it is necessary to do
* so to continue processing. */
if(maxtargets < 0 || maxtargets > missing)
toget = missing;
else toget = maxtargets;
if(toget == 0) {
*num = 0;
return 1;
}
/* now that we are sure that a target query is going to be made,
* check the limits. */
if(iq->depth == ie->max_dependency_depth)
return 0;
if(iq->depth > 0 && iq->target_count &&
@ -1850,20 +1867,6 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq,
return 0;
}
iter_mark_cycle_targets(qstate, iq->dp);
missing = (int)delegpt_count_missing_targets(iq->dp);
log_assert(maxtargets != 0); /* that would not be useful */
/* Generate target requests. Basically, any missing targets
* are queried for here, regardless if it is necessary to do
* so to continue processing. */
if(maxtargets < 0 || maxtargets > missing)
toget = missing;
else toget = maxtargets;
if(toget == 0) {
*num = 0;
return 1;
}
/* select 'toget' items from the total of 'missing' items */
log_assert(toget <= missing);
@ -2512,7 +2515,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
iq->response = forged_response;
next_state(iq, FINISHED_STATE);
if(!iter_prepend(iq, qstate->return_msg, qstate->region)) {
log_err("rpz, prepend rrsets: out of memory");
log_err("rpz: prepend rrsets: out of memory");
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
return 0;
@ -2832,7 +2835,9 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
}
if(!qstate->no_cache_store)
iter_dns_store(qstate->env, &iq->response->qinfo,
iq->response->rep, 0, qstate->prefetch_leeway,
iq->response->rep,
iq->qchase.qtype != iq->response->qinfo.qtype,
qstate->prefetch_leeway,
iq->dp&&iq->dp->has_parent_side_NS,
qstate->region, qstate->query_flags);
/* close down outstanding requests to be discarded */
@ -3067,7 +3072,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
iq->response = forged_response;
next_state(iq, FINISHED_STATE);
if(!iter_prepend(iq, qstate->return_msg, qstate->region)) {
log_err("rpz after cname, prepend rrsets: out of memory");
log_err("rpz: after cname, prepend rrsets: out of memory");
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
qstate->return_msg->qinfo = qstate->qinfo;

View File

@ -650,7 +650,7 @@ int libworker_fg(struct ub_ctx* ctx, struct ctx_query* q)
}
/* process new query */
if(!mesh_new_callback(w->env->mesh, &qinfo, qflags, &edns,
w->back->udp_buff, qid, libworker_fg_done_cb, q)) {
w->back->udp_buff, qid, libworker_fg_done_cb, q, 0)) {
free(qinfo.qname);
return UB_NOMEM;
}
@ -730,7 +730,7 @@ int libworker_attach_mesh(struct ub_ctx* ctx, struct ctx_query* q,
if(async_id)
*async_id = q->querynum;
if(!mesh_new_callback(w->env->mesh, &qinfo, qflags, &edns,
w->back->udp_buff, qid, libworker_event_done_cb, q)) {
w->back->udp_buff, qid, libworker_event_done_cb, q, 0)) {
free(qinfo.qname);
return UB_NOMEM;
}
@ -867,7 +867,7 @@ handle_newq(struct libworker* w, uint8_t* buf, uint32_t len)
q->w = w;
/* process new query */
if(!mesh_new_callback(w->env->mesh, &qinfo, qflags, &edns,
w->back->udp_buff, qid, libworker_bg_done_cb, q)) {
w->back->udp_buff, qid, libworker_bg_done_cb, q, 0)) {
add_bg_result(w, q, NULL, UB_NOMEM, NULL, 0);
}
free(qinfo.qname);

View File

@ -60,7 +60,7 @@ EDNS options
.. function:: edns_opt_list_remove(list, code);
Remove an ENDS option code from the list.
Remove an EDNS option code from the list.
.. note:: All :class:`edns_option` with the code will be removed
:param list: linked list of :class:`edns_option`

View File

@ -77,7 +77,7 @@ module_qstate
.. attribute:: edns_opts_back_in_iter
Iterator for `ends_opts_back_in`.
Iterator for `edns_opts_back_in`.
.. attribute:: edns_opts_front_out

View File

@ -207,7 +207,7 @@ def inplace_servfail_callback(qinfo, qstate, rep, rcode, edns, opt_list_out,
"""
log_info("python: called back while servfail.")
# Append the example ENDS option
# Append the example EDNS option
b = bytearray.fromhex("")
edns_opt_list_append(opt_list_out, 65003, b, region)

View File

@ -1377,7 +1377,7 @@ struct delegpt* dns_cache_find_delegation(struct module_env* env,
uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass,
struct regional* region, struct dns_msg** msg, uint32_t timenow);
int iter_dp_is_useless(struct query_info* qinfo, uint16_t qflags,
struct delegpt* dp);
struct delegpt* dp, int supports_ipv4, int supports_ipv6);
struct iter_hints_stub* hints_lookup_stub(struct iter_hints* hints,
uint8_t* qname, uint16_t qclass, struct delegpt* dp);
@ -1407,7 +1407,8 @@ struct delegpt* find_delegation(struct module_qstate* qstate, char *nm, size_t n
dp = dns_cache_find_delegation(qstate->env, (uint8_t*)nm, nmlen, qinfo.qtype, qinfo.qclass, region, &msg, timenow);
if(!dp)
return NULL;
if(iter_dp_is_useless(&qinfo, BIT_RD, dp)) {
if(iter_dp_is_useless(&qinfo, BIT_RD, dp,
qstate->env->cfg->do_ip4, qstate->env->cfg->do_ip6)) {
if (dname_is_root((uint8_t*)nm))
return NULL;
nm = (char*)dp->name;

View File

@ -833,8 +833,11 @@ static int
respip_use_rpz(struct resp_addr* raddr, struct rpz* r,
enum respip_action* action,
struct ub_packed_rrset_key** data, int* rpz_log, char** log_name,
int* rpz_cname_override, struct regional* region, int* is_rpz)
int* rpz_cname_override, struct regional* region, int* is_rpz,
int* rpz_passthru)
{
if(rpz_passthru && *rpz_passthru)
return 0;
if(r->action_override == RPZ_DISABLED_ACTION) {
*is_rpz = 0;
return 1;
@ -848,6 +851,9 @@ respip_use_rpz(struct resp_addr* raddr, struct rpz* r,
*data = r->cname_override;
*rpz_cname_override = 1;
}
if(*action == respip_always_transparent /* RPZ_PASSTHRU_ACTION */
&& rpz_passthru)
*rpz_passthru = 1;
*rpz_log = r->log;
if(r->log_name)
if(!(*log_name = regional_strdup(region, r->log_name)))
@ -861,7 +867,7 @@ respip_rewrite_reply(const struct query_info* qinfo,
const struct respip_client_info* cinfo, const struct reply_info* rep,
struct reply_info** new_repp, struct respip_action_info* actinfo,
struct ub_packed_rrset_key** alias_rrset, int search_only,
struct regional* region, struct auth_zones* az)
struct regional* region, struct auth_zones* az, int* rpz_passthru)
{
const uint8_t* ctaglist;
size_t ctaglen;
@ -934,7 +940,7 @@ respip_rewrite_reply(const struct query_info* qinfo,
ipset->tagname, ipset->num_tags);
}
lock_rw_rdlock(&az->rpz_lock);
for(a = az->rpz_first; a && !raddr; a = a->rpz_az_next) {
for(a = az->rpz_first; a && !raddr && !(rpz_passthru && *rpz_passthru); a = a->rpz_az_next) {
lock_rw_rdlock(&a->lock);
r = a->rpz;
if(!r->taglist || taglist_intersect(r->taglist,
@ -943,7 +949,7 @@ respip_rewrite_reply(const struct query_info* qinfo,
r->respip_set, &rrset_id, &rr_id))) {
if(!respip_use_rpz(raddr, r, &action, &data,
&rpz_log, &log_name, &rpz_cname_override,
region, &rpz_used)) {
region, &rpz_used, rpz_passthru)) {
log_err("out of memory");
lock_rw_unlock(&raddr->lock);
lock_rw_unlock(&a->lock);
@ -964,7 +970,7 @@ respip_rewrite_reply(const struct query_info* qinfo,
addr_to_str(&raddr->node.addr,
raddr->node.addrlen,
nm, sizeof(nm));
verbose(VERB_ALGO, "respip: rpz response-ip trigger %s/%d on %s %s with action %s", nm, raddr->node.net, qn, ip, rpz_action_to_string(respip_action_to_rpz_action(action)));
verbose(VERB_ALGO, "respip: rpz: response-ip trigger %s/%d on %s %s with action %s", nm, raddr->node.net, qn, ip, rpz_action_to_string(respip_action_to_rpz_action(action)));
}
/* break to make sure 'a' stays pointed
* to used auth_zone, and keeps lock */
@ -1094,7 +1100,8 @@ respip_operate(struct module_qstate* qstate, enum module_ev event, int id,
if(!respip_rewrite_reply(&qstate->qinfo,
qstate->client_info, qstate->return_msg->rep,
&new_rep, &actinfo, &alias_rrset, 0,
qstate->region, qstate->env->auth_zones)) {
qstate->region, qstate->env->auth_zones,
&qstate->rpz_passthru)) {
goto servfail;
}
if(actinfo.action != respip_none) {
@ -1169,7 +1176,7 @@ respip_merge_cname(struct reply_info* base_rep,
/* see if the target reply would be subject to a response-ip action. */
if(!respip_rewrite_reply(qinfo, cinfo, tgt_rep, &tmp_rep, &actinfo,
&alias_rrset, 1, region, az))
&alias_rrset, 1, region, az, NULL))
return 0;
if(actinfo.action != respip_none) {
log_info("CNAME target of redirect response-ip action would "
@ -1301,7 +1308,7 @@ respip_inform_print(struct respip_action_info* respip_actinfo, uint8_t* qname,
respip, sizeof(respip));
if(respip_actinfo->rpz_log) {
txtlen += snprintf(txt+txtlen, sizeof(txt)-txtlen, "%s",
"RPZ applied ");
"rpz: applied ");
if(respip_actinfo->rpz_cname_override)
actionstr = rpz_action_to_string(
RPZ_CNAME_OVERRIDE_ACTION);

View File

@ -176,6 +176,8 @@ int respip_merge_cname(struct reply_info* base_rep,
* will be set (or intact) accordingly but the modified reply won't be built.
* @param az: auth zones containing RPZ information.
* @param region: allocator to build *new_repp.
* @param rpz_passthru: keeps track of query state can have passthru that
* stops further rpz processing. Or NULL for cached answer processing.
* @return 1 on success, 0 on error.
*/
int respip_rewrite_reply(const struct query_info* qinfo,
@ -183,7 +185,8 @@ int respip_rewrite_reply(const struct query_info* qinfo,
const struct reply_info *rep, struct reply_info** new_repp,
struct respip_action_info* actinfo,
struct ub_packed_rrset_key** alias_rrset,
int search_only, struct regional* region, struct auth_zones* az);
int search_only, struct regional* region, struct auth_zones* az,
int* rpz_passthru);
/**
* Get the response-ip function block.

View File

@ -132,6 +132,7 @@ msg_create(struct regional* region, struct query_info* qinfo)
return NULL;
msg->rep->flags = (uint16_t)(BIT_QR | BIT_AA);
msg->rep->authoritative = 1;
msg->rep->reason_bogus = LDNS_EDE_NONE;
msg->rep->qdcount = 1;
/* rrsets is NULL, no rrsets yet */
return msg;
@ -1882,6 +1883,8 @@ static int auth_zone_zonemd_check_hash(struct auth_zone* z,
struct regional* region = NULL;
struct sldns_buffer* buf = NULL;
uint32_t soa_serial = 0;
char* unsupported_reason = NULL;
int only_unsupported = 1;
region = env->scratch;
regional_free_all(region);
buf = env->scratch_buffer;
@ -1911,6 +1914,7 @@ static int auth_zone_zonemd_check_hash(struct auth_zone* z,
&hashalgo, &hash, &hashlen)) {
/* malformed RR */
*reason = "ZONEMD rdata malformed";
only_unsupported = 0;
continue;
}
/* check for duplicates */
@ -1920,25 +1924,51 @@ static int auth_zone_zonemd_check_hash(struct auth_zone* z,
* is not allowed. */
*reason = "ZONEMD RRSet contains more than one RR "
"with the same scheme and hash algorithm";
only_unsupported = 0;
continue;
}
regional_free_all(region);
if(serial != soa_serial) {
*reason = "ZONEMD serial is wrong";
only_unsupported = 0;
continue;
}
*reason = NULL;
if(auth_zone_generate_zonemd_check(z, scheme, hashalgo,
hash, hashlen, region, buf, reason)) {
/* success */
if(*reason) {
if(!unsupported_reason)
unsupported_reason = *reason;
/* continue to check for valid ZONEMD */
if(verbosity >= VERB_ALGO) {
char zstr[255+1];
dname_str(z->name, zstr);
verbose(VERB_ALGO, "auth-zone %s ZONEMD %d %d is unsupported: %s", zstr, (int)scheme, (int)hashalgo, *reason);
}
*reason = NULL;
continue;
}
if(verbosity >= VERB_ALGO) {
char zstr[255+1];
dname_str(z->name, zstr);
verbose(VERB_ALGO, "auth-zone %s ZONEMD hash is correct", zstr);
if(!*reason)
verbose(VERB_ALGO, "auth-zone %s ZONEMD hash is correct", zstr);
}
return 1;
}
only_unsupported = 0;
/* try next one */
}
/* have we seen no failures but only unsupported algo,
* and one unsupported algorithm, or more. */
if(only_unsupported && unsupported_reason) {
/* only unsupported algorithms, with valid serial, not
* malformed. Did not see supported algorithms, failed or
* successful ones. */
*reason = unsupported_reason;
return 1;
}
/* fail, we may have reason */
if(!*reason)
*reason = "no ZONEMD records found";
@ -4456,7 +4486,7 @@ chunkline_get_line_collated(struct auth_chunk** chunk, size_t* chunk_pos,
return 1;
}
/** process $ORIGIN for http */
/** process $ORIGIN for http, 0 nothing, 1 done, 2 error */
static int
http_parse_origin(sldns_buffer* buf, struct sldns_file_parse_state* pstate)
{
@ -4467,13 +4497,16 @@ http_parse_origin(sldns_buffer* buf, struct sldns_file_parse_state* pstate)
pstate->origin_len = sizeof(pstate->origin);
s = sldns_str2wire_dname_buf(sldns_strip_ws(line+8),
pstate->origin, &pstate->origin_len);
if(s) pstate->origin_len = 0;
if(s) {
pstate->origin_len = 0;
return 2;
}
return 1;
}
return 0;
}
/** process $TTL for http */
/** process $TTL for http, 0 nothing, 1 done, 2 error */
static int
http_parse_ttl(sldns_buffer* buf, struct sldns_file_parse_state* pstate)
{
@ -4481,8 +4514,12 @@ http_parse_ttl(sldns_buffer* buf, struct sldns_file_parse_state* pstate)
if(strncmp(line, "$TTL", 4) == 0 &&
isspace((unsigned char)line[4])) {
const char* end = NULL;
int overflow = 0;
pstate->default_ttl = sldns_str2period(
sldns_strip_ws(line+5), &end);
sldns_strip_ws(line+5), &end, &overflow);
if(overflow) {
return 2;
}
return 1;
}
return 0;
@ -4493,15 +4530,20 @@ static int
chunkline_non_comment_RR(struct auth_chunk** chunk, size_t* chunk_pos,
sldns_buffer* buf, struct sldns_file_parse_state* pstate)
{
int ret;
while(chunkline_get_line_collated(chunk, chunk_pos, buf)) {
if(chunkline_is_comment_line_or_empty(buf)) {
/* a comment, go to next line */
continue;
}
if(http_parse_origin(buf, pstate)) {
if((ret=http_parse_origin(buf, pstate))!=0) {
if(ret == 2)
return 0;
continue; /* $ORIGIN has been handled */
}
if(http_parse_ttl(buf, pstate)) {
if((ret=http_parse_ttl(buf, pstate))!=0) {
if(ret == 2)
return 0;
continue; /* $TTL has been handled */
}
return 1;
@ -5007,6 +5049,7 @@ apply_http(struct auth_xfer* xfr, struct auth_zone* z,
struct sldns_file_parse_state pstate;
struct auth_chunk* chunk;
size_t chunk_pos;
int ret;
memset(&pstate, 0, sizeof(pstate));
pstate.default_ttl = 3600;
if(xfr->namelen < sizeof(pstate.origin)) {
@ -5063,10 +5106,24 @@ apply_http(struct auth_xfer* xfr, struct auth_zone* z,
continue;
}
/* parse line and add RR */
if(http_parse_origin(scratch_buffer, &pstate)) {
if((ret=http_parse_origin(scratch_buffer, &pstate))!=0) {
if(ret == 2) {
verbose(VERB_ALGO, "error parsing ORIGIN on line [%s:%d] %s",
xfr->task_transfer->master->file,
pstate.lineno,
sldns_buffer_begin(scratch_buffer));
return 0;
}
continue; /* $ORIGIN has been handled */
}
if(http_parse_ttl(scratch_buffer, &pstate)) {
if((ret=http_parse_ttl(scratch_buffer, &pstate))!=0) {
if(ret == 2) {
verbose(VERB_ALGO, "error parsing TTL on line [%s:%d] %s",
xfr->task_transfer->master->file,
pstate.lineno,
sldns_buffer_begin(scratch_buffer));
return 0;
}
continue; /* $TTL has been handled */
}
if(!http_parse_add_rr(xfr, z, scratch_buffer, &pstate)) {
@ -5370,7 +5427,7 @@ xfr_transfer_lookup_host(struct auth_xfer* xfr, struct module_env* env)
* called straight away */
lock_basic_unlock(&xfr->lock);
if(!mesh_new_callback(env->mesh, &qinfo, qflags, &edns, buf, 0,
&auth_xfer_transfer_lookup_callback, xfr)) {
&auth_xfer_transfer_lookup_callback, xfr, 0)) {
lock_basic_lock(&xfr->lock);
log_err("out of memory lookup up master %s", master->host);
return 0;
@ -6561,7 +6618,7 @@ xfr_probe_lookup_host(struct auth_xfer* xfr, struct module_env* env)
* called straight away */
lock_basic_unlock(&xfr->lock);
if(!mesh_new_callback(env->mesh, &qinfo, qflags, &edns, buf, 0,
&auth_xfer_probe_lookup_callback, xfr)) {
&auth_xfer_probe_lookup_callback, xfr, 0)) {
lock_basic_lock(&xfr->lock);
log_err("out of memory lookup up master %s", master->host);
return 0;
@ -7632,13 +7689,16 @@ int auth_zone_generate_zonemd_check(struct auth_zone* z, int scheme,
{
uint8_t gen[512];
size_t genlen = 0;
*reason = NULL;
if(!zonemd_hashalgo_supported(hashalgo)) {
/* allow it */
*reason = "unsupported algorithm";
return 0;
return 1;
}
if(!zonemd_scheme_supported(scheme)) {
/* allow it */
*reason = "unsupported scheme";
return 0;
return 1;
}
if(hashlen < 12) {
/* the ZONEMD draft requires digests to fail if too small */
@ -7726,7 +7786,7 @@ static int zonemd_dnssec_verify_rrset(struct auth_zone* z,
auth_zone_log(z->name, VERB_ALGO,
"zonemd: verify %s RRset with DNSKEY", typestr);
}
sec = dnskeyset_verify_rrset(env, ve, &pk, dnskey, sigalg, why_bogus,
sec = dnskeyset_verify_rrset(env, ve, &pk, dnskey, sigalg, why_bogus, NULL,
LDNS_SECTION_ANSWER, NULL);
if(sec == sec_status_secure) {
return 1;
@ -8003,9 +8063,13 @@ auth_zone_verify_zonemd_with_key(struct auth_zone* z, struct module_env* env,
}
/* success! log the success */
auth_zone_log(z->name, VERB_ALGO, "ZONEMD verification successful");
if(reason)
auth_zone_log(z->name, VERB_ALGO, "ZONEMD %s", reason);
else auth_zone_log(z->name, VERB_ALGO, "ZONEMD verification successful");
if(result) {
*result = strdup("ZONEMD verification successful");
if(reason)
*result = strdup(reason);
else *result = strdup("ZONEMD verification successful");
if(!*result) log_err("out of memory");
}
}
@ -8065,7 +8129,7 @@ zonemd_get_dnskey_from_anchor(struct auth_zone* z, struct module_env* env,
auth_zone_log(z->name, VERB_QUERY,
"zonemd: verify DNSKEY RRset with trust anchor");
sec = val_verify_DNSKEY_with_TA(env, ve, keystorage, anchor->ds_rrset,
anchor->dnskey_rrset, NULL, why_bogus, NULL);
anchor->dnskey_rrset, NULL, why_bogus, NULL, NULL);
regional_free_all(env->scratch);
if(sec == sec_status_secure) {
/* success */
@ -8123,8 +8187,9 @@ auth_zone_verify_zonemd_key_with_ds(struct auth_zone* z,
keystorage->rk.type = htons(LDNS_RR_TYPE_DNSKEY);
keystorage->rk.rrset_class = htons(z->dclass);
auth_zone_log(z->name, VERB_QUERY, "zonemd: verify zone DNSKEY with DS");
// @TODO add EDE here? we currently just pass NULL
sec = val_verify_DNSKEY_with_DS(env, ve, keystorage, ds, sigalg,
why_bogus, NULL);
why_bogus, NULL, NULL);
regional_free_all(env->scratch);
if(sec == sec_status_secure) {
/* success */
@ -8340,7 +8405,7 @@ zonemd_lookup_dnskey(struct auth_zone* z, struct module_env* env)
/* the callback can be called straight away */
lock_rw_unlock(&z->lock);
if(!mesh_new_callback(env->mesh, &qinfo, qflags, &edns, buf, 0,
&auth_zonemd_dnskey_lookup_callback, z)) {
&auth_zonemd_dnskey_lookup_callback, z, 0)) {
lock_rw_wrlock(&z->lock);
log_err("out of memory lookup of %s for zonemd",
(fetch_ds?"DS":"DNSKEY"));

View File

@ -747,6 +747,9 @@ int zonemd_scheme_supported(int scheme);
* @param region: temp region for allocs during canonicalisation.
* @param buf: temp buffer during canonicalisation.
* @param reason: string returned with failure reason.
* If the hash cannot be checked, but it is allowed, for unknown
* algorithms, the routine returns success, and the reason is nonNULL,
* with the allowance reason.
* @return false on failure.
*/
int auth_zone_generate_zonemd_check(struct auth_zone* z, int scheme,

View File

@ -428,6 +428,7 @@ dns_msg_create(uint8_t* qname, size_t qnamelen, uint16_t qtype,
return NULL; /* integer overflow protection */
msg->rep->flags = BIT_QR; /* with QR, no AA */
msg->rep->qdcount = 1;
msg->rep->reason_bogus = LDNS_EDE_NONE;
msg->rep->rrsets = (struct ub_packed_rrset_key**)
regional_alloc(region,
capacity*sizeof(struct ub_packed_rrset_key*));
@ -524,6 +525,7 @@ gen_dns_msg(struct regional* region, struct query_info* q, size_t num)
sizeof(struct reply_info) - sizeof(struct rrset_ref));
if(!msg->rep)
return NULL;
msg->rep->reason_bogus = LDNS_EDE_NONE;
if(num > RR_COUNT_MAX)
return NULL; /* integer overflow protection */
msg->rep->rrsets = (struct ub_packed_rrset_key**)
@ -577,6 +579,7 @@ tomsg(struct module_env* env, struct query_info* q, struct reply_info* r,
msg->rep->ar_numrrsets = r->ar_numrrsets;
msg->rep->rrset_count = r->rrset_count;
msg->rep->authoritative = r->authoritative;
msg->rep->reason_bogus = r->reason_bogus;
if(!rrset_array_lock(r->ref, r->rrset_count, now_control)) {
return NULL;
}
@ -632,6 +635,7 @@ rrset_msg(struct ub_packed_rrset_key* rrset, struct regional* region,
msg->rep->ns_numrrsets = 0;
msg->rep->ar_numrrsets = 0;
msg->rep->rrset_count = 1;
msg->rep->reason_bogus = LDNS_EDE_NONE;
msg->rep->rrsets[0] = packed_rrset_copy_region(rrset, region, now);
if(!msg->rep->rrsets[0]) /* copy CNAME */
return NULL;
@ -670,6 +674,7 @@ synth_dname_msg(struct ub_packed_rrset_key* rrset, struct regional* region,
msg->rep->ns_numrrsets = 0;
msg->rep->ar_numrrsets = 0;
msg->rep->rrset_count = 1;
msg->rep->reason_bogus = LDNS_EDE_NONE;
msg->rep->rrsets[0] = packed_rrset_copy_region(rrset, region, now);
if(!msg->rep->rrsets[0]) /* copy DNAME */
return NULL;

View File

@ -47,6 +47,7 @@
#ifdef USE_TCP_FASTOPEN
#include <netinet/tcp.h>
#endif
#include <ctype.h>
#include "services/listen_dnsport.h"
#include "services/outside_network.h"
#include "util/netevent.h"
@ -1157,7 +1158,7 @@ if_is_ssl(const char* ifname, const char* port, int ssl_port,
* @param do_auto: use automatic interface detection.
* If enabled, then ifname must be the wildcard name.
* @param do_udp: if udp should be used.
* @param do_tcp: if udp should be used.
* @param do_tcp: if tcp should be used.
* @param hints: for getaddrinfo. family and flags have to be set by caller.
* @param port: Port number to use (as string).
* @param list: list of open ports, appended to, changed to point to list head.
@ -1369,17 +1370,17 @@ listen_create(struct comm_base* base, struct listen_port* ports,
while(ports) {
struct comm_point* cp = NULL;
if(ports->ftype == listen_type_udp ||
ports->ftype == listen_type_udp_dnscrypt)
ports->ftype == listen_type_udp_dnscrypt) {
cp = comm_point_create_udp(base, ports->fd,
front->udp_buff, cb, cb_arg, ports->socket);
else if(ports->ftype == listen_type_tcp ||
ports->ftype == listen_type_tcp_dnscrypt)
} else if(ports->ftype == listen_type_tcp ||
ports->ftype == listen_type_tcp_dnscrypt) {
cp = comm_point_create_tcp(base, ports->fd,
tcp_accept_count, tcp_idle_timeout,
harden_large_queries, 0, NULL,
tcp_conn_limit, bufsize, front->udp_buff,
ports->ftype, cb, cb_arg, ports->socket);
else if(ports->ftype == listen_type_ssl ||
} else if(ports->ftype == listen_type_ssl ||
ports->ftype == listen_type_http) {
cp = comm_point_create_tcp(base, ports->fd,
tcp_accept_count, tcp_idle_timeout,
@ -1410,15 +1411,22 @@ listen_create(struct comm_base* base, struct listen_port* ports,
#endif
}
} else if(ports->ftype == listen_type_udpancil ||
ports->ftype == listen_type_udpancil_dnscrypt)
ports->ftype == listen_type_udpancil_dnscrypt) {
cp = comm_point_create_udp_ancil(base, ports->fd,
front->udp_buff, cb, cb_arg, ports->socket);
}
if(!cp) {
log_err("can't create commpoint");
listen_delete(front);
return NULL;
}
if(http_notls && ports->ftype == listen_type_http)
if((http_notls && ports->ftype == listen_type_http) ||
(ports->ftype == listen_type_tcp) ||
(ports->ftype == listen_type_udp) ||
(ports->ftype == listen_type_udpancil) ||
(ports->ftype == listen_type_tcp_dnscrypt) ||
(ports->ftype == listen_type_udp_dnscrypt) ||
(ports->ftype == listen_type_udpancil_dnscrypt))
cp->ssl = NULL;
else
cp->ssl = sslctx;
@ -1709,6 +1717,63 @@ listening_ports_open(struct config_file* cfg, char** ifs, int num_ifs,
}
/* create ip4 and ip6 ports so that return addresses are nice. */
if(do_auto || num_ifs == 0) {
if(do_auto && cfg->if_automatic_ports &&
cfg->if_automatic_ports[0]!=0) {
char* now = cfg->if_automatic_ports;
while(now && *now) {
char* after;
int extraport;
while(isspace((unsigned char)*now))
now++;
if(!*now)
break;
after = now;
extraport = (int)strtol(now, &after, 10);
if(extraport < 0 || extraport > 65535) {
log_err("interface-automatic-ports port number out of range, at position %d of '%s'", (int)(now-cfg->if_automatic_ports)+1, cfg->if_automatic_ports);
listening_ports_free(list);
return NULL;
}
if(extraport == 0 && now == after) {
log_err("interface-automatic-ports could not be parsed, at position %d of '%s'", (int)(now-cfg->if_automatic_ports)+1, cfg->if_automatic_ports);
listening_ports_free(list);
return NULL;
}
now = after;
snprintf(portbuf, sizeof(portbuf), "%d", extraport);
if(do_ip6) {
hints.ai_family = AF_INET6;
if(!ports_create_if("::0",
do_auto, cfg->do_udp, do_tcp,
&hints, portbuf, &list,
cfg->so_rcvbuf, cfg->so_sndbuf,
cfg->ssl_port, cfg->tls_additional_port,
cfg->https_port, reuseport, cfg->ip_transparent,
cfg->tcp_mss, cfg->ip_freebind,
cfg->http_nodelay, cfg->use_systemd,
cfg->dnscrypt_port, cfg->ip_dscp)) {
listening_ports_free(list);
return NULL;
}
}
if(do_ip4) {
hints.ai_family = AF_INET;
if(!ports_create_if("0.0.0.0",
do_auto, cfg->do_udp, do_tcp,
&hints, portbuf, &list,
cfg->so_rcvbuf, cfg->so_sndbuf,
cfg->ssl_port, cfg->tls_additional_port,
cfg->https_port, reuseport, cfg->ip_transparent,
cfg->tcp_mss, cfg->ip_freebind,
cfg->http_nodelay, cfg->use_systemd,
cfg->dnscrypt_port, cfg->ip_dscp)) {
listening_ports_free(list);
return NULL;
}
}
}
return list;
}
if(do_ip6) {
hints.ai_family = AF_INET6;
if(!ports_create_if(do_auto?"::0":"::1",

View File

@ -1328,7 +1328,8 @@ local_encode(struct query_info* qinfo, struct module_env* env,
static void
local_error_encode(struct query_info* qinfo, struct module_env* env,
struct edns_data* edns, struct comm_reply* repinfo, sldns_buffer* buf,
struct regional* temp, int rcode, int r)
struct regional* temp, int rcode, int r, int ede_code,
const char* ede_txt)
{
edns->edns_version = EDNS_ADVERTISED_VERSION;
edns->udp_size = EDNS_ADVERTISED_SIZE;
@ -1338,6 +1339,12 @@ local_error_encode(struct query_info* qinfo, struct module_env* env,
if(!inplace_cb_reply_local_call(env, qinfo, NULL, NULL,
rcode, edns, repinfo, temp, env->now_tv))
edns->opt_list_inplace_cb_out = NULL;
if(ede_code != LDNS_EDE_NONE && env->cfg->ede) {
edns_opt_list_append_ede(&edns->opt_list_out, temp,
ede_code, ede_txt);
}
error_encode(buf, r, qinfo, *(uint16_t*)sldns_buffer_begin(buf),
sldns_buffer_read_u16_at(buf, 2), edns);
}
@ -1535,7 +1542,9 @@ local_data_answer(struct local_zone* z, struct module_env* env,
qinfo->local_alias = NULL;
local_error_encode(qinfo, env, edns, repinfo,
buf, temp, LDNS_RCODE_YXDOMAIN,
(LDNS_RCODE_YXDOMAIN|BIT_AA));
(LDNS_RCODE_YXDOMAIN|BIT_AA),
LDNS_EDE_OTHER,
"DNAME expansion became too large");
return 1;
}
memset(&qinfo->local_alias->rrset->entry, 0,
@ -1638,7 +1647,8 @@ local_zones_zone_answer(struct local_zone* z, struct module_env* env,
} else if(lz_type == local_zone_refuse
|| lz_type == local_zone_always_refuse) {
local_error_encode(qinfo, env, edns, repinfo, buf, temp,
LDNS_RCODE_REFUSED, (LDNS_RCODE_REFUSED|BIT_AA));
LDNS_RCODE_REFUSED, (LDNS_RCODE_REFUSED|BIT_AA),
LDNS_EDE_NONE, NULL);
return 1;
} else if(lz_type == local_zone_static ||
lz_type == local_zone_redirect ||
@ -1663,8 +1673,8 @@ local_zones_zone_answer(struct local_zone* z, struct module_env* env,
if(z != NULL && z->soa && z->soa_negative)
return local_encode(qinfo, env, edns, repinfo, buf, temp,
z->soa_negative, 0, rcode);
local_error_encode(qinfo, env, edns, repinfo, buf, temp, rcode,
(rcode|BIT_AA));
local_error_encode(qinfo, env, edns, repinfo, buf, temp,
rcode, (rcode|BIT_AA), LDNS_EDE_NONE, NULL);
return 1;
} else if(lz_type == local_zone_typetransparent
|| lz_type == local_zone_always_transparent) {
@ -1705,9 +1715,10 @@ local_zones_zone_answer(struct local_zone* z, struct module_env* env,
return local_encode(qinfo, env, edns, repinfo, buf, temp,
&lrr, 1, LDNS_RCODE_NOERROR);
} else {
/* NODATA: No EDE needed */
local_error_encode(qinfo, env, edns, repinfo, buf,
temp, LDNS_RCODE_NOERROR,
(LDNS_RCODE_NOERROR|BIT_AA));
(LDNS_RCODE_NOERROR|BIT_AA), -1, NULL);
}
return 1;
}
@ -1720,8 +1731,9 @@ local_zones_zone_answer(struct local_zone* z, struct module_env* env,
if(z != NULL && z->soa && z->soa_negative)
return local_encode(qinfo, env, edns, repinfo, buf, temp,
z->soa_negative, 0, rcode);
/* NODATA: No EDE needed */
local_error_encode(qinfo, env, edns, repinfo, buf, temp, rcode,
(rcode|BIT_AA));
(rcode|BIT_AA), LDNS_EDE_NONE, NULL);
return 1;
}

View File

@ -64,6 +64,11 @@
#include "respip/respip.h"
#include "services/listen_dnsport.h"
#ifdef CLIENT_SUBNET
#include "edns-subnet/subnetmod.h"
#include "edns-subnet/edns-subnet.h"
#endif
/** subtract timers and the values do not overflow or become negative */
static void
timeval_subtract(struct timeval* d, const struct timeval* end, const struct timeval* start)
@ -458,7 +463,8 @@ mesh_serve_expired_init(struct mesh_state* mstate, int timeout)
void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
struct respip_client_info* cinfo, uint16_t qflags,
struct edns_data* edns, struct comm_reply* rep, uint16_t qid)
struct edns_data* edns, struct comm_reply* rep, uint16_t qid,
int rpz_passthru)
{
struct mesh_state* s = NULL;
int unique = unique_mesh_state(edns->opt_list_in, mesh->env);
@ -513,6 +519,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
}
if(unique)
mesh_state_make_unique(s);
s->s.rpz_passthru = rpz_passthru;
/* copy the edns options we got from the front */
if(edns->opt_list_in) {
s->s.edns_opts_front_in = edns_opt_copy_region(edns->opt_list_in,
@ -606,7 +613,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
int
mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
uint16_t qflags, struct edns_data* edns, sldns_buffer* buf,
uint16_t qid, mesh_cb_func_type cb, void* cb_arg)
uint16_t qid, mesh_cb_func_type cb, void* cb_arg, int rpz_passthru)
{
struct mesh_state* s = NULL;
int unique = unique_mesh_state(edns->opt_list_in, mesh->env);
@ -632,6 +639,7 @@ mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
}
if(unique)
mesh_state_make_unique(s);
s->s.rpz_passthru = rpz_passthru;
if(edns->opt_list_in) {
s->s.edns_opts_front_in = edns_opt_copy_region(edns->opt_list_in,
s->s.region);
@ -686,7 +694,8 @@ mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
* 0 (false), in which case the new state is only made runnable so it
* will not be run recursively on top of the current state. */
static void mesh_schedule_prefetch(struct mesh_area* mesh,
struct query_info* qinfo, uint16_t qflags, time_t leeway, int run)
struct query_info* qinfo, uint16_t qflags, time_t leeway, int run,
int rpz_passthru)
{
struct mesh_state* s = mesh_area_find(mesh, NULL, qinfo,
qflags&(BIT_RD|BIT_CD), 0, 0);
@ -732,15 +741,16 @@ static void mesh_schedule_prefetch(struct mesh_area* mesh,
/* move to either the forever or the jostle_list */
if(mesh->num_forever_states < mesh->max_forever_states) {
mesh->num_forever_states ++;
mesh_list_insert(s, &mesh->forever_first,
mesh_list_insert(s, &mesh->forever_first,
&mesh->forever_last);
s->list_select = mesh_forever_list;
} else {
mesh_list_insert(s, &mesh->jostle_first,
mesh_list_insert(s, &mesh->jostle_first,
&mesh->jostle_last);
s->list_select = mesh_jostle_list;
}
}
s->s.rpz_passthru = rpz_passthru;
if(!run) {
#ifdef UNBOUND_DEBUG
@ -756,10 +766,114 @@ static void mesh_schedule_prefetch(struct mesh_area* mesh,
mesh_run(mesh, s, module_event_new, NULL);
}
void mesh_new_prefetch(struct mesh_area* mesh, struct query_info* qinfo,
uint16_t qflags, time_t leeway)
#ifdef CLIENT_SUBNET
/* Same logic as mesh_schedule_prefetch but tailored to the subnet module logic
* like passing along the comm_reply info. This will be faked into an EDNS
* option for processing by the subnet module if the client has not already
* attached its own ECS data. */
static void mesh_schedule_prefetch_subnet(struct mesh_area* mesh,
struct query_info* qinfo, uint16_t qflags, time_t leeway, int run,
int rpz_passthru, struct comm_reply* rep, struct edns_option* edns_list)
{
mesh_schedule_prefetch(mesh, qinfo, qflags, leeway, 1);
struct mesh_state* s = NULL;
struct edns_option* opt = NULL;
#ifdef UNBOUND_DEBUG
struct rbnode_type* n;
#endif
if(!mesh_make_new_space(mesh, NULL)) {
verbose(VERB_ALGO, "Too many queries. dropped prefetch.");
mesh->stats_dropped ++;
return;
}
s = mesh_state_create(mesh->env, qinfo, NULL,
qflags&(BIT_RD|BIT_CD), 0, 0);
if(!s) {
log_err("prefetch_subnet mesh_state_create: out of memory");
return;
}
mesh_state_make_unique(s);
opt = edns_opt_list_find(edns_list, mesh->env->cfg->client_subnet_opcode);
if(opt) {
/* Use the client's ECS data */
if(!edns_opt_list_append(&s->s.edns_opts_front_in, opt->opt_code,
opt->opt_len, opt->opt_data, s->s.region)) {
log_err("prefetch_subnet edns_opt_list_append: out of memory");
return;
}
} else {
/* Fake the ECS data from the client's IP */
struct ecs_data ecs;
memset(&ecs, 0, sizeof(ecs));
subnet_option_from_ss(&rep->addr, &ecs, mesh->env->cfg);
if(ecs.subnet_validdata == 0) {
log_err("prefetch_subnet subnet_option_from_ss: invalid data");
return;
}
subnet_ecs_opt_list_append(&ecs, &s->s.edns_opts_front_in, &s->s);
if(!s->s.edns_opts_front_in) {
log_err("prefetch_subnet subnet_ecs_opt_list_append: out of memory");
return;
}
}
#ifdef UNBOUND_DEBUG
n =
#else
(void)
#endif
rbtree_insert(&mesh->all, &s->node);
log_assert(n != NULL);
/* set detached (it is now) */
mesh->num_detached_states++;
/* make it ignore the cache */
sock_list_insert(&s->s.blacklist, NULL, 0, s->s.region);
s->s.prefetch_leeway = leeway;
if(s->list_select == mesh_no_list) {
/* move to either the forever or the jostle_list */
if(mesh->num_forever_states < mesh->max_forever_states) {
mesh->num_forever_states ++;
mesh_list_insert(s, &mesh->forever_first,
&mesh->forever_last);
s->list_select = mesh_forever_list;
} else {
mesh_list_insert(s, &mesh->jostle_first,
&mesh->jostle_last);
s->list_select = mesh_jostle_list;
}
}
s->s.rpz_passthru = rpz_passthru;
if(!run) {
#ifdef UNBOUND_DEBUG
n =
#else
(void)
#endif
rbtree_insert(&mesh->run, &s->run_node);
log_assert(n != NULL);
return;
}
mesh_run(mesh, s, module_event_new, NULL);
}
#endif /* CLIENT_SUBNET */
void mesh_new_prefetch(struct mesh_area* mesh, struct query_info* qinfo,
uint16_t qflags, time_t leeway, int rpz_passthru,
struct comm_reply* rep, struct edns_option* opt_list)
{
(void)opt_list;
(void)rep;
#ifdef CLIENT_SUBNET
if(rep)
mesh_schedule_prefetch_subnet(mesh, qinfo, qflags, leeway, 1,
rpz_passthru, rep, opt_list);
else
#endif
mesh_schedule_prefetch(mesh, qinfo, qflags, leeway, 1,
rpz_passthru);
}
void mesh_report_reply(struct mesh_area* mesh, struct outbound_entry* e,
@ -1234,7 +1348,7 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
(rep->security <= sec_status_bogus ||
rep->security == sec_status_secure_sentinel_fail)) {
rcode = LDNS_RCODE_SERVFAIL;
if(m->s.env->cfg->stat_extended)
if(m->s.env->cfg->stat_extended)
m->s.env->mesh->ans_bogus++;
}
if(rep && rep->security == sec_status_secure)
@ -1290,6 +1404,36 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
&r->edns, &r->query_reply, m->s.region, &r->start_time))
r->edns.opt_list_inplace_cb_out = NULL;
}
/* Send along EDE BOGUS EDNS0 option when answer is bogus */
if(m->s.env->cfg->ede && rcode == LDNS_RCODE_SERVFAIL &&
m->s.env->need_to_validate && (!(r->qflags&BIT_CD) ||
m->s.env->cfg->ignore_cd) && rep &&
(rep->security <= sec_status_bogus ||
rep->security == sec_status_secure_sentinel_fail)) {
char *reason = m->s.env->cfg->val_log_level >= 2
? errinf_to_str_bogus(&m->s) : NULL;
/* During validation the EDE code can be received via two
* code paths. One code path fills the reply_info EDE, and
* the other fills it in the errinf_strlist. These paths
* intersect at some points, but where is opaque due to
* the complexity of the validator. At the time of writing
* we make the choice to prefer the EDE from errinf_strlist
* but a compelling reason to do otherwise is just as valid
*/
sldns_ede_code reason_bogus = errinf_to_reason_bogus(&m->s);
if ((reason_bogus == LDNS_EDE_DNSSEC_BOGUS &&
rep->reason_bogus != LDNS_EDE_NONE) ||
reason_bogus == LDNS_EDE_NONE) {
reason_bogus = rep->reason_bogus;
}
if(reason_bogus != LDNS_EDE_NONE) {
edns_opt_list_append_ede(&r->edns.opt_list_out,
m->s.region, reason_bogus, reason);
}
free(reason);
}
error_encode(r_buffer, rcode, &m->s.qinfo, r->qid,
r->qflags, &r->edns);
m->reply_list = NULL;
@ -1313,6 +1457,8 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
if(!inplace_cb_reply_servfail_call(m->s.env, &m->s.qinfo, &m->s,
rep, LDNS_RCODE_SERVFAIL, &r->edns, &r->query_reply, m->s.region, &r->start_time))
r->edns.opt_list_inplace_cb_out = NULL;
/* internal server error (probably malloc failure) so no
* EDE (RFC8914) needed */
error_encode(r_buffer, LDNS_RCODE_SERVFAIL,
&m->s.qinfo, r->qid, r->qflags, &r->edns);
}
@ -1524,7 +1670,7 @@ int mesh_state_add_reply(struct mesh_state* s, struct edns_data* edns,
struct comm_reply* rep, uint16_t qid, uint16_t qflags,
const struct query_info* qinfo)
{
struct mesh_reply* r = regional_alloc(s->s.region,
struct mesh_reply* r = regional_alloc(s->s.region,
sizeof(struct mesh_reply));
if(!r)
return 0;
@ -1693,6 +1839,7 @@ mesh_continue(struct mesh_area* mesh, struct mesh_state* mstate,
if(mstate->s.curmod == 0) {
struct query_info* qinfo = NULL;
uint16_t qflags;
int rpz_p = 0;
mesh_query_done(mstate);
mesh_walk_supers(mesh, mstate);
@ -1701,13 +1848,15 @@ mesh_continue(struct mesh_area* mesh, struct mesh_state* mstate,
* from an external DNS server, we'll need to schedule
* a prefetch after removing the current state, so
* we need to make a copy of the query info here. */
if(mstate->s.need_refetch)
if(mstate->s.need_refetch) {
mesh_copy_qinfo(mstate, &qinfo, &qflags);
rpz_p = mstate->s.rpz_passthru;
}
mesh_state_delete(&mstate->s);
if(qinfo) {
mesh_schedule_prefetch(mesh, qinfo, qflags,
0, 1);
0, 1, rpz_p);
}
return 0;
}
@ -1917,7 +2066,7 @@ apply_respip_action(struct module_qstate* qstate,
return 1;
if(!respip_rewrite_reply(qinfo, cinfo, rep, encode_repp, actinfo,
alias_rrset, 0, qstate->region, az))
alias_rrset, 0, qstate->region, az, NULL))
return 0;
/* xxx_deny actions mean dropping the reply, unless the original reply
@ -2042,6 +2191,14 @@ mesh_serve_expired_callback(void* arg)
}
}
/* Add EDE Stale Answer (RCF8914). Ignore global ede as this is
* warning instead of an error */
if (r->edns.edns_present && qstate->env->cfg->ede_serve_expired &&
qstate->env->cfg->ede) {
edns_opt_list_append_ede(&r->edns.opt_list_out,
mstate->s.region, LDNS_EDE_STALE_ANSWER, NULL);
}
r_buffer = r->query_reply.c->buffer;
if(r->query_reply.c->tcp_req_info)
r_buffer = r->query_reply.c->tcp_req_info->spool_buffer;

View File

@ -296,10 +296,13 @@ void mesh_delete(struct mesh_area* mesh);
* @param edns: edns data from client query.
* @param rep: where to reply to.
* @param qid: query id to reply with.
* @param rpz_passthru: if true, the rpz passthru was previously found and
* further rpz processing is stopped.
*/
void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
struct respip_client_info* cinfo, uint16_t qflags,
struct edns_data* edns, struct comm_reply* rep, uint16_t qid);
struct edns_data* edns, struct comm_reply* rep, uint16_t qid,
int rpz_passthru);
/**
* New query with callback. Create new query state if needed, and
@ -314,11 +317,13 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
* @param qid: query id to reply with.
* @param cb: callback function.
* @param cb_arg: callback user arg.
* @param rpz_passthru: if true, the rpz passthru was previously found and
* further rpz processing is stopped.
* @return 0 on error.
*/
int mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
uint16_t qflags, struct edns_data* edns, struct sldns_buffer* buf,
uint16_t qid, mesh_cb_func_type cb, void* cb_arg);
uint16_t qid, mesh_cb_func_type cb, void* cb_arg, int rpz_passthru);
/**
* New prefetch message. Create new query state if needed.
@ -328,9 +333,15 @@ int mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
* @param qinfo: query from client.
* @param qflags: flags from client query.
* @param leeway: TTL leeway what to expire earlier for this update.
* @param rpz_passthru: if true, the rpz passthru was previously found and
* further rpz processing is stopped.
* @param rep: comm_reply for the client; to be used when subnet is enabled.
* @param opt_list: edns opt_list from the client; to be used when subnet is
* enabled.
*/
void mesh_new_prefetch(struct mesh_area* mesh, struct query_info* qinfo,
uint16_t qflags, time_t leeway);
uint16_t qflags, time_t leeway, int rpz_passthru,
struct comm_reply* rep, struct edns_option* opt_list);
/**
* Handle new event from the wire. A serviced query has returned.

View File

@ -1994,6 +1994,9 @@ static int udp_connect_needs_log(int err)
# endif
# ifdef ENETDOWN
case ENETDOWN:
# endif
# ifdef EADDRNOTAVAIL
case EADDRNOTAVAIL:
# endif
case EPERM:
case EACCES:
@ -2294,7 +2297,7 @@ reuse_tcp_select_id(struct reuse_tcp* reuse, struct outside_network* outnet)
node = rbtree_first(&reuse->tree_by_id);
log_assert(node && node != RBTREE_NULL); /* tree not empty */
/* see if select is before first node */
if(select < tree_by_id_get_id(node))
if(select < (unsigned)tree_by_id_get_id(node))
return select;
count += tree_by_id_get_id(node);
/* perhaps select is between nodes */

View File

@ -526,13 +526,13 @@ rpz_create(struct config_auth* p)
size_t nmlen = sizeof(nm);
if(!p->rpz_cname) {
log_err("RPZ override with cname action found, but no "
log_err("rpz: override with cname action found, but no "
"rpz-cname-override configured");
goto err;
}
if(sldns_str2wire_dname_buf(p->rpz_cname, nm, &nmlen) != 0) {
log_err("cannot parse RPZ cname override: %s",
log_err("rpz: cannot parse cname override: %s",
p->rpz_cname);
goto err;
}
@ -614,7 +614,7 @@ rpz_insert_local_zones_trigger(struct local_zones* lz, uint8_t* dname,
return; /* no need to log these types as unsupported */
}
dname_str(dname, str);
verbose(VERB_ALGO, "RPZ: qname trigger, %s skipping unsupported action: %s",
verbose(VERB_ALGO, "rpz: qname trigger, %s skipping unsupported action: %s",
str, rpz_action_to_string(a));
free(dname);
return;
@ -999,7 +999,7 @@ rpz_insert_response_ip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen,
rpz_action_to_respip_action(a) == respip_invalid) {
char str[255+1];
dname_str(dname, str);
verbose(VERB_ALGO, "RPZ: respip trigger, %s skipping unsupported action: %s",
verbose(VERB_ALGO, "rpz: respip trigger, %s skipping unsupported action: %s",
str, rpz_action_to_string(a));
return 0;
}
@ -1560,7 +1560,9 @@ rpz_local_encode(struct module_env* env, struct query_info* qinfo,
}
static struct local_rrset*
rpz_find_synthesized_rrset(int qtype, struct clientip_synthesized_rr* data) {
rpz_find_synthesized_rrset(uint16_t qtype,
struct clientip_synthesized_rr* data)
{
struct local_rrset* cursor = data->data;
while( cursor != NULL) {
struct packed_rrset_key* packed_rrset = &cursor->rrset->rk;
@ -1997,6 +1999,7 @@ rpz_apply_nsip_trigger(struct module_qstate* ms, struct rpz* r,
break;
case RPZ_PASSTHRU_ACTION:
ret = NULL;
ms->rpz_passthru = 1;
break;
default:
verbose(VERB_ALGO, "rpz: nsip: bug: unhandled or invalid action: '%s'",
@ -2051,6 +2054,7 @@ rpz_apply_nsdname_trigger(struct module_qstate* ms, struct rpz* r,
break;
case RPZ_PASSTHRU_ACTION:
ret = NULL;
ms->rpz_passthru = 1;
break;
default:
verbose(VERB_ALGO, "rpz: nsip: bug: unhandled or invalid action: '%s'",
@ -2114,6 +2118,11 @@ rpz_callback_from_iterator_module(struct module_qstate* ms, struct iter_qstate*
struct local_zone* z = NULL;
struct matched_delegation_point match = {0};
if(ms->rpz_passthru) {
verbose(VERB_ALGO, "query is rpz_passthru, no further processing");
return NULL;
}
if(ms->env == NULL || ms->env->auth_zones == NULL) { return 0; }
az = ms->env->auth_zones;
@ -2179,6 +2188,11 @@ struct dns_msg* rpz_callback_from_iterator_cname(struct module_qstate* ms,
enum localzone_type lzt;
struct dns_msg* ret = NULL;
if(ms->rpz_passthru) {
verbose(VERB_ALGO, "query is rpz_passthru, no further processing");
return NULL;
}
if(ms->env == NULL || ms->env->auth_zones == NULL) { return 0; }
az = ms->env->auth_zones;
@ -2253,6 +2267,7 @@ struct dns_msg* rpz_callback_from_iterator_cname(struct module_qstate* ms,
break;
case RPZ_PASSTHRU_ACTION:
ret = NULL;
ms->rpz_passthru = 1;
break;
default:
verbose(VERB_ALGO, "rpz: qname trigger after cname: bug: unhandled or invalid action: '%s'",
@ -2270,7 +2285,8 @@ rpz_apply_maybe_clientip_trigger(struct auth_zones* az, struct module_env* env,
uint8_t* taglist, size_t taglen, struct ub_server_stats* stats,
sldns_buffer* buf, struct regional* temp,
/* output parameters */
struct local_zone** z_out, struct auth_zone** a_out, struct rpz** r_out)
struct local_zone** z_out, struct auth_zone** a_out, struct rpz** r_out,
int* passthru)
{
int ret = 0;
enum rpz_action client_action;
@ -2278,7 +2294,9 @@ rpz_apply_maybe_clientip_trigger(struct auth_zones* az, struct module_env* env,
az, qinfo, repinfo, taglist, taglen, stats, z_out, a_out, r_out);
client_action = ((node == NULL) ? RPZ_INVALID_ACTION : node->action);
if(client_action == RPZ_PASSTHRU_ACTION) {
*passthru = 1;
}
if(*z_out == NULL || (client_action != RPZ_INVALID_ACTION &&
client_action != RPZ_PASSTHRU_ACTION)) {
if(client_action == RPZ_PASSTHRU_ACTION
@ -2323,7 +2341,7 @@ int
rpz_callback_from_worker_request(struct auth_zones* az, struct module_env* env,
struct query_info* qinfo, struct edns_data* edns, sldns_buffer* buf,
struct regional* temp, struct comm_reply* repinfo, uint8_t* taglist,
size_t taglen, struct ub_server_stats* stats)
size_t taglen, struct ub_server_stats* stats, int* passthru)
{
struct rpz* r = NULL;
struct auth_zone* a = NULL;
@ -2332,7 +2350,8 @@ rpz_callback_from_worker_request(struct auth_zones* az, struct module_env* env,
enum localzone_type lzt;
int clientip_trigger = rpz_apply_maybe_clientip_trigger(az, env, qinfo,
edns, repinfo, taglist, taglen, stats, buf, temp, &z, &a, &r);
edns, repinfo, taglist, taglen, stats, buf, temp, &z, &a, &r,
passthru);
if(clientip_trigger >= 0) {
if(a) {
lock_rw_unlock(&a->lock);
@ -2357,6 +2376,10 @@ rpz_callback_from_worker_request(struct auth_zones* az, struct module_env* env,
} else {
lzt = rpz_action_to_localzone_type(r->action_override);
}
if(r->action_override == RPZ_PASSTHRU_ACTION ||
lzt == local_zone_always_transparent /* RPZ_PASSTHRU_ACTION */) {
*passthru = 1;
}
if(verbosity >= VERB_ALGO) {
char nm[255+1], zn[255+1];

View File

@ -176,12 +176,14 @@ void rpz_remove_rr(struct rpz* r, size_t aznamelen, uint8_t* dname,
* @param taglist: taglist to lookup.
* @param taglen: length of taglist.
* @param stats: worker stats struct
* @param passthru: returns if the query can passthru further rpz processing.
* @return: 1 if client answer is ready, 0 to continue resolving
*/
int rpz_callback_from_worker_request(struct auth_zones* az, struct module_env* env,
struct query_info* qinfo, struct edns_data* edns, sldns_buffer* buf,
struct regional* temp, struct comm_reply* repinfo,
uint8_t* taglist, size_t taglen, struct ub_server_stats* stats);
uint8_t* taglist, size_t taglen, struct ub_server_stats* stats,
int* passthru);
/**
* Callback to process when the iterator module is about to send queries.

View File

@ -209,11 +209,13 @@ sldns_hexdigit_to_int(char ch)
}
uint32_t
sldns_str2period(const char *nptr, const char **endptr)
sldns_str2period(const char *nptr, const char **endptr, int* overflow)
{
int sign = 0;
uint32_t i = 0;
uint32_t seconds = 0;
const uint32_t maxint = 0xffffffff;
*overflow = 0;
for(*endptr = nptr; **endptr; (*endptr)++) {
switch (**endptr) {
@ -236,26 +238,46 @@ sldns_str2period(const char *nptr, const char **endptr)
break;
case 's':
case 'S':
if(seconds > maxint-i) {
*overflow = 1;
return 0;
}
seconds += i;
i = 0;
break;
case 'm':
case 'M':
if(i > maxint/60 || seconds > maxint-(i*60)) {
*overflow = 1;
return 0;
}
seconds += i * 60;
i = 0;
break;
case 'h':
case 'H':
if(i > maxint/(60*60) || seconds > maxint-(i*60*60)) {
*overflow = 1;
return 0;
}
seconds += i * 60 * 60;
i = 0;
break;
case 'd':
case 'D':
if(i > maxint/(60*60*24) || seconds > maxint-(i*60*60*24)) {
*overflow = 1;
return 0;
}
seconds += i * 60 * 60 * 24;
i = 0;
break;
case 'w':
case 'W':
if(i > maxint/(60*60*24*7) || seconds > maxint-(i*60*60*24*7)) {
*overflow = 1;
return 0;
}
seconds += i * 60 * 60 * 24 * 7;
i = 0;
break;
@ -269,15 +291,27 @@ sldns_str2period(const char *nptr, const char **endptr)
case '7':
case '8':
case '9':
if(i > maxint/10 || i*10 > maxint - (**endptr - '0')) {
*overflow = 1;
return 0;
}
i *= 10;
i += (**endptr - '0');
break;
default:
if(seconds > maxint-i) {
*overflow = 1;
return 0;
}
seconds += i;
/* disregard signedness */
return seconds;
}
}
if(seconds > maxint-i) {
*overflow = 1;
return 0;
}
seconds += i;
/* disregard signedness */
return seconds;

View File

@ -74,9 +74,11 @@ struct tm * sldns_serial_arithmetics_gmtime_r(int32_t time, time_t now, struct t
* converts a ttl value (like 5d2h) to a long.
* \param[in] nptr the start of the string
* \param[out] endptr points to the last char in case of error
* \param[out] overflow returns if the string causes integer overflow error,
* the number is too big, string of digits too long.
* \return the convert duration value
*/
uint32_t sldns_str2period(const char *nptr, const char **endptr);
uint32_t sldns_str2period(const char *nptr, const char **endptr, int* overflow);
/**
* Returns the int value of the given (hex) digit

View File

@ -97,18 +97,22 @@ extern "C" {
#define QDCOUNT(wirebuf) (ntohs(*(uint16_t *)(wirebuf+QDCOUNT_OFF)))
*/
#define LDNS_QDCOUNT(wirebuf) (sldns_read_uint16(wirebuf+LDNS_QDCOUNT_OFF))
#define LDNS_QDCOUNT_SET(wirebuf, i) (sldns_write_uint16(wirebuf+LDNS_QDCOUNT_OFF, i))
/* Counter of the answer section */
#define LDNS_ANCOUNT_OFF 6
#define LDNS_ANCOUNT(wirebuf) (sldns_read_uint16(wirebuf+LDNS_ANCOUNT_OFF))
#define LDNS_ANCOUNT_SET(wirebuf, i) (sldns_write_uint16(wirebuf+LDNS_ANCOUNT_OFF, i))
/* Counter of the authority section */
#define LDNS_NSCOUNT_OFF 8
#define LDNS_NSCOUNT(wirebuf) (sldns_read_uint16(wirebuf+LDNS_NSCOUNT_OFF))
#define LDNS_NSCOUNT_SET(wirebuf, i) (sldns_write_uint16(wirebuf+LDNS_NSCOUNT_OFF, i))
/* Counter of the additional section */
#define LDNS_ARCOUNT_OFF 10
#define LDNS_ARCOUNT(wirebuf) (sldns_read_uint16(wirebuf+LDNS_ARCOUNT_OFF))
#define LDNS_ARCOUNT_SET(wirebuf, i) (sldns_write_uint16(wirebuf+LDNS_ARCOUNT_OFF, i))
/**
* The sections of a packet

View File

@ -435,10 +435,42 @@ enum sldns_enum_edns_option
LDNS_EDNS_CLIENT_SUBNET = 8, /* RFC7871 */
LDNS_EDNS_KEEPALIVE = 11, /* draft-ietf-dnsop-edns-tcp-keepalive*/
LDNS_EDNS_PADDING = 12, /* RFC7830 */
LDNS_EDNS_EDE = 15, /* RFC8914 */
LDNS_EDNS_CLIENT_TAG = 16 /* draft-bellis-dnsop-edns-tags-01 */
};
typedef enum sldns_enum_edns_option sldns_edns_option;
enum sldns_enum_ede_code
{
LDNS_EDE_NONE = -1, /* EDE undefined for internal use */
LDNS_EDE_OTHER = 0,
LDNS_EDE_UNSUPPORTED_DNSKEY_ALG = 1,
LDNS_EDE_UNSUPPORTED_DS_DIGEST = 2,
LDNS_EDE_STALE_ANSWER = 3,
LDNS_EDE_FORGED_ANSWER = 4,
LDNS_EDE_DNSSEC_INDETERMINATE = 5,
LDNS_EDE_DNSSEC_BOGUS = 6,
LDNS_EDE_SIGNATURE_EXPIRED = 7,
LDNS_EDE_SIGNATURE_NOT_YET_VALID = 8,
LDNS_EDE_DNSKEY_MISSING = 9,
LDNS_EDE_RRSIGS_MISSING = 10,
LDNS_EDE_NO_ZONE_KEY_BIT_SET = 11,
LDNS_EDE_NSEC_MISSING = 12,
LDNS_EDE_CACHED_ERROR = 13,
LDNS_EDE_NOT_READY = 14,
LDNS_EDE_BLOCKED = 15,
LDNS_EDE_CENSORED = 16,
LDNS_EDE_FILTERED = 17,
LDNS_EDE_PROHIBITED = 18,
LDNS_EDE_STALE_NXDOMAIN_ANSWER = 19,
LDNS_EDE_NOT_AUTHORITATIVE = 20,
LDNS_EDE_NOT_SUPPORTED = 21,
LDNS_EDE_NO_REACHABLE_AUTHORITY = 22,
LDNS_EDE_NETWORK_ERROR = 23,
LDNS_EDE_INVALID_DATA = 24,
};
typedef enum sldns_enum_ede_code sldns_ede_code;
#define LDNS_EDNS_MASK_DO_BIT 0x8000
/** TSIG and TKEY extended rcodes (16bit), 0-15 are the normal rcodes. */

View File

@ -249,11 +249,16 @@ rrinternal_get_ttl(sldns_buffer* strbuf, char* token, size_t token_len,
int* not_there, uint32_t* ttl, uint32_t default_ttl)
{
const char* endptr;
int overflow;
if(sldns_bget_token(strbuf, token, "\t\n ", token_len) == -1) {
return RET_ERR(LDNS_WIREPARSE_ERR_SYNTAX_TTL,
sldns_buffer_position(strbuf));
}
*ttl = (uint32_t) sldns_str2period(token, &endptr);
*ttl = (uint32_t) sldns_str2period(token, &endptr, &overflow);
if(overflow) {
return RET_ERR(LDNS_WIREPARSE_ERR_SYNTAX_INTEGER_OVERFLOW,
sldns_buffer_position(strbuf));
}
if (strlen(token) > 0 && !isdigit((unsigned char)token[0])) {
*not_there = 1;
@ -373,7 +378,8 @@ rrinternal_get_quoted(sldns_buffer* strbuf, const char** delimiters,
/* skip spaces */
while(sldns_buffer_remaining(strbuf) > 0 &&
*(sldns_buffer_current(strbuf)) == ' ') {
(*(sldns_buffer_current(strbuf)) == ' ' ||
*(sldns_buffer_current(strbuf)) == '\t')) {
sldns_buffer_skip(strbuf, 1);
}
@ -606,7 +612,7 @@ sldns_affix_token(sldns_buffer* strbuf, char* token, size_t* token_len,
/* add space */
/* 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. */
* assignment below. */
if(addlen < 2) return 0;
token[*token_strlen] = ' ';
token[++(*token_strlen)] = 0;
@ -670,10 +676,10 @@ static int sldns_str2wire_check_svcbparams(uint8_t* rdata, uint16_t rdata_len)
,sldns_str2wire_svcparam_key_cmp);
/* The code below revolves around sematic errors in the SVCParam set.
/* The code below revolves around semantic errors in the SVCParam set.
* So long as we do not distinguish between running Unbound as a primary
* or as a secondary, we default to secondary behavior and we ignore the
* sematic errors. */
* semantic errors. */
#ifdef SVCB_SEMANTIC_ERRORS
{
@ -775,7 +781,8 @@ rrinternal_parse_rdata(sldns_buffer* strbuf, char* token, size_t token_len,
/* unknown RR data */
if(token_strlen>=2 && strncmp(token, "\\#", 2) == 0 &&
!quoted && (token_strlen == 2 || token[2]==' ')) {
!quoted && (token_strlen == 2 || token[2]==' ' ||
token[2]=='\t')) {
was_unknown_rr_format = 1;
if((status=rrinternal_parse_unknown(strbuf, token,
token_len, rr, rr_len, &rr_cur_len,
@ -1055,12 +1062,15 @@ int sldns_fp2wire_rr_buf(FILE* in, uint8_t* rr, size_t* len, size_t* dname_len,
return s;
} else if(strncmp(line, "$TTL", 4) == 0 && isspace((unsigned char)line[4])) {
const char* end = NULL;
int overflow = 0;
strlcpy((char*)rr, line, *len);
*len = 0;
*dname_len = 0;
if(!parse_state) return LDNS_WIREPARSE_ERR_OK;
parse_state->default_ttl = sldns_str2period(
sldns_strip_ws(line+5), &end);
sldns_strip_ws(line+5), &end, &overflow);
if(overflow)
return LDNS_WIREPARSE_ERR_SYNTAX_INTEGER_OVERFLOW;
} else if (strncmp(line, "$INCLUDE", 8) == 0) {
strlcpy((char*)rr, line, *len);
*len = 0;
@ -1117,7 +1127,7 @@ sldns_str2wire_svcparam_key_lookup(const char *key, size_t key_len)
if (!strncmp(key, "mandatory", sizeof("mandatory")-1))
return SVCB_KEY_MANDATORY;
if (!strncmp(key, "echconfig", sizeof("echconfig")-1))
return SVCB_KEY_ECH; /* allow "echconfig as well as "ech" */
return SVCB_KEY_ECH; /* allow "echconfig" as well as "ech" */
break;
case sizeof("alpn")-1:
@ -1356,7 +1366,7 @@ sldns_str2wire_svcbparam_mandatory(const char* val, uint8_t* rd, size_t* rd_len)
*/
qsort((void *)(rd + 4), count, sizeof(uint16_t), sldns_network_uint16_cmp);
/* The code below revolves around sematic errors in the SVCParam set.
/* The code below revolves around semantic errors in the SVCParam set.
* So long as we do not distinguish between running Unbound as a primary
* or as a secondary, we default to secondary behavior and we ignore the
* semantic errors. */
@ -1588,12 +1598,12 @@ static int sldns_str2wire_svcparam_buf(const char* str, uint8_t* rd, size_t* rd_
if (*val_in == '"') {
val_in++;
while (*val_in != '"'
&& (unsigned)(val_out - unescaped_val + 1) < sizeof(unescaped_val)
&& (size_t)(val_out - unescaped_val + 1) < sizeof(unescaped_val)
&& sldns_parse_char( (uint8_t*) val_out, &val_in)) {
val_out++;
}
} else {
while ((unsigned)(val_out - unescaped_val + 1) < sizeof(unescaped_val)
while ((size_t)(val_out - unescaped_val + 1) < sizeof(unescaped_val)
&& sldns_parse_char( (uint8_t*) val_out, &val_in)) {
val_out++;
}
@ -2157,9 +2167,13 @@ int sldns_str2wire_tsigtime_buf(const char* str, uint8_t* rd, size_t* len)
int sldns_str2wire_period_buf(const char* str, uint8_t* rd, size_t* len)
{
const char* end;
uint32_t p = sldns_str2period(str, &end);
int overflow;
uint32_t p = sldns_str2period(str, &end, &overflow);
if(*end != 0)
return RET_ERR(LDNS_WIREPARSE_ERR_SYNTAX_PERIOD, end-str);
if(overflow)
return RET_ERR(LDNS_WIREPARSE_ERR_SYNTAX_INTEGER_OVERFLOW,
end-str);
if(*len < 4)
return LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL;
sldns_write_uint32(rd, p);

View File

@ -194,6 +194,7 @@ static sldns_lookup_table sldns_edns_options_data[] = {
{ 8, "edns-client-subnet" },
{ 11, "edns-tcp-keepalive"},
{ 12, "Padding" },
{ 15, "EDE"},
{ 0, NULL}
};
sldns_lookup_table* sldns_edns_options = sldns_edns_options_data;

View File

@ -408,6 +408,28 @@ interfacechecks(struct config_file* cfg)
}
}
/** check interface-automatic-ports */
static void
ifautomaticportschecks(char* ifautomaticports)
{
char* now = ifautomaticports;
while(now && *now) {
char* after;
int extraport;
while(isspace((unsigned char)*now))
now++;
if(!*now)
break;
after = now;
extraport = (int)strtol(now, &after, 10);
if(extraport < 0 || extraport > 65535)
fatal_exit("interface-automatic-ports: port out of range at position %d in '%s'", (int)(now-ifautomaticports)+1, ifautomaticports);
if(extraport == 0 && now == after)
fatal_exit("interface-automatic-ports: parse error at position %d in '%s'", (int)(now-ifautomaticports)+1, ifautomaticports);
now = after;
}
}
/** check acl ips */
static void
aclchecks(struct config_file* cfg)
@ -608,6 +630,7 @@ morechecks(struct config_file* cfg)
warn_hosts("stub-host", cfg->stubs);
warn_hosts("forward-host", cfg->forwards);
interfacechecks(cfg);
ifautomaticportschecks(cfg->if_automatic_ports);
aclchecks(cfg);
tcpconnlimitchecks(cfg);

View File

@ -155,9 +155,9 @@ usage(void)
printf(" ratelimit_list [+a] list ratelimited domains\n");
printf(" ip_ratelimit_list [+a] list ratelimited ip addresses\n");
printf(" +a list all, also not ratelimited\n");
printf(" list_auth_zones list auth zones\n");
printf(" auth_zone_reload zone reload auth zone from zonefile\n");
printf(" auth_zone_transfer zone transfer auth zone from master\n");
printf(" list_auth_zones list auth zones (includes RPZ zones)\n");
printf(" auth_zone_reload zone reload auth zone (or RPZ zone) from zonefile\n");
printf(" auth_zone_transfer zone transfer auth zone (or RPZ zone) from master\n");
printf(" view_list_local_zones view list local-zones in view\n");
printf(" view_list_local_data view list local-data RRs in view\n");
printf(" view_local_zone view name type add local-zone in view\n");
@ -444,7 +444,7 @@ static void do_stats_shm(struct config_file* cfg, struct ub_stats_info* stats,
#endif /* HAVE_SHMGET */
/** print statistics from shm memory segment */
static void print_stats_shm(const char* cfgfile)
static void print_stats_shm(const char* cfgfile, int quiet)
{
#ifdef HAVE_SHMGET
struct config_file* cfg;
@ -474,8 +474,11 @@ static void print_stats_shm(const char* cfgfile)
fatal_exit("shmat(%d): %s", id_arr, strerror(errno));
}
/* print the stats */
do_stats_shm(cfg, stats, shm_stat);
if(!quiet) {
/* print the stats */
do_stats_shm(cfg, stats, shm_stat);
}
/* shutdown */
shmdt(shm_stat);
@ -499,7 +502,7 @@ static void ssl_path_err(const char* s, const char *path)
{
unsigned long err;
err = ERR_peek_error();
if (ERR_GET_LIB(err) == ERR_LIB_SYS) {
if(ERR_GET_LIB(err) == ERR_LIB_SYS) {
fprintf(stderr, "error: %s\n%s: %s\n",
s, path, ERR_reason_error_string(err));
exit(1);
@ -541,11 +544,11 @@ setup_ctx(struct config_file* cfg)
#endif
if(!SSL_CTX_use_certificate_chain_file(ctx,c_cert))
ssl_path_err("Error setting up SSL_CTX client cert", c_cert);
if (!SSL_CTX_use_PrivateKey_file(ctx,c_key,SSL_FILETYPE_PEM))
if(!SSL_CTX_use_PrivateKey_file(ctx,c_key,SSL_FILETYPE_PEM))
ssl_path_err("Error setting up SSL_CTX client key", c_key);
if (!SSL_CTX_check_private_key(ctx))
if(!SSL_CTX_check_private_key(ctx))
ssl_err("Error setting up SSL_CTX client key");
if (SSL_CTX_load_verify_locations(ctx, s_cert, NULL) != 1)
if(SSL_CTX_load_verify_locations(ctx, s_cert, NULL) != 1)
ssl_path_err("Error setting up SSL_CTX verify, server cert",
s_cert);
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
@ -880,8 +883,9 @@ go_cmd(SSL* ssl, int fd, int quiet, int argc, char* argv[])
if(first_line && strncmp(buf, "error", 5) == 0) {
printf("%s", buf);
was_error = 1;
} else if (!quiet)
} else if(!quiet) {
printf("%s", buf);
}
first_line = 0;
}
@ -987,7 +991,7 @@ int main(int argc, char* argv[])
#endif
}
if(argc >= 1 && strcmp(argv[0], "stats_shm")==0) {
print_stats_shm(cfgfile);
print_stats_shm(cfgfile, quiet);
return 0;
}
check_args_for_listcmd(argc, argv);

View File

@ -128,6 +128,8 @@ static void matchline(char* line, struct entry* e)
e->match_answer = 1;
} else if(str_keyword(&parse, "subdomain")) {
e->match_subdomain = 1;
} else if(str_keyword(&parse, "all_noedns")) {
e->match_all_noedns = 1;
} else if(str_keyword(&parse, "all")) {
e->match_all = 1;
} else if(str_keyword(&parse, "ttl")) {
@ -148,7 +150,22 @@ static void matchline(char* line, struct entry* e)
error("expected = or : in MATCH: %s", line);
parse++;
e->ixfr_soa_serial = (uint32_t)strtol(parse, (char**)&parse, 10);
while(isspace((unsigned char)*parse))
while(isspace((unsigned char)*parse))
parse++;
} else if(str_keyword(&parse, "ede")) {
e->match_ede = 1;
if(*parse != '=' && *parse != ':')
error("expected = or : in MATCH: %s", line);
parse++;
while(isspace((unsigned char)*parse))
parse++;
if(str_keyword(&parse, "any")) {
e->match_ede_any = 1;
} else {
e->ede_info_code = (uint16_t)strtol(parse,
(char**)&parse, 10);
}
while(isspace((unsigned char)*parse))
parse++;
} else {
error("could not parse MATCH: '%s'", parse);
@ -266,11 +283,15 @@ static struct entry* new_entry(void)
e->match_answer = 0;
e->match_subdomain = 0;
e->match_all = 0;
e->match_all_noedns = 0;
e->match_ttl = 0;
e->match_do = 0;
e->match_noedns = 0;
e->match_serial = 0;
e->ixfr_soa_serial = 0;
e->match_ede = 0;
e->match_ede_any = 0;
e->ede_info_code = -1;
e->match_transport = transport_any;
e->reply_list = NULL;
e->copy_id = 0;
@ -817,7 +838,7 @@ static uint32_t get_serial(uint8_t* p, size_t plen)
return 0;
}
/** get ptr to EDNS OPT record (and remaining length); behind the type u16 */
/** get ptr to EDNS OPT record (and remaining length); after the type u16 */
static int
pkt_find_edns_opt(uint8_t** p, size_t* plen)
{
@ -884,6 +905,39 @@ get_do_flag(uint8_t* pkt, size_t len)
return (int)(edns_bits&LDNS_EDNS_MASK_DO_BIT);
}
/** Snips the EDE option out of the OPT record and returns the EDNS EDE
* INFO-CODE if found, else -1 */
static int
extract_ede(uint8_t* pkt, size_t len)
{
uint8_t *rdata, *opt_position = pkt;
uint16_t rdlen, optlen;
size_t remaining = len;
int ede_code;
if(!pkt_find_edns_opt(&opt_position, &remaining)) return -1;
if(remaining < 8) return -1; /* malformed */
rdlen = sldns_read_uint16(opt_position+6);
rdata = opt_position + 8;
while(rdlen > 0) {
if(rdlen < 4) return -1; /* malformed */
optlen = sldns_read_uint16(rdata+2);
if(sldns_read_uint16(rdata) == LDNS_EDNS_EDE) {
if(rdlen < 6) return -1; /* malformed */
ede_code = sldns_read_uint16(rdata+4);
/* snip option from packet; assumes len is correct */
memmove(rdata, rdata+4+optlen,
(pkt+len)-(rdata+4+optlen));
/* update OPT size */
sldns_write_uint16(opt_position+6,
sldns_read_uint16(opt_position+6)-(4+optlen));
return ede_code;
}
rdlen -= 4 + optlen;
rdata += 4 + optlen;
}
return -1;
}
/** zero TTLs in packet */
static void
zerottls(uint8_t* pkt, size_t pktlen)
@ -1201,7 +1255,7 @@ match_question(uint8_t* q, size_t qlen, uint8_t* p, size_t plen, int mttl)
return 0;
}
/* remove after answer section, (;; AUTH, ;; ADD, ;; MSG size ..) */
/* remove after answer section, (;; ANS, ;; AUTH, ;; ADD ..) */
s = strstr(qcmpstr, ";; ANSWER SECTION");
if(!s) s = strstr(qcmpstr, ";; AUTHORITY SECTION");
if(!s) s = strstr(qcmpstr, ";; ADDITIONAL SECTION");
@ -1292,18 +1346,36 @@ match_answer(uint8_t* q, size_t qlen, uint8_t* p, size_t plen, int mttl)
return r;
}
/** ignore EDNS lines in the string by overwriting them with what's left or
* zero out if at end of the string */
static int
ignore_edns_lines(char* str) {
char* edns = str, *n;
size_t str_len = strlen(str);
while((edns = strstr(edns, "; EDNS"))) {
n = strchr(edns, '\n');
if(!n) {
/* EDNS at end of string; zero */
*edns = 0;
break;
}
memmove(edns, n+1, str_len-(n-str));
}
return 1;
}
/** match all of the packet */
int
match_all(uint8_t* q, size_t qlen, uint8_t* p, size_t plen, int mttl,
int noloc)
int noloc, int noedns)
{
char* qstr, *pstr;
uint8_t* qb = q, *pb = p;
int r;
/* zero TTLs */
qb = memdup(q, qlen);
pb = memdup(p, plen);
if(!qb || !pb) error("out of memory");
/* zero TTLs */
if(!mttl) {
zerottls(qb, qlen);
zerottls(pb, plen);
@ -1313,6 +1385,11 @@ match_all(uint8_t* q, size_t qlen, uint8_t* p, size_t plen, int mttl,
qstr = sldns_wire2str_pkt(qb, qlen);
pstr = sldns_wire2str_pkt(pb, plen);
if(!qstr || !pstr) error("cannot pkt2string");
/* should we ignore EDNS lines? */
if(noedns) {
ignore_edns_lines(qstr);
ignore_edns_lines(pstr);
}
r = (strcmp(qstr, pstr) == 0);
if(!r) {
/* remove ;; MSG SIZE (at end of string) */
@ -1321,8 +1398,8 @@ match_all(uint8_t* q, size_t qlen, uint8_t* p, size_t plen, int mttl,
s = strstr(pstr, ";; MSG SIZE");
if(s) *s=0;
r = (strcmp(qstr, pstr) == 0);
if(!r && !noloc) {
/* we are going to fail see if it is because of EDNS */
if(!r && !noloc && !noedns) {
/* we are going to fail, see if the cause is EDNS */
char* a = strstr(qstr, "; EDNS");
char* b = strstr(pstr, "; EDNS");
if( (a&&!b) || (b&&!a) ) {
@ -1428,13 +1505,32 @@ find_match(struct entry* entries, uint8_t* query_pkt, size_t len,
enum transport_type transport)
{
struct entry* p = entries;
uint8_t* reply;
size_t rlen;
uint8_t* reply, *query_pkt_orig;
size_t rlen, query_pkt_orig_len;
/* Keep the original packet; it may be modified */
query_pkt_orig = memdup(query_pkt, len);
query_pkt_orig_len = len;
for(p=entries; p; p=p->next) {
verbose(3, "comparepkt: ");
reply = p->reply_list->reply_pkt;
rlen = p->reply_list->reply_len;
if(p->match_opcode && get_opcode(query_pkt, len) !=
/* Restore the original packet for each entry */
memcpy(query_pkt, query_pkt_orig, query_pkt_orig_len);
/* EDE should be first since it may modify the query_pkt */
if(p->match_ede) {
int info_code = extract_ede(query_pkt, len);
if(info_code == -1) {
verbose(3, "bad EDE. Expected but not found\n");
continue;
} else if(!p->match_ede_any &&
(uint16_t)info_code != p->ede_info_code) {
verbose(3, "bad EDE INFO-CODE. Expected: %d, "
"and got: %d\n", (int)p->ede_info_code,
info_code);
continue;
}
}
if(p->match_opcode && get_opcode(query_pkt, len) !=
get_opcode(reply, rlen)) {
verbose(3, "bad opcode\n");
continue;
@ -1502,14 +1598,25 @@ find_match(struct entry* entries, uint8_t* query_pkt, size_t len,
verbose(3, "bad transport\n");
continue;
}
if(p->match_all_noedns && !match_all(query_pkt, len, reply,
rlen, (int)p->match_ttl, 0, 1)) {
verbose(3, "bad all_noedns match\n");
continue;
}
if(p->match_all && !match_all(query_pkt, len, reply, rlen,
(int)p->match_ttl, 0)) {
(int)p->match_ttl, 0, 0)) {
verbose(3, "bad allmatch\n");
continue;
}
verbose(3, "match!\n");
/* Restore the original packet */
memcpy(query_pkt, query_pkt_orig, query_pkt_orig_len);
free(query_pkt_orig);
return p;
}
/* Restore the original packet */
memcpy(query_pkt, query_pkt_orig, query_pkt_orig_len);
free(query_pkt_orig);
return NULL;
}

View File

@ -40,20 +40,30 @@ struct sldns_file_parse_state;
ENTRY_BEGIN
; first give MATCH lines, that say what queries are matched
; by this entry.
; 'opcode' makes the query match the opcode from the reply
; if you leave it out, any opcode matches this entry.
; 'qtype' makes the query match the qtype from the reply
; 'qname' makes the query match the qname from the reply
; 'subdomain' makes the query match subdomains of qname from the reply
; 'serial=1023' makes the query match if ixfr serial is 1023.
; 'opcode' makes the query match the opcode from the reply;
; if you leave it out, any opcode matches this entry.
; 'qtype' makes the query match the qtype from the reply.
; 'qname' makes the query match the qname from the reply.
; 'subdomain' makes the query match subdomains of qname from the reply.
; 'serial=1023' makes the query match if ixfr serial is 1023.
; 'all' has to match header byte for byte and all rrs in packet.
; 'all_noedns' has to match header byte for byte and all rrs in packet;
; ignoring EDNS.
; 'ttl' used with all, rrs in packet must also have matching TTLs.
; 'DO' will match only queries with DO bit set.
; 'noedns' matches queries without EDNS OPT records.
; 'rcode' makes the query match the rcode from the reply
; 'question' makes the query match the question section
; 'answer' makes the query match the answer section
; 'rcode' makes the query match the rcode from the reply.
; 'question' makes the query match the question section.
; 'answer' makes the query match the answer section.
; 'ednsdata' matches queries to HEX_EDNS section.
; 'UDP' matches if the transport is UDP.
; 'TCP' matches if the transport is TCP.
; 'ede=2' makes the query match if the EDNS EDE info-code is 2.
; It also snips the EDE record out of the packet to facilitate
; other matches.
; 'ede=any' makes the query match any EDNS EDE info-code.
; It also snips the EDE record out of the packet to facilitate
; other matches.
MATCH [opcode] [qtype] [qname] [serial=<value>] [all] [ttl]
MATCH [UDP|TCP] DO
MATCH ...
@ -72,6 +82,12 @@ struct sldns_file_parse_state;
; 'sleep=10' sleeps for 10 seconds before giving the answer (TCP is open)
ADJUST [sleep=<num>] ; sleep before giving any reply
ADJUST [packet_sleep=<num>] ; sleep before this packet in sequence
; 'copy_ednsdata_assume_clientsubnet' copies ednsdata to reply, assumes
; it is clientsubnet and adjusts scopemask to match sourcemask.
ADJUST copy_ednsdata_assume_clientsubnet
; 'increment_ecs_scope' increments the ECS scope copied from the
; sourcemask by one.
ADJUST increment_ecs_scope
SECTION QUESTION
<RRs, one per line> ; the RRcount is determined automatically.
SECTION ANSWER
@ -167,11 +183,11 @@ struct entry {
/* match */
/* How to match an incoming query with this canned reply */
/** match query opcode with answer opcode */
uint8_t match_opcode;
uint8_t match_opcode;
/** match qtype with answer qtype */
uint8_t match_qtype;
uint8_t match_qtype;
/** match qname with answer qname */
uint8_t match_qname;
uint8_t match_qname;
/** match rcode with answer rcode */
uint8_t match_rcode;
/** match question section */
@ -179,11 +195,17 @@ struct entry {
/** match answer section */
uint8_t match_answer;
/** match qname as subdomain of answer qname */
uint8_t match_subdomain;
uint8_t match_subdomain;
/** match SOA serial number, from auth section */
uint8_t match_serial;
uint8_t match_serial;
/** match EDNS EDE info-code */
uint8_t match_ede;
/** match any EDNS EDE info-code */
uint8_t match_ede_any;
/** match all of the packet */
uint8_t match_all;
/** match all of the packet; ignore EDNS */
uint8_t match_all_noedns;
/** match ttls in the packet */
uint8_t match_ttl;
/** match DO bit */
@ -193,9 +215,11 @@ struct entry {
/** match edns data field given in hex */
uint8_t match_ednsdata_raw;
/** match query serial with this value. */
uint32_t ixfr_soa_serial;
uint32_t ixfr_soa_serial;
/** match on UDP/TCP */
enum transport_type match_transport;
enum transport_type match_transport;
/** match EDNS EDE info-code with this value. */
uint16_t ede_info_code;
/** pre canned reply */
struct reply_packet *reply_list;
@ -260,10 +284,11 @@ struct entry* find_match(struct entry* entries, uint8_t* query_pkt,
* @param mttl: if true, ttls must match, if false, ttls do not need to match
* @param noloc: if true, rrs may be reordered in their packet-section.
* rrs are then matches without location of the rr being important.
* @param noedns: if true, edns is not compared, if false, edns must match.
* @return true if matched.
*/
int match_all(uint8_t* q, size_t qlen, uint8_t* p, size_t plen, int mttl,
int noloc);
int noloc, int noedns);
/**
* copy & adjust packet, mallocs a copy.

View File

@ -243,28 +243,28 @@ b64_test(void)
memset(target, 0, sizeof(target));
result = sldns_b64_pton(p1, (uint8_t*)target, tarsize);
unit_assert(result == strlen("hello") && strcmp(target, "hello") == 0);
unit_assert(result == (int)strlen("hello") && strcmp(target, "hello") == 0);
memset(target, 0, sizeof(target));
result = sldns_b64_pton(p2, (uint8_t*)target, tarsize);
unit_assert(result == strlen("hello>") && strcmp(target, "hello>") == 0);
unit_assert(result == (int)strlen("hello>") && strcmp(target, "hello>") == 0);
memset(target, 0, sizeof(target));
result = sldns_b64_pton(p3, (uint8_t*)target, tarsize);
unit_assert(result == strlen("hello?!") && strcmp(target, "hello?!") == 0);
unit_assert(result == (int)strlen("hello?!") && strcmp(target, "hello?!") == 0);
memset(target, 0, sizeof(target));
result = sldns_b64_pton(p4, (uint8_t*)target, tarsize);
/* when padding is used everything that is not a block of 4 will be
* ignored */
unit_assert(result == strlen("hel") && strcmp(target, "hel") == 0);
unit_assert(result == (int)strlen("hel") && strcmp(target, "hel") == 0);
memset(target, 0, sizeof(target));
result = sldns_b64url_pton(u1, strlen(u1), (uint8_t*)target, tarsize);
unit_assert(result == strlen("hello") && strcmp(target, "hello") == 0);
unit_assert(result == (int)strlen("hello") && strcmp(target, "hello") == 0);
memset(target, 0, sizeof(target));
result = sldns_b64url_pton(u2, strlen(u2), (uint8_t*)target, tarsize);
unit_assert(result == strlen("hello>") && strcmp(target, "hello>") == 0);
unit_assert(result == (int)strlen("hello>") && strcmp(target, "hello>") == 0);
memset(target, 0, sizeof(target));
result = sldns_b64url_pton(u3, strlen(u3), (uint8_t*)target, tarsize);
unit_assert(result == strlen("hello+/") && strcmp(target, "hello?!") == 0);
unit_assert(result == (int)strlen("hello+/") && strcmp(target, "hello?!") == 0);
/* one item in block of four is not allowed */
memset(target, 0, sizeof(target));
result = sldns_b64url_pton(u4, strlen(u4), (uint8_t*)target, tarsize);

View File

@ -137,7 +137,7 @@ test_buffers(sldns_buffer* pkt, sldns_buffer* out)
/* compare packets */
unit_assert(match_all(sldns_buffer_begin(pkt), sldns_buffer_limit(pkt),
sldns_buffer_begin(out), sldns_buffer_limit(out), 1,
matches_nolocation));
matches_nolocation, 0));
return 0;
}

View File

@ -187,7 +187,7 @@ verifytest_rrset(struct module_env* env, struct val_env* ve,
}
setup_sigalg(dnskey, sigalg); /* check all algorithms in the dnskey */
/* ok to give null as qstate here, won't be used for answer section. */
sec = dnskeyset_verify_rrset(env, ve, rrset, dnskey, sigalg, &reason,
sec = dnskeyset_verify_rrset(env, ve, rrset, dnskey, sigalg, &reason, NULL,
LDNS_SECTION_ANSWER, NULL);
if(vsig) {
printf("verify outcome is: %s %s\n", sec_status_to_string(sec),

View File

@ -221,10 +221,10 @@ static void zonemd_check_test(void)
unit_assert(result && reason == NULL);
result = auth_zone_generate_zonemd_check(z, 241, hashalgo,
hash, hashlen, region, buf, &reason);
unit_assert(!result && strcmp(reason, "unsupported scheme")==0);
unit_assert(result && strcmp(reason, "unsupported scheme")==0);
result = auth_zone_generate_zonemd_check(z, scheme, 242,
hash, hashlen, region, buf, &reason);
unit_assert(!result && strcmp(reason, "unsupported algorithm")==0);
unit_assert(result && strcmp(reason, "unsupported algorithm")==0);
result = auth_zone_generate_zonemd_check(z, scheme, hashalgo,
hash, 2, region, buf, &reason);
unit_assert(!result && strcmp(reason, "digest length too small, less than 12")==0);

184
testdata/auth_zonemd_file_unknown.rpl vendored Normal file
View File

@ -0,0 +1,184 @@
; config options
server:
target-fetch-policy: "0 0 0 0 0"
auth-zone:
name: "example.com."
## zonefile (or none).
## zonefile: "example.com.zone"
## master by IP address or hostname
## can list multiple masters, each on one line.
## master:
## url for http fetch
## url:
## queries from downstream clients get authoritative answers.
## for-downstream: yes
for-downstream: no
## queries are used to fetch authoritative answers from this zone,
## instead of unbound itself sending queries there.
## for-upstream: yes
for-upstream: yes
## on failures with for-upstream, fallback to sending queries to
## the authority servers
## fallback-enabled: no
zonemd-check: yes
## this line generates zonefile: \n"/tmp/xxx.example.com"\n
zonefile:
TEMPFILE_NAME example.com
## this is the inline file /tmp/xxx.example.com
## the tempfiles are deleted when the testrun is over.
TEMPFILE_CONTENTS example.com
example.com. IN SOA ns.example.com. hostmaster.example.com. 200154054 28800 7200 604800 3600
example.com. IN NS ns.example.com.
example.com. IN ZONEMD 200154054 1 22 EFAA5B78B38AB1C45DE57B8167BCCE906451D0E72118E1F5E80B5F0C3CF04BFFC65D53C011185528EAD439D6F3A02F511961E090E5E4E0DFA013BD276D728B22
example.com. IN ZONEMD 200154054 21 2 EFAA5B78B38AB1C45DE57B8167BCCE906451D0E72118E1F5E80B5F0C3CF04BFFC65D53C011185528EAD439D6F3A02F511961E090E5E4E0DFA013BD276D728B22
www.example.com. IN A 127.0.0.1
ns.example.com. IN A 127.0.0.1
bar.example.com. IN A 1.2.3.4
ding.example.com. IN A 1.2.3.4
foo.example.com. IN A 1.2.3.4
TEMPFILE_END
stub-zone:
name: "."
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
CONFIG_END
SCENARIO_BEGIN Test authority zone with ZONEMD with unknown algo from zonefile
; 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 subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
com. IN NS
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 subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
example.com. IN NS
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.44
ENTRY_END
RANGE_END
; ns.example.net.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.44
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
example.net. IN NS
SECTION ANSWER
example.net. IN NS ns.example.net.
SECTION ADDITIONAL
ns.example.net. IN A 1.2.3.44
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ns.example.net. IN A
SECTION ANSWER
ns.example.net. IN A 1.2.3.44
SECTION AUTHORITY
example.net. IN NS ns.example.net.
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ns.example.net. IN AAAA
SECTION AUTHORITY
example.net. IN NS ns.example.net.
SECTION ADDITIONAL
www.example.net. IN A 1.2.3.44
ENTRY_END
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.net.
ENTRY_END
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
ENTRY_END
RANGE_END
STEP 1 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.example.com. IN A
ENTRY_END
; recursion happens here.
STEP 20 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. IN A 127.0.0.1
ENTRY_END
SCENARIO_END

View File

@ -4,6 +4,8 @@ server:
log-time-ascii: yes
fake-sha1: yes
trust-anchor-signaling: no
ede: yes
stub-zone:
name: "."
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
@ -150,7 +152,7 @@ ENTRY_END
STEP 20 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
MATCH all ede=9
REPLY QR RD RA DO SERVFAIL
SECTION QUESTION
www.example.com. IN A

View File

@ -5,6 +5,8 @@ server:
log-time-ascii: yes
fake-sha1: yes
trust-anchor-signaling: no
ede: yes
stub-zone:
name: "."
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
@ -138,7 +140,7 @@ ENTRY_END
STEP 20 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
MATCH all ede=6
REPLY QR RD RA DO SERVFAIL
SECTION QUESTION
www.example.com. IN A

View File

@ -4,6 +4,8 @@ server:
log-time-ascii: yes
fake-sha1: yes
trust-anchor-signaling: no
ede: yes
stub-zone:
name: "."
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
@ -155,7 +157,7 @@ ENTRY_END
STEP 30 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
MATCH all ede=9
REPLY QR RD RA DO SERVFAIL
SECTION QUESTION
www.example.com. IN A

View File

@ -4,6 +4,8 @@ server:
log-time-ascii: yes
fake-sha1: yes
trust-anchor-signaling: no
ede: yes
stub-zone:
name: "."
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
@ -155,7 +157,7 @@ ENTRY_END
STEP 30 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
MATCH all ede=6
REPLY QR RD RA DO SERVFAIL
SECTION QUESTION
www.example.com. IN A

View File

@ -6,6 +6,7 @@ server:
target-fetch-policy: "0 0 0 0 0"
fake-sha1: yes
trust-anchor-signaling: no
ede: yes
stub-zone:
name: "."
@ -578,7 +579,7 @@ ENTRY_END
; recursion happens here.
STEP 10 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
MATCH all ede=7
REPLY QR RD RA DO SERVFAIL
SECTION QUESTION
www.sub.example.com. IN A
@ -595,7 +596,7 @@ ENTRY_END
STEP 120 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
MATCH all ede=7
REPLY QR RD RA DO SERVFAIL
SECTION QUESTION
ftp.sub.example.com. IN A

View File

@ -6,6 +6,7 @@ server:
target-fetch-policy: "0 0 0 0 0"
fake-sha1: yes
trust-anchor-signaling: no
ede: yes
stub-zone:
name: "."
@ -560,7 +561,7 @@ ENTRY_END
; recursion happens here.
STEP 10 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
MATCH all ede=7
REPLY QR RD RA DO SERVFAIL
SECTION QUESTION
www.sub.example.com. IN A
@ -577,7 +578,7 @@ ENTRY_END
STEP 120 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
MATCH all ede=7
REPLY QR RD RA DO SERVFAIL
SECTION QUESTION
ftp.sub.example.com. IN A

View File

@ -7,6 +7,7 @@ server:
qname-minimisation: "no"
fake-sha1: yes
trust-anchor-signaling: no
ede: yes
stub-zone:
name: "."
@ -285,7 +286,7 @@ ENTRY_END
; recursion happens here.
STEP 10 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
MATCH all ede=7
REPLY QR RD RA DO SERVFAIL
SECTION QUESTION
www.example.com. IN A
@ -304,7 +305,7 @@ ENTRY_END
; recursion happens here.
STEP 120 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
MATCH all ede=7
REPLY QR RD RA DO SERVFAIL
SECTION QUESTION
ftp.example.com. IN A

1
testdata/ede.tdir/bogus/clean.sh vendored Executable file
View File

@ -0,0 +1 @@
rm -f K* piece1 base expired notyetincepted trust-anchors dnssec-failures.test.signed dnskey-failures.test.signed nsec-failures.test.signed rrsig-failures.test.signed

View File

@ -0,0 +1,10 @@
$ORIGIN dnskey-failures.test.
@ SOA ns hostmaster (
1 ; serial
14400 ; refresh (4 hours)
1800 ; retry (30 minutes)
2419200 ; expire (4 weeks)
300 ; minimum (5 minutes)
)
A 192.0.2.1

View File

@ -0,0 +1,15 @@
$ORIGIN dnssec-failures.test.
@ SOA ns hostmaster (
1 ; serial
14400 ; refresh (4 hours)
1800 ; retry (30 minutes)
2419200 ; expire (4 weeks)
300 ; minimum (5 minutes)
)
NS ns
ns A 192.0.2.1
notyetincepted TXT "Not yet incepted"
expired TXT "Expired"
sigsinvalid TXT "Signatures invalid"
missingrrsigs TXT "Signatures missing"

67
testdata/ede.tdir/bogus/make-broken-zone.sh vendored Executable file
View File

@ -0,0 +1,67 @@
#!/usr/bin/env bash
# create oudated zones
CSK=`ldns-keygen -a ECDSAP256SHA256 -k -r /dev/urandom dnssec-failures.test`
echo $CSK
echo ". IN DS 20326 8 2 e06d44b80b8f1d39a95c0b0d7c65d08458e880409bbc683457104237c7f8ec8d" | \
cat $CSK.ds - > bogus/trust-anchors
# differentiate for MacOS with "gdate"
DATE=date
which gdate > /dev/null 2>&1 && DATE=gdate
ONEMONTHAGO=`$DATE -d 'now - 1 month' +%Y%m%d`
YESTERDAY=`$DATE -d 'now - 2 days' +%Y%m%d`
TOMORROW=`$DATE -d 'now + 2 days' +%Y%m%d`
ldns-signzone -i $YESTERDAY -f - bogus/dnssec-failures.test $CSK | \
grep -v '^missingrrsigs\.dnssec-failures\.test\..*IN.*RRSIG.*TXT' | \
sed 's/Signatures invalid/Signatures INVALID/g' | \
grep -v '^notyetincepted\.dnssec-failures\.test\..*IN.*TXT' | \
grep -v '^notyetincepted\.dnssec-failures\.test\..*IN.*RRSIG.*TXT' | \
grep -v '^expired\.dnssec-failures\.test\..*IN.*TXT' | \
grep -v '^expired\.dnssec-failures\.test\..*IN.*RRSIG.*TXT' > base
ldns-signzone -i $ONEMONTHAGO -e $YESTERDAY -f - bogus/dnssec-failures.test $CSK | \
grep -v '[ ]NSEC[ ]' | \
grep '^expired\.dnssec-failures\.test\..*IN.*TXT' > expired
ldns-signzone -i $TOMORROW -f - bogus/dnssec-failures.test $CSK | \
grep -v '[ ]NSEC[ ]' | \
grep '^notyetincepted\.dnssec-failures\.test\..*IN.*TXT' > notyetincepted
cat base expired notyetincepted > bogus/dnssec-failures.test.signed
# cleanup old zone keys
rm -f $CSK.*
# create zone with DNSKEY missing
CSK=`ldns-keygen -a ECDSAP256SHA256 -k -r /dev/urandom dnskey-failures.test`
echo $CSK
cat $CSK.ds >> bogus/trust-anchors
ldns-signzone -f tmp.signed bogus/dnskey-failures.test $CSK
grep -v ' DNSKEY ' tmp.signed > bogus/dnskey-failures.test.signed
# cleanup old zone keys
rm -f $CSK.*
# create zone with NSEC missing
CSK=`ldns-keygen -a ECDSAP256SHA256 -k -r /dev/urandom nsec-failures.test`
echo $CSK
cat $CSK.ds >> bogus/trust-anchors
ldns-signzone -f tmp.signed bogus/nsec-failures.test $CSK
grep -v ' NSEC ' tmp.signed > bogus/nsec-failures.test.signed
# cleanup old zone keys
rm -f $CSK.*
# create zone with RRSIGs missing
CSK=`ldns-keygen -a ECDSAP256SHA256 -k -r /dev/urandom rrsig-failures.test`
echo $CSK
cat $CSK.ds >> bogus/trust-anchors
ldns-signzone -f tmp.signed bogus/rrsig-failures.test $CSK
grep -v ' RRSIG ' tmp.signed > bogus/rrsig-failures.test.signed
# cleanup
rm -f base expired notyetincepted tmp.signed $CSK.*

View File

@ -0,0 +1,10 @@
$ORIGIN nsec-failures.test.
@ SOA ns hostmaster (
1 ; serial
14400 ; refresh (4 hours)
1800 ; retry (30 minutes)
2419200 ; expire (4 weeks)
300 ; minimum (5 minutes)
)
A 192.0.2.1

View File

@ -0,0 +1,10 @@
$ORIGIN rrsig-failures.test.
@ SOA ns hostmaster (
1 ; serial
14400 ; refresh (4 hours)
1800 ; retry (30 minutes)
2419200 ; expire (4 weeks)
300 ; minimum (5 minutes)
)
A 192.0.2.1

27
testdata/ede.tdir/ede-auth.conf vendored Normal file
View File

@ -0,0 +1,27 @@
server:
verbosity: 1
use-syslog: no
chroot: ""
username: ""
directory: ""
pidfile: "unbound2.pid"
local-zone: test nodefault
interface: 127.0.0.1
port: @PORT2@
auth-zone:
name: "dnssec-failures.test"
zonefile: "bogus/dnssec-failures.test.signed"
auth-zone:
name: "dnskey-failures.test"
zonefile: "bogus/dnskey-failures.test.signed"
auth-zone:
name: "nsec-failures.test"
zonefile: "bogus/nsec-failures.test.signed"
auth-zone:
name: "rrsig-failures.test"
zonefile: "bogus/rrsig-failures.test.signed"

49
testdata/ede.tdir/ede.conf vendored Normal file
View File

@ -0,0 +1,49 @@
server:
verbosity: 2
interface: 127.0.0.1
port: @PORT@
use-syslog: no
directory: .
pidfile: "unbound.pid"
chroot: ""
username: ""
directory: ""
val-log-level: 2
trust-anchor-file: "bogus/trust-anchors"
module-config: "respip validator iterator"
ede: yes
access-control: 127.0.0.2/32 refuse
access-control: 127.0.0.3/32 allow
local-zone: hopsa.kidee. always_refuse
local-data: "hopsa.kidee. TXT hela hola"
local-zone: nlnetlabs.nl transparent
local-data: "hopsa.nlnetlabs.nl. TXT hela hola"
local-zone: uva.nl. always_null
local-zone: example.com redirect
local-data: "example.com CNAME *.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaa."
local-zone: test nodefault
do-not-query-localhost: no
forward-zone:
name: "dnssec-failures.test"
forward-addr: 127.0.0.1@@PORT2@
forward-zone:
name: "dnskey-failures.test"
forward-addr: 127.0.0.1@@PORT2@
forward-zone:
name: "nsec-failures.test"
forward-addr: 127.0.0.1@@PORT2@
forward-zone:
name: "rrsig-failures.test"
forward-addr: 127.0.0.1@@PORT2@

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

@ -0,0 +1,16 @@
BaseName: ede
Version: 1.0
Description: Test Extended DNS Errors (rfc8914)
CreationDate: Fri Aug 20 15:42:11 UTC 2021
Maintainer: Tom Carpay
Category:
Component:
CmdDepends:
Depends:
Help:
Pre: ede.pre
Post: ede.post
Test: ede.test
AuxFiles:
Passed:
Failure:

10
testdata/ede.tdir/ede.post vendored Normal file
View File

@ -0,0 +1,10 @@
# #-- ede.post --#
# 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
# teardown
. ../common.sh
kill_pid $UNBOUND_PID
kill_pid $UNBOUND_PID2

37
testdata/ede.tdir/ede.pre vendored Normal file
View File

@ -0,0 +1,37 @@
# #-- ede.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
. ../common.sh
get_random_port 2
UNBOUND_PORT=$RND_PORT
UNBOUND_PORT2=$(($RND_PORT + 1))
echo "UNBOUND_PORT=$UNBOUND_PORT" >> .tpkg.var.test
echo "UNBOUND_PORT2=$UNBOUND_PORT2" >> .tpkg.var.test
# rewrite config file with created ports
sed -e 's/@PORT\@/'$UNBOUND_PORT'/' < ede.conf > temp.conf
sed -e 's/@PORT2\@/'$UNBOUND_PORT2'/' < temp.conf > ub.conf
sed -e 's/@PORT2\@/'$UNBOUND_PORT2'/' < ede-auth.conf > ub2.conf
# create broken dnssec zone
bogus/make-broken-zone.sh
# start unbound in the background
PRE="../.."
$PRE/unbound -d -c ub.conf > unbound.log 2>&1 &
UNBOUND_PID=$!
echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test
# start authoritative unbound in the background
$PRE/unbound -d -c ub2.conf > unbound2.log 2>&1 &
UNBOUND_PID2=$!
echo "UNBOUND_PID2=$UNBOUND_PID2" >> .tpkg.var.test
cat .tpkg.var.test
wait_unbound_up unbound.log
wait_unbound_up unbound2.log

72
testdata/ede.tdir/ede.test vendored Normal file
View File

@ -0,0 +1,72 @@
# #-- ede.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
# DNSSEC failure: Signature Expired or DNSKEY Missing (depending on the servfail configuration)
dig @127.0.0.1 -p $UNBOUND_PORT servfail.nl > servfail.txt
# DNSSEC failure: key not incepted
dig @127.0.0.1 -p $UNBOUND_PORT notyetincepted.dnssec-failures.test. TXT +dnssec > sig_notyetincepted.txt
if ! grep -q -e "OPT=15: 00 08" -e "EDE: 8" sig_notyetincepted.txt
then
echo "Signature not yet valid does not return EDE Signature Not Yet Valid"
cat sig_notyetincepted.txt
exit 1
fi
# DNSSEC failure: key expired
dig @127.0.0.1 -p $UNBOUND_PORT expired.dnssec-failures.test. TXT +dnssec > sig_expired.txt
if ! grep -q -e "OPT=15: 00 07" -e "EDE: 7" sig_expired.txt
then
echo "Expired signature does not return EDE Signature expired"
cat sig_expired.txt
exit 1
fi
# DNSSEC failure: missing rrsigs
dig @127.0.0.1 -p $UNBOUND_PORT missingrrsigs.dnssec-failures.test. TXT +dnssec > missingrrsigs.txt
if ! grep -q -e "OPT=15: 00 0a" -e "EDE: 10" missingrrsigs.txt
then
echo "Expired signature does not return EDE RRSIGs missing"
cat missingrrsigs.txt
exit 1
fi
# signed zone with DNSKEY missing
dig @127.0.0.1 -p $UNBOUND_PORT dnskey-failures.test > dnskey-failure.txt
if ! grep -q -e "OPT=15: 00 09" -e "EDE: 9" dnskey-failure.txt
then
echo "Expired signature does not return EDE DNSKEY missing"
cat dnskey-failure.txt
exit 1
fi
# signed zone with RRSIGs missing
dig @127.0.0.1 -p $UNBOUND_PORT rrsig-failures.test > rrsig-failure.txt
if ! grep -q -e "OPT=15: 00 0a" -e "EDE: 10" rrsig-failure.txt
then
echo "Expired signature does not return EDE RRSIGs missing"
cat rrsig-failure.txt
exit 1
fi
# signed zone with NSEC missing
dig @127.0.0.1 -p $UNBOUND_PORT abc.nsec-failures.test > nsec-failure.txt
if ! grep -q -e "OPT=15: 00 0c" -e "EDE: 12" nsec-failure.txt
then
echo "Expired signature does not return EDE NSEC missing"
cat nsec-failure.txt
exit 1
fi
# @TODO DNSSEC indeterminate when implemented

35
testdata/ede_acl_refused.rpl vendored Normal file
View File

@ -0,0 +1,35 @@
; config options
server:
access-control: 127.0.0.0/8 refuse
ede: yes
CONFIG_END
SCENARIO_BEGIN Test ede-acl-refused
; Scenario overview:
; - query for example.com. A record with EDNS
; - check that we get a refused answer with EDE (RFC8914) code 18 - Prohibited
; Query without RD flag
STEP 1 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
example.com. IN A
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
HEX_EDNSDATA_END
ENTRY_END
; Check that we got ede 18
STEP 2 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ede=18
REPLY QR RD REFUSED
SECTION QUESTION
example.com. IN A
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
HEX_EDNSDATA_END
ENTRY_END
SCENARIO_END

33
testdata/ede_cache_snoop_noth_auth.rpl vendored Normal file
View File

@ -0,0 +1,33 @@
; config options
server:
ede: yes
CONFIG_END
SCENARIO_BEGIN Test ede-cache-snoop-not-authoritative
; Scenario overview:
; - query for example.com. A record with EDNS without the RD bit
; - check that we get a refused answer with EDE (RFC8914) code 20 - Not Authoritative
; Query without RD flag
STEP 1 QUERY
ENTRY_BEGIN
SECTION QUESTION
example.com. IN A
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
HEX_EDNSDATA_END
ENTRY_END
; Check that we got ede 20
STEP 10 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ede=20
REPLY QR RA REFUSED
SECTION QUESTION
example.com. IN A
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
HEX_EDNSDATA_END
ENTRY_END
SCENARIO_END

View File

@ -0,0 +1,37 @@
; config options
server:
local-zone: example.com redirect
local-data: "example.com CNAME *.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaa."
ede: yes
CONFIG_END
SCENARIO_BEGIN Test ede-localzone-dname-expansion
; Scenario overview:
; - query for www.qhqwer.qwer.qwer.h.example.com. (a large Qname) A record with EDNS
; - check that we get a YXDOMAIN answer with EDE (RFC8914) code 0 - Other (which adds a DNAME expansion message)
; Query with RD flag
STEP 1 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.qhqwer.qwer.qwer.h.example.com A
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
HEX_EDNSDATA_END
ENTRY_END
; Check that we got the correct answer (should be cached)
STEP 10 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ede=0
REPLY QR AA RD RA YXDOMAIN
SECTION QUESTION
www.qhqwer.qwer.qwer.h.example.com A
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
HEX_EDNSDATA_END
ENTRY_END
SCENARIO_END

View File

@ -47,14 +47,10 @@ STEP 1 QUERY
STEP 10 CHECK_ANSWER
ENTRY_BEGIN
MATCH TCP ednsdata
MATCH TCP
REPLY RD FORMERR
SECTION QUESTION
www.example.com. IN A
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
; Empty
HEX_EDNSDATA_END
ENTRY_END
STEP 20 QUERY

23
testdata/ipset.tdir/ipset.conf vendored Normal file
View File

@ -0,0 +1,23 @@
server:
verbosity: 3
num-threads: 1
module-config: "ipset iterator"
outgoing-range: 16
interface: 127.0.0.1
port: @PORT@
use-syslog: no
directory: ""
pidfile: "unbound.pid"
chroot: ""
username: ""
do-not-query-localhost: no
local-zone: "example.net." ipset
stub-zone:
name: "example.net."
stub-addr: "127.0.0.1@@TOPORT@"
stub-zone:
name: "example.com."
stub-addr: "127.0.0.1@@TOPORT@"
ipset:
name-v4: atotallymadeupnamefor4
name-v6: atotallymadeupnamefor6

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

@ -0,0 +1,16 @@
BaseName: ipset
Version: 1.0
Description: mock test ipset module
CreationDate: Wed Mar 2 13:00:38 CET 2022
Maintainer: George Thessalonikefs
Category:
Component:
CmdDepends:
Depends:
Help:
Pre: ipset.pre
Post: ipset.post
Test: ipset.test
AuxFiles:
Passed:
Failure:

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

@ -0,0 +1,14 @@
# #-- ipset.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
PRE="../.."
if grep "define USE_IPSET 1" $PRE/config.h; then echo test enabled; else echo test skipped; exit 0; fi
kill_pid $FWD_PID
kill_pid $UNBOUND_PID
cat unbound.log
exit 0

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

@ -0,0 +1,33 @@
# #-- ipset.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
. ../common.sh
PRE="../.."
if grep "define USE_IPSET 1" $PRE/config.h; then echo test enabled; else echo test skipped; exit 0; fi
get_random_port 2
UNBOUND_PORT=$RND_PORT
FWD_PORT=$(($RND_PORT + 1))
echo "UNBOUND_PORT=$UNBOUND_PORT" >> .tpkg.var.test
echo "FWD_PORT=$FWD_PORT" >> .tpkg.var.test
# start forwarder
get_ldns_testns
$LDNS_TESTNS -p $FWD_PORT ipset.testns >fwd.log 2>&1 &
FWD_PID=$!
echo "FWD_PID=$FWD_PID" >> .tpkg.var.test
# make config file
sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@TOPORT\@/'$FWD_PORT'/' < ipset.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
cat .tpkg.var.test
wait_ldns_testns_up fwd.log
wait_unbound_up unbound.log

155
testdata/ipset.tdir/ipset.test vendored Normal file
View File

@ -0,0 +1,155 @@
# #-- ipset.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
. ../common.sh
PRE="../.."
if grep "define USE_IPSET 1" $PRE/config.h; then echo test enabled; else echo test skipped; exit 0; fi
# Make all the queries. They need to succeed by the way.
echo "> dig www.example.net."
dig @127.0.0.1 -p $UNBOUND_PORT www.example.net. | tee outfile
echo "> check answer"
if grep "1.1.1.1" outfile; then
echo "OK"
else
echo "> cat logfiles"
cat fwd.log
cat unbound.log
echo "Not OK"
exit 1
fi
echo "> check ipset"
if grep "ipset: add 1.1.1.1 to atotallymadeupnamefor4 for www.example.net." unbound.log; then
echo "ipset OK"
else
echo "> cat logfiles"
cat fwd.log
cat unbound.log
echo "Not OK"
exit 1
fi
echo "> dig www.example.net. AAAA"
dig @127.0.0.1 -p $UNBOUND_PORT www.example.net. AAAA | tee outfile
echo "> check answer"
if grep "::1" outfile; then
echo "OK"
else
echo "> cat logfiles"
cat fwd.log
cat unbound.log
echo "Not OK"
exit 1
fi
echo "> check ipset"
if grep "ipset: add ::1 to atotallymadeupnamefor6 for www.example.net." unbound.log; then
echo "ipset OK"
else
echo "> cat logfiles"
cat fwd.log
cat unbound.log
echo "Not OK"
exit 1
fi
echo "> dig cname.example.net."
dig @127.0.0.1 -p $UNBOUND_PORT cname.example.net. | tee outfile
echo "> check answer"
if grep "2.2.2.2" outfile; then
echo "OK"
else
echo "> cat logfiles"
cat fwd.log
cat unbound.log
echo "Not OK"
exit 1
fi
echo "> check ipset"
if grep "ipset: add 2.2.2.2 to atotallymadeupnamefor4 for target.example.net." unbound.log; then
echo "ipset OK"
else
echo "> cat logfiles"
cat fwd.log
cat unbound.log
echo "Not OK"
exit 1
fi
echo "> dig cname.example.net. AAAA"
dig @127.0.0.1 -p $UNBOUND_PORT cname.example.net. AAAA | tee outfile
echo "> check answer"
if grep "::2" outfile; then
echo "OK"
else
echo "> cat logfiles"
cat fwd.log
cat unbound.log
echo "Not OK"
exit 1
fi
echo "> check ipset"
if grep "ipset: add ::2 to atotallymadeupnamefor6 for target.example.net." unbound.log; then
echo "ipset OK"
else
echo "> cat logfiles"
cat fwd.log
cat unbound.log
echo "Not OK"
exit 1
fi
echo "> dig outsidecname.example.net."
dig @127.0.0.1 -p $UNBOUND_PORT outsidecname.example.net. | tee outfile
echo "> check answer"
if grep "3.3.3.3" outfile; then
echo "OK"
else
echo "> cat logfiles"
cat fwd.log
cat unbound.log
echo "Not OK"
exit 1
fi
echo "> check ipset"
if grep "ipset: add 3.3.3.3 to atotallymadeupnamefor4 for target.example.com." unbound.log; then
echo "ipset OK"
else
echo "> cat logfiles"
cat fwd.log
cat unbound.log
echo "Not OK"
exit 1
fi
echo "> dig outsidecname.example.net. AAAA"
dig @127.0.0.1 -p $UNBOUND_PORT outsidecname.example.net. AAAA | tee outfile
echo "> check answer"
if grep "::3" outfile; then
echo "OK"
else
echo "> cat logfiles"
cat fwd.log
cat unbound.log
echo "Not OK"
exit 1
fi
echo "> check ipset"
if grep "ipset: add ::3 to atotallymadeupnamefor6 for target.example.com." unbound.log; then
echo "ipset OK"
else
echo "> cat logfiles"
cat fwd.log
cat unbound.log
echo "Not OK"
exit 1
fi
echo "> cat logfiles"
cat tap.log
cat tap.errlog
cat fwd.log
echo "> OK"
exit 0

103
testdata/ipset.tdir/ipset.testns vendored Normal file
View File

@ -0,0 +1,103 @@
; nameserver test file
$ORIGIN example.net.
$TTL 3600
ENTRY_BEGIN
MATCH opcode qtype qname
REPLY QR AA NOERROR
ADJUST copy_id
SECTION QUESTION
www IN A
SECTION ANSWER
www IN A 1.1.1.1
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
REPLY QR AA NOERROR
ADJUST copy_id
SECTION QUESTION
www IN AAAA
SECTION ANSWER
www IN AAAA ::1
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
REPLY QR AA NOERROR
ADJUST copy_id
SECTION QUESTION
cname IN A
SECTION ANSWER
cname IN CNAME target.example.net.
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
REPLY QR AA NOERROR
ADJUST copy_id
SECTION QUESTION
cname IN AAAA
SECTION ANSWER
cname IN CNAME target.example.net.
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
REPLY QR AA NOERROR
ADJUST copy_id
SECTION QUESTION
outsidecname IN A
SECTION ANSWER
outsidecname IN CNAME target.example.com.
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
REPLY QR AA NOERROR
ADJUST copy_id
SECTION QUESTION
outsidecname IN AAAA
SECTION ANSWER
outsidecname IN CNAME target.example.com.
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
REPLY QR AA NOERROR
ADJUST copy_id
SECTION QUESTION
target IN A
SECTION ANSWER
target IN A 2.2.2.2
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
REPLY QR AA NOERROR
ADJUST copy_id
SECTION QUESTION
target IN AAAA
SECTION ANSWER
target IN AAAA ::2
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
REPLY QR AA NOERROR
ADJUST copy_id
SECTION QUESTION
target.example.com. IN A
SECTION ANSWER
target.example.com. IN A 3.3.3.3
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
REPLY QR AA NOERROR
ADJUST copy_id
SECTION QUESTION
target.example.com. IN AAAA
SECTION ANSWER
target.example.com. IN AAAA ::3
ENTRY_END

179
testdata/iter_cname_minimise.rpl vendored Normal file
View File

@ -0,0 +1,179 @@
; config options
server:
target-fetch-policy: "0 0 0 0 0"
qname-minimisation: yes
module-config: "iterator"
stub-zone:
name: "."
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
CONFIG_END
SCENARIO_BEGIN Test cname chain resolution with qname minimisation.
; 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 subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
com. IN NS
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 subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
example.com. IN NS
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.44
ENTRY_END
RANGE_END
; ns.example.com.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.44
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.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.44
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ns.example.com. IN A
SECTION ANSWER
ns.example.com. IN A 1.2.3.44
SECTION AUTHORITY
example.com. IN NS ns.example.com.
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ns.example.com. IN AAAA
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
www.example.com. IN A 1.2.3.44
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 300 IN A 10.20.30.40
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com IN A 1.2.3.44
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
c.example.com. IN A
SECTION ANSWER
c.example.com. 10 IN CNAME www.example.com.
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
c.example.com. IN CNAME
SECTION ANSWER
c.example.com. 10 IN CNAME www.example.com.
ENTRY_END
RANGE_END
STEP 1 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
c.example.com. IN CNAME
ENTRY_END
STEP 20 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
c.example.com. IN CNAME
SECTION ANSWER
c.example.com. 10 IN CNAME www.example.com.
ENTRY_END
STEP 30 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
c.example.com. IN A
ENTRY_END
STEP 40 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
c.example.com. IN A
SECTION ANSWER
c.example.com. 10 IN CNAME www.example.com.
www.example.com. 300 IN A 10.20.30.40
ENTRY_END
SCENARIO_END

168
testdata/iter_dp_ip6useless.rpl vendored Normal file
View File

@ -0,0 +1,168 @@
; config options
server:
do-ip6: no
target-fetch-policy: "0 0 0 0 0"
qname-minimisation: no
stub-zone:
name: "."
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
CONFIG_END
SCENARIO_BEGIN Test iterator when doip6 is no and dp is useless with only ip6
; 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 subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
com. IN NS
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 subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
example.com. IN NS
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
; short TTL here, so it can expire
ns.example.com. 1 IN A 1.2.3.4
ns.example.com. 100 IN AAAA ::53
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.
SECTION ADDITIONAL
; short TTL here, so it can expire
ns.example.com. 1 IN A 1.2.3.4
ns.example.com. 100 IN AAAA ::53
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ns.example.com. IN A
SECTION ANSWER
; short TTL
ns.example.com. 1 IN A 1.2.3.4
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
ns.example.com. IN AAAA
SECTION ANSWER
ns.example.com. IN AAAA ::53
ENTRY_END
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
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
mail.example.com. IN A
SECTION ANSWER
mail.example.com. IN A 10.20.30.50
ENTRY_END
RANGE_END
STEP 1 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.example.com. IN A
ENTRY_END
; recursion happens here.
STEP 10 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. IN A 10.20.30.40
ENTRY_END
STEP 20 TIME_PASSES ELAPSE 5.0
STEP 30 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
mail.example.com. IN A
ENTRY_END
STEP 40 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
mail.example.com. IN A
SECTION ANSWER
mail.example.com. IN A 10.20.30.50
ENTRY_END
SCENARIO_END

View File

@ -9,6 +9,7 @@ server:
trust-anchor-signaling: no
minimal-responses: no
nsid: "ascii_hopsa kidee"
ede: yes
stub-zone:
name: "."
@ -157,7 +158,7 @@ ENTRY_END
; recursion happens here.
STEP 10 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
MATCH all ede=9
REPLY QR RD RA DO SERVFAIL
SECTION QUESTION
www.example.com. IN A

View File

@ -4,6 +4,7 @@ server:
val-override-date: "20180423171826"
target-fetch-policy: "0 0 0 0 0"
trust-anchor-signaling: no
ede: yes
stub-zone:
name: "."
@ -138,7 +139,7 @@ ENTRY_END
; recursion happens here.
STEP 22 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
MATCH all ede=6
REPLY QR RD RA DO SERVFAIL
SECTION QUESTION
root-key-sentinel-not-ta-19036. IN A
@ -154,7 +155,7 @@ ENTRY_END
; recursion happens here.
STEP 33 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
MATCH all ede=6
REPLY QR RD RA DO SERVFAIL
SECTION QUESTION
root-key-sentinel-is-ta-20326. IN A

154
testdata/rpz_passthru.rpl vendored Normal file
View File

@ -0,0 +1,154 @@
; 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-log: yes
rpz-log-name: "rpz.example.com"
rpz-action-override: passthru
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.
c.a TXT "local data 1st zone"
d.a A 127.0.0.1
TEMPFILE_END
rpz:
name: "wl.example.com."
rpz-log: yes
rpz-log-name: "wl.example.com"
zonefile:
TEMPFILE_NAME wl.example.com
TEMPFILE_CONTENTS wl.example.com
$ORIGIN example.com.
wl 3600 IN SOA ns1.wl.example.com. hostmaster.wl.example.com. (
1379078166 28800 7200 604800 7200 )
3600 IN NS ns1.wl.example.com.
3600 IN NS ns2.wl.example.com.
$ORIGIN wl.example.com.
e.a CNAME rpz-passthru.
TEMPFILE_END
rpz:
name: "rpz2.example.com."
rpz-log: yes
rpz-log-name: "rpz2.example.com"
rpz-action-override: nxdomain
zonefile:
TEMPFILE_NAME rpz2.example.com
TEMPFILE_CONTENTS rpz2.example.com
$ORIGIN example.com.
rpz2 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 rpz2.example.com.
c.a TXT "local data 2nd zone"
24.0.5.0.192.rpz-client-ip A 127.0.0.1
24.0.5.0.192.rpz-client-ip TXT "clientip 2nd zone"
24.0.3.2.1.rpz-ip A 127.0.0.2
TEMPFILE_END
stub-zone:
name: "a."
stub-addr: 10.20.30.40
CONFIG_END
SCENARIO_BEGIN Test RPZ passthru ends processing for later triggers.
; a.
RANGE_BEGIN 0 1000
ADDRESS 10.20.30.40
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
c.a. IN TXT
SECTION ANSWER
c.a. IN TXT "answer from upstream ns"
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
d.a. IN A
SECTION ANSWER
d.a. IN A 1.2.3.4
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
e.a. IN A
SECTION ANSWER
e.a. IN A 1.2.3.4
ENTRY_END
RANGE_END
STEP 10 QUERY ADDRESS 192.0.5.1
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
c.a. IN TXT
ENTRY_END
STEP 11 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
c.a. IN TXT
SECTION ANSWER
c.a. IN TXT "answer from upstream ns"
ENTRY_END
STEP 20 QUERY ADDRESS 192.0.2.1
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
d.a. IN A
ENTRY_END
STEP 21 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
d.a. IN A
SECTION ANSWER
d.a. IN A 1.2.3.4
ENTRY_END
STEP 30 QUERY ADDRESS 192.0.2.1
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
e.a. IN A
ENTRY_END
STEP 31 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
e.a. IN A
SECTION ANSWER
e.a. IN A 1.2.3.4
ENTRY_END
SCENARIO_END

View File

@ -6,6 +6,8 @@ server:
rpz:
name: "rpz.example.com."
rpz-log: yes
rpz-log-name: "rpz.example.com"
zonefile:
TEMPFILE_NAME rpz.example.com
TEMPFILE_CONTENTS rpz.example.com
@ -20,10 +22,13 @@ a CNAME *. ; duplicate CNAME here on purpose
*.a TXT "wildcard local data"
b.a CNAME *.
c.a CNAME rpz-passthru.
c.g CNAME rpz-passthru.
TEMPFILE_END
rpz:
name: "rpz2.example.com."
rpz-log: yes
rpz-log-name: "rpz2.example.com"
zonefile:
TEMPFILE_NAME rpz2.example.com
TEMPFILE_CONTENTS rpz2.example.com
@ -39,6 +44,7 @@ e CNAME *.a.example.
*.e CNAME *.b.example.
drop CNAME rpz-drop.
tcp CNAME rpz-tcp-only.
c.g CNAME .
TEMPFILE_END
stub-zone:
@ -50,6 +56,9 @@ stub-zone:
stub-zone:
name: "tcp."
stub-addr: 10.20.30.60
stub-zone:
name: "g."
stub-addr: 10.20.30.40
CONFIG_END
SCENARIO_BEGIN Test all support RPZ action for QNAME trigger
@ -89,6 +98,16 @@ SECTION ANSWER
x.b.a. IN TXT "answer from upstream ns"
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
c.g. IN TXT
SECTION ANSWER
c.g. IN TXT "answer from upstream ns"
ENTRY_END
RANGE_END
; example.
@ -396,5 +415,23 @@ f.example. IN CNAME d.
d. IN TXT "local data 2nd zone"
ENTRY_END
; check if passthru ends processing
STEP 110 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
c.g. IN TXT
ENTRY_END
STEP 111 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA NOERROR
SECTION QUESTION
c.g. IN TXT
SECTION ANSWER
c.g. IN TXT "answer from upstream ns"
ENTRY_END
; no answer is checked at exit of testbound.
SCENARIO_END

View File

@ -5,6 +5,8 @@ server:
minimal-responses: no
serve-expired: yes
access-control: 127.0.0.1/32 allow_snoop
ede: yes
ede-serve-expired: yes
stub-zone:
name: "example.com"
@ -78,6 +80,7 @@ STEP 11 TIME_PASSES ELAPSE 3601
; Query again without RD bit
STEP 30 QUERY
ENTRY_BEGIN
REPLY DO
SECTION QUESTION
example.com. IN A
ENTRY_END
@ -85,8 +88,8 @@ ENTRY_END
; Check that we got a stale answer
STEP 40 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RA NOERROR
MATCH all ttl ede=3
REPLY QR RA DO NOERROR
SECTION QUESTION
example.com. IN A
SECTION ANSWER

View File

@ -6,6 +6,8 @@ server:
serve-expired: yes
serve-expired-client-timeout: 1
serve-expired-reply-ttl: 123
ede: yes
ede-serve-expired: yes
stub-zone:
name: "example.com"
@ -83,7 +85,7 @@ STEP 11 TIME_PASSES ELAPSE 3600
; Query again
STEP 30 QUERY
ENTRY_BEGIN
REPLY RD
REPLY RD DO
SECTION QUESTION
example.com. IN A
ENTRY_END
@ -94,8 +96,8 @@ STEP 31 TIME_PASSES ELAPSE 1
; Check that we got a stale answer
STEP 40 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA NOERROR
MATCH all ttl ede=3
REPLY QR RD RA DO NOERROR
SECTION QUESTION
example.com. IN A
SECTION ANSWER

View File

@ -5,6 +5,8 @@ server:
minimal-responses: no
serve-expired: yes
serve-expired-reply-ttl: 123
ede: yes
ede-serve-expired: yes
stub-zone:
name: "example.com"
@ -77,7 +79,7 @@ STEP 11 TIME_PASSES ELAPSE 3601
; Query again
STEP 30 QUERY
ENTRY_BEGIN
REPLY RD
REPLY RD DO
SECTION QUESTION
example.com. IN A
ENTRY_END
@ -85,8 +87,8 @@ ENTRY_END
; Check that we got a stale answer
STEP 40 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA NOERROR
MATCH all ttl ede=3
REPLY QR RD RA DO NOERROR
SECTION QUESTION
example.com. IN A
SECTION ANSWER

View File

@ -7,6 +7,8 @@ server:
serve-expired-client-timeout: 1800
serve-expired-reply-ttl: 123
log-servfail: yes
ede: yes
ede-serve-expired: yes
stub-zone:
@ -94,7 +96,7 @@ STEP 11 TIME_PASSES ELAPSE 3601
; Query again
STEP 30 QUERY
ENTRY_BEGIN
REPLY RD
REPLY RD DO
SECTION QUESTION
example.com. IN A
ENTRY_END
@ -102,8 +104,8 @@ ENTRY_END
; Check that we got a stale answer
STEP 40 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA NOERROR
MATCH all ttl ede=3
REPLY QR RD RA DO NOERROR
SECTION QUESTION
example.com. IN A
SECTION ANSWER

View File

@ -5,6 +5,8 @@ server:
minimal-responses: no
serve-expired: yes
serve-expired-reply-ttl: 123
ede: yes
ede-serve-expired: yes
stub-zone:
name: "example.com"
@ -128,7 +130,7 @@ STEP 30 TIME_PASSES ELAPSE 11
; Query with RD flag
STEP 40 QUERY
ENTRY_BEGIN
REPLY RD
REPLY RD DO
SECTION QUESTION
example.com. IN A
ENTRY_END
@ -136,8 +138,8 @@ ENTRY_END
; Check that we got the correct answer
STEP 49 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA NOERROR
MATCH all ttl ede=3
REPLY QR RD RA DO NOERROR
SECTION QUESTION
example.com. IN A
SECTION ANSWER

View File

@ -9,6 +9,8 @@ server:
cache-min-ttl: 20
serve-expired: yes
serve-expired-reply-ttl: 123
ede: yes
ede-serve-expired: yes
stub-zone:
name: "example.com"
@ -110,7 +112,7 @@ STEP 31 TIME_PASSES ELAPSE 3601
; Query again
STEP 40 QUERY
ENTRY_BEGIN
REPLY
REPLY DO
SECTION QUESTION
example.com. IN A
ENTRY_END
@ -118,8 +120,8 @@ ENTRY_END
; Check that we got a stale answer with the original TTL
STEP 50 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RA NOERROR
MATCH all ttl ede=3
REPLY QR RA DO NOERROR
SECTION QUESTION
example.com. IN A
SECTION ANSWER

Some files were not shown because too many files have changed in this diff Show More