unbound: Vendor import 1.16.0
Merge commit '5f9f82264b91e041df7cba2406625146e7268ce4' into main MFC after: 1 month
This commit is contained in:
commit
a39a5a6905
@ -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 \
|
||||
|
@ -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
contrib/unbound/config.guess
vendored
34
contrib/unbound/config.guess
vendored
@ -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
|
||||
|
@ -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
contrib/unbound/configure
vendored
116
contrib/unbound/configure
vendored
@ -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\\"
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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 "
|
||||
|
@ -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. */
|
||||
@ -742,8 +764,10 @@ 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)
|
||||
uint16_t flags, struct comm_reply* repinfo, time_t leeway, int noreply,
|
||||
int rpz_passthru, struct edns_option* opt_list)
|
||||
{
|
||||
(void)opt_list;
|
||||
/* first send answer to client to keep its latency
|
||||
* as small as a cachereply */
|
||||
if(!noreply) {
|
||||
@ -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);
|
||||
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);
|
||||
|
@ -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.
|
||||
|
@ -1,4 +1,4 @@
|
||||
README for Unbound 1.15.0
|
||||
README for Unbound 1.16.0
|
||||
Copyright 2007 NLnet Labs
|
||||
http://unbound.net
|
||||
|
||||
|
@ -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.
|
||||
#
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
.\"
|
||||
|
@ -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
|
||||
.\"
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
.\"
|
||||
|
@ -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 ]
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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"));
|
||||
|
@ -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,
|
||||
|
5
contrib/unbound/services/cache/dns.c
vendored
5
contrib/unbound/services/cache/dns.c
vendored
@ -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;
|
||||
|
@ -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",
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
@ -741,6 +750,7 @@ static void mesh_schedule_prefetch(struct mesh_area* mesh,
|
||||
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,
|
||||
@ -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);
|
||||
}
|
||||
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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 */
|
||||
|
@ -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];
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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. */
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
contrib/unbound/testdata/auth_zonemd_file_unknown.rpl
vendored
Normal file
184
contrib/unbound/testdata/auth_zonemd_file_unknown.rpl
vendored
Normal 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
|
1
contrib/unbound/testdata/ede.tdir/bogus/clean.sh
vendored
Executable file
1
contrib/unbound/testdata/ede.tdir/bogus/clean.sh
vendored
Executable 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
|
10
contrib/unbound/testdata/ede.tdir/bogus/dnskey-failures.test
vendored
Normal file
10
contrib/unbound/testdata/ede.tdir/bogus/dnskey-failures.test
vendored
Normal 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
|
15
contrib/unbound/testdata/ede.tdir/bogus/dnssec-failures.test
vendored
Normal file
15
contrib/unbound/testdata/ede.tdir/bogus/dnssec-failures.test
vendored
Normal 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
contrib/unbound/testdata/ede.tdir/bogus/make-broken-zone.sh
vendored
Executable file
67
contrib/unbound/testdata/ede.tdir/bogus/make-broken-zone.sh
vendored
Executable 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.*
|
10
contrib/unbound/testdata/ede.tdir/bogus/nsec-failures.test
vendored
Normal file
10
contrib/unbound/testdata/ede.tdir/bogus/nsec-failures.test
vendored
Normal 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
|
10
contrib/unbound/testdata/ede.tdir/bogus/rrsig-failures.test
vendored
Normal file
10
contrib/unbound/testdata/ede.tdir/bogus/rrsig-failures.test
vendored
Normal 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
contrib/unbound/testdata/ede.tdir/ede-auth.conf
vendored
Normal file
27
contrib/unbound/testdata/ede.tdir/ede-auth.conf
vendored
Normal 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
contrib/unbound/testdata/ede.tdir/ede.conf
vendored
Normal file
49
contrib/unbound/testdata/ede.tdir/ede.conf
vendored
Normal 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
contrib/unbound/testdata/ede.tdir/ede.dsc
vendored
Normal file
16
contrib/unbound/testdata/ede.tdir/ede.dsc
vendored
Normal 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
contrib/unbound/testdata/ede.tdir/ede.post
vendored
Normal file
10
contrib/unbound/testdata/ede.tdir/ede.post
vendored
Normal 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
contrib/unbound/testdata/ede.tdir/ede.pre
vendored
Normal file
37
contrib/unbound/testdata/ede.tdir/ede.pre
vendored
Normal 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
contrib/unbound/testdata/ede.tdir/ede.test
vendored
Normal file
72
contrib/unbound/testdata/ede.tdir/ede.test
vendored
Normal 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
contrib/unbound/testdata/ede_acl_refused.rpl
vendored
Normal file
35
contrib/unbound/testdata/ede_acl_refused.rpl
vendored
Normal 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
contrib/unbound/testdata/ede_cache_snoop_noth_auth.rpl
vendored
Normal file
33
contrib/unbound/testdata/ede_cache_snoop_noth_auth.rpl
vendored
Normal 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
|
37
contrib/unbound/testdata/ede_localzone_dname_expansion.rpl
vendored
Normal file
37
contrib/unbound/testdata/ede_localzone_dname_expansion.rpl
vendored
Normal 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
|
23
contrib/unbound/testdata/ipset.tdir/ipset.conf
vendored
Normal file
23
contrib/unbound/testdata/ipset.tdir/ipset.conf
vendored
Normal 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
contrib/unbound/testdata/ipset.tdir/ipset.dsc
vendored
Normal file
16
contrib/unbound/testdata/ipset.tdir/ipset.dsc
vendored
Normal 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
contrib/unbound/testdata/ipset.tdir/ipset.post
vendored
Normal file
14
contrib/unbound/testdata/ipset.tdir/ipset.post
vendored
Normal 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
contrib/unbound/testdata/ipset.tdir/ipset.pre
vendored
Normal file
33
contrib/unbound/testdata/ipset.tdir/ipset.pre
vendored
Normal 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
contrib/unbound/testdata/ipset.tdir/ipset.test
vendored
Normal file
155
contrib/unbound/testdata/ipset.tdir/ipset.test
vendored
Normal 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
contrib/unbound/testdata/ipset.tdir/ipset.testns
vendored
Normal file
103
contrib/unbound/testdata/ipset.tdir/ipset.testns
vendored
Normal 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
contrib/unbound/testdata/iter_cname_minimise.rpl
vendored
Normal file
179
contrib/unbound/testdata/iter_cname_minimise.rpl
vendored
Normal 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
contrib/unbound/testdata/iter_dp_ip6useless.rpl
vendored
Normal file
168
contrib/unbound/testdata/iter_dp_ip6useless.rpl
vendored
Normal 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
|
3
contrib/unbound/testdata/nsid_bogus.rpl
vendored
3
contrib/unbound/testdata/nsid_bogus.rpl
vendored
@ -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
|
||||
|
154
contrib/unbound/testdata/rpz_passthru.rpl
vendored
Normal file
154
contrib/unbound/testdata/rpz_passthru.rpl
vendored
Normal 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
|
215
contrib/unbound/testdata/subnet_prefetch.crpl
vendored
Normal file
215
contrib/unbound/testdata/subnet_prefetch.crpl
vendored
Normal file
@ -0,0 +1,215 @@
|
||||
; Check if the prefetch option works properly for messages stored in the global
|
||||
; cache for non-ECS clients. The prefetch query needs to result in an ECS
|
||||
; outgoing query based on the client's IP.
|
||||
|
||||
server:
|
||||
trust-anchor-signaling: no
|
||||
target-fetch-policy: "0 0 0 0 0"
|
||||
send-client-subnet: 1.2.3.4
|
||||
max-client-subnet-ipv4: 21
|
||||
module-config: "subnetcache iterator"
|
||||
verbosity: 3
|
||||
access-control: 127.0.0.1 allow_snoop
|
||||
qname-minimisation: no
|
||||
minimal-responses: no
|
||||
serve-expired: yes
|
||||
prefetch: yes
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
|
||||
CONFIG_END
|
||||
|
||||
SCENARIO_BEGIN Test prefetch option for global cache
|
||||
|
||||
; K.ROOT-SERVERS.NET.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 193.0.14.129
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname ednsdata
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
. IN NS
|
||||
SECTION ANSWER
|
||||
. IN NS K.ROOT-SERVERS.NET.
|
||||
SECTION ADDITIONAL
|
||||
HEX_EDNSDATA_BEGIN
|
||||
;; we expect to receive empty
|
||||
HEX_EDNSDATA_END
|
||||
K.ROOT-SERVERS.NET. IN A 193.0.14.129
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION AUTHORITY
|
||||
com. IN NS a.gtld-servers.net.
|
||||
SECTION ADDITIONAL
|
||||
a.gtld-servers.net. IN A 192.5.6.30
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; a.gtld-servers.net.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 192.5.6.30
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname ednsdata
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
com. IN NS
|
||||
SECTION ANSWER
|
||||
com. IN NS a.gtld-servers.net.
|
||||
SECTION ADDITIONAL
|
||||
HEX_EDNSDATA_BEGIN
|
||||
;; we expect to receive empty
|
||||
HEX_EDNSDATA_END
|
||||
a.gtld-servers.net. IN A 192.5.6.30
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; ns.example.com.
|
||||
RANGE_BEGIN 0 10
|
||||
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
|
||||
HEX_EDNSDATA_BEGIN
|
||||
;; we expect to receive empty
|
||||
HEX_EDNSDATA_END
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; response to query of interest
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 10 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.4
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; ns.example.com.
|
||||
RANGE_BEGIN 11 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
|
||||
HEX_EDNSDATA_BEGIN
|
||||
;; we expect to receive empty
|
||||
HEX_EDNSDATA_END
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; response to query of interest
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname ednsdata
|
||||
ADJUST copy_id copy_ednsdata_assume_clientsubnet
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. IN A 10.20.30.40
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
HEX_EDNSDATA_BEGIN
|
||||
; client is 127.0.0.1
|
||||
00 08 ; OPC
|
||||
00 07 ; option length
|
||||
00 01 ; Family
|
||||
15 00 ; source mask, scopemask
|
||||
7f 00 00 ; address
|
||||
HEX_EDNSDATA_END
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
STEP 1 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
; This answer should be in the global cache
|
||||
STEP 2 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
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; Try to trigger a prefetch
|
||||
STEP 3 TIME_PASSES ELAPSE 11
|
||||
|
||||
STEP 11 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
; This expired record came from the cache and a prefetch is triggered
|
||||
STEP 12 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 30 IN A 10.20.30.40
|
||||
SECTION AUTHORITY
|
||||
example.com. 3589 IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. 3589 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; Allow upstream to reply to the prefetch query.
|
||||
; It can only be answered if correct ECS was derived from the client's IP.
|
||||
; Otherwise the test will fail with "messages pending".
|
||||
STEP 13 TRAFFIC
|
||||
|
||||
SCENARIO_END
|
221
contrib/unbound/testdata/subnet_prefetch_with_client_ecs.crpl
vendored
Normal file
221
contrib/unbound/testdata/subnet_prefetch_with_client_ecs.crpl
vendored
Normal file
@ -0,0 +1,221 @@
|
||||
; Check if the prefetch option works properly for messages stored in the global
|
||||
; cache for ECS clients. The prefetch query needs to result in an ECS
|
||||
; outgoing query using the client's ECS data.
|
||||
|
||||
server:
|
||||
trust-anchor-signaling: no
|
||||
target-fetch-policy: "0 0 0 0 0"
|
||||
send-client-subnet: 1.2.3.4
|
||||
max-client-subnet-ipv4: 21
|
||||
module-config: "subnetcache iterator"
|
||||
verbosity: 3
|
||||
access-control: 127.0.0.1 allow_snoop
|
||||
qname-minimisation: no
|
||||
minimal-responses: no
|
||||
serve-expired: yes
|
||||
prefetch: yes
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
|
||||
CONFIG_END
|
||||
|
||||
SCENARIO_BEGIN Test prefetch option for global cache
|
||||
|
||||
; K.ROOT-SERVERS.NET.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 193.0.14.129
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname ednsdata
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
. IN NS
|
||||
SECTION ANSWER
|
||||
. IN NS K.ROOT-SERVERS.NET.
|
||||
SECTION ADDITIONAL
|
||||
HEX_EDNSDATA_BEGIN
|
||||
;; we expect to receive empty
|
||||
HEX_EDNSDATA_END
|
||||
K.ROOT-SERVERS.NET. IN A 193.0.14.129
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION AUTHORITY
|
||||
com. IN NS a.gtld-servers.net.
|
||||
SECTION ADDITIONAL
|
||||
a.gtld-servers.net. IN A 192.5.6.30
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; a.gtld-servers.net.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 192.5.6.30
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname ednsdata
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
com. IN NS
|
||||
SECTION ANSWER
|
||||
com. IN NS a.gtld-servers.net.
|
||||
SECTION ADDITIONAL
|
||||
HEX_EDNSDATA_BEGIN
|
||||
;; we expect to receive empty
|
||||
HEX_EDNSDATA_END
|
||||
a.gtld-servers.net. IN A 192.5.6.30
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; ns.example.com.
|
||||
RANGE_BEGIN 0 10
|
||||
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
|
||||
HEX_EDNSDATA_BEGIN
|
||||
;; we expect to receive empty
|
||||
HEX_EDNSDATA_END
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; response to query of interest
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 10 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.4
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; ns.example.com.
|
||||
RANGE_BEGIN 11 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
|
||||
HEX_EDNSDATA_BEGIN
|
||||
;; we expect to receive empty
|
||||
HEX_EDNSDATA_END
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; response to query of interest
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname ednsdata
|
||||
ADJUST copy_id copy_ednsdata_assume_clientsubnet
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. IN A 10.20.30.40
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
HEX_EDNSDATA_BEGIN
|
||||
; client is 127.0.0.1
|
||||
00 08 ; OPC
|
||||
00 05 ; option length
|
||||
00 01 ; Family
|
||||
08 00 ; source mask, scopemask
|
||||
7f ; address
|
||||
HEX_EDNSDATA_END
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
STEP 1 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
; This answer should be in the global cache
|
||||
STEP 2 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
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; Try to trigger a prefetch
|
||||
STEP 3 TIME_PASSES ELAPSE 11
|
||||
|
||||
STEP 11 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ADDITIONAL
|
||||
HEX_EDNSDATA_BEGIN
|
||||
00 08 00 05 ; OPC, optlen
|
||||
00 01 08 00 ; ip4, source 8, scope 0
|
||||
7f ; 127.0.0.0/8
|
||||
HEX_EDNSDATA_END
|
||||
ENTRY_END
|
||||
|
||||
; This expired record came from the cache and a prefetch is triggered
|
||||
STEP 12 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA DO NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 30 IN A 10.20.30.40
|
||||
SECTION AUTHORITY
|
||||
example.com. 3589 IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. 3589 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; Allow upstream to reply to the prefetch query.
|
||||
; It can only be answered if correct ECS was derived from the client's IP.
|
||||
; Otherwise the test will fail with "messages pending".
|
||||
STEP 13 TRAFFIC
|
||||
|
||||
SCENARIO_END
|
@ -195,6 +195,7 @@ config_create(void)
|
||||
cfg->use_systemd = 0;
|
||||
cfg->do_daemonize = 1;
|
||||
cfg->if_automatic = 0;
|
||||
cfg->if_automatic_ports = NULL;
|
||||
cfg->so_rcvbuf = 0;
|
||||
cfg->so_sndbuf = 0;
|
||||
cfg->so_reuseport = REUSEPORT_DEFAULT;
|
||||
@ -267,6 +268,7 @@ config_create(void)
|
||||
cfg->serve_expired_ttl_reset = 0;
|
||||
cfg->serve_expired_reply_ttl = 30;
|
||||
cfg->serve_expired_client_timeout = 0;
|
||||
cfg->ede_serve_expired = 0;
|
||||
cfg->serve_original_ttl = 0;
|
||||
cfg->zonemd_permissive_mode = 0;
|
||||
cfg->add_holddown = 30*24*3600;
|
||||
@ -375,6 +377,7 @@ config_create(void)
|
||||
cfg->ipset_name_v4 = NULL;
|
||||
cfg->ipset_name_v6 = NULL;
|
||||
#endif
|
||||
cfg->ede = 0;
|
||||
return cfg;
|
||||
error_exit:
|
||||
config_delete(cfg);
|
||||
@ -476,7 +479,7 @@ int config_set_option(struct config_file* cfg, const char* opt,
|
||||
else if(atoi(val) == 0)
|
||||
return 0;
|
||||
else cfg->stat_interval = atoi(val);
|
||||
} else if(strcmp(opt, "num_threads:") == 0) {
|
||||
} else if(strcmp(opt, "num-threads:") == 0) {
|
||||
/* not supported, library must have 1 thread in bgworker */
|
||||
return 0;
|
||||
} else if(strcmp(opt, "outgoing-port-permit:") == 0) {
|
||||
@ -543,6 +546,7 @@ int config_set_option(struct config_file* cfg, const char* opt,
|
||||
else S_STR("ssl-cert-bundle:", tls_cert_bundle)
|
||||
else S_STR("tls-cert-bundle:", tls_cert_bundle)
|
||||
else S_YNO("tls-win-cert:", tls_win_cert)
|
||||
else S_YNO("tls-system-cert:", tls_win_cert)
|
||||
else S_STRLIST("additional-ssl-port:", tls_additional_port)
|
||||
else S_STRLIST("additional-tls-port:", tls_additional_port)
|
||||
else S_STRLIST("tls-additional-ports:", tls_additional_port)
|
||||
@ -559,6 +563,7 @@ int config_set_option(struct config_file* cfg, const char* opt,
|
||||
else S_YNO("http-nodelay:", http_nodelay)
|
||||
else S_YNO("http-notls-downstream:", http_notls_downstream)
|
||||
else S_YNO("interface-automatic:", if_automatic)
|
||||
else S_STR("interface-automatic-ports:", if_automatic_ports)
|
||||
else S_YNO("use-systemd:", use_systemd)
|
||||
else S_YNO("do-daemonize:", do_daemonize)
|
||||
else S_NUMBER_NONZERO("port:", port)
|
||||
@ -668,6 +673,8 @@ int config_set_option(struct config_file* cfg, const char* opt,
|
||||
else if(strcmp(opt, "serve-expired-reply-ttl:") == 0)
|
||||
{ IS_NUMBER_OR_ZERO; cfg->serve_expired_reply_ttl = atoi(val); SERVE_EXPIRED_REPLY_TTL=(time_t)cfg->serve_expired_reply_ttl;}
|
||||
else S_NUMBER_OR_ZERO("serve-expired-client-timeout:", serve_expired_client_timeout)
|
||||
else S_YNO("ede:", ede)
|
||||
else S_YNO("ede-serve-expired:", ede_serve_expired)
|
||||
else S_YNO("serve-original-ttl:", serve_original_ttl)
|
||||
else S_STR("val-nsec3-keysize-iterations:", val_nsec3_key_iterations)
|
||||
else S_YNO("zonemd-permissive-mode:", zonemd_permissive_mode)
|
||||
@ -990,6 +997,7 @@ config_get_option(struct config_file* cfg, const char* opt,
|
||||
else O_IFC(opt, "interface", num_ifs, ifs)
|
||||
else O_IFC(opt, "outgoing-interface", num_out_ifs, out_ifs)
|
||||
else O_YNO(opt, "interface-automatic", if_automatic)
|
||||
else O_STR(opt, "interface-automatic-ports", if_automatic_ports)
|
||||
else O_DEC(opt, "port", port)
|
||||
else O_DEC(opt, "outgoing-range", outgoing_num_ports)
|
||||
else O_DEC(opt, "outgoing-num-tcp", outgoing_num_tcp)
|
||||
@ -1049,6 +1057,7 @@ config_get_option(struct config_file* cfg, const char* opt,
|
||||
else O_STR(opt, "ssl-cert-bundle", tls_cert_bundle)
|
||||
else O_STR(opt, "tls-cert-bundle", tls_cert_bundle)
|
||||
else O_YNO(opt, "tls-win-cert", tls_win_cert)
|
||||
else O_YNO(opt, "tls-system-cert", tls_win_cert)
|
||||
else O_LST(opt, "additional-ssl-port", tls_additional_port)
|
||||
else O_LST(opt, "additional-tls-port", tls_additional_port)
|
||||
else O_LST(opt, "tls-additional-ports", tls_additional_port)
|
||||
@ -1108,6 +1117,8 @@ config_get_option(struct config_file* cfg, const char* opt,
|
||||
else O_YNO(opt, "serve-expired-ttl-reset", serve_expired_ttl_reset)
|
||||
else O_DEC(opt, "serve-expired-reply-ttl", serve_expired_reply_ttl)
|
||||
else O_DEC(opt, "serve-expired-client-timeout", serve_expired_client_timeout)
|
||||
else O_YNO(opt, "ede", ede)
|
||||
else O_YNO(opt, "ede-serve-expired", ede_serve_expired)
|
||||
else O_YNO(opt, "serve-original-ttl", serve_original_ttl)
|
||||
else O_STR(opt, "val-nsec3-keysize-iterations",val_nsec3_key_iterations)
|
||||
else O_YNO(opt, "zonemd-permissive-mode", zonemd_permissive_mode)
|
||||
@ -1534,6 +1545,7 @@ config_delete(struct config_file* cfg)
|
||||
free(cfg->directory);
|
||||
free(cfg->logfile);
|
||||
free(cfg->pidfile);
|
||||
free(cfg->if_automatic_ports);
|
||||
free(cfg->target_fetch_policy);
|
||||
free(cfg->ssl_service_key);
|
||||
free(cfg->ssl_service_pem);
|
||||
@ -2553,126 +2565,6 @@ void w_config_adjust_directory(struct config_file* cfg)
|
||||
}
|
||||
#endif /* UB_ON_WINDOWS */
|
||||
|
||||
void errinf(struct module_qstate* qstate, const char* str)
|
||||
{
|
||||
struct config_strlist* p;
|
||||
if((qstate->env->cfg->val_log_level < 2 && !qstate->env->cfg->log_servfail) || !str)
|
||||
return;
|
||||
p = (struct config_strlist*)regional_alloc(qstate->region, sizeof(*p));
|
||||
if(!p) {
|
||||
log_err("malloc failure in validator-error-info string");
|
||||
return;
|
||||
}
|
||||
p->next = NULL;
|
||||
p->str = regional_strdup(qstate->region, str);
|
||||
if(!p->str) {
|
||||
log_err("malloc failure in validator-error-info string");
|
||||
return;
|
||||
}
|
||||
/* add at end */
|
||||
if(qstate->errinf) {
|
||||
struct config_strlist* q = qstate->errinf;
|
||||
while(q->next)
|
||||
q = q->next;
|
||||
q->next = p;
|
||||
} else qstate->errinf = p;
|
||||
}
|
||||
|
||||
void errinf_origin(struct module_qstate* qstate, struct sock_list *origin)
|
||||
{
|
||||
struct sock_list* p;
|
||||
if(qstate->env->cfg->val_log_level < 2 && !qstate->env->cfg->log_servfail)
|
||||
return;
|
||||
for(p=origin; p; p=p->next) {
|
||||
char buf[256];
|
||||
if(p == origin)
|
||||
snprintf(buf, sizeof(buf), "from ");
|
||||
else snprintf(buf, sizeof(buf), "and ");
|
||||
if(p->len == 0)
|
||||
snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf),
|
||||
"cache");
|
||||
else
|
||||
addr_to_str(&p->addr, p->len, buf+strlen(buf),
|
||||
sizeof(buf)-strlen(buf));
|
||||
errinf(qstate, buf);
|
||||
}
|
||||
}
|
||||
|
||||
char* errinf_to_str_bogus(struct module_qstate* qstate)
|
||||
{
|
||||
char buf[20480];
|
||||
char* p = buf;
|
||||
size_t left = sizeof(buf);
|
||||
struct config_strlist* s;
|
||||
char dname[LDNS_MAX_DOMAINLEN+1];
|
||||
char t[16], c[16];
|
||||
sldns_wire2str_type_buf(qstate->qinfo.qtype, t, sizeof(t));
|
||||
sldns_wire2str_class_buf(qstate->qinfo.qclass, c, sizeof(c));
|
||||
dname_str(qstate->qinfo.qname, dname);
|
||||
snprintf(p, left, "validation failure <%s %s %s>:", dname, t, c);
|
||||
left -= strlen(p); p += strlen(p);
|
||||
if(!qstate->errinf)
|
||||
snprintf(p, left, " misc failure");
|
||||
else for(s=qstate->errinf; s; s=s->next) {
|
||||
snprintf(p, left, " %s", s->str);
|
||||
left -= strlen(p); p += strlen(p);
|
||||
}
|
||||
p = strdup(buf);
|
||||
if(!p)
|
||||
log_err("malloc failure in errinf_to_str");
|
||||
return p;
|
||||
}
|
||||
|
||||
char* errinf_to_str_servfail(struct module_qstate* qstate)
|
||||
{
|
||||
char buf[20480];
|
||||
char* p = buf;
|
||||
size_t left = sizeof(buf);
|
||||
struct config_strlist* s;
|
||||
char dname[LDNS_MAX_DOMAINLEN+1];
|
||||
char t[16], c[16];
|
||||
sldns_wire2str_type_buf(qstate->qinfo.qtype, t, sizeof(t));
|
||||
sldns_wire2str_class_buf(qstate->qinfo.qclass, c, sizeof(c));
|
||||
dname_str(qstate->qinfo.qname, dname);
|
||||
snprintf(p, left, "SERVFAIL <%s %s %s>:", dname, t, c);
|
||||
left -= strlen(p); p += strlen(p);
|
||||
if(!qstate->errinf)
|
||||
snprintf(p, left, " misc failure");
|
||||
else for(s=qstate->errinf; s; s=s->next) {
|
||||
snprintf(p, left, " %s", s->str);
|
||||
left -= strlen(p); p += strlen(p);
|
||||
}
|
||||
p = strdup(buf);
|
||||
if(!p)
|
||||
log_err("malloc failure in errinf_to_str");
|
||||
return p;
|
||||
}
|
||||
|
||||
void errinf_rrset(struct module_qstate* qstate, struct ub_packed_rrset_key *rr)
|
||||
{
|
||||
char buf[1024];
|
||||
char dname[LDNS_MAX_DOMAINLEN+1];
|
||||
char t[16], c[16];
|
||||
if((qstate->env->cfg->val_log_level < 2 && !qstate->env->cfg->log_servfail) || !rr)
|
||||
return;
|
||||
sldns_wire2str_type_buf(ntohs(rr->rk.type), t, sizeof(t));
|
||||
sldns_wire2str_class_buf(ntohs(rr->rk.rrset_class), c, sizeof(c));
|
||||
dname_str(rr->rk.dname, dname);
|
||||
snprintf(buf, sizeof(buf), "for <%s %s %s>", dname, t, c);
|
||||
errinf(qstate, buf);
|
||||
}
|
||||
|
||||
void errinf_dname(struct module_qstate* qstate, const char* str, uint8_t* dname)
|
||||
{
|
||||
char b[1024];
|
||||
char buf[LDNS_MAX_DOMAINLEN+1];
|
||||
if((qstate->env->cfg->val_log_level < 2 && !qstate->env->cfg->log_servfail) || !str || !dname)
|
||||
return;
|
||||
dname_str(dname, buf);
|
||||
snprintf(b, sizeof(b), "%s %s", str, buf);
|
||||
errinf(qstate, b);
|
||||
}
|
||||
|
||||
int options_remote_is_address(struct config_file* cfg)
|
||||
{
|
||||
if(!cfg->remote_control_enable) return 0;
|
||||
|
@ -41,6 +41,7 @@
|
||||
|
||||
#ifndef UTIL_CONFIG_FILE_H
|
||||
#define UTIL_CONFIG_FILE_H
|
||||
#include "sldns/rrdef.h"
|
||||
struct config_stub;
|
||||
struct config_auth;
|
||||
struct config_view;
|
||||
@ -205,6 +206,8 @@ struct config_file {
|
||||
/** automatic interface for incoming messages. Uses ipv6 remapping,
|
||||
* and recvmsg/sendmsg ancillary data to detect interfaces, boolean */
|
||||
int if_automatic;
|
||||
/** extra ports to open if if_automatic enabled, or NULL for default */
|
||||
char* if_automatic_ports;
|
||||
/** SO_RCVBUF size to set on port 53 UDP socket */
|
||||
size_t so_rcvbuf;
|
||||
/** SO_SNDBUF size to set on port 53 UDP socket */
|
||||
@ -404,6 +407,8 @@ struct config_file {
|
||||
/** serve expired entries only after trying to update the entries and this
|
||||
* timeout (in milliseconds) is reached */
|
||||
int serve_expired_client_timeout;
|
||||
/** serve EDE code 3 - Stale Answer (RFC8914) for expired entries */
|
||||
int ede_serve_expired;
|
||||
/** serve original TTLs rather than decrementing ones */
|
||||
int serve_original_ttl;
|
||||
/** nsec3 maximum iterations per key size, string */
|
||||
@ -677,6 +682,8 @@ struct config_file {
|
||||
char* ipset_name_v4;
|
||||
char* ipset_name_v6;
|
||||
#endif
|
||||
/** respond with Extended DNS Errors (RFC8914) */
|
||||
int ede;
|
||||
};
|
||||
|
||||
/** from cfg username, after daemonize setup performed */
|
||||
@ -1239,56 +1246,6 @@ char* fname_after_chroot(const char* fname, struct config_file* cfg,
|
||||
*/
|
||||
char* cfg_ptr_reverse(char* str);
|
||||
|
||||
/**
|
||||
* Append text to the error info for validation.
|
||||
* @param qstate: query state.
|
||||
* @param str: copied into query region and appended.
|
||||
* Failures to allocate are logged.
|
||||
*/
|
||||
void errinf(struct module_qstate* qstate, const char* str);
|
||||
|
||||
/**
|
||||
* Append text to error info: from 1.2.3.4
|
||||
* @param qstate: query state.
|
||||
* @param origin: sock list with origin of trouble.
|
||||
* Every element added.
|
||||
* If NULL: nothing is added.
|
||||
* if 0len element: 'from cache' is added.
|
||||
*/
|
||||
void errinf_origin(struct module_qstate* qstate, struct sock_list *origin);
|
||||
|
||||
/**
|
||||
* Append text to error info: for RRset name type class
|
||||
* @param qstate: query state.
|
||||
* @param rr: rrset_key.
|
||||
*/
|
||||
void errinf_rrset(struct module_qstate* qstate, struct ub_packed_rrset_key *rr);
|
||||
|
||||
/**
|
||||
* Append text to error info: str dname
|
||||
* @param qstate: query state.
|
||||
* @param str: explanation string
|
||||
* @param dname: the dname.
|
||||
*/
|
||||
void errinf_dname(struct module_qstate* qstate, const char* str,
|
||||
uint8_t* dname);
|
||||
|
||||
/**
|
||||
* Create error info in string. For validation failures.
|
||||
* @param qstate: query state.
|
||||
* @return string or NULL on malloc failure (already logged).
|
||||
* This string is malloced and has to be freed by caller.
|
||||
*/
|
||||
char* errinf_to_str_bogus(struct module_qstate* qstate);
|
||||
|
||||
/**
|
||||
* Create error info in string. For other servfails.
|
||||
* @param qstate: query state.
|
||||
* @return string or NULL on malloc failure (already logged).
|
||||
* This string is malloced and has to be freed by caller.
|
||||
*/
|
||||
char* errinf_to_str_servfail(struct module_qstate* qstate);
|
||||
|
||||
/**
|
||||
* Used during options parsing
|
||||
*/
|
||||
|
@ -252,6 +252,7 @@ tls-port{COLON} { YDVAR(1, VAR_SSL_PORT) }
|
||||
ssl-cert-bundle{COLON} { YDVAR(1, VAR_TLS_CERT_BUNDLE) }
|
||||
tls-cert-bundle{COLON} { YDVAR(1, VAR_TLS_CERT_BUNDLE) }
|
||||
tls-win-cert{COLON} { YDVAR(1, VAR_TLS_WIN_CERT) }
|
||||
tls-system-cert{COLON} { YDVAR(1, VAR_TLS_WIN_CERT) }
|
||||
additional-ssl-port{COLON} { YDVAR(1, VAR_TLS_ADDITIONAL_PORT) }
|
||||
additional-tls-port{COLON} { YDVAR(1, VAR_TLS_ADDITIONAL_PORT) }
|
||||
tls-additional-ports{COLON} { YDVAR(1, VAR_TLS_ADDITIONAL_PORT) }
|
||||
@ -273,6 +274,7 @@ interface{COLON} { YDVAR(1, VAR_INTERFACE) }
|
||||
ip-address{COLON} { YDVAR(1, VAR_INTERFACE) }
|
||||
outgoing-interface{COLON} { YDVAR(1, VAR_OUTGOING_INTERFACE) }
|
||||
interface-automatic{COLON} { YDVAR(1, VAR_INTERFACE_AUTOMATIC) }
|
||||
interface-automatic-ports{COLON} { YDVAR(1, VAR_INTERFACE_AUTOMATIC_PORTS) }
|
||||
so-rcvbuf{COLON} { YDVAR(1, VAR_SO_RCVBUF) }
|
||||
so-sndbuf{COLON} { YDVAR(1, VAR_SO_SNDBUF) }
|
||||
so-reuseport{COLON} { YDVAR(1, VAR_SO_REUSEPORT) }
|
||||
@ -402,6 +404,7 @@ serve-expired-ttl{COLON} { YDVAR(1, VAR_SERVE_EXPIRED_TTL) }
|
||||
serve-expired-ttl-reset{COLON} { YDVAR(1, VAR_SERVE_EXPIRED_TTL_RESET) }
|
||||
serve-expired-reply-ttl{COLON} { YDVAR(1, VAR_SERVE_EXPIRED_REPLY_TTL) }
|
||||
serve-expired-client-timeout{COLON} { YDVAR(1, VAR_SERVE_EXPIRED_CLIENT_TIMEOUT) }
|
||||
ede-serve-expired{COLON} { YDVAR(1, VAR_EDE_SERVE_EXPIRED) }
|
||||
serve-original-ttl{COLON} { YDVAR(1, VAR_SERVE_ORIGINAL_TTL) }
|
||||
fake-dsa{COLON} { YDVAR(1, VAR_FAKE_DSA) }
|
||||
fake-sha1{COLON} { YDVAR(1, VAR_FAKE_SHA1) }
|
||||
@ -553,6 +556,7 @@ tcp-connection-limit{COLON} { YDVAR(2, VAR_TCP_CONNECTION_LIMIT) }
|
||||
edns-client-string{COLON} { YDVAR(2, VAR_EDNS_CLIENT_STRING) }
|
||||
edns-client-string-opcode{COLON} { YDVAR(1, VAR_EDNS_CLIENT_STRING_OPCODE) }
|
||||
nsid{COLON} { YDVAR(1, VAR_NSID ) }
|
||||
ede{COLON} { YDVAR(1, VAR_EDE ) }
|
||||
<INITIAL,val>{NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++; }
|
||||
|
||||
/* Quoted strings. Strip leading and ending quotes */
|
||||
|
@ -155,7 +155,8 @@ extern struct config_parser_state* cfg_parser;
|
||||
%token VAR_ACCESS_CONTROL_TAG_DATA VAR_VIEW VAR_ACCESS_CONTROL_VIEW
|
||||
%token VAR_VIEW_FIRST VAR_SERVE_EXPIRED VAR_SERVE_EXPIRED_TTL
|
||||
%token VAR_SERVE_EXPIRED_TTL_RESET VAR_SERVE_EXPIRED_REPLY_TTL
|
||||
%token VAR_SERVE_EXPIRED_CLIENT_TIMEOUT VAR_SERVE_ORIGINAL_TTL VAR_FAKE_DSA
|
||||
%token VAR_SERVE_EXPIRED_CLIENT_TIMEOUT VAR_EDE_SERVE_EXPIRED
|
||||
%token VAR_SERVE_ORIGINAL_TTL VAR_FAKE_DSA
|
||||
%token VAR_FAKE_SHA1 VAR_LOG_IDENTITY VAR_HIDE_TRUSTANCHOR
|
||||
%token VAR_HIDE_HTTP_USER_AGENT VAR_HTTP_USER_AGENT
|
||||
%token VAR_TRUST_ANCHOR_SIGNALING VAR_AGGRESSIVE_NSEC VAR_USE_SYSTEMD
|
||||
@ -188,7 +189,7 @@ extern struct config_parser_state* cfg_parser;
|
||||
%token VAR_DYNLIB VAR_DYNLIB_FILE VAR_EDNS_CLIENT_STRING
|
||||
%token VAR_EDNS_CLIENT_STRING_OPCODE VAR_NSID
|
||||
%token VAR_ZONEMD_PERMISSIVE_MODE VAR_ZONEMD_CHECK VAR_ZONEMD_REJECT_ABSENCE
|
||||
%token VAR_RPZ_SIGNAL_NXDOMAIN_RA
|
||||
%token VAR_RPZ_SIGNAL_NXDOMAIN_RA VAR_INTERFACE_AUTOMATIC_PORTS VAR_EDE
|
||||
|
||||
%%
|
||||
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
|
||||
@ -292,7 +293,7 @@ content_server: server_num_threads | server_verbosity | server_port |
|
||||
server_serve_expired |
|
||||
server_serve_expired_ttl | server_serve_expired_ttl_reset |
|
||||
server_serve_expired_reply_ttl | server_serve_expired_client_timeout |
|
||||
server_serve_original_ttl | server_fake_dsa |
|
||||
server_ede_serve_expired | server_serve_original_ttl | server_fake_dsa |
|
||||
server_log_identity | server_use_systemd |
|
||||
server_response_ip_tag | server_response_ip | server_response_ip_data |
|
||||
server_shm_enable | server_shm_key | server_fake_sha1 |
|
||||
@ -311,7 +312,8 @@ content_server: server_num_threads | server_verbosity | server_port |
|
||||
server_tls_use_sni | server_edns_client_string |
|
||||
server_edns_client_string_opcode | server_nsid |
|
||||
server_zonemd_permissive_mode | server_max_reuse_tcp_queries |
|
||||
server_tcp_reuse_timeout | server_tcp_auth_query_timeout
|
||||
server_tcp_reuse_timeout | server_tcp_auth_query_timeout |
|
||||
server_interface_automatic_ports | server_ede
|
||||
|
||||
;
|
||||
stubstart: VAR_STUB_ZONE
|
||||
@ -800,6 +802,13 @@ server_interface_automatic: VAR_INTERFACE_AUTOMATIC STRING_ARG
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
server_interface_automatic_ports: VAR_INTERFACE_AUTOMATIC_PORTS STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_interface_automatic_ports:%s)\n", $2));
|
||||
free(cfg_parser->cfg->if_automatic_ports);
|
||||
cfg_parser->cfg->if_automatic_ports = $2;
|
||||
}
|
||||
;
|
||||
server_do_ip4: VAR_DO_IP4 STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_do_ip4:%s)\n", $2));
|
||||
@ -2026,6 +2035,15 @@ server_serve_expired_client_timeout: VAR_SERVE_EXPIRED_CLIENT_TIMEOUT STRING_ARG
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
server_ede_serve_expired: VAR_EDE_SERVE_EXPIRED STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_ede_serve_expired:%s)\n", $2));
|
||||
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
|
||||
yyerror("expected yes or no.");
|
||||
else cfg_parser->cfg->ede_serve_expired = (strcmp($2, "yes")==0);
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
server_serve_original_ttl: VAR_SERVE_ORIGINAL_TTL STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_serve_original_ttl:%s)\n", $2));
|
||||
@ -2167,7 +2185,7 @@ server_local_zone: VAR_LOCAL_ZONE STRING_ARG STRING_ARG
|
||||
&& strcmp($3, "noview")!=0
|
||||
&& strcmp($3, "inform")!=0 && strcmp($3, "inform_deny")!=0
|
||||
&& strcmp($3, "inform_redirect") != 0
|
||||
&& strcmp($3, "ipset") != 0) {
|
||||
&& strcmp($3, "ipset") != 0) {
|
||||
yyerror("local-zone type: expected static, deny, "
|
||||
"refuse, redirect, transparent, "
|
||||
"typetransparent, inform, inform_deny, "
|
||||
@ -2184,6 +2202,16 @@ server_local_zone: VAR_LOCAL_ZONE STRING_ARG STRING_ARG
|
||||
free($3);
|
||||
#ifdef USE_IPSET
|
||||
} else if(strcmp($3, "ipset")==0) {
|
||||
size_t len = strlen($2);
|
||||
/* Make sure to add the trailing dot.
|
||||
* These are str compared to domain names. */
|
||||
if($2[len-1] != '.') {
|
||||
if(!($2 = realloc($2, len+2))) {
|
||||
fatal_exit("out of memory adding local-zone");
|
||||
}
|
||||
$2[len] = '.';
|
||||
$2[len+1] = 0;
|
||||
}
|
||||
if(!cfg_strlist_insert(&cfg_parser->cfg->
|
||||
local_zones_ipset, $2))
|
||||
fatal_exit("out of memory adding local-zone");
|
||||
@ -2713,7 +2741,15 @@ server_edns_client_string_opcode: VAR_EDNS_CLIENT_STRING_OPCODE STRING_ARG
|
||||
yyerror("option code must be in interval [0, 65535]");
|
||||
else cfg_parser->cfg->edns_client_string_opcode = atoi($2);
|
||||
free($2);
|
||||
|
||||
}
|
||||
;
|
||||
server_ede: VAR_EDE STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_ede:%s)\n", $2));
|
||||
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
|
||||
yyerror("expected yes or no.");
|
||||
else cfg_parser->cfg->ede = (strcmp($2, "yes")==0);
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
stub_name: VAR_NAME STRING_ARG
|
||||
@ -2982,6 +3018,16 @@ view_local_zone: VAR_LOCAL_ZONE STRING_ARG STRING_ARG
|
||||
free($3);
|
||||
#ifdef USE_IPSET
|
||||
} else if(strcmp($3, "ipset")==0) {
|
||||
size_t len = strlen($2);
|
||||
/* Make sure to add the trailing dot.
|
||||
* These are str compared to domain names. */
|
||||
if($2[len-1] != '.') {
|
||||
if(!($2 = realloc($2, len+2))) {
|
||||
fatal_exit("out of memory adding local-zone");
|
||||
}
|
||||
$2[len] = '.';
|
||||
$2[len+1] = 0;
|
||||
}
|
||||
if(!cfg_strlist_insert(&cfg_parser->cfg->views->
|
||||
local_zones_ipset, $2))
|
||||
fatal_exit("out of memory adding local-zone");
|
||||
|
@ -1157,7 +1157,7 @@ skip_pkt_rr(sldns_buffer* pkt)
|
||||
}
|
||||
|
||||
/** skip RRs from packet */
|
||||
static int
|
||||
int
|
||||
skip_pkt_rrs(sldns_buffer* pkt, int num)
|
||||
{
|
||||
int i;
|
||||
@ -1235,3 +1235,4 @@ log_edns_opt_list(enum verbosity_value level, const char* info_str,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -293,6 +293,15 @@ int parse_packet(struct sldns_buffer* pkt, struct msg_parse* msg,
|
||||
int parse_extract_edns_from_response_msg(struct msg_parse* msg,
|
||||
struct edns_data* edns, struct regional* region);
|
||||
|
||||
/**
|
||||
* Skip RRs from packet
|
||||
* @param pkt: the packet. position at start must be right after the query
|
||||
* section. At end, right after EDNS data or no movement if failed.
|
||||
* @param num: Limit of the number of records we want to parse.
|
||||
* @return: 0 on success, 1 on failure.
|
||||
*/
|
||||
int skip_pkt_rrs(struct sldns_buffer* pkt, int num);
|
||||
|
||||
/**
|
||||
* If EDNS data follows a query section, extract it and initialize edns struct.
|
||||
* @param pkt: the packet. position at start must be right after the query
|
||||
|
@ -117,6 +117,7 @@ construct_reply_info_base(struct regional* region, uint16_t flags, size_t qd,
|
||||
rep->ar_numrrsets = ar;
|
||||
rep->rrset_count = total;
|
||||
rep->security = sec;
|
||||
rep->reason_bogus = LDNS_EDE_NONE;
|
||||
rep->authoritative = 0;
|
||||
/* array starts after the refs */
|
||||
if(region)
|
||||
@ -989,6 +990,36 @@ parse_reply_in_temp_region(sldns_buffer* pkt, struct regional* region,
|
||||
return rep;
|
||||
}
|
||||
|
||||
int edns_opt_list_append_ede(struct edns_option** list, struct regional* region,
|
||||
sldns_ede_code code, const char *txt)
|
||||
{
|
||||
struct edns_option** prevp;
|
||||
struct edns_option* opt;
|
||||
size_t txt_len = txt ? strlen(txt) : 0;
|
||||
|
||||
/* allocate new element */
|
||||
opt = (struct edns_option*)regional_alloc(region, sizeof(*opt));
|
||||
if(!opt)
|
||||
return 0;
|
||||
opt->next = NULL;
|
||||
opt->opt_code = LDNS_EDNS_EDE;
|
||||
opt->opt_len = txt_len + sizeof(uint16_t);
|
||||
opt->opt_data = regional_alloc(region, txt_len + sizeof(uint16_t));
|
||||
if(!opt->opt_data)
|
||||
return 0;
|
||||
sldns_write_uint16(opt->opt_data, (uint16_t)code);
|
||||
if (txt_len)
|
||||
memmove(opt->opt_data + 2, txt, txt_len);
|
||||
|
||||
/* append at end of list */
|
||||
prevp = list;
|
||||
while(*prevp != NULL)
|
||||
prevp = &((*prevp)->next);
|
||||
verbose(VERB_ALGO, "attached EDE code: %d with message: %s", code, txt);
|
||||
*prevp = opt;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int edns_opt_list_append(struct edns_option** list, uint16_t code, size_t len,
|
||||
uint8_t* data, struct regional* region)
|
||||
{
|
||||
|
@ -43,6 +43,7 @@
|
||||
#define UTIL_DATA_MSGREPLY_H
|
||||
#include "util/storage/lruhash.h"
|
||||
#include "util/data/packed_rrset.h"
|
||||
#include "sldns/rrdef.h"
|
||||
struct sldns_buffer;
|
||||
struct comm_reply;
|
||||
struct alloc_cache;
|
||||
@ -167,6 +168,11 @@ struct reply_info {
|
||||
*/
|
||||
enum sec_status security;
|
||||
|
||||
/**
|
||||
* EDE (rfc8914) code with reason for DNSSEC bogus status.
|
||||
*/
|
||||
sldns_ede_code reason_bogus;
|
||||
|
||||
/**
|
||||
* Number of RRsets in each section.
|
||||
* The answer section. Add up the RRs in every RRset to calculate
|
||||
@ -528,7 +534,38 @@ void log_query_info(enum verbosity_value v, const char* str,
|
||||
* @return false on failure.
|
||||
*/
|
||||
int edns_opt_list_append(struct edns_option** list, uint16_t code, size_t len,
|
||||
uint8_t* data, struct regional* region);
|
||||
uint8_t* data, struct regional* region);
|
||||
|
||||
/**
|
||||
* Append edns EDE option to edns options list
|
||||
* @param LIST: the edns option list to append the edns option to.
|
||||
* @param REGION: region to allocate the new edns option.
|
||||
* @param CODE: the EDE code.
|
||||
* @param TXT: Additional text for the option
|
||||
*/
|
||||
#define EDNS_OPT_LIST_APPEND_EDE(LIST, REGION, CODE, TXT) \
|
||||
do { \
|
||||
struct { \
|
||||
uint16_t code; \
|
||||
char text[sizeof(TXT) - 1]; \
|
||||
} ede = { htons(CODE), TXT }; \
|
||||
verbose(VERB_ALGO, "attached EDE code: %d with" \
|
||||
" message: %s", CODE, TXT); \
|
||||
edns_opt_list_append((LIST), LDNS_EDNS_EDE, \
|
||||
sizeof(uint16_t) + sizeof(TXT) - 1, \
|
||||
(void *)&ede, (REGION)); \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
* Append edns EDE option to edns options list
|
||||
* @param list: the edns option list to append the edns option to.
|
||||
* @param region: region to allocate the new edns option.
|
||||
* @param code: the EDE code.
|
||||
* @param txt: Additional text for the option
|
||||
* @return false on failure.
|
||||
*/
|
||||
int edns_opt_list_append_ede(struct edns_option** list, struct regional* region,
|
||||
sldns_ede_code code, const char *txt);
|
||||
|
||||
/**
|
||||
* Remove any option found on the edns option list that matches the code.
|
||||
|
@ -40,6 +40,10 @@
|
||||
#include "config.h"
|
||||
#include "util/module.h"
|
||||
#include "sldns/wire2str.h"
|
||||
#include "util/config_file.h"
|
||||
#include "util/regional.h"
|
||||
#include "util/data/dname.h"
|
||||
#include "util/net_help.h"
|
||||
|
||||
const char*
|
||||
strextstate(enum module_ext_state s)
|
||||
@ -71,6 +75,144 @@ strmodulevent(enum module_ev e)
|
||||
return "bad_event_value";
|
||||
}
|
||||
|
||||
void errinf(struct module_qstate* qstate, const char* str)
|
||||
{
|
||||
errinf_ede(qstate, str, LDNS_EDE_NONE);
|
||||
}
|
||||
|
||||
void errinf_ede(struct module_qstate* qstate,
|
||||
const char* str, sldns_ede_code reason_bogus)
|
||||
{
|
||||
struct errinf_strlist* p;
|
||||
if((qstate->env->cfg->val_log_level < 2 && !qstate->env->cfg->log_servfail) || !str)
|
||||
return;
|
||||
p = (struct errinf_strlist*)regional_alloc(qstate->region, sizeof(*p));
|
||||
if(!p) {
|
||||
log_err("malloc failure in validator-error-info string");
|
||||
return;
|
||||
}
|
||||
p->next = NULL;
|
||||
p->str = regional_strdup(qstate->region, str);
|
||||
p->reason_bogus = reason_bogus;
|
||||
if(!p->str) {
|
||||
log_err("malloc failure in validator-error-info string");
|
||||
return;
|
||||
}
|
||||
/* add at end */
|
||||
if(qstate->errinf) {
|
||||
struct errinf_strlist* q = qstate->errinf;
|
||||
while(q->next)
|
||||
q = q->next;
|
||||
q->next = p;
|
||||
} else qstate->errinf = p;
|
||||
}
|
||||
|
||||
void errinf_origin(struct module_qstate* qstate, struct sock_list *origin)
|
||||
{
|
||||
struct sock_list* p;
|
||||
if(qstate->env->cfg->val_log_level < 2 && !qstate->env->cfg->log_servfail)
|
||||
return;
|
||||
for(p=origin; p; p=p->next) {
|
||||
char buf[256];
|
||||
if(p == origin)
|
||||
snprintf(buf, sizeof(buf), "from ");
|
||||
else snprintf(buf, sizeof(buf), "and ");
|
||||
if(p->len == 0)
|
||||
snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf),
|
||||
"cache");
|
||||
else
|
||||
addr_to_str(&p->addr, p->len, buf+strlen(buf),
|
||||
sizeof(buf)-strlen(buf));
|
||||
errinf(qstate, buf);
|
||||
}
|
||||
}
|
||||
|
||||
char* errinf_to_str_bogus(struct module_qstate* qstate)
|
||||
{
|
||||
char buf[20480];
|
||||
char* p = buf;
|
||||
size_t left = sizeof(buf);
|
||||
struct errinf_strlist* s;
|
||||
char dname[LDNS_MAX_DOMAINLEN+1];
|
||||
char t[16], c[16];
|
||||
sldns_wire2str_type_buf(qstate->qinfo.qtype, t, sizeof(t));
|
||||
sldns_wire2str_class_buf(qstate->qinfo.qclass, c, sizeof(c));
|
||||
dname_str(qstate->qinfo.qname, dname);
|
||||
snprintf(p, left, "validation failure <%s %s %s>:", dname, t, c);
|
||||
left -= strlen(p); p += strlen(p);
|
||||
if(!qstate->errinf)
|
||||
snprintf(p, left, " misc failure");
|
||||
else for(s=qstate->errinf; s; s=s->next) {
|
||||
snprintf(p, left, " %s", s->str);
|
||||
left -= strlen(p); p += strlen(p);
|
||||
}
|
||||
p = strdup(buf);
|
||||
if(!p)
|
||||
log_err("malloc failure in errinf_to_str");
|
||||
return p;
|
||||
}
|
||||
|
||||
sldns_ede_code errinf_to_reason_bogus(struct module_qstate* qstate)
|
||||
{
|
||||
struct errinf_strlist* s;
|
||||
for(s=qstate->errinf; s; s=s->next) {
|
||||
if (s->reason_bogus != LDNS_EDE_NONE) {
|
||||
return s->reason_bogus;
|
||||
}
|
||||
}
|
||||
return LDNS_EDE_NONE;
|
||||
}
|
||||
|
||||
char* errinf_to_str_servfail(struct module_qstate* qstate)
|
||||
{
|
||||
char buf[20480];
|
||||
char* p = buf;
|
||||
size_t left = sizeof(buf);
|
||||
struct errinf_strlist* s;
|
||||
char dname[LDNS_MAX_DOMAINLEN+1];
|
||||
char t[16], c[16];
|
||||
sldns_wire2str_type_buf(qstate->qinfo.qtype, t, sizeof(t));
|
||||
sldns_wire2str_class_buf(qstate->qinfo.qclass, c, sizeof(c));
|
||||
dname_str(qstate->qinfo.qname, dname);
|
||||
snprintf(p, left, "SERVFAIL <%s %s %s>:", dname, t, c);
|
||||
left -= strlen(p); p += strlen(p);
|
||||
if(!qstate->errinf)
|
||||
snprintf(p, left, " misc failure");
|
||||
else for(s=qstate->errinf; s; s=s->next) {
|
||||
snprintf(p, left, " %s", s->str);
|
||||
left -= strlen(p); p += strlen(p);
|
||||
}
|
||||
p = strdup(buf);
|
||||
if(!p)
|
||||
log_err("malloc failure in errinf_to_str");
|
||||
return p;
|
||||
}
|
||||
|
||||
void errinf_rrset(struct module_qstate* qstate, struct ub_packed_rrset_key *rr)
|
||||
{
|
||||
char buf[1024];
|
||||
char dname[LDNS_MAX_DOMAINLEN+1];
|
||||
char t[16], c[16];
|
||||
if((qstate->env->cfg->val_log_level < 2 && !qstate->env->cfg->log_servfail) || !rr)
|
||||
return;
|
||||
sldns_wire2str_type_buf(ntohs(rr->rk.type), t, sizeof(t));
|
||||
sldns_wire2str_class_buf(ntohs(rr->rk.rrset_class), c, sizeof(c));
|
||||
dname_str(rr->rk.dname, dname);
|
||||
snprintf(buf, sizeof(buf), "for <%s %s %s>", dname, t, c);
|
||||
errinf(qstate, buf);
|
||||
}
|
||||
|
||||
void errinf_dname(struct module_qstate* qstate, const char* str, uint8_t* dname)
|
||||
{
|
||||
char b[1024];
|
||||
char buf[LDNS_MAX_DOMAINLEN+1];
|
||||
if((qstate->env->cfg->val_log_level < 2 && !qstate->env->cfg->log_servfail) || !str || !dname)
|
||||
return;
|
||||
dname_str(dname, buf);
|
||||
snprintf(b, sizeof(b), "%s %s", str, buf);
|
||||
errinf(qstate, b);
|
||||
}
|
||||
|
||||
int
|
||||
edns_known_options_init(struct module_env* env)
|
||||
{
|
||||
|
@ -187,6 +187,15 @@ struct respip_addr_info;
|
||||
/** Maximum number of known edns options */
|
||||
#define MAX_KNOWN_EDNS_OPTS 256
|
||||
|
||||
struct errinf_strlist {
|
||||
/** next item in list */
|
||||
struct errinf_strlist* next;
|
||||
/** config option string */
|
||||
char* str;
|
||||
/** EDE code companion to the error str */
|
||||
int reason_bogus;
|
||||
};
|
||||
|
||||
enum inplace_cb_list_type {
|
||||
/* Inplace callbacks for when a resolved reply is ready to be sent to the
|
||||
* front.*/
|
||||
@ -624,8 +633,7 @@ struct module_qstate {
|
||||
/** region for this query. Cleared when query process finishes. */
|
||||
struct regional* region;
|
||||
/** failure reason information if val-log-level is high */
|
||||
struct config_strlist* errinf;
|
||||
|
||||
struct errinf_strlist* errinf;
|
||||
/** which module is executing */
|
||||
int curmod;
|
||||
/** module states */
|
||||
@ -667,6 +675,8 @@ struct module_qstate {
|
||||
/** Extended result of response-ip action processing, mainly
|
||||
* for logging purposes. */
|
||||
struct respip_action_info* respip_action_info;
|
||||
/** if the query is rpz passthru, no further rpz processing for it */
|
||||
int rpz_passthru;
|
||||
|
||||
/** whether the reply should be dropped */
|
||||
int is_drop;
|
||||
@ -759,6 +769,65 @@ const char* strextstate(enum module_ext_state s);
|
||||
*/
|
||||
const char* strmodulevent(enum module_ev e);
|
||||
|
||||
/**
|
||||
* Append text to the error info for validation.
|
||||
* @param qstate: query state.
|
||||
* @param str: copied into query region and appended.
|
||||
* Failures to allocate are logged.
|
||||
*/
|
||||
void errinf(struct module_qstate* qstate, const char* str);
|
||||
void errinf_ede(struct module_qstate* qstate, const char* str,
|
||||
sldns_ede_code reason_bogus);
|
||||
|
||||
/**
|
||||
* Append text to error info: from 1.2.3.4
|
||||
* @param qstate: query state.
|
||||
* @param origin: sock list with origin of trouble.
|
||||
* Every element added.
|
||||
* If NULL: nothing is added.
|
||||
* if 0len element: 'from cache' is added.
|
||||
*/
|
||||
void errinf_origin(struct module_qstate* qstate, struct sock_list *origin);
|
||||
|
||||
/**
|
||||
* Append text to error info: for RRset name type class
|
||||
* @param qstate: query state.
|
||||
* @param rr: rrset_key.
|
||||
*/
|
||||
void errinf_rrset(struct module_qstate* qstate, struct ub_packed_rrset_key *rr);
|
||||
|
||||
/**
|
||||
* Append text to error info: str dname
|
||||
* @param qstate: query state.
|
||||
* @param str: explanation string
|
||||
* @param dname: the dname.
|
||||
*/
|
||||
void errinf_dname(struct module_qstate* qstate, const char* str,
|
||||
uint8_t* dname);
|
||||
|
||||
/**
|
||||
* Create error info in string. For validation failures.
|
||||
* @param qstate: query state.
|
||||
* @return string or NULL on malloc failure (already logged).
|
||||
* This string is malloced and has to be freed by caller.
|
||||
*/
|
||||
char* errinf_to_str_bogus(struct module_qstate* qstate);
|
||||
/**
|
||||
* Check the sldns_ede_code of the qstate.
|
||||
* @param qstate: query state.
|
||||
* @return LDNS_EDE_DNSSEC_BOGUS by default, or the first explicitly set
|
||||
* sldns_ede_code.
|
||||
*/
|
||||
sldns_ede_code errinf_to_reason_bogus(struct module_qstate* qstate);
|
||||
|
||||
/**
|
||||
* Create error info in string. For other servfails.
|
||||
* @param qstate: query state.
|
||||
* @return string or NULL on malloc failure (already logged).
|
||||
* This string is malloced and has to be freed by caller.
|
||||
*/
|
||||
char* errinf_to_str_servfail(struct module_qstate* qstate);
|
||||
|
||||
/**
|
||||
* Initialize the edns known options by allocating the required space.
|
||||
* @param env: the module environment.
|
||||
|
@ -1271,7 +1271,13 @@ void* connect_sslctx_create(char* key, char* pem, char* verifypem, int wincert)
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)wincert;
|
||||
if(wincert) {
|
||||
if(!SSL_CTX_set_default_verify_paths(ctx)) {
|
||||
log_crypto_err("error in default_verify_paths");
|
||||
SSL_CTX_free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
|
||||
}
|
||||
|
@ -1209,23 +1209,22 @@ squelch_err_ssl_handshake(unsigned long err)
|
||||
{
|
||||
if(verbosity >= VERB_QUERY)
|
||||
return 0; /* only squelch on low verbosity */
|
||||
/* this is very specific, we could filter on ERR_GET_REASON()
|
||||
* (the third element in ERR_PACK) */
|
||||
if(err == ERR_PACK(ERR_LIB_SSL, SSL_F_SSL3_GET_RECORD, SSL_R_HTTPS_PROXY_REQUEST) ||
|
||||
err == ERR_PACK(ERR_LIB_SSL, SSL_F_SSL3_GET_RECORD, SSL_R_HTTP_REQUEST) ||
|
||||
err == ERR_PACK(ERR_LIB_SSL, SSL_F_SSL3_GET_RECORD, SSL_R_WRONG_VERSION_NUMBER) ||
|
||||
err == ERR_PACK(ERR_LIB_SSL, SSL_F_SSL3_READ_BYTES, SSL_R_SSLV3_ALERT_BAD_CERTIFICATE)
|
||||
if(ERR_GET_LIB(err) == ERR_LIB_SSL &&
|
||||
(ERR_GET_REASON(err) == SSL_R_HTTPS_PROXY_REQUEST ||
|
||||
ERR_GET_REASON(err) == SSL_R_HTTP_REQUEST ||
|
||||
ERR_GET_REASON(err) == SSL_R_WRONG_VERSION_NUMBER ||
|
||||
ERR_GET_REASON(err) == SSL_R_SSLV3_ALERT_BAD_CERTIFICATE
|
||||
#ifdef SSL_F_TLS_POST_PROCESS_CLIENT_HELLO
|
||||
|| err == ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_POST_PROCESS_CLIENT_HELLO, SSL_R_NO_SHARED_CIPHER)
|
||||
|| ERR_GET_REASON(err) == SSL_R_NO_SHARED_CIPHER
|
||||
#endif
|
||||
#ifdef SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO
|
||||
|| err == ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, SSL_R_UNKNOWN_PROTOCOL)
|
||||
|| err == ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, SSL_R_UNSUPPORTED_PROTOCOL)
|
||||
|| ERR_GET_REASON(err) == SSL_R_UNKNOWN_PROTOCOL
|
||||
|| ERR_GET_REASON(err) == SSL_R_UNSUPPORTED_PROTOCOL
|
||||
# ifdef SSL_R_VERSION_TOO_LOW
|
||||
|| err == ERR_PACK(ERR_LIB_SSL, SSL_F_TLS_EARLY_POST_PROCESS_CLIENT_HELLO, SSL_R_VERSION_TOO_LOW)
|
||||
|| ERR_GET_REASON(err) == SSL_R_VERSION_TOO_LOW
|
||||
# endif
|
||||
#endif
|
||||
)
|
||||
))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
@ -1278,6 +1277,12 @@ ssl_handshake(struct comm_point* c)
|
||||
if(errno == ECONNRESET && verbosity < 2)
|
||||
return 0; /* silence reset by peer */
|
||||
#endif
|
||||
if(!tcp_connect_errno_needs_log(
|
||||
(struct sockaddr*)&c->repinfo.addr,
|
||||
c->repinfo.addrlen))
|
||||
return 0; /* silence connect failures that
|
||||
show up because after connect this is the
|
||||
first system call that accesses the socket */
|
||||
if(errno != 0)
|
||||
log_err("SSL_handshake syscall: %s",
|
||||
strerror(errno));
|
||||
@ -2480,7 +2485,7 @@ http_nonchunk_segment(struct comm_point* c)
|
||||
remainbufferlen = sldns_buffer_capacity(c->buffer) -
|
||||
sldns_buffer_limit(c->buffer);
|
||||
if(remainbufferlen+got_now >= c->tcp_byte_count ||
|
||||
remainbufferlen >= (c->ssl?16384:2048)) {
|
||||
remainbufferlen >= (size_t)(c->ssl?16384:2048)) {
|
||||
size_t total = sldns_buffer_limit(c->buffer);
|
||||
sldns_buffer_clear(c->buffer);
|
||||
sldns_buffer_set_position(c->buffer, total);
|
||||
|
@ -1203,13 +1203,8 @@ void autr_write_file(struct module_env* env, struct trust_anchor* tp)
|
||||
#else
|
||||
llvalue = (unsigned long long)tp;
|
||||
#endif
|
||||
#ifndef USE_WINSOCK
|
||||
snprintf(tempf, sizeof(tempf), "%s.%d-%d-%llx", fname, (int)getpid(),
|
||||
snprintf(tempf, sizeof(tempf), "%s.%d-%d-" ARG_LL "x", fname, (int)getpid(),
|
||||
env->worker?*(int*)env->worker:0, llvalue);
|
||||
#else
|
||||
snprintf(tempf, sizeof(tempf), "%s.%d-%d-%I64x", fname, (int)getpid(),
|
||||
env->worker?*(int*)env->worker:0, llvalue);
|
||||
#endif
|
||||
#endif /* S_SPLINT_S */
|
||||
verbose(VERB_ALGO, "autotrust: write to disk: %s", tempf);
|
||||
out = fopen(tempf, "w");
|
||||
@ -1268,7 +1263,7 @@ verify_dnskey(struct module_env* env, struct val_env* ve,
|
||||
int downprot = env->cfg->harden_algo_downgrade;
|
||||
enum sec_status sec = val_verify_DNSKEY_with_TA(env, ve, rrset,
|
||||
tp->ds_rrset, tp->dnskey_rrset, downprot?sigalg:NULL, &reason,
|
||||
qstate);
|
||||
NULL, qstate);
|
||||
/* sigalg is ignored, it returns algorithms signalled to exist, but
|
||||
* in 5011 there are no other rrsets to check. if downprot is
|
||||
* enabled, then it checks that the DNSKEY is signed with all
|
||||
@ -1317,7 +1312,7 @@ rr_is_selfsigned_revoked(struct module_env* env, struct val_env* ve,
|
||||
/* no algorithm downgrade protection necessary, if it is selfsigned
|
||||
* revoked it can be removed. */
|
||||
sec = dnskey_verify_rrset(env, ve, dnskey_rrset, dnskey_rrset, i,
|
||||
&reason, LDNS_SECTION_ANSWER, qstate);
|
||||
&reason, NULL, LDNS_SECTION_ANSWER, qstate);
|
||||
return (sec == sec_status_secure);
|
||||
}
|
||||
|
||||
@ -2397,7 +2392,7 @@ probe_anchor(struct module_env* env, struct trust_anchor* tp)
|
||||
qinfo.qclass);
|
||||
|
||||
if(!mesh_new_callback(env->mesh, &qinfo, qflags, &edns, buf, 0,
|
||||
&probe_answer_cb, env)) {
|
||||
&probe_answer_cb, env, 0)) {
|
||||
log_err("out of memory making 5011 probe");
|
||||
}
|
||||
}
|
||||
|
@ -90,6 +90,7 @@ key_cache_insert(struct key_cache* kcache, struct key_entry_key* kkey,
|
||||
qstate->env->cfg->val_log_level >= 2) {
|
||||
/* on malloc failure there is simply no reason string */
|
||||
key_entry_set_reason(k, errinf_to_str_bogus(qstate));
|
||||
key_entry_set_reason_bogus(k, errinf_to_reason_bogus(qstate));
|
||||
}
|
||||
key_entry_hash(k);
|
||||
slabhash_insert(kcache->slab, k->entry.hash, &k->entry,
|
||||
|
@ -244,6 +244,15 @@ key_entry_set_reason(struct key_entry_key* kkey, char* reason)
|
||||
d->reason = reason;
|
||||
}
|
||||
|
||||
void
|
||||
key_entry_set_reason_bogus(struct key_entry_key* kkey, sldns_ede_code ede)
|
||||
{
|
||||
struct key_entry_data* d = (struct key_entry_data*)kkey->entry.data;
|
||||
if (ede != LDNS_EDE_NONE) { /* reason_bogus init is LDNS_EDE_NONE already */
|
||||
d->reason_bogus = ede;
|
||||
}
|
||||
}
|
||||
|
||||
char*
|
||||
key_entry_get_reason(struct key_entry_key* kkey)
|
||||
{
|
||||
@ -251,6 +260,14 @@ key_entry_get_reason(struct key_entry_key* kkey)
|
||||
return d->reason;
|
||||
}
|
||||
|
||||
sldns_ede_code
|
||||
key_entry_get_reason_bogus(struct key_entry_key* kkey)
|
||||
{
|
||||
struct key_entry_data* d = (struct key_entry_data*)kkey->entry.data;
|
||||
return d->reason_bogus;
|
||||
|
||||
}
|
||||
|
||||
/** setup key entry in region */
|
||||
static int
|
||||
key_entry_setup(struct regional* region,
|
||||
@ -286,6 +303,7 @@ key_entry_create_null(struct regional* region,
|
||||
d->ttl = now + ttl;
|
||||
d->isbad = 0;
|
||||
d->reason = NULL;
|
||||
d->reason_bogus = LDNS_EDE_NONE;
|
||||
d->rrset_type = LDNS_RR_TYPE_DNSKEY;
|
||||
d->rrset_data = NULL;
|
||||
d->algo = NULL;
|
||||
@ -306,6 +324,7 @@ key_entry_create_rrset(struct regional* region,
|
||||
d->ttl = rd->ttl + now;
|
||||
d->isbad = 0;
|
||||
d->reason = NULL;
|
||||
d->reason_bogus = LDNS_EDE_NONE;
|
||||
d->rrset_type = ntohs(rrset->rk.type);
|
||||
d->rrset_data = (struct packed_rrset_data*)regional_alloc_init(region,
|
||||
rd, packed_rrset_sizeof(rd));
|
||||
@ -332,6 +351,7 @@ key_entry_create_bad(struct regional* region,
|
||||
d->ttl = now + ttl;
|
||||
d->isbad = 1;
|
||||
d->reason = NULL;
|
||||
d->reason_bogus = LDNS_EDE_NONE;
|
||||
d->rrset_type = LDNS_RR_TYPE_DNSKEY;
|
||||
d->rrset_data = NULL;
|
||||
d->algo = NULL;
|
||||
|
@ -45,6 +45,7 @@ struct packed_rrset_data;
|
||||
struct regional;
|
||||
struct ub_packed_rrset_key;
|
||||
#include "util/storage/lruhash.h"
|
||||
#include "sldns/rrdef.h"
|
||||
|
||||
/**
|
||||
* A key entry for the validator.
|
||||
@ -80,6 +81,8 @@ struct key_entry_data {
|
||||
struct packed_rrset_data* rrset_data;
|
||||
/** not NULL sometimes to give reason why bogus */
|
||||
char* reason;
|
||||
/** not NULL to give reason why bogus */
|
||||
sldns_ede_code reason_bogus;
|
||||
/** list of algorithms signalled, ends with 0, or NULL */
|
||||
uint8_t* algo;
|
||||
/** DNS RR type of the rrset data (host order) */
|
||||
@ -150,6 +153,15 @@ int key_entry_isbad(struct key_entry_key* kkey);
|
||||
*/
|
||||
void key_entry_set_reason(struct key_entry_key* kkey, char* reason);
|
||||
|
||||
/**
|
||||
* Set the EDE (RFC8914) code why the key is bad, if it
|
||||
* exists (so not LDNS_EDE_NONE).
|
||||
* @param kkey: bad key.
|
||||
* @param ede: EDE code to attach to this key.
|
||||
*/
|
||||
void key_entry_set_reason_bogus(struct key_entry_key* kkey, sldns_ede_code ede);
|
||||
|
||||
|
||||
/**
|
||||
* Get reason why a key is bad.
|
||||
* @param kkey: bad key
|
||||
@ -158,6 +170,13 @@ void key_entry_set_reason(struct key_entry_key* kkey, char* reason);
|
||||
*/
|
||||
char* key_entry_get_reason(struct key_entry_key* kkey);
|
||||
|
||||
/**
|
||||
* Get the EDE (RFC8914) code why a key is bad. Can return LDNS_EDE_NONE.
|
||||
* @param kkey: bad key
|
||||
* @return the ede code.
|
||||
*/
|
||||
sldns_ede_code key_entry_get_reason_bogus(struct key_entry_key* kkey);
|
||||
|
||||
/**
|
||||
* Create a null entry, in the given region.
|
||||
* @param region: where to allocate
|
||||
|
@ -187,7 +187,7 @@ nsec_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
if(d->security == sec_status_secure)
|
||||
return 1;
|
||||
d->security = val_verify_rrset_entry(env, ve, nsec, kkey, reason,
|
||||
LDNS_SECTION_AUTHORITY, qstate);
|
||||
NULL, LDNS_SECTION_AUTHORITY, qstate);
|
||||
if(d->security == sec_status_secure) {
|
||||
rrset_update_sec_status(env->rrset_cache, nsec, *env->now);
|
||||
return 1;
|
||||
|
@ -1289,7 +1289,8 @@ nsec3_prove_wildcard(struct module_env* env, struct val_env* ve,
|
||||
static int
|
||||
list_is_secure(struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key** list, size_t num,
|
||||
struct key_entry_key* kkey, char** reason, struct module_qstate* qstate)
|
||||
struct key_entry_key* kkey, char** reason, sldns_ede_code *reason_bogus,
|
||||
struct module_qstate* qstate)
|
||||
{
|
||||
struct packed_rrset_data* d;
|
||||
size_t i;
|
||||
@ -1303,7 +1304,7 @@ list_is_secure(struct module_env* env, struct val_env* ve,
|
||||
if(d->security == sec_status_secure)
|
||||
continue;
|
||||
d->security = val_verify_rrset_entry(env, ve, list[i], kkey,
|
||||
reason, LDNS_SECTION_AUTHORITY, qstate);
|
||||
reason, reason_bogus, LDNS_SECTION_AUTHORITY, qstate);
|
||||
if(d->security != sec_status_secure) {
|
||||
verbose(VERB_ALGO, "NSEC3 did not verify");
|
||||
return 0;
|
||||
@ -1317,7 +1318,7 @@ enum sec_status
|
||||
nsec3_prove_nods(struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key** list, size_t num,
|
||||
struct query_info* qinfo, struct key_entry_key* kkey, char** reason,
|
||||
struct module_qstate* qstate)
|
||||
sldns_ede_code* reason_bogus, struct module_qstate* qstate)
|
||||
{
|
||||
rbtree_type ct;
|
||||
struct nsec3_filter flt;
|
||||
@ -1330,8 +1331,10 @@ nsec3_prove_nods(struct module_env* env, struct val_env* ve,
|
||||
*reason = "no valid NSEC3s";
|
||||
return sec_status_bogus; /* no valid NSEC3s, bogus */
|
||||
}
|
||||
if(!list_is_secure(env, ve, list, num, kkey, reason, qstate))
|
||||
if(!list_is_secure(env, ve, list, num, kkey, reason, reason_bogus, qstate)) {
|
||||
*reason = "not all NSEC3 records secure";
|
||||
return sec_status_bogus; /* not all NSEC3 records secure */
|
||||
}
|
||||
rbtree_init(&ct, &nsec3_hash_cmp); /* init names-to-hash cache */
|
||||
filter_init(&flt, list, num, qinfo); /* init RR iterator */
|
||||
if(!flt.zone) {
|
||||
|
@ -68,6 +68,7 @@
|
||||
#define VALIDATOR_VAL_NSEC3_H
|
||||
#include "util/rbtree.h"
|
||||
#include "util/data/packed_rrset.h"
|
||||
#include "sldns/rrdef.h"
|
||||
struct val_env;
|
||||
struct regional;
|
||||
struct module_env;
|
||||
@ -186,6 +187,7 @@ nsec3_prove_wildcard(struct module_env* env, struct val_env* ve,
|
||||
* @param qinfo: query that is verified for.
|
||||
* @param kkey: key entry that signed the NSEC3s.
|
||||
* @param reason: string for bogus result.
|
||||
* @param reason_bogus: EDE (RFC8914) code paired with the reason of failure.
|
||||
* @param qstate: qstate with region.
|
||||
* @return:
|
||||
* sec_status SECURE of the proposition is proven by the NSEC3 RRs,
|
||||
@ -197,7 +199,7 @@ enum sec_status
|
||||
nsec3_prove_nods(struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key** list, size_t num,
|
||||
struct query_info* qinfo, struct key_entry_key* kkey, char** reason,
|
||||
struct module_qstate* qstate);
|
||||
sldns_ede_code* reason_bogus, struct module_qstate* qstate);
|
||||
|
||||
/**
|
||||
* Prove NXDOMAIN or NODATA.
|
||||
|
@ -525,11 +525,19 @@ int algo_needs_missing(struct algo_needs* n)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static enum sec_status
|
||||
dnskeyset_verify_rrset_sig(struct module_env* env, struct val_env* ve,
|
||||
time_t now, struct ub_packed_rrset_key* rrset,
|
||||
struct ub_packed_rrset_key* dnskey, size_t sig_idx,
|
||||
struct rbtree_type** sortree,
|
||||
char** reason, sldns_ede_code *reason_bogus,
|
||||
sldns_pkt_section section, struct module_qstate* qstate);
|
||||
|
||||
enum sec_status
|
||||
dnskeyset_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey,
|
||||
uint8_t* sigalg, char** reason, sldns_pkt_section section,
|
||||
struct module_qstate* qstate)
|
||||
uint8_t* sigalg, char** reason, sldns_ede_code *reason_bogus,
|
||||
sldns_pkt_section section, struct module_qstate* qstate)
|
||||
{
|
||||
enum sec_status sec;
|
||||
size_t i, num;
|
||||
@ -543,6 +551,8 @@ dnskeyset_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
verbose(VERB_QUERY, "rrset failed to verify due to a lack of "
|
||||
"signatures");
|
||||
*reason = "no signatures";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_RRSIGS_MISSING;
|
||||
return sec_status_bogus;
|
||||
}
|
||||
|
||||
@ -551,12 +561,15 @@ dnskeyset_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
if(algo_needs_num_missing(&needs) == 0) {
|
||||
verbose(VERB_QUERY, "zone has no known algorithms");
|
||||
*reason = "zone has no known algorithms";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_UNSUPPORTED_DNSKEY_ALG;
|
||||
return sec_status_insecure;
|
||||
}
|
||||
}
|
||||
for(i=0; i<num; i++) {
|
||||
sec = dnskeyset_verify_rrset_sig(env, ve, *env->now, rrset,
|
||||
dnskey, i, &sortree, reason, section, qstate);
|
||||
dnskey, i, &sortree, reason, reason_bogus,
|
||||
section, qstate);
|
||||
/* see which algorithm has been fixed up */
|
||||
if(sec == sec_status_secure) {
|
||||
if(!sigalg)
|
||||
@ -597,8 +610,8 @@ void algo_needs_reason(struct module_env* env, int alg, char** reason, char* s)
|
||||
enum sec_status
|
||||
dnskey_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey,
|
||||
size_t dnskey_idx, char** reason, sldns_pkt_section section,
|
||||
struct module_qstate* qstate)
|
||||
size_t dnskey_idx, char** reason, sldns_ede_code *reason_bogus,
|
||||
sldns_pkt_section section, struct module_qstate* qstate)
|
||||
{
|
||||
enum sec_status sec;
|
||||
size_t i, num, numchecked = 0;
|
||||
@ -612,6 +625,8 @@ dnskey_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
verbose(VERB_QUERY, "rrset failed to verify due to a lack of "
|
||||
"signatures");
|
||||
*reason = "no signatures";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_RRSIGS_MISSING;
|
||||
return sec_status_bogus;
|
||||
}
|
||||
for(i=0; i<num; i++) {
|
||||
@ -623,7 +638,7 @@ dnskey_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
sec = dnskey_verify_rrset_sig(env->scratch,
|
||||
env->scratch_buffer, ve, *env->now, rrset,
|
||||
dnskey, dnskey_idx, i, &sortree, &buf_canon, reason,
|
||||
section, qstate);
|
||||
reason_bogus, section, qstate);
|
||||
if(sec == sec_status_secure)
|
||||
return sec;
|
||||
numchecked ++;
|
||||
@ -633,12 +648,13 @@ dnskey_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
return sec_status_bogus;
|
||||
}
|
||||
|
||||
enum sec_status
|
||||
static enum sec_status
|
||||
dnskeyset_verify_rrset_sig(struct module_env* env, struct val_env* ve,
|
||||
time_t now, struct ub_packed_rrset_key* rrset,
|
||||
struct ub_packed_rrset_key* dnskey, size_t sig_idx,
|
||||
struct rbtree_type** sortree, char** reason, sldns_pkt_section section,
|
||||
struct module_qstate* qstate)
|
||||
struct rbtree_type** sortree,
|
||||
char** reason, sldns_ede_code *reason_bogus,
|
||||
sldns_pkt_section section, struct module_qstate* qstate)
|
||||
{
|
||||
/* find matching keys and check them */
|
||||
enum sec_status sec = sec_status_bogus;
|
||||
@ -649,6 +665,8 @@ dnskeyset_verify_rrset_sig(struct module_env* env, struct val_env* ve,
|
||||
int buf_canon = 0;
|
||||
verbose(VERB_ALGO, "verify sig %d %d", (int)tag, algo);
|
||||
if(!dnskey_algo_id_is_supported(algo)) {
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_UNSUPPORTED_DNSKEY_ALG;
|
||||
verbose(VERB_QUERY, "verify sig: unknown algorithm");
|
||||
return sec_status_insecure;
|
||||
}
|
||||
@ -663,12 +681,15 @@ dnskeyset_verify_rrset_sig(struct module_env* env, struct val_env* ve,
|
||||
/* see if key verifies */
|
||||
sec = dnskey_verify_rrset_sig(env->scratch,
|
||||
env->scratch_buffer, ve, now, rrset, dnskey, i,
|
||||
sig_idx, sortree, &buf_canon, reason, section, qstate);
|
||||
sig_idx, sortree, &buf_canon, reason, reason_bogus,
|
||||
section, qstate);
|
||||
if(sec == sec_status_secure)
|
||||
return sec;
|
||||
}
|
||||
if(numchecked == 0) {
|
||||
*reason = "signatures from unknown keys";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_DNSKEY_MISSING;
|
||||
verbose(VERB_QUERY, "verify: could not find appropriate key");
|
||||
return sec_status_bogus;
|
||||
}
|
||||
@ -1361,8 +1382,8 @@ subtract_1982(uint32_t a, uint32_t b)
|
||||
|
||||
/** check rrsig dates */
|
||||
static int
|
||||
check_dates(struct val_env* ve, uint32_t unow,
|
||||
uint8_t* expi_p, uint8_t* incep_p, char** reason)
|
||||
check_dates(struct val_env* ve, uint32_t unow, uint8_t* expi_p,
|
||||
uint8_t* incep_p, char** reason, sldns_ede_code *reason_bogus)
|
||||
{
|
||||
/* read out the dates */
|
||||
uint32_t expi, incep, now;
|
||||
@ -1386,6 +1407,14 @@ check_dates(struct val_env* ve, uint32_t unow,
|
||||
sigdate_error("verify: inception after expiration, "
|
||||
"signature bad", expi, incep, now);
|
||||
*reason = "signature inception after expiration";
|
||||
if(reason_bogus){
|
||||
/* from RFC8914 on Signature Not Yet Valid: The resolver
|
||||
* attempted to perform DNSSEC validation, but no
|
||||
* signatures are presently valid and at least some are
|
||||
* not yet valid. */
|
||||
*reason_bogus = LDNS_EDE_SIGNATURE_NOT_YET_VALID;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
if(compare_1982(incep, now) > 0) {
|
||||
@ -1397,6 +1426,8 @@ check_dates(struct val_env* ve, uint32_t unow,
|
||||
sigdate_error("verify: signature bad, current time is"
|
||||
" before inception date", expi, incep, now);
|
||||
*reason = "signature before inception date";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_SIGNATURE_NOT_YET_VALID;
|
||||
return 0;
|
||||
}
|
||||
sigdate_error("verify warning suspicious signature inception "
|
||||
@ -1410,6 +1441,8 @@ check_dates(struct val_env* ve, uint32_t unow,
|
||||
sigdate_error("verify: signature expired", expi,
|
||||
incep, now);
|
||||
*reason = "signature expired";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_SIGNATURE_EXPIRED;
|
||||
return 0;
|
||||
}
|
||||
sigdate_error("verify warning suspicious signature expiration "
|
||||
@ -1473,7 +1506,8 @@ dnskey_verify_rrset_sig(struct regional* region, sldns_buffer* buf,
|
||||
struct val_env* ve, time_t now,
|
||||
struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey,
|
||||
size_t dnskey_idx, size_t sig_idx,
|
||||
struct rbtree_type** sortree, int* buf_canon, char** reason,
|
||||
struct rbtree_type** sortree, int* buf_canon,
|
||||
char** reason, sldns_ede_code *reason_bogus,
|
||||
sldns_pkt_section section, struct module_qstate* qstate)
|
||||
{
|
||||
enum sec_status sec;
|
||||
@ -1492,12 +1526,16 @@ dnskey_verify_rrset_sig(struct regional* region, sldns_buffer* buf,
|
||||
if(siglen < 2+20) {
|
||||
verbose(VERB_QUERY, "verify: signature too short");
|
||||
*reason = "signature too short";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
return sec_status_bogus;
|
||||
}
|
||||
|
||||
if(!(dnskey_get_flags(dnskey, dnskey_idx) & DNSKEY_BIT_ZSK)) {
|
||||
verbose(VERB_QUERY, "verify: dnskey without ZSK flag");
|
||||
*reason = "dnskey without ZSK flag";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_NO_ZONE_KEY_BIT_SET;
|
||||
return sec_status_bogus;
|
||||
}
|
||||
|
||||
@ -1505,6 +1543,8 @@ dnskey_verify_rrset_sig(struct regional* region, sldns_buffer* buf,
|
||||
/* RFC 4034 says DNSKEY PROTOCOL MUST be 3 */
|
||||
verbose(VERB_QUERY, "verify: dnskey has wrong key protocol");
|
||||
*reason = "dnskey has wrong protocolnumber";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
return sec_status_bogus;
|
||||
}
|
||||
|
||||
@ -1514,17 +1554,23 @@ dnskey_verify_rrset_sig(struct regional* region, sldns_buffer* buf,
|
||||
if(!signer_len) {
|
||||
verbose(VERB_QUERY, "verify: malformed signer name");
|
||||
*reason = "signer name malformed";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
return sec_status_bogus; /* signer name invalid */
|
||||
}
|
||||
if(!dname_subdomain_c(rrset->rk.dname, signer)) {
|
||||
verbose(VERB_QUERY, "verify: signer name is off-tree");
|
||||
*reason = "signer name off-tree";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
return sec_status_bogus; /* signer name offtree */
|
||||
}
|
||||
sigblock = (unsigned char*)signer+signer_len;
|
||||
if(siglen < 2+18+signer_len+1) {
|
||||
verbose(VERB_QUERY, "verify: too short, no signature data");
|
||||
*reason = "signature too short, no signature data";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
return sec_status_bogus; /* sig rdf is < 1 byte */
|
||||
}
|
||||
sigblock_len = (unsigned int)(siglen - 2 - 18 - signer_len);
|
||||
@ -1537,6 +1583,8 @@ dnskey_verify_rrset_sig(struct regional* region, sldns_buffer* buf,
|
||||
log_nametypeclass(VERB_QUERY, "the key name is",
|
||||
dnskey->rk.dname, 0, 0);
|
||||
*reason = "signer name mismatches key name";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
return sec_status_bogus;
|
||||
}
|
||||
|
||||
@ -1545,18 +1593,24 @@ dnskey_verify_rrset_sig(struct regional* region, sldns_buffer* buf,
|
||||
if(memcmp(sig+2, &rrset->rk.type, 2) != 0) {
|
||||
verbose(VERB_QUERY, "verify: wrong type covered");
|
||||
*reason = "signature covers wrong type";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
return sec_status_bogus;
|
||||
}
|
||||
/* verify keytag and sig algo (possibly again) */
|
||||
if((int)sig[2+2] != dnskey_get_algo(dnskey, dnskey_idx)) {
|
||||
verbose(VERB_QUERY, "verify: wrong algorithm");
|
||||
*reason = "signature has wrong algorithm";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
return sec_status_bogus;
|
||||
}
|
||||
ktag = htons(dnskey_calc_keytag(dnskey, dnskey_idx));
|
||||
if(memcmp(sig+2+16, &ktag, 2) != 0) {
|
||||
verbose(VERB_QUERY, "verify: wrong keytag");
|
||||
*reason = "signature has wrong keytag";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
return sec_status_bogus;
|
||||
}
|
||||
|
||||
@ -1564,6 +1618,8 @@ dnskey_verify_rrset_sig(struct regional* region, sldns_buffer* buf,
|
||||
if((int)sig[2+3] > dname_signame_label_count(rrset->rk.dname)) {
|
||||
verbose(VERB_QUERY, "verify: labelcount out of range");
|
||||
*reason = "signature labelcount out of range";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
|
||||
return sec_status_bogus;
|
||||
}
|
||||
|
||||
@ -1598,7 +1654,8 @@ dnskey_verify_rrset_sig(struct regional* region, sldns_buffer* buf,
|
||||
/* verify inception, expiration dates
|
||||
* Do this last so that if you ignore expired-sigs the
|
||||
* rest is sure to be OK. */
|
||||
if(!check_dates(ve, now, sig+2+8, sig+2+12, reason)) {
|
||||
if(!check_dates(ve, now, sig+2+8, sig+2+12,
|
||||
reason, reason_bogus)) {
|
||||
return sec_status_bogus;
|
||||
}
|
||||
}
|
||||
|
@ -45,6 +45,7 @@
|
||||
#define VALIDATOR_VAL_SIGCRYPT_H
|
||||
#include "util/data/packed_rrset.h"
|
||||
#include "sldns/pkthdr.h"
|
||||
#include "sldns/rrdef.h"
|
||||
struct val_env;
|
||||
struct module_env;
|
||||
struct module_qstate;
|
||||
@ -256,6 +257,7 @@ uint16_t dnskey_get_flags(struct ub_packed_rrset_key* k, size_t idx);
|
||||
* @param sigalg: if nonNULL provide downgrade protection otherwise one
|
||||
* algorithm is enough.
|
||||
* @param reason: if bogus, a string returned, fixed or alloced in scratch.
|
||||
* @param reason_bogus: EDE (RFC8914) code paired with the reason of failure.
|
||||
* @param section: section of packet where this rrset comes from.
|
||||
* @param qstate: qstate with region.
|
||||
* @return SECURE if one key in the set verifies one rrsig.
|
||||
@ -264,9 +266,11 @@ uint16_t dnskey_get_flags(struct ub_packed_rrset_key* k, size_t idx);
|
||||
*/
|
||||
enum sec_status dnskeyset_verify_rrset(struct module_env* env,
|
||||
struct val_env* ve, struct ub_packed_rrset_key* rrset,
|
||||
struct ub_packed_rrset_key* dnskey, uint8_t* sigalg, char** reason,
|
||||
struct ub_packed_rrset_key* dnskey, uint8_t* sigalg,
|
||||
char** reason, sldns_ede_code *reason_bogus,
|
||||
sldns_pkt_section section, struct module_qstate* qstate);
|
||||
|
||||
|
||||
/**
|
||||
* verify rrset against one specific dnskey (from rrset)
|
||||
* @param env: module environment, scratch space is used.
|
||||
@ -275,38 +279,17 @@ enum sec_status dnskeyset_verify_rrset(struct module_env* env,
|
||||
* @param dnskey: DNSKEY rrset, keyset.
|
||||
* @param dnskey_idx: which key from the rrset to try.
|
||||
* @param reason: if bogus, a string returned, fixed or alloced in scratch.
|
||||
* @param reason_bogus: EDE (RFC8914) code paired with the reason of failure.
|
||||
* @param section: section of packet where this rrset comes from.
|
||||
* @param qstate: qstate with region.
|
||||
* @return secure if *this* key signs any of the signatures on rrset.
|
||||
* unchecked on error or and bogus on bad signature.
|
||||
*/
|
||||
enum sec_status dnskey_verify_rrset(struct module_env* env,
|
||||
struct val_env* ve, struct ub_packed_rrset_key* rrset,
|
||||
struct ub_packed_rrset_key* dnskey, size_t dnskey_idx, char** reason,
|
||||
enum sec_status dnskey_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey,
|
||||
size_t dnskey_idx, char** reason, sldns_ede_code *reason_bogus,
|
||||
sldns_pkt_section section, struct module_qstate* qstate);
|
||||
|
||||
/**
|
||||
* verify rrset, with dnskey rrset, for a specific rrsig in rrset
|
||||
* @param env: module environment, scratch space is used.
|
||||
* @param ve: validator environment, date settings.
|
||||
* @param now: current time for validation (can be overridden).
|
||||
* @param rrset: to be validated.
|
||||
* @param dnskey: DNSKEY rrset, keyset to try.
|
||||
* @param sig_idx: which signature to try to validate.
|
||||
* @param sortree: reused sorted order. Stored in region. Pass NULL at start,
|
||||
* and for a new rrset.
|
||||
* @param reason: if bogus, a string returned, fixed or alloced in scratch.
|
||||
* @param section: section of packet where this rrset comes from.
|
||||
* @param qstate: qstate with region.
|
||||
* @return secure if any key signs *this* signature. bogus if no key signs it,
|
||||
* or unchecked on error.
|
||||
*/
|
||||
enum sec_status dnskeyset_verify_rrset_sig(struct module_env* env,
|
||||
struct val_env* ve, time_t now, struct ub_packed_rrset_key* rrset,
|
||||
struct ub_packed_rrset_key* dnskey, size_t sig_idx,
|
||||
struct rbtree_type** sortree, char** reason, sldns_pkt_section section,
|
||||
struct module_qstate* qstate);
|
||||
|
||||
/**
|
||||
* verify rrset, with specific dnskey(from set), for a specific rrsig
|
||||
* @param region: scratch region used for temporary allocation.
|
||||
@ -323,17 +306,19 @@ enum sec_status dnskeyset_verify_rrset_sig(struct module_env* env,
|
||||
* pass false at start. pass old value only for same rrset and same
|
||||
* signature (but perhaps different key) for reuse.
|
||||
* @param reason: if bogus, a string returned, fixed or alloced in scratch.
|
||||
* @param reason_bogus: EDE (8914) code paired with the reason of failure.
|
||||
* @param section: section of packet where this rrset comes from.
|
||||
* @param qstate: qstate with region.
|
||||
* @return secure if this key signs this signature. unchecked on error or
|
||||
* bogus if it did not validate.
|
||||
*/
|
||||
enum sec_status dnskey_verify_rrset_sig(struct regional* region,
|
||||
struct sldns_buffer* buf, struct val_env* ve, time_t now,
|
||||
struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey,
|
||||
size_t dnskey_idx, size_t sig_idx,
|
||||
struct rbtree_type** sortree, int* buf_canon, char** reason,
|
||||
sldns_pkt_section section, struct module_qstate* qstate);
|
||||
struct sldns_buffer* buf, struct val_env* ve, time_t now,
|
||||
struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey,
|
||||
size_t dnskey_idx, size_t sig_idx,
|
||||
struct rbtree_type** sortree, int* buf_canon,
|
||||
char** reason, sldns_ede_code *reason_bogus,
|
||||
sldns_pkt_section section, struct module_qstate* qstate);
|
||||
|
||||
/**
|
||||
* canonical compare for two tree entries
|
||||
|
@ -332,11 +332,11 @@ rrset_get_ttl(struct ub_packed_rrset_key* rrset)
|
||||
return d->ttl;
|
||||
}
|
||||
|
||||
enum sec_status
|
||||
static enum sec_status
|
||||
val_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* keys,
|
||||
uint8_t* sigalg, char** reason, sldns_pkt_section section,
|
||||
struct module_qstate* qstate)
|
||||
uint8_t* sigalg, char** reason, sldns_ede_code *reason_bogus,
|
||||
sldns_pkt_section section, struct module_qstate* qstate)
|
||||
{
|
||||
enum sec_status sec;
|
||||
struct packed_rrset_data* d = (struct packed_rrset_data*)rrset->
|
||||
@ -359,7 +359,7 @@ val_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
log_nametypeclass(VERB_ALGO, "verify rrset", rrset->rk.dname,
|
||||
ntohs(rrset->rk.type), ntohs(rrset->rk.rrset_class));
|
||||
sec = dnskeyset_verify_rrset(env, ve, rrset, keys, sigalg, reason,
|
||||
section, qstate);
|
||||
reason_bogus, section, qstate);
|
||||
verbose(VERB_ALGO, "verify result: %s", sec_status_to_string(sec));
|
||||
regional_free_all(env->scratch);
|
||||
|
||||
@ -392,7 +392,8 @@ val_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
enum sec_status
|
||||
val_verify_rrset_entry(struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* rrset, struct key_entry_key* kkey,
|
||||
char** reason, sldns_pkt_section section, struct module_qstate* qstate)
|
||||
char** reason, sldns_ede_code *reason_bogus,
|
||||
sldns_pkt_section section, struct module_qstate* qstate)
|
||||
{
|
||||
/* temporary dnskey rrset-key */
|
||||
struct ub_packed_rrset_key dnskey;
|
||||
@ -406,7 +407,7 @@ val_verify_rrset_entry(struct module_env* env, struct val_env* ve,
|
||||
dnskey.entry.key = &dnskey;
|
||||
dnskey.entry.data = kd->rrset_data;
|
||||
sec = val_verify_rrset(env, ve, rrset, &dnskey, kd->algo, reason,
|
||||
section, qstate);
|
||||
reason_bogus, section, qstate);
|
||||
return sec;
|
||||
}
|
||||
|
||||
@ -415,7 +416,7 @@ static enum sec_status
|
||||
verify_dnskeys_with_ds_rr(struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* dnskey_rrset,
|
||||
struct ub_packed_rrset_key* ds_rrset, size_t ds_idx, char** reason,
|
||||
struct module_qstate* qstate)
|
||||
sldns_ede_code *reason_bogus, struct module_qstate* qstate)
|
||||
{
|
||||
enum sec_status sec = sec_status_bogus;
|
||||
size_t i, num, numchecked = 0, numhashok = 0, numsizesupp = 0;
|
||||
@ -450,8 +451,8 @@ verify_dnskeys_with_ds_rr(struct module_env* env, struct val_env* ve,
|
||||
|
||||
/* Otherwise, we have a match! Make sure that the DNSKEY
|
||||
* verifies *with this key* */
|
||||
sec = dnskey_verify_rrset(env, ve, dnskey_rrset,
|
||||
dnskey_rrset, i, reason, LDNS_SECTION_ANSWER, qstate);
|
||||
sec = dnskey_verify_rrset(env, ve, dnskey_rrset, dnskey_rrset,
|
||||
i, reason, reason_bogus, LDNS_SECTION_ANSWER, qstate);
|
||||
if(sec == sec_status_secure) {
|
||||
return sec;
|
||||
}
|
||||
@ -488,11 +489,12 @@ int val_favorite_ds_algo(struct ub_packed_rrset_key* ds_rrset)
|
||||
return digest_algo;
|
||||
}
|
||||
|
||||
// @TODO change the use of this function to _ede function in authzone.c:8111
|
||||
enum sec_status
|
||||
val_verify_DNSKEY_with_DS(struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* dnskey_rrset,
|
||||
struct ub_packed_rrset_key* ds_rrset, uint8_t* sigalg, char** reason,
|
||||
struct module_qstate* qstate)
|
||||
sldns_ede_code *reason_bogus, struct module_qstate* qstate)
|
||||
{
|
||||
/* as long as this is false, we can consider this DS rrset to be
|
||||
* equivalent to no DS rrset. */
|
||||
@ -529,7 +531,7 @@ val_verify_DNSKEY_with_DS(struct module_env* env, struct val_env* ve,
|
||||
}
|
||||
|
||||
sec = verify_dnskeys_with_ds_rr(env, ve, dnskey_rrset,
|
||||
ds_rrset, i, reason, qstate);
|
||||
ds_rrset, i, reason, reason_bogus, qstate);
|
||||
if(sec == sec_status_insecure)
|
||||
continue;
|
||||
|
||||
@ -575,11 +577,12 @@ struct key_entry_key*
|
||||
val_verify_new_DNSKEYs(struct regional* region, struct module_env* env,
|
||||
struct val_env* ve, struct ub_packed_rrset_key* dnskey_rrset,
|
||||
struct ub_packed_rrset_key* ds_rrset, int downprot, char** reason,
|
||||
struct module_qstate* qstate)
|
||||
sldns_ede_code *reason_bogus, struct module_qstate* qstate)
|
||||
{
|
||||
uint8_t sigalg[ALGO_NEEDS_MAX+1];
|
||||
enum sec_status sec = val_verify_DNSKEY_with_DS(env, ve,
|
||||
dnskey_rrset, ds_rrset, downprot?sigalg:NULL, reason, qstate);
|
||||
dnskey_rrset, ds_rrset, downprot?sigalg:NULL, reason,
|
||||
reason_bogus, qstate);
|
||||
|
||||
if(sec == sec_status_secure) {
|
||||
return key_entry_create_rrset(region,
|
||||
@ -602,7 +605,7 @@ val_verify_DNSKEY_with_TA(struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* dnskey_rrset,
|
||||
struct ub_packed_rrset_key* ta_ds,
|
||||
struct ub_packed_rrset_key* ta_dnskey, uint8_t* sigalg, char** reason,
|
||||
struct module_qstate* qstate)
|
||||
sldns_ede_code *reason_bogus, struct module_qstate* qstate)
|
||||
{
|
||||
/* as long as this is false, we can consider this anchor to be
|
||||
* equivalent to no anchor. */
|
||||
@ -617,6 +620,8 @@ val_verify_DNSKEY_with_TA(struct module_env* env, struct val_env* ve,
|
||||
verbose(VERB_QUERY, "DNSKEY RRset did not match DS RRset "
|
||||
"by name");
|
||||
*reason = "DNSKEY RRset did not match DS RRset by name";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_DNSKEY_MISSING;
|
||||
return sec_status_bogus;
|
||||
}
|
||||
if(ta_dnskey && (dnskey_rrset->rk.dname_len != ta_dnskey->rk.dname_len
|
||||
@ -625,6 +630,8 @@ val_verify_DNSKEY_with_TA(struct module_env* env, struct val_env* ve,
|
||||
verbose(VERB_QUERY, "DNSKEY RRset did not match anchor RRset "
|
||||
"by name");
|
||||
*reason = "DNSKEY RRset did not match anchor RRset by name";
|
||||
if(reason_bogus)
|
||||
*reason_bogus = LDNS_EDE_DNSKEY_MISSING;
|
||||
return sec_status_bogus;
|
||||
}
|
||||
|
||||
@ -648,7 +655,7 @@ val_verify_DNSKEY_with_TA(struct module_env* env, struct val_env* ve,
|
||||
continue;
|
||||
|
||||
sec = verify_dnskeys_with_ds_rr(env, ve, dnskey_rrset,
|
||||
ta_ds, i, reason, qstate);
|
||||
ta_ds, i, reason, reason_bogus, qstate);
|
||||
if(sec == sec_status_insecure)
|
||||
continue;
|
||||
|
||||
@ -688,7 +695,7 @@ val_verify_DNSKEY_with_TA(struct module_env* env, struct val_env* ve,
|
||||
has_useful_ta = 1;
|
||||
|
||||
sec = dnskey_verify_rrset(env, ve, dnskey_rrset,
|
||||
ta_dnskey, i, reason, LDNS_SECTION_ANSWER, qstate);
|
||||
ta_dnskey, i, reason, NULL, LDNS_SECTION_ANSWER, qstate);
|
||||
if(sec == sec_status_secure) {
|
||||
if(!sigalg || algo_needs_set_secure(&needs,
|
||||
(uint8_t)dnskey_get_algo(ta_dnskey, i))) {
|
||||
@ -726,12 +733,12 @@ val_verify_new_DNSKEYs_with_ta(struct regional* region, struct module_env* env,
|
||||
struct val_env* ve, struct ub_packed_rrset_key* dnskey_rrset,
|
||||
struct ub_packed_rrset_key* ta_ds_rrset,
|
||||
struct ub_packed_rrset_key* ta_dnskey_rrset, int downprot,
|
||||
char** reason, struct module_qstate* qstate)
|
||||
char** reason, sldns_ede_code *reason_bogus, struct module_qstate* qstate)
|
||||
{
|
||||
uint8_t sigalg[ALGO_NEEDS_MAX+1];
|
||||
enum sec_status sec = val_verify_DNSKEY_with_TA(env, ve,
|
||||
dnskey_rrset, ta_ds_rrset, ta_dnskey_rrset,
|
||||
downprot?sigalg:NULL, reason, qstate);
|
||||
downprot?sigalg:NULL, reason, reason_bogus, qstate);
|
||||
|
||||
if(sec == sec_status_secure) {
|
||||
return key_entry_create_rrset(region,
|
||||
@ -776,6 +783,7 @@ val_dsset_isusable(struct ub_packed_rrset_key* ds_rrset)
|
||||
if(lt) snprintf(aerr, sizeof(aerr), "%s", lt->name);
|
||||
else snprintf(aerr, sizeof(aerr), "%d",
|
||||
(int)ds_get_key_algo(ds_rrset, 0));
|
||||
|
||||
verbose(VERB_ALGO, "DS unsupported, hash %s %s, "
|
||||
"key algorithm %s %s", herr,
|
||||
(ds_digest_algo_is_supported(ds_rrset, 0)?
|
||||
|
@ -43,6 +43,7 @@
|
||||
#define VALIDATOR_VAL_UTILS_H
|
||||
#include "util/data/packed_rrset.h"
|
||||
#include "sldns/pkthdr.h"
|
||||
#include "sldns/rrdef.h"
|
||||
struct query_info;
|
||||
struct reply_info;
|
||||
struct val_env;
|
||||
@ -113,24 +114,6 @@ void val_find_signer(enum val_classification subtype,
|
||||
struct query_info* qinf, struct reply_info* rep,
|
||||
size_t cname_skip, uint8_t** signer_name, size_t* signer_len);
|
||||
|
||||
/**
|
||||
* Verify RRset with keys
|
||||
* @param env: module environment (scratch buffer)
|
||||
* @param ve: validator environment (verification settings)
|
||||
* @param rrset: what to verify
|
||||
* @param keys: dnskey rrset to verify with.
|
||||
* @param sigalg: if nonNULL provide downgrade protection otherwise one
|
||||
* algorithm is enough. Algo list is constructed in here.
|
||||
* @param reason: reason of failure. Fixed string or alloced in scratch.
|
||||
* @param section: section of packet where this rrset comes from.
|
||||
* @param qstate: qstate with region.
|
||||
* @return security status of verification.
|
||||
*/
|
||||
enum sec_status val_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* keys,
|
||||
uint8_t* sigalg, char** reason, sldns_pkt_section section,
|
||||
struct module_qstate* qstate);
|
||||
|
||||
/**
|
||||
* Verify RRset with keys from a keyset.
|
||||
* @param env: module environment (scratch buffer)
|
||||
@ -138,14 +121,15 @@ enum sec_status val_verify_rrset(struct module_env* env, struct val_env* ve,
|
||||
* @param rrset: what to verify
|
||||
* @param kkey: key_entry to verify with.
|
||||
* @param reason: reason of failure. Fixed string or alloced in scratch.
|
||||
* @param reason_bogus: EDE (RFC8914) code paired with the reason of failure.
|
||||
* @param section: section of packet where this rrset comes from.
|
||||
* @param qstate: qstate with region.
|
||||
* @return security status of verification.
|
||||
*/
|
||||
enum sec_status val_verify_rrset_entry(struct module_env* env,
|
||||
struct val_env* ve, struct ub_packed_rrset_key* rrset,
|
||||
struct key_entry_key* kkey, char** reason, sldns_pkt_section section,
|
||||
struct module_qstate* qstate);
|
||||
struct key_entry_key* kkey, char** reason, sldns_ede_code *reason_bogus,
|
||||
sldns_pkt_section section, struct module_qstate* qstate);
|
||||
|
||||
/**
|
||||
* Verify DNSKEYs with DS rrset. Like val_verify_new_DNSKEYs but
|
||||
@ -158,15 +142,16 @@ enum sec_status val_verify_rrset_entry(struct module_env* env,
|
||||
* algorithm is enough. The list of signalled algorithms is returned,
|
||||
* must have enough space for ALGO_NEEDS_MAX+1.
|
||||
* @param reason: reason of failure. Fixed string or alloced in scratch.
|
||||
* @param reason_bogus: EDE (RFC8914) code paired with the reason of failure.
|
||||
* @param qstate: qstate with region.
|
||||
* @return: sec_status_secure if a DS matches.
|
||||
* sec_status_insecure if end of trust (i.e., unknown algorithms).
|
||||
* sec_status_bogus if it fails.
|
||||
*/
|
||||
enum sec_status val_verify_DNSKEY_with_DS(struct module_env* env,
|
||||
struct val_env* ve, struct ub_packed_rrset_key* dnskey_rrset,
|
||||
struct ub_packed_rrset_key* ds_rrset, uint8_t* sigalg, char** reason,
|
||||
struct module_qstate* qstate);
|
||||
struct val_env* ve, struct ub_packed_rrset_key* dnskey_rrset,
|
||||
struct ub_packed_rrset_key* ds_rrset, uint8_t* sigalg, char** reason,
|
||||
sldns_ede_code *reason_bogus, struct module_qstate* qstate);
|
||||
|
||||
/**
|
||||
* Verify DNSKEYs with DS and DNSKEY rrset. Like val_verify_DNSKEY_with_DS
|
||||
@ -180,16 +165,17 @@ enum sec_status val_verify_DNSKEY_with_DS(struct module_env* env,
|
||||
* algorithm is enough. The list of signalled algorithms is returned,
|
||||
* must have enough space for ALGO_NEEDS_MAX+1.
|
||||
* @param reason: reason of failure. Fixed string or alloced in scratch.
|
||||
* @param reason_bogus: EDE (RFC8914) code paired with the reason of failure.
|
||||
* @param qstate: qstate with region.
|
||||
* @return: sec_status_secure if a DS matches.
|
||||
* sec_status_insecure if end of trust (i.e., unknown algorithms).
|
||||
* sec_status_bogus if it fails.
|
||||
*/
|
||||
enum sec_status val_verify_DNSKEY_with_TA(struct module_env* env,
|
||||
struct val_env* ve, struct ub_packed_rrset_key* dnskey_rrset,
|
||||
struct ub_packed_rrset_key* ta_ds,
|
||||
struct ub_packed_rrset_key* ta_dnskey, uint8_t* sigalg, char** reason,
|
||||
struct module_qstate* qstate);
|
||||
struct val_env* ve, struct ub_packed_rrset_key* dnskey_rrset,
|
||||
struct ub_packed_rrset_key* ta_ds,
|
||||
struct ub_packed_rrset_key* ta_dnskey, uint8_t* sigalg, char** reason,
|
||||
sldns_ede_code *reason_bogus, struct module_qstate* qstate);
|
||||
|
||||
/**
|
||||
* Verify new DNSKEYs with DS rrset. The DS contains hash values that should
|
||||
@ -204,6 +190,7 @@ enum sec_status val_verify_DNSKEY_with_TA(struct module_env* env,
|
||||
* @param downprot: if true provide downgrade protection otherwise one
|
||||
* algorithm is enough.
|
||||
* @param reason: reason of failure. Fixed string or alloced in scratch.
|
||||
* @param reason_bogus: EDE (RFC8914) code paired with the reason of failure.
|
||||
* @param qstate: qstate with region.
|
||||
* @return a KeyEntry. This will either contain the now trusted
|
||||
* dnskey_rrset, a "null" key entry indicating that this DS
|
||||
@ -216,11 +203,10 @@ enum sec_status val_verify_DNSKEY_with_TA(struct module_env* env,
|
||||
* if downprot is set, a key entry with an algo list is made.
|
||||
*/
|
||||
struct key_entry_key* val_verify_new_DNSKEYs(struct regional* region,
|
||||
struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* dnskey_rrset,
|
||||
struct ub_packed_rrset_key* ds_rrset, int downprot, char** reason,
|
||||
struct module_qstate* qstate);
|
||||
|
||||
struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* dnskey_rrset,
|
||||
struct ub_packed_rrset_key* ds_rrset, int downprot, char** reason,
|
||||
sldns_ede_code *reason_bogus, struct module_qstate* qstate);
|
||||
|
||||
/**
|
||||
* Verify rrset with trust anchor: DS and DNSKEY rrset.
|
||||
@ -234,6 +220,7 @@ struct key_entry_key* val_verify_new_DNSKEYs(struct regional* region,
|
||||
* @param downprot: if true provide downgrade protection otherwise one
|
||||
* algorithm is enough.
|
||||
* @param reason: reason of failure. Fixed string or alloced in scratch.
|
||||
* @param reason_bogus: EDE (RFC8914) code paired with the reason of failure.
|
||||
* @param qstate: qstate with region.
|
||||
* @return a KeyEntry. This will either contain the now trusted
|
||||
* dnskey_rrset, a "null" key entry indicating that this DS
|
||||
@ -246,11 +233,11 @@ struct key_entry_key* val_verify_new_DNSKEYs(struct regional* region,
|
||||
* if downprot is set, a key entry with an algo list is made.
|
||||
*/
|
||||
struct key_entry_key* val_verify_new_DNSKEYs_with_ta(struct regional* region,
|
||||
struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* dnskey_rrset,
|
||||
struct ub_packed_rrset_key* ta_ds_rrset,
|
||||
struct ub_packed_rrset_key* ta_dnskey_rrset,
|
||||
int downprot, char** reason, struct module_qstate* qstate);
|
||||
struct module_env* env, struct val_env* ve,
|
||||
struct ub_packed_rrset_key* dnskey_rrset,
|
||||
struct ub_packed_rrset_key* ta_ds_rrset,
|
||||
struct ub_packed_rrset_key* ta_dnskey_rrset, int downprot,
|
||||
char** reason, sldns_ede_code *reason_bogus, struct module_qstate* qstate);
|
||||
|
||||
/**
|
||||
* Determine if DS rrset is usable for validator or not.
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user