mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-08-17 21:25:50 +02:00
Compare commits
153
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
75b6dba593 | ||
|
|
138fb48eac | ||
|
|
dae7a37974 | ||
|
|
8ae4b4545d | ||
|
|
c343fff3a4 | ||
|
|
a794c87578 | ||
|
|
ef5ca84360 | ||
|
|
8d8fa42266 | ||
|
|
a587535c5d | ||
|
|
94d5babaee | ||
|
|
fe946ba4e9 | ||
|
|
6a31e470f8 | ||
|
|
e577695aeb | ||
|
|
25fe602024 | ||
|
|
df0e86de49 | ||
|
|
e49b550cf3 | ||
|
|
07c96792f2 | ||
|
|
84ab430e11 | ||
|
|
53499e4a88 | ||
|
|
8a25a97687 | ||
|
|
c112bcf2fd | ||
|
|
9de549c498 | ||
|
|
84c645e7b3 | ||
|
|
197a425c7d | ||
|
|
311054728d | ||
|
|
6d74856212 | ||
|
|
d489e6027e | ||
|
|
e1d146d6b0 | ||
|
|
eb2fe8df8d | ||
|
|
86a8be75f0 | ||
|
|
52fc5ee374 | ||
|
|
82359c8fb1 | ||
|
|
c996671a1f | ||
|
|
e233a1ef65 | ||
|
|
06ff9f20d0 | ||
|
|
af209a12ea | ||
|
|
84ac7e1b58 | ||
|
|
24d502763c | ||
|
|
99c61c19ac | ||
|
|
cb05e9d525 | ||
|
|
abddd4e270 | ||
|
|
656b412492 | ||
|
|
f15a46fcd4 | ||
|
|
8d434bf744 | ||
|
|
13b269d398 | ||
|
|
7aff88881a | ||
|
|
b97bd3a1fc | ||
|
|
6aa5ad85f4 | ||
|
|
42b19c20c1 | ||
|
|
db1fe8b475 | ||
|
|
f4f964f4fb | ||
|
|
a2272860de | ||
|
|
95083d4377 | ||
|
|
5ce0bf5281 | ||
|
|
6a0d5e2cb1 | ||
|
|
330d5211c9 | ||
|
|
2dc28a249a | ||
|
|
c5f14dc880 | ||
|
|
a2ace114de | ||
|
|
2e9b880718 | ||
|
|
a0ec6cd946 | ||
|
|
ea36979c40 | ||
|
|
315077b9e6 | ||
|
|
535d899bef | ||
|
|
8656cfd4c8 | ||
|
|
8f44ddb7de | ||
|
|
4484dc3954 | ||
|
|
eb3bba0724 | ||
|
|
2eff1d8ab5 | ||
|
|
4672fa5b53 | ||
|
|
18029fc44f | ||
|
|
5c6f56f8f1 | ||
|
|
9af29c3ed1 | ||
|
|
76ef8c5803 | ||
|
|
94ef1a8fee | ||
|
|
683241a2f5 | ||
|
|
92ab54641e | ||
|
|
da3812953a | ||
|
|
1bd7c8dfee | ||
|
|
8f96ae7acf | ||
|
|
c4f8e60c85 | ||
|
|
a296b248b0 | ||
|
|
1ef131299a | ||
|
|
5b58a872ef | ||
|
|
94b04d6d46 | ||
|
|
f1a65eb4e8 | ||
|
|
38e1e3eec3 | ||
|
|
bff3d762ff | ||
|
|
fb322f3e87 | ||
|
|
2feee13735 | ||
|
|
1d36696462 | ||
|
|
aa4e2a9e69 | ||
|
|
8e04d04949 | ||
|
|
c5627dbd52 | ||
|
|
014ed9c5ff | ||
|
|
16e1e6d375 | ||
|
|
1a9a4e4ca1 | ||
|
|
f7f638e18f | ||
|
|
c956aea93d | ||
|
|
4556a4f490 | ||
|
|
1cdddf0fe9 | ||
|
|
18fec256b7 | ||
|
|
567c70dada | ||
|
|
8b4b2a88f7 | ||
|
|
faf40c97fc | ||
|
|
daa016e3e4 | ||
|
|
039f69e735 | ||
|
|
b39009e487 | ||
|
|
933769ee73 | ||
|
|
57bff79627 | ||
|
|
1b5559d534 | ||
|
|
9d271c5343 | ||
|
|
74cc49e6c4 | ||
|
|
d414ebf0c7 | ||
|
|
9b123d1b78 | ||
|
|
37b71261a2 | ||
|
|
4426db4d3d | ||
|
|
fe10bc7682 | ||
|
|
67d2eae28c | ||
|
|
9010a7075e | ||
|
|
cc6dbc9f38 | ||
|
|
4198343dbe | ||
|
|
08600d68e8 | ||
|
|
18e098285e | ||
|
|
f1b35bab4b | ||
|
|
84ed77238d | ||
|
|
adb0374a4d | ||
|
|
b0b634558b | ||
|
|
8546247292 | ||
|
|
44659cb3bf | ||
|
|
a1ac2d0252 | ||
|
|
5c7a26b615 | ||
|
|
09d352b917 | ||
|
|
c0522043f0 | ||
|
|
b858801feb | ||
|
|
588db09928 | ||
|
|
5c66c48a1b | ||
|
|
83336477c6 | ||
|
|
e3e5eb66cf | ||
|
|
00d3b97dbb | ||
|
|
f6269baa60 | ||
|
|
19154c6e58 | ||
|
|
0f43b0ea6c | ||
|
|
e6d92f458f | ||
|
|
a31b9d50e2 | ||
|
|
fceb4e8585 | ||
|
|
98f4257890 | ||
|
|
0a15118aff | ||
|
|
e887a79a92 | ||
|
|
f9b9050ab8 | ||
|
|
94735384fd | ||
|
|
5dab0609e5 | ||
|
|
024c921dbf |
@@ -173,7 +173,7 @@ jobs:
|
||||
cross_platform_config: "--enable-debug --disable-flto --with-libevent --disable-static"
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
submodules: false
|
||||
persist-credentials: false
|
||||
@@ -189,6 +189,8 @@ jobs:
|
||||
cd ..
|
||||
export prepath=`pwd`
|
||||
echo prepath=${prepath}
|
||||
# parralel build option
|
||||
export MINJ="-j4"
|
||||
echo "choco install winflexbison3"
|
||||
choco install winflexbison3
|
||||
echo 'LEX="win_flex"'
|
||||
@@ -211,8 +213,8 @@ jobs:
|
||||
C:/msys64/usr/bin/perl ./Configure no-shared no-asm -DOPENSSL_NO_CAPIENG mingw64 --prefix="$prepath/openssl" PERL="C:/msys64/usr/bin/perl"
|
||||
# make the libs only, build faster
|
||||
echo "make build_libs"
|
||||
#make
|
||||
make build_libs
|
||||
#make $MINJ
|
||||
make $MINJ build_libs
|
||||
mv Makefile Makefile.orig
|
||||
# fixup \\ in the installtop to /.
|
||||
echo "fixup INSTALLTOP"
|
||||
@@ -244,7 +246,7 @@ jobs:
|
||||
mv xmlwf/Makefile xmlwf/Makefile.orig
|
||||
sed -e 's/SHELL/SHELLZZ/g' < xmlwf/Makefile.orig > xmlwf/Makefile
|
||||
echo "make"
|
||||
make
|
||||
make $MINJ
|
||||
echo "make install"
|
||||
make install
|
||||
cd ..
|
||||
@@ -252,7 +254,7 @@ jobs:
|
||||
cd unbound
|
||||
echo "./configure --enable-debug --enable-static-exe --disable-flto \"--with-ssl=$prepath/openssl\" --with-libexpat=\"$prepath/expat\" --disable-shared"
|
||||
./configure --enable-debug --enable-static-exe --disable-flto "--with-ssl=$prepath/openssl" --with-libexpat="$prepath/expat" --disable-shared
|
||||
make
|
||||
make $MINJ
|
||||
# specific test output
|
||||
#make testbound.exe; ./testbound.exe -s
|
||||
#make testbound; ./testbound.exe -p testdata/acl.rpl -o -vvvv
|
||||
@@ -347,7 +349,7 @@ jobs:
|
||||
echo "::endgroup::"
|
||||
- name: cross-platform-action on ${{ matrix.cross_platform_os }} ${{ matrix.cross_platform_version }}
|
||||
if: ${{ matrix.with_cross_platform_action == 'yes' }}
|
||||
uses: cross-platform-actions/action@v0.25.0
|
||||
uses: cross-platform-actions/action@v1.0.0
|
||||
env:
|
||||
CROSS_PLATFORM_OS: ${{ matrix.cross_platform_os }}
|
||||
with:
|
||||
|
||||
@@ -12,7 +12,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: configure
|
||||
|
||||
+556
-407
File diff suppressed because it is too large
Load Diff
Vendored
+146
-202
@@ -1,6 +1,6 @@
|
||||
# generated automatically by aclocal 1.16.5 -*- Autoconf -*-
|
||||
# generated automatically by aclocal 1.16.2 -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1996-2021 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1996-2020 Free Software Foundation, Inc.
|
||||
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@@ -14,8 +14,7 @@
|
||||
m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
|
||||
# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
|
||||
#
|
||||
# Copyright (C) 1996-2001, 2003-2019, 2021-2022 Free Software
|
||||
# Foundation, Inc.
|
||||
# Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc.
|
||||
# Written by Gordon Matzigkeit, 1996
|
||||
#
|
||||
# This file is free software; the Free Software Foundation gives
|
||||
@@ -46,7 +45,7 @@ m4_define([_LT_COPYING], [dnl
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
])
|
||||
|
||||
# serial 59 LT_INIT
|
||||
# serial 58 LT_INIT
|
||||
|
||||
|
||||
# LT_PREREQ(VERSION)
|
||||
@@ -196,7 +195,6 @@ m4_require([_LT_FILEUTILS_DEFAULTS])dnl
|
||||
m4_require([_LT_CHECK_SHELL_FEATURES])dnl
|
||||
m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl
|
||||
m4_require([_LT_CMD_RELOAD])dnl
|
||||
m4_require([_LT_DECL_FILECMD])dnl
|
||||
m4_require([_LT_CHECK_MAGIC_METHOD])dnl
|
||||
m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl
|
||||
m4_require([_LT_CMD_OLD_ARCHIVE])dnl
|
||||
@@ -235,8 +233,8 @@ esac
|
||||
ofile=libtool
|
||||
can_build_shared=yes
|
||||
|
||||
# All known linkers require a '.a' archive for static linking (except MSVC and
|
||||
# ICC, which need '.lib').
|
||||
# All known linkers require a '.a' archive for static linking (except MSVC,
|
||||
# which needs '.lib').
|
||||
libext=a
|
||||
|
||||
with_gnu_ld=$lt_cv_prog_gnu_ld
|
||||
@@ -738,6 +736,7 @@ _LT_CONFIG_SAVE_COMMANDS([
|
||||
cat <<_LT_EOF >> "$cfgfile"
|
||||
#! $SHELL
|
||||
# Generated automatically by $as_me ($PACKAGE) $VERSION
|
||||
# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
|
||||
# NOTE: Changes made to this file will be lost: look at ltmain.sh.
|
||||
|
||||
# Provide generalized library-building support services.
|
||||
@@ -787,7 +786,7 @@ _LT_EOF
|
||||
# if finds mixed CR/LF and LF-only lines. Since sed operates in
|
||||
# text mode, it properly converts lines to CR/LF. This bash problem
|
||||
# is reportedly fixed, but why not run on old versions too?
|
||||
$SED '$q' "$ltmain" >> "$cfgfile" \
|
||||
sed '$q' "$ltmain" >> "$cfgfile" \
|
||||
|| (rm -f "$cfgfile"; exit 1)
|
||||
|
||||
mv -f "$cfgfile" "$ofile" ||
|
||||
@@ -1049,8 +1048,8 @@ int forced_loaded() { return 2;}
|
||||
_LT_EOF
|
||||
echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD
|
||||
$LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD
|
||||
echo "$AR $AR_FLAGS libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
|
||||
$AR $AR_FLAGS libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
|
||||
echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
|
||||
$AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
|
||||
echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD
|
||||
$RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD
|
||||
cat > conftest.c << _LT_EOF
|
||||
@@ -1074,12 +1073,17 @@ _LT_EOF
|
||||
_lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;;
|
||||
darwin1.*)
|
||||
_lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
|
||||
darwin*)
|
||||
case $MACOSX_DEPLOYMENT_TARGET,$host in
|
||||
10.[[012]],*|,*powerpc*-darwin[[5-8]]*)
|
||||
_lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
|
||||
*)
|
||||
_lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
|
||||
darwin*) # darwin 5.x on
|
||||
# if running on 10.5 or later, the deployment target defaults
|
||||
# to the OS version, if on x86, and 10.4, the deployment
|
||||
# target defaults to 10.4. Don't you love it?
|
||||
case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
|
||||
10.0,*86*-darwin8*|10.0,*-darwin[[91]]*)
|
||||
_lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
|
||||
10.[[012]][[,.]]*)
|
||||
_lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;;
|
||||
10.*)
|
||||
_lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
@@ -1128,12 +1132,12 @@ m4_defun([_LT_DARWIN_LINKER_FEATURES],
|
||||
output_verbose_link_cmd=func_echo_all
|
||||
_LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil"
|
||||
_LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil"
|
||||
_LT_TAGVAR(archive_expsym_cmds, $1)="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"
|
||||
_LT_TAGVAR(module_expsym_cmds, $1)="$SED -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil"
|
||||
_LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil"
|
||||
_LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil"
|
||||
m4_if([$1], [CXX],
|
||||
[ if test yes != "$lt_cv_apple_cc_single_mod"; then
|
||||
_LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil"
|
||||
_LT_TAGVAR(archive_expsym_cmds, $1)="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil"
|
||||
_LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil"
|
||||
fi
|
||||
],[])
|
||||
else
|
||||
@@ -1247,8 +1251,7 @@ _LT_DECL([], [ECHO], [1], [An echo program that protects backslashes])
|
||||
# _LT_WITH_SYSROOT
|
||||
# ----------------
|
||||
AC_DEFUN([_LT_WITH_SYSROOT],
|
||||
[m4_require([_LT_DECL_SED])dnl
|
||||
AC_MSG_CHECKING([for sysroot])
|
||||
[AC_MSG_CHECKING([for sysroot])
|
||||
AC_ARG_WITH([sysroot],
|
||||
[AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@],
|
||||
[Search for dependent libraries within DIR (or the compiler's sysroot
|
||||
@@ -1265,7 +1268,7 @@ case $with_sysroot in #(
|
||||
fi
|
||||
;; #(
|
||||
/*)
|
||||
lt_sysroot=`echo "$with_sysroot" | $SED -e "$sed_quote_subst"`
|
||||
lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
|
||||
;; #(
|
||||
no|'')
|
||||
;; #(
|
||||
@@ -1295,7 +1298,7 @@ ia64-*-hpux*)
|
||||
# options accordingly.
|
||||
echo 'int i;' > conftest.$ac_ext
|
||||
if AC_TRY_EVAL(ac_compile); then
|
||||
case `$FILECMD conftest.$ac_objext` in
|
||||
case `/usr/bin/file conftest.$ac_objext` in
|
||||
*ELF-32*)
|
||||
HPUX_IA64_MODE=32
|
||||
;;
|
||||
@@ -1312,7 +1315,7 @@ ia64-*-hpux*)
|
||||
echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
|
||||
if AC_TRY_EVAL(ac_compile); then
|
||||
if test yes = "$lt_cv_prog_gnu_ld"; then
|
||||
case `$FILECMD conftest.$ac_objext` in
|
||||
case `/usr/bin/file conftest.$ac_objext` in
|
||||
*32-bit*)
|
||||
LD="${LD-ld} -melf32bsmip"
|
||||
;;
|
||||
@@ -1324,7 +1327,7 @@ ia64-*-hpux*)
|
||||
;;
|
||||
esac
|
||||
else
|
||||
case `$FILECMD conftest.$ac_objext` in
|
||||
case `/usr/bin/file conftest.$ac_objext` in
|
||||
*32-bit*)
|
||||
LD="${LD-ld} -32"
|
||||
;;
|
||||
@@ -1346,7 +1349,7 @@ mips64*-*linux*)
|
||||
echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
|
||||
if AC_TRY_EVAL(ac_compile); then
|
||||
emul=elf
|
||||
case `$FILECMD conftest.$ac_objext` in
|
||||
case `/usr/bin/file conftest.$ac_objext` in
|
||||
*32-bit*)
|
||||
emul="${emul}32"
|
||||
;;
|
||||
@@ -1354,7 +1357,7 @@ mips64*-*linux*)
|
||||
emul="${emul}64"
|
||||
;;
|
||||
esac
|
||||
case `$FILECMD conftest.$ac_objext` in
|
||||
case `/usr/bin/file conftest.$ac_objext` in
|
||||
*MSB*)
|
||||
emul="${emul}btsmip"
|
||||
;;
|
||||
@@ -1362,7 +1365,7 @@ mips64*-*linux*)
|
||||
emul="${emul}ltsmip"
|
||||
;;
|
||||
esac
|
||||
case `$FILECMD conftest.$ac_objext` in
|
||||
case `/usr/bin/file conftest.$ac_objext` in
|
||||
*N32*)
|
||||
emul="${emul}n32"
|
||||
;;
|
||||
@@ -1382,14 +1385,14 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
|
||||
# not appear in the list.
|
||||
echo 'int i;' > conftest.$ac_ext
|
||||
if AC_TRY_EVAL(ac_compile); then
|
||||
case `$FILECMD conftest.o` in
|
||||
case `/usr/bin/file conftest.o` in
|
||||
*32-bit*)
|
||||
case $host in
|
||||
x86_64-*kfreebsd*-gnu)
|
||||
LD="${LD-ld} -m elf_i386_fbsd"
|
||||
;;
|
||||
x86_64-*linux*)
|
||||
case `$FILECMD conftest.o` in
|
||||
case `/usr/bin/file conftest.o` in
|
||||
*x86-64*)
|
||||
LD="${LD-ld} -m elf32_x86_64"
|
||||
;;
|
||||
@@ -1457,7 +1460,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
|
||||
# options accordingly.
|
||||
echo 'int i;' > conftest.$ac_ext
|
||||
if AC_TRY_EVAL(ac_compile); then
|
||||
case `$FILECMD conftest.o` in
|
||||
case `/usr/bin/file conftest.o` in
|
||||
*64-bit*)
|
||||
case $lt_cv_prog_gnu_ld in
|
||||
yes*)
|
||||
@@ -1496,22 +1499,9 @@ need_locks=$enable_libtool_lock
|
||||
m4_defun([_LT_PROG_AR],
|
||||
[AC_CHECK_TOOLS(AR, [ar], false)
|
||||
: ${AR=ar}
|
||||
: ${AR_FLAGS=cru}
|
||||
_LT_DECL([], [AR], [1], [The archiver])
|
||||
|
||||
# Use ARFLAGS variable as AR's operation code to sync the variable naming with
|
||||
# Automake. If both AR_FLAGS and ARFLAGS are specified, AR_FLAGS should have
|
||||
# higher priority because thats what people were doing historically (setting
|
||||
# ARFLAGS for automake and AR_FLAGS for libtool). FIXME: Make the AR_FLAGS
|
||||
# variable obsoleted/removed.
|
||||
|
||||
test ${AR_FLAGS+y} || AR_FLAGS=${ARFLAGS-cr}
|
||||
lt_ar_flags=$AR_FLAGS
|
||||
_LT_DECL([], [lt_ar_flags], [0], [Flags to create an archive (by configure)])
|
||||
|
||||
# Make AR_FLAGS overridable by 'make ARFLAGS='. Don't try to run-time override
|
||||
# by AR_FLAGS because that was never working and AR_FLAGS is about to die.
|
||||
_LT_DECL([], [AR_FLAGS], [\@S|@{ARFLAGS-"\@S|@lt_ar_flags"}],
|
||||
[Flags to create an archive])
|
||||
_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive])
|
||||
|
||||
AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file],
|
||||
[lt_cv_ar_at_file=no
|
||||
@@ -1730,7 +1720,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
|
||||
lt_cv_sys_max_cmd_len=8192;
|
||||
;;
|
||||
|
||||
bitrig* | darwin* | dragonfly* | freebsd* | midnightbsd* | netbsd* | openbsd*)
|
||||
bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*)
|
||||
# This has been around since 386BSD, at least. Likely further.
|
||||
if test -x /sbin/sysctl; then
|
||||
lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
|
||||
@@ -1773,7 +1763,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
|
||||
sysv5* | sco5v6* | sysv4.2uw2*)
|
||||
kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
|
||||
if test -n "$kargmax"; then
|
||||
lt_cv_sys_max_cmd_len=`echo $kargmax | $SED 's/.*[[ ]]//'`
|
||||
lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'`
|
||||
else
|
||||
lt_cv_sys_max_cmd_len=32768
|
||||
fi
|
||||
@@ -2223,35 +2213,26 @@ m4_defun([_LT_CMD_STRIPLIB],
|
||||
striplib=
|
||||
old_striplib=
|
||||
AC_MSG_CHECKING([whether stripping libraries is possible])
|
||||
if test -z "$STRIP"; then
|
||||
AC_MSG_RESULT([no])
|
||||
if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
|
||||
test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
|
||||
test -z "$striplib" && striplib="$STRIP --strip-unneeded"
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
if $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
|
||||
old_striplib="$STRIP --strip-debug"
|
||||
striplib="$STRIP --strip-unneeded"
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
case $host_os in
|
||||
darwin*)
|
||||
# FIXME - insert some real tests, host_os isn't really good enough
|
||||
# FIXME - insert some real tests, host_os isn't really good enough
|
||||
case $host_os in
|
||||
darwin*)
|
||||
if test -n "$STRIP"; then
|
||||
striplib="$STRIP -x"
|
||||
old_striplib="$STRIP -S"
|
||||
AC_MSG_RESULT([yes])
|
||||
;;
|
||||
freebsd*)
|
||||
if $STRIP -V 2>&1 | $GREP "elftoolchain" >/dev/null; then
|
||||
old_striplib="$STRIP --strip-debug"
|
||||
striplib="$STRIP --strip-unneeded"
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
AC_MSG_RESULT([no])
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
_LT_DECL([], [old_striplib], [1], [Commands to strip libraries])
|
||||
_LT_DECL([], [striplib], [1])
|
||||
@@ -2574,7 +2555,7 @@ cygwin* | mingw* | pw32* | cegcc*)
|
||||
case $host_os in
|
||||
cygwin*)
|
||||
# Cygwin DLLs use 'cyg' prefix rather than 'lib'
|
||||
soname_spec='`echo $libname | $SED -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
|
||||
soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
|
||||
m4_if([$1], [],[
|
||||
sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"])
|
||||
;;
|
||||
@@ -2584,14 +2565,14 @@ m4_if([$1], [],[
|
||||
;;
|
||||
pw32*)
|
||||
# pw32 DLLs use 'pw' prefix rather than 'lib'
|
||||
library_names_spec='`echo $libname | $SED -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
|
||||
library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
|
||||
;;
|
||||
esac
|
||||
dynamic_linker='Win32 ld.exe'
|
||||
;;
|
||||
|
||||
*,cl* | *,icl*)
|
||||
# Native MSVC or ICC
|
||||
*,cl*)
|
||||
# Native MSVC
|
||||
libname_spec='$name'
|
||||
soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext'
|
||||
library_names_spec='$libname.dll.lib'
|
||||
@@ -2610,7 +2591,7 @@ m4_if([$1], [],[
|
||||
done
|
||||
IFS=$lt_save_ifs
|
||||
# Convert to MSYS style.
|
||||
sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'`
|
||||
sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'`
|
||||
;;
|
||||
cygwin*)
|
||||
# Convert to unix form, then to dos form, then back to unix form
|
||||
@@ -2647,7 +2628,7 @@ m4_if([$1], [],[
|
||||
;;
|
||||
|
||||
*)
|
||||
# Assume MSVC and ICC wrapper
|
||||
# Assume MSVC wrapper
|
||||
library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib'
|
||||
dynamic_linker='Win32 ld.exe'
|
||||
;;
|
||||
@@ -2680,7 +2661,7 @@ dgux*)
|
||||
shlibpath_var=LD_LIBRARY_PATH
|
||||
;;
|
||||
|
||||
freebsd* | dragonfly* | midnightbsd*)
|
||||
freebsd* | dragonfly*)
|
||||
# DragonFly does not have aout. When/if they implement a new
|
||||
# versioning mechanism, adjust this.
|
||||
if test -x /usr/bin/objformat; then
|
||||
@@ -2892,6 +2873,9 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
|
||||
# before this can be enabled.
|
||||
hardcode_into_libs=yes
|
||||
|
||||
# Add ABI-specific directories to the system library path.
|
||||
sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib"
|
||||
|
||||
# Ideally, we could use ldconfig to report *all* directores which are
|
||||
# searched for libraries, however this is still not possible. Aside from not
|
||||
# being certain /sbin/ldconfig is available, command
|
||||
@@ -2900,7 +2884,7 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
|
||||
# appending ld.so.conf contents (and includes) to the search path.
|
||||
if test -f /etc/ld.so.conf; then
|
||||
lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
|
||||
sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
|
||||
sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra"
|
||||
fi
|
||||
|
||||
# We used to test for /lib/ld.so.1 and disable shared libraries on
|
||||
@@ -2912,18 +2896,6 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
|
||||
dynamic_linker='GNU/Linux ld.so'
|
||||
;;
|
||||
|
||||
netbsdelf*-gnu)
|
||||
version_type=linux
|
||||
need_lib_prefix=no
|
||||
need_version=no
|
||||
library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
|
||||
soname_spec='${libname}${release}${shared_ext}$major'
|
||||
shlibpath_var=LD_LIBRARY_PATH
|
||||
shlibpath_overrides_runpath=no
|
||||
hardcode_into_libs=yes
|
||||
dynamic_linker='NetBSD ld.elf_so'
|
||||
;;
|
||||
|
||||
netbsd*)
|
||||
version_type=sunos
|
||||
need_lib_prefix=no
|
||||
@@ -3491,7 +3463,7 @@ beos*)
|
||||
|
||||
bsdi[[45]]*)
|
||||
lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)'
|
||||
lt_cv_file_magic_cmd='$FILECMD -L'
|
||||
lt_cv_file_magic_cmd='/usr/bin/file -L'
|
||||
lt_cv_file_magic_test_file=/shlib/libc.so
|
||||
;;
|
||||
|
||||
@@ -3525,14 +3497,14 @@ darwin* | rhapsody*)
|
||||
lt_cv_deplibs_check_method=pass_all
|
||||
;;
|
||||
|
||||
freebsd* | dragonfly* | midnightbsd*)
|
||||
freebsd* | dragonfly*)
|
||||
if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
|
||||
case $host_cpu in
|
||||
i*86 )
|
||||
# Not sure whether the presence of OpenBSD here was a mistake.
|
||||
# Let's accept both of them until this is cleared up.
|
||||
lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library'
|
||||
lt_cv_file_magic_cmd=$FILECMD
|
||||
lt_cv_file_magic_cmd=/usr/bin/file
|
||||
lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
|
||||
;;
|
||||
esac
|
||||
@@ -3546,7 +3518,7 @@ haiku*)
|
||||
;;
|
||||
|
||||
hpux10.20* | hpux11*)
|
||||
lt_cv_file_magic_cmd=$FILECMD
|
||||
lt_cv_file_magic_cmd=/usr/bin/file
|
||||
case $host_cpu in
|
||||
ia64*)
|
||||
lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64'
|
||||
@@ -3583,7 +3555,7 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)
|
||||
lt_cv_deplibs_check_method=pass_all
|
||||
;;
|
||||
|
||||
netbsd* | netbsdelf*-gnu)
|
||||
netbsd*)
|
||||
if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
|
||||
lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
|
||||
else
|
||||
@@ -3593,7 +3565,7 @@ netbsd* | netbsdelf*-gnu)
|
||||
|
||||
newos6*)
|
||||
lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)'
|
||||
lt_cv_file_magic_cmd=$FILECMD
|
||||
lt_cv_file_magic_cmd=/usr/bin/file
|
||||
lt_cv_file_magic_test_file=/usr/lib/libnls.so
|
||||
;;
|
||||
|
||||
@@ -3720,13 +3692,13 @@ else
|
||||
mingw*) lt_bad_file=conftest.nm/nofile ;;
|
||||
*) lt_bad_file=/dev/null ;;
|
||||
esac
|
||||
case `"$tmp_nm" -B $lt_bad_file 2>&1 | $SED '1q'` in
|
||||
case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in
|
||||
*$lt_bad_file* | *'Invalid file or object type'*)
|
||||
lt_cv_path_NM="$tmp_nm -B"
|
||||
break 2
|
||||
;;
|
||||
*)
|
||||
case `"$tmp_nm" -p /dev/null 2>&1 | $SED '1q'` in
|
||||
case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
|
||||
*/dev/null*)
|
||||
lt_cv_path_NM="$tmp_nm -p"
|
||||
break 2
|
||||
@@ -3752,7 +3724,7 @@ else
|
||||
# Let the user override the test.
|
||||
else
|
||||
AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :)
|
||||
case `$DUMPBIN -symbols -headers /dev/null 2>&1 | $SED '1q'` in
|
||||
case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in
|
||||
*COFF*)
|
||||
DUMPBIN="$DUMPBIN -symbols -headers"
|
||||
;;
|
||||
@@ -3992,7 +3964,7 @@ esac
|
||||
|
||||
if test "$lt_cv_nm_interface" = "MS dumpbin"; then
|
||||
# Gets list of data symbols to import.
|
||||
lt_cv_sys_global_symbol_to_import="$SED -n -e 's/^I .* \(.*\)$/\1/p'"
|
||||
lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'"
|
||||
# Adjust the below global symbol transforms to fixup imported variables.
|
||||
lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'"
|
||||
lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'"
|
||||
@@ -4010,20 +3982,20 @@ fi
|
||||
# Transform an extracted symbol line into a proper C declaration.
|
||||
# Some systems (esp. on ia64) link data and code symbols differently,
|
||||
# so use this general approach.
|
||||
lt_cv_sys_global_symbol_to_cdecl="$SED -n"\
|
||||
lt_cv_sys_global_symbol_to_cdecl="sed -n"\
|
||||
$lt_cdecl_hook\
|
||||
" -e 's/^T .* \(.*\)$/extern int \1();/p'"\
|
||||
" -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'"
|
||||
|
||||
# Transform an extracted symbol line into symbol name and symbol address
|
||||
lt_cv_sys_global_symbol_to_c_name_address="$SED -n"\
|
||||
lt_cv_sys_global_symbol_to_c_name_address="sed -n"\
|
||||
$lt_c_name_hook\
|
||||
" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\
|
||||
" -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'"
|
||||
|
||||
# Transform an extracted symbol line into symbol name with lib prefix and
|
||||
# symbol address.
|
||||
lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="$SED -n"\
|
||||
lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\
|
||||
$lt_c_name_lib_hook\
|
||||
" -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\
|
||||
" -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\
|
||||
@@ -4047,7 +4019,7 @@ for ac_symprfx in "" "_"; do
|
||||
if test "$lt_cv_nm_interface" = "MS dumpbin"; then
|
||||
# Fake it for dumpbin and say T for any non-static function,
|
||||
# D for any global variable and I for any imported variable.
|
||||
# Also find C++ and __fastcall symbols from MSVC++ or ICC,
|
||||
# Also find C++ and __fastcall symbols from MSVC++,
|
||||
# which start with @ or ?.
|
||||
lt_cv_sys_global_symbol_pipe="$AWK ['"\
|
||||
" {last_section=section; section=\$ 3};"\
|
||||
@@ -4065,9 +4037,9 @@ for ac_symprfx in "" "_"; do
|
||||
" s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\
|
||||
" ' prfx=^$ac_symprfx]"
|
||||
else
|
||||
lt_cv_sys_global_symbol_pipe="$SED -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
|
||||
lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
|
||||
fi
|
||||
lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | $SED '/ __gnu_lto/d'"
|
||||
lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
|
||||
|
||||
# Check to see that the pipe works correctly.
|
||||
pipe_works=no
|
||||
@@ -4089,8 +4061,7 @@ _LT_EOF
|
||||
if AC_TRY_EVAL(ac_compile); then
|
||||
# Now try to grab the symbols.
|
||||
nlist=conftest.nm
|
||||
$ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&AS_MESSAGE_LOG_FD
|
||||
if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&AS_MESSAGE_LOG_FD && test -s "$nlist"; then
|
||||
if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then
|
||||
# Try sorting and uniquifying the output.
|
||||
if sort "$nlist" | uniq > "$nlist"T; then
|
||||
mv -f "$nlist"T "$nlist"
|
||||
@@ -4355,7 +4326,7 @@ m4_if([$1], [CXX], [
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
freebsd* | dragonfly* | midnightbsd*)
|
||||
freebsd* | dragonfly*)
|
||||
# FreeBSD uses GNU C++
|
||||
;;
|
||||
hpux9* | hpux10* | hpux11*)
|
||||
@@ -4438,7 +4409,7 @@ m4_if([$1], [CXX], [
|
||||
_LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
|
||||
;;
|
||||
*)
|
||||
case `$CC -V 2>&1 | $SED 5q` in
|
||||
case `$CC -V 2>&1 | sed 5q` in
|
||||
*Sun\ C*)
|
||||
# Sun C++ 5.9
|
||||
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
|
||||
@@ -4462,7 +4433,7 @@ m4_if([$1], [CXX], [
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
netbsd* | netbsdelf*-gnu)
|
||||
netbsd*)
|
||||
;;
|
||||
*qnx* | *nto*)
|
||||
# QNX uses GNU C++, but need to define -shared option too, otherwise
|
||||
@@ -4730,12 +4701,6 @@ m4_if([$1], [CXX], [
|
||||
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
|
||||
_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
|
||||
;;
|
||||
# flang / f18. f95 an alias for gfortran or flang on Debian
|
||||
flang* | f18* | f95*)
|
||||
_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
|
||||
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
|
||||
_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
|
||||
;;
|
||||
# icc used to be incompatible with GCC.
|
||||
# ICC 10 doesn't accept -KPIC any more.
|
||||
icc* | ifort*)
|
||||
@@ -4780,7 +4745,7 @@ m4_if([$1], [CXX], [
|
||||
_LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
|
||||
;;
|
||||
*)
|
||||
case `$CC -V 2>&1 | $SED 5q` in
|
||||
case `$CC -V 2>&1 | sed 5q` in
|
||||
*Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*)
|
||||
# Sun Fortran 8.3 passes all unrecognized flags to the linker
|
||||
_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
|
||||
@@ -4963,7 +4928,7 @@ m4_if([$1], [CXX], [
|
||||
if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
|
||||
_LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
|
||||
else
|
||||
_LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
|
||||
_LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
|
||||
fi
|
||||
;;
|
||||
pw32*)
|
||||
@@ -4971,7 +4936,7 @@ m4_if([$1], [CXX], [
|
||||
;;
|
||||
cygwin* | mingw* | cegcc*)
|
||||
case $cc_basename in
|
||||
cl* | icl*)
|
||||
cl*)
|
||||
_LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
|
||||
;;
|
||||
*)
|
||||
@@ -4980,9 +4945,6 @@ m4_if([$1], [CXX], [
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
linux* | k*bsd*-gnu | gnu*)
|
||||
_LT_TAGVAR(link_all_deplibs, $1)=no
|
||||
;;
|
||||
*)
|
||||
_LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
|
||||
;;
|
||||
@@ -5031,23 +4993,20 @@ dnl Note also adjust exclude_expsyms for C++ above.
|
||||
|
||||
case $host_os in
|
||||
cygwin* | mingw* | pw32* | cegcc*)
|
||||
# FIXME: the MSVC++ and ICC port hasn't been tested in a loooong time
|
||||
# FIXME: the MSVC++ port hasn't been tested in a loooong time
|
||||
# When not using gcc, we currently assume that we are using
|
||||
# Microsoft Visual C++ or Intel C++ Compiler.
|
||||
# Microsoft Visual C++.
|
||||
if test yes != "$GCC"; then
|
||||
with_gnu_ld=no
|
||||
fi
|
||||
;;
|
||||
interix*)
|
||||
# we just hope/assume this is gcc and not c89 (= MSVC++ or ICC)
|
||||
# we just hope/assume this is gcc and not c89 (= MSVC++)
|
||||
with_gnu_ld=yes
|
||||
;;
|
||||
openbsd* | bitrig*)
|
||||
with_gnu_ld=no
|
||||
;;
|
||||
linux* | k*bsd*-gnu | gnu*)
|
||||
_LT_TAGVAR(link_all_deplibs, $1)=no
|
||||
;;
|
||||
esac
|
||||
|
||||
_LT_TAGVAR(ld_shlibs, $1)=yes
|
||||
@@ -5094,7 +5053,7 @@ dnl Note also adjust exclude_expsyms for C++ above.
|
||||
_LT_TAGVAR(whole_archive_flag_spec, $1)=
|
||||
fi
|
||||
supports_anon_versioning=no
|
||||
case `$LD -v | $SED -e 's/([[^)]]\+)\s\+//' 2>&1` in
|
||||
case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in
|
||||
*GNU\ gold*) supports_anon_versioning=yes ;;
|
||||
*\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
|
||||
*\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
|
||||
@@ -5206,7 +5165,6 @@ _LT_EOF
|
||||
emximp -o $lib $output_objdir/$libname.def'
|
||||
_LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
|
||||
_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
|
||||
_LT_TAGVAR(file_list_spec, $1)='@'
|
||||
;;
|
||||
|
||||
interix[[3-9]]*)
|
||||
@@ -5221,7 +5179,7 @@ _LT_EOF
|
||||
# 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
|
||||
# time. Moving up from 0x10000000 also allows more sbrk(2) space.
|
||||
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
|
||||
_LT_TAGVAR(archive_expsym_cmds, $1)='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
|
||||
_LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
|
||||
;;
|
||||
|
||||
gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
|
||||
@@ -5264,7 +5222,7 @@ _LT_EOF
|
||||
_LT_TAGVAR(compiler_needs_object, $1)=yes
|
||||
;;
|
||||
esac
|
||||
case `$CC -V 2>&1 | $SED 5q` in
|
||||
case `$CC -V 2>&1 | sed 5q` in
|
||||
*Sun\ C*) # Sun C 5.9
|
||||
_LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive'
|
||||
_LT_TAGVAR(compiler_needs_object, $1)=yes
|
||||
@@ -5276,14 +5234,13 @@ _LT_EOF
|
||||
|
||||
if test yes = "$supports_anon_versioning"; then
|
||||
_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
|
||||
cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
|
||||
cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
|
||||
echo "local: *; };" >> $output_objdir/$libname.ver~
|
||||
$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
|
||||
fi
|
||||
|
||||
case $cc_basename in
|
||||
tcc*)
|
||||
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
|
||||
_LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic'
|
||||
;;
|
||||
xlf* | bgf* | bgxlf* | mpixlf*)
|
||||
@@ -5293,7 +5250,7 @@ _LT_EOF
|
||||
_LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
|
||||
if test yes = "$supports_anon_versioning"; then
|
||||
_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
|
||||
cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
|
||||
cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
|
||||
echo "local: *; };" >> $output_objdir/$libname.ver~
|
||||
$LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
|
||||
fi
|
||||
@@ -5304,7 +5261,7 @@ _LT_EOF
|
||||
fi
|
||||
;;
|
||||
|
||||
netbsd* | netbsdelf*-gnu)
|
||||
netbsd*)
|
||||
if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
|
||||
_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
|
||||
wlarc=
|
||||
@@ -5425,7 +5382,7 @@ _LT_EOF
|
||||
if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
|
||||
_LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols'
|
||||
else
|
||||
_LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
|
||||
_LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols'
|
||||
fi
|
||||
aix_use_runtimelinking=no
|
||||
|
||||
@@ -5608,12 +5565,12 @@ _LT_EOF
|
||||
|
||||
cygwin* | mingw* | pw32* | cegcc*)
|
||||
# When not using gcc, we currently assume that we are using
|
||||
# Microsoft Visual C++ or Intel C++ Compiler.
|
||||
# Microsoft Visual C++.
|
||||
# hardcode_libdir_flag_spec is actually meaningless, as there is
|
||||
# no search path for DLLs.
|
||||
case $cc_basename in
|
||||
cl* | icl*)
|
||||
# Native MSVC or ICC
|
||||
cl*)
|
||||
# Native MSVC
|
||||
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
|
||||
_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
|
||||
_LT_TAGVAR(always_export_symbols, $1)=yes
|
||||
@@ -5654,7 +5611,7 @@ _LT_EOF
|
||||
fi'
|
||||
;;
|
||||
*)
|
||||
# Assume MSVC and ICC wrapper
|
||||
# Assume MSVC wrapper
|
||||
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
|
||||
_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
|
||||
# Tell ltmain to make .lib files, not .a files.
|
||||
@@ -5702,7 +5659,7 @@ _LT_EOF
|
||||
;;
|
||||
|
||||
# FreeBSD 3 and greater uses gcc -shared to do shared libraries.
|
||||
freebsd* | dragonfly* | midnightbsd*)
|
||||
freebsd* | dragonfly*)
|
||||
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
|
||||
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
|
||||
_LT_TAGVAR(hardcode_direct, $1)=yes
|
||||
@@ -5825,7 +5782,6 @@ _LT_EOF
|
||||
if test yes = "$lt_cv_irix_exported_symbol"; then
|
||||
_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib'
|
||||
fi
|
||||
_LT_TAGVAR(link_all_deplibs, $1)=no
|
||||
else
|
||||
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib'
|
||||
_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib'
|
||||
@@ -5843,12 +5799,11 @@ _LT_EOF
|
||||
# Fabrice Bellard et al's Tiny C Compiler
|
||||
_LT_TAGVAR(ld_shlibs, $1)=yes
|
||||
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
|
||||
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir'
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
|
||||
netbsd* | netbsdelf*-gnu)
|
||||
netbsd*)
|
||||
if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
|
||||
_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
|
||||
else
|
||||
@@ -5915,7 +5870,6 @@ _LT_EOF
|
||||
emximp -o $lib $output_objdir/$libname.def'
|
||||
_LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
|
||||
_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
|
||||
_LT_TAGVAR(file_list_spec, $1)='@'
|
||||
;;
|
||||
|
||||
osf3*)
|
||||
@@ -6471,7 +6425,7 @@ if test yes != "$_lt_caught_CXX_error"; then
|
||||
# Commands to make compiler produce verbose output that lists
|
||||
# what "hidden" libraries, object files and flags are used when
|
||||
# linking a shared library.
|
||||
output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
|
||||
output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
|
||||
|
||||
else
|
||||
GXX=no
|
||||
@@ -6682,8 +6636,8 @@ if test yes != "$_lt_caught_CXX_error"; then
|
||||
|
||||
cygwin* | mingw* | pw32* | cegcc*)
|
||||
case $GXX,$cc_basename in
|
||||
,cl* | no,cl* | ,icl* | no,icl*)
|
||||
# Native MSVC or ICC
|
||||
,cl* | no,cl*)
|
||||
# Native MSVC
|
||||
# hardcode_libdir_flag_spec is actually meaningless, as there is
|
||||
# no search path for DLLs.
|
||||
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
|
||||
@@ -6781,7 +6735,6 @@ if test yes != "$_lt_caught_CXX_error"; then
|
||||
emximp -o $lib $output_objdir/$libname.def'
|
||||
_LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def'
|
||||
_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
|
||||
_LT_TAGVAR(file_list_spec, $1)='@'
|
||||
;;
|
||||
|
||||
dgux*)
|
||||
@@ -6812,7 +6765,7 @@ if test yes != "$_lt_caught_CXX_error"; then
|
||||
_LT_TAGVAR(archive_cmds_need_lc, $1)=no
|
||||
;;
|
||||
|
||||
freebsd* | dragonfly* | midnightbsd*)
|
||||
freebsd* | dragonfly*)
|
||||
# FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
|
||||
# conventions
|
||||
_LT_TAGVAR(ld_shlibs, $1)=yes
|
||||
@@ -6847,7 +6800,7 @@ if test yes != "$_lt_caught_CXX_error"; then
|
||||
# explicitly linking system object files so we need to strip them
|
||||
# from the output so that they don't get included in the library
|
||||
# dependencies.
|
||||
output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
|
||||
output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
|
||||
;;
|
||||
*)
|
||||
if test yes = "$GXX"; then
|
||||
@@ -6912,7 +6865,7 @@ if test yes != "$_lt_caught_CXX_error"; then
|
||||
# explicitly linking system object files so we need to strip them
|
||||
# from the output so that they don't get included in the library
|
||||
# dependencies.
|
||||
output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
|
||||
output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
|
||||
;;
|
||||
*)
|
||||
if test yes = "$GXX"; then
|
||||
@@ -6949,7 +6902,7 @@ if test yes != "$_lt_caught_CXX_error"; then
|
||||
# 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
|
||||
# time. Moving up from 0x10000000 also allows more sbrk(2) space.
|
||||
_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
|
||||
_LT_TAGVAR(archive_expsym_cmds, $1)='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
|
||||
_LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
|
||||
;;
|
||||
irix5* | irix6*)
|
||||
case $cc_basename in
|
||||
@@ -7089,13 +7042,13 @@ if test yes != "$_lt_caught_CXX_error"; then
|
||||
_LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib'
|
||||
if test yes = "$supports_anon_versioning"; then
|
||||
_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
|
||||
cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
|
||||
cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
|
||||
echo "local: *; };" >> $output_objdir/$libname.ver~
|
||||
$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib'
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
case `$CC -V 2>&1 | $SED 5q` in
|
||||
case `$CC -V 2>&1 | sed 5q` in
|
||||
*Sun\ C*)
|
||||
# Sun C++ 5.9
|
||||
_LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
|
||||
@@ -7251,7 +7204,7 @@ if test yes != "$_lt_caught_CXX_error"; then
|
||||
# Commands to make compiler produce verbose output that lists
|
||||
# what "hidden" libraries, object files and flags are used when
|
||||
# linking a shared library.
|
||||
output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
|
||||
output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
|
||||
|
||||
else
|
||||
# FIXME: insert proper C++ library support
|
||||
@@ -7335,7 +7288,7 @@ if test yes != "$_lt_caught_CXX_error"; then
|
||||
# Commands to make compiler produce verbose output that lists
|
||||
# what "hidden" libraries, object files and flags are used when
|
||||
# linking a shared library.
|
||||
output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
|
||||
output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
|
||||
else
|
||||
# g++ 2.7 appears to require '-G' NOT '-shared' on this
|
||||
# platform.
|
||||
@@ -7346,7 +7299,7 @@ if test yes != "$_lt_caught_CXX_error"; then
|
||||
# Commands to make compiler produce verbose output that lists
|
||||
# what "hidden" libraries, object files and flags are used when
|
||||
# linking a shared library.
|
||||
output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"'
|
||||
output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
|
||||
fi
|
||||
|
||||
_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir'
|
||||
@@ -8233,14 +8186,6 @@ _LT_DECL([], [DLLTOOL], [1], [DLL creation program])
|
||||
AC_SUBST([DLLTOOL])
|
||||
])
|
||||
|
||||
# _LT_DECL_FILECMD
|
||||
# ----------------
|
||||
# Check for a file(cmd) program that can be used to detect file type and magic
|
||||
m4_defun([_LT_DECL_FILECMD],
|
||||
[AC_CHECK_TOOL([FILECMD], [file], [:])
|
||||
_LT_DECL([], [FILECMD], [1], [A file(cmd) program that detects file types])
|
||||
])# _LD_DECL_FILECMD
|
||||
|
||||
# _LT_DECL_SED
|
||||
# ------------
|
||||
# Check for a fully-functional sed program, that truncates
|
||||
@@ -8420,8 +8365,8 @@ _LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd],
|
||||
|
||||
# Helper functions for option handling. -*- Autoconf -*-
|
||||
#
|
||||
# Copyright (C) 2004-2005, 2007-2009, 2011-2019, 2021-2022 Free
|
||||
# Software Foundation, Inc.
|
||||
# Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software
|
||||
# Foundation, Inc.
|
||||
# Written by Gary V. Vaughan, 2004
|
||||
#
|
||||
# This file is free software; the Free Software Foundation gives
|
||||
@@ -8852,7 +8797,7 @@ LT_OPTION_DEFINE([LTDL_INIT], [convenience],
|
||||
|
||||
# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*-
|
||||
#
|
||||
# Copyright (C) 2004-2005, 2007-2008, 2011-2019, 2021-2022 Free Software
|
||||
# Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software
|
||||
# Foundation, Inc.
|
||||
# Written by Gary V. Vaughan, 2004
|
||||
#
|
||||
@@ -8977,8 +8922,7 @@ m4_define([lt_dict_filter],
|
||||
|
||||
# ltversion.m4 -- version numbers -*- Autoconf -*-
|
||||
#
|
||||
# Copyright (C) 2004, 2011-2019, 2021-2022 Free Software Foundation,
|
||||
# Inc.
|
||||
# Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc.
|
||||
# Written by Scott James Remnant, 2004
|
||||
#
|
||||
# This file is free software; the Free Software Foundation gives
|
||||
@@ -8987,23 +8931,23 @@ m4_define([lt_dict_filter],
|
||||
|
||||
# @configure_input@
|
||||
|
||||
# serial 4245 ltversion.m4
|
||||
# serial 4179 ltversion.m4
|
||||
# This file is part of GNU Libtool
|
||||
|
||||
m4_define([LT_PACKAGE_VERSION], [2.4.7])
|
||||
m4_define([LT_PACKAGE_REVISION], [2.4.7])
|
||||
m4_define([LT_PACKAGE_VERSION], [2.4.6])
|
||||
m4_define([LT_PACKAGE_REVISION], [2.4.6])
|
||||
|
||||
AC_DEFUN([LTVERSION_VERSION],
|
||||
[macro_version='2.4.7'
|
||||
macro_revision='2.4.7'
|
||||
[macro_version='2.4.6'
|
||||
macro_revision='2.4.6'
|
||||
_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
|
||||
_LT_DECL(, macro_revision, 0)
|
||||
])
|
||||
|
||||
# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*-
|
||||
#
|
||||
# Copyright (C) 2004-2005, 2007, 2009, 2011-2019, 2021-2022 Free
|
||||
# Software Foundation, Inc.
|
||||
# Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software
|
||||
# Foundation, Inc.
|
||||
# Written by Scott James Remnant, 2004.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation gives
|
||||
@@ -9100,8 +9044,8 @@ m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])])
|
||||
m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])])
|
||||
m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])])
|
||||
|
||||
# pkg.m4 - Macros to locate and use pkg-config. -*- Autoconf -*-
|
||||
# serial 12 (pkg-config-0.29.2)
|
||||
# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
|
||||
# serial 11 (pkg-config-0.29.1)
|
||||
|
||||
dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
|
||||
dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com>
|
||||
@@ -9143,7 +9087,7 @@ dnl
|
||||
dnl See the "Since" comment for each macro you use to see what version
|
||||
dnl of the macros you require.
|
||||
m4_defun([PKG_PREREQ],
|
||||
[m4_define([PKG_MACROS_VERSION], [0.29.2])
|
||||
[m4_define([PKG_MACROS_VERSION], [0.29.1])
|
||||
m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,
|
||||
[m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])
|
||||
])dnl PKG_PREREQ
|
||||
@@ -9188,7 +9132,7 @@ dnl Check to see whether a particular set of modules exists. Similar to
|
||||
dnl PKG_CHECK_MODULES(), but does not set variables or print errors.
|
||||
dnl
|
||||
dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
|
||||
dnl only at the first occurrence in configure.ac, so if the first place
|
||||
dnl only at the first occurence in configure.ac, so if the first place
|
||||
dnl it's called might be skipped (such as if it is within an "if", you
|
||||
dnl have to call PKG_CHECK_EXISTS manually
|
||||
AC_DEFUN([PKG_CHECK_EXISTS],
|
||||
@@ -9244,7 +9188,7 @@ AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
|
||||
AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
|
||||
|
||||
pkg_failed=no
|
||||
AC_MSG_CHECKING([for $2])
|
||||
AC_MSG_CHECKING([for $1])
|
||||
|
||||
_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
|
||||
_PKG_CONFIG([$1][_LIBS], [libs], [$2])
|
||||
@@ -9254,17 +9198,17 @@ and $1[]_LIBS to avoid the need to call pkg-config.
|
||||
See the pkg-config man page for more details.])
|
||||
|
||||
if test $pkg_failed = yes; then
|
||||
AC_MSG_RESULT([no])
|
||||
AC_MSG_RESULT([no])
|
||||
_PKG_SHORT_ERRORS_SUPPORTED
|
||||
if test $_pkg_short_errors_supported = yes; then
|
||||
$1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
|
||||
else
|
||||
$1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
|
||||
$1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
|
||||
else
|
||||
$1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
|
||||
fi
|
||||
# Put the nasty error message in config.log where it belongs
|
||||
echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
|
||||
# Put the nasty error message in config.log where it belongs
|
||||
echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
|
||||
|
||||
m4_default([$4], [AC_MSG_ERROR(
|
||||
m4_default([$4], [AC_MSG_ERROR(
|
||||
[Package requirements ($2) were not met:
|
||||
|
||||
$$1_PKG_ERRORS
|
||||
@@ -9275,8 +9219,8 @@ installed software in a non-standard prefix.
|
||||
_PKG_TEXT])[]dnl
|
||||
])
|
||||
elif test $pkg_failed = untried; then
|
||||
AC_MSG_RESULT([no])
|
||||
m4_default([$4], [AC_MSG_FAILURE(
|
||||
AC_MSG_RESULT([no])
|
||||
m4_default([$4], [AC_MSG_FAILURE(
|
||||
[The pkg-config script could not be found or is too old. Make sure it
|
||||
is in your PATH or set the PKG_CONFIG environment variable to the full
|
||||
path to pkg-config.
|
||||
@@ -9286,10 +9230,10 @@ _PKG_TEXT
|
||||
To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl
|
||||
])
|
||||
else
|
||||
$1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
|
||||
$1[]_LIBS=$pkg_cv_[]$1[]_LIBS
|
||||
$1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
|
||||
$1[]_LIBS=$pkg_cv_[]$1[]_LIBS
|
||||
AC_MSG_RESULT([yes])
|
||||
$3
|
||||
$3
|
||||
fi[]dnl
|
||||
])dnl PKG_CHECK_MODULES
|
||||
|
||||
@@ -9446,7 +9390,7 @@ AS_IF([test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"],
|
||||
|
||||
# AM_CONDITIONAL -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1997-2021 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1997-2020 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@@ -9477,7 +9421,7 @@ AC_CONFIG_COMMANDS_PRE(
|
||||
Usually this means the macro was only invoked conditionally.]])
|
||||
fi])])
|
||||
|
||||
# Copyright (C) 2006-2021 Free Software Foundation, Inc.
|
||||
# Copyright (C) 2006-2020 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
|
||||
+7
-1
@@ -2,7 +2,9 @@
|
||||
# Copyright 2009, Wouter Wijngaards, NLnet Labs.
|
||||
# BSD licensed.
|
||||
#
|
||||
# Version 50
|
||||
# Version 51
|
||||
# 2025-11-06 Fix ACX_CHECK_NONSTRING_ATTRIBUTE to reject clang, that prints
|
||||
# a warning for 'unknown attribute' when nonstring is used.
|
||||
# 2025-09-29 add ac_cv_func_malloc_0_nonnull as a cache value for the malloc(0)
|
||||
# check by ACX_FUNC_MALLOC.
|
||||
# 2025-09-29 add ACX_CHECK_NONSTRING_ATTRIBUTE, AHX_CONFIG_NONSTRING_ATTRIBUTE.
|
||||
@@ -535,6 +537,9 @@ dnl result in HAVE_ATTR_NONSTRING.
|
||||
dnl Make sure you include AHX_CONFIG_NONSTRING_ATTRIBUTE also.
|
||||
AC_DEFUN([ACX_CHECK_NONSTRING_ATTRIBUTE],
|
||||
[AC_REQUIRE([AC_PROG_CC])
|
||||
AC_REQUIRE([ACX_CHECK_ERROR_FLAGS])
|
||||
BAKCFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS $ERRFLAG"
|
||||
AC_MSG_CHECKING(whether the C compiler (${CC-cc}) accepts the "nonstring" attribute)
|
||||
AC_CACHE_VAL(ac_cv_c_nonstring_attribute,
|
||||
[ac_cv_c_nonstring_attribute=no
|
||||
@@ -546,6 +551,7 @@ struct test {
|
||||
struct test t = { "1" };
|
||||
(void) t;
|
||||
]])],[ac_cv_c_nonstring_attribute="yes"],[ac_cv_c_nonstring_attribute="no"])
|
||||
CFLAGS="$BAKCFLAGS"
|
||||
])
|
||||
|
||||
dnl Setup ATTR_NONSTRING config.h parts.
|
||||
|
||||
+11
-4
@@ -754,8 +754,10 @@ cachedb_intcache_store(struct module_qstate* qstate, int msg_expired,
|
||||
"(original ttl: %d)", (int)original_ttl);
|
||||
/* The expired entry does not get checked by the validator
|
||||
* and we need a validation value for it. */
|
||||
/* By setting this to unchecked, bogus data is not returned
|
||||
* as non-bogus. */
|
||||
if(qstate->env->cfg->cachedb_check_when_serve_expired)
|
||||
qstate->return_msg->rep->security = sec_status_insecure;
|
||||
qstate->return_msg->rep->security = sec_status_unchecked;
|
||||
}
|
||||
(void)dns_cache_store(qstate->env, &qstate->qinfo,
|
||||
qstate->return_msg->rep, 0, qstate->prefetch_leeway, 0,
|
||||
@@ -803,8 +805,11 @@ cachedb_handle_query(struct module_qstate* qstate,
|
||||
return;
|
||||
}
|
||||
|
||||
if(qstate->blacklist || qstate->no_cache_lookup) {
|
||||
/* cache is blacklisted or we are instructed from edns to not look */
|
||||
if(qstate->blacklist || qstate->no_cache_lookup
|
||||
|| iter_stub_fwd_no_cache(qstate, &qstate->qinfo, NULL, NULL,
|
||||
NULL, 0)) {
|
||||
/* cache is blacklisted or we are instructed from edns to not
|
||||
* look or a forwarder/stub forbids it */
|
||||
/* pass request to next module */
|
||||
qstate->ext_state[id] = module_wait_module;
|
||||
return;
|
||||
@@ -892,7 +897,9 @@ cachedb_handle_response(struct module_qstate* qstate,
|
||||
{
|
||||
qstate->is_cachedb_answer = 0;
|
||||
/* check if we are not enabled or instructed to not cache, and skip */
|
||||
if(!ie->enabled || qstate->no_cache_store) {
|
||||
if(!ie->enabled || qstate->no_cache_store
|
||||
|| iter_stub_fwd_no_cache(qstate, &qstate->qinfo, NULL, NULL,
|
||||
NULL, 0)) {
|
||||
/* we are done with the query */
|
||||
qstate->ext_state[id] = module_finished;
|
||||
return;
|
||||
|
||||
@@ -38,6 +38,9 @@
|
||||
#ifndef UB_ON_WINDOWS
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
#ifdef __QNX__
|
||||
#include "util/log.h"
|
||||
#endif /* __QNX__ */
|
||||
|
||||
#define KEYSTREAM_ONLY
|
||||
#include "chacha_private.h"
|
||||
@@ -187,7 +190,11 @@ _rs_stir(void)
|
||||
if(errno != ENOSYS ||
|
||||
fallback_getentropy_urandom(rnd, sizeof rnd) == -1) {
|
||||
#ifdef SIGKILL
|
||||
#ifndef __QNX__
|
||||
raise(SIGKILL);
|
||||
#else /* !__QNX__ */
|
||||
fatal_exit("failed to getentropy");
|
||||
#endif /* __QNX__ */
|
||||
#else
|
||||
exit(9); /* windows */
|
||||
#endif
|
||||
|
||||
@@ -48,8 +48,8 @@ typedef struct
|
||||
a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \
|
||||
c = PLUS(c,d); b = ROTATE(XOR(b,c), 7);
|
||||
|
||||
static const char sigma[16] = "expand 32-byte k";
|
||||
static const char tau[16] = "expand 16-byte k";
|
||||
static const char ATTR_NONSTRING(sigma[16]) = "expand 32-byte k";
|
||||
static const char ATTR_NONSTRING(tau[16]) = "expand 16-byte k";
|
||||
|
||||
static void
|
||||
chacha_keysetup(chacha_ctx *x,const u8 *k,u32 kbits,u32 ATTR_UNUSED(ivbits))
|
||||
|
||||
@@ -29,7 +29,9 @@
|
||||
#include <sys/param.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/resource.h>
|
||||
#ifndef __QNX__
|
||||
#include <sys/syscall.h>
|
||||
#endif /* !__QNX__ */
|
||||
#ifdef SYS__sysctl
|
||||
#include <linux/sysctl.h>
|
||||
#endif
|
||||
@@ -42,7 +44,9 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#ifndef __QNX__
|
||||
#include <link.h>
|
||||
#endif /* __QNX__ */
|
||||
#include <termios.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
@@ -60,12 +64,14 @@
|
||||
#define SHA512_Final(r, c) sha512_digest(c, SHA512_DIGEST_SIZE, r)
|
||||
#endif
|
||||
|
||||
#ifndef __QNX__
|
||||
#include <linux/types.h>
|
||||
#include <linux/random.h>
|
||||
#ifdef HAVE_GETAUXVAL
|
||||
#include <sys/auxv.h>
|
||||
#endif
|
||||
#include <sys/vfs.h>
|
||||
#endif /* !__QNX__ */
|
||||
#ifndef MAP_ANON
|
||||
#define MAP_ANON MAP_ANONYMOUS
|
||||
#endif
|
||||
@@ -94,8 +100,10 @@ static int getentropy_urandom(void *buf, size_t len);
|
||||
#ifdef SYS__sysctl
|
||||
static int getentropy_sysctl(void *buf, size_t len);
|
||||
#endif
|
||||
#ifndef __QNX__
|
||||
static int getentropy_fallback(void *buf, size_t len);
|
||||
static int getentropy_phdr(struct dl_phdr_info *info, size_t size, void *data);
|
||||
#endif /* !__QNX__ */
|
||||
|
||||
int
|
||||
getentropy(void *buf, size_t len)
|
||||
@@ -178,6 +186,7 @@ getentropy(void *buf, size_t len)
|
||||
* sysctl ABI, or consider providing a new failsafe API which
|
||||
* works in a chroot or when file descriptors are exhausted.
|
||||
*/
|
||||
#ifndef __QNX__
|
||||
#undef FAIL_INSTEAD_OF_TRYING_FALLBACK
|
||||
#ifdef FAIL_INSTEAD_OF_TRYING_FALLBACK
|
||||
raise(SIGKILL);
|
||||
@@ -185,6 +194,9 @@ getentropy(void *buf, size_t len)
|
||||
ret = getentropy_fallback(buf, len);
|
||||
if (ret != -1)
|
||||
return (ret);
|
||||
#else /* !__QNX__ */
|
||||
fatal_exit("failed to read from /dev/urandom");
|
||||
#endif /* __QNX__ */
|
||||
|
||||
errno = EIO;
|
||||
return (ret);
|
||||
@@ -214,7 +226,11 @@ getentropy_urandom(void *buf, size_t len)
|
||||
{
|
||||
struct stat st;
|
||||
size_t i;
|
||||
#ifndef __QNX__
|
||||
int fd, cnt, flags;
|
||||
#else /* !__QNX__ */
|
||||
int fd, flags;
|
||||
#endif /* __QNX__ */
|
||||
int save_errno = errno;
|
||||
|
||||
start:
|
||||
@@ -241,10 +257,12 @@ start:
|
||||
close(fd);
|
||||
goto nodevrandom;
|
||||
}
|
||||
#ifndef __QNX__
|
||||
if (ioctl(fd, RNDGETENTCNT, &cnt) == -1) {
|
||||
close(fd);
|
||||
goto nodevrandom;
|
||||
}
|
||||
#endif /* !__QNX__ */
|
||||
for (i = 0; i < len; ) {
|
||||
size_t wanted = len - i;
|
||||
ssize_t ret = read(fd, (char *)buf + i, wanted);
|
||||
@@ -265,6 +283,7 @@ nodevrandom:
|
||||
return (-1);
|
||||
}
|
||||
|
||||
#ifndef __QNX__
|
||||
#ifdef SYS__sysctl
|
||||
static int
|
||||
getentropy_sysctl(void *buf, size_t len)
|
||||
@@ -537,3 +556,4 @@ getentropy_fallback(void *buf, size_t len)
|
||||
errno = save_errno;
|
||||
return (0); /* satisfied */
|
||||
}
|
||||
#endif /* !__QNX__ */
|
||||
|
||||
+1
-4
@@ -42,10 +42,7 @@ static const int year_lengths[2] = {
|
||||
};
|
||||
|
||||
static void
|
||||
timesub(timep, offset, tmp)
|
||||
const time_t * const timep;
|
||||
const long offset;
|
||||
struct tm * const tmp;
|
||||
timesub(const time_t * const timep, const long offset, struct tm * const tmp)
|
||||
{
|
||||
long days;
|
||||
long rem;
|
||||
|
||||
+21
-9
@@ -256,9 +256,6 @@
|
||||
/* Define to 1 if you have the `EVP_EncryptInit_ex' function. */
|
||||
#undef HAVE_EVP_ENCRYPTINIT_EX
|
||||
|
||||
/* Define to 1 if you have the `EVP_MAC_CTX_new' function. */
|
||||
#undef HAVE_EVP_MAC_CTX_NEW
|
||||
|
||||
/* Define to 1 if you have the `EVP_MAC_CTX_set_params' function. */
|
||||
#undef HAVE_EVP_MAC_CTX_SET_PARAMS
|
||||
|
||||
@@ -340,9 +337,6 @@
|
||||
/* Define to 1 if you have the <hiredis/hiredis.h> header file. */
|
||||
#undef HAVE_HIREDIS_HIREDIS_H
|
||||
|
||||
/* Define to 1 if you have the `HMAC_CTX_new' function. */
|
||||
#undef HAVE_HMAC_CTX_NEW
|
||||
|
||||
/* Define to 1 if you have the `HMAC_Init_ex' function. */
|
||||
#undef HAVE_HMAC_INIT_EX
|
||||
|
||||
@@ -570,12 +564,27 @@
|
||||
/* Define if you have POSIX threads libraries and header files. */
|
||||
#undef HAVE_PTHREAD
|
||||
|
||||
/* Define to 1 if you have the <pthread_np.h> header file. */
|
||||
#undef HAVE_PTHREAD_NP_H
|
||||
|
||||
/* Have PTHREAD_PRIO_INHERIT. */
|
||||
#undef HAVE_PTHREAD_PRIO_INHERIT
|
||||
|
||||
/* Define to 1 if the system has the type `pthread_rwlock_t'. */
|
||||
#undef HAVE_PTHREAD_RWLOCK_T
|
||||
|
||||
/* Define if pthread_setname_np has the common 2 arguments. */
|
||||
#undef HAVE_PTHREAD_SETNAME_NP
|
||||
|
||||
/* Define if pthread_setname_np has only 1 argument. */
|
||||
#undef HAVE_PTHREAD_SETNAME_NP1
|
||||
|
||||
/* Define if pthread_setname_np has 3 arguments. */
|
||||
#undef HAVE_PTHREAD_SETNAME_NP3
|
||||
|
||||
/* Define if pthread_setname_np exists as pthread_set_name_np instead. */
|
||||
#undef HAVE_PTHREAD_SET_NAME_NP
|
||||
|
||||
/* Define to 1 if the system has the type `pthread_spinlock_t'. */
|
||||
#undef HAVE_PTHREAD_SPINLOCK_T
|
||||
|
||||
@@ -664,9 +673,6 @@
|
||||
function. */
|
||||
#undef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB
|
||||
|
||||
/* Define to 1 if you have the `SSL_CTX_set_tmp_ecdh' function. */
|
||||
#undef HAVE_SSL_CTX_SET_TMP_ECDH
|
||||
|
||||
/* Define to 1 if you have the `SSL_get0_alpn_selected' function. */
|
||||
#undef HAVE_SSL_GET0_ALPN_SELECTED
|
||||
|
||||
@@ -744,6 +750,12 @@
|
||||
/* Define to 1 if `sun_len' is a member of `struct sockaddr_un'. */
|
||||
#undef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
|
||||
|
||||
/* Define to 1 if `st_mtimensec' is a member of `struct stat'. */
|
||||
#undef HAVE_STRUCT_STAT_ST_MTIMENSEC
|
||||
|
||||
/* Define to 1 if `st_mtim.tv_nsec' is a member of `struct stat'. */
|
||||
#undef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
|
||||
|
||||
/* Define if you have Swig libraries and header files. */
|
||||
#undef HAVE_SWIG
|
||||
|
||||
|
||||
+85
-5
@@ -11,15 +11,15 @@ sinclude(dnscrypt/dnscrypt.m4)
|
||||
|
||||
# must be numbers. ac_defun because of later processing
|
||||
m4_define([VERSION_MAJOR],[1])
|
||||
m4_define([VERSION_MINOR],[24])
|
||||
m4_define([VERSION_MICRO],[2])
|
||||
m4_define([VERSION_MINOR],[25])
|
||||
m4_define([VERSION_MICRO],[1])
|
||||
AC_INIT([unbound],m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]),[unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues],[unbound])
|
||||
AC_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR])
|
||||
AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR])
|
||||
AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO])
|
||||
|
||||
LIBUNBOUND_CURRENT=9
|
||||
LIBUNBOUND_REVISION=35
|
||||
LIBUNBOUND_REVISION=37
|
||||
LIBUNBOUND_AGE=1
|
||||
# 1.0.0 had 0:12:0
|
||||
# 1.0.1 had 0:13:0
|
||||
@@ -122,6 +122,8 @@ LIBUNBOUND_AGE=1
|
||||
# 1.24.0 had 9:33:1
|
||||
# 1.24.1 had 9:34:1
|
||||
# 1.24.2 had 9:35:1
|
||||
# 1.25.0 had 9:36:1
|
||||
# 1.25.1 had 9:37:1
|
||||
|
||||
# Current -- the number of the binary API that we're implementing
|
||||
# Revision -- which iteration of the implementation of the binary
|
||||
@@ -361,7 +363,14 @@ AC_MSG_CHECKING(whether the C compiler (${CC-cc}) accepts the "noreturn" attribu
|
||||
AC_CACHE_VAL(ac_cv_c_noreturn_attribute,
|
||||
[ac_cv_c_noreturn_attribute=no
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <stdio.h>
|
||||
__attribute__((noreturn)) void f(int x) { printf("%d", x); }
|
||||
#ifdef STDC_HEADERS
|
||||
# include <stdlib.h>
|
||||
#else
|
||||
# ifdef HAVE_STDLIB_H
|
||||
# include <stdlib.h>
|
||||
# endif
|
||||
#endif
|
||||
__attribute__((noreturn)) void f(int x) { printf("%d", x); exit(1); }
|
||||
]], [[
|
||||
f(1);
|
||||
]])],[ac_cv_c_noreturn_attribute="yes"],[ac_cv_c_noreturn_attribute="no"])
|
||||
@@ -723,6 +732,76 @@ int main(void) {return 0;}
|
||||
])
|
||||
fi
|
||||
|
||||
if test x_$ub_have_pthreads != x_no; then
|
||||
# Long checks to support pthread_setname_np().
|
||||
# Some OSes have the extra non-portable functions in a specific
|
||||
# header file.
|
||||
AC_CHECK_HEADERS([pthread_np.h],,, [AC_INCLUDES_DEFAULT])
|
||||
BAKCFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS -Werror"
|
||||
# MacOS only has 1 argument, the name.
|
||||
AC_MSG_CHECKING([whether pthread_setname_np has only 1 argument])
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT
|
||||
#include <pthread.h>
|
||||
#ifdef HAVE_PTHREAD_NP_H
|
||||
#include <pthread_np.h>
|
||||
#endif
|
||||
],[
|
||||
(void)pthread_setname_np("");
|
||||
])],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_PTHREAD_SETNAME_NP1, 1, [Define if pthread_setname_np has only 1 argument.])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
# NetBSD has 3 arguments to allow for formatting of the name.
|
||||
AC_MSG_CHECKING([whether pthread_setname_np has 3 arguments])
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT
|
||||
#include <pthread.h>
|
||||
#ifdef HAVE_PTHREAD_NP_H
|
||||
#include <pthread_np.h>
|
||||
#endif
|
||||
],[
|
||||
(void)pthread_setname_np(0, "", NULL);
|
||||
])],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_PTHREAD_SETNAME_NP3, 1, [Define if pthread_setname_np has 3 arguments.])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
# Most OSes have the common 2 arguments, thread and name.
|
||||
AC_MSG_CHECKING([whether pthread_setname_np has the common 2 arguments])
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT
|
||||
#include <pthread.h>
|
||||
#ifdef HAVE_PTHREAD_NP_H
|
||||
#include <pthread_np.h>
|
||||
#endif
|
||||
],[
|
||||
(void)pthread_setname_np(0, "");
|
||||
])],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_PTHREAD_SETNAME_NP, 1, [Define if pthread_setname_np has the common 2 arguments.])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
# FreeBSD/OpenBSD use a slightly different function name.
|
||||
AC_MSG_CHECKING([whether pthread_setname_np exists as pthread_set_name_np instead])
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT
|
||||
#include <pthread.h>
|
||||
#ifdef HAVE_PTHREAD_NP_H
|
||||
#include <pthread_np.h>
|
||||
#endif
|
||||
],[
|
||||
(void)pthread_set_name_np(0, "");
|
||||
])],[
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_PTHREAD_SET_NAME_NP, 1, [Define if pthread_setname_np exists as pthread_set_name_np instead.])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
CFLAGS="$BAKCFLAGS"
|
||||
fi
|
||||
|
||||
# check solaris thread library
|
||||
AC_ARG_WITH(solaris-threads, AS_HELP_STRING([--with-solaris-threads],[use solaris native thread library.]), [ ],[ withval="no" ])
|
||||
ub_have_sol_threads=no
|
||||
@@ -1000,7 +1079,7 @@ else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
AC_CHECK_HEADERS([openssl/conf.h openssl/engine.h openssl/bn.h openssl/dh.h openssl/dsa.h openssl/rsa.h openssl/core_names.h openssl/param_build.h],,, [AC_INCLUDES_DEFAULT])
|
||||
AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_default_properties_is_fips_enabled EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ENGINE_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex CRYPTO_THREADID_set_callback EVP_MAC_CTX_set_params OSSL_PARAM_BLD_new BIO_set_callback_ex SSL_CTX_set_tmp_ecdh HMAC_CTX_new EVP_MAC_CTX_new])
|
||||
AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_default_properties_is_fips_enabled EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ENGINE_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex CRYPTO_THREADID_set_callback EVP_MAC_CTX_set_params OSSL_PARAM_BLD_new BIO_set_callback_ex])
|
||||
|
||||
# these check_funcs need -lssl
|
||||
BAKLIBS="$LIBS"
|
||||
@@ -1761,6 +1840,7 @@ if test $ac_cv_func_daemon = yes; then
|
||||
])
|
||||
fi
|
||||
|
||||
AC_CHECK_MEMBERS([struct stat.st_mtimensec, struct stat.st_mtim.tv_nsec])
|
||||
AC_CHECK_MEMBERS([struct sockaddr_un.sun_len],,,[
|
||||
AC_INCLUDES_DEFAULT
|
||||
#ifdef HAVE_SYS_UN_H
|
||||
|
||||
@@ -58,3 +58,5 @@ distribution but may be helpful.
|
||||
* unbound.init_yocto: An init script to start and stop the server. Put it
|
||||
in /etc/init.d/unbound to use it. It is for the Yocto Project, in
|
||||
embedded systems, contributed by beni-sandu.
|
||||
* gost12.patch: adds ECC-GOST12 support for the informational RFC9558.
|
||||
Contributed by Igor V. Ruzanov.
|
||||
|
||||
@@ -0,0 +1,325 @@
|
||||
diff --git a/sldns/keyraw.c b/sldns/keyraw.c
|
||||
index 42a9262a3..cc6406a56 100644
|
||||
--- a/sldns/keyraw.c
|
||||
+++ b/sldns/keyraw.c
|
||||
@@ -85,7 +85,7 @@ sldns_rr_dnskey_key_size_raw(const unsigned char* keydata,
|
||||
}
|
||||
break;
|
||||
#ifdef USE_GOST
|
||||
- case LDNS_ECC_GOST:
|
||||
+ case LDNS_ECC_GOST12:
|
||||
return 512;
|
||||
#endif
|
||||
#ifdef USE_ECDSA
|
||||
@@ -146,7 +146,7 @@ sldns_key_EVP_load_gost_id(void)
|
||||
if(gost_id) return gost_id;
|
||||
|
||||
/* see if configuration loaded gost implementation from other engine*/
|
||||
- meth = EVP_PKEY_asn1_find_str(NULL, "gost2001", -1);
|
||||
+ meth = EVP_PKEY_asn1_find_str(NULL, "gost2012_256", -1);
|
||||
if(meth) {
|
||||
EVP_PKEY_asn1_get0_info(&gost_id, NULL, NULL, NULL, NULL, meth);
|
||||
return gost_id;
|
||||
@@ -170,7 +170,7 @@ sldns_key_EVP_load_gost_id(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
- meth = EVP_PKEY_asn1_find_str(&e, "gost2001", -1);
|
||||
+ meth = EVP_PKEY_asn1_find_str(&e, "gost2012_256", -1);
|
||||
if(!meth) {
|
||||
/* algo not found */
|
||||
ENGINE_finish(e);
|
||||
@@ -536,12 +536,17 @@ EVP_PKEY* sldns_key_rsa2pkey_raw(unsigned char* key, size_t len)
|
||||
EVP_PKEY*
|
||||
sldns_gost2pkey_raw(unsigned char* key, size_t keylen)
|
||||
{
|
||||
- /* prefix header for X509 encoding */
|
||||
- uint8_t asn[37] = { 0x30, 0x63, 0x30, 0x1c, 0x06, 0x06, 0x2a, 0x85,
|
||||
- 0x03, 0x02, 0x02, 0x13, 0x30, 0x12, 0x06, 0x07, 0x2a, 0x85,
|
||||
- 0x03, 0x02, 0x02, 0x23, 0x01, 0x06, 0x07, 0x2a, 0x85, 0x03,
|
||||
- 0x02, 0x02, 0x1e, 0x01, 0x03, 0x43, 0x00, 0x04, 0x40};
|
||||
- unsigned char encoded[37+64];
|
||||
+ /* prefix header for X509 encoding
|
||||
+ *
|
||||
+ * note: based on draft-makarenko-gost2012-dnssec-01 (pre-RFC9558 and it DOES work!)
|
||||
+ * ASN1 header described in RFC9558 is not suitable due to d2i_PUBKEY() works with
|
||||
+ * non-compressed public keys (two additional bytes 0x04, 0x40 at the end of header)
|
||||
+ */
|
||||
+ uint8_t asn[32] = { 0x30, 0x5e, 0x30, 0x17, 0x06, 0x08, 0x2a, 0x85,
|
||||
+ 0x03, 0x07, 0x01, 0x01, 0x01, 0x01, 0x30, 0x0b,
|
||||
+ 0x06, 0x09, 0x2a, 0x85, 0x03, 0x07, 0x01, 0x02,
|
||||
+ 0x01, 0x01, 0x01, 0x03, 0x43, 0x00, 0x04, 0x40 };
|
||||
+ unsigned char encoded[32+64];
|
||||
const unsigned char* pp;
|
||||
if(keylen != 64) {
|
||||
/* key wrong size */
|
||||
@@ -549,8 +554,8 @@ sldns_gost2pkey_raw(unsigned char* key, size_t keylen)
|
||||
}
|
||||
|
||||
/* create evp_key */
|
||||
- memmove(encoded, asn, 37);
|
||||
- memmove(encoded+37, key, 64);
|
||||
+ memmove(encoded, asn, 32);
|
||||
+ memmove(encoded+32, key, 64);
|
||||
pp = (unsigned char*)&encoded[0];
|
||||
|
||||
return d2i_PUBKEY(NULL, &pp, (int)sizeof(encoded));
|
||||
diff --git a/sldns/rrdef.h b/sldns/rrdef.h
|
||||
index bbc3d5b86..7d5f3c057 100644
|
||||
--- a/sldns/rrdef.h
|
||||
+++ b/sldns/rrdef.h
|
||||
@@ -384,11 +384,12 @@ enum sldns_enum_algorithm
|
||||
LDNS_RSASHA1_NSEC3 = 7,
|
||||
LDNS_RSASHA256 = 8, /* RFC 5702 */
|
||||
LDNS_RSASHA512 = 10, /* RFC 5702 */
|
||||
- LDNS_ECC_GOST = 12, /* RFC 5933 */
|
||||
+ LDNS_ECC_GOST = 12, /* RFC 5933, deprecated */
|
||||
LDNS_ECDSAP256SHA256 = 13, /* RFC 6605 */
|
||||
LDNS_ECDSAP384SHA384 = 14, /* RFC 6605 */
|
||||
LDNS_ED25519 = 15, /* RFC 8080 */
|
||||
LDNS_ED448 = 16, /* RFC 8080 */
|
||||
+ LDNS_ECC_GOST12 = 23, /* RFC 9558 */
|
||||
LDNS_INDIRECT = 252,
|
||||
LDNS_PRIVATEDNS = 253,
|
||||
LDNS_PRIVATEOID = 254
|
||||
@@ -402,8 +403,9 @@ enum sldns_enum_hash
|
||||
{
|
||||
LDNS_SHA1 = 1, /* RFC 4034 */
|
||||
LDNS_SHA256 = 2, /* RFC 4509 */
|
||||
- LDNS_HASH_GOST = 3, /* RFC 5933 */
|
||||
- LDNS_SHA384 = 4 /* RFC 6605 */
|
||||
+ LDNS_HASH_GOST = 3, /* RFC 5933, deprecated */
|
||||
+ LDNS_SHA384 = 4, /* RFC 6605 */
|
||||
+ LDNS_HASH_GOST12 = 5 /* RFC 9558 */
|
||||
};
|
||||
typedef enum sldns_enum_hash sldns_hash;
|
||||
|
||||
diff --git a/sldns/wire2str.c b/sldns/wire2str.c
|
||||
index 75b8f37b0..b4c4755e6 100644
|
||||
--- a/sldns/wire2str.c
|
||||
+++ b/sldns/wire2str.c
|
||||
@@ -45,11 +45,12 @@ static sldns_lookup_table sldns_algorithms_data[] = {
|
||||
{ LDNS_RSASHA1_NSEC3, "RSASHA1-NSEC3-SHA1" },
|
||||
{ LDNS_RSASHA256, "RSASHA256"},
|
||||
{ LDNS_RSASHA512, "RSASHA512"},
|
||||
- { LDNS_ECC_GOST, "ECC-GOST"},
|
||||
+ { LDNS_ECC_GOST, "ECC-GOST"}, /* deprecated */
|
||||
{ LDNS_ECDSAP256SHA256, "ECDSAP256SHA256"},
|
||||
{ LDNS_ECDSAP384SHA384, "ECDSAP384SHA384"},
|
||||
{ LDNS_ED25519, "ED25519"},
|
||||
{ LDNS_ED448, "ED448"},
|
||||
+ { LDNS_ECC_GOST12, "ECC-GOST12"},
|
||||
{ LDNS_INDIRECT, "INDIRECT" },
|
||||
{ LDNS_PRIVATEDNS, "PRIVATEDNS" },
|
||||
{ LDNS_PRIVATEOID, "PRIVATEOID" },
|
||||
@@ -61,8 +62,9 @@ sldns_lookup_table* sldns_algorithms = sldns_algorithms_data;
|
||||
static sldns_lookup_table sldns_hashes_data[] = {
|
||||
{ LDNS_SHA1, "SHA1" },
|
||||
{ LDNS_SHA256, "SHA256" },
|
||||
- { LDNS_HASH_GOST, "HASH-GOST" },
|
||||
+ { LDNS_HASH_GOST, "HASH-GOST" }, /* deprecated */
|
||||
{ LDNS_SHA384, "SHA384" },
|
||||
+ { LDNS_HASH_GOST12, "HASH-GOST12" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
sldns_lookup_table* sldns_hashes = sldns_hashes_data;
|
||||
diff --git a/testcode/unitverify.c b/testcode/unitverify.c
|
||||
index fcf2e2ffe..4a33e9f6a 100644
|
||||
--- a/testcode/unitverify.c
|
||||
+++ b/testcode/unitverify.c
|
||||
@@ -696,7 +696,7 @@ verify_test(void)
|
||||
#endif
|
||||
#ifdef USE_GOST
|
||||
if(sldns_key_EVP_load_gost_id())
|
||||
- verifytest_file(SRCDIRSTR "/testdata/test_sigs.gost", "20090807060504");
|
||||
+ verifytest_file(SRCDIRSTR "/testdata/test_sigs.gost12", "20251226060504");
|
||||
else printf("Warning: skipped GOST, openssl does not provide gost.\n");
|
||||
#endif
|
||||
#ifdef USE_ECDSA
|
||||
diff --git a/testdata/test_sigs.gost12 b/testdata/test_sigs.gost12
|
||||
new file mode 100644
|
||||
index 000000000..72a250cff
|
||||
--- /dev/null
|
||||
+++ b/testdata/test_sigs.gost12
|
||||
@@ -0,0 +1,39 @@
|
||||
+; Signature test file
|
||||
+
|
||||
+; first entry is a DNSKEY answer, with the DNSKEY rrset used for verification.
|
||||
+; later entries are verified with it.
|
||||
+
|
||||
+; Test GOST signatures using algo number 23.
|
||||
+
|
||||
+ENTRY_BEGIN
|
||||
+SECTION QUESTION
|
||||
+nlnetlabs.nl. IN DNSKEY
|
||||
+SECTION ANSWER
|
||||
+nlnetlabs.nl. 3600 IN DNSKEY 256 3 23 cdOtkEcb6NhcdOpIbPYtWyWxdlUiKgtKQbYg3lIjtG7i3fYjUID9zyOgoQEiV9wuGCfrw5cNsnvNw+8HiVFK4g== ;{id = 12301 (zsk), size = 512b}
|
||||
+ENTRY_END
|
||||
+
|
||||
+; entry to test
|
||||
+ENTRY_BEGIN
|
||||
+SECTION QUESTION
|
||||
+open.nlnetlabs.nl. IN A
|
||||
+SECTION ANSWER
|
||||
+open.nlnetlabs.nl. 600 IN A 213.154.224.1
|
||||
+open.nlnetlabs.nl. 600 IN RRSIG A 23 3 600 20260122084903 20251225084903 12301 nlnetlabs.nl. I12wYNs96DxMy26CWx296/sWMJAFg4nNXBo0sw7PnuMbJW5NFAmZYtFWhUdOWn4umaiodYOAmKG8Zg/OKvEtAQ==
|
||||
+ENTRY_END
|
||||
+
|
||||
+ENTRY_BEGIN
|
||||
+SECTION QUESTION
|
||||
+open.nlnetlabs.nl. IN AAAA
|
||||
+SECTION ANSWER
|
||||
+open.nlnetlabs.nl. 600 IN AAAA 2001:7b8:206:1::1
|
||||
+open.nlnetlabs.nl. 600 IN AAAA 2001:7b8:206:1::53
|
||||
+open.nlnetlabs.nl. 600 IN RRSIG AAAA 23 3 600 20260122084903 20251225084903 12301 nlnetlabs.nl. J0jHa+CP8HM6UDa2+uYgaze2mfpJTh2hkZ2KwMTYb5sfL6iBmxxql0c/403Itk4fMfYBMGn7zfzDQ+CxnCgSWw==
|
||||
+ENTRY_END
|
||||
+
|
||||
+ENTRY_BEGIN
|
||||
+SECTION QUESTION
|
||||
+open.nlnetlabs.nl. IN NSEC
|
||||
+SECTION ANSWER
|
||||
+open.nlnetlabs.nl. 86400 IN NSEC nlnetlabs.nl. A AAAA RRSIG NSEC
|
||||
+open.nlnetlabs.nl. 86400 IN RRSIG NSEC 23 3 86400 20260122084903 20251225084903 12301 nlnetlabs.nl. INCLYe9vAaNYaYx5Ay3Q6QdX+wPW9sMRvVlGt/jUEGgCi+88QlV80CT1oHrhRI66I14Wk6NRAGZRNx1tUPSHSg==
|
||||
+ENTRY_END
|
||||
diff --git a/validator/val_secalgo.c b/validator/val_secalgo.c
|
||||
index be8347b1b..4f621a309 100644
|
||||
--- a/validator/val_secalgo.c
|
||||
+++ b/validator/val_secalgo.c
|
||||
@@ -246,10 +246,10 @@ ds_digest_size_supported(int algo)
|
||||
return SHA256_DIGEST_LENGTH;
|
||||
#endif
|
||||
#ifdef USE_GOST
|
||||
- case LDNS_HASH_GOST:
|
||||
+ case LDNS_HASH_GOST12:
|
||||
/* we support GOST if it can be loaded */
|
||||
(void)sldns_key_EVP_load_gost_id();
|
||||
- if(EVP_get_digestbyname("md_gost94"))
|
||||
+ if(EVP_get_digestbyname("md_gost12_256"))
|
||||
return 32;
|
||||
else return 0;
|
||||
#endif
|
||||
@@ -265,9 +265,9 @@ ds_digest_size_supported(int algo)
|
||||
#ifdef USE_GOST
|
||||
/** Perform GOST hash */
|
||||
static int
|
||||
-do_gost94(unsigned char* data, size_t len, unsigned char* dest)
|
||||
+do_gost12(unsigned char* data, size_t len, unsigned char* dest)
|
||||
{
|
||||
- const EVP_MD* md = EVP_get_digestbyname("md_gost94");
|
||||
+ const EVP_MD* md = EVP_get_digestbyname("md_gost12_256");
|
||||
if(!md)
|
||||
return 0;
|
||||
return sldns_digest_evp(data, (unsigned int)len, dest, md);
|
||||
@@ -302,8 +302,8 @@ secalgo_ds_digest(int algo, unsigned char* buf, size_t len,
|
||||
return 1;
|
||||
#endif
|
||||
#ifdef USE_GOST
|
||||
- case LDNS_HASH_GOST:
|
||||
- if(do_gost94(buf, len, res))
|
||||
+ case LDNS_HASH_GOST12:
|
||||
+ if(do_gost12(buf, len, res))
|
||||
return 1;
|
||||
break;
|
||||
#endif
|
||||
@@ -384,7 +384,7 @@ dnskey_algo_id_is_supported(int id)
|
||||
#endif
|
||||
|
||||
#ifdef USE_GOST
|
||||
- case LDNS_ECC_GOST:
|
||||
+ case LDNS_ECC_GOST12:
|
||||
/* we support GOST if it can be loaded */
|
||||
return sldns_key_EVP_load_gost_id();
|
||||
#endif
|
||||
@@ -612,17 +612,17 @@ setup_key_digest(int algo, EVP_PKEY** evp_key, const EVP_MD** digest_type,
|
||||
|
||||
break;
|
||||
#ifdef USE_GOST
|
||||
- case LDNS_ECC_GOST:
|
||||
+ case LDNS_ECC_GOST12:
|
||||
*evp_key = sldns_gost2pkey_raw(key, keylen);
|
||||
if(!*evp_key) {
|
||||
verbose(VERB_QUERY, "verify: "
|
||||
"sldns_gost2pkey_raw failed");
|
||||
return 0;
|
||||
}
|
||||
- *digest_type = EVP_get_digestbyname("md_gost94");
|
||||
+ *digest_type = EVP_get_digestbyname("md_gost12_256");
|
||||
if(!*digest_type) {
|
||||
verbose(VERB_QUERY, "verify: "
|
||||
- "EVP_getdigest md_gost94 failed");
|
||||
+ "EVP_getdigest md_gost12_256 failed");
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
@@ -964,7 +964,7 @@ ds_digest_size_supported(int algo)
|
||||
return SHA384_LENGTH;
|
||||
#endif
|
||||
/* GOST not supported in NSS */
|
||||
- case LDNS_HASH_GOST:
|
||||
+ case LDNS_HASH_GOST12:
|
||||
default: break;
|
||||
}
|
||||
return 0;
|
||||
@@ -991,7 +991,7 @@ secalgo_ds_digest(int algo, unsigned char* buf, size_t len,
|
||||
return HASH_HashBuf(HASH_AlgSHA384, res, buf, len)
|
||||
== SECSuccess;
|
||||
#endif
|
||||
- case LDNS_HASH_GOST:
|
||||
+ case LDNS_HASH_GOST12:
|
||||
default:
|
||||
verbose(VERB_QUERY, "unknown DS digest algorithm %d",
|
||||
algo);
|
||||
@@ -1031,7 +1031,7 @@ dnskey_algo_id_is_supported(int id)
|
||||
case LDNS_ECDSAP384SHA384:
|
||||
return PK11_TokenExists(CKM_ECDSA);
|
||||
#endif
|
||||
- case LDNS_ECC_GOST:
|
||||
+ case LDNS_ECC_GOST12:
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -1352,7 +1352,7 @@ nss_setup_key_digest(int algo, SECKEYPublicKey** pubkey, HASH_HashType* htype,
|
||||
/* no prefix for DSA verification */
|
||||
break;
|
||||
#endif /* USE_ECDSA */
|
||||
- case LDNS_ECC_GOST:
|
||||
+ case LDNS_ECC_GOST12:
|
||||
default:
|
||||
verbose(VERB_QUERY, "verify: unknown algorithm %d",
|
||||
algo);
|
||||
@@ -1675,7 +1675,7 @@ ds_digest_size_supported(int algo)
|
||||
return SHA384_DIGEST_SIZE;
|
||||
#endif
|
||||
/* GOST not supported */
|
||||
- case LDNS_HASH_GOST:
|
||||
+ case LDNS_ECC_GOST12:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1700,7 +1700,7 @@ secalgo_ds_digest(int algo, unsigned char* buf, size_t len,
|
||||
return _digest_nettle(SHA384_DIGEST_SIZE, buf, len, res);
|
||||
|
||||
#endif
|
||||
- case LDNS_HASH_GOST:
|
||||
+ case LDNS_ECC_GOST12:
|
||||
default:
|
||||
verbose(VERB_QUERY, "unknown DS digest algorithm %d",
|
||||
algo);
|
||||
@@ -1744,7 +1744,7 @@ dnskey_algo_id_is_supported(int id)
|
||||
return 1;
|
||||
#endif
|
||||
case LDNS_RSAMD5: /* RFC 6725 deprecates RSAMD5 */
|
||||
- case LDNS_ECC_GOST:
|
||||
+ case LDNS_ECC_GOST12:
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -2103,7 +2103,7 @@ verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock,
|
||||
return sec_status_secure;
|
||||
#endif
|
||||
case LDNS_RSAMD5:
|
||||
- case LDNS_ECC_GOST:
|
||||
+ case LDNS_ECC_GOST12:
|
||||
default:
|
||||
*reason = "unable to verify signature, unknown algorithm";
|
||||
return sec_status_bogus;
|
||||
+309
-54
@@ -77,7 +77,6 @@
|
||||
#include "util/storage/lookup3.h"
|
||||
#include "util/storage/slabhash.h"
|
||||
#include "util/tcp_conn_limit.h"
|
||||
#include "util/allow_response_list.h"
|
||||
#include "util/edns.h"
|
||||
#include "services/listen_dnsport.h"
|
||||
#include "services/cache/rrset.h"
|
||||
@@ -90,7 +89,6 @@
|
||||
#include "util/random.h"
|
||||
#include "util/tube.h"
|
||||
#include "util/net_help.h"
|
||||
#include "util/tsig.h"
|
||||
#include "sldns/keyraw.h"
|
||||
#include "respip/respip.h"
|
||||
#include "iterator/iter_fwd.h"
|
||||
@@ -201,6 +199,255 @@ signal_handling_playback(struct worker* wrk)
|
||||
sig_record_reload = 0;
|
||||
}
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
/* setup a listening ssl context, fatal_exit() on any failure */
|
||||
static void
|
||||
setup_listen_sslctx(void** ctx, int is_dot, int is_doh,
|
||||
struct config_file* cfg, char* chroot)
|
||||
{
|
||||
char* key = cfg->ssl_service_key;
|
||||
char* pem = cfg->ssl_service_pem;
|
||||
if(chroot && strncmp(key, chroot, strlen(chroot)) == 0)
|
||||
key += strlen(chroot);
|
||||
if(chroot && pem && strncmp(pem, chroot, strlen(chroot)) == 0)
|
||||
pem += strlen(chroot);
|
||||
if(!(*ctx = listen_sslctx_create(key, pem, NULL,
|
||||
cfg->tls_ciphers, cfg->tls_ciphersuites,
|
||||
(cfg->tls_session_ticket_keys.first &&
|
||||
cfg->tls_session_ticket_keys.first->str[0] != 0),
|
||||
is_dot, is_doh, cfg->tls_protocols))) {
|
||||
fatal_exit("could not set up listen SSL_CTX");
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_SSL */
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
void* daemon_setup_listen_dot_sslctx(struct daemon* daemon,
|
||||
struct config_file* cfg)
|
||||
{
|
||||
void* ctx;
|
||||
(void)setup_listen_sslctx(&ctx, 1, 0, cfg, daemon->chroot);
|
||||
return ctx;
|
||||
}
|
||||
#endif /* HAVE_SSL */
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_NGHTTP2_NGHTTP2_H
|
||||
void* daemon_setup_listen_doh_sslctx(struct daemon* daemon,
|
||||
struct config_file* cfg)
|
||||
{
|
||||
void* ctx;
|
||||
(void)setup_listen_sslctx(&ctx, 0, 1, cfg, daemon->chroot);
|
||||
return ctx;
|
||||
}
|
||||
#endif /* HAVE_NGHTTP2_NGHTTP2_H */
|
||||
#endif /* HAVE_SSL */
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
#ifdef HAVE_NGTCP2
|
||||
void* daemon_setup_listen_quic_sslctx(struct daemon* daemon,
|
||||
struct config_file* cfg)
|
||||
{
|
||||
void* ctx;
|
||||
char* chroot = daemon->chroot;
|
||||
char* key = cfg->ssl_service_key;
|
||||
char* pem = cfg->ssl_service_pem;
|
||||
if(chroot && strncmp(key, chroot, strlen(chroot)) == 0)
|
||||
key += strlen(chroot);
|
||||
if(chroot && pem && strncmp(pem, chroot, strlen(chroot)) == 0)
|
||||
pem += strlen(chroot);
|
||||
|
||||
if(!(ctx = quic_sslctx_create(key, pem, NULL))) {
|
||||
fatal_exit("could not set up quic SSL_CTX");
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
#endif /* HAVE_NGTCP2 */
|
||||
#endif /* HAVE_SSL */
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
void* daemon_setup_connect_dot_sslctx(struct daemon* daemon,
|
||||
struct config_file* cfg)
|
||||
{
|
||||
void* ctx;
|
||||
char* bundle, *chroot = daemon->chroot;
|
||||
bundle = cfg->tls_cert_bundle;
|
||||
if(chroot && bundle && strncmp(bundle, chroot, strlen(chroot)) == 0)
|
||||
bundle += strlen(chroot);
|
||||
|
||||
if(!(ctx = connect_sslctx_create(NULL, NULL, bundle,
|
||||
cfg->tls_win_cert)))
|
||||
fatal_exit("could not set up connect SSL_CTX");
|
||||
return ctx;
|
||||
}
|
||||
#endif /* HAVE_SSL */
|
||||
|
||||
/* setups the needed ssl contexts, fatal_exit() on any failure */
|
||||
void
|
||||
daemon_setup_sslctxs(struct daemon* daemon, struct config_file* cfg)
|
||||
{
|
||||
#ifdef HAVE_SSL
|
||||
char* chroot = daemon->chroot;
|
||||
if(cfg->ssl_service_key && cfg->ssl_service_key[0]) {
|
||||
char* key = cfg->ssl_service_key;
|
||||
char* pem = cfg->ssl_service_pem;
|
||||
if(chroot && strncmp(key, chroot, strlen(chroot)) == 0)
|
||||
key += strlen(chroot);
|
||||
if(chroot && pem && strncmp(pem, chroot, strlen(chroot)) == 0)
|
||||
pem += strlen(chroot);
|
||||
|
||||
/* setup the session keys; the callback to use them will be
|
||||
* attached to each sslctx separately */
|
||||
if(cfg->tls_session_ticket_keys.first &&
|
||||
cfg->tls_session_ticket_keys.first->str[0] != 0) {
|
||||
if(!listen_sslctx_setup_ticket_keys(
|
||||
cfg->tls_session_ticket_keys.first, chroot)) {
|
||||
fatal_exit("could not set session ticket SSL_CTX");
|
||||
}
|
||||
}
|
||||
daemon->listen_dot_sslctx = daemon_setup_listen_dot_sslctx(
|
||||
daemon, cfg);
|
||||
#ifdef HAVE_NGHTTP2_NGHTTP2_H
|
||||
if(cfg_has_https(cfg)) {
|
||||
daemon->listen_doh_sslctx =
|
||||
daemon_setup_listen_doh_sslctx(daemon, cfg);
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_NGTCP2
|
||||
if(cfg_has_quic(cfg)) {
|
||||
daemon->listen_quic_sslctx =
|
||||
daemon_setup_listen_quic_sslctx(daemon, cfg);
|
||||
}
|
||||
#endif /* HAVE_NGTCP2 */
|
||||
|
||||
/* Store the file name and mtime to detect changes later. */
|
||||
daemon->ssl_service_key = strdup(cfg->ssl_service_key);
|
||||
if(!daemon->ssl_service_key)
|
||||
fatal_exit("could not setup ssl ctx: out of memory");
|
||||
if(cfg->ssl_service_pem) {
|
||||
daemon->ssl_service_pem = strdup(cfg->ssl_service_pem);
|
||||
if(!daemon->ssl_service_pem)
|
||||
fatal_exit("could not setup ssl ctx: out of memory");
|
||||
} else {
|
||||
daemon->ssl_service_pem = NULL;
|
||||
}
|
||||
if(!file_get_mtime(key,
|
||||
&daemon->mtime_ssl_service_key,
|
||||
&daemon->mtime_ns_ssl_service_key, NULL))
|
||||
log_err("Could not stat(%s): %s",
|
||||
key, strerror(errno));
|
||||
if(pem) {
|
||||
if(!file_get_mtime(pem,
|
||||
&daemon->mtime_ssl_service_pem,
|
||||
&daemon->mtime_ns_ssl_service_pem, NULL))
|
||||
log_err("Could not stat(%s): %s",
|
||||
pem, strerror(errno));
|
||||
} else {
|
||||
daemon->mtime_ssl_service_pem = 0;
|
||||
daemon->mtime_ns_ssl_service_pem = 0;
|
||||
}
|
||||
}
|
||||
daemon->connect_dot_sslctx = daemon_setup_connect_dot_sslctx(
|
||||
daemon, cfg);
|
||||
#else /* HAVE_SSL */
|
||||
(void)daemon;(void)cfg;
|
||||
#endif /* HAVE_SSL */
|
||||
}
|
||||
|
||||
/** Delete the ssl ctxs */
|
||||
static void
|
||||
daemon_delete_sslctxs(struct daemon* daemon)
|
||||
{
|
||||
#ifdef HAVE_SSL
|
||||
listen_sslctx_delete_ticket_keys();
|
||||
SSL_CTX_free((SSL_CTX*)daemon->listen_dot_sslctx);
|
||||
daemon->listen_dot_sslctx = NULL;
|
||||
SSL_CTX_free((SSL_CTX*)daemon->listen_doh_sslctx);
|
||||
daemon->listen_doh_sslctx = NULL;
|
||||
SSL_CTX_free((SSL_CTX*)daemon->connect_dot_sslctx);
|
||||
daemon->connect_dot_sslctx = NULL;
|
||||
free(daemon->ssl_service_key);
|
||||
daemon->ssl_service_key = NULL;
|
||||
free(daemon->ssl_service_pem);
|
||||
daemon->ssl_service_pem = NULL;
|
||||
#else
|
||||
(void)daemon;
|
||||
#endif
|
||||
#ifdef HAVE_NGTCP2
|
||||
SSL_CTX_free((SSL_CTX*)daemon->listen_quic_sslctx);
|
||||
daemon->listen_quic_sslctx = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
ssl_cert_changed(struct daemon* daemon, struct config_file* cfg)
|
||||
{
|
||||
time_t mtime = 0;
|
||||
long ns = 0;
|
||||
char* chroot = daemon->chroot;
|
||||
char* key = cfg->ssl_service_key;
|
||||
char* pem = cfg->ssl_service_pem;
|
||||
log_assert(daemon->ssl_service_key && cfg->ssl_service_key);
|
||||
if(chroot && strncmp(key, chroot, strlen(chroot)) == 0)
|
||||
key += strlen(chroot);
|
||||
if(chroot && pem && strncmp(pem, chroot, strlen(chroot)) == 0)
|
||||
pem += strlen(chroot);
|
||||
|
||||
if(strcmp(daemon->ssl_service_key, cfg->ssl_service_key) != 0)
|
||||
return 1;
|
||||
if(daemon->ssl_service_pem && cfg->ssl_service_pem &&
|
||||
strcmp(daemon->ssl_service_pem, cfg->ssl_service_pem) != 0)
|
||||
return 1;
|
||||
if(!file_get_mtime(key, &mtime, &ns, NULL)) {
|
||||
log_err("Could not stat(%s): %s",
|
||||
key, strerror(errno));
|
||||
/* It has probably changed, but file read is likely going to
|
||||
* fail. */
|
||||
return 0;
|
||||
}
|
||||
if(mtime != daemon->mtime_ssl_service_key ||
|
||||
ns != daemon->mtime_ns_ssl_service_key)
|
||||
return 1;
|
||||
if(pem) {
|
||||
if(!file_get_mtime(pem, &mtime, &ns, NULL)) {
|
||||
log_err("Could not stat(%s): %s",
|
||||
pem, strerror(errno));
|
||||
/* It has probably changed, but file read is likely going to
|
||||
* fail. */
|
||||
return 0;
|
||||
}
|
||||
if(mtime != daemon->mtime_ssl_service_pem ||
|
||||
ns != daemon->mtime_ns_ssl_service_pem)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Reload the sslctxs if they have changed */
|
||||
static void
|
||||
daemon_reload_sslctxs(struct daemon* daemon)
|
||||
{
|
||||
#ifdef HAVE_SSL
|
||||
if(daemon->cfg->ssl_service_key && daemon->cfg->ssl_service_key[0]) {
|
||||
/* See if changed */
|
||||
if(!daemon->ssl_service_key ||
|
||||
ssl_cert_changed(daemon,daemon->cfg)) {
|
||||
verbose(VERB_ALGO, "Reloading certificates");
|
||||
daemon_delete_sslctxs(daemon);
|
||||
daemon_setup_sslctxs(daemon, daemon->cfg);
|
||||
}
|
||||
} else {
|
||||
/* See if sslctxs are removed from config. */
|
||||
if(daemon->ssl_service_key) {
|
||||
verbose(VERB_ALGO, "Removing certificates");
|
||||
daemon_delete_sslctxs(daemon);
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)daemon;
|
||||
#endif
|
||||
}
|
||||
|
||||
struct daemon*
|
||||
daemon_init(void)
|
||||
{
|
||||
@@ -237,7 +484,11 @@ daemon_init(void)
|
||||
# else
|
||||
OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS
|
||||
| OPENSSL_INIT_ADD_ALL_DIGESTS
|
||||
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
|
||||
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS
|
||||
# if defined(OPENSSL_INIT_NO_LOAD_CONFIG) && defined(UB_ON_WINDOWS)
|
||||
| OPENSSL_INIT_NO_LOAD_CONFIG
|
||||
# endif
|
||||
, NULL);
|
||||
# endif
|
||||
# if HAVE_DECL_SSL_COMP_GET_COMPRESSION_METHODS
|
||||
/* grab the COMP method ptr because openssl leaks it */
|
||||
@@ -246,7 +497,11 @@ daemon_init(void)
|
||||
# if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL)
|
||||
(void)SSL_library_init();
|
||||
# else
|
||||
(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL);
|
||||
(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS
|
||||
# if defined(OPENSSL_INIT_NO_LOAD_CONFIG) && defined(UB_ON_WINDOWS)
|
||||
| OPENSSL_INIT_NO_LOAD_CONFIG
|
||||
# endif
|
||||
, NULL);
|
||||
# endif
|
||||
# if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED)
|
||||
if(!ub_openssl_lock_init())
|
||||
@@ -299,16 +554,6 @@ daemon_init(void)
|
||||
free(daemon);
|
||||
return NULL;
|
||||
}
|
||||
daemon->arl = arl_list_create();
|
||||
if(!daemon->arl) {
|
||||
acl_list_delete(daemon->acl_interface);
|
||||
acl_list_delete(daemon->acl);
|
||||
tcl_list_delete(daemon->tcl);
|
||||
edns_known_options_delete(daemon->env);
|
||||
free(daemon->env);
|
||||
free(daemon);
|
||||
return NULL;
|
||||
}
|
||||
listen_setup_locks();
|
||||
if(gettimeofday(&daemon->time_boot, NULL) < 0)
|
||||
log_err("gettimeofday: %s", strerror(errno));
|
||||
@@ -317,7 +562,6 @@ daemon_init(void)
|
||||
acl_list_delete(daemon->acl_interface);
|
||||
acl_list_delete(daemon->acl);
|
||||
tcl_list_delete(daemon->tcl);
|
||||
arl_list_delete(daemon->arl);
|
||||
edns_known_options_delete(daemon->env);
|
||||
free(daemon->env);
|
||||
free(daemon);
|
||||
@@ -328,24 +572,11 @@ daemon_init(void)
|
||||
acl_list_delete(daemon->acl_interface);
|
||||
acl_list_delete(daemon->acl);
|
||||
tcl_list_delete(daemon->tcl);
|
||||
arl_list_delete(daemon->arl);
|
||||
edns_known_options_delete(daemon->env);
|
||||
free(daemon->env);
|
||||
free(daemon);
|
||||
return NULL;
|
||||
}
|
||||
if(!(daemon->env->tsig_key_table = tsig_key_table_create())) {
|
||||
auth_zones_delete(daemon->env->auth_zones);
|
||||
acl_list_delete(daemon->acl_interface);
|
||||
acl_list_delete(daemon->acl);
|
||||
tcl_list_delete(daemon->tcl);
|
||||
arl_list_delete(daemon->arl);
|
||||
edns_known_options_delete(daemon->env);
|
||||
edns_strings_delete(daemon->env->edns_strings);
|
||||
free(daemon->env);
|
||||
free(daemon);
|
||||
return NULL;
|
||||
}
|
||||
return daemon;
|
||||
}
|
||||
|
||||
@@ -584,9 +815,11 @@ daemon_create_workers(struct daemon* daemon)
|
||||
verbose(VERB_ALGO, "total of %d outgoing ports available", numport);
|
||||
|
||||
#ifdef HAVE_NGTCP2
|
||||
daemon->doq_table = doq_table_create(daemon->cfg, daemon->rand);
|
||||
if(!daemon->doq_table)
|
||||
fatal_exit("could not create doq_table: out of memory");
|
||||
if (cfg_has_quic(daemon->cfg)) {
|
||||
daemon->doq_table = doq_table_create(daemon->cfg, daemon->rand);
|
||||
if(!daemon->doq_table)
|
||||
fatal_exit("could not create doq_table: out of memory");
|
||||
}
|
||||
#endif
|
||||
|
||||
daemon->num = (daemon->cfg->num_threads?daemon->cfg->num_threads:1);
|
||||
@@ -657,6 +890,25 @@ static void close_other_pipes(struct daemon* daemon, int thr)
|
||||
}
|
||||
#endif /* THREADS_DISABLED */
|
||||
|
||||
/**
|
||||
* Function to set the thread local log ID.
|
||||
* Either the internal thread number, or the LWP ID on Linux based on
|
||||
* configuration.
|
||||
*/
|
||||
static void
|
||||
set_log_thread_id(struct worker* worker, struct config_file* cfg)
|
||||
{
|
||||
(void)cfg;
|
||||
log_assert(worker);
|
||||
#if defined(HAVE_GETTID) && !defined(THREADS_DISABLED)
|
||||
worker->thread_tid = gettid();
|
||||
if(cfg->log_thread_id)
|
||||
log_thread_set(&worker->thread_tid);
|
||||
else
|
||||
#endif
|
||||
log_thread_set(&worker->thread_num);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to start one thread.
|
||||
* @param arg: user argument.
|
||||
@@ -667,7 +919,14 @@ thread_start(void* arg)
|
||||
{
|
||||
struct worker* worker = (struct worker*)arg;
|
||||
int port_num = 0;
|
||||
log_thread_set(&worker->thread_num);
|
||||
log_assert(worker->thr_id);
|
||||
set_log_thread_id(worker, worker->daemon->cfg);
|
||||
{
|
||||
char name[16]; /* seems to be the safest size between
|
||||
different OSes */
|
||||
snprintf(name, sizeof(name), "unbound/%u", worker->thread_num);
|
||||
ub_thread_setname(worker->thr_id, name);
|
||||
}
|
||||
ub_thread_blocksigs();
|
||||
#ifdef THREADS_DISABLED
|
||||
/* close pipe ends used by main */
|
||||
@@ -742,6 +1001,7 @@ daemon_fork(struct daemon* daemon)
|
||||
#endif
|
||||
|
||||
log_assert(daemon);
|
||||
daemon_reload_sslctxs(daemon);
|
||||
if(!(daemon->env->views = views_create()))
|
||||
fatal_exit("Could not create views: out of memory");
|
||||
/* create individual views and their localzone/data trees */
|
||||
@@ -755,8 +1015,6 @@ daemon_fork(struct daemon* daemon)
|
||||
fatal_exit("Could not setup interface control list");
|
||||
if(!tcl_list_apply_cfg(daemon->tcl, daemon->cfg))
|
||||
fatal_exit("Could not setup TCP connection limits");
|
||||
if(!arl_list_apply_cfg(daemon->arl, daemon->cfg))
|
||||
fatal_exit("Could not setup allow response list");
|
||||
if(daemon->cfg->dnscrypt) {
|
||||
#ifdef USE_DNSCRYPT
|
||||
daemon->dnscenv = dnsc_create();
|
||||
@@ -799,17 +1057,12 @@ daemon_fork(struct daemon* daemon)
|
||||
daemon->use_response_ip = !respip_set_is_empty(
|
||||
daemon->env->respip_set) || have_view_respip_cfg;
|
||||
|
||||
/* setup tsig keys */
|
||||
if(!tsig_key_table_apply_cfg(daemon->env->tsig_key_table, daemon->cfg))
|
||||
fatal_exit("Could not set up TSIG keys");
|
||||
|
||||
/* setup modules */
|
||||
daemon_setup_modules(daemon);
|
||||
|
||||
/* read auth zonefiles */
|
||||
if(!auth_zones_apply_cfg(daemon->env->auth_zones, daemon->cfg, 1,
|
||||
&daemon->use_rpz, daemon->env, &daemon->mods,
|
||||
daemon->env->tsig_key_table))
|
||||
&daemon->use_rpz, daemon->env, &daemon->mods))
|
||||
fatal_exit("auth_zones could not be setup");
|
||||
|
||||
/* Set-up EDNS strings */
|
||||
@@ -834,9 +1087,19 @@ daemon_fork(struct daemon* daemon)
|
||||
fatal_exit("RPZ requires the respip module");
|
||||
|
||||
/* first create all the worker structures, so we can pass
|
||||
* them to the newly created threads.
|
||||
* them to the newly created threads.
|
||||
*/
|
||||
daemon_create_workers(daemon);
|
||||
/* Set it for the first (main) worker since it does not take part in
|
||||
* the thread_start() procedure.
|
||||
*/
|
||||
set_log_thread_id(daemon->workers[0], daemon->cfg);
|
||||
/* If shm stats need an offset, calculate it */
|
||||
if(daemon->cfg->shm_enable && daemon->cfg->stat_interval > 0) {
|
||||
daemon->stat_time_specific = 1;
|
||||
daemon->stat_time_offset =
|
||||
((int)time(NULL))%daemon->cfg->stat_interval;
|
||||
}
|
||||
|
||||
#if defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP)
|
||||
/* in libev the first inited base gets signals */
|
||||
@@ -950,8 +1213,10 @@ daemon_cleanup(struct daemon* daemon)
|
||||
daemon->dnscenv = NULL;
|
||||
#endif
|
||||
#ifdef HAVE_NGTCP2
|
||||
doq_table_delete(daemon->doq_table);
|
||||
daemon->doq_table = NULL;
|
||||
if (daemon->doq_table) {
|
||||
doq_table_delete(daemon->doq_table);
|
||||
daemon->doq_table = NULL;
|
||||
}
|
||||
#endif
|
||||
daemon->cfg = NULL;
|
||||
}
|
||||
@@ -977,29 +1242,19 @@ daemon_delete(struct daemon* daemon)
|
||||
edns_known_options_delete(daemon->env);
|
||||
edns_strings_delete(daemon->env->edns_strings);
|
||||
auth_zones_delete(daemon->env->auth_zones);
|
||||
tsig_key_table_delete(daemon->env->tsig_key_table);
|
||||
}
|
||||
ub_randfree(daemon->rand);
|
||||
alloc_clear(&daemon->superalloc);
|
||||
acl_list_delete(daemon->acl);
|
||||
acl_list_delete(daemon->acl_interface);
|
||||
tcl_list_delete(daemon->tcl);
|
||||
arl_list_delete(daemon->arl);
|
||||
cookie_secrets_delete(daemon->cookie_secrets);
|
||||
listen_desetup_locks();
|
||||
free(daemon->chroot);
|
||||
free(daemon->pidfile);
|
||||
free(daemon->cfgfile);
|
||||
free(daemon->env);
|
||||
#ifdef HAVE_SSL
|
||||
listen_sslctx_delete_ticket_keys();
|
||||
SSL_CTX_free((SSL_CTX*)daemon->listen_dot_sslctx);
|
||||
SSL_CTX_free((SSL_CTX*)daemon->listen_doh_sslctx);
|
||||
SSL_CTX_free((SSL_CTX*)daemon->connect_dot_sslctx);
|
||||
#endif
|
||||
#ifdef HAVE_NGTCP2
|
||||
SSL_CTX_free((SSL_CTX*)daemon->listen_quic_sslctx);
|
||||
#endif
|
||||
daemon_delete_sslctxs(daemon);
|
||||
free(daemon);
|
||||
/* lex cleanup */
|
||||
ub_c_lex_destroy();
|
||||
|
||||
+41
-2
@@ -107,6 +107,18 @@ struct daemon {
|
||||
void* listen_doh_sslctx;
|
||||
/** ssl context for listening to quic */
|
||||
void* listen_quic_sslctx;
|
||||
/** the file name that the ssl context is made with, private key. */
|
||||
char* ssl_service_key;
|
||||
/** the file name that the ssl context is made with, certificate. */
|
||||
char* ssl_service_pem;
|
||||
/** modification time for ssl_service_key, in sec and ns. Like
|
||||
* in a struct timespec, but without that for portability. */
|
||||
time_t mtime_ssl_service_key;
|
||||
long mtime_ns_ssl_service_key;
|
||||
/** modification time for ssl_service_pem, in sec and ns. Like
|
||||
* in a struct timespec, but without that for portability. */
|
||||
time_t mtime_ssl_service_pem;
|
||||
long mtime_ns_ssl_service_pem;
|
||||
/** num threads allocated */
|
||||
int num;
|
||||
/** num threads allocated in the previous config or 0 at first */
|
||||
@@ -133,8 +145,6 @@ struct daemon {
|
||||
struct acl_list* acl_interface;
|
||||
/** TCP connection limit, limit connections from client IPs */
|
||||
struct tcl_list* tcl;
|
||||
/** allow response list, to cache responses send by client IPs */
|
||||
struct arl_list* arl;
|
||||
/** local authority zones */
|
||||
struct local_zones* local_zones;
|
||||
/** last time of statistics printout */
|
||||
@@ -145,7 +155,14 @@ struct daemon {
|
||||
/** the dnstap environment master value, copied and changed by threads*/
|
||||
struct dt_env* dtenv;
|
||||
#endif
|
||||
/** The SHM info for shared memory stats. */
|
||||
struct shm_main_info* shm_info;
|
||||
/** if the timeout for statistics is attempted at specific offset.
|
||||
* If it is true, the stat timeout is the interval+offset, and that
|
||||
* picks (roughly) the same time offset every time period. */
|
||||
int stat_time_specific;
|
||||
/** if the timeout is specific, what offset in the period. */
|
||||
int stat_time_offset;
|
||||
/** some response-ip tags or actions are configured if true */
|
||||
int use_response_ip;
|
||||
/** some RPZ policies are configured */
|
||||
@@ -231,4 +248,26 @@ void daemon_apply_cfg(struct daemon* daemon, struct config_file* cfg);
|
||||
*/
|
||||
int setup_acl_for_ports(struct acl_list* list, struct listen_port* port_list);
|
||||
|
||||
/* setups the needed ssl contexts, fatal_exit() on any failure */
|
||||
void daemon_setup_sslctxs(struct daemon* daemon, struct config_file* cfg);
|
||||
|
||||
/** See if the SSL cert files have changed */
|
||||
int ssl_cert_changed(struct daemon* daemon, struct config_file* cfg);
|
||||
|
||||
/** Setup the listening DoT SSL_CTX, returns the ssl ctx. */
|
||||
void* daemon_setup_listen_dot_sslctx(struct daemon* daemon,
|
||||
struct config_file* cfg);
|
||||
|
||||
/** Setup the listening DoH SSL_CTX, returns the ssl ctx. */
|
||||
void* daemon_setup_listen_doh_sslctx(struct daemon* daemon,
|
||||
struct config_file* cfg);
|
||||
|
||||
/** Setup the listening Quic SSL_CTX, returns the ssl ctx */
|
||||
void* daemon_setup_listen_quic_sslctx(struct daemon* daemon,
|
||||
struct config_file* cfg);
|
||||
|
||||
/** Setup the connect DoT SSL_CTX, returns the ssl ctx */
|
||||
void* daemon_setup_connect_dot_sslctx(struct daemon* daemon,
|
||||
struct config_file* cfg);
|
||||
|
||||
#endif /* DAEMON_H */
|
||||
|
||||
+311
-56
@@ -97,9 +97,7 @@
|
||||
#include "sldns/sbuffer.h"
|
||||
#include "util/timeval_func.h"
|
||||
#include "util/tcp_conn_limit.h"
|
||||
#include "util/allow_response_list.h"
|
||||
#include "util/edns.h"
|
||||
#include "util/tsig.h"
|
||||
#ifdef USE_CACHEDB
|
||||
#include "cachedb/cachedb.h"
|
||||
#endif
|
||||
@@ -155,7 +153,7 @@ remote_setup_ctx(struct daemon_remote* rc, struct config_file* cfg)
|
||||
log_crypto_err("could not SSL_CTX_new");
|
||||
return 0;
|
||||
}
|
||||
if(!listen_sslctx_setup(rc->ctx, cfg->tls_use_system_policy_versions)) {
|
||||
if(!listen_sslctx_setup(rc->ctx, cfg->tls_protocols)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -309,6 +307,26 @@ add_open(const char* ip, int nr, struct listen_port** list, int noproto_is_err,
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
char* s = strchr(ip, '@');
|
||||
char newif[128];
|
||||
if(s) {
|
||||
/* override port with ifspec@port */
|
||||
int portnr;
|
||||
if((size_t)(s-ip) >= sizeof(newif)) {
|
||||
log_err("ifname too long: %s", ip);
|
||||
return -1;
|
||||
}
|
||||
portnr = atoi(s+1);
|
||||
if(portnr < 0 || 0 == portnr || portnr > 65535) {
|
||||
log_err("invalid portnumber in control-interface: %s", ip);
|
||||
return -1;
|
||||
}
|
||||
(void)strlcpy(newif, ip, sizeof(newif));
|
||||
newif[s-ip] = 0;
|
||||
ip = newif;
|
||||
snprintf(port, sizeof(port), "%d", portnr);
|
||||
port[sizeof(port)-1]=0;
|
||||
}
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
|
||||
if((r = getaddrinfo(ip, port, &hints, &res)) != 0 || !res) {
|
||||
@@ -803,6 +821,8 @@ print_stats(RES* ssl, const char* nm, struct ub_stats_info* s)
|
||||
(unsigned long)s->svr.num_queries_cookie_invalid)) return 0;
|
||||
if(!ssl_printf(ssl, "%s.num.queries_discard_timeout"SQ"%lu\n", nm,
|
||||
(unsigned long)s->svr.num_queries_discard_timeout)) return 0;
|
||||
if(!ssl_printf(ssl, "%s.num.queries_replyaddr_limit"SQ"%lu\n", nm,
|
||||
(unsigned long)s->svr.num_queries_replyaddr_limit)) return 0;
|
||||
if(!ssl_printf(ssl, "%s.num.queries_wait_limit"SQ"%lu\n", nm,
|
||||
(unsigned long)s->svr.num_queries_wait_limit)) return 0;
|
||||
if(!ssl_printf(ssl, "%s.num.cachehits"SQ"%lu\n", nm,
|
||||
@@ -847,6 +867,8 @@ print_stats(RES* ssl, const char* nm, struct ub_stats_info* s)
|
||||
(unsigned long)s->mesh_num_states)) return 0;
|
||||
if(!ssl_printf(ssl, "%s.requestlist.current.user"SQ"%lu\n", nm,
|
||||
(unsigned long)s->mesh_num_reply_states)) return 0;
|
||||
if(!ssl_printf(ssl, "%s.requestlist.current.replies"SQ"%lu\n", nm,
|
||||
(unsigned long)s->mesh_num_reply_addrs)) return 0;
|
||||
#ifndef S_SPLINT_S
|
||||
sumwait.tv_sec = s->mesh_replies_sum_wait_sec;
|
||||
sumwait.tv_usec = s->mesh_replies_sum_wait_usec;
|
||||
@@ -4631,6 +4653,26 @@ fr_init_time(struct timeval* time_start, struct timeval* time_read,
|
||||
* are kept in here. They can then be deleted.
|
||||
*/
|
||||
struct fast_reload_construct {
|
||||
/** ssl context for listening to dnstcp over ssl */
|
||||
void* listen_dot_sslctx;
|
||||
/** ssl context for connecting to dnstcp over ssl */
|
||||
void* connect_dot_sslctx;
|
||||
/** ssl context for listening to DoH */
|
||||
void* listen_doh_sslctx;
|
||||
/** ssl context for listening to quic */
|
||||
void* listen_quic_sslctx;
|
||||
/** the file name that the ssl context is made with, private key. */
|
||||
char* ssl_service_key;
|
||||
/** the file name that the ssl context is made with, certificate. */
|
||||
char* ssl_service_pem;
|
||||
/** modification time for ssl_service_key, in sec and ns. Like
|
||||
* in a struct timespec, but without that for portability. */
|
||||
time_t mtime_ssl_service_key;
|
||||
long mtime_ns_ssl_service_key;
|
||||
/** modification time for ssl_service_pem, in sec and ns. Like
|
||||
* in a struct timespec, but without that for portability. */
|
||||
time_t mtime_ssl_service_pem;
|
||||
long mtime_ns_ssl_service_pem;
|
||||
/** construct for views */
|
||||
struct views* views;
|
||||
/** construct for auth zones */
|
||||
@@ -4647,10 +4689,6 @@ struct fast_reload_construct {
|
||||
struct acl_list* acl_interface;
|
||||
/** construct for tcp connection limit */
|
||||
struct tcl_list* tcl;
|
||||
/** construct for allow response list */
|
||||
struct arl_list* arl;
|
||||
/** tsig key table */
|
||||
struct tsig_key_table* tsig_key_table;
|
||||
/** construct for local zones */
|
||||
struct local_zones* local_zones;
|
||||
/** if there is response ip configuration in use */
|
||||
@@ -4938,9 +4976,7 @@ fr_check_compat_cfg(struct fast_reload_thread* fr, struct config_file* newcfg)
|
||||
FR_CHECK_CHANGED_CFG("http_notls_downstream", http_notls_downstream, changed_str);
|
||||
FR_CHECK_CHANGED_CFG("https-port", https_port, changed_str);
|
||||
FR_CHECK_CHANGED_CFG("tls-port", ssl_port, changed_str);
|
||||
FR_CHECK_CHANGED_CFG_STR("tls-service-key", ssl_service_key, changed_str);
|
||||
FR_CHECK_CHANGED_CFG_STR("tls-service-pem", ssl_service_pem, changed_str);
|
||||
FR_CHECK_CHANGED_CFG_STR("tls-cert-bundle", tls_cert_bundle, changed_str);
|
||||
FR_CHECK_CHANGED_CFG_STR("tls-protocols", tls_protocols, changed_str);
|
||||
FR_CHECK_CHANGED_CFG_STRLIST("proxy-protocol-port", proxy_protocol_port, changed_str);
|
||||
FR_CHECK_CHANGED_CFG_STRLIST("tls-additional-port", tls_additional_port, changed_str);
|
||||
FR_CHECK_CHANGED_CFG_STR("interface-automatic-ports", if_automatic_ports, changed_str);
|
||||
@@ -5037,8 +5073,6 @@ fr_construct_clear(struct fast_reload_construct* ct)
|
||||
acl_list_delete(ct->acl);
|
||||
acl_list_delete(ct->acl_interface);
|
||||
tcl_list_delete(ct->tcl);
|
||||
arl_list_delete(ct->arl);
|
||||
tsig_key_table_delete(ct->tsig_key_table);
|
||||
edns_strings_delete(ct->edns_strings);
|
||||
anchors_delete(ct->anchors);
|
||||
views_delete(ct->views);
|
||||
@@ -5051,6 +5085,19 @@ fr_construct_clear(struct fast_reload_construct* ct)
|
||||
wait_limits_free(&ct->wait_limits_netblock);
|
||||
wait_limits_free(&ct->wait_limits_cookie_netblock);
|
||||
domain_limits_free(&ct->domain_limits);
|
||||
#ifdef HAVE_SSL
|
||||
/* The SSL contexts can be SSL_CTX_free here. It is reference
|
||||
* counted. So ongoing transfers with can continue.
|
||||
* Once they are done, the context is freed. */
|
||||
SSL_CTX_free((SSL_CTX*)ct->listen_dot_sslctx);
|
||||
SSL_CTX_free((SSL_CTX*)ct->connect_dot_sslctx);
|
||||
SSL_CTX_free((SSL_CTX*)ct->listen_doh_sslctx);
|
||||
#endif /* HAVE_SSL */
|
||||
#ifdef HAVE_NGTCP2
|
||||
SSL_CTX_free((SSL_CTX*)ct->listen_quic_sslctx);
|
||||
#endif
|
||||
free(ct->ssl_service_key);
|
||||
free(ct->ssl_service_pem);
|
||||
/* Delete the log identity here so that the global value is not
|
||||
* reset by config_delete. */
|
||||
if(ct->oldcfg && ct->oldcfg->log_identity) {
|
||||
@@ -5141,8 +5188,6 @@ getmem_config_auth(struct config_auth* p)
|
||||
+ getmem_config_strlist(s->masters)
|
||||
+ getmem_config_strlist(s->urls)
|
||||
+ getmem_config_strlist(s->allow_notify)
|
||||
+ getmem_config_str2list(s->masters_tsig)
|
||||
+ getmem_config_str2list(s->allow_notify_tsig)
|
||||
+ getmem_str(s->zonefile)
|
||||
+ s->rpz_taglistlen
|
||||
+ getmem_str(s->rpz_action_override)
|
||||
@@ -5185,6 +5230,7 @@ config_file_getmem(struct config_file* cfg)
|
||||
m += getmem_config_strlist(cfg->tls_session_ticket_keys.first);
|
||||
m += getmem_str(cfg->tls_ciphers);
|
||||
m += getmem_str(cfg->tls_ciphersuites);
|
||||
m += getmem_str(cfg->tls_protocols);
|
||||
m += getmem_str(cfg->http_endpoint);
|
||||
m += (cfg->outgoing_avail_ports?65536*sizeof(int):0);
|
||||
m += getmem_str(cfg->target_fetch_policy);
|
||||
@@ -5237,7 +5283,6 @@ config_file_getmem(struct config_file* cfg)
|
||||
m += getmem_config_str3list(cfg->acl_tag_datas);
|
||||
m += getmem_config_str2list(cfg->acl_view);
|
||||
m += getmem_config_str2list(cfg->interface_actions);
|
||||
m += getmem_config_str2list(cfg->allow_response_list);
|
||||
m += getmem_config_strbytelist(cfg->interface_tags);
|
||||
m += getmem_config_str3list(cfg->interface_tag_actions);
|
||||
m += getmem_config_str3list(cfg->interface_tag_datas);
|
||||
@@ -5302,17 +5347,17 @@ fr_printmem(struct fast_reload_thread* fr,
|
||||
size_t mem = 0;
|
||||
if(fr_poll_for_quit(fr))
|
||||
return 1;
|
||||
mem += getmem_str(ct->ssl_service_key);
|
||||
mem += getmem_str(ct->ssl_service_pem);
|
||||
mem += views_get_mem(ct->views);
|
||||
mem += respip_set_get_mem(ct->respip_set);
|
||||
mem += auth_zones_get_mem(ct->auth_zones);
|
||||
mem += forwards_get_mem(ct->fwds);
|
||||
mem += hints_get_mem(ct->hints);
|
||||
mem += tsig_key_table_get_mem(ct->tsig_key_table);
|
||||
mem += local_zones_get_mem(ct->local_zones);
|
||||
mem += acl_list_get_mem(ct->acl);
|
||||
mem += acl_list_get_mem(ct->acl_interface);
|
||||
mem += tcl_list_get_mem(ct->tcl);
|
||||
mem += arl_list_get_mem(ct->arl);
|
||||
mem += edns_strings_get_mem(ct->edns_strings);
|
||||
mem += anchors_get_mem(ct->anchors);
|
||||
mem += sizeof(*ct->oldcfg);
|
||||
@@ -5397,12 +5442,6 @@ xfr_auth_master_equal(struct auth_master* m1, struct auth_master* m2)
|
||||
return 0;
|
||||
if(m1->port != m2->port)
|
||||
return 0;
|
||||
|
||||
if((m1->tsig_key_name && !m2->tsig_key_name) || (!m1->tsig_key_name && m2->tsig_key_name))
|
||||
return 0;
|
||||
if(m1->tsig_key_name && m2->tsig_key_name && strcmp(m1->tsig_key_name, m2->tsig_key_name) != 0)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -5543,6 +5582,96 @@ auth_zones_check_changes(struct fast_reload_thread* fr,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** Check if the sslctxs have changed. */
|
||||
static int
|
||||
fr_check_sslctx_change(struct fast_reload_thread* fr,
|
||||
struct config_file* newcfg)
|
||||
{
|
||||
#ifdef HAVE_SSL
|
||||
struct daemon* daemon = fr->worker->daemon;
|
||||
if(newcfg->ssl_service_key && newcfg->ssl_service_key[0]) {
|
||||
if(!daemon->ssl_service_key ||
|
||||
ssl_cert_changed(daemon, newcfg))
|
||||
return 1;
|
||||
} else {
|
||||
if(daemon->ssl_service_key)
|
||||
return 1; /* it is removed */
|
||||
}
|
||||
if((daemon->cfg->tls_cert_bundle && !newcfg->tls_cert_bundle) ||
|
||||
(!daemon->cfg->tls_cert_bundle && newcfg->tls_cert_bundle) ||
|
||||
(daemon->cfg->tls_cert_bundle && newcfg->tls_cert_bundle &&
|
||||
strcmp(daemon->cfg->tls_cert_bundle, newcfg->tls_cert_bundle)!=0))
|
||||
return 1; /* The tls-cert-bundle has changed and return
|
||||
true here makes it reload the connect_dot_sslctx. */
|
||||
#else
|
||||
(void)fr; (void)newcfg;
|
||||
#endif /* HAVE_SSL */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Create the SSL CTXs when they have changed. */
|
||||
static int
|
||||
ct_create_sslctxs(struct fast_reload_construct* ct,
|
||||
struct config_file* newcfg, struct daemon* daemon)
|
||||
{
|
||||
#ifdef HAVE_SSL
|
||||
char* chroot = daemon->chroot;
|
||||
char* key = newcfg->ssl_service_key;
|
||||
char* pem = newcfg->ssl_service_pem;
|
||||
|
||||
if(!(newcfg->ssl_service_key && newcfg->ssl_service_key[0])) {
|
||||
/* Leave listen ctxs and file str at NULL */
|
||||
ct->connect_dot_sslctx = daemon_setup_connect_dot_sslctx(
|
||||
daemon, newcfg);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(chroot && strncmp(key, chroot, strlen(chroot)) == 0)
|
||||
key += strlen(chroot);
|
||||
if(chroot && pem && strncmp(pem, chroot, strlen(chroot)) == 0)
|
||||
pem += strlen(chroot);
|
||||
|
||||
ct->listen_dot_sslctx = daemon_setup_listen_dot_sslctx(daemon, newcfg);
|
||||
#ifdef HAVE_NGHTTP2_NGHTTP2_H
|
||||
if(cfg_has_https(newcfg)) {
|
||||
ct->listen_doh_sslctx = daemon_setup_listen_doh_sslctx(
|
||||
daemon, newcfg);
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_NGTCP2
|
||||
if(cfg_has_quic(newcfg)) {
|
||||
ct->listen_quic_sslctx = daemon_setup_listen_quic_sslctx(
|
||||
daemon, newcfg);
|
||||
}
|
||||
#endif /* HAVE_NGTCP2 */
|
||||
ct->connect_dot_sslctx = daemon_setup_connect_dot_sslctx(daemon,
|
||||
newcfg);
|
||||
|
||||
/* Store mtime and names */
|
||||
ct->ssl_service_key = strdup(newcfg->ssl_service_key);
|
||||
if(!ct->ssl_service_key) {
|
||||
log_err("ct_create_sslctxs: out of memory");
|
||||
return 0;
|
||||
}
|
||||
ct->ssl_service_pem = strdup(newcfg->ssl_service_pem);
|
||||
if(!ct->ssl_service_pem) {
|
||||
log_err("ct_create_sslctxs: out of memory");
|
||||
return 0;
|
||||
}
|
||||
if(!file_get_mtime(key, &ct->mtime_ssl_service_key,
|
||||
&ct->mtime_ns_ssl_service_key, NULL))
|
||||
log_err("Could not stat(%s): %s",
|
||||
key, strerror(errno));
|
||||
if(!file_get_mtime(pem, &ct->mtime_ssl_service_pem,
|
||||
&ct->mtime_ns_ssl_service_pem, NULL))
|
||||
log_err("Could not stat(%s): %s",
|
||||
pem, strerror(errno));
|
||||
#else
|
||||
(void)ct; (void)newcfg; (void)daemon;
|
||||
#endif /* HAVE_SSL */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** fast reload thread, construct from config the new items */
|
||||
static int
|
||||
fr_construct_from_config(struct fast_reload_thread* fr,
|
||||
@@ -5550,6 +5679,13 @@ fr_construct_from_config(struct fast_reload_thread* fr,
|
||||
{
|
||||
int have_view_respip_cfg = 0;
|
||||
|
||||
fr->sslctxs_changed = fr_check_sslctx_change(fr, newcfg);
|
||||
if(fr->sslctxs_changed) {
|
||||
if(!ct_create_sslctxs(ct, newcfg, fr->worker->daemon)) {
|
||||
fr_construct_clear(ct);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if(!(ct->views = views_create())) {
|
||||
fr_construct_clear(ct);
|
||||
return 0;
|
||||
@@ -5602,35 +5738,12 @@ fr_construct_from_config(struct fast_reload_thread* fr,
|
||||
if(fr_poll_for_quit(fr))
|
||||
return 1;
|
||||
|
||||
if(!(ct->arl = arl_list_create())) {
|
||||
fr_construct_clear(ct);
|
||||
return 0;
|
||||
}
|
||||
if(!arl_list_apply_cfg(ct->arl, newcfg)) {
|
||||
fr_construct_clear(ct);
|
||||
return 0;
|
||||
}
|
||||
if(fr_poll_for_quit(fr))
|
||||
return 1;
|
||||
|
||||
if(!(ct->tsig_key_table = tsig_key_table_create())) {
|
||||
fr_construct_clear(ct);
|
||||
return 0;
|
||||
}
|
||||
if(!tsig_key_table_apply_cfg(ct->tsig_key_table, newcfg)) {
|
||||
fr_construct_clear(ct);
|
||||
return 0;
|
||||
}
|
||||
if(fr_poll_for_quit(fr))
|
||||
return 1;
|
||||
|
||||
if(!(ct->auth_zones = auth_zones_create())) {
|
||||
fr_construct_clear(ct);
|
||||
return 0;
|
||||
}
|
||||
if(!auth_zones_apply_cfg(ct->auth_zones, newcfg, 1, &ct->use_rpz,
|
||||
fr->worker->daemon->env, &fr->worker->daemon->mods,
|
||||
ct->tsig_key_table)) {
|
||||
fr->worker->daemon->env, &fr->worker->daemon->mods)) {
|
||||
fr_construct_clear(ct);
|
||||
return 0;
|
||||
}
|
||||
@@ -5850,6 +5963,44 @@ auth_zones_swap(struct auth_zones* az, struct auth_zones* data)
|
||||
* the xfer elements can continue to be their callbacks. */
|
||||
}
|
||||
|
||||
/** Swap two void* */
|
||||
static void
|
||||
void_ptr_swap(void** a, void **b)
|
||||
{
|
||||
void* tmp = *a;
|
||||
*a = *b;
|
||||
*b = tmp;
|
||||
}
|
||||
|
||||
/** Swap two char* */
|
||||
static void
|
||||
char_ptr_swap(char** a, char **b)
|
||||
{
|
||||
char* tmp = *a;
|
||||
*a = *b;
|
||||
*b = tmp;
|
||||
}
|
||||
|
||||
/** Swap and set ssl ctx information */
|
||||
static void
|
||||
sslctxs_swap(struct daemon* daemon, struct fast_reload_construct* ct)
|
||||
{
|
||||
void_ptr_swap(&daemon->listen_dot_sslctx, &ct->listen_dot_sslctx);
|
||||
void_ptr_swap(&daemon->connect_dot_sslctx, &ct->connect_dot_sslctx);
|
||||
#ifdef HAVE_NGHTTP2_NGHTTP2_H
|
||||
void_ptr_swap(&daemon->listen_doh_sslctx, &ct->listen_doh_sslctx);
|
||||
#endif
|
||||
#ifdef HAVE_NGTCP2
|
||||
void_ptr_swap(&daemon->listen_quic_sslctx, &ct->listen_quic_sslctx);
|
||||
#endif /* HAVE_NGTCP2 */
|
||||
char_ptr_swap(&daemon->ssl_service_key, &ct->ssl_service_key);
|
||||
char_ptr_swap(&daemon->ssl_service_pem, &ct->ssl_service_pem);
|
||||
daemon->mtime_ssl_service_key = ct->mtime_ssl_service_key;
|
||||
daemon->mtime_ns_ssl_service_key = ct->mtime_ns_ssl_service_key;
|
||||
daemon->mtime_ssl_service_pem = ct->mtime_ssl_service_pem;
|
||||
daemon->mtime_ns_ssl_service_pem = ct->mtime_ns_ssl_service_pem;
|
||||
}
|
||||
|
||||
#if defined(ATOMIC_POINTER_LOCK_FREE) && defined(HAVE_LINK_ATOMIC_STORE)
|
||||
/** Fast reload thread, if atomics are available, copy the config items
|
||||
* one by one with atomic store operations. */
|
||||
@@ -5911,8 +6062,8 @@ fr_atomic_copy_cfg(struct config_file* oldcfg, struct config_file* cfg,
|
||||
COPY_VAR_ptr(tls_session_ticket_keys.last);
|
||||
COPY_VAR_ptr(tls_ciphers);
|
||||
COPY_VAR_ptr(tls_ciphersuites);
|
||||
COPY_VAR_ptr(tls_protocols);
|
||||
COPY_VAR_int(tls_use_sni);
|
||||
COPY_VAR_int(tls_use_system_policy_versions);
|
||||
COPY_VAR_int(https_port);
|
||||
COPY_VAR_ptr(http_endpoint);
|
||||
COPY_VAR_uint32_t(http_max_streams);
|
||||
@@ -5960,7 +6111,6 @@ fr_atomic_copy_cfg(struct config_file* oldcfg, struct config_file* cfg,
|
||||
COPY_VAR_ptr(forwards);
|
||||
COPY_VAR_ptr(auths);
|
||||
COPY_VAR_ptr(views);
|
||||
COPY_VAR_ptr(tsig_keys);
|
||||
COPY_VAR_ptr(donotqueryaddrs);
|
||||
#ifdef CLIENT_SUBNET
|
||||
COPY_VAR_ptr(client_subnet);
|
||||
@@ -6011,6 +6161,7 @@ fr_atomic_copy_cfg(struct config_file* oldcfg, struct config_file* cfg,
|
||||
COPY_VAR_int(log_servfail);
|
||||
COPY_VAR_ptr(log_identity);
|
||||
COPY_VAR_int(log_destaddr);
|
||||
COPY_VAR_int(log_thread_id);
|
||||
COPY_VAR_int(hide_identity);
|
||||
COPY_VAR_int(hide_version);
|
||||
COPY_VAR_int(hide_trustanchor);
|
||||
@@ -6078,7 +6229,6 @@ fr_atomic_copy_cfg(struct config_file* oldcfg, struct config_file* cfg,
|
||||
*/
|
||||
COPY_VAR_ptr(acl_view);
|
||||
COPY_VAR_ptr(interface_actions);
|
||||
COPY_VAR_ptr(allow_response_list);
|
||||
/* These reference tags
|
||||
COPY_VAR_ptr(interface_tags);
|
||||
COPY_VAR_ptr(interface_tag_actions);
|
||||
@@ -6221,7 +6371,20 @@ fr_atomic_copy_cfg(struct config_file* oldcfg, struct config_file* cfg,
|
||||
COPY_VAR_ptr(ipset_name_v6);
|
||||
#endif
|
||||
COPY_VAR_int(ede);
|
||||
COPY_VAR_int(iter_scrub_ns);
|
||||
COPY_VAR_int(iter_scrub_cname);
|
||||
COPY_VAR_int(iter_scrub_rrsig);
|
||||
COPY_VAR_int(max_global_quota);
|
||||
COPY_VAR_int(iter_scrub_promiscuous);
|
||||
|
||||
#undef COPY_VAR_int
|
||||
#undef COPY_VAR_ptr
|
||||
#undef COPY_VAR_unsigned_int
|
||||
#undef COPY_VAR_size_t
|
||||
#undef COPY_VAR_uint8_t
|
||||
#undef COPY_VAR_uint16_t
|
||||
#undef COPY_VAR_uint32_t
|
||||
#undef COPY_VAR_int32_t
|
||||
}
|
||||
#endif /* ATOMIC_POINTER_LOCK_FREE && HAVE_LINK_ATOMIC_STORE */
|
||||
|
||||
@@ -6400,7 +6563,6 @@ fr_reload_config(struct fast_reload_thread* fr, struct config_file* newcfg,
|
||||
lock_basic_lock(&ct->anchors->lock);
|
||||
lock_basic_lock(&env->anchors->lock);
|
||||
}
|
||||
lock_rw_wrlock(&env->tsig_key_table->lock);
|
||||
|
||||
#if defined(ATOMIC_POINTER_LOCK_FREE) && defined(HAVE_LINK_ATOMIC_STORE)
|
||||
if(fr->fr_nopause) {
|
||||
@@ -6437,9 +6599,6 @@ fr_reload_config(struct fast_reload_thread* fr, struct config_file* newcfg,
|
||||
acl_list_swap_tree(daemon->acl, ct->acl);
|
||||
acl_list_swap_tree(daemon->acl_interface, ct->acl_interface);
|
||||
tcl_list_swap_tree(daemon->tcl, ct->tcl);
|
||||
arl_list_swap_tree(daemon->arl, ct->arl);
|
||||
tsig_key_table_swap_tree(daemon->env->tsig_key_table,
|
||||
ct->tsig_key_table);
|
||||
local_zones_swap_tree(daemon->local_zones, ct->local_zones);
|
||||
respip_set_swap_tree(env->respip_set, ct->respip_set);
|
||||
daemon->use_response_ip = ct->use_response_ip;
|
||||
@@ -6451,6 +6610,9 @@ fr_reload_config(struct fast_reload_thread* fr, struct config_file* newcfg,
|
||||
daemon->env->cachedb_enabled = cachedb_is_enabled(&daemon->mods,
|
||||
daemon->env);
|
||||
#endif
|
||||
if(fr->sslctxs_changed) {
|
||||
sslctxs_swap(daemon, ct);
|
||||
}
|
||||
#ifdef USE_DNSTAP
|
||||
if(env->cfg->dnstap) {
|
||||
if(!fr->fr_nopause)
|
||||
@@ -6486,7 +6648,6 @@ fr_reload_config(struct fast_reload_thread* fr, struct config_file* newcfg,
|
||||
lock_basic_unlock(&ct->anchors->lock);
|
||||
lock_basic_unlock(&env->anchors->lock);
|
||||
}
|
||||
lock_rw_unlock(&env->tsig_key_table->lock);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -6676,7 +6837,19 @@ static void* fast_reload_thread_main(void* arg)
|
||||
struct fast_reload_thread* fast_reload_thread = (struct fast_reload_thread*)arg;
|
||||
struct timeval time_start, time_read, time_construct, time_reload,
|
||||
time_end;
|
||||
log_thread_set(&fast_reload_thread->threadnum);
|
||||
const char name[16] = "unbound/freload"; /* seems to be the safest size
|
||||
between different OSes */
|
||||
|
||||
#if defined(HAVE_GETTID) && !defined(THREADS_DISABLED)
|
||||
fast_reload_thread->thread_tid = gettid();
|
||||
if(fast_reload_thread->thread_tid_log)
|
||||
log_thread_set(&fast_reload_thread->thread_tid);
|
||||
else
|
||||
#endif
|
||||
log_thread_set(&fast_reload_thread->threadnum);
|
||||
|
||||
ub_thread_setname(fast_reload_thread->tid, name);
|
||||
(void)name; /* When setname is not defined, ignore the name variable. */
|
||||
|
||||
verbose(VERB_ALGO, "start fast reload thread");
|
||||
if(fast_reload_thread->fr_verb >= 1) {
|
||||
@@ -7064,6 +7237,9 @@ fast_reload_thread_setup(struct worker* worker, int fr_verb, int fr_nopause,
|
||||
lock_basic_init(&fr->fr_output_lock);
|
||||
lock_protect(&fr->fr_output_lock, fr->fr_output,
|
||||
sizeof(*fr->fr_output));
|
||||
#ifdef HAVE_GETTID
|
||||
fr->thread_tid_log = worker->env.cfg->log_thread_id;
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -7638,6 +7814,44 @@ fr_worker_pickup_auth_changes(struct worker* worker,
|
||||
}
|
||||
}
|
||||
|
||||
/** Fast reload, the worker picks up changes in listen_dnsport. */
|
||||
static void
|
||||
fr_worker_pickup_listen_dnsport(struct worker* worker)
|
||||
{
|
||||
struct listen_dnsport* front = worker->front;
|
||||
struct daemon* daemon = worker->daemon;
|
||||
if(worker->daemon->fast_reload_thread->sslctxs_changed) {
|
||||
struct listen_list* ll;
|
||||
void* dot_sslctx = daemon->listen_dot_sslctx;
|
||||
void* doh_sslctx = daemon->listen_doh_sslctx;
|
||||
#ifdef HAVE_NGTCP2
|
||||
void* quic_sslctx = daemon->listen_quic_sslctx;
|
||||
#endif /* HAVE_NGTCP2 */
|
||||
for(ll = front->cps; ll; ll = ll->next) {
|
||||
struct comm_point* cp = ll->com;
|
||||
if(cp->type == comm_tcp_accept &&
|
||||
cp->tcp_handlers &&
|
||||
cp->max_tcp_count > 0 &&
|
||||
cp->tcp_handlers[0]->type == comm_http) {
|
||||
if(cp->ssl)
|
||||
cp->ssl = doh_sslctx;
|
||||
} else if(cp->type == comm_tcp_accept) {
|
||||
if(cp->ssl)
|
||||
cp->ssl = dot_sslctx;
|
||||
#ifdef HAVE_NGTCP2
|
||||
} else if(cp->type == comm_doq) {
|
||||
if(cp->ssl) {
|
||||
cp->ssl = quic_sslctx;
|
||||
if(cp->doq_socket)
|
||||
cp->doq_socket->ctx =
|
||||
(SSL_CTX*)quic_sslctx;
|
||||
}
|
||||
#endif /* HAVE_NGTCP2 */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Fast reload, the worker picks up changes in outside_network. */
|
||||
static void
|
||||
fr_worker_pickup_outside_network(struct worker* worker)
|
||||
@@ -7653,6 +7867,8 @@ fr_worker_pickup_outside_network(struct worker* worker)
|
||||
outnet->tcp_reuse_timeout = cfg->tcp_reuse_timeout;
|
||||
outnet->tcp_auth_query_timeout = cfg->tcp_auth_query_timeout;
|
||||
outnet->delayclose = cfg->delay_close;
|
||||
if(worker->daemon->fast_reload_thread->sslctxs_changed)
|
||||
outnet->sslctx = worker->daemon->connect_dot_sslctx;
|
||||
if(outnet->delayclose) {
|
||||
#ifndef S_SPLINT_S
|
||||
outnet->delay_tv.tv_sec = cfg->delay_close/1000;
|
||||
@@ -7661,6 +7877,41 @@ fr_worker_pickup_outside_network(struct worker* worker)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef USE_DNSTAP
|
||||
/** Fast reload, the worker picks up changes to DNSTAP configuration. */
|
||||
static void
|
||||
fr_worker_pickup_dnstap_changes(struct worker* worker)
|
||||
{
|
||||
struct dt_env* w_dtenv = &worker->dtenv;
|
||||
struct dt_env* d_dtenv = worker->daemon->dtenv;
|
||||
log_assert(d_dtenv != NULL || !worker->daemon->cfg->dnstap);
|
||||
if(d_dtenv == NULL) {
|
||||
/* There is no environment when DNSTAP was not enabled
|
||||
* in the configuration. */
|
||||
return;
|
||||
}
|
||||
w_dtenv->identity = d_dtenv->identity;
|
||||
w_dtenv->len_identity = d_dtenv->len_identity;
|
||||
w_dtenv->version = d_dtenv->version;
|
||||
w_dtenv->len_version = d_dtenv->len_version;
|
||||
w_dtenv->log_resolver_query_messages =
|
||||
d_dtenv->log_resolver_query_messages;
|
||||
w_dtenv->log_resolver_response_messages =
|
||||
d_dtenv->log_resolver_response_messages;
|
||||
w_dtenv->log_client_query_messages =
|
||||
d_dtenv->log_client_query_messages;
|
||||
w_dtenv->log_client_response_messages =
|
||||
d_dtenv->log_client_response_messages;
|
||||
w_dtenv->log_forwarder_query_messages =
|
||||
d_dtenv->log_forwarder_query_messages;
|
||||
w_dtenv->log_forwarder_response_messages =
|
||||
d_dtenv->log_forwarder_response_messages;
|
||||
lock_basic_lock(&d_dtenv->sample_lock);
|
||||
w_dtenv->sample_rate = d_dtenv->sample_rate;
|
||||
lock_basic_unlock(&d_dtenv->sample_lock);
|
||||
}
|
||||
#endif /* USE_DNSTAP */
|
||||
|
||||
void
|
||||
fast_reload_worker_pickup_changes(struct worker* worker)
|
||||
{
|
||||
@@ -7688,7 +7939,11 @@ fast_reload_worker_pickup_changes(struct worker* worker)
|
||||
#ifdef USE_CACHEDB
|
||||
worker->env.cachedb_enabled = worker->daemon->env->cachedb_enabled;
|
||||
#endif
|
||||
fr_worker_pickup_listen_dnsport(worker);
|
||||
fr_worker_pickup_outside_network(worker);
|
||||
#ifdef USE_DNSTAP
|
||||
fr_worker_pickup_dnstap_changes(worker);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** fast reload thread, handle reload_stop notification, send reload stop
|
||||
|
||||
@@ -206,6 +206,12 @@ struct fast_reload_thread {
|
||||
int commpair[2];
|
||||
/** thread id, of the io thread */
|
||||
ub_thread_type tid;
|
||||
#ifdef HAVE_GETTID
|
||||
/** thread tid, the LWP id */
|
||||
pid_t thread_tid;
|
||||
/** if logging should include the LWP id */
|
||||
int thread_tid_log;
|
||||
#endif
|
||||
/** if the io processing has started */
|
||||
int started;
|
||||
/** if the thread has to quit */
|
||||
@@ -249,6 +255,8 @@ struct fast_reload_thread {
|
||||
struct fast_reload_auth_change* auth_zone_change_list;
|
||||
/** the old tree of auth zones, to lookup. */
|
||||
struct auth_zones* old_auth_zones;
|
||||
/** If the ssl ctxs have changed. */
|
||||
int sslctxs_changed;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -262,6 +262,7 @@ server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset)
|
||||
s->svr = worker->stats;
|
||||
s->mesh_num_states = (long long)worker->env.mesh->all.count;
|
||||
s->mesh_num_reply_states = (long long)worker->env.mesh->num_reply_states;
|
||||
s->mesh_num_reply_addrs = (long long)worker->env.mesh->num_reply_addrs;
|
||||
s->mesh_jostled = (long long)worker->env.mesh->stats_jostled;
|
||||
s->mesh_dropped = (long long)worker->env.mesh->stats_dropped;
|
||||
s->mesh_replies_sent = (long long)worker->env.mesh->replies_sent;
|
||||
@@ -284,6 +285,8 @@ server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset)
|
||||
NUM_BUCKETS_HIST);
|
||||
s->svr.num_queries_discard_timeout +=
|
||||
(long long)worker->env.mesh->num_queries_discard_timeout;
|
||||
s->svr.num_queries_replyaddr_limit +=
|
||||
(long long)worker->env.mesh->num_queries_replyaddr_limit;
|
||||
s->svr.num_queries_wait_limit +=
|
||||
(long long)worker->env.mesh->num_queries_wait_limit;
|
||||
s->svr.num_dns_error_reports +=
|
||||
@@ -448,6 +451,8 @@ void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a)
|
||||
total->svr.num_queries_cookie_invalid += a->svr.num_queries_cookie_invalid;
|
||||
total->svr.num_queries_discard_timeout +=
|
||||
a->svr.num_queries_discard_timeout;
|
||||
total->svr.num_queries_replyaddr_limit +=
|
||||
a->svr.num_queries_replyaddr_limit;
|
||||
total->svr.num_queries_wait_limit += a->svr.num_queries_wait_limit;
|
||||
total->svr.num_dns_error_reports += a->svr.num_dns_error_reports;
|
||||
total->svr.num_queries_missed_cache += a->svr.num_queries_missed_cache;
|
||||
@@ -519,6 +524,7 @@ void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a)
|
||||
|
||||
total->mesh_num_states += a->mesh_num_states;
|
||||
total->mesh_num_reply_states += a->mesh_num_reply_states;
|
||||
total->mesh_num_reply_addrs += a->mesh_num_reply_addrs;
|
||||
total->mesh_jostled += a->mesh_jostled;
|
||||
total->mesh_dropped += a->mesh_dropped;
|
||||
total->mesh_replies_sent += a->mesh_replies_sent;
|
||||
|
||||
+4
-47
@@ -463,57 +463,13 @@ detach(void)
|
||||
#endif /* HAVE_DAEMON */
|
||||
}
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
/* setup a listening ssl context, fatal_exit() on any failure */
|
||||
/** setup the remote and ticket keys */
|
||||
static void
|
||||
setup_listen_sslctx(void** ctx, int is_dot, int is_doh, struct config_file* cfg)
|
||||
{
|
||||
if(!(*ctx = listen_sslctx_create(
|
||||
cfg->ssl_service_key, cfg->ssl_service_pem, NULL,
|
||||
cfg->tls_ciphers, cfg->tls_ciphersuites,
|
||||
(cfg->tls_session_ticket_keys.first &&
|
||||
cfg->tls_session_ticket_keys.first->str[0] != 0),
|
||||
is_dot, is_doh, cfg->tls_use_system_policy_versions))) {
|
||||
fatal_exit("could not set up listen SSL_CTX");
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_SSL */
|
||||
|
||||
/* setups the needed ssl contexts, fatal_exit() on any failure */
|
||||
static void
|
||||
setup_sslctxs(struct daemon* daemon, struct config_file* cfg)
|
||||
setup_sslctx_remote(struct daemon* daemon, struct config_file* cfg)
|
||||
{
|
||||
#ifdef HAVE_SSL
|
||||
if(!(daemon->rc = daemon_remote_create(cfg)))
|
||||
fatal_exit("could not set up remote-control");
|
||||
if(cfg->ssl_service_key && cfg->ssl_service_key[0]) {
|
||||
/* setup the session keys; the callback to use them will be
|
||||
* attached to each sslctx separately */
|
||||
if(cfg->tls_session_ticket_keys.first &&
|
||||
cfg->tls_session_ticket_keys.first->str[0] != 0) {
|
||||
if(!listen_sslctx_setup_ticket_keys(
|
||||
cfg->tls_session_ticket_keys.first)) {
|
||||
fatal_exit("could not set session ticket SSL_CTX");
|
||||
}
|
||||
}
|
||||
(void)setup_listen_sslctx(&daemon->listen_dot_sslctx, 1, 0, cfg);
|
||||
#ifdef HAVE_NGHTTP2_NGHTTP2_H
|
||||
if(cfg_has_https(cfg)) {
|
||||
(void)setup_listen_sslctx(&daemon->listen_doh_sslctx, 0, 1, cfg);
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_NGTCP2
|
||||
if(cfg_has_quic(cfg)) {
|
||||
if(!(daemon->listen_quic_sslctx = quic_sslctx_create(
|
||||
cfg->ssl_service_key, cfg->ssl_service_pem, NULL))) {
|
||||
fatal_exit("could not set up quic SSL_CTX");
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_NGTCP2 */
|
||||
}
|
||||
if(!(daemon->connect_dot_sslctx = connect_sslctx_create(NULL, NULL,
|
||||
cfg->tls_cert_bundle, cfg->tls_win_cert)))
|
||||
fatal_exit("could not set up connect SSL_CTX");
|
||||
#else /* HAVE_SSL */
|
||||
(void)daemon;(void)cfg;
|
||||
#endif /* HAVE_SSL */
|
||||
@@ -545,7 +501,8 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
|
||||
#endif
|
||||
|
||||
/* read ssl keys while superuser and outside chroot */
|
||||
(void)setup_sslctxs(daemon, cfg);
|
||||
setup_sslctx_remote(daemon, cfg);
|
||||
daemon_setup_sslctxs(daemon, cfg);
|
||||
|
||||
/* init syslog (as root) if needed, before daemonize, otherwise
|
||||
* a fork error could not be printed since daemonize closed stderr.*/
|
||||
|
||||
+188
-274
@@ -43,7 +43,6 @@
|
||||
#include "util/log.h"
|
||||
#include "util/net_help.h"
|
||||
#include "util/random.h"
|
||||
#include "util/tsig.h"
|
||||
#include "daemon/worker.h"
|
||||
#include "daemon/daemon.h"
|
||||
#include "daemon/remote.h"
|
||||
@@ -68,7 +67,6 @@
|
||||
#include "util/data/dname.h"
|
||||
#include "util/fptr_wlist.h"
|
||||
#include "util/proxy_protocol.h"
|
||||
#include "util/tsig.h"
|
||||
#include "util/tube.h"
|
||||
#include "util/edns.h"
|
||||
#include "util/timeval_func.h"
|
||||
@@ -80,13 +78,11 @@
|
||||
#include "respip/respip.h"
|
||||
#include "libunbound/context.h"
|
||||
#include "libunbound/libworker.h"
|
||||
#include "sldns/parseutil.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
#include "sldns/wire2str.h"
|
||||
#include "util/shm_side/shm_main.h"
|
||||
#include "dnscrypt/dnscrypt.h"
|
||||
#include "dnstap/dtstream.h"
|
||||
#include "util/allow_response_list.h"
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
# include <sys/types.h>
|
||||
@@ -259,7 +255,8 @@ worker_handle_service_reply(struct comm_point* c, void* arg, int error,
|
||||
return 0;
|
||||
}
|
||||
/* sanity check. */
|
||||
if(!LDNS_QR_WIRE(sldns_buffer_begin(c->buffer))
|
||||
if(sldns_buffer_limit(c->buffer) < LDNS_HEADER_SIZE
|
||||
|| !LDNS_QR_WIRE(sldns_buffer_begin(c->buffer))
|
||||
|| LDNS_OPCODE_WIRE(sldns_buffer_begin(c->buffer)) !=
|
||||
LDNS_PACKET_QUERY
|
||||
|| LDNS_QDCOUNT(sldns_buffer_begin(c->buffer)) > 1) {
|
||||
@@ -276,11 +273,6 @@ worker_handle_service_reply(struct comm_point* c, void* arg, int error,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define REQUEST_OK 0
|
||||
#define DROP_REQUEST -1
|
||||
#define RESPONSE_MESSAGE -2
|
||||
|
||||
|
||||
/** ratelimit error replies
|
||||
* @param worker: the worker struct with ratelimit counter
|
||||
* @param err: error code that would be wanted.
|
||||
@@ -292,7 +284,7 @@ worker_err_ratelimit(struct worker* worker, int err)
|
||||
if(worker->err_limit_time == *worker->env.now) {
|
||||
/* see if limit is exceeded for this second */
|
||||
if(worker->err_limit_count++ > ERROR_RATELIMIT)
|
||||
return DROP_REQUEST;
|
||||
return -1;
|
||||
} else {
|
||||
/* new second, new limits */
|
||||
worker->err_limit_time = *worker->env.now;
|
||||
@@ -301,13 +293,48 @@ worker_err_ratelimit(struct worker* worker, int err)
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reply with an error.
|
||||
* This reply includes the qname if it has been parsed.
|
||||
* For error ratelimiting, the err ratelimit routine should be checked
|
||||
* beforehand. The reply is without EDNS, and copies RD and sets QR flag.
|
||||
* @param pkt: the packet buffer from the comm point.
|
||||
* @param err: the error code that would be wanted.
|
||||
* @param qname_len: 0 if not parsed, and the qname length in packet.
|
||||
*/
|
||||
static void
|
||||
query_error(sldns_buffer* pkt, int err, size_t qname_len)
|
||||
{
|
||||
/* Preserve the RD flag.
|
||||
* The CD flag must be cleared in authoritative answers,
|
||||
* also the AD flag need not be copied into answers.
|
||||
* The other flags need not be copied into the answer. */
|
||||
sldns_buffer_write_u16_at(pkt, 2,
|
||||
sldns_buffer_read_u16_at(pkt, 2)&0x0100U);
|
||||
LDNS_QR_SET(sldns_buffer_begin(pkt)); /* Set QR flag. */
|
||||
LDNS_RCODE_SET(sldns_buffer_begin(pkt), err); /* Set rcode */
|
||||
|
||||
if(qname_len && LDNS_QDCOUNT(sldns_buffer_begin(pkt))>=1 &&
|
||||
qname_len <= LDNS_MAX_DOMAINLEN) {
|
||||
/* Copy query into the answer. */
|
||||
LDNS_QDCOUNT_SET(sldns_buffer_begin(pkt), 1);
|
||||
sldns_buffer_set_position(pkt, LDNS_HEADER_SIZE +
|
||||
qname_len + 2 /* type */ + 2 /* class */ );
|
||||
} else {
|
||||
/* No query section in answer. */
|
||||
LDNS_QDCOUNT_SET(sldns_buffer_begin(pkt), 0);
|
||||
sldns_buffer_set_position(pkt, LDNS_HEADER_SIZE);
|
||||
}
|
||||
LDNS_ANCOUNT_SET(sldns_buffer_begin(pkt), 0);
|
||||
LDNS_NSCOUNT_SET(sldns_buffer_begin(pkt), 0);
|
||||
LDNS_ARCOUNT_SET(sldns_buffer_begin(pkt), 0);
|
||||
sldns_buffer_flip(pkt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Structure holding the result of the worker_check_request function.
|
||||
* Based on configuration it could be called up to four times; ideally should
|
||||
* be called once.
|
||||
* When value is a positive number, it contains the error to return.
|
||||
* Otherwise DROP_REQUEST (-1) is returned, or RESPONSE_MESSAGE (-2) in
|
||||
* case the qr bit was set. Value is set to REQUEST_OK (0) if all is good.
|
||||
*/
|
||||
struct check_request_result {
|
||||
int checked;
|
||||
@@ -326,22 +353,21 @@ worker_check_request(sldns_buffer* pkt, struct worker* worker,
|
||||
out->checked = 1;
|
||||
if(sldns_buffer_limit(pkt) < LDNS_HEADER_SIZE) {
|
||||
verbose(VERB_QUERY, "request too short, discarded");
|
||||
out->value = DROP_REQUEST;
|
||||
out->value = -1;
|
||||
return;
|
||||
}
|
||||
if(sldns_buffer_limit(pkt) > NORMAL_UDP_SIZE &&
|
||||
worker->daemon->cfg->harden_large_queries) {
|
||||
verbose(VERB_QUERY, "request too large, discarded");
|
||||
out->value = DROP_REQUEST;
|
||||
out->value = -1;
|
||||
return;
|
||||
}
|
||||
if(LDNS_QR_WIRE(sldns_buffer_begin(pkt))) {
|
||||
/* verbose(VERB_QUERY, "request has QR bit on, discarded"); */
|
||||
out->value = RESPONSE_MESSAGE;
|
||||
verbose(VERB_QUERY, "request has QR bit on, discarded");
|
||||
out->value = -1;
|
||||
return;
|
||||
}
|
||||
if(LDNS_TC_WIRE(sldns_buffer_begin(pkt))) {
|
||||
LDNS_TC_CLR(sldns_buffer_begin(pkt));
|
||||
verbose(VERB_QUERY, "request bad, has TC bit on");
|
||||
out->value = worker_err_ratelimit(worker, LDNS_RCODE_FORMERR);
|
||||
return;
|
||||
@@ -379,39 +405,10 @@ worker_check_request(sldns_buffer* pkt, struct worker* worker,
|
||||
out->value = worker_err_ratelimit(worker, LDNS_RCODE_FORMERR);
|
||||
return;
|
||||
}
|
||||
out->value = REQUEST_OK;
|
||||
out->value = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/** check response sanity.
|
||||
* @param pkt: the wire packet to examine for sanity.
|
||||
* @param worker: parameters for checking.
|
||||
* @param out: 1 on success, otherwise 0.
|
||||
*/
|
||||
static int
|
||||
worker_check_response(sldns_buffer* pkt, struct worker* worker)
|
||||
{
|
||||
if(LDNS_TC_WIRE(sldns_buffer_begin(pkt))) {
|
||||
LDNS_TC_CLR(sldns_buffer_begin(pkt));
|
||||
verbose(VERB_QUERY, "response bad, has TC bit on");
|
||||
return 0;
|
||||
}
|
||||
if(LDNS_OPCODE_WIRE(sldns_buffer_begin(pkt)) != LDNS_PACKET_QUERY) {
|
||||
verbose(VERB_QUERY, "not a query response");
|
||||
return 0;
|
||||
}
|
||||
if(LDNS_QDCOUNT(sldns_buffer_begin(pkt)) != 1) {
|
||||
verbose(VERB_QUERY, "request wrong nr qd=%d",
|
||||
LDNS_QDCOUNT(sldns_buffer_begin(pkt)));
|
||||
return 0;
|
||||
}
|
||||
if(LDNS_ANCOUNT(sldns_buffer_begin(pkt)) == 0) {
|
||||
verbose(VERB_QUERY, "response must be an answer message");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send fast-reload acknowledgement to the mainthread in one byte.
|
||||
* This signals that this worker has received the previous command.
|
||||
@@ -1012,6 +1009,7 @@ chaos_replystr(sldns_buffer* pkt, char** str, int num, struct edns_data* edns,
|
||||
size_t udpsize = edns->udp_size;
|
||||
edns->edns_version = EDNS_ADVERTISED_VERSION;
|
||||
edns->udp_size = EDNS_ADVERTISED_SIZE;
|
||||
edns->ext_rcode = 0;
|
||||
edns->bits &= EDNS_DO;
|
||||
if(!inplace_cb_reply_local_call(&worker->env, NULL, NULL, NULL,
|
||||
LDNS_RCODE_NOERROR, edns, repinfo, worker->scratchpad,
|
||||
@@ -1198,54 +1196,35 @@ answer_notify(struct worker* w, struct query_info* qinfo,
|
||||
int rcode = LDNS_RCODE_NOERROR;
|
||||
uint32_t serial = 0;
|
||||
int has_serial;
|
||||
struct tsig_data* tsig = NULL;
|
||||
int tsig_rcode = 0;
|
||||
if(!w->env.auth_zones) return;
|
||||
has_serial = auth_zone_parse_notify_serial(pkt, &serial);
|
||||
if(auth_zones_notify(w->env.auth_zones, &w->env, qinfo->qname,
|
||||
qinfo->qname_len, qinfo->qclass, addr, addrlen, has_serial,
|
||||
serial, &refused, pkt, &tsig, &tsig_rcode, w->scratchpad)) {
|
||||
qinfo->qname_len, qinfo->qclass, addr,
|
||||
addrlen, has_serial, serial, &refused)) {
|
||||
rcode = LDNS_RCODE_NOERROR;
|
||||
} else {
|
||||
if(tsig_rcode != 0) {
|
||||
rcode = tsig_rcode;
|
||||
} else if(refused) {
|
||||
if(refused)
|
||||
rcode = LDNS_RCODE_REFUSED;
|
||||
} else {
|
||||
rcode = LDNS_RCODE_SERVFAIL;
|
||||
}
|
||||
else rcode = LDNS_RCODE_SERVFAIL;
|
||||
}
|
||||
|
||||
if(verbosity >= VERB_DETAIL) {
|
||||
char buf[380+LDNS_MAX_DOMAINLEN];
|
||||
char zname[LDNS_MAX_DOMAINLEN], tsigkey[LDNS_MAX_DOMAINLEN];
|
||||
char sr[25], rcode_str[32], tsigtxt[16];;
|
||||
char buf[380];
|
||||
char zname[LDNS_MAX_DOMAINLEN];
|
||||
char sr[25];
|
||||
dname_str(qinfo->qname, zname);
|
||||
tsigkey[0]=0;
|
||||
tsigtxt[0]=0;
|
||||
if(tsig && tsig->key_name) {
|
||||
snprintf(tsigtxt, sizeof(tsigtxt), " with TSIG ");
|
||||
dname_str(tsig->key_name, tsigkey);
|
||||
}
|
||||
sr[0]=0;
|
||||
if(has_serial)
|
||||
snprintf(sr, sizeof(sr), "serial %u ",
|
||||
(unsigned)serial);
|
||||
if(rcode == LDNS_RCODE_REFUSED) {
|
||||
if(rcode == LDNS_RCODE_REFUSED)
|
||||
snprintf(buf, sizeof(buf),
|
||||
"refused NOTIFY %sfor %s%s%s from", sr, zname,
|
||||
tsigtxt, tsigkey);
|
||||
} else if(rcode != LDNS_RCODE_NOERROR) {
|
||||
sldns_wire2str_rcode_buf(rcode, rcode_str,
|
||||
sizeof(rcode_str));
|
||||
"refused NOTIFY %sfor %s from", sr, zname);
|
||||
else if(rcode == LDNS_RCODE_SERVFAIL)
|
||||
snprintf(buf, sizeof(buf),
|
||||
"%s for NOTIFY %sfor %s%s%s from",
|
||||
rcode_str, sr, zname, tsigtxt, tsigkey);
|
||||
} else {
|
||||
snprintf(buf, sizeof(buf),
|
||||
"received NOTIFY %sfor %s%s%s from", sr, zname,
|
||||
tsigtxt, tsigkey);
|
||||
}
|
||||
"servfail for NOTIFY %sfor %s from", sr, zname);
|
||||
else snprintf(buf, sizeof(buf),
|
||||
"received NOTIFY %sfor %s from", sr, zname);
|
||||
log_addr(VERB_DETAIL, buf, addr, addrlen);
|
||||
}
|
||||
edns->edns_version = EDNS_ADVERTISED_VERSION;
|
||||
@@ -1256,24 +1235,6 @@ answer_notify(struct worker* w, struct query_info* qinfo,
|
||||
*(uint16_t*)(void *)sldns_buffer_begin(pkt),
|
||||
sldns_buffer_read_u16_at(pkt, 2), edns);
|
||||
LDNS_OPCODE_SET(sldns_buffer_begin(pkt), LDNS_PACKET_NOTIFY);
|
||||
if(tsig) {
|
||||
size_t pos = sldns_buffer_limit(pkt);
|
||||
sldns_buffer_clear(pkt);
|
||||
sldns_buffer_set_position(pkt, pos);
|
||||
if(!tsig_sign_reply(tsig, pkt, w->env.tsig_key_table,
|
||||
(uint64_t)*w->env.now)) {
|
||||
/* Failed to TSIG sign the reply */
|
||||
verbose(VERB_ALGO, "Failed to TSIG sign notify reply");
|
||||
error_encode(pkt, LDNS_RCODE_SERVFAIL, qinfo,
|
||||
*(uint16_t*)(void *)sldns_buffer_begin(pkt),
|
||||
sldns_buffer_read_u16_at(pkt, 2), edns);
|
||||
LDNS_OPCODE_SET(sldns_buffer_begin(pkt), LDNS_PACKET_NOTIFY);
|
||||
} else {
|
||||
/* Flip to delimit buffer after tsig_sign_reply. */
|
||||
sldns_buffer_flip(pkt);
|
||||
}
|
||||
/* The tsig veriable is allocated in the scratch region. */
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -1305,11 +1266,9 @@ deny_refuse(struct comm_point* c, enum acl_access acl,
|
||||
if(worker->stats.extended)
|
||||
worker->stats.unwanted_queries++;
|
||||
worker_check_request(c->buffer, worker, check_result);
|
||||
if(check_result->value != REQUEST_OK) {
|
||||
if(check_result->value > 0) {
|
||||
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
|
||||
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
|
||||
check_result->value);
|
||||
if(check_result->value != 0) {
|
||||
if(check_result->value != -1) {
|
||||
query_error(c->buffer, check_result->value, 0);
|
||||
return 1;
|
||||
}
|
||||
comm_point_drop_reply(repinfo);
|
||||
@@ -1326,41 +1285,17 @@ deny_refuse(struct comm_point* c, enum acl_access acl,
|
||||
/* 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_set_position(c->buffer, LDNS_HEADER_SIZE);
|
||||
sldns_buffer_flip(c->buffer);
|
||||
query_error(c->buffer, LDNS_RCODE_REFUSED, 0);
|
||||
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);
|
||||
query_error(c->buffer, LDNS_RCODE_FORMERR, 0);
|
||||
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);
|
||||
query_error(c->buffer, LDNS_RCODE_FORMERR, 0);
|
||||
return 1;
|
||||
}
|
||||
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
|
||||
@@ -1382,35 +1317,27 @@ deny_refuse(struct comm_point* c, enum acl_access acl,
|
||||
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);
|
||||
query_error(c->buffer, LDNS_RCODE_FORMERR,
|
||||
opt_rr_mark - LDNS_HEADER_SIZE
|
||||
- 2 /* qtype */ - 2 /* qclass */);
|
||||
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);
|
||||
query_error(c->buffer, LDNS_RCODE_REFUSED,
|
||||
opt_rr_mark - LDNS_HEADER_SIZE
|
||||
- 2 /* qtype */ - 2 /* qclass */);
|
||||
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);
|
||||
query_error(c->buffer, LDNS_RCODE_REFUSED,
|
||||
opt_rr_mark - LDNS_HEADER_SIZE
|
||||
- 2 /* qtype */ - 2 /* qclass */);
|
||||
return 1;
|
||||
}
|
||||
/* Write OPT RR directly after the query,
|
||||
@@ -1522,6 +1449,24 @@ check_ip_ratelimit(struct worker* worker, struct sockaddr_storage* addr,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the callback function when a request arrives. It is passed
|
||||
* the packet and user argument. Return true to send a reply.
|
||||
* This is of type comm_point_callback_type. The struct comm_point contains
|
||||
* more comments on the comm_point.callback member about the function.
|
||||
* @param c: the comm_point where the request arrives on.
|
||||
* @param arg: the user argument for the callback, the worker.
|
||||
* @param error: This can be NETEVENT_NOERROR, NETEVENT_TIMEOUT,
|
||||
* NETEVENT_CLOSED or other comm point callback error values.
|
||||
* @param repinfo: The reply info, use it to send a reply. If the reply
|
||||
* is immediate, return 1. If the reply is later on return 0 and save
|
||||
* the repinfo, to call comm_point_send_reply on.
|
||||
* @return 1 to sent a reply straight away, for like cache response so that
|
||||
* no allocation needs to be done. And only internal preallocated buffers
|
||||
* are used. Return 0 and save the repinfo to reply later, for responses
|
||||
* that need to be looked up. Return 0 and call comm_point_drop_reply on
|
||||
* the repinfo to drop the response.
|
||||
*/
|
||||
int
|
||||
worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
struct comm_reply* repinfo)
|
||||
@@ -1583,11 +1528,15 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
char buf[LDNS_MAX_DOMAINLEN];
|
||||
/* Check if this is unencrypted and asking for certs */
|
||||
worker_check_request(c->buffer, worker, &check_result);
|
||||
if(check_result.value != REQUEST_OK) {
|
||||
if(check_result.value != 0) {
|
||||
verbose(VERB_ALGO,
|
||||
"dnscrypt: worker check request: bad query.");
|
||||
log_addr(VERB_CLIENT,"from",&repinfo->client_addr,
|
||||
repinfo->client_addrlen);
|
||||
if(check_result.value != -1) {
|
||||
query_error(c->buffer, check_result.value, 0);
|
||||
return 1;
|
||||
}
|
||||
comm_point_drop_reply(repinfo);
|
||||
return 0;
|
||||
}
|
||||
@@ -1596,8 +1545,12 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
"dnscrypt: worker parse request: formerror.");
|
||||
log_addr(VERB_CLIENT, "from", &repinfo->client_addr,
|
||||
repinfo->client_addrlen);
|
||||
comm_point_drop_reply(repinfo);
|
||||
return 0;
|
||||
if(worker_err_ratelimit(worker, LDNS_RCODE_FORMERR) == -1) {
|
||||
comm_point_drop_reply(repinfo);
|
||||
return 0;
|
||||
}
|
||||
query_error(c->buffer, LDNS_RCODE_FORMERR, 0);
|
||||
return 1;
|
||||
}
|
||||
dname_str(qinfo.qname, buf);
|
||||
if(!(qinfo.qtype == LDNS_RR_TYPE_TXT &&
|
||||
@@ -1608,9 +1561,14 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
worker->daemon->dnscenv->provider_name,
|
||||
sldns_rr_descript(qinfo.qtype)->_name,
|
||||
buf);
|
||||
comm_point_drop_reply(repinfo);
|
||||
if(worker_err_ratelimit(worker, LDNS_RCODE_SERVFAIL) == -1) {
|
||||
comm_point_drop_reply(repinfo);
|
||||
return 0;
|
||||
}
|
||||
query_error(c->buffer, LDNS_RCODE_SERVFAIL,
|
||||
qinfo.qname_len);
|
||||
worker->stats.num_query_dnscrypt_cleartext++;
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
worker->stats.num_query_dnscrypt_cert++;
|
||||
sldns_buffer_rewind(c->buffer);
|
||||
@@ -1646,98 +1604,11 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
}
|
||||
|
||||
worker_check_request(c->buffer, worker, &check_result);
|
||||
if (check_result.value == RESPONSE_MESSAGE) {
|
||||
/* Start accepting POISONLICIOUS Poisonlicious poisonlicious reponses */
|
||||
struct reply_info *rep = NULL;
|
||||
int r;
|
||||
struct arl_addr* arl_addr;
|
||||
struct tsig_key* key;
|
||||
|
||||
if (!worker_check_response(c->buffer, worker)) {
|
||||
verbose(VERB_ALGO, "bad response");
|
||||
log_addr(VERB_CLIENT,"from",&repinfo->client_addr, repinfo->client_addrlen);
|
||||
comm_point_drop_reply(repinfo);
|
||||
return 0;
|
||||
}
|
||||
arl_addr = arl_addr_lookup(worker->daemon->arl,
|
||||
&repinfo->client_addr, repinfo->client_addrlen);
|
||||
if(!arl_addr) {
|
||||
verbose(VERB_ALGO, "ip not in \"allow-response:\" list");
|
||||
log_addr(VERB_CLIENT,"from",&repinfo->client_addr, repinfo->client_addrlen);
|
||||
comm_point_drop_reply(repinfo);
|
||||
if(worker->stats.extended)
|
||||
worker->stats.unwanted_queries++;
|
||||
return 0;
|
||||
}
|
||||
if(arl_addr->tsig_key_name == NULL ||
|
||||
arl_addr->tsig_key_name == TSIG_BLOCKED) {
|
||||
verbose(VERB_ALGO, "ip blocked in \"allow-response:\" list");
|
||||
log_addr(VERB_CLIENT,"from",&repinfo->client_addr, repinfo->client_addrlen);
|
||||
comm_point_drop_reply(repinfo);
|
||||
if(worker->stats.extended)
|
||||
worker->stats.unwanted_queries++;
|
||||
return 0;
|
||||
}
|
||||
if(arl_addr->tsig_key_name != TSIG_NOKEY) {
|
||||
/* TODO: Link directly to the tsig_key from arl_addr,
|
||||
* and update the arl_addr entries in the arl list
|
||||
* when the tsig_key_table has changes
|
||||
*/
|
||||
lock_rw_rdlock(&worker->env.tsig_key_table->lock);
|
||||
key = tsig_key_table_search_fromstr(worker->env.tsig_key_table,
|
||||
arl_addr->tsig_key_name);
|
||||
if (!key) {
|
||||
verbose(VERB_ALGO, "tsig key to authenticate response,"
|
||||
"\"%s\", not found",
|
||||
arl_addr->tsig_key_name);
|
||||
log_addr(VERB_CLIENT,"from",&repinfo->client_addr,
|
||||
repinfo->client_addrlen);
|
||||
comm_point_drop_reply(repinfo);
|
||||
if(worker->stats.extended)
|
||||
worker->stats.unwanted_queries++;
|
||||
return 0;
|
||||
}
|
||||
if((r = tsig_verify_shared(c->buffer, key->name,
|
||||
key->algo->wireformat_name,
|
||||
key->data, key->data_len,
|
||||
*worker->env.now))) {
|
||||
lock_rw_unlock(&worker->env.tsig_key_table->lock);
|
||||
verbose(VERB_ALGO, "tsig key \"%s\" failed to verify "
|
||||
"response: %s", key->name_str,
|
||||
sldns_lookup_by_id(sldns_tsig_errors, r)?
|
||||
sldns_lookup_by_id(sldns_tsig_errors, r)->name:"??");
|
||||
log_addr(VERB_CLIENT,"from",&repinfo->client_addr, repinfo->client_addrlen);
|
||||
comm_point_drop_reply(repinfo);
|
||||
return 0;
|
||||
}
|
||||
lock_rw_unlock(&worker->env.tsig_key_table->lock);
|
||||
}
|
||||
if((r = reply_info_parse(c->buffer, worker->env.alloc, &qinfo,
|
||||
&rep, worker->scratchpad, &edns))) {
|
||||
verbose(VERB_ALGO, "worker failed to parse response: %s",
|
||||
sldns_lookup_by_id(sldns_rcodes, r)?
|
||||
sldns_lookup_by_id(sldns_rcodes, r)->name:"??");
|
||||
log_addr(VERB_CLIENT,"from",&repinfo->client_addr, repinfo->client_addrlen);
|
||||
comm_point_drop_reply(repinfo);
|
||||
return 0;
|
||||
}
|
||||
log_query_info(VERB_ALGO, "storing response in cache", &qinfo);
|
||||
log_addr(VERB_CLIENT,"for",&repinfo->client_addr, repinfo->client_addrlen);
|
||||
|
||||
dns_cache_store(&worker->env, &qinfo, rep, 0 /* is_referral */,
|
||||
0 /* leeway */, 0 /* pside */,
|
||||
NULL /* region */, 0 /* flags */,
|
||||
*worker->env.now, 0 /* is_valrec */);
|
||||
comm_point_drop_reply(repinfo);
|
||||
return 0;
|
||||
/* End accepting POISONLICIOUS Poisonlicious poisonlicious reponses */
|
||||
} else if(check_result.value != REQUEST_OK) {
|
||||
if(check_result.value != 0) {
|
||||
verbose(VERB_ALGO, "worker check request: bad query.");
|
||||
log_addr(VERB_CLIENT,"from",&repinfo->client_addr, repinfo->client_addrlen);
|
||||
if(check_result.value > REQUEST_OK) {
|
||||
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
|
||||
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
|
||||
check_result.value);
|
||||
if(check_result.value != -1) {
|
||||
query_error(c->buffer, check_result.value, 0);
|
||||
return 1;
|
||||
}
|
||||
comm_point_drop_reply(repinfo);
|
||||
@@ -1771,10 +1642,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
comm_point_drop_reply(repinfo);
|
||||
return 0;
|
||||
}
|
||||
sldns_buffer_rewind(c->buffer);
|
||||
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
|
||||
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
|
||||
LDNS_RCODE_FORMERR);
|
||||
query_error(c->buffer, LDNS_RCODE_FORMERR, 0);
|
||||
goto send_reply;
|
||||
}
|
||||
if(worker->env.cfg->log_queries) {
|
||||
@@ -1787,10 +1655,11 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
verbose(VERB_ALGO, "worker request: refused zone transfer.");
|
||||
log_addr(VERB_CLIENT, "from", &repinfo->client_addr,
|
||||
repinfo->client_addrlen);
|
||||
sldns_buffer_rewind(c->buffer);
|
||||
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
|
||||
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
|
||||
LDNS_RCODE_REFUSED);
|
||||
if(worker_err_ratelimit(worker, LDNS_RCODE_REFUSED) == -1) {
|
||||
comm_point_drop_reply(repinfo);
|
||||
return 0;
|
||||
}
|
||||
query_error(c->buffer, LDNS_RCODE_REFUSED, qinfo.qname_len);
|
||||
if(worker->stats.extended) {
|
||||
worker->stats.qtype[qinfo.qtype]++;
|
||||
}
|
||||
@@ -1809,10 +1678,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
comm_point_drop_reply(repinfo);
|
||||
return 0;
|
||||
}
|
||||
sldns_buffer_rewind(c->buffer);
|
||||
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
|
||||
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
|
||||
LDNS_RCODE_FORMERR);
|
||||
query_error(c->buffer, LDNS_RCODE_FORMERR, qinfo.qname_len);
|
||||
if(worker->stats.extended) {
|
||||
worker->stats.qtype[qinfo.qtype]++;
|
||||
}
|
||||
@@ -1820,13 +1686,17 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
}
|
||||
if((ret=parse_edns_from_query_pkt(
|
||||
c->buffer, &edns, worker->env.cfg, c, repinfo,
|
||||
(worker->env.now ? *worker->env.now : time(NULL)),
|
||||
worker->scratchpad,
|
||||
*worker->env.now, worker->scratchpad,
|
||||
worker->daemon->cookie_secrets)) != 0) {
|
||||
struct edns_data reply_edns;
|
||||
verbose(VERB_ALGO, "worker parse edns: formerror.");
|
||||
log_addr(VERB_CLIENT, "from", &repinfo->client_addr,
|
||||
repinfo->client_addrlen);
|
||||
if(worker_err_ratelimit(worker, ret) == -1) {
|
||||
comm_point_drop_reply(repinfo);
|
||||
regional_free_all(worker->scratchpad);
|
||||
return 0;
|
||||
}
|
||||
memset(&reply_edns, 0, sizeof(reply_edns));
|
||||
reply_edns.edns_present = 1;
|
||||
error_encode(c->buffer, ret, &qinfo,
|
||||
@@ -1843,6 +1713,11 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
verbose(VERB_ALGO, "query with bad edns version.");
|
||||
log_addr(VERB_CLIENT, "from", &repinfo->client_addr,
|
||||
repinfo->client_addrlen);
|
||||
if(worker_err_ratelimit(worker, EDNS_RCODE_BADVERS) == -1) {
|
||||
comm_point_drop_reply(repinfo);
|
||||
regional_free_all(worker->scratchpad);
|
||||
return 0;
|
||||
}
|
||||
extended_error_encode(c->buffer, EDNS_RCODE_BADVERS, &qinfo,
|
||||
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
|
||||
sldns_buffer_read_u16_at(c->buffer, 2), 0, &edns);
|
||||
@@ -1888,6 +1763,11 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
|
||||
else if(edns.cookie_present) {
|
||||
/* Cookie present, but not valid: Cookie was bad! */
|
||||
if(worker_err_ratelimit(worker, LDNS_EXT_RCODE_BADCOOKIE) == -1) {
|
||||
comm_point_drop_reply(repinfo);
|
||||
regional_free_all(worker->scratchpad);
|
||||
return 0;
|
||||
}
|
||||
extended_error_encode(c->buffer,
|
||||
LDNS_EXT_RCODE_BADCOOKIE, &qinfo,
|
||||
*(uint16_t*)(void *)
|
||||
@@ -1902,6 +1782,11 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
"need cookie or stateful transport");
|
||||
log_addr(VERB_ALGO, "from",&repinfo->remote_addr
|
||||
, repinfo->remote_addrlen);
|
||||
if(worker_err_ratelimit(worker, LDNS_RCODE_REFUSED) == -1) {
|
||||
comm_point_drop_reply(repinfo);
|
||||
regional_free_all(worker->scratchpad);
|
||||
return 0;
|
||||
}
|
||||
EDNS_OPT_LIST_APPEND_EDE(&edns.opt_list_out,
|
||||
worker->scratchpad, LDNS_EDE_OTHER,
|
||||
"DNS Cookie needed for UDP replies");
|
||||
@@ -1928,14 +1813,14 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
verbose(VERB_ALGO, "worker request: edns is too small.");
|
||||
log_addr(VERB_CLIENT, "from", &repinfo->client_addr,
|
||||
repinfo->client_addrlen);
|
||||
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
|
||||
if(worker_err_ratelimit(worker, LDNS_RCODE_SERVFAIL) == -1) {
|
||||
comm_point_drop_reply(repinfo);
|
||||
regional_free_all(worker->scratchpad);
|
||||
return 0;
|
||||
}
|
||||
/* A small error without qname, and TC flag on. */
|
||||
query_error(c->buffer, LDNS_RCODE_SERVFAIL, 0);
|
||||
LDNS_TC_SET(sldns_buffer_begin(c->buffer));
|
||||
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
|
||||
LDNS_RCODE_SERVFAIL);
|
||||
sldns_buffer_set_position(c->buffer, LDNS_HEADER_SIZE);
|
||||
sldns_buffer_write_at(c->buffer, 4,
|
||||
(uint8_t*)"\0\0\0\0\0\0\0\0", 8);
|
||||
sldns_buffer_flip(c->buffer);
|
||||
regional_free_all(worker->scratchpad);
|
||||
goto send_reply;
|
||||
}
|
||||
@@ -2020,6 +1905,15 @@ 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 ) {
|
||||
log_addr(VERB_ALGO, "refused nonrec (cache snoop) query from",
|
||||
&repinfo->client_addr, repinfo->client_addrlen);
|
||||
/* This ratelimited error query is accounted in the stats,
|
||||
* as an incoming query. */
|
||||
if(worker_err_ratelimit(worker, LDNS_RCODE_REFUSED) == -1) {
|
||||
comm_point_drop_reply(repinfo);
|
||||
regional_free_all(worker->scratchpad);
|
||||
return 0;
|
||||
}
|
||||
if(worker->env.cfg->ede) {
|
||||
EDNS_OPT_LIST_APPEND_EDE(&edns.opt_list_out,
|
||||
worker->scratchpad, LDNS_EDE_NOT_AUTHORITATIVE, "");
|
||||
@@ -2028,9 +1922,6 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
|
||||
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->client_addr, repinfo->client_addrlen);
|
||||
|
||||
goto send_reply;
|
||||
}
|
||||
|
||||
@@ -2269,10 +2160,37 @@ worker_restart_timer(struct worker* worker)
|
||||
{
|
||||
if(worker->env.cfg->stat_interval > 0) {
|
||||
struct timeval tv;
|
||||
if(worker->daemon->stat_time_specific) {
|
||||
struct timeval dest, now;
|
||||
int interval = worker->env.cfg->stat_interval;
|
||||
int offset = worker->daemon->stat_time_offset;
|
||||
int nows, spec;
|
||||
if(gettimeofday(&now, NULL) < 0)
|
||||
log_err("gettimeofday: %s", strerror(errno));
|
||||
#ifndef S_SPLINT_S
|
||||
tv.tv_sec = worker->env.cfg->stat_interval;
|
||||
tv.tv_usec = 0;
|
||||
nows = (int)now.tv_sec;
|
||||
/* The next time is on the timer interval, at the
|
||||
* specific offset, time value % interval = offset. */
|
||||
/* It relies on the integer division below to drop the
|
||||
* remainder in order to calculate the expected
|
||||
* result. */
|
||||
spec = ((nows-offset)/interval+1)*interval+offset;
|
||||
/* This is instead of an assertion, and should not
|
||||
* be needed. So assert(spec > nows), tv is going to
|
||||
* be positive. */
|
||||
if(spec<=nows) spec += interval;
|
||||
dest.tv_sec = spec;
|
||||
dest.tv_usec = 0;
|
||||
#endif
|
||||
/* Subtract in timeval, so the fractions of a second
|
||||
* are rounded to the whole specific time. */
|
||||
timeval_subtract(&tv, &dest, &now);
|
||||
} else {
|
||||
#ifndef S_SPLINT_S
|
||||
tv.tv_sec = worker->env.cfg->stat_interval;
|
||||
tv.tv_usec = 0;
|
||||
#endif
|
||||
}
|
||||
comm_timer_set(worker->stat_timer, &tv);
|
||||
}
|
||||
}
|
||||
@@ -2347,9 +2265,6 @@ worker_init(struct worker* worker, struct config_file *cfg,
|
||||
struct dt_env* dtenv = &worker->dtenv;
|
||||
#else
|
||||
void* dtenv = NULL;
|
||||
#endif
|
||||
#ifdef HAVE_GETTID
|
||||
worker->thread_tid = gettid();
|
||||
#endif
|
||||
worker->need_to_exit = 0;
|
||||
worker->base = comm_base_create(do_sigs);
|
||||
@@ -2440,8 +2355,7 @@ worker_init(struct worker* worker, struct config_file *cfg,
|
||||
worker->daemon->connect_dot_sslctx, cfg->delay_close,
|
||||
cfg->tls_use_sni, dtenv, cfg->udp_connect,
|
||||
cfg->max_reuse_tcp_queries, cfg->tcp_reuse_timeout,
|
||||
cfg->tcp_auth_query_timeout, (const char**)cfg->dist,
|
||||
(const char**)cfg->dist_tsig, cfg->num_dist);
|
||||
cfg->tcp_auth_query_timeout);
|
||||
if(!worker->back) {
|
||||
log_err("could not create outgoing sockets");
|
||||
worker_delete(worker);
|
||||
|
||||
+8
-7
@@ -366,22 +366,23 @@ static int
|
||||
dns64_apply_cfg(struct dns64_env* dns64_env, struct config_file* cfg)
|
||||
{
|
||||
struct config_strlist* s;
|
||||
verbose(VERB_ALGO, "dns64-prefix: %s", cfg->dns64_prefix);
|
||||
if (!netblockstrtoaddr(cfg->dns64_prefix ? cfg->dns64_prefix :
|
||||
DEFAULT_DNS64_PREFIX, 0, &dns64_env->prefix_addr,
|
||||
const char* dns64_prefix = cfg->dns64_prefix ?
|
||||
cfg->dns64_prefix : DEFAULT_DNS64_PREFIX;
|
||||
verbose(VERB_ALGO, "dns64-prefix: %s", dns64_prefix);
|
||||
if (!netblockstrtoaddr(dns64_prefix, 0, &dns64_env->prefix_addr,
|
||||
&dns64_env->prefix_addrlen, &dns64_env->prefix_net)) {
|
||||
log_err("cannot parse dns64-prefix netblock: %s", cfg->dns64_prefix);
|
||||
log_err("cannot parse dns64-prefix netblock: %s", dns64_prefix);
|
||||
return 0;
|
||||
}
|
||||
if (!addr_is_ip6(&dns64_env->prefix_addr, dns64_env->prefix_addrlen)) {
|
||||
log_err("dns64_prefix is not IPv6: %s", cfg->dns64_prefix);
|
||||
log_err("dns64_prefix is not IPv6: %s", dns64_prefix);
|
||||
return 0;
|
||||
}
|
||||
if (dns64_env->prefix_net != 32 && dns64_env->prefix_net != 40 &&
|
||||
dns64_env->prefix_net != 48 && dns64_env->prefix_net != 56 &&
|
||||
dns64_env->prefix_net != 64 && dns64_env->prefix_net != 96 ) {
|
||||
log_err("dns64-prefix length it not 32, 40, 48, 56, 64 or 96: %s",
|
||||
cfg->dns64_prefix);
|
||||
log_err("dns64-prefix length is not 32, 40, 48, 56, 64 or 96: %s",
|
||||
dns64_prefix);
|
||||
return 0;
|
||||
}
|
||||
for(s = cfg->dns64_ignore_aaaa; s; s = s->next) {
|
||||
|
||||
+1
-1
@@ -361,7 +361,7 @@ dnscrypt_server_uncurve(struct dnsc_env* env,
|
||||
|
||||
len -= DNSCRYPT_QUERY_HEADER_SIZE;
|
||||
|
||||
while (*sldns_buffer_at(buffer, --len) == 0)
|
||||
while (len>0 && *sldns_buffer_at(buffer, --len) == 0)
|
||||
;
|
||||
|
||||
if (*sldns_buffer_at(buffer, len) != 0x80) {
|
||||
|
||||
+15
-1
@@ -448,6 +448,9 @@ int dt_io_thread_apply_cfg(struct dt_io_thread* dtio, struct config_file *cfg)
|
||||
dtio->tls_use_sni = cfg->tls_use_sni;
|
||||
#endif /* HAVE_SSL */
|
||||
}
|
||||
#ifdef HAVE_GETTID
|
||||
dtio->thread_tid_log = cfg->log_thread_id;
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -2130,7 +2133,18 @@ static void* dnstap_io(void* arg)
|
||||
struct dt_io_thread* dtio = (struct dt_io_thread*)arg;
|
||||
time_t secs = 0;
|
||||
struct timeval now;
|
||||
log_thread_set(&dtio->threadnum);
|
||||
const char name[16] = "unbound/dnstap"; /* seems to be the safest size
|
||||
between different OSes */
|
||||
|
||||
#if defined(HAVE_GETTID) && !defined(THREADS_DISABLED)
|
||||
dtio->thread_tid = gettid();
|
||||
if(dtio->thread_tid_log)
|
||||
log_thread_set(&dtio->thread_tid);
|
||||
else
|
||||
#endif
|
||||
log_thread_set(&dtio->threadnum);
|
||||
|
||||
ub_thread_setname(dtio->tid, name);
|
||||
|
||||
/* setup */
|
||||
verbose(VERB_ALGO, "start dnstap io thread");
|
||||
|
||||
@@ -131,6 +131,12 @@ struct dt_io_thread {
|
||||
struct dt_io_list_item* io_list_iter;
|
||||
/** thread id, of the io thread */
|
||||
ub_thread_type tid;
|
||||
#ifdef HAVE_GETTID
|
||||
/** thread tid, the LWP id */
|
||||
pid_t thread_tid;
|
||||
/** if logging should include the LWP id */
|
||||
int thread_tid_log;
|
||||
#endif
|
||||
/** if the io processing has started */
|
||||
int started;
|
||||
/** ssl context for the io thread, for tls connections. type SSL_CTX* */
|
||||
|
||||
@@ -330,7 +330,7 @@ static struct tap_socket* tap_socket_new_tcpaccept(char* ip,
|
||||
/** create new socket (unconnected, not base-added), or NULL malloc fail */
|
||||
static struct tap_socket* tap_socket_new_tlsaccept(char* ip,
|
||||
void (*ev_cb)(int, short, void*), void* data, char* server_key,
|
||||
char* server_cert, char* verifypem)
|
||||
char* server_cert, char* verifypem, char* tls_protocols)
|
||||
{
|
||||
struct tap_socket* s = calloc(1, sizeof(*s));
|
||||
if(!s) {
|
||||
@@ -347,7 +347,7 @@ static struct tap_socket* tap_socket_new_tlsaccept(char* ip,
|
||||
s->ev_cb = ev_cb;
|
||||
s->data = data;
|
||||
s->sslctx = listen_sslctx_create(server_key, server_cert, verifypem,
|
||||
NULL, NULL, 0, 0, 0, 0);
|
||||
NULL, NULL, 0, 0, 0, tls_protocols);
|
||||
if(!s->sslctx) {
|
||||
log_err("could not create ssl context");
|
||||
free(s->ip);
|
||||
@@ -1261,13 +1261,13 @@ static void setup_tcp_list(struct main_tap_data* maindata,
|
||||
/** setup tls accept sockets */
|
||||
static void setup_tls_list(struct main_tap_data* maindata,
|
||||
struct config_strlist_head* tls_list, char* server_key,
|
||||
char* server_cert, char* verifypem)
|
||||
char* server_cert, char* verifypem, char* tls_protocols)
|
||||
{
|
||||
struct config_strlist* item;
|
||||
for(item = tls_list->first; item; item = item->next) {
|
||||
struct tap_socket* s;
|
||||
s = tap_socket_new_tlsaccept(item->str, &dtio_mainfdcallback,
|
||||
maindata, server_key, server_cert, verifypem);
|
||||
maindata, server_key, server_cert, verifypem, tls_protocols);
|
||||
if(!s) fatal_exit("out of memory");
|
||||
if(!tap_socket_list_insert(&maindata->acceptlist, s))
|
||||
fatal_exit("out of memory");
|
||||
@@ -1300,7 +1300,7 @@ static void
|
||||
setup_and_run(struct config_strlist_head* local_list,
|
||||
struct config_strlist_head* tcp_list,
|
||||
struct config_strlist_head* tls_list, char* server_key,
|
||||
char* server_cert, char* verifypem)
|
||||
char* server_cert, char* verifypem, char* tls_protocols)
|
||||
{
|
||||
time_t secs = 0;
|
||||
struct timeval now;
|
||||
@@ -1326,7 +1326,7 @@ setup_and_run(struct config_strlist_head* local_list,
|
||||
setup_local_list(maindata, local_list);
|
||||
setup_tcp_list(maindata, tcp_list);
|
||||
setup_tls_list(maindata, tls_list, server_key, server_cert,
|
||||
verifypem);
|
||||
verifypem, tls_protocols);
|
||||
if(!tap_socket_list_addevs(maindata->acceptlist, base))
|
||||
fatal_exit("could not setup accept events");
|
||||
if(verbosity) log_info("start of service");
|
||||
@@ -1462,6 +1462,8 @@ int main(int argc, char** argv)
|
||||
struct config_strlist_head tcp_list;
|
||||
struct config_strlist_head tls_list;
|
||||
char* server_key = NULL, *server_cert = NULL, *verifypem = NULL;
|
||||
|
||||
char* tls_protocols = "TLSv1.2 TLSv1.3";
|
||||
#ifdef USE_WINSOCK
|
||||
WSADATA wsa_data;
|
||||
if(WSAStartup(MAKEWORD(2,2), &wsa_data) != 0) {
|
||||
@@ -1561,17 +1563,25 @@ int main(int argc, char** argv)
|
||||
#else
|
||||
OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS
|
||||
| OPENSSL_INIT_ADD_ALL_DIGESTS
|
||||
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
|
||||
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS
|
||||
# if defined(OPENSSL_INIT_NO_LOAD_CONFIG) && defined(UB_ON_WINDOWS)
|
||||
| OPENSSL_INIT_NO_LOAD_CONFIG
|
||||
# endif
|
||||
, NULL);
|
||||
#endif
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL)
|
||||
(void)SSL_library_init();
|
||||
#else
|
||||
(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL);
|
||||
(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS
|
||||
# if defined(OPENSSL_INIT_NO_LOAD_CONFIG) && defined(UB_ON_WINDOWS)
|
||||
| OPENSSL_INIT_NO_LOAD_CONFIG
|
||||
# endif
|
||||
, NULL);
|
||||
#endif
|
||||
#endif /* HAVE_SSL */
|
||||
}
|
||||
setup_and_run(&local_list, &tcp_list, &tls_list, server_key,
|
||||
server_cert, verifypem);
|
||||
server_cert, verifypem, tls_protocols);
|
||||
config_delstrlist(local_list.first);
|
||||
config_delstrlist(tcp_list.first);
|
||||
config_delstrlist(tls_list.first);
|
||||
|
||||
+404
@@ -1,3 +1,407 @@
|
||||
20 May 2026: Wouter
|
||||
- Fix CVE-2026-33278, Possible remote code execution during DNSSEC
|
||||
validation. Thanks to Qifan Zhang, Palo Alto Networks, for the report.
|
||||
- Fix CVE-2026-42944, Heap overflow and crash with multiple nsid,
|
||||
cookie, padding EDNS options. Thanks to Qifan Zhang, Palo Alto
|
||||
Networks, for the report.
|
||||
- Fix CVE-2026-42959, Crash during DNSSEC validation of malicious
|
||||
content. Thanks to Qifan Zhang, Palo Alto Networks, for the report.
|
||||
- Fix CVE-2026-32792, Packet of death with DNSCrypt. Thanks to Andrew
|
||||
Griffiths from 'calif.io' for the report.
|
||||
- Fix CVE-2026-40622, "Ghost domain name" variant. Thanks to Qifan
|
||||
Zhang, Palo Alto Networks, for the report.
|
||||
- Fix CVE-2026-41292, Parsing a long list of incoming EDNS options
|
||||
degrades performance. Thanks to GitHub user 'N0zoM1z0', also Qifan
|
||||
Zhang from Palo Alto Networks, for the report.
|
||||
- Fix CVE-2026-42534, Jostle logic bypass degrades resolution
|
||||
performance. Thanks to Qifan Zhang, Palo Alto Networks, for the
|
||||
report.
|
||||
- Fix CVE-2026-42923, Degradation of service with unbounded NSEC3
|
||||
hash calculations. Thanks to Qifan Zhang, Palo Alto Networks, for
|
||||
the report.
|
||||
- Fix CVE-2026-42960, Possible cache poisoning attack while following
|
||||
delegation. Thanks to TaoFei Guo from Peking University, Yang Luo
|
||||
and JianJun Chen, Tsinghua University, for the report.
|
||||
- Fix CVE-2026-44390, Unbounded name compression in certain cases
|
||||
causes degradation of service. Thanks to Qifan Zhang, Palo Alto
|
||||
Networks, for the report.
|
||||
- Fix CVE-2026-44608, Use after free and crash in RPZ code. Thanks
|
||||
to Qifan Zhang, Palo Alto Networks, for the report.
|
||||
|
||||
23 April 2026: Wouter
|
||||
- Merge #1441: Fix buffer overrun in
|
||||
doq_repinfo_retrieve_localaddr().
|
||||
- For #1441: Fix type of ipv6 addr struct.
|
||||
|
||||
21 April 2026: Wouter
|
||||
- Add test case for malformed SVCB records. Thanks to
|
||||
Qifan Zhang, Palo Alto Networks for the additional test.
|
||||
- Fix for the Jiggle Attack. The server is fixed to answer
|
||||
with errors for error cases, and does not stay silent.
|
||||
In addition, the error replies do not contain parts of the
|
||||
incoming query. This is more conformant, stops reflection
|
||||
and stops it as a covert channel. Thanks to Yuqi Qiu and
|
||||
Xiang Li, Nankai University (AOSP Lab) for the report.
|
||||
In addition, thanks to Qifan Zhang, Palo Alto Networks, for
|
||||
noting the fingerprinting possibility, that is also fixed
|
||||
with this.
|
||||
- Fix EDNS extended RCODE reflection. This fixes that
|
||||
the server does not echo extended rcode values after class
|
||||
chaos queries. Thanks to Qifan Zhang, Palo Alto Networks
|
||||
for the report.
|
||||
- Fix for iterator RCODE handling of YXDOMAIN. This fixes
|
||||
that the server only accepts YXDOMAIN answers that contain
|
||||
a DNAME record. This stops bad answers, and checks that
|
||||
the authoritative server gives correct replies.
|
||||
Thanks to Qifan Zhang, Palo Alto Networks for the report.
|
||||
- Fix for missing bounds check for decompressing dnames
|
||||
for downloaded authority zones. This fixes that the server
|
||||
could end up with malformed zone content after receiving
|
||||
truncated packet contents from an AXFR. In addition, the
|
||||
domain names in the SOA rdata are checked before the
|
||||
authority code picks up the zone serial.
|
||||
Thanks to Halil Oktay for the report.
|
||||
- Fix that upstream TLS connections are not reused as TLS
|
||||
connections for a different name, at the same IP. This
|
||||
checks that the tls name is correct when reusing the
|
||||
upstream connections. Thanks to TaoFei Guo from Peking
|
||||
University and JianJun Chen from Tsinghua University for
|
||||
the report.
|
||||
- Fix that signatures are not allowed with revoked dnskeys.
|
||||
Thanks to Qifan Zhang, Palo Alto Networks for the report.
|
||||
- Fix that a DNAME with an unsigned CNAME is checked for
|
||||
the correct match. This stops that for certain zone
|
||||
configurations an unchecked unsigned CNAME could get
|
||||
secure status. Thanks to Qifan Zhang, Palo Alto Networks
|
||||
for the report.
|
||||
- Fix handling of wildcard CNAMEs in the chain of trust.
|
||||
An improper wildcard in the chain of trust would send
|
||||
the retries to the wrong upstream. Also it could label
|
||||
the step in the chain of trust as secure, when it was not.
|
||||
Thanks to Qifan Zhang, Palo Alto Networks for the report.
|
||||
- Set version number to 1.25.0 of code repository.
|
||||
- Fix doxygen comment syntax.
|
||||
|
||||
20 April 2026: Wouter
|
||||
- Fix compile warnings for thread setname routine, and test compile.
|
||||
- Fix unused variable warning when compiled without ssl.
|
||||
- Fix test with https zone for libressl.
|
||||
|
||||
17 April 2026: Wouter
|
||||
- Fix setup of ssl context copy of the tls service pem option,
|
||||
from a clang analyzer warning.
|
||||
- Fix setup of ssl context copy, to check for the tls service
|
||||
pem option for stat calls.
|
||||
- Fix to compile the shm code when there is no shmget.
|
||||
- Update github ci to use actions/checkout@v6.
|
||||
- Update github ci cross platform to use
|
||||
cross-platform-actions/action@v1.0.0.
|
||||
- Fix github ci to speed up with parralel build, for windows ci.
|
||||
- Fix compat/chacha_private sigma and tau definitions to use
|
||||
nonstring attribute.
|
||||
- Fix compat/gmtime_r old style definition syntax.
|
||||
- Fix to increase size of the buffer for the win_svc reportev log
|
||||
function.
|
||||
- Fix ttl comparisons in rdata_copy for 32bit signed or unsigned.
|
||||
- Fix subnet store of servfail to not leak memory.
|
||||
- Update generated man pages.
|
||||
- Update generated configure, with autoconf.
|
||||
- Fix pthread_setname detection to fail on warnings.
|
||||
|
||||
17 April 2026: Yorgos
|
||||
- Merge #1400: Support pthread_setname_np. Adds support for
|
||||
pthread_setname_np and variants to set the name on spawned threads
|
||||
for easier debugging/monitoring.
|
||||
|
||||
16 April 2026: Yorgos
|
||||
- Merge #1406: Introduce new 'tls-protocols' configuration option.
|
||||
- Introduce new 'tls-protocols' configuration option that specifies
|
||||
which of the supported TLS protocols will be used.
|
||||
This change invalidates some previous changes:
|
||||
- TLSv1.2 is again enabled by default, but can be selectively turned
|
||||
off if desired (related to #1303).
|
||||
- The biefly introduced (not yet released) 'tls-use-system-versions'
|
||||
configuration option, that addressed #1346, is reverted in favor of
|
||||
'tls-protocols'.
|
||||
- The briefly introduced (not yet released) '--enable-system-tls'
|
||||
configure option, related to #1401, is no longer needed with the new
|
||||
option and the current default.
|
||||
- Fix cleaning up DoH session. The same query can be on multiple
|
||||
streams in a session.
|
||||
|
||||
16 April 2026: Wouter
|
||||
- Fix configure, autoconf for #1406.
|
||||
|
||||
15 April 2026: Wouter
|
||||
- Fix RFC7766 compliance when client sends EOF over TCP. It stops
|
||||
pending replies and closes. Thanks to Yuxiao Wu, Tsinghua
|
||||
University for the report.
|
||||
- Fix to shorten RRSIG count in scrubber, this protects against
|
||||
an overly large number of RRSIGs. It can be configured with
|
||||
`iter-scrub-rrsig: 8`, it has default 8. Thanks to Yuxiao Wu,
|
||||
Tsinghua University for the report.
|
||||
|
||||
14 April 2026: Wouter
|
||||
- Fix #1017: memory corruption related core dumps.
|
||||
When alloc_reg_obtain has an empty list, return a new allocation.
|
||||
- Fix clang analyzer warning for subnetmod, when return_msg is
|
||||
NULL for update cache, like when it stores servfail status.
|
||||
- iana portlist updated.
|
||||
|
||||
13 April 2026: Yorgos
|
||||
- Update the documentation of 'max-query-restarts' in the man page.
|
||||
|
||||
10 April 2026: Wouter
|
||||
- Fix for EDNS client subnet so that it does not store SERVFAIL in
|
||||
the global cache after a failed lookup, such as timeouts. A failure
|
||||
entry is stored in the subnet cache, for the query name, for a
|
||||
couple of seconds. Queries can continue to use the subnet cache
|
||||
during that time.
|
||||
|
||||
7 April 2026: Yorgos
|
||||
- Fix unused variable warning.
|
||||
|
||||
30 March 2026: Wouter
|
||||
- Merge #1408: Fix shared memory stats with threads.
|
||||
|
||||
27 March 2026: Wouter
|
||||
- Fix to allow the control-interface config to use ip@port notation.
|
||||
- Fix test code to allow empty hex answer packets from testbound.
|
||||
- Fix defense in depth for service callback with empty packet.
|
||||
|
||||
24 March 2026: Wouter
|
||||
- Fix to check for invalid http content length and chunk size,
|
||||
and to check the RR rdata field lengths when decompressing and
|
||||
inserting RRs from an authority zone transfer. This stops
|
||||
large memory use and heap buffer-overflow read errors. Thanks
|
||||
to Haruto Kimura (Stella) for the report.
|
||||
|
||||
20 March 2026: Wouter
|
||||
- Fix for testcode pktview to check buffer size and log errors.
|
||||
|
||||
13 March 2026: Yorgos
|
||||
- Fix to ignore out-of-zone DNAME records for CNAME synthesis. Thanks
|
||||
to Yuxiao Wu, Yiyi Wang, Zhang Chao, Baojun Liu, and Haixin Duan from
|
||||
Tsinghua University.
|
||||
|
||||
13 March 2026: Wouter
|
||||
- Fix #278: DoT: complete unbound restart required on certificate
|
||||
renew. Fix so that a reload checks if the files have changed, and
|
||||
if so, reload the contexts. Also for DoH, DoQ and outgoing DoT.
|
||||
- iana portlist updated.
|
||||
- For #278: fast_reload can reload tls-service-key, tls-service-pem
|
||||
and tls-cert-bundle changes. It checks the modification time of
|
||||
the tls-service-key and tls-service-pem files for update.
|
||||
- Fix detection of http listening port in fast_reload.
|
||||
- Fix to add tls-service-key to memory printout for fast_reload.
|
||||
|
||||
9 March 2026: Wouter
|
||||
- Fix compile failure in unbound-checkconf for older gcc compiler.
|
||||
- Merge #1418: Apply cache TTL policy to DNAME and synthesized
|
||||
CNAME on wire path.
|
||||
|
||||
6 March 2026: Wouter
|
||||
- Merge #1415: Add lock unlock for view in memory error handling.
|
||||
|
||||
6 March 2026: Yorgos
|
||||
- Document the suggestion for a higher value for 'outgoing-range';
|
||||
helps when the request list is full.
|
||||
- Warn for unused 'nodefault' local-zone configuration in
|
||||
unbound-checkconf (related to #1416).
|
||||
|
||||
5 March 2026: Wouter
|
||||
- Fix for DNS Rebinding Bypass via SVCB/HTTPS Records in Unbound.
|
||||
Thanks to Kunta Chu, School of Software, Tsinghua University,
|
||||
Taofei Guo, Peking University, and Jianjun Chen, Institute for
|
||||
Network Sciences and Cyberspace, Tsinghua University for the
|
||||
report. The private-address option is fixed to also elide
|
||||
SVCB and HTTPS records that match the filter.
|
||||
- Update generated man pages.
|
||||
|
||||
4 March 2026: Yorgos
|
||||
- For #1411: Introduce a failing case in the rpl test so that it only
|
||||
passes with the fix in place.
|
||||
|
||||
3 March 2026: Wouter
|
||||
- Merge #1411: Allow synthesized DNAME TTL=0 to be served from cache
|
||||
within grace period. The responses are served from cache within
|
||||
a 1-second grace period. Reduces recursion when authoritative
|
||||
servers return DNAME with TTL=0 (RFC 2308). Response
|
||||
still returns TTL=0 to clients. Adds a test for it.
|
||||
- For #1411: Fix that the lookup for DNAME uses flag. Fix assertion
|
||||
in expired calc debug routine.
|
||||
|
||||
27 February 2026: Wouter
|
||||
- Merge #1409: Documentation CNAME in redirect-type local-zone.
|
||||
- Update generated man pages.
|
||||
|
||||
25 February 2026: Wouter
|
||||
- Fix validator to set unchecked when validation recursion
|
||||
requests are passed. The edns subnet module checks if validation
|
||||
is needed for a cache response, and set the validator to protect
|
||||
the cache with validation for non-subnet lookups.
|
||||
|
||||
23 February 2026: Wouter
|
||||
- Fix to have cachedb not return expired bogus data as non-bogus.
|
||||
- Fix to make the cachedb_val_expired.crpl succeed.
|
||||
|
||||
23 February 2026: Yorgos
|
||||
- Fix to disallow cache lookup/store in external cachedb when a
|
||||
forwarder/stub forbids it with the no-cache option.
|
||||
- Fixed some typos reported in #1395 by rezky_nightky.
|
||||
|
||||
17 February 2026: Wouter
|
||||
- Fix to remove unused conditional from cookie timestamp at
|
||||
worker env.
|
||||
- For #1405: local-zone always_refuse also blocks queries of type DS.
|
||||
|
||||
16 February 2026: Yorgos
|
||||
- Fix #1404: Priming the root key fails after loading ipfire.org RPZ
|
||||
zones. Fixed by including the ZONEMD RRtype in the list of types to
|
||||
ignore for RPZ zones. Analysis and patch provided by ummeegge.
|
||||
|
||||
16 February 2026: Wouter
|
||||
- Fix that cachedb aggressive negative responses have the RA flag set.
|
||||
|
||||
11 February 2026: Wouter
|
||||
- Fix #1403: Inconsistency between do-nat64 and do-not-query-address
|
||||
during retries.
|
||||
|
||||
9 February 2026: Wouter
|
||||
- Merge #1401: Add a new build-time option for system TLS.
|
||||
The --enable-system-tls flag enables the
|
||||
tls-use-system-policy-versions setting by default.
|
||||
- Update generated man pages.
|
||||
|
||||
6 February 2026: Yorgos
|
||||
- Fix #1389: [FR] replacement with ECC-GOST12 according to RFC9558.
|
||||
Patch contributed by Igor V. Ruzanov, available in
|
||||
contrib/gost12.patch.
|
||||
|
||||
4 February 2026: Wouter
|
||||
- Fix local privilege escalation on Windows. Thanks to Hao Huang and
|
||||
CrisprXiang with Fudan University for the report. The OpenSSL
|
||||
init calls are set to not load the openssl.cnf file when compiled
|
||||
for Windows.
|
||||
|
||||
3 February 2026: Yorgos
|
||||
- Eagerly remove .skip mark files in between mini_tdir.sh runs in case
|
||||
there has been a change on the environment.
|
||||
|
||||
27 January 2026: Wouter
|
||||
- Add test for allow-notify with a host name.
|
||||
|
||||
26 January 2026: Wouter
|
||||
- Fix that allow-notify entries with hostnames are copied after IPv4
|
||||
and IPv6 lookup.
|
||||
- Fix to not skip allow-notify hostname lookups when there are only
|
||||
urls.
|
||||
|
||||
23 January 2026: Yorgos
|
||||
- Merge #1396: Log Linux thread ID.
|
||||
- On Linux systems log the system-wide unique thread ID instead of
|
||||
Unbound's internal thread counter.
|
||||
- Introduce the 'log-thread-id' configuration option to manage logging
|
||||
the system-wide Linux thread ID for easier debugging with system
|
||||
tools.
|
||||
- Update generated man pages.
|
||||
|
||||
22 January 2026: Wouter
|
||||
- Fix that fast reload copies the iter_scrub_ns, iter_scrub_cname
|
||||
and max_global_quota options.
|
||||
- Fix http test tool petal to not print errors when there is no
|
||||
error.
|
||||
|
||||
21 January 2026: Wouter
|
||||
- Merge #1388: QNX Porting support for unbound.
|
||||
|
||||
19 January 2026: Wouter
|
||||
- Merge #1392: Include "V" (version) option in synopsis.
|
||||
|
||||
15 January 2026: Wouter
|
||||
- Fix documentation for requestlist.overwritten and
|
||||
requestlist.exceeded, it explains which query was dropped.
|
||||
|
||||
8 January 2026: Wouter
|
||||
- Merge #1381: Do not initialize quic_table unless it is enabled.
|
||||
|
||||
6 January 2026: Wouter
|
||||
- Fix edns subnet, that scope zero queries, when there is a
|
||||
subquery without subnet, and the forward-no-cache or
|
||||
stub-no-cache option is set, it is not stored in cache due to
|
||||
the forward or stub option.
|
||||
|
||||
6 January 2026: Yorgos
|
||||
- Merge #1391 from Götz Görisch: Fix documentation to adhere to
|
||||
RFC5952.
|
||||
|
||||
31 December 2025: Yorgos
|
||||
- Update the unbound-anchor man page to note write permissions of the
|
||||
generated file if it is to be used with Unbound's
|
||||
auto-trust-anchor-file option.
|
||||
- Use the same EDE removal logic when encoding errors as when encoding
|
||||
replies.
|
||||
|
||||
30 December 2025: Yorgos
|
||||
- Mark "THROWAWAY" and "(DNSSEC) LAME" responses clearly as Unbound's
|
||||
categorization in the log output.
|
||||
|
||||
24 December 2025: Yorgos
|
||||
- More specific wording in the unbound.conf man page for stub-first
|
||||
and forward-first options.
|
||||
|
||||
3 December 2025: Wouter
|
||||
- Fix http2 drop handling to clear the postpone_drop state so that
|
||||
other streams on the http2 session are not affected by a drop,
|
||||
and can clean up properly if also dropped. Fix http2 send reply
|
||||
so that when there is a send failure is does not recurse into
|
||||
the mesh functions and also does not drop the connection due to
|
||||
the condition of one stream.
|
||||
|
||||
2 December 2025: Wouter
|
||||
- Fix to remove http2 stream mesh state when mesh new request is
|
||||
dropping the new request.
|
||||
|
||||
1 December 2025: Wouter
|
||||
- Fix to add EDNS CO flag to testbound and debug message log.
|
||||
- Fix header comment about EDE reference in validator/val_sigcrypt.h.
|
||||
|
||||
28 November 2025: Yorgos
|
||||
- For #1375, there is no DNSTAP environment if it wasn't configured.
|
||||
|
||||
26 November 2025: Yorgos
|
||||
- Tag for 1.24.2 release.
|
||||
The repository continues with version 1.24.3.
|
||||
|
||||
13 November 2025: Wouter
|
||||
- Merge #1374: Mesh reply counters.
|
||||
This adds the statistics num.queries.replyaddr_limit and
|
||||
requestlist.current.replies.
|
||||
- Merge #1375: Copy DNSTAP changes from daemon to workers after
|
||||
fast_reload.
|
||||
|
||||
12 November 2025: Wouter
|
||||
- Fix that when discard timeout drops packet, they are accounted as
|
||||
less reply addresses in use in the mesh area.
|
||||
- iana portlist updated.
|
||||
|
||||
6 November 2025: Wouter
|
||||
- Fix add comment to worker_handle_request function that explain it.
|
||||
- Fix configure test for noreturn attribute so it compiles without
|
||||
warning.
|
||||
- Fix configure test for nonstring attribute so that it does not
|
||||
accept when the compiler prints a warning about an unknown
|
||||
attribute.
|
||||
|
||||
4 November 2025: Wouter
|
||||
- Fix dns64 log output to log the default instead of a null string.
|
||||
|
||||
1 November 2025: Yorgos
|
||||
- Fix #1366: Infra cache does not work correctly for NAT64, by
|
||||
moving the NAT64 synthesis from the iterator when selecting a target
|
||||
address, to the delegation point itself when adding target
|
||||
addresses.
|
||||
|
||||
27 October 2025: Yorgos
|
||||
- Merge #1331 from Jitka Plesníková: Replace deprecated $function by
|
||||
new $action, for SWIG.
|
||||
|
||||
+3
-3
@@ -13,7 +13,7 @@ If you're not using DNSSEC then you may remove "validator".
|
||||
|
||||
2. The "dns64-prefix" directive indicates your DNS64 prefix. For example:
|
||||
|
||||
dns64-prefix: 64:FF9B::/96
|
||||
dns64-prefix: 64:ff9b::/96
|
||||
|
||||
The prefix must be a /96 or shorter.
|
||||
|
||||
@@ -42,9 +42,9 @@ To enable NAT64 in Unbound, add to unbound.conf's "server" section:
|
||||
do-nat64: yes
|
||||
|
||||
The NAT64 prefix defaults to the DNS64 prefix, which in turn defaults to the
|
||||
standard 64:FF9B::/96 prefix. You can reconfigure it with:
|
||||
standard 64:ff9b::/96 prefix. You can reconfigure it with:
|
||||
|
||||
nat64-prefix: 64:FF9B::/96
|
||||
nat64-prefix: 64:ff9b::/96
|
||||
|
||||
To test NAT64 operation, pick a domain that only has IPv4 reachability for its
|
||||
nameservers and try resolving any names in that domain.
|
||||
|
||||
+19
-29
@@ -54,7 +54,7 @@ server:
|
||||
# interface: 192.0.2.153
|
||||
# interface: 192.0.2.154
|
||||
# interface: 192.0.2.154@5003
|
||||
# interface: 2001:DB8::5
|
||||
# interface: 2001:db8::5
|
||||
# interface: eth0@5003
|
||||
|
||||
# enable this feature to copy the source address of queries to reply.
|
||||
@@ -72,12 +72,12 @@ server:
|
||||
# server from by ip-address. If none, the default (all) interface
|
||||
# is used. Specify every interface on a 'outgoing-interface:' line.
|
||||
# outgoing-interface: 192.0.2.153
|
||||
# outgoing-interface: 2001:DB8::5
|
||||
# outgoing-interface: 2001:DB8::6
|
||||
# outgoing-interface: 2001:db8::5
|
||||
# outgoing-interface: 2001:db8::6
|
||||
|
||||
# Specify a netblock to use remainder 64 bits as random bits for
|
||||
# upstream queries. Uses freebind option (Linux).
|
||||
# outgoing-interface: 2001:DB8::/64
|
||||
# outgoing-interface: 2001:db8::/64
|
||||
# Also (Linux:) ip -6 addr add 2001:db8::/64 dev lo
|
||||
# And: ip -6 route add local 2001:db8::/64 dev lo
|
||||
# And set prefer-ip6: yes to use the ip6 randomness from a netblock.
|
||||
@@ -193,6 +193,9 @@ server:
|
||||
# Limit on number of CNAME, DNAME records for incoming packets.
|
||||
# iter-scrub-cname: 11
|
||||
|
||||
# Limit on number of RRSIGs for an RRset for incoming packets.
|
||||
# iter-scrub-rrsig: 8
|
||||
|
||||
# Limit on upstream queries for an incoming query and its recursion.
|
||||
# max-global-quota: 200
|
||||
|
||||
@@ -379,7 +382,7 @@ server:
|
||||
# interface-action: 192.0.2.153 allow
|
||||
# interface-action: 192.0.2.154 allow
|
||||
# interface-action: 192.0.2.154@5003 allow
|
||||
# interface-action: 2001:DB8::5 allow
|
||||
# interface-action: 2001:db8::5 allow
|
||||
# interface-action: eth0@5003 allow
|
||||
|
||||
# Similar to 'access-control-tag:' but for interfaces.
|
||||
@@ -496,6 +499,10 @@ server:
|
||||
# print log lines that say why queries return SERVFAIL to clients.
|
||||
# log-servfail: no
|
||||
|
||||
# log system-wide Linux thread ID, insted of Unbound's internal thread
|
||||
# counter. Only on Linux and only when threads are available.
|
||||
# log-thread-id: no
|
||||
|
||||
# the pid file. Can be an absolute path outside of chroot/work dir.
|
||||
# pidfile: "@UNBOUND_PIDFILE@"
|
||||
|
||||
@@ -658,7 +665,7 @@ server:
|
||||
# or, just before the iterator).
|
||||
# module-config: "validator iterator"
|
||||
|
||||
# File with trusted keys, kept uptodate using RFC5011 probes,
|
||||
# File with trusted keys, kept up-to-date using RFC5011 probes,
|
||||
# initial file like trust-anchor-file, then it stores metadata.
|
||||
# Use several entries, one per domain name, to track multiple zones.
|
||||
#
|
||||
@@ -718,7 +725,7 @@ server:
|
||||
# val-max-restart: 5
|
||||
|
||||
# Should additional section of secure message also be kept clean of
|
||||
# unsecure data. Useful to shield the users of this validator from
|
||||
# non-secure data. Useful to shield the users of this validator from
|
||||
# potential bogus data in the additional section. All unsigned data
|
||||
# in the additional section is removed from secure messages.
|
||||
# val-clean-additional: yes
|
||||
@@ -961,16 +968,12 @@ server:
|
||||
# tls-ciphersuites: "TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_8_SHA256:TLS_AES_128_CCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256"
|
||||
|
||||
# Use the SNI extension for TLS connections. Default is yes.
|
||||
# Changing the value requires a reload.
|
||||
# Changing the value requires a restart.
|
||||
# tls-use-sni: yes
|
||||
|
||||
# Allow general-purpose version-flexible TLS server configuration that
|
||||
# may be further restricted by the system's policy.
|
||||
# Use only if you want to support legacy TLS client connections.
|
||||
# Default is no and Unbound will only use the latest available TLS
|
||||
# version.
|
||||
# Changing the value requires a reload.
|
||||
# tls-use-system-policy-versions: no
|
||||
# TLS protocols.
|
||||
# Changing the value requires a restart.
|
||||
# tls-protocols: "TLSv1.2 TLSv1.3"
|
||||
|
||||
# Add the secret file for TLS Session Ticket.
|
||||
# Secret file must be 80 bytes of random data.
|
||||
@@ -1255,8 +1258,7 @@ remote-control:
|
||||
# authoritatively. zonefile: reads from file (and writes to it if you also
|
||||
# download it), primary: fetches with AXFR and IXFR, or url to zonefile.
|
||||
# With allow-notify: you can give additional (apart from primaries and urls)
|
||||
# sources of notifies. primary-tsig: and allow-notify-tsig: use addr keyname,
|
||||
# with the name of the TSIG key to use, declared as a tsig-key:.
|
||||
# sources of notifies.
|
||||
# auth-zone:
|
||||
# name: "."
|
||||
# primary: 170.247.170.2 # b.root-servers.net
|
||||
@@ -1438,7 +1440,6 @@ remote-control:
|
||||
# and drop. Policies can be loaded from a file, or using zone
|
||||
# transfer, or using HTTP. The respip module needs to be added
|
||||
# to the module-config, e.g.: module-config: "respip validator iterator".
|
||||
# Can also use primary-tsig: and allow-notify-tsig:
|
||||
# rpz:
|
||||
# name: "rpz.example.com"
|
||||
# zonefile: "rpz.example.com"
|
||||
@@ -1452,14 +1453,3 @@ remote-control:
|
||||
# rpz-signal-nxdomain-ra: no
|
||||
# for-downstream: no
|
||||
# tags: "example"
|
||||
|
||||
# TSIG keys
|
||||
# tsig-key:
|
||||
# # The key name is sent to the other party, it must be the same
|
||||
# name: "keyname"
|
||||
# # algorithm hmac-md5, or sha1, sha256, sha224, sha384, sha512
|
||||
# algorithm: sha256
|
||||
# # secret material, must be the same as the other party uses.
|
||||
# # base64 encoded random number.
|
||||
# # e.g. from dd if=/dev/random of=/dev/stdout count=1 bs=32 | base64
|
||||
# secret: "K2tf3TRjvQkVCmJF3/Z9vA=="
|
||||
|
||||
+1
-1
@@ -416,6 +416,6 @@ on a function return with file read failure.
|
||||
.SH AUTHOR
|
||||
Unbound developers are mentioned in the CREDITS file in the distribution.
|
||||
.SH COPYRIGHT
|
||||
1999-2025, NLnet Labs
|
||||
1999-2026, NLnet Labs
|
||||
.\" Generated by docutils manpage writer.
|
||||
.
|
||||
|
||||
+13
-4
@@ -39,9 +39,17 @@ unbound-anchor \- Unbound @version@ anchor utility.
|
||||
validation.
|
||||
The program fetches the trust anchor with the method from \fI\%RFC 7958\fP when
|
||||
regular \fI\%RFC 5011\fP update fails to bring it up to date.
|
||||
It can be run (as root) from the commandline, or run as part of startup
|
||||
scripts.
|
||||
Before you start the \fI\%unbound(8)\fP DNS server.
|
||||
It can be run from the commandline, or run as part of startup scripts before
|
||||
you start the \fI\%unbound(8)\fP DNS server.
|
||||
.sp
|
||||
Note that if you want to use \fI\%RFC 5011\fP with Unbound (i.e., the
|
||||
\fI\%auto\-trust\-anchor\-file\fP option) so
|
||||
that trust anchor information is automatically tracked by Unbound during
|
||||
operation, the user that Unbound runs under (by default \(aqunbound\(aq) must have
|
||||
write permissions to the file and the directory the file lives in (for creating
|
||||
temporary files).
|
||||
In this case you would probably want to run this program as the designated
|
||||
Unbound user.
|
||||
.sp
|
||||
Suggested usage:
|
||||
.INDENT 0.0
|
||||
@@ -52,6 +60,7 @@ Suggested usage:
|
||||
# in the init scripts.
|
||||
# provide or update the root anchor (if necessary)
|
||||
unbound\-anchor \-a \(dq@UNBOUND_ROOTKEY_FILE@\(dq
|
||||
|
||||
# Please note usage of this root anchor is at your own risk
|
||||
# and under the terms of our LICENSE (see source).
|
||||
#
|
||||
@@ -295,6 +304,6 @@ Signature on the root key information.
|
||||
.SH AUTHOR
|
||||
Unbound developers are mentioned in the CREDITS file in the distribution.
|
||||
.SH COPYRIGHT
|
||||
1999-2025, NLnet Labs
|
||||
1999-2026, NLnet Labs
|
||||
.\" Generated by docutils manpage writer.
|
||||
.
|
||||
|
||||
+12
-3
@@ -51,9 +51,17 @@ Description
|
||||
validation.
|
||||
The program fetches the trust anchor with the method from :rfc:`7958` when
|
||||
regular :rfc:`5011` update fails to bring it up to date.
|
||||
It can be run (as root) from the commandline, or run as part of startup
|
||||
scripts.
|
||||
Before you start the :doc:`unbound(8)</manpages/unbound>` DNS server.
|
||||
It can be run from the commandline, or run as part of startup scripts before
|
||||
you start the :doc:`unbound(8)</manpages/unbound>` DNS server.
|
||||
|
||||
Note that if you want to use :rfc:`5011` with Unbound (i.e., the
|
||||
:ref:`auto-trust-anchor-file<unbound.conf.auto-trust-anchor-file>` option) so
|
||||
that trust anchor information is automatically tracked by Unbound during
|
||||
operation, the user that Unbound runs under (by default 'unbound') must have
|
||||
write permissions to the file and the directory the file lives in (for creating
|
||||
temporary files).
|
||||
In this case you would probably want to run this program as the designated
|
||||
Unbound user.
|
||||
|
||||
Suggested usage:
|
||||
|
||||
@@ -62,6 +70,7 @@ Suggested usage:
|
||||
# in the init scripts.
|
||||
# provide or update the root anchor (if necessary)
|
||||
unbound-anchor -a "@UNBOUND_ROOTKEY_FILE@"
|
||||
|
||||
# Please note usage of this root anchor is at your own risk
|
||||
# and under the terms of our LICENSE (see source).
|
||||
#
|
||||
|
||||
@@ -88,6 +88,6 @@ Unbound configuration file.
|
||||
.SH AUTHOR
|
||||
Unbound developers are mentioned in the CREDITS file in the distribution.
|
||||
.SH COPYRIGHT
|
||||
1999-2025, NLnet Labs
|
||||
1999-2026, NLnet Labs
|
||||
.\" Generated by docutils manpage writer.
|
||||
.
|
||||
|
||||
@@ -168,6 +168,8 @@ ipset,
|
||||
\fI\%tcp\-auth\-query\-timeout\fP,
|
||||
\fI\%delay\-close\fP\&.
|
||||
\fI\%iter\-scrub\-promiscuous\fP\&.
|
||||
\fI\%tls\-service\-key\fP\&.
|
||||
\fI\%tls\-service\-pem\fP\&.
|
||||
.sp
|
||||
It does not work with
|
||||
\fI\%interface\fP and
|
||||
@@ -880,6 +882,11 @@ number of queries removed due to discard\-timeout by thread
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B threadX.num.queries_replyaddr_limit
|
||||
number of queries removed due to replyaddr limits by thread
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B threadX.num.queries_wait_limit
|
||||
number of queries removed due to wait\-limit by thread
|
||||
.UNINDENT
|
||||
@@ -973,6 +980,10 @@ Number of requests in the request list that were overwritten by newer
|
||||
entries.
|
||||
This happens if there is a flood of queries that recursive processing and
|
||||
the server has a hard time.
|
||||
The counter is increased when during the flood the
|
||||
\fI\%jostle\-timeout\fP
|
||||
allows a query to be removed in favor of a new incoming query.
|
||||
The older query is then dropped to make space.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
@@ -980,6 +991,12 @@ the server has a hard time.
|
||||
Queries that were dropped because the request list was full.
|
||||
This happens if a flood of queries need recursive processing, and the
|
||||
server can not keep up.
|
||||
The counter is increased when during the flood there is no space
|
||||
to be made with the jostle out of an older query, and the new query
|
||||
is dropped.
|
||||
Since no older queries are removed, see
|
||||
\fI\%jostle\-timeout\fP setting, there
|
||||
is no space for the new query.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
@@ -994,6 +1011,13 @@ Current size of the request list, only the requests from client queries.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B threadX.requestlist.current.replies
|
||||
Current count of the number of reply entries waiting on request list
|
||||
entries. Because a request list entry can send results to multiple reply
|
||||
addresses, this number may be larger than the size of the request list.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B threadX.recursion.time.avg
|
||||
Average time it took to answer queries that needed recursive processing.
|
||||
Note that queries that were answered from the cache are not in this average.
|
||||
@@ -1048,6 +1072,11 @@ summed over threads.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B total.num.queries_replyaddr_limit
|
||||
summed over threads.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B total.num.queries_wait_limit
|
||||
summed over threads.
|
||||
.UNINDENT
|
||||
@@ -1138,6 +1167,16 @@ summed over threads.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B total.requestlist.current.user
|
||||
summed over threads.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B total.requestlist.current.replies
|
||||
summed over threads.
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B total.recursion.time.median
|
||||
averaged over threads.
|
||||
.UNINDENT
|
||||
@@ -1543,6 +1582,6 @@ directory with private keys (\fBunbound_server.key\fP and
|
||||
.SH AUTHOR
|
||||
Unbound developers are mentioned in the CREDITS file in the distribution.
|
||||
.SH COPYRIGHT
|
||||
1999-2025, NLnet Labs
|
||||
1999-2026, NLnet Labs
|
||||
.\" Generated by docutils manpage writer.
|
||||
.
|
||||
|
||||
+34
-1
@@ -150,7 +150,6 @@ There are several commands that the server understands.
|
||||
:ref:`trusted-keys-file<unbound.conf.trusted-keys-file>`,
|
||||
:ref:`auto-trust-anchor-file<unbound.conf.auto-trust-anchor-file>`,
|
||||
:ref:`edns-client-string<unbound.conf.edns-client-string>`,
|
||||
:ref:`tsig-key<unbound.conf.tsig-key>`,
|
||||
ipset,
|
||||
:ref:`log-identity<unbound.conf.log-identity>`,
|
||||
:ref:`infra-cache-numhosts<unbound.conf.infra-cache-numhosts>`,
|
||||
@@ -171,6 +170,8 @@ There are several commands that the server understands.
|
||||
:ref:`tcp-auth-query-timeout<unbound.conf.tcp-auth-query-timeout>`,
|
||||
:ref:`delay-close<unbound.conf.delay-close>`.
|
||||
:ref:`iter-scrub-promiscuous<unbound.conf.iter-scrub-promiscuous>`.
|
||||
:ref:`tls-service-key<unbound.conf.tls-service-key>`.
|
||||
:ref:`tls-service-pem<unbound.conf.tls-service-pem>`.
|
||||
|
||||
It does not work with
|
||||
:ref:`interface<unbound.conf.interface>` and
|
||||
@@ -816,6 +817,10 @@ number of statistic counters:
|
||||
number of queries removed due to discard-timeout by thread
|
||||
|
||||
|
||||
@@UAHL@unbound-control.stats@threadX.num.queries_replyaddr_limit@@
|
||||
number of queries removed due to replyaddr limits by thread
|
||||
|
||||
|
||||
@@UAHL@unbound-control.stats@threadX.num.queries_wait_limit@@
|
||||
number of queries removed due to wait-limit by thread
|
||||
|
||||
@@ -894,12 +899,22 @@ number of statistic counters:
|
||||
entries.
|
||||
This happens if there is a flood of queries that recursive processing and
|
||||
the server has a hard time.
|
||||
The counter is increased when during the flood the
|
||||
:ref:`jostle-timeout<unbound.conf.jostle-timeout>`
|
||||
allows a query to be removed in favor of a new incoming query.
|
||||
The older query is then dropped to make space.
|
||||
|
||||
|
||||
@@UAHL@unbound-control.stats@threadX.requestlist.exceeded@@
|
||||
Queries that were dropped because the request list was full.
|
||||
This happens if a flood of queries need recursive processing, and the
|
||||
server can not keep up.
|
||||
The counter is increased when during the flood there is no space
|
||||
to be made with the jostle out of an older query, and the new query
|
||||
is dropped.
|
||||
Since no older queries are removed, see
|
||||
:ref:`jostle-timeout<unbound.conf.jostle-timeout>` setting, there
|
||||
is no space for the new query.
|
||||
|
||||
|
||||
@@UAHL@unbound-control.stats@threadX.requestlist.current.all@@
|
||||
@@ -911,6 +926,12 @@ number of statistic counters:
|
||||
Current size of the request list, only the requests from client queries.
|
||||
|
||||
|
||||
@@UAHL@unbound-control.stats@threadX.requestlist.current.replies@@
|
||||
Current count of the number of reply entries waiting on request list
|
||||
entries. Because a request list entry can send results to multiple reply
|
||||
addresses, this number may be larger than the size of the request list.
|
||||
|
||||
|
||||
@@UAHL@unbound-control.stats@threadX.recursion.time.avg@@
|
||||
Average time it took to answer queries that needed recursive processing.
|
||||
Note that queries that were answered from the cache are not in this average.
|
||||
@@ -956,6 +977,10 @@ number of statistic counters:
|
||||
summed over threads.
|
||||
|
||||
|
||||
@@UAHL@unbound-control.stats@total.num.queries_replyaddr_limit@@
|
||||
summed over threads.
|
||||
|
||||
|
||||
@@UAHL@unbound-control.stats@total.num.queries_wait_limit@@
|
||||
summed over threads.
|
||||
|
||||
@@ -1028,6 +1053,14 @@ number of statistic counters:
|
||||
summed over threads.
|
||||
|
||||
|
||||
@@UAHL@unbound-control.stats@total.requestlist.current.user@@
|
||||
summed over threads.
|
||||
|
||||
|
||||
@@UAHL@unbound-control.stats@total.requestlist.current.replies@@
|
||||
summed over threads.
|
||||
|
||||
|
||||
@@UAHL@unbound-control.stats@total.recursion.time.median@@
|
||||
averaged over threads.
|
||||
|
||||
|
||||
@@ -185,6 +185,6 @@ encountered a fatal error.
|
||||
.SH AUTHOR
|
||||
Unbound developers are mentioned in the CREDITS file in the distribution.
|
||||
.SH COPYRIGHT
|
||||
1999-2025, NLnet Labs
|
||||
1999-2026, NLnet Labs
|
||||
.\" Generated by docutils manpage writer.
|
||||
.
|
||||
|
||||
+2
-2
@@ -32,7 +32,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||||
unbound \- Unbound DNS validating resolver @version@.
|
||||
.SH SYNOPSIS
|
||||
.sp
|
||||
\fBunbound\fP [\fB\-hdpv\fP] [\fB\-c <cfgfile>\fP]
|
||||
\fBunbound\fP [\fB\-hdpVv\fP] [\fB\-c <cfgfile>\fP]
|
||||
.SH DESCRIPTION
|
||||
.sp
|
||||
\fBunbound\fP is a caching DNS resolver.
|
||||
@@ -118,6 +118,6 @@ Show the version number and build options, and exit.
|
||||
.SH AUTHOR
|
||||
Unbound developers are mentioned in the CREDITS file in the distribution.
|
||||
.SH COPYRIGHT
|
||||
1999-2025, NLnet Labs
|
||||
1999-2026, NLnet Labs
|
||||
.\" Generated by docutils manpage writer.
|
||||
.
|
||||
|
||||
+118
-31
@@ -102,7 +102,7 @@ server:
|
||||
interface: 0.0.0.0
|
||||
interface: ::0
|
||||
access\-control: 10.0.0.0/8 allow
|
||||
access\-control: 2001:DB8::/64 allow
|
||||
access\-control: 2001:db8::/64 allow
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
@@ -382,6 +382,10 @@ Default depends on compile options.
|
||||
Larger numbers need extra resources from the operating system.
|
||||
For performance a very large value is best, use libevent to make this
|
||||
possible.
|
||||
Should be higher (preferably double) than the value of
|
||||
\fI\%num\-queries\-per\-thread\fP to
|
||||
account for cases where the request list is full and avoid file descriptor
|
||||
starvation.
|
||||
.sp
|
||||
Default: 4096 (libevent) / 960 (minievent) / 48 (windows)
|
||||
.UNINDENT
|
||||
@@ -1135,9 +1139,13 @@ The file must contain the private key for the TLS session, the public
|
||||
certificate is in the \fI\%tls\-service\-pem\fP
|
||||
file and it must also be specified if
|
||||
\fI\%tls\-service\-key\fP is specified.
|
||||
Enabling or disabling this service requires a restart (a reload is not
|
||||
enough), because the key is read while root permissions are held and before
|
||||
chroot (if any).
|
||||
If the key is stored with root permissions or outside of chroot, then
|
||||
a change or enabling or disabling requires a restart (a reload is not
|
||||
enough).
|
||||
But if the key file (and tls\-service\-pem file) are accessible, then they
|
||||
are read in on reload, and fast_reload.
|
||||
The server checks the modification time of the file (and the filename)
|
||||
to see if the file has changed for reload.
|
||||
The ports enabled implicitly or explicitly via
|
||||
\fI\%tls\-port\fP and
|
||||
\fI\%https\-port\fP do not provide normal DNS TCP
|
||||
@@ -1290,7 +1298,7 @@ Enable or disable sending the SNI extension on TLS connections.
|
||||
\fBNOTE:\fP
|
||||
.INDENT 7.0
|
||||
.INDENT 3.5
|
||||
Changing the value requires a reload.
|
||||
Changing the value requires a restart.
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -1298,30 +1306,19 @@ Default: yes
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B tls\-use\-system\-policy\-versions: \fI<yes or no>\fP
|
||||
Enable or disable general\-puspose version\-flexible TLS server configuration
|
||||
when serving TLS.
|
||||
This will allow the whole list of available TLS versions provided by the
|
||||
crypto library, which may have been further restricted by the system\(aqs
|
||||
crypto policy.
|
||||
.sp
|
||||
By default Unbound only uses the latest available TLS version.
|
||||
.sp
|
||||
\fBCAUTION:\fP
|
||||
.INDENT 7.0
|
||||
.INDENT 3.5
|
||||
Use only if you want to support legacy TLS client connections.
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.B tls\-protocols: \fI\(dq<list of protocols>\(dq\fP
|
||||
Specify the allowed TLS protocol versions to use, in no particular order.
|
||||
Possible values are \fBTLSv1.2\fP and \fBTLSv1.3\fP\&.
|
||||
Enclose list of protocols in quotes (\fB\(dq\(dq\fP) and put spaces between them.
|
||||
.sp
|
||||
\fBNOTE:\fP
|
||||
.INDENT 7.0
|
||||
.INDENT 3.5
|
||||
Changing the value requires a reload.
|
||||
Changing the value requires a restart.
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
Default: no
|
||||
Default: \(dqTLSv1.2 TLSv1.3\(dq
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
@@ -1450,6 +1447,9 @@ The port number on which to provide DNS\-over\-QUIC service.
|
||||
Only interfaces configured with that port number as @number get the QUIC
|
||||
service.
|
||||
The interface uses QUIC for the UDP traffic on that port number.
|
||||
If it is set to 0, the server does not init QUIC code, and QUIC is
|
||||
disabled.
|
||||
This is similar to if QUIC is not in use, but then explicitly.
|
||||
.sp
|
||||
Default: 853
|
||||
.UNINDENT
|
||||
@@ -1927,6 +1927,16 @@ Default: no
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B log\-thread\-id: \fI<yes or no>\fP
|
||||
(Only on Linux and only when threads are available)
|
||||
Logs the system\-wide Linux thread ID instead of Unbound\(aqs internal thread
|
||||
counter.
|
||||
Can be useful when debugging with system tools.
|
||||
.sp
|
||||
Default: no
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B pidfile: \fI<filename>\fP
|
||||
The process id is written to the file.
|
||||
Default is \fB\(dq@UNBOUND_PIDFILE@\(dq\fP\&.
|
||||
@@ -2259,6 +2269,11 @@ This protects against so\-called DNS Rebinding, where a user browser is
|
||||
turned into a network proxy, allowing remote access through the browser to
|
||||
other parts of your private network.
|
||||
.sp
|
||||
The option removes resource records of types A, AAAA, SVCB and HTTPS
|
||||
that match the filter.
|
||||
Inside the SVCB and HTTPS records, the svcparams of type ipv4hint
|
||||
and ipv6hint are checked for matches.
|
||||
.sp
|
||||
Some names can be allowed to contain your private addresses, by default all
|
||||
the \fI\%local\-data\fP that you configured is
|
||||
allowed to, and you can specify additional names using
|
||||
@@ -2997,6 +3012,39 @@ local\-data: \(dqexample.com. A 127.0.0.1\(dq
|
||||
queries for \fBwww.example.com\fP and \fBwww.foo.example.com\fP are
|
||||
redirected, so that users with web browsers cannot access sites with
|
||||
suffix example.com.
|
||||
.sp
|
||||
A \fBCNAME\fP record can also be provided via local\-data:
|
||||
.INDENT 7.0
|
||||
.INDENT 3.5
|
||||
.sp
|
||||
.nf
|
||||
.ft C
|
||||
local\-zone: \(dqexample.com.\(dq redirect
|
||||
local\-data: \(dqexample.com. CNAME www.example.org.\(dq
|
||||
.ft P
|
||||
.fi
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
In that case, the \fBCNAME\fP is resolved and the answer
|
||||
includes resolved target records as well.
|
||||
The \fBCNAME\fP record has to be with the zone name of the local\-zone,
|
||||
and there can be one CNAME, not more.
|
||||
The \fBCNAME\fP record has to be at the zone apex of the
|
||||
\fBredirect\fP zone, then it is used for redirection.
|
||||
The resolution proceeds with upstream DNS resolution, and
|
||||
that does not include the lookup in local zones.
|
||||
So the record is not able to point in local zones, but it
|
||||
can point to upstream DNS answers.
|
||||
.sp
|
||||
\fBCNAME\fP resolution is supported only in type \fBredirect\fP
|
||||
local\-zone, and in type \fBinform_redirect\fP local\-zone.
|
||||
.sp
|
||||
As different from \fBCNAME\fP records that are used elsewhere, in
|
||||
the \fBredirect\fP type local\-zone, it is supported that in the target
|
||||
of the record a wildcard label gets expanded to the query name, with
|
||||
for example: \fBexample.com. CNAME *.foo.net.\fP gets expanded
|
||||
to \fBwww.example.com. CNAME www.example.com.foo.net.\fP\&.
|
||||
.UNINDENT
|
||||
.INDENT 7.0
|
||||
.TP
|
||||
@@ -3055,6 +3103,9 @@ use IPv6 protocol and avoid any queries to IPv4.
|
||||
.B always_refuse
|
||||
Like \fI\%refuse\fP, but ignores
|
||||
local data and refuses the query.
|
||||
This type also blocks queries of type DS for the zone name.
|
||||
That can break the DNSSEC chain of trust, but it is refused anyway.
|
||||
The block for type DS assists in more completely blocking the zone.
|
||||
.UNINDENT
|
||||
.INDENT 7.0
|
||||
.TP
|
||||
@@ -3377,7 +3428,7 @@ zone section below.
|
||||
Configure local data shorthand for a PTR record with the reversed IPv4 or
|
||||
IPv6 address and the host name.
|
||||
For example \fB\(dq192.0.2.4 www.example.com\(dq\fP\&.
|
||||
TTL can be inserted like this: \fB\(dq2001:DB8::4 7200 www.example.com\(dq\fP
|
||||
TTL can be inserted like this: \fB\(dq2001:db8::4 7200 www.example.com\(dq\fP
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
@@ -3718,6 +3769,10 @@ Default: 32
|
||||
Hard limit on the number of times Unbound is allowed to restart a query
|
||||
upon encountering a CNAME record.
|
||||
Results in SERVFAIL when reached.
|
||||
This applies to chained CNAME records but not sporadic CNAME records that
|
||||
could be encountered in the lifetime of the query\(aqs resolution effort.
|
||||
When a CNAME chain concludes, the counter keeping track of this limit is
|
||||
reset.
|
||||
Changing this value needs caution as it can allow long CNAME chains to be
|
||||
accepted, where Unbound needs to verify (resolve) each link individually.
|
||||
.sp
|
||||
@@ -3745,6 +3800,16 @@ Default: 11
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B iter\-scrub\-rrsig: \fI<number>\fP
|
||||
Limit on the number of RRSIGs allowed for an RRset, from the iterator
|
||||
scrubber.
|
||||
This protects against an overly large number of RRSIGs.
|
||||
Clips off the remainder of the RRSIG list at that point.
|
||||
.sp
|
||||
Default: 8
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B max\-global\-quota: \fI<number>\fP
|
||||
Limit on the number of upstream queries sent out for an incoming query and
|
||||
its subqueries from recursion.
|
||||
@@ -3926,7 +3991,7 @@ Default: no
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B control\-interface: \fI<IP address or interface name or path>\fP
|
||||
.B control\-interface: \fI<IP address or interface name[@port] or path>\fP
|
||||
Give IPv4 or IPv6 addresses or local socket path to listen on for control
|
||||
commands.
|
||||
If an interface name is used instead of an IP address, the list of IP
|
||||
@@ -4135,6 +4200,9 @@ Default: no
|
||||
If enabled, a query is attempted without this stub section if it fails.
|
||||
The data could not be retrieved and would have caused SERVFAIL because the
|
||||
servers are unreachable, instead it is tried without this stub section.
|
||||
This can lead to using less specific configured forward/stub/auth zones if
|
||||
any, or end up to otherwise normal recursive resolution for that particular
|
||||
query.
|
||||
.sp
|
||||
Default: no
|
||||
.UNINDENT
|
||||
@@ -4255,9 +4323,11 @@ The cert must also match a CA from the
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B forward\-first: \fI<yes or no>\fP
|
||||
If a forwarded query is met with a SERVFAIL error, and this option is
|
||||
enabled, Unbound will fall back to normal recursive resolution for this
|
||||
query as if no query forwarding had been specified.
|
||||
If a forwarded query is met with a SERVFAIL error and this option is
|
||||
enabled Unbound will fall back to less specific resolution.
|
||||
This can lead to using less specific configured forward/stub/auth zones if
|
||||
any, or end up to otherwise normal recursive resolution for that particular
|
||||
query.
|
||||
.sp
|
||||
Default: no
|
||||
.UNINDENT
|
||||
@@ -4370,9 +4440,15 @@ does not support AXFR/IXFR for the zone, but if you used
|
||||
\fI\%url\fP to download the zonefile as a text file
|
||||
from a webserver that would work.
|
||||
.sp
|
||||
If you specify the hostname, you cannot use the domain from the zonefile,
|
||||
because it may not have that when retrieving that data, instead use a plain
|
||||
IP address to avoid a circular dependency on retrieving that IP address.
|
||||
\fBCAUTION:\fP
|
||||
.INDENT 7.0
|
||||
.INDENT 3.5
|
||||
If you specify the hostname, you cannot use the domain from the
|
||||
zonefile, because it may not have that when retrieving that data,
|
||||
instead use a plain IP address to avoid a circular dependency on
|
||||
retrieving that IP address.
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
@@ -4732,6 +4808,17 @@ Default: no
|
||||
Use a specific NAT64 prefix to reach IPv4\-only servers.
|
||||
The prefix length must be one of /32, /40, /48, /56, /64 or /96.
|
||||
.sp
|
||||
The NAT64 prefix is allowed by the
|
||||
\fI\%do\-not\-query\-address\fP option,
|
||||
so that there is a clear outcome of addresses in both; the NAT64 prefix
|
||||
is allowed.
|
||||
The IPv4 address could be filtered by the
|
||||
\fI\%do\-not\-query\-address\fP option,
|
||||
if needed.
|
||||
Allowing the NAT64 prefix is useful when using do\-not\-query\-address
|
||||
for a cluster of machines that is IPv6\-only and uses NAT64, but does
|
||||
not have internet access.
|
||||
.sp
|
||||
Default: 64:ff9b::/96 (same as \fI\%dns64\-prefix\fP)
|
||||
.UNINDENT
|
||||
.SH DNSCRYPT OPTIONS
|
||||
@@ -5907,6 +5994,6 @@ Default is to log to \fIsyslog(3)\fP\&.
|
||||
.SH AUTHOR
|
||||
Unbound developers are mentioned in the CREDITS file in the distribution.
|
||||
.SH COPYRIGHT
|
||||
1999-2025, NLnet Labs
|
||||
1999-2026, NLnet Labs
|
||||
.\" Generated by docutils manpage writer.
|
||||
.
|
||||
|
||||
+100
-82
@@ -102,7 +102,7 @@ all the options.
|
||||
interface: 0.0.0.0
|
||||
interface: ::0
|
||||
access-control: 10.0.0.0/8 allow
|
||||
access-control: 2001:DB8::/64 allow
|
||||
access-control: 2001:db8::/64 allow
|
||||
|
||||
.. _unbound.conf.clauses:
|
||||
|
||||
@@ -366,6 +366,10 @@ These options are part of the ``server:`` section.
|
||||
Larger numbers need extra resources from the operating system.
|
||||
For performance a very large value is best, use libevent to make this
|
||||
possible.
|
||||
Should be higher (preferably double) than the value of
|
||||
:ref:`num-queries-per-thread<unbound.conf.num-queries-per-thread>` to
|
||||
account for cases where the request list is full and avoid file descriptor
|
||||
starvation.
|
||||
|
||||
Default: 4096 (libevent) / 960 (minievent) / 48 (windows)
|
||||
|
||||
@@ -1044,9 +1048,13 @@ These options are part of the ``server:`` section.
|
||||
certificate is in the :ref:`tls-service-pem<unbound.conf.tls-service-pem>`
|
||||
file and it must also be specified if
|
||||
:ref:`tls-service-key<unbound.conf.tls-service-key>` is specified.
|
||||
Enabling or disabling this service requires a restart (a reload is not
|
||||
enough), because the key is read while root permissions are held and before
|
||||
chroot (if any).
|
||||
If the key is stored with root permissions or outside of chroot, then
|
||||
a change or enabling or disabling requires a restart (a reload is not
|
||||
enough).
|
||||
But if the key file (and tls-service-pem file) are accessible, then they
|
||||
are read in on reload, and fast_reload.
|
||||
The server checks the modification time of the file (and the filename)
|
||||
to see if the file has changed for reload.
|
||||
The ports enabled implicitly or explicitly via
|
||||
:ref:`tls-port<unbound.conf.tls-port>` and
|
||||
:ref:`https-port<unbound.conf.https-port>` do not provide normal DNS TCP
|
||||
@@ -1172,25 +1180,19 @@ These options are part of the ``server:`` section.
|
||||
@@UAHL@unbound.conf@tls-use-sni@@: *<yes or no>*
|
||||
Enable or disable sending the SNI extension on TLS connections.
|
||||
|
||||
.. note:: Changing the value requires a reload.
|
||||
.. note:: Changing the value requires a restart.
|
||||
|
||||
Default: yes
|
||||
|
||||
|
||||
@@UAHL@unbound.conf@tls-use-system-policy-versions@@: *<yes or no>*
|
||||
Enable or disable general-puspose version-flexible TLS server configuration
|
||||
when serving TLS.
|
||||
This will allow the whole list of available TLS versions provided by the
|
||||
crypto library, which may have been further restricted by the system's
|
||||
crypto policy.
|
||||
@@UAHL@unbound.conf@tls-protocols@@: *"<list of protocols>"*
|
||||
Specify the allowed TLS protocol versions to use, in no particular order.
|
||||
Possible values are ``TLSv1.2`` and ``TLSv1.3``.
|
||||
Enclose list of protocols in quotes (``""``) and put spaces between them.
|
||||
|
||||
By default Unbound only uses the latest available TLS version.
|
||||
.. note:: Changing the value requires a restart.
|
||||
|
||||
.. caution:: Use only if you want to support legacy TLS client connections.
|
||||
|
||||
.. note:: Changing the value requires a reload.
|
||||
|
||||
Default: no
|
||||
Default: "TLSv1.2 TLSv1.3"
|
||||
|
||||
|
||||
@@UAHL@unbound.conf@pad-responses@@: *<yes or no>*
|
||||
@@ -1306,6 +1308,9 @@ These options are part of the ``server:`` section.
|
||||
Only interfaces configured with that port number as @number get the QUIC
|
||||
service.
|
||||
The interface uses QUIC for the UDP traffic on that port number.
|
||||
If it is set to 0, the server does not init QUIC code, and QUIC is
|
||||
disabled.
|
||||
This is similar to if QUIC is not in use, but then explicitly.
|
||||
|
||||
Default: 853
|
||||
|
||||
@@ -1714,6 +1719,15 @@ These options are part of the ``server:`` section.
|
||||
Default: no
|
||||
|
||||
|
||||
@@UAHL@unbound.conf@log-thread-id@@: *<yes or no>*
|
||||
(Only on Linux and only when threads are available)
|
||||
Logs the system-wide Linux thread ID instead of Unbound's internal thread
|
||||
counter.
|
||||
Can be useful when debugging with system tools.
|
||||
|
||||
Default: no
|
||||
|
||||
|
||||
@@UAHL@unbound.conf@pidfile@@: *<filename>*
|
||||
The process id is written to the file.
|
||||
Default is :file:`"@UNBOUND_PIDFILE@"`.
|
||||
@@ -2000,6 +2014,11 @@ These options are part of the ``server:`` section.
|
||||
turned into a network proxy, allowing remote access through the browser to
|
||||
other parts of your private network.
|
||||
|
||||
The option removes resource records of types A, AAAA, SVCB and HTTPS
|
||||
that match the filter.
|
||||
Inside the SVCB and HTTPS records, the svcparams of type ipv4hint
|
||||
and ipv6hint are checked for matches.
|
||||
|
||||
Some names can be allowed to contain your private addresses, by default all
|
||||
the :ref:`local-data<unbound.conf.local-data>` that you configured is
|
||||
allowed to, and you can specify additional names using
|
||||
@@ -2650,6 +2669,33 @@ These options are part of the ``server:`` section.
|
||||
redirected, so that users with web browsers cannot access sites with
|
||||
suffix example.com.
|
||||
|
||||
A ``CNAME`` record can also be provided via local-data:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
local-zone: "example.com." redirect
|
||||
local-data: "example.com. CNAME www.example.org."
|
||||
|
||||
In that case, the ``CNAME`` is resolved and the answer
|
||||
includes resolved target records as well.
|
||||
The ``CNAME`` record has to be with the zone name of the local-zone,
|
||||
and there can be one CNAME, not more.
|
||||
The ``CNAME`` record has to be at the zone apex of the
|
||||
``redirect`` zone, then it is used for redirection.
|
||||
The resolution proceeds with upstream DNS resolution, and
|
||||
that does not include the lookup in local zones.
|
||||
So the record is not able to point in local zones, but it
|
||||
can point to upstream DNS answers.
|
||||
|
||||
``CNAME`` resolution is supported only in type ``redirect``
|
||||
local-zone, and in type ``inform_redirect`` local-zone.
|
||||
|
||||
As different from ``CNAME`` records that are used elsewhere, in
|
||||
the ``redirect`` type local-zone, it is supported that in the target
|
||||
of the record a wildcard label gets expanded to the query name, with
|
||||
for example: ``example.com. CNAME *.foo.net.`` gets expanded
|
||||
to ``www.example.com. CNAME www.example.com.foo.net.``.
|
||||
|
||||
@@UAHL@unbound.conf.local-zone.type@inform@@
|
||||
The query is answered normally, same as
|
||||
:ref:`transparent<unbound.conf.local-zone.type.transparent>`.
|
||||
@@ -2689,6 +2735,9 @@ These options are part of the ``server:`` section.
|
||||
@@UAHL@unbound.conf.local-zone.type@always_refuse@@
|
||||
Like :ref:`refuse<unbound.conf.local-zone.type.refuse>`, but ignores
|
||||
local data and refuses the query.
|
||||
This type also blocks queries of type DS for the zone name.
|
||||
That can break the DNSSEC chain of trust, but it is refused anyway.
|
||||
The block for type DS assists in more completely blocking the zone.
|
||||
|
||||
@@UAHL@unbound.conf.local-zone.type@always_nxdomain@@
|
||||
Like :ref:`static<unbound.conf.local-zone.type.static>`, but ignores
|
||||
@@ -2896,7 +2945,7 @@ These options are part of the ``server:`` section.
|
||||
Configure local data shorthand for a PTR record with the reversed IPv4 or
|
||||
IPv6 address and the host name.
|
||||
For example ``"192.0.2.4 www.example.com"``.
|
||||
TTL can be inserted like this: ``"2001:DB8::4 7200 www.example.com"``
|
||||
TTL can be inserted like this: ``"2001:db8::4 7200 www.example.com"``
|
||||
|
||||
|
||||
@@UAHL@unbound.conf@local-zone-tag@@: *<zone> <"list of tags">*
|
||||
@@ -3211,6 +3260,10 @@ These options are part of the ``server:`` section.
|
||||
Hard limit on the number of times Unbound is allowed to restart a query
|
||||
upon encountering a CNAME record.
|
||||
Results in SERVFAIL when reached.
|
||||
This applies to chained CNAME records but not sporadic CNAME records that
|
||||
could be encountered in the lifetime of the query's resolution effort.
|
||||
When a CNAME chain concludes, the counter keeping track of this limit is
|
||||
reset.
|
||||
Changing this value needs caution as it can allow long CNAME chains to be
|
||||
accepted, where Unbound needs to verify (resolve) each link individually.
|
||||
|
||||
@@ -3235,6 +3288,15 @@ These options are part of the ``server:`` section.
|
||||
Default: 11
|
||||
|
||||
|
||||
@@UAHL@unbound.conf@iter-scrub-rrsig@@: *<number>*
|
||||
Limit on the number of RRSIGs allowed for an RRset, from the iterator
|
||||
scrubber.
|
||||
This protects against an overly large number of RRSIGs.
|
||||
Clips off the remainder of the RRSIG list at that point.
|
||||
|
||||
Default: 8
|
||||
|
||||
|
||||
@@UAHL@unbound.conf@max-global-quota@@: *<number>*
|
||||
Limit on the number of upstream queries sent out for an incoming query and
|
||||
its subqueries from recursion.
|
||||
@@ -3399,7 +3461,7 @@ To setup the correct self-signed certificates use the
|
||||
Default: no
|
||||
|
||||
|
||||
@@UAHL@unbound.conf.remote@control-interface@@: *<IP address or interface name or path>*
|
||||
@@UAHL@unbound.conf.remote@control-interface@@: *<IP address or interface name[@port] or path>*
|
||||
Give IPv4 or IPv6 addresses or local socket path to listen on for control
|
||||
commands.
|
||||
If an interface name is used instead of an IP address, the list of IP
|
||||
@@ -3587,6 +3649,9 @@ The :ref:`local-zone: nodefault<unbound.conf.local-zone.type.nodefault>` (or
|
||||
If enabled, a query is attempted without this stub section if it fails.
|
||||
The data could not be retrieved and would have caused SERVFAIL because the
|
||||
servers are unreachable, instead it is tried without this stub section.
|
||||
This can lead to using less specific configured forward/stub/auth zones if
|
||||
any, or end up to otherwise normal recursive resolution for that particular
|
||||
query.
|
||||
|
||||
Default: no
|
||||
|
||||
@@ -3699,9 +3764,11 @@ cache).
|
||||
|
||||
|
||||
@@UAHL@unbound.conf.forward@forward-first@@: *<yes or no>*
|
||||
If a forwarded query is met with a SERVFAIL error, and this option is
|
||||
enabled, Unbound will fall back to normal recursive resolution for this
|
||||
query as if no query forwarding had been specified.
|
||||
If a forwarded query is met with a SERVFAIL error and this option is
|
||||
enabled Unbound will fall back to less specific resolution.
|
||||
This can lead to using less specific configured forward/stub/auth zones if
|
||||
any, or end up to otherwise normal recursive resolution for that particular
|
||||
query.
|
||||
|
||||
Default: no
|
||||
|
||||
@@ -3823,12 +3890,6 @@ fallback activates to fetch from the upstream instead of the SERVFAIL.
|
||||
Alternate syntax for :ref:`primary<unbound.conf.auth.primary>`.
|
||||
|
||||
|
||||
@@UAHL@unbound.conf.auth@primary-tsig@@: *<IP address or host name>* *<tsig key>*
|
||||
Similar to :ref:`primary<unbound.conf.auth.primary>` and the tsig key
|
||||
is used for TSIG.
|
||||
The key name is from a :ref:`tsig-key<unbound.conf.tsig-key>` entry.
|
||||
|
||||
|
||||
@@UAHL@unbound.conf.auth@url@@: *<URL to zone file>*
|
||||
Where to download a zonefile for the zone.
|
||||
With HTTP or HTTPS.
|
||||
@@ -3875,12 +3936,6 @@ fallback activates to fetch from the upstream instead of the SERVFAIL.
|
||||
default.
|
||||
|
||||
|
||||
@@UAHL@unbound.conf.auth@allow-notify-tsig@@: *<IP address or host name or netblockIP/prefix>* *<tsig key>*
|
||||
Similar to :ref:`allow-notify<unbound.conf.auth.allow-notify>` and the
|
||||
tsig key is used for TSIG.
|
||||
The key name is from a :ref:`tsig-key<unbound.conf.tsig-key>` entry.
|
||||
|
||||
|
||||
@@UAHL@unbound.conf.auth@fallback-enabled@@: *<yes or no>*
|
||||
If enabled, Unbound falls back to querying the internet as a resolver for
|
||||
this zone when lookups fail.
|
||||
@@ -4156,6 +4211,17 @@ servers.
|
||||
Use a specific NAT64 prefix to reach IPv4-only servers.
|
||||
The prefix length must be one of /32, /40, /48, /56, /64 or /96.
|
||||
|
||||
The NAT64 prefix is allowed by the
|
||||
:ref:`do-not-query-address<unbound.conf.do-not-query-address>` option,
|
||||
so that there is a clear outcome of addresses in both; the NAT64 prefix
|
||||
is allowed.
|
||||
The IPv4 address could be filtered by the
|
||||
:ref:`do-not-query-address<unbound.conf.do-not-query-address>` option,
|
||||
if needed.
|
||||
Allowing the NAT64 prefix is useful when using do-not-query-address
|
||||
for a cluster of machines that is IPv6-only and uses NAT64, but does
|
||||
not have internet access.
|
||||
|
||||
Default: 64:ff9b::/96 (same as :ref:`dns64-prefix<unbound.conf.dns64.dns64-prefix>`)
|
||||
|
||||
.. _unbound.conf.dnscrypt:
|
||||
@@ -5030,12 +5096,6 @@ answer queries with that content.
|
||||
Alternate syntax for :ref:`primary<unbound.conf.rpz.primary>`.
|
||||
|
||||
|
||||
@@UAHL@unbound.conf.rpz@primary-tsig@@: *<IP address or host name>* *<tsig key>*
|
||||
Similar to :ref:`primary<unbound.conf.rpz.primary>` and the tsig key
|
||||
is used for TSIG.
|
||||
The key name is from a :ref:`tsig-key<unbound.conf.tsig-key>` entry.
|
||||
|
||||
|
||||
@@UAHL@unbound.conf.rpz@url@@: *<url to zonefile>*
|
||||
Where to download a zonefile for the zone.
|
||||
With HTTP or HTTPS.
|
||||
@@ -5073,12 +5133,6 @@ answer queries with that content.
|
||||
default.
|
||||
|
||||
|
||||
@@UAHL@unbound.conf.rpz@allow-notify-tsig@@: *<IP address or host name or netblockIP/prefix>* *<tsig key>*
|
||||
Similar to :ref:`allow-notify<unbound.conf.rpz.allow-notify>` and the
|
||||
tsig key is used for TSIG.
|
||||
The key name is from a :ref:`tsig-key<unbound.conf.tsig-key>` entry.
|
||||
|
||||
|
||||
@@UAHL@unbound.conf.rpz@zonefile@@: *<filename>*
|
||||
The filename where the zone is stored.
|
||||
If not given then no zonefile is used.
|
||||
@@ -5137,42 +5191,6 @@ answer queries with that content.
|
||||
If no tags are specified the policies from this section will be applied for
|
||||
all clients.
|
||||
|
||||
.. _unbound.conf.tsig-key:
|
||||
|
||||
TSIG Key Options
|
||||
^^^^^^^^^^^^^^^^^
|
||||
|
||||
The **tsig-key:** clauses specify the TSIG keys that are used.
|
||||
There can be multiple **tsig-key:** clauses, with each specifying a
|
||||
different key.
|
||||
Each key has a name, algorithm and secret key material.
|
||||
|
||||
TSIG keys are shared secrets.
|
||||
Both sides of the connection share the secret information.
|
||||
Also they must both use the same name for the key, and same algorithm.
|
||||
|
||||
With ``include: "key.conf"`` it is possible to put the declaration of the key
|
||||
or some lines of it in an external file from the main configuration file.
|
||||
It can also be used without such an include, with it the config statements
|
||||
and key material can be put in separate files.
|
||||
|
||||
|
||||
@@UAHL@unbound.conf.tsig-key@name@@: *"<key name>"*
|
||||
Name of the TSIG key.
|
||||
The key name is transferred in DNS wireformat in the TSIG record, and
|
||||
is used to reference the TSIG key from where it is configured to be used.
|
||||
|
||||
|
||||
@@UAHL@unbound.conf.tsig-key@algorithm@@: *<algorithm name>*
|
||||
Name of the algorithm to use with this TSIG key.
|
||||
This can be md5, sha1, sha224, sha256, sha384 or sha512.
|
||||
|
||||
|
||||
@@UAHL@unbound.conf.tsig-key@secret@@: *"<base64 blob>"*
|
||||
The secret contents is a base64 string.
|
||||
A way to get random base64 bytes is e.g.
|
||||
from ``dd if=/dev/random of=/dev/stdout count=1 bs=32 | base64``
|
||||
|
||||
Memory Control Example
|
||||
----------------------
|
||||
|
||||
|
||||
+1
-1
@@ -42,7 +42,7 @@ unbound(8)
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
**unbound** [``-hdpv``] [``-c <cfgfile>``]
|
||||
**unbound** [``-hdpVv``] [``-c <cfgfile>``]
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
+99
-5
@@ -70,6 +70,7 @@ subnet_data_delete(void *d, void *ATTR_UNUSED(arg))
|
||||
r = (struct subnet_msg_cache_data*)d;
|
||||
addrtree_delete(r->tree4);
|
||||
addrtree_delete(r->tree6);
|
||||
free(r->reason_fail);
|
||||
free(r);
|
||||
}
|
||||
|
||||
@@ -84,6 +85,8 @@ msg_cache_sizefunc(void *k, void *d)
|
||||
+ q->key.qname_len + lock_get_mem(&q->entry.lock);
|
||||
s += addrtree_size(r->tree4);
|
||||
s += addrtree_size(r->tree6);
|
||||
if(r->reason_fail)
|
||||
s += strlen(r->reason_fail)+1;
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -162,8 +165,15 @@ int ecs_whitelist_check(struct query_info* qinfo,
|
||||
if(!ecs_is_whitelisted(sn_env->whitelist,
|
||||
addr, addrlen, qinfo->qname, qinfo->qname_len,
|
||||
qinfo->qclass)) {
|
||||
verbose(VERB_ALGO, "subnet store subquery global, name and addr have no subnet treatment.");
|
||||
qstate->no_cache_store = 0;
|
||||
/* The stub or forward can have no_cache set.*/
|
||||
if(iter_stub_fwd_no_cache(qstate, &qstate->qinfo, NULL, NULL, NULL, 0)) {
|
||||
verbose(VERB_ALGO, "subnet subquery is not stored globally, stuborfwd is no_cache");
|
||||
} else {
|
||||
verbose(VERB_ALGO, "subnet store subquery global, name and addr have no subnet treatment.%s",
|
||||
(sq->started_no_cache_store?
|
||||
" But the subnet module was started with no_cache_store for the super query, and that is still applied to this query":""));
|
||||
qstate->no_cache_store = sq->started_no_cache_store;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
@@ -193,12 +203,18 @@ int ecs_whitelist_check(struct query_info* qinfo,
|
||||
if(sq->ecs_server_out.subnet_source_mask == 0) {
|
||||
sq->subnet_sent_no_subnet = 1;
|
||||
sq->subnet_sent = 0;
|
||||
/* The result should end up in subnet cache,
|
||||
* not in global cache. */
|
||||
qstate->no_cache_store = 1;
|
||||
return 1;
|
||||
}
|
||||
subnet_ecs_opt_list_append(&sq->ecs_server_out,
|
||||
&qstate->edns_opts_back_out, qstate, region);
|
||||
}
|
||||
sq->subnet_sent = 1;
|
||||
/* Do not store servfails in global cache, since the subnet
|
||||
* option is sent out. */
|
||||
qstate->no_cache_store = 1;
|
||||
}
|
||||
else {
|
||||
/* Outgoing ECS option is set, but we don't want to sent it to
|
||||
@@ -420,6 +436,35 @@ update_cache(struct module_qstate *qstate, int id)
|
||||
}
|
||||
/* lru_entry->lock is locked regardless of how we got here,
|
||||
* either from the slabhash_lookup, or above in the new allocated */
|
||||
if(!qstate->return_msg && qstate->error_response_cache) {
|
||||
struct subnet_msg_cache_data *data =
|
||||
(struct subnet_msg_cache_data*)lru_entry->data;
|
||||
data->ttl_servfail = *qstate->env->now + NORR_TTL;
|
||||
data->ede_fail = errinf_to_reason_bogus(qstate);
|
||||
diff_size = (data->reason_fail?strlen(data->reason_fail)+1:0);
|
||||
if(qstate->errinf) {
|
||||
char* str = errinf_to_str_misc(qstate);
|
||||
free(data->reason_fail);
|
||||
data->reason_fail = NULL;
|
||||
if(str)
|
||||
data->reason_fail = strdup(str);
|
||||
}
|
||||
diff_size = (data->reason_fail?strlen(data->reason_fail)+1:0)
|
||||
- diff_size;
|
||||
lock_rw_unlock(&lru_entry->lock);
|
||||
if (need_to_insert) {
|
||||
slabhash_insert(subnet_msg_cache, h, lru_entry,
|
||||
lru_entry->data, NULL);
|
||||
} else {
|
||||
slabhash_update_space_used(subnet_msg_cache, h, NULL,
|
||||
diff_size);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(!qstate->return_msg) {
|
||||
lock_rw_unlock(&lru_entry->lock);
|
||||
return;
|
||||
}
|
||||
/* Step 2, find the correct tree */
|
||||
if (!(tree = get_tree(lru_entry->data, edns, sne, qstate->env->cfg))) {
|
||||
lock_rw_unlock(&lru_entry->lock);
|
||||
@@ -463,6 +508,21 @@ update_cache(struct module_qstate *qstate, int id)
|
||||
}
|
||||
}
|
||||
|
||||
/** See if there is a stored servfail, returns true if so, and sets reply. */
|
||||
static int
|
||||
lookup_check_servfail(struct module_qstate *qstate,
|
||||
struct subnet_msg_cache_data *data)
|
||||
{
|
||||
struct module_env *env = qstate->env;
|
||||
if(!data)
|
||||
return 0;
|
||||
if(!data->ttl_servfail || TTL_IS_EXPIRED(data->ttl_servfail, *env->now))
|
||||
return 0;
|
||||
qstate->return_rcode = LDNS_RCODE_SERVFAIL;
|
||||
errinf_ede(qstate, data->reason_fail, data->ede_fail);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** Lookup in cache and reply true iff reply is sent. */
|
||||
static int
|
||||
lookup_and_reply(struct module_qstate *qstate, int id, struct subnet_qstate *sq, int prefetch)
|
||||
@@ -476,6 +536,8 @@ lookup_and_reply(struct module_qstate *qstate, int id, struct subnet_qstate *sq,
|
||||
struct addrtree *tree;
|
||||
struct addrnode *node;
|
||||
uint8_t scope;
|
||||
int must_validate = (!(qstate->query_flags&BIT_CD)
|
||||
|| qstate->env->cfg->ignore_cd) && qstate->env->need_to_validate;
|
||||
|
||||
memset(&sq->ecs_client_out, 0, sizeof(sq->ecs_client_out));
|
||||
|
||||
@@ -489,12 +551,20 @@ lookup_and_reply(struct module_qstate *qstate, int id, struct subnet_qstate *sq,
|
||||
tree = (ecs->subnet_addr_fam == EDNSSUBNET_ADDRFAM_IP4)?
|
||||
data->tree4 : data->tree6;
|
||||
if (!tree) { /* qinfo in cache but not for this family */
|
||||
if(lookup_check_servfail(qstate, data)) {
|
||||
lock_rw_unlock(&e->lock);
|
||||
return 1;
|
||||
}
|
||||
lock_rw_unlock(&e->lock);
|
||||
return 0;
|
||||
}
|
||||
node = addrtree_find(tree, (addrkey_t*)ecs->subnet_addr,
|
||||
ecs->subnet_source_mask, *env->now);
|
||||
if (!node) { /* plain old cache miss */
|
||||
if(lookup_check_servfail(qstate, data)) {
|
||||
lock_rw_unlock(&e->lock);
|
||||
return 1;
|
||||
}
|
||||
lock_rw_unlock(&e->lock);
|
||||
return 0;
|
||||
}
|
||||
@@ -503,12 +573,24 @@ lookup_and_reply(struct module_qstate *qstate, int id, struct subnet_qstate *sq,
|
||||
(struct reply_info *)node->elem, qstate->region, *env->now, 0,
|
||||
env->scratch);
|
||||
scope = (uint8_t)node->scope;
|
||||
lock_rw_unlock(&e->lock);
|
||||
|
||||
if (!qstate->return_msg) { /* Failed allocation or expired TTL */
|
||||
if(lookup_check_servfail(qstate, data)) {
|
||||
lock_rw_unlock(&e->lock);
|
||||
return 1;
|
||||
}
|
||||
lock_rw_unlock(&e->lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
lock_rw_unlock(&e->lock);
|
||||
if(qstate->return_msg->rep->security == sec_status_unchecked
|
||||
&& must_validate) {
|
||||
/* The message has to be validated first. */
|
||||
verbose(VERB_ALGO, "subnet: unchecked cache entry needs "
|
||||
"validation");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sq->subnet_downstream) { /* relay to interested client */
|
||||
sq->ecs_client_out.subnet_scope_mask = scope;
|
||||
sq->ecs_client_out.subnet_addr_fam = ecs->subnet_addr_fam;
|
||||
@@ -563,7 +645,10 @@ generate_sub_request(struct module_qstate *qstate, int id, struct subnet_qstate*
|
||||
qflags |= BIT_RD;
|
||||
if((qstate->query_flags & BIT_CD)!=0) {
|
||||
qflags |= BIT_CD;
|
||||
valrec = 1;
|
||||
/* The valrec is left off. Leave out: valrec = 1;
|
||||
* So that the cache is protected with DNSSEC validation.
|
||||
* Just like the global cache. DNSSEC validation is performed
|
||||
* regardless of the setting of the querier's CD flag. */
|
||||
}
|
||||
|
||||
fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub));
|
||||
@@ -580,6 +665,7 @@ generate_sub_request(struct module_qstate *qstate, int id, struct subnet_qstate*
|
||||
}
|
||||
subsq = (struct subnet_qstate*)subq->minfo[id];
|
||||
subsq->is_subquery_nonsubnet = 1;
|
||||
subsq->started_no_cache_store = sq->started_no_cache_store;
|
||||
|
||||
/* When the client asks 0.0.0.0/0 and the name is not treated
|
||||
* as subnet, it is to be stored in the global cache.
|
||||
@@ -632,6 +718,12 @@ eval_response(struct module_qstate *qstate, int id, struct subnet_qstate *sq)
|
||||
/* already an answer and its not a message, but retain
|
||||
* the actual rcode, instead of module_error, so send
|
||||
* module_finished */
|
||||
if(qstate->error_response_cache) {
|
||||
verbose(VERB_ALGO, "subnet: store error response");
|
||||
lock_rw_wrlock(&sne->biglock);
|
||||
update_cache(qstate, id);
|
||||
lock_rw_unlock(&sne->biglock);
|
||||
}
|
||||
return module_finished;
|
||||
}
|
||||
|
||||
@@ -881,9 +973,11 @@ ecs_edns_back_parsed(struct module_qstate* qstate, int id,
|
||||
sq->max_scope = sq->ecs_server_in.subnet_scope_mask;
|
||||
} else if(sq->subnet_sent_no_subnet) {
|
||||
/* The answer can be stored as scope 0, not in global cache. */
|
||||
/* This was already set in ecs_whitelist_check */
|
||||
qstate->no_cache_store = 1;
|
||||
} else if(sq->subnet_sent) {
|
||||
/* Need another query to be able to store in global cache. */
|
||||
/* This was already set in ecs_whitelist_check */
|
||||
qstate->no_cache_store = 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -69,8 +69,18 @@ struct subnet_env {
|
||||
};
|
||||
|
||||
struct subnet_msg_cache_data {
|
||||
/** Tree for nodes with IPv4 subnets. */
|
||||
struct addrtree* tree4;
|
||||
/** Tree for nodes with IPv6 subnets. */
|
||||
struct addrtree* tree6;
|
||||
/** If servfail is stored, for how long. Abs time in seconds.
|
||||
* This protects against too much recusion on the item when
|
||||
* resolution fails, for a couple of seconds. */
|
||||
time_t ttl_servfail;
|
||||
/** servfail ede */
|
||||
sldns_ede_code ede_fail;
|
||||
/** servfail reason */
|
||||
char* reason_fail;
|
||||
};
|
||||
|
||||
struct subnet_qstate {
|
||||
|
||||
+167
-1
@@ -207,6 +207,168 @@ size_t priv_get_mem(struct iter_priv* priv)
|
||||
return sizeof(*priv) + regional_get_mem(priv->region);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if svcparam ipv4hint contains a private address.
|
||||
* @param priv: private address lookup struct.
|
||||
* @param d: the data bytes.
|
||||
* @param data_len: number of data bytes in the svcparam.
|
||||
* @param addr: address to return the private address to log in to.
|
||||
* It has space for IPv4 and IPv6 addresses.
|
||||
* @param addrlen: length of the addr. Returns the correct size for the addr.
|
||||
* @return true if the rdata contains a private address.
|
||||
*/
|
||||
static int svcb_ipv4hint_contains_priv_addr(struct iter_priv* priv,
|
||||
uint8_t* d, uint16_t data_len, struct sockaddr_storage* addr,
|
||||
socklen_t* addrlen)
|
||||
{
|
||||
struct sockaddr_in sa;
|
||||
*addrlen = (socklen_t)sizeof(struct sockaddr_in);
|
||||
memset(&sa, 0, sizeof(struct sockaddr_in));
|
||||
sa.sin_family = AF_INET;
|
||||
sa.sin_port = (in_port_t)htons(UNBOUND_DNS_PORT);
|
||||
|
||||
while(data_len >= LDNS_IP4ADDRLEN) {
|
||||
memmove(&sa.sin_addr, d, LDNS_IP4ADDRLEN);
|
||||
memmove(addr, &sa, *addrlen);
|
||||
if(priv_lookup_addr(priv, addr, *addrlen))
|
||||
return 1;
|
||||
|
||||
d += LDNS_IP4ADDRLEN;
|
||||
data_len -= LDNS_IP4ADDRLEN;
|
||||
}
|
||||
/* if data_len != 0 here, then the svcparam is malformed. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if svcparam ipv6hint contains a private address.
|
||||
* @param priv: private address lookup struct.
|
||||
* @param d: the data bytes.
|
||||
* @param data_len: number of data bytes in the svcparam.
|
||||
* @param addr: address to return the private address to log in to.
|
||||
* It has space for IPv4 and IPv6 addresses.
|
||||
* @param addrlen: length of the addr. Returns the correct size for the addr.
|
||||
* @return true if the rdata contains a private address.
|
||||
*/
|
||||
static int svcb_ipv6hint_contains_priv_addr(struct iter_priv* priv,
|
||||
uint8_t* d, uint16_t data_len, struct sockaddr_storage* addr,
|
||||
socklen_t* addrlen)
|
||||
{
|
||||
struct sockaddr_in6 sa;
|
||||
*addrlen = (socklen_t)sizeof(struct sockaddr_in6);
|
||||
memset(&sa, 0, sizeof(struct sockaddr_in6));
|
||||
sa.sin6_family = AF_INET6;
|
||||
sa.sin6_port = (in_port_t)htons(UNBOUND_DNS_PORT);
|
||||
|
||||
while(data_len >= LDNS_IP6ADDRLEN) {
|
||||
memmove(&sa.sin6_addr, d, LDNS_IP6ADDRLEN);
|
||||
memmove(addr, &sa, *addrlen);
|
||||
if(priv_lookup_addr(priv, addr, *addrlen))
|
||||
return 1;
|
||||
|
||||
d += LDNS_IP6ADDRLEN;
|
||||
data_len -= LDNS_IP6ADDRLEN;
|
||||
}
|
||||
/* if data_len != 0 here, then the svcparam is malformed. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if type SVCB and HTTPS rdata contains a private address.
|
||||
* @param priv: private address lookup struct.
|
||||
* @param pkt: the packet.
|
||||
* @param rr: the rr with rdata to check.
|
||||
* @param addr: address to return the private address to log in to.
|
||||
* @param addrlen: length of the addr. Initially the total size, on
|
||||
* return the correct size for the addr.
|
||||
* @return true if the rdata contains a private address.
|
||||
*/
|
||||
static int svcb_rr_contains_priv_addr(struct iter_priv* priv,
|
||||
sldns_buffer* pkt, struct rr_parse* rr, struct sockaddr_storage* addr,
|
||||
socklen_t* addrlen)
|
||||
{
|
||||
uint8_t* d = rr->ttl_data;
|
||||
uint16_t svcparamkey, data_len, rdatalen;
|
||||
size_t oldpos, dname_len, dname_start, dname_compr_len;
|
||||
d += 4; /* skip TTL */
|
||||
rdatalen = sldns_read_uint16(d); /* read rdata length */
|
||||
d += 2;
|
||||
|
||||
if(rdatalen < 2 /* priority */ + 1 /* 1 length target */)
|
||||
return 0; /* malformed, too short */
|
||||
d += 2; /* skip priority */
|
||||
rdatalen -= 2;
|
||||
oldpos = sldns_buffer_position(pkt);
|
||||
sldns_buffer_set_position(pkt, (size_t)(d - sldns_buffer_begin(pkt)));
|
||||
dname_start = sldns_buffer_position(pkt);
|
||||
dname_len = pkt_dname_len(pkt);
|
||||
dname_compr_len = sldns_buffer_position(pkt) - dname_start;
|
||||
sldns_buffer_set_position(pkt, oldpos);
|
||||
if(dname_len == 0)
|
||||
return 0; /* dname malformed */
|
||||
if(dname_compr_len > rdatalen)
|
||||
return 0; /* malformed */
|
||||
d += dname_compr_len; /* skip target */
|
||||
rdatalen -= dname_compr_len;
|
||||
|
||||
while(rdatalen >= 4) {
|
||||
svcparamkey = sldns_read_uint16(d);
|
||||
data_len = sldns_read_uint16(d+2);
|
||||
d += 4;
|
||||
rdatalen -= 4;
|
||||
|
||||
/* verify that we have data_len data */
|
||||
if(data_len > rdatalen) {
|
||||
/* It is malformed, but if there are addresses
|
||||
* in there it can be rejected. */
|
||||
data_len = rdatalen;
|
||||
}
|
||||
|
||||
if(!data_len)
|
||||
continue; /* no data for the svcparamkey */
|
||||
|
||||
if(svcparamkey == SVCB_KEY_IPV4HINT) {
|
||||
if(svcb_ipv4hint_contains_priv_addr(priv, d, data_len,
|
||||
addr, addrlen))
|
||||
return 1;
|
||||
} else if(svcparamkey == SVCB_KEY_IPV6HINT) {
|
||||
if(svcb_ipv6hint_contains_priv_addr(priv, d, data_len,
|
||||
addr, addrlen))
|
||||
return 1;
|
||||
}
|
||||
d += data_len;
|
||||
rdatalen -= data_len;
|
||||
}
|
||||
/* If rdatalen != 0 here, then the svcb rdata is malformed. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the SVCB and HTTPS rrset is bad.
|
||||
* @param priv: private address lookup struct.
|
||||
* @param pkt: the packet.
|
||||
* @param rrset: the rrset to check.
|
||||
* @return 1 if the entire rrset has to be removed. 0 if not.
|
||||
* It removes RRs if they have private addresses, and log that.
|
||||
*/
|
||||
static int priv_svcb_rrset_bad(struct iter_priv* priv, sldns_buffer* pkt,
|
||||
struct rrset_parse* rrset)
|
||||
{
|
||||
struct rr_parse* rr, *prev = NULL;
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addrlen = (socklen_t)sizeof(addr);
|
||||
for(rr = rrset->rr_first; rr; rr = rr->next) {
|
||||
if(svcb_rr_contains_priv_addr(priv, pkt, rr, &addr,
|
||||
&addrlen)) {
|
||||
if(msgparse_rrset_remove_rr("sanitize: removing public name with private address", pkt, rrset, prev, rr, &addr, addrlen))
|
||||
return 1;
|
||||
continue;
|
||||
}
|
||||
prev = rr;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int priv_rrset_bad(struct iter_priv* priv, sldns_buffer* pkt,
|
||||
struct rrset_parse* rrset)
|
||||
{
|
||||
@@ -268,7 +430,11 @@ int priv_rrset_bad(struct iter_priv* priv, sldns_buffer* pkt,
|
||||
}
|
||||
prev = rr;
|
||||
}
|
||||
}
|
||||
} else if(rrset->type == LDNS_RR_TYPE_SVCB ||
|
||||
rrset->type == LDNS_RR_TYPE_HTTPS) {
|
||||
if(priv_svcb_rrset_bad(priv, pkt, rrset))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
+105
-12
@@ -285,6 +285,17 @@ synth_cname_rrset(uint8_t** sname, size_t* snamelen, uint8_t* alias,
|
||||
return NULL;
|
||||
memmove(cn->rr_first->ttl_data, rrset->rr_first->ttl_data,
|
||||
sizeof(uint32_t)); /* RFC6672: synth CNAME TTL == DNAME TTL */
|
||||
/* Apply cache TTL policy so DNAME and synthesized CNAME stay equal
|
||||
* and respect cache-min-ttl/cache-max-ttl (same as rdata_copy path). */
|
||||
if(!SERVE_ORIGINAL_TTL) {
|
||||
uint32_t ttl = sldns_read_uint32(cn->rr_first->ttl_data);
|
||||
time_t ttl_t = (time_t)ttl;
|
||||
if(ttl_t < MIN_TTL) ttl_t = MIN_TTL;
|
||||
if(ttl_t > MAX_TTL) ttl_t = MAX_TTL;
|
||||
ttl = (uint32_t)ttl_t;
|
||||
sldns_write_uint32(cn->rr_first->ttl_data, ttl);
|
||||
sldns_write_uint32(rrset->rr_first->ttl_data, ttl);
|
||||
}
|
||||
sldns_write_uint16(cn->rr_first->ttl_data+4, aliaslen);
|
||||
memmove(cn->rr_first->ttl_data+6, alias, aliaslen);
|
||||
cn->rr_first->size = sizeof(uint16_t)+aliaslen;
|
||||
@@ -408,6 +419,43 @@ shorten_rrset(sldns_buffer* pkt, struct rrset_parse* rrset, int count)
|
||||
else rrset->rr_first = NULL;
|
||||
}
|
||||
|
||||
/** Shorten RRSIGs list */
|
||||
static void
|
||||
shorten_rrsig(sldns_buffer* pkt, struct rrset_parse* rrset, int count)
|
||||
{
|
||||
/* The too large list of RRSIGs on the RRset is shortened.
|
||||
* This is so that too large content does not overwhelm the cache.
|
||||
* The validator does not validate more than a max number of
|
||||
* RRSIGs as well. */
|
||||
int i;
|
||||
struct rr_parse* rr = rrset->rrsig_first, *prev = NULL;
|
||||
if(!rr)
|
||||
return;
|
||||
for(i=0; i<count; i++) {
|
||||
prev = rr;
|
||||
rr = rr->next;
|
||||
if(!rr)
|
||||
return; /* The RRSIG list is already short. */
|
||||
}
|
||||
if(verbosity >= VERB_QUERY
|
||||
&& rrset->dname_len <= LDNS_MAX_DOMAINLEN) {
|
||||
uint8_t buf[LDNS_MAX_DOMAINLEN+1];
|
||||
dname_pkt_copy(pkt, buf, rrset->dname);
|
||||
log_nametypeclass(VERB_QUERY, "normalize: shorten RRSIGs:",
|
||||
buf, rrset->type, ntohs(rrset->rrset_class));
|
||||
}
|
||||
/* remove further rrsigs */
|
||||
rrset->rrsig_last = prev;
|
||||
rrset->rrsig_count = count;
|
||||
while(rr) {
|
||||
rrset->size -= rr->size;
|
||||
rr = rr->next;
|
||||
}
|
||||
if(rrset->rrsig_last)
|
||||
rrset->rrsig_last->next = NULL;
|
||||
else rrset->rrsig_first = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine normalizes a response. This includes removing "irrelevant"
|
||||
* records from the answer and additional sections and (re)synthesizing
|
||||
@@ -418,12 +466,13 @@ shorten_rrset(sldns_buffer* pkt, struct rrset_parse* rrset, int count)
|
||||
* @param qinfo: original query.
|
||||
* @param region: where to allocate synthesized CNAMEs.
|
||||
* @param env: module env with config options.
|
||||
* @param zonename: name of server zone.
|
||||
* @return 0 on error.
|
||||
*/
|
||||
static int
|
||||
scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
|
||||
struct query_info* qinfo, struct regional* region,
|
||||
struct module_env* env)
|
||||
struct module_env* env, uint8_t* zonename)
|
||||
{
|
||||
uint8_t* sname = qinfo->qname;
|
||||
size_t snamelen = qinfo->qname_len;
|
||||
@@ -431,7 +480,8 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
|
||||
int cname_length = 0; /* number of CNAMEs, or DNAMEs */
|
||||
|
||||
if(FLAGS_GET_RCODE(msg->flags) != LDNS_RCODE_NOERROR &&
|
||||
FLAGS_GET_RCODE(msg->flags) != LDNS_RCODE_NXDOMAIN)
|
||||
FLAGS_GET_RCODE(msg->flags) != LDNS_RCODE_NXDOMAIN &&
|
||||
FLAGS_GET_RCODE(msg->flags) != LDNS_RCODE_YXDOMAIN)
|
||||
return 1;
|
||||
|
||||
/* For the ANSWER section, remove all "irrelevant" records and add
|
||||
@@ -443,6 +493,8 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
|
||||
prev = NULL;
|
||||
rrset = msg->rrset_first;
|
||||
while(rrset && rrset->section == LDNS_SECTION_ANSWER) {
|
||||
if((int)rrset->rrsig_count > env->cfg->iter_scrub_rrsig)
|
||||
shorten_rrsig(pkt, rrset, env->cfg->iter_scrub_rrsig);
|
||||
if(cname_length > env->cfg->iter_scrub_cname) {
|
||||
/* Too many CNAMEs, or DNAMEs, from the authority
|
||||
* server, scrub down the length to something
|
||||
@@ -453,8 +505,9 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
|
||||
pkt, msg, prev, &rrset);
|
||||
continue;
|
||||
}
|
||||
if(rrset->type == LDNS_RR_TYPE_DNAME &&
|
||||
pkt_strict_sub(pkt, sname, rrset->dname)) {
|
||||
if(rrset->type == LDNS_RR_TYPE_DNAME &&
|
||||
pkt_strict_sub(pkt, sname, rrset->dname) &&
|
||||
pkt_sub(pkt, rrset->dname, zonename)) {
|
||||
/* check if next rrset is correct CNAME. else,
|
||||
* synthesize a CNAME */
|
||||
struct rrset_parse* nx = rrset->rrset_all_next;
|
||||
@@ -470,6 +523,11 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
|
||||
&aliaslen, pkt)) {
|
||||
verbose(VERB_ALGO, "synthesized CNAME "
|
||||
"too long");
|
||||
if(FLAGS_GET_RCODE(msg->flags) == LDNS_RCODE_YXDOMAIN) {
|
||||
prev = rrset;
|
||||
rrset = rrset->rrset_all_next;
|
||||
continue;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
cname_length++;
|
||||
@@ -495,8 +553,6 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
|
||||
log_err("out of memory synthesizing CNAME");
|
||||
return 0;
|
||||
}
|
||||
/* FIXME: resolve the conflict between synthesized
|
||||
* CNAME ttls and the cache. */
|
||||
rrset = nx;
|
||||
continue;
|
||||
|
||||
@@ -518,7 +574,8 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
|
||||
if(nx && nx->section == LDNS_SECTION_ANSWER &&
|
||||
nx->type == LDNS_RR_TYPE_DNAME &&
|
||||
nx->rr_count == 1 &&
|
||||
pkt_strict_sub(pkt, sname, nx->dname)) {
|
||||
pkt_strict_sub(pkt, sname, nx->dname) &&
|
||||
pkt_sub(pkt, nx->dname, zonename)) {
|
||||
/* there is a DNAME after this CNAME, it
|
||||
* is in the ANSWER section, and the DNAME
|
||||
* applies to the name we cover */
|
||||
@@ -613,6 +670,8 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
|
||||
"RRset:", pkt, msg, prev, &rrset);
|
||||
continue;
|
||||
}
|
||||
if((int)rrset->rrsig_count > env->cfg->iter_scrub_rrsig)
|
||||
shorten_rrsig(pkt, rrset, env->cfg->iter_scrub_rrsig);
|
||||
/* only one NS set allowed in authority section */
|
||||
if(rrset->type==LDNS_RR_TYPE_NS) {
|
||||
/* NS set must be pertinent to the query */
|
||||
@@ -650,6 +709,29 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
|
||||
"RRset:", pkt, msg, prev, &rrset);
|
||||
continue;
|
||||
}
|
||||
/* Also delete promiscuous NS for other RCODEs */
|
||||
if(FLAGS_GET_RCODE(msg->flags) != LDNS_RCODE_NOERROR
|
||||
&& env->cfg->iter_scrub_promiscuous) {
|
||||
remove_rrset("normalize: removing promiscuous "
|
||||
"RRset:", pkt, msg, prev, &rrset);
|
||||
continue;
|
||||
}
|
||||
/* Also delete promiscuous NS for NOERROR with nodata
|
||||
* for authoritative answers, not for delegations.
|
||||
* NOERROR with an_rrsets!=0 already handled.
|
||||
* Also NOERROR and soa_in_auth already handled.
|
||||
* NOERROR with an_rrsets==0, and not a referral.
|
||||
* referral is (NS not the zonename, noSOA).
|
||||
*/
|
||||
if(FLAGS_GET_RCODE(msg->flags) == LDNS_RCODE_NOERROR
|
||||
&& msg->an_rrsets == 0
|
||||
&& !(dname_pkt_compare(pkt, rrset->dname,
|
||||
zonename) != 0 && !soa_in_auth(msg))
|
||||
&& env->cfg->iter_scrub_promiscuous) {
|
||||
remove_rrset("normalize: removing promiscuous "
|
||||
"RRset:", pkt, msg, prev, &rrset);
|
||||
continue;
|
||||
}
|
||||
if(nsset == NULL) {
|
||||
nsset = rrset;
|
||||
} else {
|
||||
@@ -695,7 +777,13 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
|
||||
rrset->rrset_all_next = NULL;
|
||||
return 1;
|
||||
}
|
||||
mark_additional_rrset(pkt, msg, rrset);
|
||||
/* Only mark glue as allowed for type NS in the authority
|
||||
* section. Other RR types do not get glue for them, it
|
||||
* is allowed from the answer section, but not authority
|
||||
* so that a message can not have address records cached
|
||||
* as a side effect to the query. */
|
||||
if(rrset->type==LDNS_RR_TYPE_NS)
|
||||
mark_additional_rrset(pkt, msg, rrset);
|
||||
prev = rrset;
|
||||
rrset = rrset->rrset_all_next;
|
||||
}
|
||||
@@ -732,6 +820,8 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
|
||||
"RRset:", pkt, msg, prev, &rrset);
|
||||
continue;
|
||||
}
|
||||
if((int)rrset->rrsig_count > env->cfg->iter_scrub_rrsig)
|
||||
shorten_rrsig(pkt, rrset, env->cfg->iter_scrub_rrsig);
|
||||
prev = rrset;
|
||||
rrset = rrset->rrset_all_next;
|
||||
}
|
||||
@@ -942,8 +1032,10 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg,
|
||||
}
|
||||
|
||||
/* remove private addresses */
|
||||
if( (rrset->type == LDNS_RR_TYPE_A ||
|
||||
rrset->type == LDNS_RR_TYPE_AAAA)) {
|
||||
if(rrset->type == LDNS_RR_TYPE_A ||
|
||||
rrset->type == LDNS_RR_TYPE_AAAA ||
|
||||
rrset->type == LDNS_RR_TYPE_SVCB ||
|
||||
rrset->type == LDNS_RR_TYPE_HTTPS) {
|
||||
|
||||
/* do not set servfail since this leads to too
|
||||
* many drops of other people using rfc1918 space */
|
||||
@@ -1060,7 +1152,8 @@ scrub_message(sldns_buffer* pkt, struct msg_parse* msg,
|
||||
/* this is not required for basic operation but is a forgery
|
||||
* resistance (security) feature */
|
||||
if((FLAGS_GET_RCODE(msg->flags) == LDNS_RCODE_NOERROR ||
|
||||
FLAGS_GET_RCODE(msg->flags) == LDNS_RCODE_NXDOMAIN) &&
|
||||
FLAGS_GET_RCODE(msg->flags) == LDNS_RCODE_NXDOMAIN ||
|
||||
FLAGS_GET_RCODE(msg->flags) == LDNS_RCODE_YXDOMAIN) &&
|
||||
msg->qdcount == 0)
|
||||
return 0;
|
||||
|
||||
@@ -1074,7 +1167,7 @@ scrub_message(sldns_buffer* pkt, struct msg_parse* msg,
|
||||
}
|
||||
|
||||
/* normalize the response, this cleans up the additional. */
|
||||
if(!scrub_normalize(pkt, msg, qinfo, region, env))
|
||||
if(!scrub_normalize(pkt, msg, qinfo, region, env, zonename))
|
||||
return 0;
|
||||
/* delete all out-of-zone information */
|
||||
if(!scrub_sanitize(pkt, msg, qinfo, zonename, env, ie, qstate))
|
||||
|
||||
+46
-4
@@ -253,7 +253,9 @@ iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** filter out unsuitable targets
|
||||
/** filter out unsuitable targets.
|
||||
* Applies NAT64 if needed as well by replacing the IPv4 with the synthesized
|
||||
* IPv6 address.
|
||||
* @param iter_env: iterator environment with ipv6-support flag.
|
||||
* @param env: module environment with infra cache.
|
||||
* @param name: zone name
|
||||
@@ -306,9 +308,30 @@ iter_filter_unsuitable(struct iter_env* iter_env, struct module_env* env,
|
||||
if(a->bogus)
|
||||
return -1; /* address of server is bogus */
|
||||
if(donotq_lookup(iter_env->donotq, &a->addr, a->addrlen)) {
|
||||
log_addr(VERB_ALGO, "skip addr on the donotquery list",
|
||||
&a->addr, a->addrlen);
|
||||
return -1; /* server is on the donotquery list */
|
||||
if(iter_env->nat64.use_nat64 &&
|
||||
addr_is_ip6(&a->addr, a->addrlen) &&
|
||||
a->addrlen == iter_env->nat64.nat64_prefix_addrlen &&
|
||||
addr_in_common(&a->addr, 128,
|
||||
&iter_env->nat64.nat64_prefix_addr,
|
||||
iter_env->nat64.nat64_prefix_net,
|
||||
iter_env->nat64.nat64_prefix_addrlen) ==
|
||||
iter_env->nat64.nat64_prefix_net) {
|
||||
/* The NAT64 is enabled, and address is IPv6, it is
|
||||
* in the NAT64 prefix. It is allowed.
|
||||
* So that in an IPv6-only cluster without internet
|
||||
* access, that makes the NAT64 translation continue
|
||||
* to work. The NAT64 prefix is allowed. */
|
||||
/* Otherwise, after a timeout, the already NAT64
|
||||
* translated address would be treated differently,
|
||||
* and that causes confusion. */
|
||||
log_addr(VERB_ALGO, "the addr is on the donotquery "
|
||||
"list, but allowed because it is NAT64",
|
||||
&a->addr, a->addrlen);
|
||||
} else {
|
||||
log_addr(VERB_ALGO, "skip addr on the donotquery list",
|
||||
&a->addr, a->addrlen);
|
||||
return -1; /* server is on the donotquery list */
|
||||
}
|
||||
}
|
||||
if(!iter_env->supports_ipv6 && addr_is_ip6(&a->addr, a->addrlen)) {
|
||||
return -1; /* there is no ip6 available */
|
||||
@@ -317,6 +340,20 @@ iter_filter_unsuitable(struct iter_env* iter_env, struct module_env* env,
|
||||
!addr_is_ip6(&a->addr, a->addrlen)) {
|
||||
return -1; /* there is no ip4 available */
|
||||
}
|
||||
if(iter_env->nat64.use_nat64 && !addr_is_ip6(&a->addr, a->addrlen)) {
|
||||
struct sockaddr_storage real_addr;
|
||||
socklen_t real_addrlen;
|
||||
addr_to_nat64(&a->addr, &iter_env->nat64.nat64_prefix_addr,
|
||||
iter_env->nat64.nat64_prefix_addrlen,
|
||||
iter_env->nat64.nat64_prefix_net,
|
||||
&real_addr, &real_addrlen);
|
||||
log_name_addr(VERB_QUERY, "NAT64 apply: from: ",
|
||||
name, &a->addr, a->addrlen);
|
||||
log_name_addr(VERB_QUERY, "NAT64 apply: to: ",
|
||||
name, &real_addr, real_addrlen);
|
||||
a->addr = real_addr;
|
||||
a->addrlen = real_addrlen;
|
||||
}
|
||||
/* check lameness - need zone , class info */
|
||||
if(infra_get_lame_rtt(env->infra_cache, &a->addr, a->addrlen,
|
||||
name, namelen, qtype, &lame, &dnsseclame, &reclame,
|
||||
@@ -1511,6 +1548,11 @@ iter_stub_fwd_no_cache(struct module_qstate *qstate, struct query_info *qinf,
|
||||
struct delegpt *dp;
|
||||
int nolock = 1;
|
||||
|
||||
log_assert((retdpname && retdpnamelen
|
||||
&& dpname_storage && dpname_storage_len > 0) ||
|
||||
(retdpname == NULL && retdpnamelen == NULL
|
||||
&& dpname_storage == NULL && dpname_storage_len == 0));
|
||||
|
||||
/* Check for stub. */
|
||||
/* Lock both forwards and hints for atomic read. */
|
||||
lock_rw_rdlock(&qstate->env->fwds->lock);
|
||||
|
||||
@@ -84,6 +84,7 @@ int iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg);
|
||||
/**
|
||||
* Select a valid, nice target to send query to.
|
||||
* Sorting and removing unsuitable targets is combined.
|
||||
* Adds records to the infra cache if not already there.
|
||||
*
|
||||
* @param iter_env: iterator module global state, with ip6 enabled and
|
||||
* do-not-query-addresses.
|
||||
|
||||
+18
-19
@@ -297,6 +297,7 @@ error_response_cache(struct module_qstate* qstate, int id, int rcode)
|
||||
struct reply_info err;
|
||||
struct msgreply_entry* msg;
|
||||
if(qstate->no_cache_store) {
|
||||
qstate->error_response_cache = 1;
|
||||
return error_response(qstate, id, rcode);
|
||||
}
|
||||
if(qstate->prefetch_leeway > NORR_TTL) {
|
||||
@@ -2436,8 +2437,6 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
int tf_policy;
|
||||
struct delegpt_addr* target;
|
||||
struct outbound_entry* outq;
|
||||
struct sockaddr_storage real_addr;
|
||||
socklen_t real_addrlen;
|
||||
int auth_fallback = 0;
|
||||
uint8_t* qout_orig = NULL;
|
||||
size_t qout_orig_len = 0;
|
||||
@@ -3060,17 +3059,6 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
iq->dnssec_lame_query?" but lame_query anyway": "");
|
||||
}
|
||||
|
||||
real_addr = target->addr;
|
||||
real_addrlen = target->addrlen;
|
||||
|
||||
if(ie->nat64.use_nat64 && target->addr.ss_family == AF_INET) {
|
||||
addr_to_nat64(&target->addr, &ie->nat64.nat64_prefix_addr,
|
||||
ie->nat64.nat64_prefix_addrlen, ie->nat64.nat64_prefix_net,
|
||||
&real_addr, &real_addrlen);
|
||||
log_name_addr(VERB_QUERY, "applied NAT64:",
|
||||
iq->dp->name, &real_addr, real_addrlen);
|
||||
}
|
||||
|
||||
fptr_ok(fptr_whitelist_modenv_send_query(qstate->env->send_query));
|
||||
outq = (*qstate->env->send_query)(&iq->qinfo_out,
|
||||
iq->chase_flags | (iq->chase_to_rd?BIT_RD:0),
|
||||
@@ -3082,7 +3070,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
!qstate->blacklist&&(!iter_qname_indicates_dnssec(qstate->env,
|
||||
&iq->qinfo_out)||target->attempts==1)?0:BIT_CD),
|
||||
iq->dnssec_expected, iq->caps_fallback || is_caps_whitelisted(
|
||||
ie, iq), sq_check_ratelimit, &real_addr, real_addrlen,
|
||||
ie, iq), sq_check_ratelimit, &target->addr, target->addrlen,
|
||||
iq->dp->name, iq->dp->namelen,
|
||||
(iq->dp->tcp_upstream || qstate->env->cfg->tcp_upstream),
|
||||
(iq->dp->ssl_upstream || qstate->env->cfg->ssl_upstream),
|
||||
@@ -3099,7 +3087,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
log_addr(VERB_QUERY, "error sending query to auth server",
|
||||
&real_addr, real_addrlen);
|
||||
&target->addr, target->addrlen);
|
||||
if(qstate->env->cfg->qname_minimisation)
|
||||
iq->minimisation_state = SKIP_MINIMISE_STATE;
|
||||
return next_state(iq, QUERYTARGETS_STATE);
|
||||
@@ -3236,8 +3224,19 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
} else iter_scrub_ds(iq->response, NULL, NULL);
|
||||
if(type == RESPONSE_TYPE_THROWAWAY &&
|
||||
FLAGS_GET_RCODE(iq->response->rep->flags) == LDNS_RCODE_YXDOMAIN) {
|
||||
/* YXDOMAIN is a permanent error, no need to retry */
|
||||
type = RESPONSE_TYPE_ANSWER;
|
||||
/* YXDOMAIN is a permanent error for DNAME expansion overflow
|
||||
* (RFC 6672 Section 2.2). Only accept if the response
|
||||
* contains a DNAME record in the answer section; otherwise
|
||||
* treat as invalid, to make sure the authoritative answer
|
||||
* make sense. */
|
||||
size_t i;
|
||||
for(i=0; i<iq->response->rep->an_numrrsets; i++) {
|
||||
if(ntohs(iq->response->rep->rrsets[i]->rk.type)
|
||||
== LDNS_RR_TYPE_DNAME) {
|
||||
type = RESPONSE_TYPE_ANSWER;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(type == RESPONSE_TYPE_CNAME)
|
||||
origtypecname = 1;
|
||||
@@ -3616,7 +3615,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
return next_state(iq, INIT_REQUEST_STATE);
|
||||
} else if(type == RESPONSE_TYPE_LAME) {
|
||||
/* Cache the LAMEness. */
|
||||
verbose(VERB_DETAIL, "query response was %sLAME",
|
||||
verbose(VERB_DETAIL, "query response was categorized as %sLAME",
|
||||
dnsseclame?"DNSSEC ":"");
|
||||
if(!dname_subdomain_c(iq->qchase.qname, iq->dp->name)) {
|
||||
log_err("mark lame: mismatch in qname and dpname");
|
||||
@@ -3655,7 +3654,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
* In this case, the event is just sent directly back to
|
||||
* the QUERYTARGETS_STATE without resetting anything,
|
||||
* because, clearly, the next target must be tried. */
|
||||
verbose(VERB_DETAIL, "query response was THROWAWAY");
|
||||
verbose(VERB_DETAIL, "query response was categorized as THROWAWAY");
|
||||
} else {
|
||||
log_warn("A query response came back with an unknown type: %d",
|
||||
(int)type);
|
||||
|
||||
@@ -52,7 +52,6 @@
|
||||
#include "util/data/msgreply.h"
|
||||
#include "util/storage/slabhash.h"
|
||||
#include "util/edns.h"
|
||||
#include "util/tsig.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
#include "iterator/iter_fwd.h"
|
||||
#include "iterator/iter_hints.h"
|
||||
@@ -82,15 +81,13 @@ context_finalize(struct ub_ctx* ctx)
|
||||
return UB_INITFAIL;
|
||||
listen_setup_locks();
|
||||
log_edns_known_options(VERB_ALGO, ctx->env);
|
||||
if(!tsig_key_table_apply_cfg(ctx->env->tsig_key_table, cfg))
|
||||
return UB_INITFAIL;
|
||||
ctx->local_zones = local_zones_create();
|
||||
if(!ctx->local_zones)
|
||||
return UB_NOMEM;
|
||||
if(!local_zones_apply_cfg(ctx->local_zones, cfg))
|
||||
return UB_INITFAIL;
|
||||
if(!auth_zones_apply_cfg(ctx->env->auth_zones, cfg, 1, &is_rpz,
|
||||
ctx->env, &ctx->mods, ctx->env->tsig_key_table))
|
||||
ctx->env, &ctx->mods))
|
||||
return UB_INITFAIL;
|
||||
if(!(ctx->env->fwds = forwards_create()) ||
|
||||
!forwards_apply_cfg(ctx->env->fwds, cfg))
|
||||
|
||||
@@ -59,7 +59,6 @@
|
||||
#include "util/tube.h"
|
||||
#include "util/ub_event.h"
|
||||
#include "util/edns.h"
|
||||
#include "util/tsig.h"
|
||||
#include "services/modstack.h"
|
||||
#include "services/localzone.h"
|
||||
#include "services/cache/infra.h"
|
||||
@@ -169,18 +168,6 @@ static struct ub_ctx* ub_ctx_create_nopipe(void)
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
ctx->env->tsig_key_table = tsig_key_table_create();
|
||||
if(!ctx->env->tsig_key_table) {
|
||||
auth_zones_delete(ctx->env->auth_zones);
|
||||
edns_known_options_delete(ctx->env);
|
||||
edns_strings_delete(ctx->env->edns_strings);
|
||||
config_delete(ctx->env->cfg);
|
||||
free(ctx->env);
|
||||
ub_randfree(ctx->seed_rnd);
|
||||
free(ctx);
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ctx->env->alloc = &ctx->superalloc;
|
||||
ctx->env->worker = NULL;
|
||||
@@ -401,7 +388,6 @@ ub_ctx_delete(struct ub_ctx* ctx)
|
||||
config_delete(ctx->env->cfg);
|
||||
edns_known_options_delete(ctx->env);
|
||||
edns_strings_delete(ctx->env->edns_strings);
|
||||
tsig_key_table_delete(ctx->env->tsig_key_table);
|
||||
forwards_delete(ctx->env->fwds);
|
||||
hints_delete(ctx->env->hints);
|
||||
auth_zones_delete(ctx->env->auth_zones);
|
||||
|
||||
@@ -229,9 +229,7 @@ libworker_setup(struct ub_ctx* ctx, int is_bg, struct ub_event_base* eb)
|
||||
cfg->do_udp || cfg->udp_upstream_without_downstream, w->sslctx,
|
||||
cfg->delay_close, cfg->tls_use_sni, NULL, cfg->udp_connect,
|
||||
cfg->max_reuse_tcp_queries, cfg->tcp_reuse_timeout,
|
||||
cfg->tcp_auth_query_timeout, (const char**)cfg->dist,
|
||||
(const char**)cfg->dist_tsig,
|
||||
cfg->num_dist);
|
||||
cfg->tcp_auth_query_timeout);
|
||||
w->env->outnet = w->back;
|
||||
if(!w->is_bg || w->is_bg_thread) {
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
|
||||
@@ -853,6 +853,8 @@ struct ub_server_stats {
|
||||
long long qquic;
|
||||
/** number of queries removed due to discard-timeout */
|
||||
long long num_queries_discard_timeout;
|
||||
/** number of queries removed due to replyaddr limit */
|
||||
long long num_queries_replyaddr_limit;
|
||||
/** number of queries removed due to wait-limit */
|
||||
long long num_queries_wait_limit;
|
||||
/** number of dns error reports generated */
|
||||
@@ -872,6 +874,8 @@ struct ub_stats_info {
|
||||
long long mesh_num_states;
|
||||
/** mesh stats: current number of reply (user) states */
|
||||
long long mesh_num_reply_states;
|
||||
/** mesh stats: current number of reply entries */
|
||||
long long mesh_num_reply_addrs;
|
||||
/** mesh stats: number of reply states overwritten with a new one */
|
||||
long long mesh_jostled;
|
||||
/** mesh stats: number of incoming queries dropped */
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -973,6 +973,9 @@ respip_rewrite_reply(const struct query_info* qinfo,
|
||||
lock_rw_unlock(&raddr->lock);
|
||||
lock_rw_unlock(&a->lock);
|
||||
lock_rw_unlock(&az->rpz_lock);
|
||||
if(view) {
|
||||
lock_rw_unlock(&view->lock);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if(rpz_used) {
|
||||
|
||||
+114
-307
@@ -55,7 +55,6 @@
|
||||
#include "util/log.h"
|
||||
#include "util/module.h"
|
||||
#include "util/random.h"
|
||||
#include "util/tsig.h"
|
||||
#include "services/cache/dns.h"
|
||||
#include "services/outside_network.h"
|
||||
#include "services/listen_dnsport.h"
|
||||
@@ -1370,6 +1369,10 @@ decompress_rr_into_buffer(struct sldns_buffer* buf, uint8_t* pkt,
|
||||
uncompressed_len = pkt_dname_len(&pktbuf);
|
||||
if(!uncompressed_len)
|
||||
return 0; /* parse error in dname */
|
||||
compressed_len = sldns_buffer_position(
|
||||
&pktbuf) - oldpos;
|
||||
if(compressed_len > rdlen)
|
||||
return 0; /* dname exceeds rdata */
|
||||
if(!sldns_buffer_available(buf,
|
||||
uncompressed_len))
|
||||
/* dname too long for buffer */
|
||||
@@ -1377,14 +1380,15 @@ decompress_rr_into_buffer(struct sldns_buffer* buf, uint8_t* pkt,
|
||||
dname_pkt_copy(&pktbuf,
|
||||
sldns_buffer_current(buf), rd);
|
||||
sldns_buffer_skip(buf, (ssize_t)uncompressed_len);
|
||||
compressed_len = sldns_buffer_position(
|
||||
&pktbuf) - oldpos;
|
||||
rd += compressed_len;
|
||||
rdlen -= compressed_len;
|
||||
count--;
|
||||
len = 0;
|
||||
break;
|
||||
case LDNS_RDF_TYPE_STR:
|
||||
/* Check rdlen for resilience, because it is
|
||||
* checked above, that rdlen > 0 */
|
||||
if(rdlen < 1) return 0; /* malformed */
|
||||
len = rd[0] + 1;
|
||||
break;
|
||||
default:
|
||||
@@ -1392,6 +1396,8 @@ decompress_rr_into_buffer(struct sldns_buffer* buf, uint8_t* pkt,
|
||||
break;
|
||||
}
|
||||
if(len) {
|
||||
if(len > rdlen)
|
||||
return 0; /* malformed */
|
||||
if(!sldns_buffer_available(buf, len))
|
||||
return 0; /* too long for buffer */
|
||||
sldns_buffer_write(buf, rd, len);
|
||||
@@ -1999,12 +2005,21 @@ auth_zone_get_serial(struct auth_zone* z, uint32_t* serial)
|
||||
struct auth_data* apex;
|
||||
struct auth_rrset* soa;
|
||||
struct packed_rrset_data* d;
|
||||
size_t primlen, mboxlen;
|
||||
apex = az_find_name(z, z->name, z->namelen);
|
||||
if(!apex) return 0;
|
||||
soa = az_domain_rrset(apex, LDNS_RR_TYPE_SOA);
|
||||
if(!soa || soa->data->count==0)
|
||||
return 0; /* no RRset or no RRs in rrset */
|
||||
if(soa->data->rr_len[0] < 2+4*5) return 0; /* SOA too short */
|
||||
if((primlen = dname_valid(soa->data->rr_data[0]+2,
|
||||
soa->data->rr_len[0]-2)) == 0)
|
||||
return 0; /* primary dname malformed */
|
||||
if((mboxlen = dname_valid(soa->data->rr_data[0]+2+primlen,
|
||||
soa->data->rr_len[0]-2-primlen)) == 0)
|
||||
return 0; /* mailbox dname malformed */
|
||||
if(2+primlen+mboxlen+4*5 != soa->data->rr_len[0])
|
||||
return 0; /* rdata malformed */
|
||||
d = soa->data;
|
||||
*serial = sldns_read_uint32(d->rr_data[0]+(d->rr_len[0]-20));
|
||||
return 1;
|
||||
@@ -2017,12 +2032,21 @@ xfr_find_soa(struct auth_zone* z, struct auth_xfer* xfr)
|
||||
struct auth_data* apex;
|
||||
struct auth_rrset* soa;
|
||||
struct packed_rrset_data* d;
|
||||
size_t primlen, mboxlen;
|
||||
apex = az_find_name(z, z->name, z->namelen);
|
||||
if(!apex) return 0;
|
||||
soa = az_domain_rrset(apex, LDNS_RR_TYPE_SOA);
|
||||
if(!soa || soa->data->count==0)
|
||||
return 0; /* no RRset or no RRs in rrset */
|
||||
if(soa->data->rr_len[0] < 2+4*5) return 0; /* SOA too short */
|
||||
if((primlen = dname_valid(soa->data->rr_data[0]+2,
|
||||
soa->data->rr_len[0]-2)) == 0)
|
||||
return 0; /* primary dname malformed */
|
||||
if((mboxlen = dname_valid(soa->data->rr_data[0]+2+primlen,
|
||||
soa->data->rr_len[0]-2-primlen)) == 0)
|
||||
return 0; /* mailbox dname malformed */
|
||||
if(2+primlen+mboxlen+4*5 != soa->data->rr_len[0])
|
||||
return 0; /* rdata malformed */
|
||||
/* SOA record ends with serial, refresh, retry, expiry, minimum,
|
||||
* as 4 byte fields */
|
||||
d = soa->data;
|
||||
@@ -2092,8 +2116,7 @@ auth_zones_setup_zones(struct auth_zones* az)
|
||||
|
||||
/** set config items and create zones */
|
||||
static int
|
||||
auth_zones_cfg(struct auth_zones* az, struct config_auth* c,
|
||||
struct tsig_key_table* tsig_key_table)
|
||||
auth_zones_cfg(struct auth_zones* az, struct config_auth* c)
|
||||
{
|
||||
struct auth_zone* z;
|
||||
struct auth_xfer* x = NULL;
|
||||
@@ -2112,7 +2135,7 @@ auth_zones_cfg(struct auth_zones* az, struct config_auth* c,
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if(c->masters || c->masters_tsig || c->urls) {
|
||||
if(c->masters || c->urls) {
|
||||
if(!(x=auth_zones_find_or_add_xfer(az, z))) {
|
||||
lock_rw_unlock(&az->lock);
|
||||
lock_rw_unlock(&z->lock);
|
||||
@@ -2173,14 +2196,12 @@ auth_zones_cfg(struct auth_zones* az, struct config_auth* c,
|
||||
if(x) {
|
||||
z->zone_is_slave = 1;
|
||||
/* set options on xfer zone */
|
||||
if(!xfer_set_masters(&x->task_probe->masters, c, 0,
|
||||
tsig_key_table)) {
|
||||
if(!xfer_set_masters(&x->task_probe->masters, c, 0)) {
|
||||
lock_basic_unlock(&x->lock);
|
||||
lock_rw_unlock(&z->lock);
|
||||
return 0;
|
||||
}
|
||||
if(!xfer_set_masters(&x->task_transfer->masters, c, 1,
|
||||
tsig_key_table)) {
|
||||
if(!xfer_set_masters(&x->task_transfer->masters, c, 1)) {
|
||||
lock_basic_unlock(&x->lock);
|
||||
lock_rw_unlock(&z->lock);
|
||||
return 0;
|
||||
@@ -2248,7 +2269,7 @@ az_delete_deleted_zones(struct auth_zones* az)
|
||||
|
||||
int auth_zones_apply_cfg(struct auth_zones* az, struct config_file* cfg,
|
||||
int setup, int* is_rpz, struct module_env* env,
|
||||
struct module_stack* mods, struct tsig_key_table* tsig_key_table)
|
||||
struct module_stack* mods)
|
||||
{
|
||||
struct config_auth* p;
|
||||
az_setall_deleted(az);
|
||||
@@ -2258,7 +2279,7 @@ int auth_zones_apply_cfg(struct auth_zones* az, struct config_file* cfg,
|
||||
continue;
|
||||
}
|
||||
*is_rpz = (*is_rpz || p->isrpz);
|
||||
if(!auth_zones_cfg(az, p, tsig_key_table)) {
|
||||
if(!auth_zones_cfg(az, p)) {
|
||||
log_err("cannot config auth zone %s", p->name);
|
||||
return 0;
|
||||
}
|
||||
@@ -2316,7 +2337,6 @@ auth_free_masters(struct auth_master* list)
|
||||
auth_free_master_addrs(list->list);
|
||||
free(list->host);
|
||||
free(list->file);
|
||||
free(list->tsig_key_name);
|
||||
free(list);
|
||||
list = n;
|
||||
}
|
||||
@@ -2336,14 +2356,12 @@ auth_xfer_delete(struct auth_xfer* xfr)
|
||||
auth_free_masters(xfr->task_probe->masters);
|
||||
comm_point_delete(xfr->task_probe->cp);
|
||||
comm_timer_delete(xfr->task_probe->timer);
|
||||
tsig_delete(xfr->task_probe->tsig);
|
||||
free(xfr->task_probe);
|
||||
}
|
||||
if(xfr->task_transfer) {
|
||||
auth_free_masters(xfr->task_transfer->masters);
|
||||
comm_point_delete(xfr->task_transfer->cp);
|
||||
comm_timer_delete(xfr->task_transfer->timer);
|
||||
tsig_delete(xfr->task_transfer->tsig);
|
||||
if(xfr->task_transfer->chunks_first) {
|
||||
auth_chunks_delete(xfr->task_transfer);
|
||||
}
|
||||
@@ -3725,30 +3743,11 @@ addr_in_list(struct auth_addr* list, struct sockaddr_storage* addr,
|
||||
* addresses in the addr list) */
|
||||
static int
|
||||
addr_matches_master(struct auth_master* master, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, struct auth_master** fromhost,
|
||||
struct tsig_data* tsig)
|
||||
socklen_t addrlen, struct auth_master** fromhost)
|
||||
{
|
||||
struct sockaddr_storage a;
|
||||
socklen_t alen = 0;
|
||||
int net = 0;
|
||||
if(master->tsig_key_name && master->tsig_key_name[0]) {
|
||||
uint8_t keyname[LDNS_MAX_DOMAINLEN+1];
|
||||
size_t keynamelen = sizeof(keyname);
|
||||
if(!tsig) {
|
||||
/* This needs a TSIG key, but no TSIG present. */
|
||||
return 0;
|
||||
}
|
||||
if(sldns_str2wire_dname_buf(master->tsig_key_name, keyname,
|
||||
&keynamelen) != 0) {
|
||||
verbose(VERB_ALGO, "could not parse allow-notify-tsig '%s'",
|
||||
master->tsig_key_name);
|
||||
return 0;
|
||||
}
|
||||
if(query_dname_compare(keyname, tsig->key_name) != 0) {
|
||||
/* The TSIG is a different key name, not matched. */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if(addr_in_list(master->list, addr, addrlen)) {
|
||||
*fromhost = master;
|
||||
return 1;
|
||||
@@ -3781,12 +3780,11 @@ addr_matches_master(struct auth_master* master, struct sockaddr_storage* addr,
|
||||
/** check access list for notifies */
|
||||
static int
|
||||
az_xfr_allowed_notify(struct auth_xfer* xfr, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, struct auth_master** fromhost,
|
||||
struct tsig_data* tsig)
|
||||
socklen_t addrlen, struct auth_master** fromhost)
|
||||
{
|
||||
struct auth_master* p;
|
||||
for(p=xfr->allow_notify_list; p; p=p->next) {
|
||||
if(addr_matches_master(p, addr, addrlen, fromhost, tsig)) {
|
||||
if(addr_matches_master(p, addr, addrlen, fromhost)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -3856,8 +3854,7 @@ xfr_process_notify(struct auth_xfer* xfr, struct module_env* env,
|
||||
int auth_zones_notify(struct auth_zones* az, struct module_env* env,
|
||||
uint8_t* nm, size_t nmlen, uint16_t dclass,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, int has_serial,
|
||||
uint32_t serial, int* refused, struct sldns_buffer* pkt,
|
||||
struct tsig_data** tsig, int* tsig_rcode, struct regional* scratchpad)
|
||||
uint32_t serial, int* refused)
|
||||
{
|
||||
struct auth_xfer* xfr;
|
||||
struct auth_master* fromhost = NULL;
|
||||
@@ -3872,20 +3869,9 @@ int auth_zones_notify(struct auth_zones* az, struct module_env* env,
|
||||
}
|
||||
lock_basic_lock(&xfr->lock);
|
||||
lock_rw_unlock(&az->lock);
|
||||
|
||||
/* check tsig */
|
||||
if(tsig_in_packet(pkt)) {
|
||||
*tsig_rcode = tsig_parse_verify_query(env->tsig_key_table,
|
||||
pkt, tsig, scratchpad, (uint64_t)*env->now);
|
||||
if(*tsig_rcode != 0) {
|
||||
/* The tsig failed to verify. */
|
||||
lock_basic_unlock(&xfr->lock);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* check access list for notifies */
|
||||
if(!az_xfr_allowed_notify(xfr, addr, addrlen, &fromhost, *tsig)) {
|
||||
if(!az_xfr_allowed_notify(xfr, addr, addrlen, &fromhost)) {
|
||||
lock_basic_unlock(&xfr->lock);
|
||||
/* notify not allowed, refuse the notify */
|
||||
*refused = 1;
|
||||
@@ -4017,20 +4003,9 @@ auth_master_copy(struct auth_master* o)
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if(m->tsig_key_name) {
|
||||
m->tsig_key_name = strdup(m->tsig_key_name);
|
||||
if(!m->tsig_key_name) {
|
||||
free(m->file);
|
||||
free(m->host);
|
||||
free(m);
|
||||
log_err("malloc failure");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if(m->list) {
|
||||
m->list = auth_addr_list_copy(m->list);
|
||||
if(!m->list) {
|
||||
free(m->tsig_key_name);
|
||||
free(m->file);
|
||||
free(m->host);
|
||||
free(m);
|
||||
@@ -4040,6 +4015,22 @@ auth_master_copy(struct auth_master* o)
|
||||
return m;
|
||||
}
|
||||
|
||||
/** append the master to the copied list. */
|
||||
static int
|
||||
auth_master_copy_and_append(struct auth_master* p, struct auth_master** list,
|
||||
struct auth_master** last)
|
||||
{
|
||||
struct auth_master* m = auth_master_copy(p);
|
||||
if(!m) {
|
||||
return 0;
|
||||
}
|
||||
m->next = NULL;
|
||||
if(*last) (*last)->next = m;
|
||||
if(!*list) *list = m;
|
||||
*last = m;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** copy the master addresses from the task_probe lookups to the allow_notify
|
||||
* list of masters */
|
||||
static void
|
||||
@@ -4048,17 +4039,27 @@ probe_copy_masters_for_allow_notify(struct auth_xfer* xfr)
|
||||
struct auth_master* list = NULL, *last = NULL;
|
||||
struct auth_master* p;
|
||||
/* build up new list with copies */
|
||||
for(p = xfr->task_transfer->masters; p; p=p->next) {
|
||||
struct auth_master* m = auth_master_copy(p);
|
||||
if(!m) {
|
||||
/* The list in task probe has been looked up before the list in
|
||||
* task transfer. */
|
||||
for(p = xfr->task_probe->masters; p; p=p->next) {
|
||||
if(!auth_master_copy_and_append(p, &list, &last)) {
|
||||
auth_free_masters(list);
|
||||
/* failed because of malloc failure, use old list */
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* The list in task transfer also contains the http entries. */
|
||||
for(p = xfr->task_transfer->masters; p; p=p->next) {
|
||||
/* Copy the http entries from this lookup. The allow_notify
|
||||
* entries are not looked up from this list. The other
|
||||
* ones are already in from the probe lookups. */
|
||||
if(!p->http)
|
||||
continue;
|
||||
if(!auth_master_copy_and_append(p, &list, &last)) {
|
||||
auth_free_masters(list);
|
||||
/* failed because of malloc failure, use old list */
|
||||
return;
|
||||
}
|
||||
m->next = NULL;
|
||||
if(last) last->next = m;
|
||||
if(!list) list = m;
|
||||
last = m;
|
||||
}
|
||||
/* success, replace list */
|
||||
auth_free_masters(xfr->allow_notify_list);
|
||||
@@ -4290,37 +4291,6 @@ xfr_create_soa_probe_packet(struct auth_xfer* xfr, sldns_buffer* buf,
|
||||
sldns_buffer_write_u16_at(buf, 0, id);
|
||||
}
|
||||
|
||||
/** sign a query for xfr. */
|
||||
static int
|
||||
xfr_sign_query(struct tsig_data** tsig, sldns_buffer* pkt,
|
||||
struct module_env* env, char* tsig_key_name)
|
||||
{
|
||||
size_t pos;
|
||||
if(*tsig) {
|
||||
tsig_delete(*tsig);
|
||||
*tsig = NULL;
|
||||
}
|
||||
*tsig = tsig_create_fromstr(env->tsig_key_table, tsig_key_name);
|
||||
if(!*tsig) {
|
||||
log_err("tsig key '%s' not found or out of memory",
|
||||
tsig_key_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Position the buffer after the packet contents. */
|
||||
pos = sldns_buffer_limit(pkt);
|
||||
sldns_buffer_clear(pkt);
|
||||
sldns_buffer_set_position(pkt, pos);
|
||||
if(!tsig_sign_query(*tsig, pkt, env->tsig_key_table,
|
||||
(uint64_t)*env->now)) {
|
||||
sldns_buffer_flip(pkt);
|
||||
log_err("tsig key '%s': could not sign query", tsig_key_name);
|
||||
return 0;
|
||||
}
|
||||
sldns_buffer_flip(pkt);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** create IXFR/AXFR packet for xfr */
|
||||
static void
|
||||
xfr_create_ixfr_packet(struct auth_xfer* xfr, sldns_buffer* buf, uint16_t id,
|
||||
@@ -4379,7 +4349,7 @@ xfr_create_ixfr_packet(struct auth_xfer* xfr, sldns_buffer* buf, uint16_t id,
|
||||
/** check if returned packet is OK */
|
||||
static int
|
||||
check_packet_ok(sldns_buffer* pkt, uint16_t qtype, struct auth_xfer* xfr,
|
||||
uint32_t* serial, struct module_env* env)
|
||||
uint32_t* serial)
|
||||
{
|
||||
/* parse to see if packet worked, valid reply */
|
||||
|
||||
@@ -4453,20 +4423,6 @@ check_packet_ok(sldns_buffer* pkt, uint16_t qtype, struct auth_xfer* xfr,
|
||||
return 0;
|
||||
*serial = sldns_buffer_read_u32(pkt);
|
||||
}
|
||||
|
||||
if(xfr->task_probe->tsig) {
|
||||
/* There could be authority or additional RRs in the reply for the
|
||||
* SOA query, if so skip them by tsig_find_rr. */
|
||||
if(!tsig_find_rr(pkt)) {
|
||||
verbose(VERB_ALGO, "TSIG expected, but not found in reply");
|
||||
return 0;
|
||||
}
|
||||
if(!tsig_parse_verify_reply(xfr->task_probe->tsig, pkt,
|
||||
env->tsig_key_table, (uint64_t)*env->now)) {
|
||||
verbose(VERB_ALGO, "valid TSIG expected in SOA probe reply, but it was not valid");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -5474,18 +5430,10 @@ xfr_process_chunk_list(struct auth_xfer* xfr, struct module_env* env,
|
||||
lock_rw_unlock(&z->lock);
|
||||
|
||||
if(verbosity >= VERB_QUERY && xfr->have_zone) {
|
||||
char zname[LDNS_MAX_DOMAINLEN], tsigtxt[16],
|
||||
tsigkey[LDNS_MAX_DOMAINLEN];
|
||||
tsigkey[0]=0;
|
||||
tsigtxt[0]=0;
|
||||
if(xfr->task_transfer->tsig &&
|
||||
xfr->task_transfer->tsig->key_name) {
|
||||
snprintf(tsigtxt, sizeof(tsigtxt), " with TSIG ");
|
||||
dname_str(xfr->task_transfer->tsig->key_name, tsigkey);
|
||||
}
|
||||
char zname[LDNS_MAX_DOMAINLEN];
|
||||
dname_str(xfr->name, zname);
|
||||
verbose(VERB_QUERY, "auth zone %s updated%s%s to serial %u",
|
||||
zname, tsigtxt, tsigkey, (unsigned)xfr->serial);
|
||||
verbose(VERB_QUERY, "auth zone %s updated to serial %u", zname,
|
||||
(unsigned)xfr->serial);
|
||||
}
|
||||
/* see if we need to write to a zonefile */
|
||||
xfr_write_after_update(xfr, env);
|
||||
@@ -5502,9 +5450,6 @@ xfr_transfer_disown(struct auth_xfer* xfr)
|
||||
/* remove the commpoint */
|
||||
comm_point_delete(xfr->task_transfer->cp);
|
||||
xfr->task_transfer->cp = NULL;
|
||||
/* remove the tsig data */
|
||||
tsig_delete(xfr->task_transfer->tsig);
|
||||
xfr->task_transfer->tsig = NULL;
|
||||
/* we don't own this item anymore */
|
||||
xfr->task_transfer->worker = NULL;
|
||||
xfr->task_transfer->env = NULL;
|
||||
@@ -5593,10 +5538,6 @@ xfr_transfer_init_fetch(struct auth_xfer* xfr, struct module_env* env)
|
||||
int timeout;
|
||||
if(!master) return 0;
|
||||
if(master->allow_notify) return 0; /* only for notify */
|
||||
if(xfr->task_transfer->tsig) {
|
||||
tsig_delete(xfr->task_transfer->tsig);
|
||||
xfr->task_transfer->tsig = NULL;
|
||||
}
|
||||
|
||||
/* get master addr */
|
||||
if(xfr->task_transfer->scan_addr) {
|
||||
@@ -5671,17 +5612,6 @@ xfr_transfer_init_fetch(struct auth_xfer* xfr, struct module_env* env)
|
||||
xfr->task_transfer->id = GET_RANDOM_ID(env->rnd);
|
||||
xfr_create_ixfr_packet(xfr, env->scratch_buffer,
|
||||
xfr->task_transfer->id, master);
|
||||
if(master->tsig_key_name) {
|
||||
if(!xfr_sign_query(&xfr->task_transfer->tsig,
|
||||
env->scratch_buffer, env, master->tsig_key_name)) {
|
||||
char zname[LDNS_MAX_DOMAINLEN], as[256];
|
||||
dname_str(xfr->name, zname);
|
||||
addr_port_to_str(&addr, addrlen, as, sizeof(as));
|
||||
verbose(VERB_ALGO, "failed to TSIG sign xfr "
|
||||
"for %s to %s", zname, as);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* connect on fd */
|
||||
xfr->task_transfer->cp = outnet_comm_point_for_tcp(env->outnet,
|
||||
@@ -5698,20 +5628,11 @@ xfr_transfer_init_fetch(struct auth_xfer* xfr, struct module_env* env)
|
||||
}
|
||||
comm_timer_set(xfr->task_transfer->timer, &t);
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
char zname[LDNS_MAX_DOMAINLEN], as[256], tsigtxt[16],
|
||||
tsigkey[LDNS_MAX_DOMAINLEN];
|
||||
tsigkey[0]=0;
|
||||
tsigtxt[0]=0;
|
||||
if(xfr->task_transfer->tsig &&
|
||||
xfr->task_transfer->tsig->key_name) {
|
||||
snprintf(tsigtxt, sizeof(tsigtxt), " with TSIG ");
|
||||
dname_str(xfr->task_transfer->tsig->key_name, tsigkey);
|
||||
}
|
||||
char zname[LDNS_MAX_DOMAINLEN], as[256];
|
||||
dname_str(xfr->name, zname);
|
||||
addr_port_to_str(&addr, addrlen, as, sizeof(as));
|
||||
verbose(VERB_ALGO, "auth zone %s transfer next %s fetch%s%s from %s started",
|
||||
zname, (xfr->task_transfer->on_ixfr?"IXFR":"AXFR"),
|
||||
tsigtxt, tsigkey, as);
|
||||
verbose(VERB_ALGO, "auth zone %s transfer next %s fetch from %s started", zname,
|
||||
(xfr->task_transfer->on_ixfr?"IXFR":"AXFR"), as);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -5896,10 +5817,9 @@ void auth_xfer_transfer_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
|
||||
*/
|
||||
static int
|
||||
check_xfer_packet(sldns_buffer* pkt, struct auth_xfer* xfr,
|
||||
struct module_env* env, int* gonextonfail, int* transferdone)
|
||||
int* gonextonfail, int* transferdone)
|
||||
{
|
||||
uint8_t* wire = sldns_buffer_begin(pkt);
|
||||
size_t initial_rr_scan_num = xfr->task_transfer->rr_scan_num;
|
||||
int i;
|
||||
if(sldns_buffer_limit(pkt) < LDNS_HEADER_SIZE) {
|
||||
verbose(VERB_ALGO, "xfr to %s failed, packet too small",
|
||||
@@ -6183,28 +6103,6 @@ check_xfer_packet(sldns_buffer* pkt, struct auth_xfer* xfr,
|
||||
sldns_buffer_skip(pkt, (ssize_t)rdlen);
|
||||
}
|
||||
|
||||
/* check tsig */
|
||||
if(xfr->task_transfer->tsig) {
|
||||
sldns_buffer_rewind(pkt);
|
||||
if(!tsig_find_rr(pkt)) {
|
||||
/* Check TSIG reply on first packet. */
|
||||
if(initial_rr_scan_num == 0) {
|
||||
verbose(VERB_ALGO, "TSIG expected, but not found in reply for xfr to %s",
|
||||
xfr->task_transfer->master->host);
|
||||
return 0;
|
||||
}
|
||||
/* No TSIG could be for sign every NTH packet. */
|
||||
sldns_buffer_set_position(pkt, sldns_buffer_limit(pkt));
|
||||
}
|
||||
if(!tsig_parse_verify_reply_xfr(xfr->task_transfer->tsig,
|
||||
pkt, env->tsig_key_table, (uint64_t)*env->now,
|
||||
*transferdone)) {
|
||||
verbose(VERB_ALGO, "valid TSIG expected in xfr reply to %s, but it was not valid",
|
||||
xfr->task_transfer->master->host);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -6381,8 +6279,7 @@ auth_xfer_transfer_tcp_callback(struct comm_point* c, void* arg, int err,
|
||||
/* handle returned packet */
|
||||
/* if it fails, cleanup and end this transfer */
|
||||
/* if it needs to fallback from IXFR to AXFR, do that */
|
||||
if(!check_xfer_packet(c->buffer, xfr, env, &gonextonfail,
|
||||
&transferdone)) {
|
||||
if(!check_xfer_packet(c->buffer, xfr, &gonextonfail, &transferdone)) {
|
||||
goto failed;
|
||||
}
|
||||
/* if it is good, link it into the list of data */
|
||||
@@ -6508,9 +6405,6 @@ xfr_probe_disown(struct auth_xfer* xfr)
|
||||
/* remove the commpoint */
|
||||
comm_point_delete(xfr->task_probe->cp);
|
||||
xfr->task_probe->cp = NULL;
|
||||
/* remove the tsig data */
|
||||
tsig_delete(xfr->task_probe->tsig);
|
||||
xfr->task_probe->tsig = NULL;
|
||||
/* we don't own this item anymore */
|
||||
xfr->task_probe->worker = NULL;
|
||||
xfr->task_probe->env = NULL;
|
||||
@@ -6531,10 +6425,6 @@ xfr_probe_send_probe(struct auth_xfer* xfr, struct module_env* env,
|
||||
if(master->allow_notify) return 0; /* only for notify */
|
||||
if(master->http) return 0; /* only masters get SOA UDP probe,
|
||||
not urls, if those are in this list */
|
||||
if(xfr->task_probe->tsig) {
|
||||
tsig_delete(xfr->task_probe->tsig);
|
||||
xfr->task_probe->tsig = NULL;
|
||||
}
|
||||
|
||||
/* get master addr */
|
||||
if(xfr->task_probe->scan_addr) {
|
||||
@@ -6572,17 +6462,6 @@ xfr_probe_send_probe(struct auth_xfer* xfr, struct module_env* env,
|
||||
xfr->task_probe->id = GET_RANDOM_ID(env->rnd);
|
||||
xfr_create_soa_probe_packet(xfr, env->scratch_buffer,
|
||||
xfr->task_probe->id);
|
||||
if(master->tsig_key_name) {
|
||||
if(!xfr_sign_query(&xfr->task_probe->tsig, env->scratch_buffer,
|
||||
env, master->tsig_key_name)) {
|
||||
char zname[LDNS_MAX_DOMAINLEN], as[256];
|
||||
dname_str(xfr->name, zname);
|
||||
addr_port_to_str(&addr, addrlen, as, sizeof(as));
|
||||
verbose(VERB_ALGO, "failed to TSIG sign soa probe "
|
||||
"for %s to %s", zname, as);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/* we need to remove the cp if we have a different ip4/ip6 type now */
|
||||
if(xfr->task_probe->cp &&
|
||||
((xfr->task_probe->cp_is_ip6 && !addr_is_ip6(&addr, addrlen)) ||
|
||||
@@ -6626,19 +6505,11 @@ xfr_probe_send_probe(struct auth_xfer* xfr, struct module_env* env,
|
||||
return 0;
|
||||
}
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
char zname[LDNS_MAX_DOMAINLEN], as[256], tsigtxt[16],
|
||||
tsigkey[LDNS_MAX_DOMAINLEN];
|
||||
tsigkey[0]=0;
|
||||
tsigtxt[0]=0;
|
||||
if(xfr->task_probe->tsig &&
|
||||
xfr->task_probe->tsig->key_name) {
|
||||
snprintf(tsigtxt, sizeof(tsigtxt), " with TSIG ");
|
||||
dname_str(xfr->task_probe->tsig->key_name, tsigkey);
|
||||
}
|
||||
char zname[LDNS_MAX_DOMAINLEN], as[256];
|
||||
dname_str(xfr->name, zname);
|
||||
addr_port_to_str(&addr, addrlen, as, sizeof(as));
|
||||
verbose(VERB_ALGO, "auth zone %s soa probe%s%s sent to %s",
|
||||
zname, tsigtxt, tsigkey, as);
|
||||
verbose(VERB_ALGO, "auth zone %s soa probe sent to %s", zname,
|
||||
as);
|
||||
}
|
||||
xfr->task_probe->timeout = timeout;
|
||||
#ifndef S_SPLINT_S
|
||||
@@ -6710,24 +6581,13 @@ auth_xfer_probe_udp_callback(struct comm_point* c, void* arg, int err,
|
||||
if(err == NETEVENT_NOERROR) {
|
||||
uint32_t serial = 0;
|
||||
if(check_packet_ok(c->buffer, LDNS_RR_TYPE_SOA, xfr,
|
||||
&serial, env)) {
|
||||
&serial)) {
|
||||
/* successful lookup */
|
||||
if(verbosity >= VERB_ALGO) {
|
||||
char buf[LDNS_MAX_DOMAINLEN], tsigtxt[16],
|
||||
tsigkey[LDNS_MAX_DOMAINLEN];
|
||||
tsigkey[0]=0;
|
||||
tsigtxt[0]=0;
|
||||
if(xfr->task_probe->tsig &&
|
||||
xfr->task_probe->tsig->key_name) {
|
||||
snprintf(tsigtxt, sizeof(tsigtxt),
|
||||
" with TSIG ");
|
||||
dname_str(xfr->task_probe->tsig->
|
||||
key_name, tsigkey);
|
||||
}
|
||||
char buf[LDNS_MAX_DOMAINLEN];
|
||||
dname_str(xfr->name, buf);
|
||||
verbose(VERB_ALGO, "auth zone %s: soa probe"
|
||||
"%s%s serial is %u", buf, tsigtxt,
|
||||
tsigkey, (unsigned)serial);
|
||||
verbose(VERB_ALGO, "auth zone %s: soa probe "
|
||||
"serial is %u", buf, (unsigned)serial);
|
||||
}
|
||||
/* see if this serial indicates that the zone has
|
||||
* to be updated */
|
||||
@@ -6780,9 +6640,6 @@ auth_xfer_probe_udp_callback(struct comm_point* c, void* arg, int err,
|
||||
/* delete commpoint so a new one is created, with a fresh port nr */
|
||||
comm_point_delete(xfr->task_probe->cp);
|
||||
xfr->task_probe->cp = NULL;
|
||||
/* remove the tsig data */
|
||||
tsig_delete(xfr->task_probe->tsig);
|
||||
xfr->task_probe->tsig = NULL;
|
||||
|
||||
/* if the result was not a successful probe, we need
|
||||
* to send the next one */
|
||||
@@ -6863,6 +6720,18 @@ xfr_probe_lookup_host(struct auth_xfer* xfr, struct module_env* env)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** return true if there are probe (SOA UDP query) targets in the master list*/
|
||||
static int
|
||||
have_probe_targets(struct auth_master* list)
|
||||
{
|
||||
struct auth_master* p;
|
||||
for(p=list; p; p = p->next) {
|
||||
if(!p->allow_notify && p->host)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** move to sending the probe packets, next if fails. task_probe */
|
||||
static void
|
||||
xfr_probe_send_or_end(struct auth_xfer* xfr, struct module_env* env)
|
||||
@@ -6902,6 +6771,16 @@ xfr_probe_send_or_end(struct auth_xfer* xfr, struct module_env* env)
|
||||
verbose(VERB_ALGO, "auth zone %s probe: finished only_lookup", zname);
|
||||
}
|
||||
xfr_probe_disown(xfr);
|
||||
if(!have_probe_targets(xfr->task_probe->masters)) {
|
||||
/* If there are no masters to probe, go to transfer. */
|
||||
if(xfr->task_transfer->worker == NULL) {
|
||||
xfr_start_transfer(xfr, env, NULL);
|
||||
return;
|
||||
}
|
||||
/* The transfer is already in progress. */
|
||||
lock_basic_unlock(&xfr->lock);
|
||||
return;
|
||||
}
|
||||
if(xfr->task_nextprobe->worker == NULL)
|
||||
xfr_set_timeout(xfr, env, 0, 0);
|
||||
lock_basic_unlock(&xfr->lock);
|
||||
@@ -7058,18 +6937,6 @@ auth_xfer_timer(void* arg)
|
||||
}
|
||||
}
|
||||
|
||||
/** return true if there are probe (SOA UDP query) targets in the master list*/
|
||||
static int
|
||||
have_probe_targets(struct auth_master* list)
|
||||
{
|
||||
struct auth_master* p;
|
||||
for(p=list; p; p = p->next) {
|
||||
if(!p->allow_notify && p->host)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** start task_probe if possible, if no masters for probe start task_transfer
|
||||
* returns true if task has been started, and false if the task is already
|
||||
* in progress. */
|
||||
@@ -7081,7 +6948,9 @@ xfr_start_probe(struct auth_xfer* xfr, struct module_env* env,
|
||||
* progress (due to notify)) */
|
||||
if(xfr->task_probe->worker == NULL) {
|
||||
if(!have_probe_targets(xfr->task_probe->masters) &&
|
||||
!(xfr->task_probe->only_lookup &&
|
||||
xfr->task_probe->masters != NULL)
|
||||
xfr->task_probe->only_lookup = 1;
|
||||
if(!(xfr->task_probe->only_lookup &&
|
||||
xfr->task_probe->masters != NULL)) {
|
||||
/* useless to pick up task_probe, no masters to
|
||||
* probe. Instead attempt to pick up task transfer */
|
||||
@@ -7488,34 +7357,12 @@ parse_url(char* url, char** host, char** file, int* port, int* ssl)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** Check the tsig key exists */
|
||||
static int
|
||||
check_tsig_key_exists(struct tsig_key_table* tsig_key_table,
|
||||
const char* optname, char* str, char* str2)
|
||||
{
|
||||
struct tsig_key* key;
|
||||
if(!tsig_key_table)
|
||||
return 1;
|
||||
|
||||
lock_rw_rdlock(&tsig_key_table->lock);
|
||||
key = tsig_key_table_search_fromstr(tsig_key_table, str2);
|
||||
lock_rw_unlock(&tsig_key_table->lock);
|
||||
|
||||
if(!key) {
|
||||
log_err("could not find tsig-key for %s: %s %s",
|
||||
optname, str, str2);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
xfer_set_masters(struct auth_master** list, struct config_auth* c,
|
||||
int with_http, struct tsig_key_table* tsig_key_table)
|
||||
int with_http)
|
||||
{
|
||||
struct auth_master* m;
|
||||
struct config_strlist* p;
|
||||
struct config_str2list* p2;
|
||||
/* list points to the first, or next pointer for the new element */
|
||||
while(*list) {
|
||||
list = &( (*list)->next );
|
||||
@@ -7538,24 +7385,6 @@ xfer_set_masters(struct auth_master** list, struct config_auth* c,
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
for(p2 = c->masters_tsig; p2; p2 = p2->next) {
|
||||
m = auth_master_new(&list);
|
||||
if(!m) return 0;
|
||||
m->ixfr = 1; /* this flag is not configurable */
|
||||
m->host = strdup(p2->str);
|
||||
if(!m->host) {
|
||||
log_err("malloc failure");
|
||||
return 0;
|
||||
}
|
||||
if(!check_tsig_key_exists(tsig_key_table, "primary-tsig",
|
||||
p2->str, p2->str2))
|
||||
return 0;
|
||||
m->tsig_key_name = strdup(p2->str2);
|
||||
if(!m->tsig_key_name) {
|
||||
log_err("malloc failure");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
for(p = c->allow_notify; p; p = p->next) {
|
||||
m = auth_master_new(&list);
|
||||
if(!m) return 0;
|
||||
@@ -7566,24 +7395,6 @@ xfer_set_masters(struct auth_master** list, struct config_auth* c,
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
for(p2 = c->allow_notify_tsig; p2; p2 = p2->next) {
|
||||
m = auth_master_new(&list);
|
||||
if(!m) return 0;
|
||||
m->allow_notify = 1;
|
||||
m->host = strdup(p2->str);
|
||||
if(!m->host) {
|
||||
log_err("malloc failure");
|
||||
return 0;
|
||||
}
|
||||
if(!check_tsig_key_exists(tsig_key_table, "allow-notify-tsig",
|
||||
p2->str, p2->str2))
|
||||
return 0;
|
||||
m->tsig_key_name = strdup(p2->str2);
|
||||
if(!m->tsig_key_name) {
|
||||
log_err("malloc failure");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -8919,8 +8730,6 @@ auth_primaries_get_mem(struct auth_master* list)
|
||||
m += strlen(n->host)+1;
|
||||
if(n->file)
|
||||
m += strlen(n->file)+1;
|
||||
if(n->tsig_key_name)
|
||||
m += strlen(n->tsig_key_name)+1;
|
||||
}
|
||||
return m;
|
||||
}
|
||||
@@ -8950,14 +8759,12 @@ auth_xfer_get_mem(struct auth_xfer* xfr)
|
||||
m += auth_primaries_get_mem(xfr->task_probe->masters);
|
||||
m += comm_point_get_mem(xfr->task_probe->cp);
|
||||
m += comm_timer_get_mem(xfr->task_probe->timer);
|
||||
m += tsig_get_mem(xfr->task_probe->tsig);
|
||||
|
||||
/* auth_transfer */
|
||||
m += auth_chunks_get_mem(xfr->task_transfer->chunks_first);
|
||||
m += auth_primaries_get_mem(xfr->task_transfer->masters);
|
||||
m += comm_point_get_mem(xfr->task_transfer->cp);
|
||||
m += comm_timer_get_mem(xfr->task_transfer->timer);
|
||||
m += tsig_get_mem(xfr->task_transfer->tsig);
|
||||
|
||||
/* allow_notify_list */
|
||||
m += auth_primaries_get_mem(xfr->allow_notify_list);
|
||||
|
||||
+3
-21
@@ -55,8 +55,6 @@ struct query_info;
|
||||
struct dns_msg;
|
||||
struct edns_data;
|
||||
struct module_env;
|
||||
struct tsig_data;
|
||||
struct tsig_key_table;
|
||||
struct worker;
|
||||
struct comm_point;
|
||||
struct comm_timer;
|
||||
@@ -363,8 +361,6 @@ struct auth_probe {
|
||||
struct comm_timer* timer;
|
||||
/** timeout in msec */
|
||||
int timeout;
|
||||
/** the tsig data for the packet */
|
||||
struct tsig_data* tsig;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -434,8 +430,6 @@ struct auth_transfer {
|
||||
/** timeout for the transfer.
|
||||
* on the workers event base. */
|
||||
struct comm_timer* timer;
|
||||
/** the tsig data for the transfer */
|
||||
struct tsig_data* tsig;
|
||||
};
|
||||
|
||||
/** list of addresses */
|
||||
@@ -467,8 +461,6 @@ struct auth_master {
|
||||
int ssl;
|
||||
/** the port number (for urls) */
|
||||
int port;
|
||||
/** the tsig key name (if any, or NULL) */
|
||||
char* tsig_key_name;
|
||||
/** if the host is a hostname, the list of resolved addrs, if any*/
|
||||
struct auth_addr* list;
|
||||
};
|
||||
@@ -498,13 +490,11 @@ struct auth_zones* auth_zones_create(void);
|
||||
* @param is_rpz: set to 1 if at least one RPZ zone is configured.
|
||||
* @param env: environment for offline verification.
|
||||
* @param mods: modules in environment.
|
||||
* @param tsig_key_table: tsig key table to check if tsig keys exist.
|
||||
* If NULL, no check is performed.
|
||||
* @return false on failure.
|
||||
*/
|
||||
int auth_zones_apply_cfg(struct auth_zones* az, struct config_file* cfg,
|
||||
int setup, int* is_rpz, struct module_env* env,
|
||||
struct module_stack* mods, struct tsig_key_table* tsig_key_table);
|
||||
struct module_stack* mods);
|
||||
|
||||
/** initial pick up of worker timeouts, ties events to worker event loop
|
||||
* @param az: auth zones structure
|
||||
@@ -629,19 +619,13 @@ int auth_zones_can_fallback(struct auth_zones* az, uint8_t* nm, size_t nmlen,
|
||||
* @param has_serial: if true, the notify has a serial attached.
|
||||
* @param serial: the serial number, if has_serial is true.
|
||||
* @param refused: is set to true on failure to note refused access.
|
||||
* @param pkt: the packet for TSIG verify.
|
||||
* @param tsig: if TSIG, the structure is returned here, allocated in
|
||||
* the worker scratch region.
|
||||
* @param tsig_rcode: if not NOERROR it is the TSIG error code, TSIG failed.
|
||||
* @param scratchpad: region to allocate tsig in.
|
||||
* @return fail on failures (refused is false) and when access is
|
||||
* denied (refused is true). True when processed.
|
||||
*/
|
||||
int auth_zones_notify(struct auth_zones* az, struct module_env* env,
|
||||
uint8_t* nm, size_t nmlen, uint16_t dclass,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, int has_serial,
|
||||
uint32_t serial, int* refused, struct sldns_buffer* pkt,
|
||||
struct tsig_data** tsig, int* tsig_rcode, struct regional* scratchpad);
|
||||
uint32_t serial, int* refused);
|
||||
|
||||
/** process notify packet and read serial number from SOA.
|
||||
* returns 0 if no soa record in the notify */
|
||||
@@ -687,12 +671,10 @@ struct auth_xfer* auth_xfer_create(struct auth_zones* az, struct auth_zone* z);
|
||||
* @param list: pointer to start of list. The malloced list is returned here.
|
||||
* @param c: the config items to copy over.
|
||||
* @param with_http: if true, http urls are also included, before the masters.
|
||||
* @param tsig_key_table: if nonNULL, used to check that tsig keys exist in
|
||||
* the key table.
|
||||
* @return false on failure.
|
||||
*/
|
||||
int xfer_set_masters(struct auth_master** list, struct config_auth* c,
|
||||
int with_http, struct tsig_key_table* tsig_key_table);
|
||||
int with_http);
|
||||
|
||||
/** xfer nextprobe timeout callback, this is part of task_nextprobe */
|
||||
void auth_xfer_timer(void* arg);
|
||||
|
||||
Vendored
+27
-7
@@ -232,8 +232,15 @@ find_closest_of_type(struct module_env* env, uint8_t* qname, size_t qnamelen,
|
||||
|
||||
/* snip off front part of qname until the type is found */
|
||||
while(qnamelen > 0) {
|
||||
if((rrset = rrset_cache_lookup(env->rrset_cache, qname,
|
||||
qnamelen, searchtype, qclass, 0, now, 0))) {
|
||||
rrset = rrset_cache_lookup(env->rrset_cache, qname,
|
||||
qnamelen, searchtype, qclass, 0, now, 0);
|
||||
if(!rrset && searchtype == LDNS_RR_TYPE_DNAME)
|
||||
/* If not found, for type DNAME, try 0TTL stored,
|
||||
* for its grace period. */
|
||||
rrset = rrset_cache_lookup(env->rrset_cache, qname,
|
||||
qnamelen, searchtype, qclass,
|
||||
PACKED_RRSET_UPSTREAM_0TTL, now, 0);
|
||||
if(rrset) {
|
||||
uint8_t* origqname = qname;
|
||||
size_t origqnamelen = qnamelen;
|
||||
if(!noexpiredabove)
|
||||
@@ -705,10 +712,16 @@ struct dns_msg*
|
||||
dns_msg_deepcopy_region(struct dns_msg* origin, struct regional* region)
|
||||
{
|
||||
size_t i;
|
||||
struct ub_packed_rrset_key** saved_rrsets;
|
||||
struct dns_msg* res = NULL;
|
||||
size_t rep_alloc_size = sizeof(struct reply_info)
|
||||
- sizeof(struct rrset_ref); /* this is the size of res->rep
|
||||
allocated in gen_dns_msg() */
|
||||
res = gen_dns_msg(region, &origin->qinfo, origin->rep->rrset_count);
|
||||
if(!res) return NULL;
|
||||
*res->rep = *origin->rep;
|
||||
saved_rrsets = res->rep->rrsets; /* save rrsets alloc by gen_dns_msg */
|
||||
memcpy(res->rep, origin->rep, rep_alloc_size);
|
||||
res->rep->rrsets = saved_rrsets;
|
||||
if(origin->rep->reason_bogus_str) {
|
||||
res->rep->reason_bogus_str = regional_strdup(region,
|
||||
origin->rep->reason_bogus_str);
|
||||
@@ -766,8 +779,15 @@ synth_dname_msg(struct ub_packed_rrset_key* rrset, struct regional* region,
|
||||
rrset->entry.data;
|
||||
uint8_t* newname, *dtarg = NULL;
|
||||
size_t newlen, dtarglen;
|
||||
if(TTL_IS_EXPIRED(d->ttl, now))
|
||||
return NULL;
|
||||
time_t rr_ttl;
|
||||
if(TTL_IS_EXPIRED(d->ttl, now)) {
|
||||
/* Allow TTL=0 DNAME from upstream within grace period */
|
||||
if(!(rrset->rk.flags & PACKED_RRSET_UPSTREAM_0TTL))
|
||||
return NULL;
|
||||
rr_ttl = 0;
|
||||
} else {
|
||||
rr_ttl = d->ttl - now;
|
||||
}
|
||||
/* only allow validated (with DNSSEC) DNAMEs used from cache
|
||||
* for insecure DNAMEs, query again. */
|
||||
*sec_status = d->security;
|
||||
@@ -779,7 +799,7 @@ synth_dname_msg(struct ub_packed_rrset_key* rrset, struct regional* region,
|
||||
msg->rep->flags = BIT_QR; /* reply, no AA, no error */
|
||||
msg->rep->authoritative = 0; /* reply stored in cache can't be authoritative */
|
||||
msg->rep->qdcount = 1;
|
||||
msg->rep->ttl = d->ttl - now;
|
||||
msg->rep->ttl = rr_ttl;
|
||||
msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl);
|
||||
msg->rep->serve_expired_ttl = msg->rep->ttl + SERVE_EXPIRED_TTL;
|
||||
msg->rep->serve_expired_norec_ttl = 0;
|
||||
@@ -831,7 +851,7 @@ synth_dname_msg(struct ub_packed_rrset_key* rrset, struct regional* region,
|
||||
if(!newd)
|
||||
return NULL;
|
||||
ck->entry.data = newd;
|
||||
newd->ttl = d->ttl - now; /* RFC6672: synth CNAME TTL == DNAME TTL */
|
||||
newd->ttl = rr_ttl; /* RFC6672: synth CNAME TTL == DNAME TTL */
|
||||
newd->count = 1;
|
||||
newd->rrsig_count = 0;
|
||||
newd->trust = rrset_trust_ans_noAA;
|
||||
|
||||
Vendored
+25
-3
@@ -149,6 +149,16 @@ need_to_update_rrset(void* nd, void* cd, time_t timenow, int equal, int ns)
|
||||
if(equal && !TTL_IS_EXPIRED(cached->ttl, timenow) &&
|
||||
cached->security == sec_status_bogus)
|
||||
return 0;
|
||||
/* ghost-domain: never let an NS overwrite extend lifetime
|
||||
* past the entry it replaces, regardless of trust. */
|
||||
if(ns && !TTL_IS_EXPIRED(cached->ttl, timenow) &&
|
||||
newd->ttl > cached->ttl) {
|
||||
size_t i;
|
||||
newd->ttl = cached->ttl;
|
||||
for(i=0; i<(newd->count+newd->rrsig_count); i++)
|
||||
if(newd->rr_ttl[i] > newd->ttl)
|
||||
newd->rr_ttl[i] = newd->ttl;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/* o item in cache has expired */
|
||||
@@ -278,6 +288,10 @@ void rrset_cache_update_wildcard(struct rrset_cache* rrset_cache,
|
||||
(void)rrset_cache_update(rrset_cache, &ref, alloc, timenow);
|
||||
}
|
||||
|
||||
/** Grace period in seconds for TTL=0 DNAME rrsets (RFC 2308: do not cache).
|
||||
* Allows synthesis from cache within this window to reduce recursion load. */
|
||||
#define DNAME_TTL0_GRACE_SECONDS 1
|
||||
|
||||
struct ub_packed_rrset_key*
|
||||
rrset_cache_lookup(struct rrset_cache* r, uint8_t* qname, size_t qnamelen,
|
||||
uint16_t qtype, uint16_t qclass, uint32_t flags, time_t timenow,
|
||||
@@ -300,12 +314,20 @@ rrset_cache_lookup(struct rrset_cache* r, uint8_t* qname, size_t qnamelen,
|
||||
/* check TTL */
|
||||
struct packed_rrset_data* data =
|
||||
(struct packed_rrset_data*)e->data;
|
||||
struct ub_packed_rrset_key* k = (struct ub_packed_rrset_key*)e->key;
|
||||
if(TTL_IS_EXPIRED(data->ttl, timenow)) {
|
||||
lock_rw_unlock(&e->lock);
|
||||
return NULL;
|
||||
/* Allow TTL=0 DNAME within grace period for synthesis */
|
||||
if(qtype == LDNS_RR_TYPE_DNAME &&
|
||||
(k->rk.flags & PACKED_RRSET_UPSTREAM_0TTL) &&
|
||||
(timenow - data->ttl_add) <= DNAME_TTL0_GRACE_SECONDS) {
|
||||
/* within grace: allow for synthesis */
|
||||
} else {
|
||||
lock_rw_unlock(&e->lock);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
/* we're done */
|
||||
return (struct ub_packed_rrset_key*)e->key;
|
||||
return k;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+17
-23
@@ -1564,7 +1564,7 @@ listen_create(struct comm_base* base, struct listen_port* ports,
|
||||
cp = comm_point_create_udp(base, ports->fd,
|
||||
front->udp_buff, ports->pp2_enabled, cb,
|
||||
cb_arg, ports->socket);
|
||||
} else if(ports->ftype == listen_type_doq) {
|
||||
} else if(ports->ftype == listen_type_doq && doq_table) {
|
||||
#ifndef HAVE_NGTCP2
|
||||
log_warn("Unbound is not compiled with "
|
||||
"ngtcp2. This is required to use DNS "
|
||||
@@ -2300,21 +2300,8 @@ int
|
||||
tcp_req_info_handle_read_close(struct tcp_req_info* req)
|
||||
{
|
||||
verbose(VERB_ALGO, "tcp channel read side closed %d", req->cp->fd);
|
||||
/* reset byte count for (potential) partial read */
|
||||
req->cp->tcp_byte_count = 0;
|
||||
/* if we still have results to write, pick up next and write it */
|
||||
if(req->num_done_req != 0) {
|
||||
tcp_req_pickup_next_result(req);
|
||||
tcp_req_info_setup_listen(req);
|
||||
return 1;
|
||||
}
|
||||
/* if nothing to do, this closes the connection */
|
||||
if(req->num_open_req == 0 && req->num_done_req == 0)
|
||||
return 0;
|
||||
/* otherwise, we must be waiting for dns resolve, wait with timeout */
|
||||
req->read_is_closed = 1;
|
||||
tcp_req_info_setup_listen(req);
|
||||
return 1;
|
||||
/* RFC 7766 6.2.4 says to drop pending replies when client closes. */
|
||||
return 0; /* drop connection */
|
||||
}
|
||||
|
||||
void
|
||||
@@ -2884,6 +2871,7 @@ submit_http_error:
|
||||
sldns_buffer_flip(h2_stream->qbuffer);
|
||||
h2_session->postpone_drop = 1;
|
||||
query_read_done = http2_query_read_done(h2_session, h2_stream);
|
||||
h2_session->postpone_drop = 0;
|
||||
if(query_read_done < 0)
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
else if(!query_read_done) {
|
||||
@@ -2893,11 +2881,9 @@ submit_http_error:
|
||||
* failure will result in reclaiming (and closing)
|
||||
* of comm point. */
|
||||
verbose(VERB_QUERY, "http2 query dropped in worker cb");
|
||||
h2_session->postpone_drop = 0;
|
||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
/* nothing to submit right now, query added to mesh. */
|
||||
h2_session->postpone_drop = 0;
|
||||
return 0;
|
||||
}
|
||||
if(!http2_submit_dns_response(h2_session)) {
|
||||
@@ -3275,14 +3261,18 @@ nghttp2_session_callbacks* http2_req_callbacks_create(void)
|
||||
struct doq_table*
|
||||
doq_table_create(struct config_file* cfg, struct ub_randstate* rnd)
|
||||
{
|
||||
struct doq_table* table = calloc(1, sizeof(*table));
|
||||
struct doq_table* table;
|
||||
|
||||
if (!cfg->quic_port)
|
||||
return NULL;
|
||||
table = calloc(1, sizeof(*table));
|
||||
if(!table)
|
||||
return NULL;
|
||||
#ifdef USE_NGTCP2_CRYPTO_OSSL
|
||||
/* Initialize the ossl crypto, it is harmless to call twice,
|
||||
* and this is before use of doq connections. */
|
||||
if(ngtcp2_crypto_ossl_init() != 0) {
|
||||
log_err("ngtcp2_crypto_oss_init failed");
|
||||
log_err("ngtcp2_crypto_ossl_init failed");
|
||||
free(table);
|
||||
return NULL;
|
||||
}
|
||||
@@ -3354,7 +3344,7 @@ conn_tree_del(rbnode_type* node, void* arg)
|
||||
{
|
||||
struct doq_table* table = (struct doq_table*)arg;
|
||||
struct doq_conn* conn;
|
||||
if(!node)
|
||||
if(!node || !table)
|
||||
return;
|
||||
conn = (struct doq_conn*)node->key;
|
||||
if(conn->timer.timer_in_list) {
|
||||
@@ -3413,6 +3403,7 @@ doq_timer_find_time(struct doq_table* table, struct timeval* tv)
|
||||
{
|
||||
struct doq_timer key;
|
||||
struct rbnode_type* node;
|
||||
log_assert(table != NULL);
|
||||
memset(&key, 0, sizeof(key));
|
||||
key.time.tv_sec = tv->tv_sec;
|
||||
key.time.tv_usec = tv->tv_usec;
|
||||
@@ -3776,7 +3767,7 @@ doq_repinfo_retrieve_localaddr(struct comm_reply* repinfo,
|
||||
memset(sa6, 0, *localaddrlen);
|
||||
sa6->sin6_family = AF_INET6;
|
||||
memmove(&sa6->sin6_addr, &repinfo->pktinfo.v6info.ipi6_addr,
|
||||
*localaddrlen);
|
||||
sizeof(struct in6_addr));
|
||||
sa6->sin6_port = repinfo->doq_srcport;
|
||||
#endif
|
||||
} else {
|
||||
@@ -3786,7 +3777,7 @@ doq_repinfo_retrieve_localaddr(struct comm_reply* repinfo,
|
||||
memset(sa, 0, *localaddrlen);
|
||||
sa->sin_family = AF_INET;
|
||||
memmove(&sa->sin_addr, &repinfo->pktinfo.v4info.ipi_addr,
|
||||
*localaddrlen);
|
||||
sizeof(struct in_addr));
|
||||
sa->sin_port = repinfo->doq_srcport;
|
||||
#elif defined(IP_RECVDSTADDR)
|
||||
struct sockaddr_in* sa = (struct sockaddr_in*)localaddr;
|
||||
@@ -4922,6 +4913,7 @@ doq_conid_find(struct doq_table* table, const uint8_t* data, size_t datalen)
|
||||
key.node.key = &key;
|
||||
key.cid = (void*)data;
|
||||
key.cidlen = datalen;
|
||||
log_assert(table != NULL);
|
||||
node = rbtree_search(table->conid_tree, &key);
|
||||
if(node)
|
||||
return (struct doq_conid*)node->key;
|
||||
@@ -5662,6 +5654,8 @@ doq_table_quic_size_available(struct doq_table* table,
|
||||
struct config_file* cfg, size_t mem)
|
||||
{
|
||||
size_t cur;
|
||||
if (!table)
|
||||
return 0;
|
||||
lock_basic_lock(&table->size_lock);
|
||||
cur = table->current_size;
|
||||
lock_basic_unlock(&table->size_lock);
|
||||
|
||||
+106
-75
@@ -56,6 +56,24 @@
|
||||
* with 16 bytes for an A record, a 64K packet has about 4000 max */
|
||||
#define LOCALZONE_RRSET_COUNT_MAX 4096
|
||||
|
||||
static const char* default_zones_reverse_array[] = {
|
||||
"127.in-addr.arpa.", /* reverse ip4 zone */
|
||||
"1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.", /* reverse ip6 zone */
|
||||
0
|
||||
};
|
||||
const char** local_zones_default_reverse = default_zones_reverse_array;
|
||||
|
||||
static const char* default_zones_special_array[] = {
|
||||
"test.", /* RFC 6761 */
|
||||
"invalid.", /* RFC 6761 */
|
||||
"onion.", /* RFC 7686 */
|
||||
"home.arpa.", /* RFC 8375 */
|
||||
"resolver.arpa.", /* RFC 9462 */
|
||||
"service.arpa.", /* RFC 9665 */
|
||||
0
|
||||
};
|
||||
const char** local_zones_default_special = default_zones_special_array;
|
||||
|
||||
/** print all RRsets in local zone */
|
||||
static void
|
||||
local_zone_out(struct local_zone* z)
|
||||
@@ -650,7 +668,7 @@ lz_enter_rr_str(struct local_zones* zones, const char* rr)
|
||||
}
|
||||
labs = dname_count_size_labels(rr_name, &len);
|
||||
lock_rw_rdlock(&zones->lock);
|
||||
z = local_zones_lookup(zones, rr_name, len, labs, rr_class, rr_type);
|
||||
z = local_zones_lookup(zones, rr_name, len, labs, rr_class, rr_type, 1);
|
||||
if(!z) {
|
||||
lock_rw_unlock(&zones->lock);
|
||||
fatal_exit("internal error: no zone for rr %s", rr);
|
||||
@@ -834,7 +852,7 @@ lz_nodefault(struct config_file* cfg, const char* name)
|
||||
|
||||
for(p = cfg->local_zones_nodefault; p; p = p->next) {
|
||||
/* compare zone name, lowercase, compare without ending . */
|
||||
if(strncasecmp(p->str, name, len) == 0 &&
|
||||
if(strncasecmp(p->str, name, len) == 0 &&
|
||||
(strlen(p->str) == len || (strlen(p->str)==len+1 &&
|
||||
p->str[len] == '.')))
|
||||
return 1;
|
||||
@@ -842,6 +860,45 @@ lz_nodefault(struct config_file* cfg, const char* name)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** enter reverse default zone */
|
||||
static int
|
||||
add_reverse_default(struct local_zones* zones, struct config_file* cfg,
|
||||
const char* name)
|
||||
{
|
||||
struct local_zone* z;
|
||||
char str[1024]; /* known long enough */
|
||||
if(lz_exists(zones, name) || lz_nodefault(cfg, name))
|
||||
return 1; /* do not enter default content */
|
||||
if(!(z=lz_enter_zone(zones, name, "static", LDNS_RR_CLASS_IN)))
|
||||
return 0;
|
||||
snprintf(str, sizeof(str), "%s 10800 IN SOA localhost. "
|
||||
"nobody.invalid. 1 3600 1200 604800 10800", name);
|
||||
if(!lz_enter_rr_into_zone(z, str)) {
|
||||
lock_rw_unlock(&z->lock);
|
||||
return 0;
|
||||
}
|
||||
snprintf(str, sizeof(str), "%s 10800 IN NS localhost. ", name);
|
||||
if(!lz_enter_rr_into_zone(z, str)) {
|
||||
lock_rw_unlock(&z->lock);
|
||||
return 0;
|
||||
}
|
||||
if(strncasecmp("127.in-addr.arpa.", name, 17) == 0) {
|
||||
if(!lz_enter_rr_into_zone(z,
|
||||
"1.0.0.127.in-addr.arpa. 10800 IN PTR localhost.")) {
|
||||
lock_rw_unlock(&z->lock);
|
||||
return 0;
|
||||
}
|
||||
} else if(strncasecmp("1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.", name, 73) == 0) {
|
||||
snprintf(str, sizeof(str), "%s 10800 IN PTR localhost.", name);
|
||||
if(!lz_enter_rr_into_zone(z, str)) {
|
||||
lock_rw_unlock(&z->lock);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
lock_rw_unlock(&z->lock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** enter (AS112) empty default zone */
|
||||
static int
|
||||
add_empty_default(struct local_zones* zones, struct config_file* cfg,
|
||||
@@ -902,72 +959,23 @@ int local_zone_enter_defaults(struct local_zones* zones, struct config_file* cfg
|
||||
}
|
||||
lock_rw_unlock(&z->lock);
|
||||
}
|
||||
/* reverse ip4 zone */
|
||||
if(!lz_exists(zones, "127.in-addr.arpa.") &&
|
||||
!lz_nodefault(cfg, "127.in-addr.arpa.")) {
|
||||
if(!(z=lz_enter_zone(zones, "127.in-addr.arpa.", "static",
|
||||
LDNS_RR_CLASS_IN)) ||
|
||||
!lz_enter_rr_into_zone(z,
|
||||
"127.in-addr.arpa. 10800 IN NS localhost.") ||
|
||||
!lz_enter_rr_into_zone(z,
|
||||
"127.in-addr.arpa. 10800 IN SOA localhost. "
|
||||
"nobody.invalid. 1 3600 1200 604800 10800") ||
|
||||
!lz_enter_rr_into_zone(z,
|
||||
"1.0.0.127.in-addr.arpa. 10800 IN PTR localhost.")) {
|
||||
|
||||
/* ip4 and ip6 reverse */
|
||||
for(zstr = local_zones_default_reverse; *zstr; zstr++) {
|
||||
if(!add_reverse_default(zones, cfg, *zstr)) {
|
||||
log_err("out of memory adding default zone");
|
||||
if(z) { lock_rw_unlock(&z->lock); }
|
||||
return 0;
|
||||
}
|
||||
lock_rw_unlock(&z->lock);
|
||||
}
|
||||
/* reverse ip6 zone */
|
||||
if(!lz_exists(zones, "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.") &&
|
||||
!lz_nodefault(cfg, "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.")) {
|
||||
if(!(z=lz_enter_zone(zones, "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.", "static",
|
||||
LDNS_RR_CLASS_IN)) ||
|
||||
!lz_enter_rr_into_zone(z,
|
||||
"1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. 10800 IN NS localhost.") ||
|
||||
!lz_enter_rr_into_zone(z,
|
||||
"1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. 10800 IN SOA localhost. "
|
||||
"nobody.invalid. 1 3600 1200 604800 10800") ||
|
||||
!lz_enter_rr_into_zone(z,
|
||||
"1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa. 10800 IN PTR localhost.")) {
|
||||
|
||||
/* special-use zones */
|
||||
for(zstr = local_zones_default_special; *zstr; zstr++) {
|
||||
if(!add_empty_default(zones, cfg, *zstr)) {
|
||||
log_err("out of memory adding default zone");
|
||||
if(z) { lock_rw_unlock(&z->lock); }
|
||||
return 0;
|
||||
}
|
||||
lock_rw_unlock(&z->lock);
|
||||
}
|
||||
/* home.arpa. zone (RFC 8375) */
|
||||
if(!add_empty_default(zones, cfg, "home.arpa.")) {
|
||||
log_err("out of memory adding default zone");
|
||||
return 0;
|
||||
}
|
||||
/* resolver.arpa. zone (RFC 9462) */
|
||||
if(!add_empty_default(zones, cfg, "resolver.arpa.")) {
|
||||
log_err("out of memory adding default zone");
|
||||
return 0;
|
||||
}
|
||||
/* service.arpa. zone (draft-ietf-dnssd-srp-25) */
|
||||
if(!add_empty_default(zones, cfg, "service.arpa.")) {
|
||||
log_err("out of memory adding default zone");
|
||||
return 0;
|
||||
}
|
||||
/* onion. zone (RFC 7686) */
|
||||
if(!add_empty_default(zones, cfg, "onion.")) {
|
||||
log_err("out of memory adding default zone");
|
||||
return 0;
|
||||
}
|
||||
/* test. zone (RFC 6761) */
|
||||
if(!add_empty_default(zones, cfg, "test.")) {
|
||||
log_err("out of memory adding default zone");
|
||||
return 0;
|
||||
}
|
||||
/* invalid. zone (RFC 6761) */
|
||||
if(!add_empty_default(zones, cfg, "invalid.")) {
|
||||
log_err("out of memory adding default zone");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* block AS112 zones, unless asked not to */
|
||||
if(!cfg->unblock_lan_zones) {
|
||||
for(zstr = as112_zones; *zstr; zstr++) {
|
||||
@@ -1062,14 +1070,15 @@ lz_setup_implicit(struct local_zones* zones, struct config_file* cfg)
|
||||
labs = dname_count_size_labels(rr_name, &len);
|
||||
lock_rw_rdlock(&zones->lock);
|
||||
if(!local_zones_lookup(zones, rr_name, len, labs, rr_class,
|
||||
rr_type)) {
|
||||
rr_type, 1)) {
|
||||
/* Check if there is a zone that this could go
|
||||
* under but for different class; created zones are
|
||||
* always for LDNS_RR_CLASS_IN. Create the zone with
|
||||
* a different class but the same configured
|
||||
* local_zone_type. */
|
||||
struct local_zone* z = local_zones_lookup(zones,
|
||||
rr_name, len, labs, LDNS_RR_CLASS_IN, rr_type);
|
||||
rr_name, len, labs, LDNS_RR_CLASS_IN, rr_type,
|
||||
1);
|
||||
if(z) {
|
||||
uint8_t* name = memdup(z->name, z->namelen);
|
||||
size_t znamelen = z->namelen;
|
||||
@@ -1231,28 +1240,48 @@ local_zones_apply_cfg(struct local_zones* zones, struct config_file* cfg)
|
||||
|
||||
struct local_zone*
|
||||
local_zones_lookup(struct local_zones* zones,
|
||||
uint8_t* name, size_t len, int labs, uint16_t dclass, uint16_t dtype)
|
||||
uint8_t* name, size_t len, int labs, uint16_t dclass, uint16_t dtype,
|
||||
int foradd)
|
||||
{
|
||||
return local_zones_tags_lookup(zones, name, len, labs,
|
||||
dclass, dtype, NULL, 0, 1);
|
||||
dclass, dtype, NULL, 0, 1, foradd);
|
||||
}
|
||||
|
||||
struct local_zone*
|
||||
local_zones_tags_lookup(struct local_zones* zones,
|
||||
uint8_t* name, size_t len, int labs, uint16_t dclass, uint16_t dtype,
|
||||
uint8_t* taglist, size_t taglen, int ignoretags)
|
||||
uint8_t* taglist, size_t taglen, int ignoretags, int foradd)
|
||||
{
|
||||
rbnode_type* res = NULL;
|
||||
struct local_zone *result;
|
||||
struct local_zone key;
|
||||
int m;
|
||||
/* for type DS use a zone higher when on a zonecut */
|
||||
if(dtype == LDNS_RR_TYPE_DS && !dname_is_root(name)) {
|
||||
dname_remove_label(&name, &len);
|
||||
labs--;
|
||||
}
|
||||
key.node.key = &key;
|
||||
key.dclass = dclass;
|
||||
/* for type DS use a zone higher when on a zonecut */
|
||||
if(dtype == LDNS_RR_TYPE_DS && !dname_is_root(name)) {
|
||||
/* If this is at a zone cut, of a local-zone, and it is
|
||||
* of type always_refuse. Then also refuse the type DS
|
||||
* for it. That could make it DNSSEC bogus, but it is
|
||||
* REFUSED anyway. It stops CNAME type answers in the
|
||||
* type DS lookup. */
|
||||
key.name = name;
|
||||
key.namelen = len;
|
||||
key.namelabs = labs;
|
||||
/* For additions and removals, use the ordinary rule,
|
||||
* to remove a label for type DS to locate the parent zone.
|
||||
* That is where the DS RR needs to be put. */
|
||||
if(!foradd &&
|
||||
(result=(struct local_zone*)rbtree_search(
|
||||
&zones->ztree, &key)) != NULL &&
|
||||
result->type == local_zone_always_refuse) {
|
||||
/* The type DS does not go up one label. */
|
||||
return result;
|
||||
} else {
|
||||
dname_remove_label(&name, &len);
|
||||
labs--;
|
||||
}
|
||||
}
|
||||
key.name = name;
|
||||
key.namelen = len;
|
||||
key.namelabs = labs;
|
||||
@@ -1863,7 +1892,7 @@ local_zones_answer(struct local_zones* zones, struct module_env* env,
|
||||
if(view->local_zones &&
|
||||
(z = local_zones_lookup(view->local_zones,
|
||||
qinfo->qname, qinfo->qname_len, labs,
|
||||
qinfo->qclass, qinfo->qtype))) {
|
||||
qinfo->qclass, qinfo->qtype, 0))) {
|
||||
lock_rw_rdlock(&z->lock);
|
||||
lzt = z->type;
|
||||
}
|
||||
@@ -1897,7 +1926,7 @@ local_zones_answer(struct local_zones* zones, struct module_env* env,
|
||||
lock_rw_rdlock(&zones->lock);
|
||||
if(!(z = local_zones_tags_lookup(zones, qinfo->qname,
|
||||
qinfo->qname_len, labs, qinfo->qclass, qinfo->qtype,
|
||||
taglist, taglen, 0))) {
|
||||
taglist, taglen, 0, 0))) {
|
||||
lock_rw_unlock(&zones->lock);
|
||||
return 0;
|
||||
}
|
||||
@@ -2102,7 +2131,8 @@ local_zones_add_RR(struct local_zones* zones, const char* rr)
|
||||
/* could first try readlock then get writelock if zone does not exist,
|
||||
* but we do not add enough RRs (from multiple threads) to optimize */
|
||||
lock_rw_wrlock(&zones->lock);
|
||||
z = local_zones_lookup(zones, rr_name, len, labs, rr_class, rr_type);
|
||||
z = local_zones_lookup(zones, rr_name, len, labs, rr_class, rr_type,
|
||||
1);
|
||||
if(!z) {
|
||||
z = local_zones_add_zone(zones, rr_name, len, labs, rr_class,
|
||||
local_zone_transparent);
|
||||
@@ -2180,7 +2210,8 @@ void local_zones_del_data(struct local_zones* zones,
|
||||
|
||||
/* remove DS */
|
||||
lock_rw_rdlock(&zones->lock);
|
||||
z = local_zones_lookup(zones, name, len, labs, dclass, LDNS_RR_TYPE_DS);
|
||||
z = local_zones_lookup(zones, name, len, labs, dclass, LDNS_RR_TYPE_DS,
|
||||
1);
|
||||
if(z) {
|
||||
lock_rw_wrlock(&z->lock);
|
||||
d = local_zone_find_data(z, name, len, labs);
|
||||
@@ -2194,7 +2225,7 @@ void local_zones_del_data(struct local_zones* zones,
|
||||
|
||||
/* remove other types */
|
||||
lock_rw_rdlock(&zones->lock);
|
||||
z = local_zones_lookup(zones, name, len, labs, dclass, 0);
|
||||
z = local_zones_lookup(zones, name, len, labs, dclass, 0, 1);
|
||||
if(!z) {
|
||||
/* no such zone, we're done */
|
||||
lock_rw_unlock(&zones->lock);
|
||||
|
||||
+10
-2
@@ -57,6 +57,9 @@ struct sldns_buffer;
|
||||
struct comm_reply;
|
||||
struct config_strlist;
|
||||
|
||||
extern const char** local_zones_default_special;
|
||||
extern const char** local_zones_default_reverse;
|
||||
|
||||
/**
|
||||
* Local zone type
|
||||
* This type determines processing for queries that did not match
|
||||
@@ -262,11 +265,13 @@ void local_zone_delete(struct local_zone* z);
|
||||
* @param taglen: length of taglist.
|
||||
* @param ignoretags: lookup zone by name and class, regardless the
|
||||
* local-zone's tags.
|
||||
* @param foradd: if the lookup is for addition or removal of the type.
|
||||
* Used for type DS. The lookup for answers turns this off.
|
||||
* @return closest local_zone or NULL if no covering zone is found.
|
||||
*/
|
||||
struct local_zone* local_zones_tags_lookup(struct local_zones* zones,
|
||||
uint8_t* name, size_t len, int labs, uint16_t dclass, uint16_t dtype,
|
||||
uint8_t* taglist, size_t taglen, int ignoretags);
|
||||
uint8_t* taglist, size_t taglen, int ignoretags, int foradd);
|
||||
|
||||
/**
|
||||
* Lookup zone that contains the given name, class.
|
||||
@@ -278,10 +283,13 @@ struct local_zone* local_zones_tags_lookup(struct local_zones* zones,
|
||||
* @param dclass: class to lookup.
|
||||
* @param dtype: type of the record, if type DS then a zone higher up is found
|
||||
* pass 0 to just plain find a zone for a name.
|
||||
* @param foradd: if the lookup is for addition or removal of the type.
|
||||
* Used for type DS. The lookup for answers turns this off.
|
||||
* @return closest local_zone or NULL if no covering zone is found.
|
||||
*/
|
||||
struct local_zone* local_zones_lookup(struct local_zones* zones,
|
||||
uint8_t* name, size_t len, int labs, uint16_t dclass, uint16_t dtype);
|
||||
uint8_t* name, size_t len, int labs, uint16_t dclass, uint16_t dtype,
|
||||
int foradd);
|
||||
|
||||
/**
|
||||
* Debug helper. Print all zones
|
||||
|
||||
+34
-74
@@ -45,7 +45,6 @@
|
||||
#include "config.h"
|
||||
#include "services/mesh.h"
|
||||
#include "services/outbound_list.h"
|
||||
#include "services/outside_network.h"
|
||||
#include "services/cache/dns.h"
|
||||
#include "services/cache/rrset.h"
|
||||
#include "services/cache/infra.h"
|
||||
@@ -59,7 +58,6 @@
|
||||
#include "util/alloc.h"
|
||||
#include "util/config_file.h"
|
||||
#include "util/edns.h"
|
||||
#include "sldns/parseutil.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
#include "sldns/wire2str.h"
|
||||
#include "services/localzone.h"
|
||||
@@ -67,8 +65,6 @@
|
||||
#include "respip/respip.h"
|
||||
#include "services/listen_dnsport.h"
|
||||
#include "util/timeval_func.h"
|
||||
#include "util/allow_response_list.h"
|
||||
#include "util/tsig.h"
|
||||
|
||||
#ifdef CLIENT_SUBNET
|
||||
#include "edns-subnet/subnetmod.h"
|
||||
@@ -235,6 +231,7 @@ mesh_create(struct module_stack* stack, struct module_env* env)
|
||||
mesh->ans_expired = 0;
|
||||
mesh->ans_cachedb = 0;
|
||||
mesh->num_queries_discard_timeout = 0;
|
||||
mesh->num_queries_replyaddr_limit = 0;
|
||||
mesh->num_queries_wait_limit = 0;
|
||||
mesh->num_dns_error_reports = 0;
|
||||
mesh->max_reply_states = env->cfg->num_queries_per_thread;
|
||||
@@ -300,12 +297,14 @@ int mesh_make_new_space(struct mesh_area* mesh, sldns_buffer* qbuf)
|
||||
if(mesh->num_reply_states < mesh->max_reply_states)
|
||||
return 1;
|
||||
/* try to kick out a jostle-list item */
|
||||
if(m && m->reply_list && m->list_select == mesh_jostle_list) {
|
||||
if(m && m->list_select == mesh_jostle_list) {
|
||||
/* how old is it? */
|
||||
struct timeval age;
|
||||
timeval_subtract(&age, mesh->env->now_tv,
|
||||
&m->reply_list->start_time);
|
||||
if(timeval_smaller(&mesh->jostle_max, &age)) {
|
||||
if(m->has_first_reply_time)
|
||||
timeval_subtract(&age, mesh->env->now_tv,
|
||||
&m->first_reply_time);
|
||||
if(!m->has_first_reply_time ||
|
||||
timeval_smaller(&mesh->jostle_max, &age)) {
|
||||
/* its a goner */
|
||||
log_nametypeclass(VERB_ALGO, "query jostled out to "
|
||||
"make space for a new one",
|
||||
@@ -466,6 +465,8 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
if(!mesh_make_new_space(mesh, rep->c->buffer)) {
|
||||
verbose(VERB_ALGO, "Too many queries. dropping "
|
||||
"incoming query.");
|
||||
if(rep->c->use_h2)
|
||||
http2_stream_remove_mesh_state(rep->c->h2_stream);
|
||||
comm_point_drop_reply(rep);
|
||||
mesh->stats_dropped++;
|
||||
return;
|
||||
@@ -477,8 +478,10 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
if(mesh->num_reply_addrs > mesh->max_reply_states*16) {
|
||||
verbose(VERB_ALGO, "Too many requests queued. "
|
||||
"dropping incoming query.");
|
||||
if(rep->c->use_h2)
|
||||
http2_stream_remove_mesh_state(rep->c->h2_stream);
|
||||
comm_point_drop_reply(rep);
|
||||
mesh->stats_dropped++;
|
||||
mesh->num_queries_replyaddr_limit++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1035,6 +1038,7 @@ mesh_state_create(struct module_env* env, struct query_info* qinfo,
|
||||
mstate->s.no_cache_store = 0;
|
||||
mstate->s.need_refetch = 0;
|
||||
mstate->s.was_ratelimited = 0;
|
||||
mstate->s.error_response_cache = 0;
|
||||
mstate->s.qstarttime = *env->now;
|
||||
|
||||
/* init modules */
|
||||
@@ -1074,6 +1078,14 @@ mesh_state_cleanup(struct mesh_state* mstate)
|
||||
if(!mstate->replies_sent) {
|
||||
struct mesh_reply* rep = mstate->reply_list;
|
||||
struct mesh_cb* cb;
|
||||
/* One http2 stream could bring down its comm_point along with
|
||||
* the other streams which could share the same query. Do all
|
||||
* the http2 stream bookkeeping upfront. */
|
||||
for(; rep; rep=rep->next) {
|
||||
if(rep->query_reply.c->use_h2)
|
||||
http2_stream_remove_mesh_state(rep->h2_stream);
|
||||
}
|
||||
rep = mstate->reply_list;
|
||||
/* in tcp_req_info, the mstates linked are removed, but
|
||||
* the reply_list is now NULL, so the remove-from-empty-list
|
||||
* takes no time and also it does not do the mesh accounting */
|
||||
@@ -1081,8 +1093,6 @@ mesh_state_cleanup(struct mesh_state* mstate)
|
||||
for(; rep; rep=rep->next) {
|
||||
infra_wait_limit_dec(mesh->env->infra_cache,
|
||||
&rep->query_reply, mesh->env->cfg);
|
||||
if(rep->query_reply.c->use_h2)
|
||||
http2_stream_remove_mesh_state(rep->h2_stream);
|
||||
comm_point_drop_reply(&rep->query_reply);
|
||||
log_assert(mesh->num_reply_addrs > 0);
|
||||
mesh->num_reply_addrs--;
|
||||
@@ -1740,69 +1750,6 @@ void mesh_query_done(struct mesh_state* mstate)
|
||||
if(mstate->reply_list && mstate->s.env->cfg->dns_error_reporting)
|
||||
dns_error_reporting(&mstate->s, rep);
|
||||
|
||||
if(mstate->reply_list && rep) {
|
||||
uint8_t data[8192];
|
||||
struct sldns_buffer dest;
|
||||
int i;
|
||||
|
||||
sldns_buffer_init_frm_data(&dest, data, sizeof(data));
|
||||
reply_info_answer_encode(&mstate->s.qinfo, rep, 0 /* id */,
|
||||
0 /* qflags */, &dest, 0 /* current time */,
|
||||
1 /* cached */, mstate->s.env->scratch,
|
||||
sizeof(data) /* udpsize */, NULL /* edns */,
|
||||
1 /* dnssec */, 0 /* secure */);
|
||||
log_err("Answer to be send to %d other unbounds, size: %d",
|
||||
mstate->s.env->outnet->num_dist,
|
||||
(int)sldns_buffer_limit(&dest));
|
||||
for(i = 0; i < mstate->s.env->outnet->num_dist; i++) {
|
||||
struct tsig_key* key;
|
||||
int r;
|
||||
uint8_t data_signed[8192];
|
||||
struct sldns_buffer dest_signed;
|
||||
|
||||
if(mstate->s.env->outnet->dist[i] == -1
|
||||
|| mstate->s.env->outnet->dist_tsig[i] == NULL)
|
||||
continue;
|
||||
if(mstate->s.env->outnet->dist_tsig[i] == TSIG_NOKEY) {
|
||||
send(mstate->s.env->outnet->dist[i],
|
||||
data, sldns_buffer_limit(&dest), 0);
|
||||
continue;
|
||||
}
|
||||
lock_rw_rdlock(&mstate->s.env->tsig_key_table->lock);
|
||||
key = tsig_key_table_search_fromstr(
|
||||
mstate->s.env->tsig_key_table,
|
||||
mstate->s.env->outnet->dist_tsig[i]);
|
||||
if(!key) {
|
||||
lock_rw_unlock(
|
||||
&mstate->s.env->tsig_key_table->lock);
|
||||
log_err("tsig key \"%s\" not found when "
|
||||
"distributing responses",
|
||||
mstate->s.env->outnet->dist_tsig[i]);
|
||||
continue;
|
||||
}
|
||||
sldns_buffer_init_frm_data(&dest_signed,
|
||||
data_signed, sizeof(data_signed));
|
||||
sldns_buffer_write(&dest_signed,
|
||||
data, sldns_buffer_limit(&dest));
|
||||
if((r = tsig_sign_shared(&dest_signed, key->name,
|
||||
key->algo->wireformat_name,
|
||||
key->data, key->data_len,
|
||||
*mstate->s.env->now))) {
|
||||
lock_rw_unlock(
|
||||
&mstate->s.env->tsig_key_table->lock);
|
||||
log_err("tsig key \"%s\" failed to sign"
|
||||
"distributing response: %s",
|
||||
key->name_str,
|
||||
sldns_lookup_by_id(sldns_tsig_errors, r)?
|
||||
sldns_lookup_by_id(sldns_tsig_errors, r)->name:"??");
|
||||
continue;
|
||||
}
|
||||
lock_rw_unlock(&mstate->s.env->tsig_key_table->lock);
|
||||
send(mstate->s.env->outnet->dist[i], data_signed,
|
||||
sldns_buffer_position(&dest_signed), 0);
|
||||
}
|
||||
}
|
||||
|
||||
for(r = mstate->reply_list; r; r = r->next) {
|
||||
if(mesh_is_udp(r)) {
|
||||
/* For UDP queries, the old replies are discarded.
|
||||
@@ -1832,6 +1779,8 @@ void mesh_query_done(struct mesh_state* mstate)
|
||||
http2_stream_remove_mesh_state(r->h2_stream);
|
||||
comm_point_drop_reply(&r->query_reply);
|
||||
mstate->reply_list = reply_list;
|
||||
log_assert(mstate->s.env->mesh->num_reply_addrs > 0);
|
||||
mstate->s.env->mesh->num_reply_addrs--;
|
||||
mstate->s.env->mesh->num_queries_discard_timeout++;
|
||||
continue;
|
||||
}
|
||||
@@ -1868,6 +1817,8 @@ void mesh_query_done(struct mesh_state* mstate)
|
||||
}
|
||||
comm_point_drop_reply(&r->query_reply);
|
||||
mstate->reply_list = reply_list;
|
||||
log_assert(mstate->s.env->mesh->num_reply_addrs > 0);
|
||||
mstate->s.env->mesh->num_reply_addrs--;
|
||||
} else {
|
||||
struct sldns_buffer* r_buffer = r->query_reply.c->buffer;
|
||||
if(r->query_reply.c->tcp_req_info) {
|
||||
@@ -2046,6 +1997,10 @@ int mesh_state_add_reply(struct mesh_state* s, struct edns_data* edns,
|
||||
r->qid = qid;
|
||||
r->qflags = qflags;
|
||||
r->start_time = *s->s.env->now_tv;
|
||||
if(s->reply_list == NULL && !s->has_first_reply_time) {
|
||||
s->first_reply_time = r->start_time;
|
||||
s->has_first_reply_time = 1;
|
||||
}
|
||||
r->next = s->reply_list;
|
||||
r->qname = regional_alloc_init(s->s.region, qinfo->qname,
|
||||
s->s.qinfo.qname_len);
|
||||
@@ -2358,6 +2313,7 @@ mesh_stats_clear(struct mesh_area* mesh)
|
||||
memset(&mesh->rpz_action[0], 0, sizeof(size_t)*UB_STATS_RPZ_ACTION_NUM);
|
||||
mesh->ans_nodata = 0;
|
||||
mesh->num_queries_discard_timeout = 0;
|
||||
mesh->num_queries_replyaddr_limit = 0;
|
||||
mesh->num_queries_wait_limit = 0;
|
||||
mesh->num_dns_error_reports = 0;
|
||||
}
|
||||
@@ -2427,6 +2383,10 @@ void mesh_state_remove_reply(struct mesh_area* mesh, struct mesh_state* m,
|
||||
mesh->num_reply_addrs--;
|
||||
infra_wait_limit_dec(mesh->env->infra_cache,
|
||||
&n->query_reply, mesh->env->cfg);
|
||||
/* We may be removing more than one http2 stream (they
|
||||
* share the same comm_point); make sure the streams
|
||||
* don't point back. */
|
||||
if(n->h2_stream) n->h2_stream->mesh_state = NULL;
|
||||
|
||||
/* prev = prev; */
|
||||
n = n->next;
|
||||
|
||||
@@ -141,6 +141,8 @@ struct mesh_area {
|
||||
size_t rpz_action[UB_STATS_RPZ_ACTION_NUM];
|
||||
/** stats, number of queries removed due to discard-timeout */
|
||||
size_t num_queries_discard_timeout;
|
||||
/** stats, number of queries removed due to replyaddr limit */
|
||||
size_t num_queries_replyaddr_limit;
|
||||
/** stats, number of queries removed due to wait-limit */
|
||||
size_t num_queries_wait_limit;
|
||||
/** stats, number of dns error reports generated */
|
||||
@@ -189,6 +191,12 @@ struct mesh_state {
|
||||
struct module_qstate s;
|
||||
/** the list of replies to clients for the results */
|
||||
struct mesh_reply* reply_list;
|
||||
/** if it has a first reply time */
|
||||
int has_first_reply_time;
|
||||
/** wall-clock time the first client reply was attached;
|
||||
* used by mesh_make_new_space() so duplicate retransmits
|
||||
* cannot reset jostle aging. */
|
||||
struct timeval first_reply_time;
|
||||
/** the list of callbacks for the results */
|
||||
struct mesh_cb* cb_list;
|
||||
/** set of superstates (that want this state's result)
|
||||
|
||||
+59
-38
@@ -59,7 +59,6 @@
|
||||
#include "util/random.h"
|
||||
#include "util/fptr_wlist.h"
|
||||
#include "util/edns.h"
|
||||
#include "util/allow_response_list.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
#include "dnstap/dnstap.h"
|
||||
#ifdef HAVE_OPENSSL_SSL_H
|
||||
@@ -161,6 +160,19 @@ reuse_cmp_addrportssl(const void* key1, const void* key2)
|
||||
return 1;
|
||||
if(!r1->is_ssl && r2->is_ssl)
|
||||
return -1;
|
||||
|
||||
/* compare tls_auth_name if SSL-enabled */
|
||||
if(r1->is_ssl) {
|
||||
if(r1->tls_auth_name && !r2->tls_auth_name)
|
||||
return 1;
|
||||
if(!r1->tls_auth_name && r2->tls_auth_name)
|
||||
return -1;
|
||||
if(r1->tls_auth_name && r2->tls_auth_name) {
|
||||
r = strcmp(r1->tls_auth_name, r2->tls_auth_name);
|
||||
if(r != 0)
|
||||
return r;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -532,7 +544,7 @@ reuse_tcp_insert(struct outside_network* outnet, struct pending_tcp* pend_tcp)
|
||||
/** find reuse tcp stream to destination for query, or NULL if none */
|
||||
static struct reuse_tcp*
|
||||
reuse_tcp_find(struct outside_network* outnet, struct sockaddr_storage* addr,
|
||||
socklen_t addrlen, int use_ssl)
|
||||
socklen_t addrlen, int use_ssl, char* tls_auth_name)
|
||||
{
|
||||
struct waiting_tcp key_w;
|
||||
struct pending_tcp key_p;
|
||||
@@ -546,8 +558,10 @@ reuse_tcp_find(struct outside_network* outnet, struct sockaddr_storage* addr,
|
||||
key_p.c = &c;
|
||||
key_p.reuse.pending = &key_p;
|
||||
key_p.reuse.node.key = &key_p.reuse;
|
||||
if(use_ssl)
|
||||
if(use_ssl) {
|
||||
key_p.reuse.is_ssl = 1;
|
||||
key_p.reuse.tls_auth_name = tls_auth_name;
|
||||
}
|
||||
if(addrlen > (socklen_t)sizeof(key_p.reuse.addr))
|
||||
return NULL;
|
||||
memmove(&key_p.reuse.addr, addr, addrlen);
|
||||
@@ -647,6 +661,7 @@ static int
|
||||
outnet_tcp_take_into_use(struct waiting_tcp* w)
|
||||
{
|
||||
struct pending_tcp* pend = w->outnet->tcp_free;
|
||||
char* tls_auth_name = NULL;
|
||||
int s;
|
||||
log_assert(pend);
|
||||
log_assert(w->pkt);
|
||||
@@ -747,7 +762,22 @@ outnet_tcp_take_into_use(struct waiting_tcp* w)
|
||||
comm_point_tcp_win_bio_cb(pend->c, pend->c->ssl);
|
||||
#endif
|
||||
pend->c->ssl_shake_state = comm_ssl_shake_write;
|
||||
if(!set_auth_name_on_ssl(pend->c->ssl, w->tls_auth_name,
|
||||
if(w->tls_auth_name) {
|
||||
/* strdup the auth name, while not linked the list yet,
|
||||
* in case of failure, easy cleanup. */
|
||||
tls_auth_name = strdup(w->tls_auth_name);
|
||||
if(!tls_auth_name) {
|
||||
log_err("out of memory: alloc tls auth name");
|
||||
pend->c->fd = s;
|
||||
#ifdef HAVE_SSL
|
||||
SSL_free(pend->c->ssl);
|
||||
#endif
|
||||
pend->c->ssl = NULL;
|
||||
comm_point_close(pend->c);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if(!set_auth_name_on_ssl(pend->c->ssl, tls_auth_name,
|
||||
w->outnet->tls_use_sni)) {
|
||||
pend->c->fd = s;
|
||||
#ifdef HAVE_SSL
|
||||
@@ -755,6 +785,7 @@ outnet_tcp_take_into_use(struct waiting_tcp* w)
|
||||
#endif
|
||||
pend->c->ssl = NULL;
|
||||
comm_point_close(pend->c);
|
||||
free(tls_auth_name);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -779,9 +810,20 @@ outnet_tcp_take_into_use(struct waiting_tcp* w)
|
||||
if(pend->reuse.node.key)
|
||||
reuse_tcp_remove_tree_list(w->outnet, &pend->reuse);
|
||||
|
||||
if(pend->c->ssl)
|
||||
if(pend->c->ssl) {
|
||||
pend->reuse.is_ssl = 1;
|
||||
else pend->reuse.is_ssl = 0;
|
||||
if(pend->reuse.tls_auth_name)
|
||||
free(pend->reuse.tls_auth_name);
|
||||
pend->reuse.tls_auth_name = tls_auth_name;
|
||||
tls_auth_name = NULL;
|
||||
} else {
|
||||
pend->reuse.is_ssl = 0;
|
||||
if(pend->reuse.tls_auth_name)
|
||||
free(pend->reuse.tls_auth_name);
|
||||
pend->reuse.tls_auth_name = NULL;
|
||||
}
|
||||
/* free tls auth name if nonNULL */
|
||||
free(tls_auth_name);
|
||||
/* insert in reuse by address tree if not already inserted there */
|
||||
(void)reuse_tcp_insert(w->outnet, pend);
|
||||
reuse_tree_by_id_insert(&pend->reuse, w);
|
||||
@@ -970,7 +1012,7 @@ use_free_buffer(struct outside_network* outnet)
|
||||
(!outnet->tcp_reuse_first && !outnet->tcp_reuse_last) ||
|
||||
(outnet->tcp_reuse_first && outnet->tcp_reuse_last));
|
||||
reuse = reuse_tcp_find(outnet, &w->addr, w->addrlen,
|
||||
w->ssl_upstream);
|
||||
w->ssl_upstream, w->tls_auth_name);
|
||||
/* re-select an ID when moving to a new TCP buffer */
|
||||
w->id = tcp_select_id(outnet, reuse);
|
||||
LDNS_ID_SET(w->pkt, w->id);
|
||||
@@ -1199,6 +1241,10 @@ decommission_pending_tcp(struct outside_network* outnet,
|
||||
/* needs unlink from the reuse tree to get deleted */
|
||||
reuse_tcp_remove_tree_list(outnet, &pend->reuse);
|
||||
}
|
||||
if(pend->reuse.tls_auth_name) {
|
||||
free(pend->reuse.tls_auth_name);
|
||||
pend->reuse.tls_auth_name = NULL;
|
||||
}
|
||||
/* free SSL structure after remove from outnet tcp reuse tree,
|
||||
* because the c->ssl null or not is used for sorting in the tree */
|
||||
if(pend->c->ssl) {
|
||||
@@ -1679,8 +1725,7 @@ outside_network_create(struct comm_base *base, size_t bufsize,
|
||||
void (*unwanted_action)(void*), void* unwanted_param, int do_udp,
|
||||
void* sslctx, int delayclose, int tls_use_sni, struct dt_env* dtenv,
|
||||
int udp_connect, int max_reuse_tcp_queries, int tcp_reuse_timeout,
|
||||
int tcp_auth_query_timeout, const char** dist, const char** dist_tsig,
|
||||
int num_dist)
|
||||
int tcp_auth_query_timeout)
|
||||
{
|
||||
struct outside_network* outnet = (struct outside_network*)
|
||||
calloc(1, sizeof(struct outside_network));
|
||||
@@ -1821,32 +1866,6 @@ outside_network_create(struct comm_base *base, size_t bufsize,
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!(outnet->num_dist = num_dist))
|
||||
outnet->dist = NULL;
|
||||
else if ((outnet->dist = calloc(num_dist, sizeof(int))) &&
|
||||
(outnet->dist_tsig = calloc(num_dist, sizeof(const char*)))) {
|
||||
int i;
|
||||
|
||||
for(i = 0; i < num_dist; i++) {
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addrlen;
|
||||
int s = -1;
|
||||
|
||||
if(!extstrtoaddr(dist[i], &addr, &addrlen, UNBOUND_DNS_PORT)
|
||||
|| (s = socket(addr.ss_family, SOCK_DGRAM, 0)) == -1
|
||||
|| !fd_set_nonblock(s)
|
||||
|| connect(s, (struct sockaddr*)&addr, addrlen)) {
|
||||
if(s != -1)
|
||||
close(s);
|
||||
s = -1;
|
||||
}
|
||||
outnet->dist[i] = s;
|
||||
outnet->dist_tsig[i] = dist_tsig[i] == NULL ? NULL
|
||||
: strcmp(dist_tsig[i], TSIG_NOKEY)
|
||||
? strdup(dist_tsig[i])
|
||||
: TSIG_NOKEY;
|
||||
}
|
||||
}
|
||||
return outnet;
|
||||
}
|
||||
|
||||
@@ -1950,6 +1969,10 @@ outside_network_delete(struct outside_network* outnet)
|
||||
* the tcp conn is working on */
|
||||
decommission_pending_tcp(outnet, pend);
|
||||
}
|
||||
if(pend->reuse.tls_auth_name) {
|
||||
free(pend->reuse.tls_auth_name);
|
||||
pend->reuse.tls_auth_name = NULL;
|
||||
}
|
||||
comm_point_delete(outnet->tcp_conns[i]->c);
|
||||
free(outnet->tcp_conns[i]);
|
||||
outnet->tcp_conns[i] = NULL;
|
||||
@@ -1977,8 +2000,6 @@ outside_network_delete(struct outside_network* outnet)
|
||||
p = np;
|
||||
}
|
||||
}
|
||||
if(outnet->num_dist > 0 && outnet->dist != NULL)
|
||||
free(outnet->dist);
|
||||
free(outnet);
|
||||
}
|
||||
|
||||
@@ -2477,7 +2498,7 @@ pending_tcp_query(struct serviced_query* sq, sldns_buffer* packet,
|
||||
/* find out if a reused stream to the target exists */
|
||||
/* if so, take it into use */
|
||||
reuse = reuse_tcp_find(sq->outnet, &sq->addr, sq->addrlen,
|
||||
sq->ssl_upstream);
|
||||
sq->ssl_upstream, sq->tls_auth_name);
|
||||
if(reuse) {
|
||||
log_reuse_tcp(VERB_CLIENT, "pending_tcp_query: found reuse", reuse);
|
||||
log_assert(reuse->pending);
|
||||
|
||||
@@ -48,6 +48,10 @@
|
||||
#include "util/regional.h"
|
||||
#include "util/netevent.h"
|
||||
#include "dnstap/dnstap_config.h"
|
||||
#ifdef __QNX__
|
||||
/* For struct timeval */
|
||||
#include <sys/time.h>
|
||||
#endif /* __QNX__ */
|
||||
struct pending;
|
||||
struct pending_timeout;
|
||||
struct ub_randstate;
|
||||
@@ -190,12 +194,6 @@ struct outside_network {
|
||||
struct waiting_tcp* tcp_wait_first;
|
||||
/** last of waiting query list */
|
||||
struct waiting_tcp* tcp_wait_last;
|
||||
/** number of IP addresses to send to be cached responses to */
|
||||
int num_dist;
|
||||
/** udp sockets to the addresses to send to be cached responses to */
|
||||
int* dist;
|
||||
/** names of TSIG keys with which to sign the outgoing responses */
|
||||
const char** dist_tsig;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -266,6 +264,9 @@ struct reuse_tcp {
|
||||
socklen_t addrlen;
|
||||
/** also key for tcp_reuse tree, if ssl is used */
|
||||
int is_ssl;
|
||||
/** If is_ssl is enabled, tls_auth_name is part of the key for
|
||||
* tcp_reuse tree. If the string is NULL, it without a tls_auth_name */
|
||||
char* tls_auth_name;
|
||||
/** lru chain, so that the oldest can be removed to get a new
|
||||
* connection when all are in (re)use. oldest is last in list.
|
||||
* The lru only contains empty connections waiting for reuse,
|
||||
@@ -576,8 +577,7 @@ struct outside_network* outside_network_create(struct comm_base* base,
|
||||
void (*unwanted_action)(void*), void* unwanted_param, int do_udp,
|
||||
void* sslctx, int delayclose, int tls_use_sni, struct dt_env *dtenv,
|
||||
int udp_connect, int max_reuse_tcp_queries, int tcp_reuse_timeout,
|
||||
int tcp_auth_query_timeout, const char** dist, const char** dist_tsig,
|
||||
int num_dist);
|
||||
int tcp_auth_query_timeout);
|
||||
|
||||
/**
|
||||
* Delete outside_network structure.
|
||||
|
||||
+7
-4
@@ -153,6 +153,7 @@ rpz_type_ignored(uint16_t rr_type)
|
||||
case LDNS_RR_TYPE_SOA:
|
||||
case LDNS_RR_TYPE_NS:
|
||||
case LDNS_RR_TYPE_DNAME:
|
||||
case LDNS_RR_TYPE_ZONEMD:
|
||||
/* all DNSSEC-related RRs must be ignored */
|
||||
case LDNS_RR_TYPE_DNSKEY:
|
||||
case LDNS_RR_TYPE_DS:
|
||||
@@ -2468,6 +2469,7 @@ rpz_callback_from_iterator_module(struct module_qstate* ms, struct iter_qstate*
|
||||
{
|
||||
struct auth_zones* az;
|
||||
struct auth_zone* a;
|
||||
struct dns_msg* ret = NULL;
|
||||
struct clientip_synthesized_rr* raddr = NULL;
|
||||
struct rpz* r = NULL;
|
||||
struct local_zone* z = NULL;
|
||||
@@ -2511,13 +2513,11 @@ rpz_callback_from_iterator_module(struct module_qstate* ms, struct iter_qstate*
|
||||
z = rpz_delegation_point_zone_lookup(is->dp, r->nsdname_zones,
|
||||
is->qchase.qclass, &match);
|
||||
if(z != NULL) {
|
||||
lock_rw_unlock(&a->lock);
|
||||
break;
|
||||
}
|
||||
|
||||
raddr = rpz_delegation_point_ipbased_trigger_lookup(r, is);
|
||||
if(raddr != NULL) {
|
||||
lock_rw_unlock(&a->lock);
|
||||
break;
|
||||
}
|
||||
lock_rw_unlock(&a->lock);
|
||||
@@ -2532,9 +2532,12 @@ rpz_callback_from_iterator_module(struct module_qstate* ms, struct iter_qstate*
|
||||
if(z) {
|
||||
lock_rw_unlock(&z->lock);
|
||||
}
|
||||
return rpz_apply_nsip_trigger(ms, &is->qchase, r, raddr, a);
|
||||
ret = rpz_apply_nsip_trigger(ms, &is->qchase, r, raddr, a);
|
||||
} else {
|
||||
ret = rpz_apply_nsdname_trigger(ms, &is->qchase, r, z, &match, a);
|
||||
}
|
||||
return rpz_apply_nsdname_trigger(ms, &is->qchase, r, z, &match, a);
|
||||
lock_rw_unlock(&a->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct dns_msg* rpz_callback_from_iterator_cname(struct module_qstate* ms,
|
||||
|
||||
+1
-1
@@ -486,6 +486,7 @@ enum sldns_enum_ede_code
|
||||
typedef enum sldns_enum_ede_code sldns_ede_code;
|
||||
|
||||
#define LDNS_EDNS_MASK_DO_BIT 0x8000
|
||||
#define LDNS_EDNS_MASK_CO_BIT 0x4000
|
||||
|
||||
/** TSIG and TKEY extended rcodes (16bit), 0-15 are the normal rcodes. */
|
||||
#define LDNS_TSIG_ERROR_NOERROR 0
|
||||
@@ -495,7 +496,6 @@ typedef enum sldns_enum_ede_code sldns_ede_code;
|
||||
#define LDNS_TSIG_ERROR_BADMODE 19
|
||||
#define LDNS_TSIG_ERROR_BADNAME 20
|
||||
#define LDNS_TSIG_ERROR_BADALG 21
|
||||
#define LDNS_TSIG_ERROR_BADTRUNC 22
|
||||
|
||||
/** DNS Cookie extended rcode */
|
||||
#define LDNS_EXT_RCODE_BADCOOKIE 23
|
||||
|
||||
@@ -56,18 +56,6 @@ sldns_read_uint32(const void *src)
|
||||
#endif
|
||||
}
|
||||
|
||||
INLINE uint64_t
|
||||
sldns_read_uint48(const void *src)
|
||||
{
|
||||
const uint8_t *p = (const uint8_t *) src;
|
||||
return ( ((uint64_t) p[0] << 40)
|
||||
| ((uint64_t) p[1] << 32)
|
||||
| ((uint64_t) p[2] << 24)
|
||||
| ((uint64_t) p[3] << 16)
|
||||
| ((uint64_t) p[4] << 8)
|
||||
| (uint64_t) p[5]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy data allowing for unaligned accesses in network byte order
|
||||
* (big endian).
|
||||
@@ -705,32 +693,6 @@ sldns_buffer_read_u32(sldns_buffer *buffer)
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the 6-byte integer value at the given position in the buffer
|
||||
* \param[in] buffer the buffer
|
||||
* \param[in] at position in the buffer
|
||||
* \return 6 byte integer
|
||||
*/
|
||||
INLINE uint64_t
|
||||
sldns_buffer_read_u48_at(sldns_buffer *buffer, size_t at)
|
||||
{
|
||||
assert(sldns_buffer_available_at(buffer, at, 6));
|
||||
return sldns_read_uint48(buffer->_data + at);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the 6-byte integer value at the current position in the buffer
|
||||
* \param[in] buffer the buffer
|
||||
* \return 6 byte integer
|
||||
*/
|
||||
INLINE uint64_t
|
||||
sldns_buffer_read_u48(sldns_buffer *buffer)
|
||||
{
|
||||
uint64_t result = sldns_buffer_read_u48_at(buffer, buffer->_position);
|
||||
buffer->_position += 6;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the status of the buffer
|
||||
* \param[in] buffer
|
||||
|
||||
+2
-1
@@ -256,7 +256,6 @@ static sldns_lookup_table sldns_tsig_errors_data[] = {
|
||||
{ LDNS_TSIG_ERROR_BADMODE, "BADMODE" },
|
||||
{ LDNS_TSIG_ERROR_BADNAME, "BADNAME" },
|
||||
{ LDNS_TSIG_ERROR_BADALG, "BADALG" },
|
||||
{ LDNS_TSIG_ERROR_BADTRUNC, "BADTRUNC" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
sldns_lookup_table* sldns_tsig_errors = sldns_tsig_errors_data;
|
||||
@@ -2487,6 +2486,8 @@ int sldns_wire2str_edns_scan(uint8_t** data, size_t* data_len, char** str,
|
||||
w += sldns_str_print(str, str_len, " flags:");
|
||||
if((edns_bits & LDNS_EDNS_MASK_DO_BIT))
|
||||
w += sldns_str_print(str, str_len, " do");
|
||||
if((edns_bits & LDNS_EDNS_MASK_CO_BIT))
|
||||
w += sldns_str_print(str, str_len, " co");
|
||||
/* the extended rcode is the value set, shifted four bits,
|
||||
* and or'd with the original rcode */
|
||||
if(ext_rcode) {
|
||||
|
||||
@@ -2430,12 +2430,20 @@ int main(int argc, char* argv[])
|
||||
#else
|
||||
OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS
|
||||
| OPENSSL_INIT_ADD_ALL_DIGESTS
|
||||
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
|
||||
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS
|
||||
# if defined(OPENSSL_INIT_NO_LOAD_CONFIG) && defined(UB_ON_WINDOWS)
|
||||
| OPENSSL_INIT_NO_LOAD_CONFIG
|
||||
# endif
|
||||
, NULL);
|
||||
#endif
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL)
|
||||
(void)SSL_library_init();
|
||||
#else
|
||||
(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL);
|
||||
(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS
|
||||
# if defined(OPENSSL_INIT_NO_LOAD_CONFIG) && defined(UB_ON_WINDOWS)
|
||||
| OPENSSL_INIT_NO_LOAD_CONFIG
|
||||
# endif
|
||||
, NULL);
|
||||
#endif
|
||||
|
||||
if(dolist) do_list_builtin();
|
||||
|
||||
@@ -44,12 +44,12 @@
|
||||
|
||||
#include "config.h"
|
||||
#include <ctype.h>
|
||||
#include "util/as112.h"
|
||||
#include "util/log.h"
|
||||
#include "util/config_file.h"
|
||||
#include "util/module.h"
|
||||
#include "util/net_help.h"
|
||||
#include "util/regional.h"
|
||||
#include "util/tsig.h"
|
||||
#include "iterator/iterator.h"
|
||||
#include "iterator/iter_fwd.h"
|
||||
#include "iterator/iter_hints.h"
|
||||
@@ -189,11 +189,56 @@ donotquerylocalhostcheck(struct config_file* cfg)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
nodefaultzonescheck(struct config_file* cfg)
|
||||
{
|
||||
struct config_strlist* d;
|
||||
const char** zstr;
|
||||
size_t len;
|
||||
|
||||
#define COMPARE_ZONE_NAME(confname, builtname, len) \
|
||||
(strncasecmp(confname, builtname, (len)) == 0 && \
|
||||
(strlen(confname) == (len) || \
|
||||
(strlen(confname) == (len) + 1 \
|
||||
&& confname[(len)] == '.')))
|
||||
|
||||
for(d = cfg->local_zones_nodefault; d; d = d->next) {
|
||||
if(!cfg->unblock_lan_zones) {
|
||||
for(zstr = as112_zones; *zstr; zstr++) {
|
||||
len = strlen(*zstr) - 1; /* trailing '.' */
|
||||
if(COMPARE_ZONE_NAME(d->str, *zstr, len))
|
||||
goto default_continue;
|
||||
}
|
||||
}
|
||||
for(zstr = local_zones_default_special; *zstr; zstr++) {
|
||||
len = strlen(*zstr) - 1; /* trailing '.' */
|
||||
if(COMPARE_ZONE_NAME(d->str, *zstr, len))
|
||||
goto default_continue;
|
||||
}
|
||||
for(zstr = local_zones_default_reverse; *zstr; zstr++) {
|
||||
len = strlen(*zstr) - 1; /* trailing '.' */
|
||||
if(COMPARE_ZONE_NAME(d->str, *zstr, len))
|
||||
goto default_continue;
|
||||
}
|
||||
if(COMPARE_ZONE_NAME(d->str, "localhost.", 10 - 1))
|
||||
goto default_continue;
|
||||
fprintf(stderr, "unbound-checkconf: warning: local-zone: '%s' "
|
||||
"is configured as 'nodefault' but there is no such "
|
||||
"default local-zone. Check the unbound.conf "
|
||||
"documentation for default configured local-zones.\n",
|
||||
d->str);
|
||||
default_continue:
|
||||
; /* statement to jump to, for older gcc. */
|
||||
}
|
||||
#undef COMPARE_ZONE_NAME
|
||||
}
|
||||
|
||||
/** check localzones */
|
||||
static void
|
||||
localzonechecks(struct config_file* cfg)
|
||||
{
|
||||
struct local_zones* zs;
|
||||
nodefaultzonescheck(cfg);
|
||||
if(!(zs = local_zones_create()))
|
||||
fatal_exit("out of memory");
|
||||
if(!local_zones_apply_cfg(zs, cfg))
|
||||
@@ -1004,23 +1049,13 @@ static void
|
||||
check_auth(struct config_file* cfg)
|
||||
{
|
||||
int is_rpz = 0;
|
||||
struct tsig_key_table* tsig_key_table;
|
||||
struct auth_zones* az = auth_zones_create();
|
||||
|
||||
/* construct tsig key table for tsig key name checks, and it
|
||||
* also checks the TSIG key name and algorithm and base64 syntax. */
|
||||
tsig_key_table = tsig_key_table_create();
|
||||
if(!tsig_key_table || !tsig_key_table_apply_cfg(tsig_key_table, cfg))
|
||||
fatal_exit("Could not set up TSIG keys");
|
||||
|
||||
if(!az || !auth_zones_apply_cfg(az, cfg, 0, &is_rpz, NULL, NULL,
|
||||
tsig_key_table)) {
|
||||
if(!az || !auth_zones_apply_cfg(az, cfg, 0, &is_rpz, NULL, NULL)) {
|
||||
fatal_exit("Could not setup authority zones");
|
||||
}
|
||||
if(is_rpz && !strstr(cfg->module_conf, "respip"))
|
||||
fatal_exit("RPZ requires the respip module");
|
||||
auth_zones_delete(az);
|
||||
tsig_key_table_delete(tsig_key_table);
|
||||
}
|
||||
|
||||
/** check config file */
|
||||
|
||||
@@ -236,6 +236,8 @@ static void pr_stats(const char* nm, struct ub_stats_info* s)
|
||||
s->svr.num_queries_cookie_invalid);
|
||||
PR_UL_NM("num.queries_discard_timeout",
|
||||
s->svr.num_queries_discard_timeout);
|
||||
PR_UL_NM("num.queries_replyaddr_limit",
|
||||
s->svr.num_queries_replyaddr_limit);
|
||||
PR_UL_NM("num.queries_wait_limit", s->svr.num_queries_wait_limit);
|
||||
PR_UL_NM("num.cachehits",
|
||||
s->svr.num_queries - s->svr.num_queries_missed_cache);
|
||||
@@ -263,6 +265,7 @@ static void pr_stats(const char* nm, struct ub_stats_info* s)
|
||||
PR_UL_NM("requestlist.exceeded", s->mesh_dropped);
|
||||
PR_UL_NM("requestlist.current.all", s->mesh_num_states);
|
||||
PR_UL_NM("requestlist.current.user", s->mesh_num_reply_states);
|
||||
PR_UL_NM("requestlist.current.replies", s->mesh_num_reply_addrs);
|
||||
#ifndef S_SPLINT_S
|
||||
sumwait.tv_sec = s->mesh_replies_sum_wait_sec;
|
||||
sumwait.tv_usec = s->mesh_replies_sum_wait_usec;
|
||||
@@ -1049,12 +1052,20 @@ int main(int argc, char* argv[])
|
||||
#else
|
||||
OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS
|
||||
| OPENSSL_INIT_ADD_ALL_DIGESTS
|
||||
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
|
||||
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS
|
||||
# if defined(OPENSSL_INIT_NO_LOAD_CONFIG) && defined(UB_ON_WINDOWS)
|
||||
| OPENSSL_INIT_NO_LOAD_CONFIG
|
||||
# endif
|
||||
, NULL);
|
||||
#endif
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL)
|
||||
(void)SSL_library_init();
|
||||
#else
|
||||
(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL);
|
||||
(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS
|
||||
# if defined(OPENSSL_INIT_NO_LOAD_CONFIG) && defined(UB_ON_WINDOWS)
|
||||
| OPENSSL_INIT_NO_LOAD_CONFIG
|
||||
# endif
|
||||
, NULL);
|
||||
#endif
|
||||
|
||||
if(!RAND_status()) {
|
||||
|
||||
+10
-2
@@ -521,12 +521,20 @@ int main(int argc, char* argv[])
|
||||
#else
|
||||
OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS
|
||||
| OPENSSL_INIT_ADD_ALL_DIGESTS
|
||||
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
|
||||
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS
|
||||
# if defined(OPENSSL_INIT_NO_LOAD_CONFIG) && defined(UB_ON_WINDOWS)
|
||||
| OPENSSL_INIT_NO_LOAD_CONFIG
|
||||
# endif
|
||||
, NULL);
|
||||
#endif
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL)
|
||||
(void)SSL_library_init();
|
||||
#else
|
||||
(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL);
|
||||
(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS
|
||||
# if defined(OPENSSL_INIT_NO_LOAD_CONFIG) && defined(UB_ON_WINDOWS)
|
||||
| OPENSSL_INIT_NO_LOAD_CONFIG
|
||||
# endif
|
||||
, NULL);
|
||||
#endif
|
||||
#endif /* HAVE_SSL */
|
||||
#ifdef HAVE_NSS
|
||||
|
||||
+10
-2
@@ -488,12 +488,20 @@ int main(int argc, char** argv)
|
||||
#else
|
||||
OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS
|
||||
| OPENSSL_INIT_ADD_ALL_DIGESTS
|
||||
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
|
||||
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS
|
||||
# if defined(OPENSSL_INIT_NO_LOAD_CONFIG) && defined(UB_ON_WINDOWS)
|
||||
| OPENSSL_INIT_NO_LOAD_CONFIG
|
||||
# endif
|
||||
, NULL);
|
||||
#endif
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL)
|
||||
(void)SSL_library_init();
|
||||
#else
|
||||
(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL);
|
||||
(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS
|
||||
# if defined(OPENSSL_INIT_NO_LOAD_CONFIG) && defined(UB_ON_WINDOWS)
|
||||
| OPENSSL_INIT_NO_LOAD_CONFIG
|
||||
# endif
|
||||
, NULL);
|
||||
#endif
|
||||
#endif /* HAVE_SSL */
|
||||
|
||||
|
||||
@@ -360,6 +360,7 @@ typedef pthread_key_t ub_thread_key_type;
|
||||
#define ub_thread_key_create(key, f) LOCKRET(pthread_key_create(key, f))
|
||||
#define ub_thread_key_set(key, v) LOCKRET(pthread_setspecific(key, v))
|
||||
#define ub_thread_key_get(key) pthread_getspecific(key)
|
||||
#define ub_thread_setname(thread, name) /* nop */
|
||||
|
||||
#endif /* USE_THREAD_DEBUG */
|
||||
#endif /* TESTCODE_CHECK_LOCKS_H */
|
||||
|
||||
+10
-2
@@ -642,12 +642,20 @@ int main(int argc, char** argv)
|
||||
#else
|
||||
OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS
|
||||
| OPENSSL_INIT_ADD_ALL_DIGESTS
|
||||
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
|
||||
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS
|
||||
# if defined(OPENSSL_INIT_NO_LOAD_CONFIG) && defined(UB_ON_WINDOWS)
|
||||
| OPENSSL_INIT_NO_LOAD_CONFIG
|
||||
# endif
|
||||
, NULL);
|
||||
#endif
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL)
|
||||
(void)SSL_library_init();
|
||||
#else
|
||||
(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL);
|
||||
(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS
|
||||
# if defined(OPENSSL_INIT_NO_LOAD_CONFIG) && defined(UB_ON_WINDOWS)
|
||||
| OPENSSL_INIT_NO_LOAD_CONFIG
|
||||
# endif
|
||||
, NULL);
|
||||
#endif
|
||||
}
|
||||
run(h2_session, port, no_tls, argc, argv);
|
||||
|
||||
@@ -2255,7 +2255,7 @@ create_doq_client_data(const char* svr, int port, struct ub_event_base* base,
|
||||
/* Initialize the ossl crypto, it is harmless to call twice,
|
||||
* and this is before use of doq connections. */
|
||||
if(ngtcp2_crypto_ossl_init() != 0)
|
||||
fatal_exit("ngtcp2_crypto_oss_init failed");
|
||||
fatal_exit("ngtcp2_crypto_ossl_init failed");
|
||||
#elif defined(HAVE_NGTCP2_CRYPTO_QUICTLS_INIT)
|
||||
if(ngtcp2_crypto_quictls_init() != 0)
|
||||
fatal_exit("ngtcp2_crypto_quictls_init failed");
|
||||
|
||||
@@ -1134,8 +1134,7 @@ outside_network_create(struct comm_base* base, size_t bufsize,
|
||||
int ATTR_UNUSED(delayclose), int ATTR_UNUSED(tls_use_sni),
|
||||
struct dt_env* ATTR_UNUSED(dtenv), int ATTR_UNUSED(udp_connect),
|
||||
int ATTR_UNUSED(max_reuse_tcp_queries), int ATTR_UNUSED(tcp_reuse_timeout),
|
||||
int ATTR_UNUSED(tcp_auth_query_timeout), const char** ATTR_UNUSED(dist),
|
||||
const char** ATTR_UNUSED(dist_tsig), int ATTR_UNUSED(num_dist))
|
||||
int ATTR_UNUSED(tcp_auth_query_timeout))
|
||||
{
|
||||
struct replay_runtime* runtime = (struct replay_runtime*)base;
|
||||
struct outside_network* outnet = calloc(1,
|
||||
|
||||
@@ -141,6 +141,13 @@ if test -f $done; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# always clear the skip mark file in case something changed in the environment
|
||||
# in between runs
|
||||
if test -f $skip; then
|
||||
echo "minitdir $skip exists; removing."
|
||||
rm $skip
|
||||
fi
|
||||
|
||||
# Copy
|
||||
if test $quiet = 0; then
|
||||
echo "minitdir copy $1 to $dir"
|
||||
|
||||
+31
-6
@@ -160,11 +160,26 @@ read_ssl_line(SSL* ssl, char* buf, size_t len)
|
||||
return 0;
|
||||
}
|
||||
if((r = SSL_read(ssl, buf+n, 1)) <= 0) {
|
||||
if(SSL_get_error(ssl, r) == SSL_ERROR_ZERO_RETURN) {
|
||||
int e = SSL_get_error(ssl, r);
|
||||
if(e == SSL_ERROR_ZERO_RETURN) {
|
||||
/* EOF */
|
||||
break;
|
||||
} else if(e == SSL_ERROR_WANT_READ) {
|
||||
continue;
|
||||
} else if(e == SSL_ERROR_WANT_WRITE) {
|
||||
continue;
|
||||
} else if(e == SSL_ERROR_SYSCALL) {
|
||||
if(verb) printf("could not SSL_read %s\n",
|
||||
strerror(errno));
|
||||
} else if(e == SSL_ERROR_SSL) {
|
||||
int er = ERR_peek_error();
|
||||
if(er)
|
||||
printf("could not SSL_read: %s\n",
|
||||
ERR_reason_error_string(er));
|
||||
} else {
|
||||
if(verb) printf("could not SSL_read "
|
||||
"(SSL_get_error %d)\n", e);
|
||||
}
|
||||
if(verb) printf("could not SSL_read\n");
|
||||
return 0;
|
||||
}
|
||||
if(endnl && buf[n] == '\n') {
|
||||
@@ -222,7 +237,8 @@ read_http_headers(SSL* ssl, char* file, size_t flen, char* host, size_t hlen,
|
||||
if(verb>=2) printf("read: %s\n", buf);
|
||||
if(buf[0] == 0) {
|
||||
int e = ERR_peek_error();
|
||||
printf("error string: %s\n", ERR_reason_error_string(e));
|
||||
if(e)
|
||||
printf("error string: %s\n", ERR_reason_error_string(e));
|
||||
return 1;
|
||||
}
|
||||
if(!process_one_header(buf, file, flen, host, hlen, vs))
|
||||
@@ -246,7 +262,8 @@ setup_ctx(char* key, char* cert)
|
||||
#endif
|
||||
if(!SSL_CTX_use_certificate_chain_file(ctx, cert)) {
|
||||
int e = ERR_peek_error();
|
||||
printf("error string: %s\n", ERR_reason_error_string(e));
|
||||
if(e)
|
||||
printf("error string: %s\n", ERR_reason_error_string(e));
|
||||
print_exit("cannot read cert");
|
||||
}
|
||||
if(!SSL_CTX_use_PrivateKey_file(ctx, key, SSL_FILETYPE_PEM))
|
||||
@@ -673,12 +690,20 @@ int main(int argc, char* argv[])
|
||||
#else
|
||||
OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS
|
||||
| OPENSSL_INIT_ADD_ALL_DIGESTS
|
||||
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
|
||||
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS
|
||||
# if defined(OPENSSL_INIT_NO_LOAD_CONFIG) && defined(UB_ON_WINDOWS)
|
||||
| OPENSSL_INIT_NO_LOAD_CONFIG
|
||||
# endif
|
||||
, NULL);
|
||||
#endif
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL)
|
||||
(void)SSL_library_init();
|
||||
#else
|
||||
(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL);
|
||||
(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS
|
||||
# if defined(OPENSSL_INIT_NO_LOAD_CONFIG) && defined(UB_ON_WINDOWS)
|
||||
| OPENSSL_INIT_NO_LOAD_CONFIG
|
||||
# endif
|
||||
, NULL);
|
||||
#endif
|
||||
|
||||
do_service(addr, port, key, cert);
|
||||
|
||||
+12
-2
@@ -59,12 +59,16 @@ static void usage(char* argv[])
|
||||
/** read hex input */
|
||||
static void read_input(sldns_buffer* pkt, FILE* in)
|
||||
{
|
||||
char buf[102400];
|
||||
/* Buffer for 64Kib packet, in hex, with spaces and comments. */
|
||||
char buf[1024000];
|
||||
char* np = buf;
|
||||
while(fgets(np, (int)sizeof(buf) - (np-buf), in)) {
|
||||
if(buf[0] == ';') /* comment */
|
||||
continue;
|
||||
np = &np[strlen(np)];
|
||||
if((size_t)(np-buf) >= sizeof(buf)-1)
|
||||
fatal_exit("input too large (%lu bytes)",
|
||||
(unsigned long)sizeof(buf));
|
||||
}
|
||||
hex_to_buf(pkt, buf);
|
||||
}
|
||||
@@ -188,10 +192,16 @@ static void analyze(sldns_buffer* pkt)
|
||||
/** main program for pktview */
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
sldns_buffer* pkt = sldns_buffer_new(65553);
|
||||
sldns_buffer* pkt;
|
||||
|
||||
log_init(NULL, 0, NULL);
|
||||
log_ident_set("pktview");
|
||||
|
||||
if(argc != 1) {
|
||||
usage(argv);
|
||||
}
|
||||
|
||||
pkt = sldns_buffer_new(65553);
|
||||
if(!pkt) fatal_exit("out of memory");
|
||||
|
||||
read_input(pkt, stdin);
|
||||
|
||||
@@ -142,6 +142,10 @@
|
||||
#include "util/netevent.h"
|
||||
#include "testcode/testpkts.h"
|
||||
#include "util/rbtree.h"
|
||||
#ifdef __QNX__
|
||||
/* For struct timeval */
|
||||
#include <sys/time.h>
|
||||
#endif /* __QNX__ */
|
||||
struct replay_answer;
|
||||
struct replay_moment;
|
||||
struct replay_range;
|
||||
|
||||
+10
-2
@@ -652,12 +652,20 @@ int main(int argc, char** argv)
|
||||
#else
|
||||
OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS
|
||||
| OPENSSL_INIT_ADD_ALL_DIGESTS
|
||||
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL);
|
||||
| OPENSSL_INIT_LOAD_CRYPTO_STRINGS
|
||||
# if defined(OPENSSL_INIT_NO_LOAD_CONFIG) && defined(UB_ON_WINDOWS)
|
||||
| OPENSSL_INIT_NO_LOAD_CONFIG
|
||||
# endif
|
||||
, NULL);
|
||||
#endif
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL)
|
||||
(void)SSL_library_init();
|
||||
#else
|
||||
(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL);
|
||||
(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS
|
||||
# if defined(OPENSSL_INIT_NO_LOAD_CONFIG) && defined(UB_ON_WINDOWS)
|
||||
| OPENSSL_INIT_NO_LOAD_CONFIG
|
||||
# endif
|
||||
, NULL);
|
||||
#endif
|
||||
}
|
||||
send_em(svr, pp2_client, udp, usessl, noanswer, onarrival, delay, argc, argv);
|
||||
|
||||
+41
-9
@@ -135,6 +135,8 @@ static void matchline(char* line, struct entry* e)
|
||||
e->match_ttl = 1;
|
||||
} else if(str_keyword(&parse, "DO")) {
|
||||
e->match_do = 1;
|
||||
} else if(str_keyword(&parse, "CO")) {
|
||||
e->match_co = 1;
|
||||
} else if(str_keyword(&parse, "noedns")) {
|
||||
e->match_noedns = 1;
|
||||
} else if(str_keyword(&parse, "ednsdata")) {
|
||||
@@ -178,7 +180,7 @@ static void matchline(char* line, struct entry* e)
|
||||
|
||||
/** parse REPLY line */
|
||||
static void replyline(char* line, uint8_t* reply, size_t reply_len,
|
||||
int* do_flag)
|
||||
int* do_flag, int* co_flag)
|
||||
{
|
||||
char* parse = line;
|
||||
if(reply_len < LDNS_HEADER_SIZE) error("packet too short for header");
|
||||
@@ -236,6 +238,8 @@ static void replyline(char* line, uint8_t* reply, size_t reply_len,
|
||||
LDNS_AD_SET(reply);
|
||||
} else if(str_keyword(&parse, "DO")) {
|
||||
*do_flag = 1;
|
||||
} else if(str_keyword(&parse, "CO")) {
|
||||
*co_flag = 1;
|
||||
} else {
|
||||
error("could not parse REPLY: '%s'", parse);
|
||||
}
|
||||
@@ -289,6 +293,7 @@ static struct entry* new_entry(void)
|
||||
e->match_all_noedns = 0;
|
||||
e->match_ttl = 0;
|
||||
e->match_do = 0;
|
||||
e->match_co = 0;
|
||||
e->match_noedns = 0;
|
||||
e->match_serial = 0;
|
||||
e->ixfr_soa_serial = 0;
|
||||
@@ -521,15 +526,17 @@ static void add_rr(char* rrstr, uint8_t* pktbuf, size_t pktsize,
|
||||
|
||||
/* add EDNS 4096 opt record */
|
||||
static void
|
||||
add_edns(uint8_t* pktbuf, size_t pktsize, int do_flag, uint8_t *ednsdata,
|
||||
uint16_t ednslen, size_t* pktlen)
|
||||
add_edns(uint8_t* pktbuf, size_t pktsize, int do_flag, int co_flag,
|
||||
uint8_t *ednsdata, uint16_t ednslen, size_t* pktlen)
|
||||
{
|
||||
uint8_t edns[] = {0x00, /* root label */
|
||||
0x00, LDNS_RR_TYPE_OPT, /* type */
|
||||
0x04, 0xD0, /* class is UDPSIZE 1232 */
|
||||
0x00, /* TTL[0] is ext rcode */
|
||||
0x00, /* TTL[1] is edns version */
|
||||
(uint8_t)(do_flag?0x80:0x00), 0x00, /* TTL[2-3] is edns flags, DO */
|
||||
(uint8_t)(do_flag?0x80:0x00)
|
||||
| (uint8_t)(co_flag?0x40:0x00)
|
||||
, 0x00, /* TTL[2-3] is edns flags, DO */
|
||||
(uint8_t)((ednslen >> 8) & 0xff),
|
||||
(uint8_t)(ednslen & 0xff), /* rdatalength */
|
||||
};
|
||||
@@ -561,6 +568,7 @@ read_entry(FILE* in, const char* name, struct sldns_file_parse_state* pstate,
|
||||
uint8_t pktbuf[MAX_PACKETLEN];
|
||||
size_t pktlen = LDNS_HEADER_SIZE;
|
||||
int do_flag = 0; /* DO flag in EDNS */
|
||||
int co_flag = 0; /* CO flag in EDNS */
|
||||
memset(pktbuf, 0, pktlen); /* ID = 0, FLAGS="", and rr counts 0 */
|
||||
|
||||
while(fgets(line, (int)sizeof(line), in) != NULL) {
|
||||
@@ -598,7 +606,7 @@ read_entry(FILE* in, const char* name, struct sldns_file_parse_state* pstate,
|
||||
if(str_keyword(&parse, "MATCH")) {
|
||||
matchline(parse, current);
|
||||
} else if(str_keyword(&parse, "REPLY")) {
|
||||
replyline(parse, pktbuf, pktlen, &do_flag);
|
||||
replyline(parse, pktbuf, pktlen, &do_flag, &co_flag);
|
||||
} else if(str_keyword(&parse, "ADJUST")) {
|
||||
adjustline(parse, current, cur_reply);
|
||||
} else if(str_keyword(&parse, "EXTRA_PACKET")) {
|
||||
@@ -654,15 +662,16 @@ read_entry(FILE* in, const char* name, struct sldns_file_parse_state* pstate,
|
||||
if(hex_ednsdata_buffer)
|
||||
sldns_buffer_free(hex_ednsdata_buffer);
|
||||
if(pktlen != 0) {
|
||||
if(do_flag || cur_reply->raw_ednsdata) {
|
||||
if(do_flag || co_flag
|
||||
|| cur_reply->raw_ednsdata) {
|
||||
if(cur_reply->raw_ednsdata &&
|
||||
sldns_buffer_limit(cur_reply->raw_ednsdata))
|
||||
add_edns(pktbuf, sizeof(pktbuf), do_flag,
|
||||
add_edns(pktbuf, sizeof(pktbuf), do_flag, co_flag,
|
||||
sldns_buffer_begin(cur_reply->raw_ednsdata),
|
||||
(uint16_t)sldns_buffer_limit(cur_reply->raw_ednsdata),
|
||||
&pktlen);
|
||||
else
|
||||
add_edns(pktbuf, sizeof(pktbuf), do_flag,
|
||||
add_edns(pktbuf, sizeof(pktbuf), do_flag, co_flag,
|
||||
NULL, 0, &pktlen);
|
||||
}
|
||||
cur_reply->reply_pkt = memdup(pktbuf, pktlen);
|
||||
@@ -909,6 +918,22 @@ get_do_flag(uint8_t* pkt, size_t len)
|
||||
return (int)(edns_bits&LDNS_EDNS_MASK_DO_BIT);
|
||||
}
|
||||
|
||||
/** return true if the CO flag is set */
|
||||
static int
|
||||
get_co_flag(uint8_t* pkt, size_t len)
|
||||
{
|
||||
uint16_t edns_bits;
|
||||
uint8_t* walk = pkt;
|
||||
size_t walk_len = len;
|
||||
if(!pkt_find_edns_opt(&walk, &walk_len)) {
|
||||
return 0;
|
||||
}
|
||||
if(walk_len < 6)
|
||||
return 0; /* malformed */
|
||||
edns_bits = sldns_read_uint16(walk+4);
|
||||
return (int)(edns_bits&LDNS_EDNS_MASK_CO_BIT);
|
||||
}
|
||||
|
||||
/** Snips the specified EDNS option out of the OPT record and puts it in the
|
||||
* provided buffer. The buffer should be able to hold any opt data ie 65535.
|
||||
* Returns the length of the option written,
|
||||
@@ -1654,6 +1679,10 @@ find_match(struct entry* entries, uint8_t* query_pkt, size_t len,
|
||||
verbose(3, "no DO bit set\n");
|
||||
continue;
|
||||
}
|
||||
if(p->match_co && !get_co_flag(query_pkt, len)) {
|
||||
verbose(3, "no CO bit set\n");
|
||||
continue;
|
||||
}
|
||||
if(p->match_noedns && get_has_edns(query_pkt, len)) {
|
||||
verbose(3, "bad; EDNS OPT present\n");
|
||||
continue;
|
||||
@@ -1745,11 +1774,14 @@ adjust_packet(struct entry* match, uint8_t** answer_pkt, size_t *answer_len,
|
||||
memmove(res+LDNS_HEADER_SIZE+dlen+4,
|
||||
orig+LDNS_HEADER_SIZE+olen+4,
|
||||
reslen-(LDNS_HEADER_SIZE+dlen+4));
|
||||
} else if(origlen == 0) {
|
||||
res = NULL;
|
||||
reslen = 0;
|
||||
} else {
|
||||
res = memdup(orig, origlen);
|
||||
reslen = origlen;
|
||||
}
|
||||
if(!res) {
|
||||
if(!res && reslen > 0) {
|
||||
verbose(1, "out of memory; send without adjust\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -218,6 +218,8 @@ struct entry {
|
||||
uint8_t match_ttl;
|
||||
/** match DO bit */
|
||||
uint8_t match_do;
|
||||
/** match CO bit */
|
||||
uint8_t match_co;
|
||||
/** match absence of EDNS OPT record in query */
|
||||
uint8_t match_noedns;
|
||||
/** match edns data field given in hex */
|
||||
|
||||
@@ -207,7 +207,11 @@ rr_test_file(const char* input, const char* check)
|
||||
#define xstr(s) str(s)
|
||||
#define str(s) #s
|
||||
|
||||
#ifndef __QNX__
|
||||
#define SRCDIRSTR xstr(SRCDIR)
|
||||
#else /* !__QNX__ */
|
||||
#define SRCDIRSTR "."
|
||||
#endif /* __QNX__ */
|
||||
|
||||
/** read rrs to and from string, to and from wireformat */
|
||||
static void
|
||||
|
||||
+3
-4
@@ -283,7 +283,7 @@ net_test(void)
|
||||
unit_assert(strcmp(astr, "1.2.3.0") == 0);
|
||||
unit_assert(ntohs(((struct sockaddr_in*)&a)->sin_port)==53);
|
||||
|
||||
res = netblockstrtoaddr("2001:DB8:33:44::/64", 53,
|
||||
res = netblockstrtoaddr("2001:db8:33:44::/64", 53,
|
||||
&a, &alen, &net);
|
||||
unit_assert(res!=0 && net == 64);
|
||||
addr_to_str(&a, alen, astr, sizeof(astr));
|
||||
@@ -1092,7 +1092,7 @@ static void edns_ede_encode_notxt_fit_test( struct query_info* qinfo,
|
||||
{
|
||||
struct edns_data edns;
|
||||
sldns_buffer* pkt;
|
||||
uint16_t edns_field_size, ede_txt_size;
|
||||
size_t edns_field_size, ede_txt_size;
|
||||
int found_ede = 0, found_ede_other = 0, found_ede_txt = 0;
|
||||
int found_other_edns = 0;
|
||||
edns_ede_encode_setup(&edns, region);
|
||||
@@ -1123,7 +1123,7 @@ static void edns_ede_encode_no_fit_test( struct query_info* qinfo,
|
||||
{
|
||||
struct edns_data edns;
|
||||
sldns_buffer* pkt;
|
||||
uint16_t edns_field_size, ede_size, ede_txt_size;
|
||||
size_t edns_field_size, ede_size, ede_txt_size;
|
||||
int found_ede = 0, found_ede_other = 0, found_ede_txt = 0;
|
||||
int found_other_edns = 0;
|
||||
edns_ede_encode_setup(&edns, region);
|
||||
@@ -1362,7 +1362,6 @@ main(int argc, char* argv[])
|
||||
#ifdef HAVE_NGTCP2
|
||||
doq_test();
|
||||
#endif /* HAVE_NGTCP2 */
|
||||
tsig_test();
|
||||
if(log_get_lock()) {
|
||||
lock_basic_destroy((lock_basic_type*)log_get_lock());
|
||||
}
|
||||
|
||||
@@ -88,7 +88,5 @@ void tcpreuse_test(void);
|
||||
void doq_test(void);
|
||||
/** unit test for infra cache functions */
|
||||
void infra_test(void);
|
||||
/** unit test for tsig functions */
|
||||
void tsig_test(void);
|
||||
|
||||
#endif /* TESTCODE_UNITMAIN_H */
|
||||
|
||||
@@ -498,7 +498,11 @@ testfromdrillfile(sldns_buffer* pkt, struct alloc_cache* alloc,
|
||||
#define xstr(s) str(s)
|
||||
#define str(s) #s
|
||||
|
||||
#ifndef __QNX__
|
||||
#define SRCDIRSTR xstr(SRCDIR)
|
||||
#else /* !__QNX__ */
|
||||
#define SRCDIRSTR "."
|
||||
#endif /* __QNX__ */
|
||||
|
||||
void msgparse_test(void)
|
||||
{
|
||||
|
||||
-1437
File diff suppressed because it is too large
Load Diff
@@ -513,8 +513,11 @@ nsec3_hash_test(const char* fname)
|
||||
#define xstr(s) str(s)
|
||||
#define str(s) #s
|
||||
|
||||
#ifndef __QNX__
|
||||
#define SRCDIRSTR xstr(SRCDIR)
|
||||
|
||||
#else /* !__QNX__ */
|
||||
#define SRCDIRSTR "."
|
||||
#endif /* __QNX__ */
|
||||
#if defined(HAVE_SSL) && defined(USE_SHA1)
|
||||
/* Detect if openssl is configured to disable RSASHA1 signatures,
|
||||
* with the rh-allow-sha1-signatures disabled. */
|
||||
|
||||
@@ -50,7 +50,11 @@
|
||||
|
||||
#define xstr(s) str(s)
|
||||
#define str(s) #s
|
||||
#ifndef __QNX__
|
||||
#define SRCDIRSTR xstr(SRCDIR)
|
||||
#else /* !__QNX__ */
|
||||
#define SRCDIRSTR "."
|
||||
#endif /* __QNX__ */
|
||||
|
||||
/** Add zone from file for testing */
|
||||
struct auth_zone* authtest_addzone(struct auth_zones* az, const char* name,
|
||||
|
||||
Vendored
+1
-1
@@ -24,7 +24,7 @@ server:
|
||||
# specify every interface on a new 'interface:' labelled line.
|
||||
interface: 192.0.2.153
|
||||
interface: 192.0.2.154
|
||||
interface: 2001:DB8::5
|
||||
interface: 2001:db8::5
|
||||
|
||||
# port to answer queries from
|
||||
port: 53
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ server:
|
||||
# specify every interface on a new 'interface:' labelled line.
|
||||
interface: 192.0.2.153
|
||||
interface: 192.0.2.154
|
||||
interface: 2001:DB8::5
|
||||
interface: 2001:db8::5
|
||||
interface: 0.0.0.0@5353
|
||||
|
||||
# config
|
||||
|
||||
Vendored
+341
@@ -0,0 +1,341 @@
|
||||
; config options
|
||||
server:
|
||||
target-fetch-policy: "0 0 0 0 0"
|
||||
access-control: 1.2.3.0/24 allow
|
||||
|
||||
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:
|
||||
master: 1.2.3.44
|
||||
## this is as a hostname, to test the hostname lookup.
|
||||
allow-notify: svr.example.org
|
||||
## url for http fetch
|
||||
## url:
|
||||
## queries from downstream clients get authoritative answers.
|
||||
## for-downstream: yes
|
||||
for-downstream: yes
|
||||
## 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
|
||||
|
||||
## 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. 3600 IN SOA ns.example.com. hostmaster.example.com. 1 3600 900 86400 3600
|
||||
TEMPFILE_END
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
|
||||
CONFIG_END
|
||||
|
||||
SCENARIO_BEGIN Test authority zone with lookup for a NOTIFY
|
||||
; The allow-notify is specified as a hostname.
|
||||
|
||||
; 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
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode subdomain
|
||||
ADJUST copy_id copy_query
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
org. IN NS
|
||||
SECTION AUTHORITY
|
||||
org. IN NS ns.org.
|
||||
SECTION ADDITIONAL
|
||||
ns.org. IN A 1.2.3.45
|
||||
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.org
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 1.2.3.45
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
org. IN NS
|
||||
SECTION ANSWER
|
||||
org. IN NS ns.org.
|
||||
SECTION ADDITIONAL
|
||||
ns.org. IN A 1.2.3.45
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode subdomain
|
||||
ADJUST copy_id copy_query
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.org. IN NS
|
||||
SECTION AUTHORITY
|
||||
example.org. IN NS ns.example.org.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.org. IN A 1.2.3.46
|
||||
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
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN SOA
|
||||
SECTION ANSWER
|
||||
; serial, refresh, retry, expire, minimum
|
||||
example.com. IN SOA ns.example.com. hostmaster.example.com. 2 3600 900 86400 3600
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOTIMPL
|
||||
SECTION QUESTION
|
||||
example.com. IN IXFR
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN AXFR
|
||||
SECTION ANSWER
|
||||
example.com. IN SOA ns.example.com. hostmaster.example.com. 2 3600 900 86400 3600
|
||||
example.com. IN NS ns.example.net.
|
||||
EXTRA_PACKET
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN AXFR
|
||||
SECTION ANSWER
|
||||
www.example.com. IN A 1.2.3.4
|
||||
example.com. IN SOA ns.example.com. hostmaster.example.com. 2 3600 900 86400 3600
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; ns.example.org.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 1.2.3.46
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
example.org. IN NS
|
||||
SECTION ANSWER
|
||||
example.org. IN NS ns.example.org.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.org. IN A 1.2.3.46
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
svr.example.org. IN A
|
||||
SECTION ANSWER
|
||||
svr.example.org. IN A 1.2.3.47
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
svr.example.org. IN AAAA
|
||||
SECTION AUTHORITY
|
||||
example.org. IN SOA ns.example.com. hostmaster.example.com. 2 3600 900 86400 3600
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; lookups for notify hostnames.
|
||||
STEP 1 TIME_PASSES ELAPSE 0
|
||||
|
||||
; now the query
|
||||
STEP 2 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 AA RD RA NXDOMAIN
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION AUTHORITY
|
||||
example.com. 3600 IN SOA ns.example.com. hostmaster.example.com. 1 3600 900 86400 3600
|
||||
ENTRY_END
|
||||
|
||||
; NOTIFY example.com
|
||||
STEP 30 QUERY ADDRESS 1.2.3.47
|
||||
ENTRY_BEGIN
|
||||
REPLY NOTIFY
|
||||
SECTION QUESTION
|
||||
example.com. IN SOA
|
||||
ENTRY_END
|
||||
; notify reply
|
||||
STEP 40 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RA NOTIFY NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN SOA
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
|
||||
STEP 50 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
; recursion happens here.
|
||||
STEP 60 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR AA RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; the zonefile was updated with new contents
|
||||
STEP 70 CHECK_TEMPFILE example.com
|
||||
FILE_BEGIN
|
||||
example.com. 3600 IN SOA ns.example.com. hostmaster.example.com. 2 3600 900 86400 3600
|
||||
example.com. 3600 IN NS ns.example.net.
|
||||
www.example.com. 3600 IN A 1.2.3.4
|
||||
FILE_END
|
||||
|
||||
SCENARIO_END
|
||||
-16
@@ -1,16 +0,0 @@
|
||||
BaseName: auth_tsig
|
||||
Version: 1.0
|
||||
Description: Perform AXFR with TSIG for authority zone.
|
||||
CreationDate: Fri 12 Sep 09:35:40 CEST 2025
|
||||
Maintainer: dr. W.C.A. Wijngaards
|
||||
Category:
|
||||
Component:
|
||||
CmdDepends:
|
||||
Depends:
|
||||
Help:
|
||||
Pre: auth_tsig.pre
|
||||
Post: auth_tsig.post
|
||||
Test: auth_tsig.test
|
||||
AuxFiles:
|
||||
Passed:
|
||||
Failure:
|
||||
-23
@@ -1,23 +0,0 @@
|
||||
server:
|
||||
logfile: "/dev/stderr"
|
||||
xfrdfile: xfrd.state
|
||||
username: ""
|
||||
chroot: ""
|
||||
zonesdir: ""
|
||||
pidfile: "nsd.pid"
|
||||
zonelistfile: "zone.list"
|
||||
verbosity: 5
|
||||
port: @NSD_PORT@
|
||||
interface: 127.0.0.1@@NSD_PORT@
|
||||
|
||||
key:
|
||||
name: "test.key"
|
||||
algorithm: sha256
|
||||
secret: "K2tf3TRjvQkVCmJF3/Z9vA=="
|
||||
|
||||
zone:
|
||||
name: "example.com"
|
||||
zonefile: "example.com.zone"
|
||||
provide-xfr: 0.0.0.0/0 test.key
|
||||
provide-xfr: ::0/0 test.key
|
||||
notify: 127.0.0.1@@UNBOUND_PORT@ test.key
|
||||
-14
@@ -1,14 +0,0 @@
|
||||
# #-- auth_tsig.post --#
|
||||
# source the master var file when it's there
|
||||
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
|
||||
# source the test var file when it's there
|
||||
[ -f .tpkg.var.test ] && source .tpkg.var.test
|
||||
#
|
||||
# do your teardown here
|
||||
. ../common.sh
|
||||
kill_pid $NSD_PID
|
||||
kill_pid $UNBOUND_PID
|
||||
echo "nsd.log"
|
||||
cat nsd.log
|
||||
echo "unbound.log"
|
||||
cat unbound.log
|
||||
-59
@@ -1,59 +0,0 @@
|
||||
# #-- auth_tsig.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
|
||||
#skip_test "Skip test due to no UDP service for SOA query"
|
||||
PRE="../.."
|
||||
if test -n "$NSD"; then
|
||||
:
|
||||
else
|
||||
if `which nsd >/dev/null 2>&1`; then
|
||||
NSD="nsd"
|
||||
else
|
||||
if test -f $PRE/../nsd/nsd; then
|
||||
NSD="$PRE/../nsd/nsd"
|
||||
else
|
||||
skip_test "need nsd"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
echo "NSD=$NSD"
|
||||
|
||||
if test -f $PRE/unbound_do_valgrind_in_test; then
|
||||
do_valgrind=yes
|
||||
else
|
||||
do_valgrind=no
|
||||
fi
|
||||
VALGRIND_FLAGS="--leak-check=full --show-leak-kinds=all"
|
||||
|
||||
get_random_port 2
|
||||
UNBOUND_PORT=$RND_PORT
|
||||
NSD_PORT=$(($RND_PORT + 1))
|
||||
echo "UNBOUND_PORT=$UNBOUND_PORT" >> .tpkg.var.test
|
||||
echo "NSD_PORT=$NSD_PORT" >> .tpkg.var.test
|
||||
|
||||
# make config file
|
||||
sed -e 's/@UNBOUND_PORT\@/'$UNBOUND_PORT'/' -e 's/@NSD_PORT\@/'$NSD_PORT'/' < auth_tsig.ub.conf > ub.conf
|
||||
sed -e 's/@UNBOUND_PORT\@/'$UNBOUND_PORT'/' -e 's/@NSD_PORT\@/'$NSD_PORT'/' < auth_tsig.nsd.conf > nsd.conf
|
||||
|
||||
# start nsd
|
||||
$NSD -d -c nsd.conf >nsd.log 2>&1 &
|
||||
NSD_PID=$!
|
||||
echo "NSD_PID=$NSD_PID" >> .tpkg.var.test
|
||||
|
||||
# start unbound in the background
|
||||
if test $do_valgrind = "yes"; then
|
||||
valgrind $VALGRIND_FLAGS $PRE/unbound -d -c ub.conf >unbound.log 2>&1 &
|
||||
UNBOUND_PID=$!
|
||||
else
|
||||
$PRE/unbound -d -c ub.conf >unbound.log 2>&1 &
|
||||
UNBOUND_PID=$!
|
||||
fi
|
||||
echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test
|
||||
|
||||
cat .tpkg.var.test
|
||||
wait_nsd_up nsd.log
|
||||
wait_unbound_up unbound.log
|
||||
-108
@@ -1,108 +0,0 @@
|
||||
# #-- auth_tsig.test --#
|
||||
# source the master var file when it's there
|
||||
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
|
||||
# use .tpkg.var.test for in test variable passing
|
||||
[ -f .tpkg.var.test ] && source .tpkg.var.test
|
||||
|
||||
PRE="../.."
|
||||
# do the test
|
||||
echo "> dig www.example.com."
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT www.example.com. | tee outfile
|
||||
if grep SERVFAIL outfile; then
|
||||
echo "> try again"
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT www.example.com. | tee outfile
|
||||
fi
|
||||
if grep SERVFAIL outfile; then
|
||||
echo "> try again"
|
||||
sleep 1
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT www.example.com. | tee outfile
|
||||
fi
|
||||
if grep SERVFAIL outfile; then
|
||||
echo "> try again"
|
||||
sleep 1
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT www.example.com. | tee outfile
|
||||
fi
|
||||
if grep SERVFAIL outfile; then
|
||||
echo "> try again"
|
||||
sleep 1
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT www.example.com. | tee outfile
|
||||
fi
|
||||
if grep SERVFAIL outfile; then
|
||||
echo "> try again"
|
||||
sleep 10
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT www.example.com. | tee outfile
|
||||
fi
|
||||
if grep SERVFAIL outfile; then
|
||||
echo "> try again"
|
||||
sleep 10
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT www.example.com. | tee outfile
|
||||
fi
|
||||
echo "> check answer"
|
||||
if grep "1.2.3.4" outfile; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "Not OK"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# update the zonefile.
|
||||
echo "www2.example.com. IN A 1.2.3.5" >> example.com.zone
|
||||
mv example.com.zone tmp.zone
|
||||
sed -e 's/2024082400/2024082401/' <tmp.zone >example.com.zone
|
||||
echo ""
|
||||
echo "new example.com.zone:"
|
||||
cat example.com.zone
|
||||
echo ""
|
||||
|
||||
# NSD reloads the zone file,
|
||||
# sends notify to unbound, with TSIG.
|
||||
# unbound replies to the notify, with TSIG.
|
||||
# unbound fetches SOA record, with TSIG.
|
||||
# unbound fetches zone transfer, with TSIG.
|
||||
kill -1 `cat nsd.pid`
|
||||
|
||||
# test if the zone has updated.
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT www2.example.com. | tee outfile
|
||||
if grep NXDOMAIN outfile; then
|
||||
echo "> try again"
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT www2.example.com. | tee outfile
|
||||
fi
|
||||
if grep NXDOMAIN outfile; then
|
||||
echo "> try again"
|
||||
sleep 1
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT www2.example.com. | tee outfile
|
||||
fi
|
||||
if grep NXDOMAIN outfile; then
|
||||
echo "> try again"
|
||||
sleep 1
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT www2.example.com. | tee outfile
|
||||
fi
|
||||
if grep NXDOMAIN outfile; then
|
||||
echo "> try again"
|
||||
sleep 1
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT www2.example.com. | tee outfile
|
||||
fi
|
||||
if grep NXDOMAIN outfile; then
|
||||
echo "> try again"
|
||||
sleep 10
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT www2.example.com. | tee outfile
|
||||
fi
|
||||
if grep NXDOMAIN outfile; then
|
||||
echo "> try again"
|
||||
sleep 10
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT www2.example.com. | tee outfile
|
||||
fi
|
||||
echo "> check answer"
|
||||
if grep "1.2.3.5" outfile; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "Not OK"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "zonefile: unbound-example.com.zone"
|
||||
cat unbound-example.com.zone
|
||||
echo ""
|
||||
|
||||
exit 0
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user