mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-10-01 06:04:55 +02:00
Compare commits
25
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c66c86e95a | ||
|
|
b2590c2022 | ||
|
|
286494366c | ||
|
|
53724c9e7b | ||
|
|
9a01a32176 | ||
|
|
08e4560065 | ||
|
|
86d4414a22 | ||
|
|
1f6e67e653 | ||
|
|
b96d80a5d3 | ||
|
|
0b42d5ba13 | ||
|
|
efc0c1e990 | ||
|
|
b0b8a3f144 | ||
|
|
172e4a9edb | ||
|
|
2c5e96f86c | ||
|
|
d3902c0e70 | ||
|
|
35e3dcb701 | ||
|
|
415a83e9d5 | ||
|
|
19751ec179 | ||
|
|
6468917fb8 | ||
|
|
747ce6ba47 | ||
|
|
831a805cd4 | ||
|
|
a00cac5094 | ||
|
|
705d180096 | ||
|
|
ece48de2bc | ||
|
|
90c2ca4c55 |
@@ -173,7 +173,7 @@ jobs:
|
||||
cross_platform_config: "--enable-debug --disable-flto --with-libevent --disable-static"
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: false
|
||||
persist-credentials: false
|
||||
@@ -189,8 +189,6 @@ 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"'
|
||||
@@ -213,8 +211,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 $MINJ
|
||||
make $MINJ build_libs
|
||||
#make
|
||||
make build_libs
|
||||
mv Makefile Makefile.orig
|
||||
# fixup \\ in the installtop to /.
|
||||
echo "fixup INSTALLTOP"
|
||||
@@ -246,7 +244,7 @@ jobs:
|
||||
mv xmlwf/Makefile xmlwf/Makefile.orig
|
||||
sed -e 's/SHELL/SHELLZZ/g' < xmlwf/Makefile.orig > xmlwf/Makefile
|
||||
echo "make"
|
||||
make $MINJ
|
||||
make
|
||||
echo "make install"
|
||||
make install
|
||||
cd ..
|
||||
@@ -254,7 +252,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 $MINJ
|
||||
make
|
||||
# specific test output
|
||||
#make testbound.exe; ./testbound.exe -s
|
||||
#make testbound; ./testbound.exe -p testdata/acl.rpl -o -vvvv
|
||||
@@ -349,7 +347,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@v1.0.0
|
||||
uses: cross-platform-actions/action@v0.25.0
|
||||
env:
|
||||
CROSS_PLATFORM_OS: ${{ matrix.cross_platform_os }}
|
||||
with:
|
||||
|
||||
@@ -12,7 +12,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: configure
|
||||
|
||||
+3
-2
@@ -187,9 +187,9 @@ unittcpreuse.lo unitdoq.lo unitinfra.lo
|
||||
UNITTEST_OBJ_LINK=$(UNITTEST_OBJ) worker_cb.lo $(COMMON_OBJ) $(SLDNS_OBJ) \
|
||||
$(COMPAT_OBJ)
|
||||
DAEMON_SRC=daemon/acl_list.c daemon/cachedump.c daemon/daemon.c \
|
||||
daemon/remote.c daemon/stats.c daemon/unbound.c daemon/worker.c @WIN_DAEMON_SRC@
|
||||
daemon/remote.c daemon/stats.c daemon/metrics.c daemon/unbound.c daemon/worker.c @WIN_DAEMON_SRC@
|
||||
DAEMON_OBJ=acl_list.lo cachedump.lo daemon.lo \
|
||||
shm_main.lo remote.lo stats.lo unbound.lo \
|
||||
shm_main.lo remote.lo stats.lo metrics.lo unbound.lo \
|
||||
worker.lo @WIN_DAEMON_OBJ@
|
||||
DAEMON_OBJ_LINK=$(DAEMON_OBJ) $(COMMON_OBJ_ALL_SYMBOLS) $(SLDNS_OBJ) \
|
||||
$(COMPAT_OBJ) @WIN_DAEMON_OBJ_LINK@
|
||||
@@ -721,6 +721,7 @@ depend:
|
||||
ipset.lo ipset.o: $(srcdir)/ipset/ipset.c
|
||||
doqclient.lo doqclient.o: $(srcdir)/testcode/doqclient.c
|
||||
unitdoq.lo unitdoq.o: $(srcdir)/testcode/unitdoq.c
|
||||
metrics.lo metrics.o: $(srcdir)/daemon/metrics.c
|
||||
|
||||
# Dependencies
|
||||
dns.lo dns.o: $(srcdir)/services/cache/dns.c config.h $(srcdir)/iterator/iter_delegpt.h $(srcdir)/util/log.h \
|
||||
|
||||
@@ -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 ATTR_NONSTRING(sigma[16]) = "expand 32-byte k";
|
||||
static const char ATTR_NONSTRING(tau[16]) = "expand 16-byte k";
|
||||
static const char sigma[16] = "expand 32-byte k";
|
||||
static const char tau[16] = "expand 16-byte k";
|
||||
|
||||
static void
|
||||
chacha_keysetup(chacha_ctx *x,const u8 *k,u32 kbits,u32 ATTR_UNUSED(ivbits))
|
||||
|
||||
+4
-1
@@ -42,7 +42,10 @@ static const int year_lengths[2] = {
|
||||
};
|
||||
|
||||
static void
|
||||
timesub(const time_t * const timep, const long offset, struct tm * const tmp)
|
||||
timesub(timep, offset, tmp)
|
||||
const time_t * const timep;
|
||||
const long offset;
|
||||
struct tm * const tmp;
|
||||
{
|
||||
long days;
|
||||
long rem;
|
||||
|
||||
+13
-15
@@ -237,6 +237,9 @@
|
||||
/* Define to 1 if you have the <event.h> header file. */
|
||||
#undef HAVE_EVENT_H
|
||||
|
||||
/* Define to 1 if you have the `evhttp_free' function. */
|
||||
#undef HAVE_EVHTTP_FREE
|
||||
|
||||
/* Define to 1 if you have the `EVP_aes_256_cbc' function. */
|
||||
#undef HAVE_EVP_AES_256_CBC
|
||||
|
||||
@@ -564,27 +567,12 @@
|
||||
/* 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
|
||||
|
||||
@@ -1001,6 +989,9 @@
|
||||
/* define this to enable debug checks. */
|
||||
#undef UNBOUND_DEBUG
|
||||
|
||||
/* Define the default metrics HTTP endpoint port. */
|
||||
#undef UNBOUND_METRICS_PORT
|
||||
|
||||
/* Define to 1 to use cachedb support */
|
||||
#undef USE_CACHEDB
|
||||
|
||||
@@ -1048,6 +1039,10 @@
|
||||
distributions) the use of non-ephemeral ports. */
|
||||
#undef USE_LINUX_IP_LOCAL_PORT_RANGE
|
||||
|
||||
/* Define this to expose Unbound statistics via a prometheus metrics HTTP
|
||||
endpoint. */
|
||||
#undef USE_METRICS
|
||||
|
||||
/* Define if you want to use internal select based events */
|
||||
#undef USE_MINI_EVENT
|
||||
|
||||
@@ -1157,6 +1152,9 @@
|
||||
#endif
|
||||
|
||||
|
||||
/* Define to 1 to prefer TLS crypto settings from the system. */
|
||||
#undef USE_SYSTEM_TLS
|
||||
|
||||
/* Define this to enable server TCP Fast Open. */
|
||||
#undef USE_TCP_FASTOPEN
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.71 for unbound 1.25.2.
|
||||
# Generated by GNU Autoconf 2.71 for unbound 1.24.3.
|
||||
#
|
||||
# Report bugs to <unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues>.
|
||||
#
|
||||
@@ -622,8 +622,8 @@ MAKEFLAGS=
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='unbound'
|
||||
PACKAGE_TARNAME='unbound'
|
||||
PACKAGE_VERSION='1.25.2'
|
||||
PACKAGE_STRING='unbound 1.25.2'
|
||||
PACKAGE_VERSION='1.24.3'
|
||||
PACKAGE_STRING='unbound 1.24.3'
|
||||
PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues'
|
||||
PACKAGE_URL=''
|
||||
|
||||
@@ -669,6 +669,7 @@ SOURCEFILE
|
||||
SOURCEDETERMINE
|
||||
IPSET_OBJ
|
||||
IPSET_SRC
|
||||
SYSTEM_TLS_DEFAULT
|
||||
IPSECMOD_HEADER
|
||||
IPSECMOD_OBJ
|
||||
CACHEDB_OBJ
|
||||
@@ -936,6 +937,7 @@ enable_dnscrypt
|
||||
with_libsodium
|
||||
enable_cachedb
|
||||
enable_ipsecmod
|
||||
enable_system_tls
|
||||
enable_ipset
|
||||
with_libmnl
|
||||
enable_explicit_port_randomisation
|
||||
@@ -1513,7 +1515,7 @@ if test "$ac_init_help" = "long"; then
|
||||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures unbound 1.25.2 to adapt to many kinds of systems.
|
||||
\`configure' configures unbound 1.24.3 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@@ -1579,7 +1581,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of unbound 1.25.2:";;
|
||||
short | recursive ) echo "Configuration of unbound 1.24.3:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@@ -1641,6 +1643,8 @@ Optional Features:
|
||||
storage
|
||||
--enable-ipsecmod Enable ipsecmod module that facilitates
|
||||
opportunistic IPsec
|
||||
--enable-system-tls Enable preference of system configured TLS socket
|
||||
options
|
||||
--enable-ipset enable ipset module
|
||||
--disable-explicit-port-randomisation
|
||||
disable explicit source port randomisation and rely
|
||||
@@ -1832,7 +1836,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
unbound configure 1.25.2
|
||||
unbound configure 1.24.3
|
||||
generated by GNU Autoconf 2.71
|
||||
|
||||
Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
@@ -2489,7 +2493,7 @@ cat >config.log <<_ACEOF
|
||||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by unbound $as_me 1.25.2, which was
|
||||
It was created by unbound $as_me 1.24.3, which was
|
||||
generated by GNU Autoconf 2.71. Invocation command line was
|
||||
|
||||
$ $0$ac_configure_args_raw
|
||||
@@ -3251,13 +3255,13 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
||||
|
||||
UNBOUND_VERSION_MAJOR=1
|
||||
|
||||
UNBOUND_VERSION_MINOR=25
|
||||
UNBOUND_VERSION_MINOR=24
|
||||
|
||||
UNBOUND_VERSION_MICRO=2
|
||||
UNBOUND_VERSION_MICRO=3
|
||||
|
||||
|
||||
LIBUNBOUND_CURRENT=9
|
||||
LIBUNBOUND_REVISION=38
|
||||
LIBUNBOUND_REVISION=36
|
||||
LIBUNBOUND_AGE=1
|
||||
# 1.0.0 had 0:12:0
|
||||
# 1.0.1 had 0:13:0
|
||||
@@ -3360,9 +3364,7 @@ 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
|
||||
# 1.25.2 had 9:38:1
|
||||
# 1.24.3 had 9:36:1
|
||||
|
||||
# Current -- the number of the binary API that we're implementing
|
||||
# Revision -- which iteration of the implementation of the binary
|
||||
@@ -19082,171 +19084,6 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
||||
|
||||
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_fn_c_check_header_compile "$LINENO" "pthread_np.h" "ac_cv_header_pthread_np_h" "$ac_includes_default
|
||||
"
|
||||
if test "x$ac_cv_header_pthread_np_h" = xyes
|
||||
then :
|
||||
printf "%s\n" "#define HAVE_PTHREAD_NP_H 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
BAKCFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS -Werror"
|
||||
# MacOS only has 1 argument, the name.
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether pthread_setname_np has only 1 argument" >&5
|
||||
printf %s "checking whether pthread_setname_np has only 1 argument... " >&6; }
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
$ac_includes_default
|
||||
#include <pthread.h>
|
||||
#ifdef HAVE_PTHREAD_NP_H
|
||||
#include <pthread_np.h>
|
||||
#endif
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
|
||||
(void)pthread_setname_np("");
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"
|
||||
then :
|
||||
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
printf "%s\n" "yes" >&6; }
|
||||
|
||||
printf "%s\n" "#define HAVE_PTHREAD_SETNAME_NP1 1" >>confdefs.h
|
||||
|
||||
|
||||
else $as_nop
|
||||
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
printf "%s\n" "no" >&6; }
|
||||
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
|
||||
# NetBSD has 3 arguments to allow for formatting of the name.
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether pthread_setname_np has 3 arguments" >&5
|
||||
printf %s "checking whether pthread_setname_np has 3 arguments... " >&6; }
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
$ac_includes_default
|
||||
#include <pthread.h>
|
||||
#ifdef HAVE_PTHREAD_NP_H
|
||||
#include <pthread_np.h>
|
||||
#endif
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
|
||||
(void)pthread_setname_np(0, "", NULL);
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"
|
||||
then :
|
||||
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
printf "%s\n" "yes" >&6; }
|
||||
|
||||
printf "%s\n" "#define HAVE_PTHREAD_SETNAME_NP3 1" >>confdefs.h
|
||||
|
||||
|
||||
else $as_nop
|
||||
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
printf "%s\n" "no" >&6; }
|
||||
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
|
||||
# Most OSes have the common 2 arguments, thread and name.
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether pthread_setname_np has the common 2 arguments" >&5
|
||||
printf %s "checking whether pthread_setname_np has the common 2 arguments... " >&6; }
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
$ac_includes_default
|
||||
#include <pthread.h>
|
||||
#ifdef HAVE_PTHREAD_NP_H
|
||||
#include <pthread_np.h>
|
||||
#endif
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
|
||||
(void)pthread_setname_np(0, "");
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"
|
||||
then :
|
||||
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
printf "%s\n" "yes" >&6; }
|
||||
|
||||
printf "%s\n" "#define HAVE_PTHREAD_SETNAME_NP 1" >>confdefs.h
|
||||
|
||||
|
||||
else $as_nop
|
||||
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
printf "%s\n" "no" >&6; }
|
||||
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
|
||||
# FreeBSD/OpenBSD use a slightly different function name.
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether pthread_setname_np exists as pthread_set_name_np instead" >&5
|
||||
printf %s "checking whether pthread_setname_np exists as pthread_set_name_np instead... " >&6; }
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
$ac_includes_default
|
||||
#include <pthread.h>
|
||||
#ifdef HAVE_PTHREAD_NP_H
|
||||
#include <pthread_np.h>
|
||||
#endif
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
|
||||
(void)pthread_set_name_np(0, "");
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"
|
||||
then :
|
||||
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
printf "%s\n" "yes" >&6; }
|
||||
|
||||
printf "%s\n" "#define HAVE_PTHREAD_SET_NAME_NP 1" >>confdefs.h
|
||||
|
||||
|
||||
else $as_nop
|
||||
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
printf "%s\n" "no" >&6; }
|
||||
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
|
||||
CFLAGS="$BAKCFLAGS"
|
||||
fi
|
||||
|
||||
# check solaris thread library
|
||||
|
||||
# Check whether --with-solaris-threads was given.
|
||||
@@ -22332,6 +22169,31 @@ else $as_nop
|
||||
fi
|
||||
printf "%s\n" "#define HAVE_DECL_EVSIGNAL_ASSIGN $ac_have_decl" >>confdefs.h
|
||||
|
||||
# prometheus metrics depend on libevent 2.0 and later, and is therefore
|
||||
# only enabled when the required version is found and used
|
||||
|
||||
for ac_func in evhttp_free
|
||||
do :
|
||||
ac_fn_c_check_func "$LINENO" "evhttp_free" "ac_cv_func_evhttp_free"
|
||||
if test "x$ac_cv_func_evhttp_free" = xyes
|
||||
then :
|
||||
printf "%s\n" "#define HAVE_EVHTTP_FREE 1" >>confdefs.h
|
||||
|
||||
|
||||
printf "%s\n" "#define USE_METRICS /**/" >>confdefs.h
|
||||
|
||||
|
||||
printf "%s\n" "#define UNBOUND_METRICS_PORT 9101" >>confdefs.h
|
||||
|
||||
|
||||
else $as_nop
|
||||
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: disabling prometheus metrics" >&5
|
||||
printf "%s\n" "$as_me: disabling prometheus metrics" >&6;}
|
||||
|
||||
fi
|
||||
|
||||
done
|
||||
PC_LIBEVENT_DEPENDENCY="libevent"
|
||||
|
||||
if test -n "$BAK_LDFLAGS_SET"; then
|
||||
@@ -22341,6 +22203,8 @@ else
|
||||
|
||||
printf "%s\n" "#define USE_MINI_EVENT 1" >>confdefs.h
|
||||
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: Prometheus metrics are disabled with the builtin libevent alternative" >&5
|
||||
printf "%s\n" "$as_me: Prometheus metrics are disabled with the builtin libevent alternative" >&6;}
|
||||
fi
|
||||
|
||||
# check for libexpat
|
||||
@@ -22923,29 +22787,6 @@ printf "%s\n" "no" >&6; }
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
|
||||
|
||||
ac_fn_check_decl "$LINENO" "CLOCK_MONOTONIC
|
||||
" "ac_cv_have_decl_CLOCK_MONOTONIC_________" "$ac_includes_default
|
||||
#ifdef TIME_WITH_SYS_TIME
|
||||
# include <sys/time.h>
|
||||
# include <time.h>
|
||||
#else
|
||||
# ifdef HAVE_SYS_TIME_H
|
||||
# include <sys/time.h>
|
||||
# else
|
||||
# include <time.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
" "$ac_c_undeclared_builtin_options" "CFLAGS"
|
||||
if test "x$ac_cv_have_decl_CLOCK_MONOTONIC_________" = xyes
|
||||
then :
|
||||
|
||||
|
||||
else $as_nop
|
||||
as_fn_error $? "ngtcp2 for QUIC needs at least CLOCK_MONOTONIC on the system" "$LINENO" 5
|
||||
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
# set static linking for uninstalled libraries if requested
|
||||
@@ -25309,6 +25150,26 @@ printf "%s\n" "#define USE_IPSECMOD 1" >>confdefs.h
|
||||
;;
|
||||
esac
|
||||
|
||||
# check for system TLS preference if requested
|
||||
# Check whether --enable-system-tls was given.
|
||||
if test ${enable_system_tls+y}
|
||||
then :
|
||||
enableval=$enable_system_tls;
|
||||
fi
|
||||
|
||||
case "$enable_system_tls" in
|
||||
yes)
|
||||
|
||||
printf "%s\n" "#define USE_SYSTEM_TLS 1" >>confdefs.h
|
||||
|
||||
SYSTEM_TLS_DEFAULT="yes"
|
||||
;;
|
||||
no|*)
|
||||
SYSTEM_TLS_DEFAULT="no"
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
# check for ipset if requested
|
||||
# Check whether --enable-ipset was given.
|
||||
if test ${enable_ipset+y}
|
||||
@@ -25576,7 +25437,7 @@ printf "%s\n" "#define MAXSYSLOGMSGLEN 10240" >>confdefs.h
|
||||
|
||||
|
||||
|
||||
version=1.25.2
|
||||
version=1.24.3
|
||||
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for build time" >&5
|
||||
printf %s "checking for build time... " >&6; }
|
||||
@@ -26106,7 +25967,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
||||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by unbound $as_me 1.25.2, which was
|
||||
This file was extended by unbound $as_me 1.24.3, which was
|
||||
generated by GNU Autoconf 2.71. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@@ -26174,7 +26035,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\
|
||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_config='$ac_cs_config_escaped'
|
||||
ac_cs_version="\\
|
||||
unbound config.status 1.25.2
|
||||
unbound config.status 1.24.3
|
||||
configured by $0, generated by GNU Autoconf 2.71,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
||||
+26
-92
@@ -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],[25])
|
||||
m4_define([VERSION_MICRO],[2])
|
||||
m4_define([VERSION_MINOR],[24])
|
||||
m4_define([VERSION_MICRO],[3])
|
||||
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=38
|
||||
LIBUNBOUND_REVISION=36
|
||||
LIBUNBOUND_AGE=1
|
||||
# 1.0.0 had 0:12:0
|
||||
# 1.0.1 had 0:13:0
|
||||
@@ -122,9 +122,7 @@ 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
|
||||
# 1.25.2 had 9:38:1
|
||||
# 1.24.3 had 9:36:1
|
||||
|
||||
# Current -- the number of the binary API that we're implementing
|
||||
# Revision -- which iteration of the implementation of the binary
|
||||
@@ -733,76 +731,6 @@ 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
|
||||
@@ -1570,6 +1498,14 @@ large outgoing port ranges. ])
|
||||
# include "event2/event.h"
|
||||
#endif
|
||||
])
|
||||
# prometheus metrics depend on libevent 2.0 and later, and is therefore
|
||||
# only enabled when the required version is found and used
|
||||
AC_CHECK_FUNCS([evhttp_free], [
|
||||
AC_DEFINE_UNQUOTED([USE_METRICS], [], [Define this to expose Unbound statistics via a prometheus metrics HTTP endpoint.])
|
||||
AC_DEFINE_UNQUOTED([UNBOUND_METRICS_PORT], [9101], [Define the default metrics HTTP endpoint port.])
|
||||
], [
|
||||
AC_MSG_NOTICE([disabling prometheus metrics])
|
||||
])
|
||||
PC_LIBEVENT_DEPENDENCY="libevent"
|
||||
AC_SUBST(PC_LIBEVENT_DEPENDENCY)
|
||||
if test -n "$BAK_LDFLAGS_SET"; then
|
||||
@@ -1577,6 +1513,7 @@ large outgoing port ranges. ])
|
||||
fi
|
||||
else
|
||||
AC_DEFINE(USE_MINI_EVENT, 1, [Define if you want to use internal select based events])
|
||||
AC_MSG_NOTICE([Prometheus metrics are disabled with the builtin libevent alternative])
|
||||
fi
|
||||
|
||||
# check for libexpat
|
||||
@@ -1736,22 +1673,6 @@ if test x_$withval = x_yes -o x_$withval != x_no; then
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
|
||||
AC_CHECK_DECL([CLOCK_MONOTONIC]
|
||||
, []
|
||||
, [AC_MSG_ERROR([ngtcp2 for QUIC needs at least CLOCK_MONOTONIC on the system])]
|
||||
, [AC_INCLUDES_DEFAULT
|
||||
#ifdef TIME_WITH_SYS_TIME
|
||||
# include <sys/time.h>
|
||||
# include <time.h>
|
||||
#else
|
||||
# ifdef HAVE_SYS_TIME_H
|
||||
# include <sys/time.h>
|
||||
# else
|
||||
# include <time.h>
|
||||
# endif
|
||||
#endif
|
||||
])
|
||||
|
||||
fi
|
||||
|
||||
# set static linking for uninstalled libraries if requested
|
||||
@@ -2169,6 +2090,19 @@ case "$enable_ipsecmod" in
|
||||
;;
|
||||
esac
|
||||
|
||||
# check for system TLS preference if requested
|
||||
AC_ARG_ENABLE(system-tls, AS_HELP_STRING([--enable-system-tls],[Enable preference of system configured TLS socket options]))
|
||||
case "$enable_system_tls" in
|
||||
yes)
|
||||
AC_DEFINE([USE_SYSTEM_TLS], [1], [Define to 1 to prefer TLS crypto settings from the system.])
|
||||
SYSTEM_TLS_DEFAULT="yes"
|
||||
;;
|
||||
no|*)
|
||||
SYSTEM_TLS_DEFAULT="no"
|
||||
;;
|
||||
esac
|
||||
AC_SUBST([SYSTEM_TLS_DEFAULT])
|
||||
|
||||
# check for ipset if requested
|
||||
AC_ARG_ENABLE(ipset, AS_HELP_STRING([--enable-ipset],[enable ipset module]))
|
||||
case "$enable_ipset" in
|
||||
|
||||
+8
-8
@@ -2,7 +2,7 @@
|
||||
# and output prometheus metrics style output.
|
||||
# use these options:
|
||||
# server: extended-statistics: yes
|
||||
# statistics-cumulative: no
|
||||
# statistics-cumulative: yes
|
||||
# statistics-interval: 0
|
||||
# remote-control: control-enable: yes
|
||||
# Can use it like unbound-control stats | awk -f "metrics.awk"
|
||||
@@ -17,7 +17,7 @@ BEGIN {
|
||||
# print the output metrics
|
||||
END {
|
||||
print "# HELP unbound_hits_queries Unbound DNS traffic and cache hits"
|
||||
print "# TYPE unbound_hits_queries gauge"
|
||||
print "# TYPE unbound_hits_queries counter"
|
||||
print "unbound_hits_queries{type=\"total.num.queries\"} " val["total.num.queries"];
|
||||
for (x=0; x<99; x++) {
|
||||
if(val["thread" $x ".num.queries"] != "") {
|
||||
@@ -70,7 +70,7 @@ END {
|
||||
print ""
|
||||
|
||||
print "# HELP unbound_by_type_queries Unbound DNS queries by type"
|
||||
print "# TYPE unbound_by_type_queries gauge"
|
||||
print "# TYPE unbound_by_type_queries counter"
|
||||
for(x in val) {
|
||||
if(x ~ /^num.query.type./) {
|
||||
if(val[x] != "") {
|
||||
@@ -82,7 +82,7 @@ END {
|
||||
print ""
|
||||
|
||||
print "# HELP unbound_by_class_queries Unbound DNS queries by class"
|
||||
print "# TYPE unbound_by_class_queries gauge"
|
||||
print "# TYPE unbound_by_class_queries counter"
|
||||
for(x in val) {
|
||||
if(x ~ /^num.query.class./) {
|
||||
if(val[x] != "") {
|
||||
@@ -94,7 +94,7 @@ END {
|
||||
print ""
|
||||
|
||||
print "# HELP unbound_by_opcode_queries Unbound DNS queries by opcode"
|
||||
print "# TYPE unbound_by_opcode_queries gauge"
|
||||
print "# TYPE unbound_by_opcode_queries counter"
|
||||
for(x in val) {
|
||||
if(x ~ /^num.query.opcode./) {
|
||||
if(val[x] != "") {
|
||||
@@ -106,7 +106,7 @@ END {
|
||||
print ""
|
||||
|
||||
print "# HELP unbound_by_rcode_queries Unbound DNS answers by rcode"
|
||||
print "# TYPE unbound_by_rcode_queries gauge"
|
||||
print "# TYPE unbound_by_rcode_queries counter"
|
||||
for(x in val) {
|
||||
if(x ~ /^num.answer.rcode./) {
|
||||
if(val[x] != "") {
|
||||
@@ -118,7 +118,7 @@ END {
|
||||
print ""
|
||||
|
||||
print "# HELP unbound_by_flags_queries Unbound DNS queries by flags"
|
||||
print "# TYPE unbound_by_flags_queries gauge"
|
||||
print "# TYPE unbound_by_flags_queries counter"
|
||||
for(x in val) {
|
||||
if(x ~ /^num.query.flags./) {
|
||||
if(val[x] != "") {
|
||||
@@ -136,7 +136,7 @@ END {
|
||||
print ""
|
||||
|
||||
print "# HELP unbound_histogram_seconds Unbound DNS histogram of reply time"
|
||||
print "# TYPE unbound_histogram_seconds gauge"
|
||||
print "# TYPE unbound_histogram_seconds counter"
|
||||
print "unbound_histogram_seconds{bucket=\"000000.000000.to.000000.000001\"} " val["histogram.000000.000000.to.000000.000001"];
|
||||
print "unbound_histogram_seconds{bucket=\"000000.000001.to.000000.000002\"} " val["histogram.000000.000001.to.000000.000002"];
|
||||
print "unbound_histogram_seconds{bucket=\"000000.000002.to.000000.000004\"} " val["histogram.000000.000002.to.000000.000004"];
|
||||
|
||||
+60
-44
@@ -69,6 +69,7 @@
|
||||
#include "daemon/daemon.h"
|
||||
#include "daemon/worker.h"
|
||||
#include "daemon/remote.h"
|
||||
#include "daemon/metrics.h"
|
||||
#include "daemon/acl_list.h"
|
||||
#include "util/log.h"
|
||||
#include "util/config_file.h"
|
||||
@@ -79,7 +80,6 @@
|
||||
#include "util/tcp_conn_limit.h"
|
||||
#include "util/edns.h"
|
||||
#include "services/listen_dnsport.h"
|
||||
#include "services/outside_network.h"
|
||||
#include "services/cache/rrset.h"
|
||||
#include "services/cache/infra.h"
|
||||
#include "services/localzone.h"
|
||||
@@ -216,7 +216,7 @@ setup_listen_sslctx(void** ctx, int is_dot, int is_doh,
|
||||
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))) {
|
||||
is_dot, is_doh, cfg->tls_use_system_policy_versions))) {
|
||||
fatal_exit("could not set up listen SSL_CTX");
|
||||
}
|
||||
}
|
||||
@@ -325,28 +325,19 @@ daemon_setup_sslctxs(struct daemon* daemon, struct config_file* cfg)
|
||||
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;
|
||||
}
|
||||
daemon->ssl_service_pem = strdup(cfg->ssl_service_pem);
|
||||
if(!daemon->ssl_service_pem)
|
||||
fatal_exit("could not setup ssl ctx: out of memory");
|
||||
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;
|
||||
}
|
||||
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));
|
||||
}
|
||||
daemon->connect_dot_sslctx = daemon_setup_connect_dot_sslctx(
|
||||
daemon, cfg);
|
||||
@@ -409,18 +400,16 @@ ssl_cert_changed(struct daemon* daemon, struct config_file* cfg)
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -559,10 +548,25 @@ daemon_init(void)
|
||||
if(gettimeofday(&daemon->time_boot, NULL) < 0)
|
||||
log_err("gettimeofday: %s", strerror(errno));
|
||||
daemon->time_last_stat = daemon->time_boot;
|
||||
#ifdef USE_METRICS
|
||||
if(!(daemon->metrics = daemon_metrics_create())) {
|
||||
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;
|
||||
}
|
||||
daemon->metrics_port = -1;
|
||||
#endif /* USE_METRICS */
|
||||
if((daemon->env->auth_zones = auth_zones_create()) == 0) {
|
||||
acl_list_delete(daemon->acl_interface);
|
||||
acl_list_delete(daemon->acl);
|
||||
tcl_list_delete(daemon->tcl);
|
||||
#ifdef USE_METRICS
|
||||
daemon_metrics_delete(daemon->metrics);
|
||||
#endif
|
||||
edns_known_options_delete(daemon->env);
|
||||
free(daemon->env);
|
||||
free(daemon);
|
||||
@@ -573,6 +577,9 @@ daemon_init(void)
|
||||
acl_list_delete(daemon->acl_interface);
|
||||
acl_list_delete(daemon->acl);
|
||||
tcl_list_delete(daemon->tcl);
|
||||
#ifdef USE_METRICS
|
||||
daemon_metrics_delete(daemon->metrics);
|
||||
#endif
|
||||
edns_known_options_delete(daemon->env);
|
||||
free(daemon->env);
|
||||
free(daemon);
|
||||
@@ -698,6 +705,19 @@ daemon_open_shared_ports(struct daemon* daemon)
|
||||
return 0;
|
||||
daemon->rc_port = daemon->cfg->control_port;
|
||||
}
|
||||
#ifdef USE_METRICS
|
||||
if(!daemon->cfg->metrics_enable && daemon->metrics_port != -1) {
|
||||
daemon_metrics_close_ports(daemon->metrics);
|
||||
daemon->metrics_port = -1;
|
||||
}
|
||||
if(daemon->cfg->metrics_enable &&
|
||||
daemon->cfg->metrics_port != daemon->metrics_port) {
|
||||
daemon_metrics_close_ports(daemon->metrics);
|
||||
if(!daemon_metrics_open_ports(daemon->metrics, daemon->cfg))
|
||||
return 0;
|
||||
daemon->metrics_port = daemon->cfg->metrics_port;
|
||||
}
|
||||
#endif /* USE_METRICS */
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -814,10 +834,6 @@ daemon_create_workers(struct daemon* daemon)
|
||||
fatal_exit("out of memory during daemon init");
|
||||
numport = daemon_get_shufport(daemon, shufport);
|
||||
verbose(VERB_ALGO, "total of %d outgoing ports available", numport);
|
||||
if(!(daemon->shared_ports = shared_ports_create(daemon->cfg->out_ifs,
|
||||
daemon->cfg->num_out_ifs, daemon->cfg->do_ip4,
|
||||
daemon->cfg->do_ip6, shufport, numport)))
|
||||
fatal_exit("could not setup shared ports: out of memory");
|
||||
|
||||
#ifdef HAVE_NGTCP2
|
||||
if (cfg_has_quic(daemon->cfg)) {
|
||||
@@ -848,7 +864,10 @@ daemon_create_workers(struct daemon* daemon)
|
||||
#endif
|
||||
}
|
||||
for(i=0; i<daemon->num; i++) {
|
||||
if(!(daemon->workers[i] = worker_create(daemon, i)))
|
||||
if(!(daemon->workers[i] = worker_create(daemon, i,
|
||||
shufport+numport*i/daemon->num,
|
||||
numport*(i+1)/daemon->num - numport*i/daemon->num)))
|
||||
/* the above is not ports/numthr, due to rounding */
|
||||
fatal_exit("could not create worker");
|
||||
}
|
||||
/* create per-worker alloc caches if not reusing existing ones. */
|
||||
@@ -921,14 +940,7 @@ thread_start(void* arg)
|
||||
{
|
||||
struct worker* worker = (struct worker*)arg;
|
||||
int port_num = 0;
|
||||
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 */
|
||||
@@ -1191,6 +1203,9 @@ daemon_cleanup(struct daemon* daemon)
|
||||
auth_zones_cleanup(daemon->env->auth_zones);
|
||||
/* key cache is cleared by module deinit during next daemon_fork() */
|
||||
daemon_remote_clear(daemon->rc);
|
||||
#ifdef USE_METRICS
|
||||
daemon_metrics_detach(daemon->metrics);
|
||||
#endif
|
||||
if(daemon->fast_reload_thread)
|
||||
fast_reload_thread_stop(daemon->fast_reload_thread);
|
||||
if(daemon->fast_reload_printq_list)
|
||||
@@ -1206,8 +1221,6 @@ daemon_cleanup(struct daemon* daemon)
|
||||
if(!daemon->reuse_cache || daemon->need_to_exit)
|
||||
daemon_clear_allocs(daemon);
|
||||
daemon->num = 0;
|
||||
shared_ports_delete(daemon->shared_ports);
|
||||
daemon->shared_ports = NULL;
|
||||
#ifdef USE_DNSTAP
|
||||
dt_delete(daemon->dtenv);
|
||||
daemon->dtenv = NULL;
|
||||
@@ -1235,6 +1248,9 @@ daemon_delete(struct daemon* daemon)
|
||||
modstack_call_destartup(&daemon->mods, daemon->env);
|
||||
modstack_free(&daemon->mods);
|
||||
daemon_remote_delete(daemon->rc);
|
||||
#ifdef USE_METRICS
|
||||
daemon_metrics_delete(daemon->metrics);
|
||||
#endif
|
||||
for(i = 0; i < daemon->num_ports; i++)
|
||||
listening_ports_free(daemon->ports[i]);
|
||||
free(daemon->ports);
|
||||
|
||||
+5
-3
@@ -56,13 +56,13 @@ struct local_zones;
|
||||
struct views;
|
||||
struct ub_randstate;
|
||||
struct daemon_remote;
|
||||
struct daemon_metrics;
|
||||
struct respip_set;
|
||||
struct shm_main_info;
|
||||
struct doq_table;
|
||||
struct cookie_secrets;
|
||||
struct fast_reload_thread;
|
||||
struct fast_reload_printq;
|
||||
struct shared_ports;
|
||||
|
||||
#include "dnstap/dnstap_config.h"
|
||||
#ifdef USE_DNSTAP
|
||||
@@ -98,10 +98,12 @@ struct daemon {
|
||||
int rc_port;
|
||||
/** listening ports for remote control */
|
||||
struct listen_port* rc_ports;
|
||||
/** the shared ports structure, with random ports numbers. */
|
||||
struct shared_ports* shared_ports;
|
||||
/** remote control connections management (for first worker) */
|
||||
struct daemon_remote* rc;
|
||||
/** port number for metrics that has ports opened. */
|
||||
int metrics_port;
|
||||
/** metrics endpoint connections management (for first worker) */
|
||||
struct daemon_metrics* metrics;
|
||||
/** ssl context for listening to dnstcp over ssl */
|
||||
void* listen_dot_sslctx;
|
||||
/** ssl context for connecting to dnstcp over ssl */
|
||||
|
||||
@@ -0,0 +1,877 @@
|
||||
/*
|
||||
* daemon/metrics.c - prometheus metrics endpoint.
|
||||
*
|
||||
* Copyright (c) 2026, NLnet Labs. All rights reserved.
|
||||
*
|
||||
* This software is open source.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of the NLNET LABS nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* The statistics output provides metrics to prometheus.
|
||||
*/
|
||||
#include "config.h"
|
||||
#include "daemon/metrics.h"
|
||||
#include "daemon/daemon.h"
|
||||
#include "daemon/worker.h"
|
||||
#include "daemon/stats.h"
|
||||
#include "util/config_file.h"
|
||||
#include "util/net_help.h"
|
||||
#include "util/ub_event.h"
|
||||
#include "util/timeval_func.h"
|
||||
#include "services/listen_dnsport.h"
|
||||
#include "services/cache/rrset.h"
|
||||
#include "services/rpz.h"
|
||||
#include "sldns/parseutil.h"
|
||||
#include "sldns/wire2str.h"
|
||||
|
||||
/* If there is no metrics enabled, do not add the code. */
|
||||
#ifdef USE_METRICS
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#include <event2/event.h>
|
||||
#include <event2/http.h>
|
||||
#include <event2/buffer.h>
|
||||
|
||||
/** The prefix for the unbound statistics. */
|
||||
#define METRICS_PREFIX "unbound_"
|
||||
|
||||
/** The callback that handles a metrics http request. */
|
||||
static void metrics_http_callback(struct evhttp_request *req, void *p);
|
||||
|
||||
struct daemon_metrics*
|
||||
daemon_metrics_create(void)
|
||||
{
|
||||
struct daemon_metrics* metrics = (struct daemon_metrics*)calloc(
|
||||
sizeof(*metrics), 1);
|
||||
if(!metrics) {
|
||||
log_err("out of memory");
|
||||
return NULL;
|
||||
}
|
||||
return metrics;
|
||||
}
|
||||
|
||||
void
|
||||
daemon_metrics_delete(struct daemon_metrics* metrics)
|
||||
{
|
||||
if(!metrics) return;
|
||||
daemon_metrics_detach(metrics);
|
||||
daemon_metrics_close_ports(metrics);
|
||||
free(metrics);
|
||||
}
|
||||
|
||||
void
|
||||
daemon_metrics_close_ports(struct daemon_metrics* metrics)
|
||||
{
|
||||
struct metrics_acceptlist *h, *nh;
|
||||
if(!metrics) return;
|
||||
|
||||
/* close listen sockets */
|
||||
h = metrics->accept_list;
|
||||
while(h) {
|
||||
nh = h->next;
|
||||
close(h->accept_fd);
|
||||
free(h->ident);
|
||||
free(h);
|
||||
h = nh;
|
||||
}
|
||||
metrics->accept_list = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
daemon_metrics_detach(struct daemon_metrics* metrics)
|
||||
{
|
||||
if(!metrics) return;
|
||||
if (metrics->http_server) {
|
||||
evhttp_free(metrics->http_server);
|
||||
metrics->http_server = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add and open a new metrics port
|
||||
* @param metrics: metrics with result list.
|
||||
* @param cfg: config options.
|
||||
* @param ip: ip str
|
||||
* @param nr: port nr
|
||||
* @param noproto_is_err: if lack of protocol support is an error.
|
||||
* @return false on failure.
|
||||
*/
|
||||
static int
|
||||
metrics_add_open(struct daemon_metrics* metrics, struct config_file* cfg,
|
||||
const char* ip, int nr, int noproto_is_err)
|
||||
{
|
||||
struct addrinfo hints;
|
||||
struct addrinfo* res;
|
||||
struct metrics_acceptlist* hl;
|
||||
int noproto = 0;
|
||||
int fd, r;
|
||||
char port[15];
|
||||
snprintf(port, sizeof(port), "%d", nr);
|
||||
port[sizeof(port)-1]=0;
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
assert(ip);
|
||||
|
||||
if(ip[0] == '/') {
|
||||
/* This looks like a local socket */
|
||||
fd = create_local_accept_sock(ip, &noproto, cfg->use_systemd);
|
||||
/*
|
||||
* Change socket ownership and permissions so users other
|
||||
* than root can access it provided they are in the same
|
||||
* group as the user we run as.
|
||||
*/
|
||||
if(fd != -1) {
|
||||
#ifdef HAVE_CHOWN
|
||||
if(chmod(ip, (mode_t)(S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP)) == -1) {
|
||||
verbose(VERB_QUERY, "cannot chmod metrics socket %s: %s", ip, strerror(errno));
|
||||
}
|
||||
if (cfg->username && cfg->username[0] &&
|
||||
cfg_uid != (uid_t)-1) {
|
||||
if(chown(ip, cfg_uid, cfg_gid) == -1)
|
||||
verbose(VERB_QUERY, "cannot chown metrics socket %u.%u %s: %s",
|
||||
(unsigned)cfg_uid, (unsigned)cfg_gid,
|
||||
ip, strerror(errno));
|
||||
}
|
||||
#else
|
||||
(void)cfg;
|
||||
#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 metrics-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 we had no interface ip name, "default" is what we
|
||||
* would do getaddrinfo for. */
|
||||
if((r = getaddrinfo(ip, port, &hints, &res)) != 0 || !res) {
|
||||
#ifdef USE_WINSOCK
|
||||
if(!noproto_is_err && r == EAI_NONAME) {
|
||||
/* tried to lookup the address as name */
|
||||
return 1; /* return success, but do nothing */
|
||||
}
|
||||
#endif /* USE_WINSOCK */
|
||||
log_err("metrics interface %s:%s getaddrinfo: %s %s",
|
||||
ip, port, gai_strerror(r),
|
||||
#ifdef EAI_SYSTEM
|
||||
r==EAI_SYSTEM?(char*)strerror(errno):""
|
||||
#else
|
||||
""
|
||||
#endif
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* open fd */
|
||||
fd = create_tcp_accept_sock(res, 1, &noproto, 0,
|
||||
cfg->ip_transparent, 0, 0, cfg->ip_freebind,
|
||||
cfg->use_systemd, cfg->ip_dscp, "metrics");
|
||||
freeaddrinfo(res);
|
||||
}
|
||||
|
||||
if(fd == -1 && noproto) {
|
||||
if(!noproto_is_err)
|
||||
return 1; /* return success, but do nothing */
|
||||
log_err("cannot open metrics interface %s %d : "
|
||||
"protocol not supported", ip, nr);
|
||||
return 0;
|
||||
}
|
||||
if(fd == -1) {
|
||||
log_err("cannot open metrics interface %s %d", ip, nr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* alloc */
|
||||
hl = (struct metrics_acceptlist*)calloc(1, sizeof(*hl));
|
||||
if(!hl) {
|
||||
sock_close(fd);
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
hl->metrics = metrics;
|
||||
hl->ident = strdup(ip);
|
||||
if(!hl->ident) {
|
||||
log_err("out of memory");
|
||||
sock_close(fd);
|
||||
free(hl);
|
||||
return 0;
|
||||
}
|
||||
hl->next = metrics->accept_list;
|
||||
metrics->accept_list = hl;
|
||||
|
||||
hl->accept_fd = fd;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
daemon_metrics_open_ports(struct daemon_metrics* metrics,
|
||||
struct config_file* cfg)
|
||||
{
|
||||
assert(cfg->metrics_enable);
|
||||
if(!cfg->stat_cumulative)
|
||||
log_warn("metrics-enable: yes but statistics-cumulative: no, access to control command 'stats' would reset the stat counters, perhaps set 'statistics-cumulative: yes'.");
|
||||
if(cfg->metrics_ifs.first) {
|
||||
char** rcif = NULL;
|
||||
int i, num_rcif = 0;
|
||||
if(!resolve_interface_names(NULL, 0, cfg->metrics_ifs.first,
|
||||
&rcif, &num_rcif)) {
|
||||
return 0;
|
||||
}
|
||||
for(i=0; i<num_rcif; i++) {
|
||||
if(!metrics_add_open(metrics, cfg, rcif[i],
|
||||
cfg->metrics_port, 1)) {
|
||||
config_del_strarray(rcif, num_rcif);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
config_del_strarray(rcif, num_rcif);
|
||||
} else {
|
||||
/* defaults */
|
||||
if(cfg->do_ip6 && !metrics_add_open(metrics, cfg, "::1",
|
||||
cfg->metrics_port, 0)) {
|
||||
return 0;
|
||||
}
|
||||
if(cfg->do_ip4 &&
|
||||
!metrics_add_open(metrics, cfg, "127.0.0.1",
|
||||
cfg->metrics_port, 1)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
daemon_metrics_attach(struct daemon_metrics* metrics, struct worker* worker)
|
||||
{
|
||||
int fd;
|
||||
struct metrics_acceptlist* p;
|
||||
if(!metrics) return 1;
|
||||
metrics->worker = worker;
|
||||
if(!metrics->accept_list)
|
||||
return 1;
|
||||
|
||||
metrics->http_server = evhttp_new(ub_libevent_get_event_base(
|
||||
comm_base_internal(worker->base)));
|
||||
if(!metrics->http_server) {
|
||||
log_err("out of memory, evhttp_new failed");
|
||||
return 0;
|
||||
}
|
||||
for(p = metrics->accept_list; p; p = p->next) {
|
||||
fd = p->accept_fd;
|
||||
if (evhttp_accept_socket(metrics->http_server, fd)) {
|
||||
log_err("metrics: cannot set http server to accept socket");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* only handle requests to metrics_path, anything else returns 404 */
|
||||
evhttp_set_cb(metrics->http_server,
|
||||
worker->daemon->cfg->metrics_path,
|
||||
metrics_http_callback, p);
|
||||
/* evhttp_set_gencb(metrics->http_server, metrics_http_callback_generic, p); */
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Add help and type printout of a metric. */
|
||||
static void
|
||||
print_metric_help_and_type(struct evbuffer *buf, char *prefix, char *name,
|
||||
char *help, char *type)
|
||||
{
|
||||
evbuffer_add_printf(buf, "# HELP %s%s %s\n# TYPE %s%s %s\n",
|
||||
prefix, name, help, prefix, name, type);
|
||||
}
|
||||
|
||||
/* print help and type for main list of metrics */
|
||||
static int
|
||||
metrics_print_types(struct evbuffer *reply)
|
||||
{
|
||||
char* prefix = METRICS_PREFIX;
|
||||
print_metric_help_and_type(reply, prefix, "hits_queries",
|
||||
"Unbound DNS traffic and cache hits", "counter");
|
||||
print_metric_help_and_type(reply, prefix, "queue_queries",
|
||||
"Unbound requestlist size", "gauge");
|
||||
print_metric_help_and_type(reply, prefix, "recursion_time",
|
||||
"Unbound recursion time, in seconds", "gauge");
|
||||
print_metric_help_and_type(reply, prefix, "query_queue_time",
|
||||
"Unbound query queue time, in msec", "gauge");
|
||||
print_metric_help_and_type(reply, prefix, "socket_count",
|
||||
"Unbound socket count", "gauge");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* metrics print of stat block */
|
||||
static int
|
||||
metrics_print_stats(struct evbuffer* reply, const char* nm,
|
||||
struct ub_stats_info* s)
|
||||
{
|
||||
char* prefix = METRICS_PREFIX;
|
||||
struct timeval sumwait, avg;
|
||||
|
||||
/* print to reply buffer the stat for prefix mt
|
||||
* of type nm.snm and long long output svar. */
|
||||
#define INFO_STATS(mt, snm, svar) \
|
||||
evbuffer_add_printf(reply, \
|
||||
"%s" mt "{type=\"%s." snm "\"} " ARG_LL "d\n", \
|
||||
prefix, nm, (long long)(svar))
|
||||
|
||||
INFO_STATS("hits_queries", "num.queries", s->svr.num_queries);
|
||||
INFO_STATS("hits_queries", "num.queries_ip_ratelimited",
|
||||
s->svr.num_queries_ip_ratelimited);
|
||||
INFO_STATS("hits_queries", "num.queries_cookie_valid",
|
||||
s->svr.num_queries_cookie_valid);
|
||||
INFO_STATS("hits_queries", "num.queries_cookie_client",
|
||||
s->svr.num_queries_cookie_client);
|
||||
INFO_STATS("hits_queries", "num.queries_cookie_invalid",
|
||||
s->svr.num_queries_cookie_invalid);
|
||||
INFO_STATS("hits_queries", "num.queries_discard_timeout",
|
||||
s->svr.num_queries_discard_timeout);
|
||||
INFO_STATS("hits_queries", "num.queries_replyaddr_limit",
|
||||
s->svr.num_queries_replyaddr_limit);
|
||||
INFO_STATS("hits_queries", "num.queries_wait_limit",
|
||||
s->svr.num_queries_wait_limit);
|
||||
INFO_STATS("hits_queries", "num.cachehits",
|
||||
s->svr.num_queries - s->svr.num_queries_missed_cache);
|
||||
INFO_STATS("hits_queries", "num.cachemiss",
|
||||
s->svr.num_queries_missed_cache);
|
||||
INFO_STATS("hits_queries", "num.prefetch",
|
||||
s->svr.num_queries_prefetch);
|
||||
INFO_STATS("hits_queries", "num.queries_timed_out",
|
||||
s->svr.num_queries_timed_out);
|
||||
INFO_STATS("hits_queries", "num.expired", s->svr.ans_expired);
|
||||
INFO_STATS("hits_queries", "num.recursivereplies",
|
||||
s->mesh_replies_sent);
|
||||
#ifdef USE_DNSCRYPT
|
||||
INFO_STATS("hits_queries", "num.dnscrypt.crypted",
|
||||
s->svr.num_query_dnscrypt_crypted);
|
||||
INFO_STATS("hits_queries", "num.dnscrypt.cert",
|
||||
s->svr.num_query_dnscrypt_cert);
|
||||
INFO_STATS("hits_queries", "num.dnscrypt.cleartext",
|
||||
s->svr.num_query_dnscrypt_cleartext);
|
||||
INFO_STATS("hits_queries", "num.dnscrypt.malformed",
|
||||
s->svr.num_query_dnscrypt_crypted_malformed);
|
||||
#endif
|
||||
INFO_STATS("hits_queries", "num.dns_error_reports",
|
||||
s->svr.num_dns_error_reports);
|
||||
|
||||
evbuffer_add_printf(reply,
|
||||
"%squeue_queries{type=\"%s.requestlist.avg\"} %g\n",
|
||||
prefix, nm,
|
||||
(s->svr.num_queries_missed_cache+s->svr.num_queries_prefetch)?
|
||||
(double)s->svr.sum_query_list_size/
|
||||
(double)(s->svr.num_queries_missed_cache+
|
||||
s->svr.num_queries_prefetch) : 0.0);
|
||||
INFO_STATS("queue_queries", "requestlist.max",
|
||||
s->svr.max_query_list_size);
|
||||
INFO_STATS("queue_queries", "requestlist.overwritten",
|
||||
s->mesh_jostled);
|
||||
INFO_STATS("queue_queries", "requestlist.exceeded",
|
||||
s->mesh_dropped);
|
||||
INFO_STATS("queue_queries", "requestlist.current.all",
|
||||
s->mesh_num_states);
|
||||
INFO_STATS("queue_queries", "requestlist.current.user",
|
||||
s->mesh_num_reply_states);
|
||||
INFO_STATS("queue_queries", "requestlist.current.replies",
|
||||
s->mesh_num_reply_addrs);
|
||||
|
||||
sumwait.tv_sec = s->mesh_replies_sum_wait_sec;
|
||||
sumwait.tv_usec = s->mesh_replies_sum_wait_usec;
|
||||
timeval_divide(&avg, &sumwait, s->mesh_replies_sent);
|
||||
evbuffer_add_printf(reply,
|
||||
"%srecursion_time{type=\"%s.recursion.time.avg\"} " ARG_LL
|
||||
"d.%6.6d\n", prefix, nm,
|
||||
(long long)avg.tv_sec, (int)avg.tv_usec);
|
||||
evbuffer_add_printf(reply,
|
||||
"%srecursion_time{type=\"%s.recursion.time.median\"} %g\n",
|
||||
prefix, nm, s->mesh_time_median);
|
||||
|
||||
INFO_STATS("query_queue_time", "query.queue_time_us.max",
|
||||
s->svr.max_query_time_us);
|
||||
|
||||
INFO_STATS("socket_count", "tcpusage", s->svr.tcp_accept_usage);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* metrics print of thread stats */
|
||||
static int
|
||||
metrics_print_thread_stats(struct evbuffer* reply, int i,
|
||||
struct ub_stats_info* s)
|
||||
{
|
||||
char nm[32];
|
||||
snprintf(nm, sizeof(nm), "thread%d", i);
|
||||
nm[sizeof(nm)-1]=0;
|
||||
return metrics_print_stats(reply, nm, s);
|
||||
}
|
||||
|
||||
/* metrics print of uptime stats */
|
||||
static int
|
||||
metrics_print_uptime(struct evbuffer* reply, struct worker* worker,
|
||||
struct timeval* stattime, struct timeval* time_last_stat)
|
||||
{
|
||||
char* prefix = METRICS_PREFIX;
|
||||
struct timeval up, dt;
|
||||
timeval_subtract(&up, stattime, &worker->daemon->time_boot);
|
||||
timeval_subtract(&dt, stattime, time_last_stat);
|
||||
|
||||
print_metric_help_and_type(reply, prefix, "time_now_seconds",
|
||||
"Time of the statistics printout, in seconds.", "untyped");
|
||||
evbuffer_add_printf(reply, "%stime_now_seconds " ARG_LL "d.%6.6u\n",
|
||||
prefix, (long long)stattime->tv_sec,
|
||||
(unsigned)stattime->tv_usec);
|
||||
|
||||
print_metric_help_and_type(reply, prefix, "time_up_seconds_total",
|
||||
"Uptime since server boot in seconds.", "counter");
|
||||
evbuffer_add_printf(reply,
|
||||
"%stime_up_seconds_total " ARG_LL "d.%6.6u\n",
|
||||
prefix, (long long)up.tv_sec, (unsigned)up.tv_usec);
|
||||
|
||||
print_metric_help_and_type(reply, prefix, "time_elapsed_seconds",
|
||||
"Time since last statistics printout and "
|
||||
"reset (by unbound-control stats) in seconds.",
|
||||
"untyped");
|
||||
evbuffer_add_printf(reply,
|
||||
"%stime_elapsed_seconds " ARG_LL "d.%6.6u\n",
|
||||
prefix, (long long)dt.tv_sec, (unsigned)dt.tv_usec);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** metrics print of mem stats */
|
||||
static int
|
||||
metrics_print_mem(struct evbuffer* reply, struct worker* worker,
|
||||
struct ub_stats_info* s)
|
||||
{
|
||||
char* prefix = METRICS_PREFIX;
|
||||
struct ub_mem_stat_info mem;
|
||||
stats_get_mem_info(worker, &mem);
|
||||
|
||||
/* print to reply buffer the stat for prefix mt
|
||||
* of type snm and long long output svar. */
|
||||
#define INFO_LL_STATS(mt, snm, svar) \
|
||||
evbuffer_add_printf(reply, \
|
||||
"%s" mt "{type=\"" snm "\"} " ARG_LL "d\n", \
|
||||
prefix, (long long)(svar))
|
||||
|
||||
print_metric_help_and_type(reply, prefix, "memory_bytes",
|
||||
"Unbound memory usage, in bytes", "gauge");
|
||||
INFO_LL_STATS("memory_bytes", "mem.cache.rrset", mem.rrset);
|
||||
INFO_LL_STATS("memory_bytes", "mem.cache.message", mem.msg);
|
||||
INFO_LL_STATS("memory_bytes", "mem.mod.iterator", mem.iter);
|
||||
INFO_LL_STATS("memory_bytes", "mem.mod.validator", mem.val);
|
||||
INFO_LL_STATS("memory_bytes", "mem.mod.respip", mem.respip);
|
||||
#ifdef CLIENT_SUBNET
|
||||
INFO_LL_STATS("memory_bytes", "mem.mod.subnet", mem.subnet);
|
||||
#endif /* CLIENT_SUBNET */
|
||||
#ifdef USE_IPSECMOD
|
||||
INFO_LL_STATS("memory_bytes", "mem.mod.ipsecmod", mem.ipsecmod);
|
||||
#endif /* USE_IPSECMOD */
|
||||
#ifdef USE_DNSCRYPT
|
||||
INFO_LL_STATS("memory_bytes", "mem.cache.dnscrypt_shared_secret",
|
||||
mem.dnscrypt_shared_secret);
|
||||
INFO_LL_STATS("memory_bytes", "mem.cache.dnscrypt_nonce",
|
||||
mem.dnscrypt_nonce);
|
||||
#endif /* USE_DNSCRYPT */
|
||||
#ifdef WITH_DYNLIBMODULE
|
||||
INFO_LL_STATS("memory_bytes", "mem.mod.dynlibmod", mem.dynlib);
|
||||
#endif /* WITH_DYNLIBMODULE */
|
||||
INFO_LL_STATS("memory_bytes", "mem.streamwait",
|
||||
s->svr.mem_stream_wait);
|
||||
INFO_LL_STATS("memory_bytes", "mem.http.query_buffer",
|
||||
s->svr.mem_http2_query_buffer);
|
||||
INFO_LL_STATS("memory_bytes", "mem.http.response_buffer",
|
||||
s->svr.mem_http2_response_buffer);
|
||||
#ifdef HAVE_NGTCP2
|
||||
INFO_LL_STATS("memory_bytes", "mem.quic", s->svr.mem_quic);
|
||||
#endif /* HAVE_NGTCP2 */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* metrics print of histogram */
|
||||
static int
|
||||
metrics_print_hist(struct evbuffer* reply, struct ub_stats_info* s)
|
||||
{
|
||||
char* prefix = METRICS_PREFIX;
|
||||
struct timehist* hist;
|
||||
size_t i;
|
||||
|
||||
print_metric_help_and_type(reply, prefix, "histogram_seconds",
|
||||
"Unbound DNS histogram of reply time", "counter");
|
||||
|
||||
hist = timehist_setup();
|
||||
if(!hist) {
|
||||
log_err("out of memory");
|
||||
return 0;
|
||||
}
|
||||
timehist_import(hist, s->svr.hist, NUM_BUCKETS_HIST);
|
||||
for(i=0; i<hist->num; i++) {
|
||||
evbuffer_add_printf(reply, "%shistogram_seconds"
|
||||
"{bucket=\"%6.6d.%6.6d.to.%6.6d.%6.6d\"} %lu\n",
|
||||
prefix,
|
||||
(int)hist->buckets[i].lower.tv_sec,
|
||||
(int)hist->buckets[i].lower.tv_usec,
|
||||
(int)hist->buckets[i].upper.tv_sec,
|
||||
(int)hist->buckets[i].upper.tv_usec,
|
||||
(unsigned long)hist->buckets[i].count);
|
||||
}
|
||||
timehist_delete(hist);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* metrics print of extended stats */
|
||||
static int
|
||||
metrics_print_ext(struct evbuffer* reply, struct ub_stats_info* s,
|
||||
int inhibit_zero)
|
||||
{
|
||||
char* prefix = METRICS_PREFIX;
|
||||
int i;
|
||||
char nm[32];
|
||||
const sldns_rr_descriptor* desc;
|
||||
const sldns_lookup_table* lt;
|
||||
|
||||
/* Print stats for metric mt, where type 'sortnm' is "snm" string,
|
||||
* with value svar. */
|
||||
#define INFO_EXT_STATS(mt, sortnm, snm, svar) \
|
||||
evbuffer_add_printf(reply, "%s%s{%s=\"%s\"} " ARG_LL "d\n", \
|
||||
prefix, mt, sortnm, snm, svar);
|
||||
|
||||
/* TYPE */
|
||||
print_metric_help_and_type(reply, prefix, "by_type_queries",
|
||||
"Unbound DNS queries by type", "counter");
|
||||
for(i=0; i<UB_STATS_QTYPE_NUM; i++) {
|
||||
if(inhibit_zero && s->svr.qtype[i] == 0)
|
||||
continue;
|
||||
desc = sldns_rr_descript((uint16_t)i);
|
||||
if(desc && desc->_name) {
|
||||
snprintf(nm, sizeof(nm), "%s", desc->_name);
|
||||
} else if (i == LDNS_RR_TYPE_IXFR) {
|
||||
snprintf(nm, sizeof(nm), "IXFR");
|
||||
} else if (i == LDNS_RR_TYPE_AXFR) {
|
||||
snprintf(nm, sizeof(nm), "AXFR");
|
||||
} else if (i == LDNS_RR_TYPE_MAILA) {
|
||||
snprintf(nm, sizeof(nm), "MAILA");
|
||||
} else if (i == LDNS_RR_TYPE_MAILB) {
|
||||
snprintf(nm, sizeof(nm), "MAILB");
|
||||
} else if (i == LDNS_RR_TYPE_ANY) {
|
||||
snprintf(nm, sizeof(nm), "ANY");
|
||||
} else {
|
||||
snprintf(nm, sizeof(nm), "TYPE%d", i);
|
||||
}
|
||||
INFO_EXT_STATS("by_type_queries", "type", nm, s->svr.qtype[i]);
|
||||
}
|
||||
if(!inhibit_zero || s->svr.qtype_big) {
|
||||
INFO_EXT_STATS("by_type_queries", "type", "other",
|
||||
s->svr.qtype_big);
|
||||
}
|
||||
|
||||
/* CLASS */
|
||||
print_metric_help_and_type(reply, prefix, "by_class_queries",
|
||||
"Unbound DNS queries by class", "counter");
|
||||
for(i=0; i<UB_STATS_QCLASS_NUM; i++) {
|
||||
if(inhibit_zero && s->svr.qclass[i] == 0)
|
||||
continue;
|
||||
lt = sldns_lookup_by_id(sldns_rr_classes, i);
|
||||
if(lt && lt->name) {
|
||||
snprintf(nm, sizeof(nm), "%s", lt->name);
|
||||
} else {
|
||||
snprintf(nm, sizeof(nm), "CLASS%d", i);
|
||||
}
|
||||
INFO_EXT_STATS("by_class_queries", "class", nm,
|
||||
s->svr.qclass[i]);
|
||||
}
|
||||
if(!inhibit_zero || s->svr.qclass_big) {
|
||||
INFO_EXT_STATS("by_class_queries", "class", "other",
|
||||
s->svr.qclass_big);
|
||||
}
|
||||
|
||||
/* OPCODE */
|
||||
print_metric_help_and_type(reply, prefix, "by_opcode_queries",
|
||||
"Unbound DNS queries by opcode", "counter");
|
||||
for(i=0; i<UB_STATS_OPCODE_NUM; i++) {
|
||||
if(inhibit_zero && s->svr.qopcode[i] == 0)
|
||||
continue;
|
||||
lt = sldns_lookup_by_id(sldns_opcodes, i);
|
||||
if(lt && lt->name) {
|
||||
snprintf(nm, sizeof(nm), "%s", lt->name);
|
||||
} else {
|
||||
snprintf(nm, sizeof(nm), "OPCODE%d", i);
|
||||
}
|
||||
INFO_EXT_STATS("by_opcode_queries", "opcode", nm,
|
||||
s->svr.qopcode[i]);
|
||||
}
|
||||
|
||||
/* RCODE */
|
||||
print_metric_help_and_type(reply, prefix, "by_rcode_queries",
|
||||
"Unbound DNS answers by rcode", "counter");
|
||||
for(i=0; i<UB_STATS_RCODE_NUM; i++) {
|
||||
/* Always include RCODEs 0-5 */
|
||||
if(inhibit_zero && i > LDNS_RCODE_REFUSED && s->svr.ans_rcode[i] == 0)
|
||||
continue;
|
||||
lt = sldns_lookup_by_id(sldns_rcodes, i);
|
||||
if(lt && lt->name) {
|
||||
snprintf(nm, sizeof(nm), "%s", lt->name);
|
||||
} else {
|
||||
snprintf(nm, sizeof(nm), "RCODE%d", i);
|
||||
}
|
||||
INFO_EXT_STATS("by_rcode_queries", "rcode", nm,
|
||||
s->svr.ans_rcode[i]);
|
||||
}
|
||||
if(!inhibit_zero || s->svr.ans_rcode_nodata) {
|
||||
INFO_EXT_STATS("by_rcode_queries", "rcode", "nodata",
|
||||
s->svr.ans_rcode_nodata);
|
||||
}
|
||||
|
||||
/* FLAGS */
|
||||
print_metric_help_and_type(reply, prefix, "by_flags_queries",
|
||||
"Unbound DNS queries by flags", "counter");
|
||||
INFO_EXT_STATS("by_flags_queries", "flag", "QR", s->svr.qbit_QR);
|
||||
INFO_EXT_STATS("by_flags_queries", "flag", "AA", s->svr.qbit_AA);
|
||||
INFO_EXT_STATS("by_flags_queries", "flag", "TC", s->svr.qbit_TC);
|
||||
INFO_EXT_STATS("by_flags_queries", "flag", "RD", s->svr.qbit_RD);
|
||||
INFO_EXT_STATS("by_flags_queries", "flag", "RA", s->svr.qbit_RA);
|
||||
INFO_EXT_STATS("by_flags_queries", "flag", "Z", s->svr.qbit_Z);
|
||||
INFO_EXT_STATS("by_flags_queries", "flag", "AD", s->svr.qbit_AD);
|
||||
INFO_EXT_STATS("by_flags_queries", "flag", "CD", s->svr.qbit_CD);
|
||||
INFO_EXT_STATS("by_flags_queries", "flag", "edns.present",
|
||||
s->svr.qEDNS);
|
||||
INFO_EXT_STATS("by_flags_queries", "flag", "edns.DO",
|
||||
s->svr.qEDNS_DO);
|
||||
|
||||
/* transport */
|
||||
print_metric_help_and_type(reply, prefix, "by_transport_queries",
|
||||
"Unbound DNS queries by transport", "counter");
|
||||
INFO_EXT_STATS("by_transport_queries", "transport", "tcp",
|
||||
s->svr.qtcp);
|
||||
INFO_EXT_STATS("by_transport_queries", "transport", "tcpout",
|
||||
s->svr.qtcp_outgoing);
|
||||
INFO_EXT_STATS("by_transport_queries", "transport", "udpout",
|
||||
s->svr.qudp_outgoing);
|
||||
INFO_EXT_STATS("by_transport_queries", "transport", "tls",
|
||||
s->svr.qtls);
|
||||
INFO_EXT_STATS("by_transport_queries", "transport", "tls.resume",
|
||||
s->svr.qtls_resume);
|
||||
INFO_EXT_STATS("by_transport_queries", "transport", "ipv6",
|
||||
s->svr.qipv6);
|
||||
INFO_EXT_STATS("by_transport_queries", "transport", "https",
|
||||
s->svr.qhttps);
|
||||
#ifdef HAVE_NGTCP2
|
||||
INFO_EXT_STATS("by_transport_queries", "transport", "quic",
|
||||
s->svr.qquic);
|
||||
#endif /* HAVE_NGTCP2 */
|
||||
|
||||
/* iteration */
|
||||
print_metric_help_and_type(reply, prefix, "ratelimited_queries",
|
||||
"Unbound DNS queries ratelimited", "counter");
|
||||
INFO_EXT_STATS("ratelimited_queries", "type", "ratelimited",
|
||||
s->svr.queries_ratelimited);
|
||||
|
||||
/* validation */
|
||||
print_metric_help_and_type(reply, prefix, "validation_queries",
|
||||
"Unbound DNS queries DNSSEC validated", "counter");
|
||||
INFO_EXT_STATS("validation_queries", "type", "secure",
|
||||
s->svr.ans_secure);
|
||||
INFO_EXT_STATS("validation_queries", "type", "bogus",
|
||||
s->svr.ans_bogus);
|
||||
INFO_EXT_STATS("validation_queries", "type", "rrset.bogus",
|
||||
s->svr.rrset_bogus);
|
||||
INFO_EXT_STATS("validation_queries", "type", "valops",
|
||||
s->svr.val_ops);
|
||||
INFO_EXT_STATS("validation_queries", "type", "aggressive.NOERROR",
|
||||
s->svr.num_neg_cache_noerror);
|
||||
INFO_EXT_STATS("validation_queries", "type", "aggressive.NXDOMAIN",
|
||||
s->svr.num_neg_cache_nxdomain);
|
||||
|
||||
/* threat detection */
|
||||
print_metric_help_and_type(reply, prefix, "threat_queries",
|
||||
"Unbound DNS queries threats", "counter");
|
||||
INFO_EXT_STATS("threat_queries", "type", "unwanted.queries",
|
||||
s->svr.unwanted_queries);
|
||||
INFO_EXT_STATS("threat_queries", "type", "unwanted.replies",
|
||||
s->svr.unwanted_replies);
|
||||
|
||||
/* cache counts */
|
||||
print_metric_help_and_type(reply, prefix, "cache_items",
|
||||
"Unbound DNS cache counts", "gauge");
|
||||
INFO_EXT_STATS("cache_items", "count", "msg.cache",
|
||||
s->svr.msg_cache_count);
|
||||
INFO_EXT_STATS("cache_items", "count", "rrset.cache",
|
||||
s->svr.rrset_cache_count);
|
||||
INFO_EXT_STATS("cache_items", "count", "infra.cache",
|
||||
s->svr.infra_cache_count);
|
||||
INFO_EXT_STATS("cache_items", "count", "key.cache",
|
||||
s->svr.key_cache_count);
|
||||
|
||||
/* max collisions */
|
||||
INFO_EXT_STATS("cache_items", "count", "msg.cache.max_collisions",
|
||||
s->svr.msg_cache_max_collisions);
|
||||
INFO_EXT_STATS("cache_items", "count", "rrset.cache.max_collisions",
|
||||
s->svr.rrset_cache_max_collisions);
|
||||
|
||||
/* applied RPZ actions */
|
||||
print_metric_help_and_type(reply, prefix, "rpz_actions",
|
||||
"Unbound DNS RPZ actions", "counter");
|
||||
for(i=0; i<UB_STATS_RPZ_ACTION_NUM; i++) {
|
||||
if(i == RPZ_NO_OVERRIDE_ACTION)
|
||||
continue;
|
||||
if(inhibit_zero && s->svr.rpz_action[i] == 0)
|
||||
continue;
|
||||
INFO_EXT_STATS("rpz_actions", "action",
|
||||
rpz_action_to_string(i), s->svr.rpz_action[i]);
|
||||
}
|
||||
|
||||
/* handling mechanism */
|
||||
print_metric_help_and_type(reply, prefix, "handled_queries",
|
||||
"Unbound DNS queries by handling mechanism", "counter");
|
||||
#ifdef USE_DNSCRYPT
|
||||
INFO_EXT_STATS("cache_items", "count", "dnscrypt_shared_secret.cache",
|
||||
s->svr.shared_secret_cache_count);
|
||||
INFO_EXT_STATS("cache_items", "count", "dnscrypt_nonce.cache",
|
||||
s->svr.nonce_cache_count);
|
||||
INFO_EXT_STATS("handled_queries", "type",
|
||||
"dnscrypt.shared_secret.cachemiss",
|
||||
s->svr.num_query_dnscrypt_secret_missed_cache);
|
||||
INFO_EXT_STATS("handled_queries", "type", "dnscrypt.replay",
|
||||
s->svr.num_query_dnscrypt_replay);
|
||||
#endif /* USE_DNSCRYPT */
|
||||
INFO_EXT_STATS("handled_queries", "type", "authzone.up",
|
||||
s->svr.num_query_authzone_up);
|
||||
INFO_EXT_STATS("handled_queries", "type", "authzone.down",
|
||||
s->svr.num_query_authzone_down);
|
||||
#ifdef CLIENT_SUBNET
|
||||
INFO_EXT_STATS("handled_queries", "type", "subnet",
|
||||
s->svr.num_query_subnet);
|
||||
INFO_EXT_STATS("handled_queries", "type", "subnet_cache",
|
||||
s->svr.num_query_subnet_cache);
|
||||
#endif /* CLIENT_SUBNET */
|
||||
#ifdef USE_CACHEDB
|
||||
INFO_EXT_STATS("handled_queries", "type", "cachedb",
|
||||
s->svr.num_query_cachedb);
|
||||
#endif /* USE_CACHEDB */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* process statistics */
|
||||
static void
|
||||
do_metrics_stats(struct evbuffer* reply, struct worker* worker, int reset)
|
||||
{
|
||||
struct daemon* daemon = worker->daemon;
|
||||
struct ub_stats_info total;
|
||||
struct ub_stats_info s;
|
||||
int i;
|
||||
struct timeval stattime, time_last_stat;
|
||||
|
||||
memset(&total, 0, sizeof(total));
|
||||
log_assert(daemon->num > 0);
|
||||
|
||||
if(!metrics_print_types(reply))
|
||||
return;
|
||||
|
||||
/* gather all thread statistics in one place */
|
||||
for(i=0; i<daemon->num; i++) {
|
||||
server_stats_obtain(worker, daemon->workers[i], &s, reset);
|
||||
if(!metrics_print_thread_stats(reply, i, &s))
|
||||
return;
|
||||
if(i == 0)
|
||||
total = s;
|
||||
else server_stats_add(&total, &s);
|
||||
}
|
||||
total.mesh_time_median /= (double)daemon->num;
|
||||
if(gettimeofday(&stattime, NULL) < 0)
|
||||
log_err("gettimeofday: %s", strerror(errno));
|
||||
time_last_stat = worker->daemon->time_last_stat;
|
||||
if(reset) {
|
||||
worker->daemon->time_last_stat = stattime;
|
||||
}
|
||||
|
||||
/* print the statistics */
|
||||
if(!metrics_print_stats(reply, "total", &total))
|
||||
return;
|
||||
if(!metrics_print_uptime(reply, worker, &stattime, &time_last_stat))
|
||||
return;
|
||||
if(daemon->cfg->stat_extended) {
|
||||
if(!metrics_print_mem(reply, worker, &total))
|
||||
return;
|
||||
if(!metrics_print_hist(reply, &total))
|
||||
return;
|
||||
if(!metrics_print_ext(reply, &total,
|
||||
daemon->cfg->stat_inhibit_zero))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Callback for handling the active http request to the specific URI */
|
||||
static void
|
||||
metrics_http_callback(struct evhttp_request *req, void *p)
|
||||
{
|
||||
struct evbuffer *reply = NULL;
|
||||
struct daemon_metrics *metrics = ((struct metrics_acceptlist *)p)->metrics;
|
||||
|
||||
/* currently only GET requests are supported/allowed */
|
||||
enum evhttp_cmd_type cmd = evhttp_request_get_command(req);
|
||||
if (cmd != EVHTTP_REQ_GET /* && cmd != EVHTTP_REQ_HEAD */) {
|
||||
evhttp_send_error(req, HTTP_BADMETHOD, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
reply = evbuffer_new();
|
||||
|
||||
if (!reply) {
|
||||
evhttp_send_error(req, HTTP_INTERNAL, 0);
|
||||
log_err("metrics: failed to allocate reply buffer\n");
|
||||
return;
|
||||
}
|
||||
|
||||
evhttp_add_header(evhttp_request_get_output_headers(req),
|
||||
"Content-Type", "text/plain; version=0.0.4");
|
||||
do_metrics_stats(reply, metrics->worker, 0 /* no reset */);
|
||||
evhttp_send_reply(req, HTTP_OK, NULL, reply);
|
||||
verbose(VERB_DETAIL, "metrics operation completed, response sent");
|
||||
evbuffer_free(reply);
|
||||
}
|
||||
#endif /* USE_METRICS */
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* daemon/metrics.h - prometheus metrics endpoint.
|
||||
*
|
||||
* Copyright (c) 2026, NLnet Labs. All rights reserved.
|
||||
*
|
||||
* This software is open source.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* Neither the name of the NLNET LABS nor the names of its contributors may
|
||||
* be used to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* The statistics output provides metrics to prometheus.
|
||||
*/
|
||||
|
||||
#ifndef DAEMON_METRICS_H
|
||||
#define DAEMON_METRICS_H
|
||||
struct daemon_metrics;
|
||||
struct config_file;
|
||||
struct worker;
|
||||
struct evhttp;
|
||||
|
||||
/* the metrics daemon needs little backlog */
|
||||
#define TCP_BACKLOG_METRICS 16 /* listen() tcp backlog */
|
||||
|
||||
/**
|
||||
* list of connection accepting file descriptors
|
||||
*/
|
||||
struct metrics_acceptlist {
|
||||
struct metrics_acceptlist* next;
|
||||
int accept_fd;
|
||||
char* ident;
|
||||
struct daemon_metrics* metrics;
|
||||
};
|
||||
|
||||
/**
|
||||
* The metrics daemon state.
|
||||
*/
|
||||
struct daemon_metrics {
|
||||
/** The worker for this metrics endpoint */
|
||||
struct worker* worker;
|
||||
/** commpoints for accepting HTTP connections */
|
||||
struct metrics_acceptlist* accept_list;
|
||||
/** libevent http server */
|
||||
struct evhttp *http_server;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create new metrics endpoint for the daemon.
|
||||
* Does not open the ports, for that call the open ports routine, and
|
||||
* later the attach routine on the worker event base.
|
||||
* @return new state, or NULL on failure.
|
||||
*/
|
||||
struct daemon_metrics* daemon_metrics_create(void);
|
||||
|
||||
/**
|
||||
* Delete metrics daemon and close HTTP listeners.
|
||||
* @param m: daemon to delete.
|
||||
*/
|
||||
void daemon_metrics_delete(struct daemon_metrics* m);
|
||||
|
||||
/**
|
||||
* Close metrics HTTP listener ports.
|
||||
* Does not delete the object itself.
|
||||
* @param m: state to close.
|
||||
*/
|
||||
void daemon_metrics_close_ports(struct daemon_metrics* m);
|
||||
|
||||
/**
|
||||
* Detach the metrics listener from the event base.
|
||||
* Does not delete the object itself.
|
||||
* @param m: state to detach.
|
||||
*/
|
||||
void daemon_metrics_detach(struct daemon_metrics* m);
|
||||
|
||||
/**
|
||||
* Open and create HTTP listeners for metrics daemon.
|
||||
* @param m: metrics state that contains list of accept sockets.
|
||||
* @param cfg: config options.
|
||||
* @return false on failure.
|
||||
*/
|
||||
int daemon_metrics_open_ports(struct daemon_metrics* m,
|
||||
struct config_file* cfg);
|
||||
|
||||
/**
|
||||
* Setup HTTP listener.
|
||||
* @param m: state
|
||||
* @param worker: The worker thread that hosts the endpoint.
|
||||
* The HTTP listener is attached to its event base.
|
||||
* @return false on failure.
|
||||
*/
|
||||
int daemon_metrics_attach(struct daemon_metrics* m, struct worker* worker);
|
||||
|
||||
#endif /* DAEMON_METRICS_H */
|
||||
+34
-77
@@ -153,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_protocols)) {
|
||||
if(!listen_sslctx_setup(rc->ctx, cfg->tls_use_system_policy_versions)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -910,73 +910,39 @@ print_longnum(RES* ssl, const char* desc, size_t x)
|
||||
|
||||
/** print mem stats */
|
||||
static int
|
||||
print_mem(RES* ssl, struct worker* worker, struct daemon* daemon,
|
||||
struct ub_stats_info* s)
|
||||
print_mem(RES* ssl, struct worker* worker, struct ub_stats_info* s)
|
||||
{
|
||||
size_t msg, rrset, val, iter, respip;
|
||||
#ifdef CLIENT_SUBNET
|
||||
size_t subnet = 0;
|
||||
#endif /* CLIENT_SUBNET */
|
||||
#ifdef USE_IPSECMOD
|
||||
size_t ipsecmod = 0;
|
||||
#endif /* USE_IPSECMOD */
|
||||
#ifdef USE_DNSCRYPT
|
||||
size_t dnscrypt_shared_secret = 0;
|
||||
size_t dnscrypt_nonce = 0;
|
||||
#endif /* USE_DNSCRYPT */
|
||||
#ifdef WITH_DYNLIBMODULE
|
||||
size_t dynlib = 0;
|
||||
#endif /* WITH_DYNLIBMODULE */
|
||||
msg = slabhash_get_mem(daemon->env->msg_cache);
|
||||
rrset = slabhash_get_mem(&daemon->env->rrset_cache->table);
|
||||
val = mod_get_mem(&worker->env, "validator");
|
||||
iter = mod_get_mem(&worker->env, "iterator");
|
||||
respip = mod_get_mem(&worker->env, "respip");
|
||||
#ifdef CLIENT_SUBNET
|
||||
subnet = mod_get_mem(&worker->env, "subnetcache");
|
||||
#endif /* CLIENT_SUBNET */
|
||||
#ifdef USE_IPSECMOD
|
||||
ipsecmod = mod_get_mem(&worker->env, "ipsecmod");
|
||||
#endif /* USE_IPSECMOD */
|
||||
#ifdef USE_DNSCRYPT
|
||||
if(daemon->dnscenv) {
|
||||
dnscrypt_shared_secret = slabhash_get_mem(
|
||||
daemon->dnscenv->shared_secrets_cache);
|
||||
dnscrypt_nonce = slabhash_get_mem(daemon->dnscenv->nonces_cache);
|
||||
}
|
||||
#endif /* USE_DNSCRYPT */
|
||||
#ifdef WITH_DYNLIBMODULE
|
||||
dynlib = mod_get_mem(&worker->env, "dynlib");
|
||||
#endif /* WITH_DYNLIBMODULE */
|
||||
struct ub_mem_stat_info mem;
|
||||
stats_get_mem_info(worker, &mem);
|
||||
|
||||
if(!print_longnum(ssl, "mem.cache.rrset"SQ, rrset))
|
||||
if(!print_longnum(ssl, "mem.cache.rrset"SQ, (size_t)mem.rrset))
|
||||
return 0;
|
||||
if(!print_longnum(ssl, "mem.cache.message"SQ, msg))
|
||||
if(!print_longnum(ssl, "mem.cache.message"SQ, (size_t)mem.msg))
|
||||
return 0;
|
||||
if(!print_longnum(ssl, "mem.mod.iterator"SQ, iter))
|
||||
if(!print_longnum(ssl, "mem.mod.iterator"SQ, (size_t)mem.iter))
|
||||
return 0;
|
||||
if(!print_longnum(ssl, "mem.mod.validator"SQ, val))
|
||||
if(!print_longnum(ssl, "mem.mod.validator"SQ, (size_t)mem.val))
|
||||
return 0;
|
||||
if(!print_longnum(ssl, "mem.mod.respip"SQ, respip))
|
||||
if(!print_longnum(ssl, "mem.mod.respip"SQ, (size_t)mem.respip))
|
||||
return 0;
|
||||
#ifdef CLIENT_SUBNET
|
||||
if(!print_longnum(ssl, "mem.mod.subnet"SQ, subnet))
|
||||
if(!print_longnum(ssl, "mem.mod.subnet"SQ, (size_t)mem.subnet))
|
||||
return 0;
|
||||
#endif /* CLIENT_SUBNET */
|
||||
#ifdef USE_IPSECMOD
|
||||
if(!print_longnum(ssl, "mem.mod.ipsecmod"SQ, ipsecmod))
|
||||
if(!print_longnum(ssl, "mem.mod.ipsecmod"SQ, (size_t)mem.ipsecmod))
|
||||
return 0;
|
||||
#endif /* USE_IPSECMOD */
|
||||
#ifdef USE_DNSCRYPT
|
||||
if(!print_longnum(ssl, "mem.cache.dnscrypt_shared_secret"SQ,
|
||||
dnscrypt_shared_secret))
|
||||
(size_t)mem.dnscrypt_shared_secret))
|
||||
return 0;
|
||||
if(!print_longnum(ssl, "mem.cache.dnscrypt_nonce"SQ,
|
||||
dnscrypt_nonce))
|
||||
(size_t)mem.dnscrypt_nonce))
|
||||
return 0;
|
||||
#endif /* USE_DNSCRYPT */
|
||||
#ifdef WITH_DYNLIBMODULE
|
||||
if(!print_longnum(ssl, "mem.mod.dynlibmod"SQ, dynlib))
|
||||
if(!print_longnum(ssl, "mem.mod.dynlibmod"SQ, (size_t)mem.dynlib))
|
||||
return 0;
|
||||
#endif /* WITH_DYNLIBMODULE */
|
||||
if(!print_longnum(ssl, "mem.streamwait"SQ,
|
||||
@@ -1264,7 +1230,7 @@ do_stats(RES* ssl, struct worker* worker, int reset)
|
||||
if(!print_uptime(ssl, worker, reset))
|
||||
return;
|
||||
if(daemon->cfg->stat_extended) {
|
||||
if(!print_mem(ssl, worker, daemon, &total))
|
||||
if(!print_mem(ssl, worker, &total))
|
||||
return;
|
||||
if(!print_hist(ssl, &total))
|
||||
return;
|
||||
@@ -1658,14 +1624,6 @@ do_view_data_add(RES* ssl, struct worker* worker, char* arg)
|
||||
ssl_printf(ssl,"error out of memory\n");
|
||||
return;
|
||||
}
|
||||
if(!v->isfirst) {
|
||||
/* Global local-zone is not used for this view,
|
||||
* therefore add defaults to this view-specific
|
||||
* local-zone. */
|
||||
struct config_file lz_cfg;
|
||||
memset(&lz_cfg, 0, sizeof(lz_cfg));
|
||||
local_zone_enter_defaults(v->local_zones, &lz_cfg);
|
||||
}
|
||||
}
|
||||
do_data_add(ssl, v->local_zones, arg2);
|
||||
lock_rw_unlock(&v->lock);
|
||||
@@ -1691,14 +1649,6 @@ do_view_datas_add(struct daemon_remote* rc, RES* ssl, struct worker* worker,
|
||||
ssl_printf(ssl,"error out of memory\n");
|
||||
return;
|
||||
}
|
||||
if(!v->isfirst) {
|
||||
/* Global local-zone is not used for this view,
|
||||
* therefore add defaults to this view-specific
|
||||
* local-zone. */
|
||||
struct config_file lz_cfg;
|
||||
memset(&lz_cfg, 0, sizeof(lz_cfg));
|
||||
local_zone_enter_defaults(v->local_zones, &lz_cfg);
|
||||
}
|
||||
}
|
||||
/* put the view name in the command buf */
|
||||
(void)snprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), "%s ", arg);
|
||||
@@ -4992,11 +4942,16 @@ 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-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);
|
||||
FR_CHECK_CHANGED_CFG("udp-upstream-without-downstream", udp_upstream_without_downstream, changed_str);
|
||||
#ifdef USE_METRICS
|
||||
FR_CHECK_CHANGED_CFG("metrics-enable", metrics_enable, changed_str);
|
||||
FR_CHECK_CHANGED_CFG("metrics-port", metrics_port, changed_str);
|
||||
FR_CHECK_CHANGED_CFG_STR("metrics-path", metrics_path, changed_str);
|
||||
FR_CHECK_CHANGED_CFG_STRLIST("metrics-interface", metrics_ifs.first, changed_str);
|
||||
#endif
|
||||
|
||||
if(changed_str[0] != 0) {
|
||||
/* The new config changes some items that do not work with
|
||||
@@ -5246,7 +5201,6 @@ 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);
|
||||
@@ -5325,6 +5279,10 @@ config_file_getmem(struct config_file* cfg)
|
||||
m += getmem_str(cfg->dnstap_tls_client_cert_file);
|
||||
m += getmem_str(cfg->dnstap_identity);
|
||||
m += getmem_str(cfg->dnstap_version);
|
||||
#ifdef USE_METRICS
|
||||
m += getmem_config_strlist(cfg->metrics_ifs.first);
|
||||
m += getmem_str(cfg->metrics_path);
|
||||
#endif
|
||||
m += getmem_config_str2list(cfg->ratelimit_for_domain);
|
||||
m += getmem_config_str2list(cfg->ratelimit_below_domain);
|
||||
m += getmem_config_str2list(cfg->edns_client_strings);
|
||||
@@ -6078,8 +6036,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);
|
||||
@@ -6309,6 +6267,13 @@ fr_atomic_copy_cfg(struct config_file* oldcfg, struct config_file* cfg,
|
||||
COPY_VAR_int(dnstap_log_forwarder_query_messages);
|
||||
COPY_VAR_int(dnstap_log_forwarder_response_messages);
|
||||
COPY_VAR_int(disable_dnssec_lame_check);
|
||||
#ifdef USE_METRICS
|
||||
COPY_VAR_int(metrics_enable);
|
||||
COPY_VAR_ptr(metrics_ifs.first);
|
||||
COPY_VAR_ptr(metrics_ifs.last);
|
||||
COPY_VAR_int(metrics_port);
|
||||
COPY_VAR_ptr(metrics_path);
|
||||
#endif
|
||||
COPY_VAR_int(ip_ratelimit);
|
||||
COPY_VAR_int(ip_ratelimit_cookie);
|
||||
COPY_VAR_size_t(ip_ratelimit_slabs);
|
||||
@@ -6389,7 +6354,6 @@ fr_atomic_copy_cfg(struct config_file* oldcfg, struct config_file* cfg,
|
||||
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);
|
||||
|
||||
@@ -6853,8 +6817,6 @@ 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;
|
||||
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();
|
||||
@@ -6864,9 +6826,6 @@ static void* fast_reload_thread_main(void* arg)
|
||||
#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) {
|
||||
fr_init_time(&time_start, &time_read, &time_construct,
|
||||
@@ -7840,9 +7799,7 @@ fr_worker_pickup_listen_dnsport(struct worker* worker)
|
||||
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 &&
|
||||
@@ -7862,7 +7819,7 @@ fr_worker_pickup_listen_dnsport(struct worker* worker)
|
||||
cp->doq_socket->ctx =
|
||||
(SSL_CTX*)quic_sslctx;
|
||||
}
|
||||
#endif /* HAVE_NGTCP2 */
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -611,3 +611,42 @@ void server_stats_downstream_cookie(struct ub_server_stats* stats,
|
||||
stats->num_queries_cookie_invalid++;
|
||||
}
|
||||
}
|
||||
|
||||
void stats_get_mem_info(struct worker* worker, struct ub_mem_stat_info* mem)
|
||||
{
|
||||
struct daemon* daemon = worker->daemon;
|
||||
mem->msg = slabhash_get_mem(daemon->env->msg_cache);
|
||||
mem->rrset = slabhash_get_mem(&daemon->env->rrset_cache->table);
|
||||
mem->val = mod_get_mem(&worker->env, "validator");
|
||||
mem->iter = mod_get_mem(&worker->env, "iterator");
|
||||
mem->respip = mod_get_mem(&worker->env, "respip");
|
||||
#ifdef CLIENT_SUBNET
|
||||
mem->subnet = mod_get_mem(&worker->env, "subnetcache");
|
||||
#else
|
||||
mem->subnet = 0;
|
||||
#endif /* CLIENT_SUBNET */
|
||||
#ifdef USE_IPSECMOD
|
||||
mem->ipsecmod = mod_get_mem(&worker->env, "ipsecmod");
|
||||
#else
|
||||
mem->ipsecmod = 0;
|
||||
#endif /* USE_IPSECMOD */
|
||||
#ifdef USE_DNSCRYPT
|
||||
if(daemon->dnscenv) {
|
||||
mem->dnscrypt_shared_secret = slabhash_get_mem(
|
||||
daemon->dnscenv->shared_secrets_cache);
|
||||
mem->dnscrypt_nonce = slabhash_get_mem(
|
||||
daemon->dnscenv->nonces_cache);
|
||||
} else {
|
||||
mem->dnscrypt_shared_secret = 0;
|
||||
mem->dnscrypt_nonce = 0;
|
||||
}
|
||||
#else
|
||||
mem->dnscrypt_shared_secret = 0;
|
||||
mem->dnscrypt_nonce = 0;
|
||||
#endif /* USE_DNSCRYPT */
|
||||
#ifdef WITH_DYNLIBMODULE
|
||||
mem->dynlib = mod_get_mem(&worker->env, "dynlib");
|
||||
#else
|
||||
mem->dynlib = 0;
|
||||
#endif /* WITH_DYNLIBMODULE */
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@ struct comm_point;
|
||||
struct comm_reply;
|
||||
struct edns_data;
|
||||
struct sldns_buffer;
|
||||
struct ub_mem_stat_info;
|
||||
|
||||
/* stats struct */
|
||||
#include "libunbound/unbound.h"
|
||||
@@ -133,4 +134,11 @@ void server_stats_insrcode(struct ub_server_stats* stats, struct sldns_buffer* b
|
||||
*/
|
||||
void server_stats_downstream_cookie(struct ub_server_stats* stats,
|
||||
struct edns_data* edns);
|
||||
|
||||
/** Get the memory statistics for the program.
|
||||
* @param worker: with worker env and ptr to daemon.
|
||||
* @param mem: filled with memory usage value statistics.
|
||||
*/
|
||||
void stats_get_mem_info(struct worker* worker, struct ub_mem_stat_info* mem);
|
||||
|
||||
#endif /* DAEMON_STATS_H */
|
||||
|
||||
+97
-130
@@ -46,6 +46,7 @@
|
||||
#include "daemon/worker.h"
|
||||
#include "daemon/daemon.h"
|
||||
#include "daemon/remote.h"
|
||||
#include "daemon/metrics.h"
|
||||
#include "daemon/acl_list.h"
|
||||
#include "util/netevent.h"
|
||||
#include "util/config_file.h"
|
||||
@@ -293,44 +294,6 @@ 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
|
||||
@@ -368,6 +331,7 @@ worker_check_request(sldns_buffer* pkt, struct worker* worker,
|
||||
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;
|
||||
@@ -1009,7 +973,6 @@ 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,
|
||||
@@ -1268,7 +1231,9 @@ deny_refuse(struct comm_point* c, enum acl_access acl,
|
||||
worker_check_request(c->buffer, worker, check_result);
|
||||
if(check_result->value != 0) {
|
||||
if(check_result->value != -1) {
|
||||
query_error(c->buffer, check_result->value, 0);
|
||||
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
|
||||
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
|
||||
check_result->value);
|
||||
return 1;
|
||||
}
|
||||
comm_point_drop_reply(repinfo);
|
||||
@@ -1285,17 +1250,41 @@ 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) {
|
||||
query_error(c->buffer, LDNS_RCODE_REFUSED, 0);
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!query_dname_len(c->buffer)) {
|
||||
query_error(c->buffer, LDNS_RCODE_FORMERR, 0);
|
||||
LDNS_QDCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
|
||||
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
|
||||
LDNS_RCODE_FORMERR);
|
||||
sldns_buffer_set_position(c->buffer, LDNS_HEADER_SIZE);
|
||||
sldns_buffer_flip(c->buffer);
|
||||
return 1;
|
||||
}
|
||||
/* space available for query type and class? */
|
||||
if (sldns_buffer_remaining(c->buffer) < 2 * sizeof(uint16_t)) {
|
||||
query_error(c->buffer, LDNS_RCODE_FORMERR, 0);
|
||||
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
|
||||
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
|
||||
LDNS_RCODE_FORMERR);
|
||||
LDNS_QDCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
sldns_buffer_set_position(c->buffer, LDNS_HEADER_SIZE);
|
||||
sldns_buffer_flip(c->buffer);
|
||||
return 1;
|
||||
}
|
||||
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
|
||||
@@ -1317,27 +1306,35 @@ 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))))) {
|
||||
query_error(c->buffer, LDNS_RCODE_FORMERR,
|
||||
opt_rr_mark - LDNS_HEADER_SIZE
|
||||
- 2 /* qtype */ - 2 /* qclass */);
|
||||
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
|
||||
LDNS_RCODE_FORMERR);
|
||||
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
sldns_buffer_set_position(c->buffer, opt_rr_mark);
|
||||
sldns_buffer_flip(c->buffer);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
/* Do we have a valid OPT RR here? If not return REFUSED (could be a valid TSIG or something so no FORMERR) */
|
||||
/* domain name must be the root of length 1. */
|
||||
if(sldns_buffer_remaining(c->buffer) < 1 || *sldns_buffer_current(c->buffer) != 0) {
|
||||
query_error(c->buffer, LDNS_RCODE_REFUSED,
|
||||
opt_rr_mark - LDNS_HEADER_SIZE
|
||||
- 2 /* qtype */ - 2 /* qclass */);
|
||||
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
sldns_buffer_set_position(c->buffer, opt_rr_mark);
|
||||
sldns_buffer_flip(c->buffer);
|
||||
return 1;
|
||||
} else {
|
||||
sldns_buffer_skip(c->buffer, 1); /* skip root label */
|
||||
}
|
||||
if(sldns_buffer_remaining(c->buffer) < 2 ||
|
||||
sldns_buffer_read_u16(c->buffer) != LDNS_RR_TYPE_OPT) {
|
||||
query_error(c->buffer, LDNS_RCODE_REFUSED,
|
||||
opt_rr_mark - LDNS_HEADER_SIZE
|
||||
- 2 /* qtype */ - 2 /* qclass */);
|
||||
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
|
||||
sldns_buffer_set_position(c->buffer, opt_rr_mark);
|
||||
sldns_buffer_flip(c->buffer);
|
||||
return 1;
|
||||
}
|
||||
/* Write OPT RR directly after the query,
|
||||
@@ -1533,10 +1530,6 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
"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;
|
||||
}
|
||||
@@ -1545,13 +1538,8 @@ 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);
|
||||
if(worker_err_ratelimit(worker, LDNS_RCODE_FORMERR) == -1) {
|
||||
comm_point_drop_reply(repinfo);
|
||||
return 0;
|
||||
}
|
||||
query_error(c->buffer, LDNS_RCODE_FORMERR, 0);
|
||||
sldns_buffer_copy(c->dnscrypt_buffer, c->buffer);
|
||||
return 1;
|
||||
comm_point_drop_reply(repinfo);
|
||||
return 0;
|
||||
}
|
||||
dname_str(qinfo.qname, buf);
|
||||
if(!(qinfo.qtype == LDNS_RR_TYPE_TXT &&
|
||||
@@ -1562,15 +1550,9 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
worker->daemon->dnscenv->provider_name,
|
||||
sldns_rr_descript(qinfo.qtype)->_name,
|
||||
buf);
|
||||
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);
|
||||
comm_point_drop_reply(repinfo);
|
||||
worker->stats.num_query_dnscrypt_cleartext++;
|
||||
sldns_buffer_copy(c->dnscrypt_buffer, c->buffer);
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
worker->stats.num_query_dnscrypt_cert++;
|
||||
sldns_buffer_rewind(c->buffer);
|
||||
@@ -1610,7 +1592,9 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
verbose(VERB_ALGO, "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);
|
||||
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
|
||||
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
|
||||
check_result.value);
|
||||
return 1;
|
||||
}
|
||||
comm_point_drop_reply(repinfo);
|
||||
@@ -1644,7 +1628,10 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
comm_point_drop_reply(repinfo);
|
||||
return 0;
|
||||
}
|
||||
query_error(c->buffer, LDNS_RCODE_FORMERR, 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);
|
||||
goto send_reply;
|
||||
}
|
||||
if(worker->env.cfg->log_queries) {
|
||||
@@ -1657,11 +1644,10 @@ 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);
|
||||
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);
|
||||
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->stats.extended) {
|
||||
worker->stats.qtype[qinfo.qtype]++;
|
||||
}
|
||||
@@ -1680,7 +1666,10 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
comm_point_drop_reply(repinfo);
|
||||
return 0;
|
||||
}
|
||||
query_error(c->buffer, LDNS_RCODE_FORMERR, qinfo.qname_len);
|
||||
sldns_buffer_rewind(c->buffer);
|
||||
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
|
||||
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
|
||||
LDNS_RCODE_FORMERR);
|
||||
if(worker->stats.extended) {
|
||||
worker->stats.qtype[qinfo.qtype]++;
|
||||
}
|
||||
@@ -1694,11 +1683,6 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
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,
|
||||
@@ -1715,11 +1699,6 @@ 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);
|
||||
@@ -1765,11 +1744,6 @@ 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 *)
|
||||
@@ -1784,11 +1758,6 @@ 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");
|
||||
@@ -1815,14 +1784,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);
|
||||
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_QR_SET(sldns_buffer_begin(c->buffer));
|
||||
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;
|
||||
}
|
||||
@@ -1830,13 +1799,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
server_stats_insquery(&worker->stats, c, qinfo.qtype,
|
||||
qinfo.qclass, &edns, repinfo);
|
||||
if(c->type != comm_udp)
|
||||
#ifdef USE_DNSCRYPT
|
||||
edns.udp_size = (c->dnscrypt && repinfo->is_dnscrypted)
|
||||
? sldns_buffer_capacity(c->buffer) - DNSCRYPT_REPLY_HEADER_SIZE
|
||||
: 65535;
|
||||
#else
|
||||
edns.udp_size = 65535; /* max size for TCP replies */
|
||||
#endif
|
||||
if(qinfo.qclass == LDNS_RR_CLASS_CH && answer_chaos(worker, &qinfo,
|
||||
&edns, repinfo, c->buffer)) {
|
||||
regional_free_all(worker->scratchpad);
|
||||
@@ -1913,15 +1876,6 @@ 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, "");
|
||||
@@ -1930,6 +1884,9 @@ 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;
|
||||
}
|
||||
|
||||
@@ -2120,7 +2077,7 @@ send_reply_rc:
|
||||
}
|
||||
}
|
||||
#ifdef USE_DNSCRYPT
|
||||
if(!dnsc_handle_uncurved_request(repinfo, c->buffer)) {
|
||||
if(!dnsc_handle_uncurved_request(repinfo)) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -2233,16 +2190,23 @@ void worker_probe_timer_cb(void* arg)
|
||||
}
|
||||
|
||||
struct worker*
|
||||
worker_create(struct daemon* daemon, int id)
|
||||
worker_create(struct daemon* daemon, int id, int* ports, int n)
|
||||
{
|
||||
unsigned int seed;
|
||||
struct worker* worker = (struct worker*)calloc(1,
|
||||
sizeof(struct worker));
|
||||
if(!worker)
|
||||
return NULL;
|
||||
worker->numports = n;
|
||||
worker->ports = (int*)memdup(ports, sizeof(int)*n);
|
||||
if(!worker->ports) {
|
||||
free(worker);
|
||||
return NULL;
|
||||
}
|
||||
worker->daemon = daemon;
|
||||
worker->thread_num = id;
|
||||
if(!(worker->cmd = tube_create())) {
|
||||
free(worker->ports);
|
||||
free(worker);
|
||||
return NULL;
|
||||
}
|
||||
@@ -2250,6 +2214,7 @@ worker_create(struct daemon* daemon, int id)
|
||||
if(!(worker->rndstate = ub_initstate(daemon->rand))) {
|
||||
log_err("could not init random numbers.");
|
||||
tube_delete(worker->cmd);
|
||||
free(worker->ports);
|
||||
free(worker);
|
||||
return NULL;
|
||||
}
|
||||
@@ -2312,6 +2277,12 @@ worker_init(struct worker* worker, struct config_file *cfg,
|
||||
worker_delete(worker);
|
||||
return 0;
|
||||
}
|
||||
#ifdef USE_METRICS
|
||||
if(!daemon_metrics_attach(worker->daemon->metrics, worker)) {
|
||||
worker_delete(worker);
|
||||
return 0;
|
||||
}
|
||||
#endif /* USE METRICS */
|
||||
#ifdef UB_ON_WINDOWS
|
||||
wsvc_setup_worker(worker);
|
||||
#endif /* UB_ON_WINDOWS */
|
||||
@@ -2348,14 +2319,14 @@ worker_init(struct worker* worker, struct config_file *cfg,
|
||||
cfg->out_ifs, cfg->num_out_ifs, cfg->do_ip4, cfg->do_ip6,
|
||||
cfg->do_tcp?cfg->outgoing_num_tcp:0, cfg->ip_dscp,
|
||||
worker->daemon->env->infra_cache, worker->rndstate,
|
||||
cfg->use_caps_bits_for_id,
|
||||
cfg->use_caps_bits_for_id, worker->ports, worker->numports,
|
||||
cfg->unwanted_threshold, cfg->outgoing_tcp_mss,
|
||||
&worker_alloc_cleanup, worker,
|
||||
cfg->do_udp || cfg->udp_upstream_without_downstream,
|
||||
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, worker->daemon->shared_ports);
|
||||
cfg->tcp_auth_query_timeout);
|
||||
if(!worker->back) {
|
||||
log_err("could not create outgoing sockets");
|
||||
worker_delete(worker);
|
||||
@@ -2506,6 +2477,7 @@ worker_delete(struct worker* worker)
|
||||
tube_delete(worker->cmd);
|
||||
comm_timer_delete(worker->stat_timer);
|
||||
comm_timer_delete(worker->env.probe_timer);
|
||||
free(worker->ports);
|
||||
if(worker->thread_num == 0) {
|
||||
#ifdef UB_ON_WINDOWS
|
||||
wsvc_desetup_worker(worker);
|
||||
@@ -2637,11 +2609,6 @@ void libworker_event_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
|
||||
log_assert(0);
|
||||
}
|
||||
|
||||
void libworker_alloc_cleanup(void* ATTR_UNUSED(arg))
|
||||
{
|
||||
log_assert(0);
|
||||
}
|
||||
|
||||
int context_query_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
|
||||
{
|
||||
log_assert(0);
|
||||
|
||||
+7
-1
@@ -104,6 +104,10 @@ struct worker {
|
||||
struct listen_dnsport* front;
|
||||
/** the backside outside network interface to the auth servers */
|
||||
struct outside_network* back;
|
||||
/** ports to be used by this worker. */
|
||||
int* ports;
|
||||
/** number of ports for this worker */
|
||||
int numports;
|
||||
/** the signal handler */
|
||||
struct comm_signal* comsig;
|
||||
/** commpoint to listen to commands. */
|
||||
@@ -142,9 +146,11 @@ struct worker {
|
||||
* with backpointers only. Use worker_init on it later.
|
||||
* @param daemon: the daemon that this worker thread is part of.
|
||||
* @param id: the thread number from 0.. numthreads-1.
|
||||
* @param ports: the ports it is allowed to use, array.
|
||||
* @param n: the number of ports.
|
||||
* @return: the new worker or NULL on alloc failure.
|
||||
*/
|
||||
struct worker* worker_create(struct daemon* daemon, int id);
|
||||
struct worker* worker_create(struct daemon* daemon, int id, int* ports, int n);
|
||||
|
||||
/**
|
||||
* Initialize worker.
|
||||
|
||||
+4
-24
@@ -361,7 +361,7 @@ dnscrypt_server_uncurve(struct dnsc_env* env,
|
||||
|
||||
len -= DNSCRYPT_QUERY_HEADER_SIZE;
|
||||
|
||||
while (len>0 && *sldns_buffer_at(buffer, --len) == 0)
|
||||
while (*sldns_buffer_at(buffer, --len) == 0)
|
||||
;
|
||||
|
||||
if (*sldns_buffer_at(buffer, len) != 0x80) {
|
||||
@@ -474,18 +474,10 @@ dnscrypt_server_curve(const dnsccert *cert,
|
||||
uint8_t *const buf = sldns_buffer_begin(buffer);
|
||||
size_t len = sldns_buffer_limit(buffer);
|
||||
|
||||
if(len + DNSCRYPT_REPLY_HEADER_SIZE > sldns_buffer_capacity(buffer))
|
||||
return -1;
|
||||
sldns_buffer_clear(buffer);
|
||||
|
||||
if(udp){
|
||||
if (max_len > max_reply_size)
|
||||
max_len = max_reply_size;
|
||||
}
|
||||
if(max_len > sldns_buffer_capacity(buffer))
|
||||
max_len = sldns_buffer_capacity(buffer);
|
||||
if(max_len > 65535)
|
||||
max_len = 65535;
|
||||
|
||||
|
||||
memcpy(nonce, client_nonce, crypto_box_HALF_NONCEBYTES);
|
||||
@@ -528,7 +520,6 @@ dnscrypt_server_curve(const dnsccert *cert,
|
||||
DNSCRYPT_MAGIC_HEADER_LEN,
|
||||
nonce,
|
||||
crypto_box_NONCEBYTES);
|
||||
sldns_buffer_flip(buffer);
|
||||
sldns_buffer_set_limit(buffer, len + DNSCRYPT_REPLY_HEADER_SIZE);
|
||||
return 0;
|
||||
}
|
||||
@@ -672,8 +663,6 @@ dnsc_find_cert(struct dnsc_env* dnscenv, struct sldns_buffer* buffer)
|
||||
}
|
||||
dnscrypt_header = (struct dnscrypt_query_header *)sldns_buffer_begin(buffer);
|
||||
for (i = 0U; i < dnscenv->signed_certs_count; i++) {
|
||||
if(!certs[i].keypair)
|
||||
continue;
|
||||
if (memcmp(certs[i].magic_query, dnscrypt_header->magic_query,
|
||||
DNSCRYPT_MAGIC_HEADER_LEN) == 0) {
|
||||
return &certs[i];
|
||||
@@ -815,7 +804,6 @@ dnsc_parse_keys(struct dnsc_env *env, struct config_file *cfg)
|
||||
sizeof *env->keypairs);
|
||||
env->certs = sodium_allocarray(env->signed_certs_count,
|
||||
sizeof *env->certs);
|
||||
memset(env->certs, 0, env->signed_certs_count * sizeof(*env->certs));
|
||||
|
||||
cert_id = 0U;
|
||||
keypair_id = 0U;
|
||||
@@ -924,13 +912,12 @@ dnsc_handle_curved_request(struct dnsc_env* dnscenv,
|
||||
}
|
||||
|
||||
int
|
||||
dnsc_handle_uncurved_request(struct comm_reply *repinfo,
|
||||
struct sldns_buffer* buffer)
|
||||
dnsc_handle_uncurved_request(struct comm_reply *repinfo)
|
||||
{
|
||||
if(!repinfo->c->dnscrypt) {
|
||||
return 1;
|
||||
}
|
||||
sldns_buffer_copy(repinfo->c->dnscrypt_buffer, buffer);
|
||||
sldns_buffer_copy(repinfo->c->dnscrypt_buffer, repinfo->c->buffer);
|
||||
if(!repinfo->is_dnscrypted) {
|
||||
return 1;
|
||||
}
|
||||
@@ -976,19 +963,12 @@ dnsc_create(void)
|
||||
int
|
||||
dnsc_apply_cfg(struct dnsc_env *env, struct config_file *cfg)
|
||||
{
|
||||
int nkeys;
|
||||
if(dnsc_parse_certs(env, cfg) <= 0) {
|
||||
fatal_exit("dnsc_apply_cfg: no cert file loaded");
|
||||
}
|
||||
nkeys = dnsc_parse_keys(env, cfg);
|
||||
if(nkeys <= 0) {
|
||||
if(dnsc_parse_keys(env, cfg) <= 0) {
|
||||
fatal_exit("dnsc_apply_cfg: no key file loaded");
|
||||
}
|
||||
if((size_t)nkeys < env->signed_certs_count) {
|
||||
fatal_exit("dnsc_apply_cfg: %u dnscrypt-provider-cert file(s) have no "
|
||||
"matching dnscrypt-secret-key",
|
||||
(unsigned)(env->signed_certs_count - (size_t)nkeys));
|
||||
}
|
||||
randombytes_buf(env->hash_key, sizeof env->hash_key);
|
||||
env->provider_name = cfg->dnscrypt_provider;
|
||||
|
||||
|
||||
+1
-2
@@ -128,8 +128,7 @@ int dnsc_handle_curved_request(struct dnsc_env* dnscenv,
|
||||
* \return 0 in case of failure.
|
||||
*/
|
||||
|
||||
int dnsc_handle_uncurved_request(struct comm_reply *repinfo,
|
||||
struct sldns_buffer* buffer);
|
||||
int dnsc_handle_uncurved_request(struct comm_reply *repinfo);
|
||||
|
||||
/**
|
||||
* Computes the size of the shared secret cache entry.
|
||||
|
||||
@@ -2133,8 +2133,6 @@ static void* dnstap_io(void* arg)
|
||||
struct dt_io_thread* dtio = (struct dt_io_thread*)arg;
|
||||
time_t secs = 0;
|
||||
struct timeval now;
|
||||
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();
|
||||
@@ -2144,8 +2142,6 @@ static void* dnstap_io(void* arg)
|
||||
#endif
|
||||
log_thread_set(&dtio->threadnum);
|
||||
|
||||
ub_thread_setname(dtio->tid, name);
|
||||
|
||||
/* setup */
|
||||
verbose(VERB_ALGO, "start dnstap io thread");
|
||||
dtio_setup_base(dtio, &secs, &now);
|
||||
|
||||
@@ -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* tls_protocols)
|
||||
char* server_cert, char* verifypem)
|
||||
{
|
||||
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, tls_protocols);
|
||||
NULL, NULL, 0, 0, 0, 0);
|
||||
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* tls_protocols)
|
||||
char* server_cert, char* verifypem)
|
||||
{
|
||||
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, tls_protocols);
|
||||
maindata, server_key, server_cert, verifypem);
|
||||
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* tls_protocols)
|
||||
char* server_cert, char* verifypem)
|
||||
{
|
||||
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, tls_protocols);
|
||||
verifypem);
|
||||
if(!tap_socket_list_addevs(maindata->acceptlist, base))
|
||||
fatal_exit("could not setup accept events");
|
||||
if(verbosity) log_info("start of service");
|
||||
@@ -1462,8 +1462,6 @@ 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) {
|
||||
@@ -1581,7 +1579,7 @@ int main(int argc, char** argv)
|
||||
#endif /* HAVE_SSL */
|
||||
}
|
||||
setup_and_run(&local_list, &tcp_list, &tls_list, server_key,
|
||||
server_cert, verifypem, tls_protocols);
|
||||
server_cert, verifypem);
|
||||
config_delstrlist(local_list.first);
|
||||
config_delstrlist(tcp_list.first);
|
||||
config_delstrlist(tls_list.first);
|
||||
@@ -1735,11 +1733,6 @@ void libworker_event_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
|
||||
log_assert(0);
|
||||
}
|
||||
|
||||
void libworker_alloc_cleanup(void* ATTR_UNUSED(arg))
|
||||
{
|
||||
log_assert(0);
|
||||
}
|
||||
|
||||
int context_query_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
|
||||
{
|
||||
log_assert(0);
|
||||
|
||||
-163
@@ -1,166 +1,3 @@
|
||||
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.
|
||||
|
||||
|
||||
+25
-7
@@ -193,9 +193,6 @@ 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
|
||||
|
||||
@@ -968,12 +965,16 @@ 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 restart.
|
||||
# Changing the value requires a reload.
|
||||
# tls-use-sni: yes
|
||||
|
||||
# TLS protocols.
|
||||
# Changing the value requires a restart.
|
||||
# tls-protocols: "TLSv1.2 TLSv1.3"
|
||||
# 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 a compilation choice.
|
||||
# With 'no' Unbound will only use the latest available TLS version.
|
||||
# Changing the value requires a reload.
|
||||
# tls-use-system-policy-versions: no
|
||||
|
||||
# Add the secret file for TLS Session Ticket.
|
||||
# Secret file must be 80 bytes of random data.
|
||||
@@ -1158,6 +1159,23 @@ server:
|
||||
# Timeout in milliseconds for TCP queries to auth servers.
|
||||
# tcp-auth-query-timeout: 3000
|
||||
|
||||
# Enable the prometheus metrics HTTP endpoint. Default is no.
|
||||
# metrics-enable: no
|
||||
|
||||
# Interfaces to expose the HTTP endpoint on, default is on localhost.
|
||||
# Interfaces can be specified by IP address or interface name.
|
||||
# With an interface name, all IP addresses associated with that
|
||||
# interface are used. Default is 127.0.0.1 and ::1.
|
||||
# metrics-interface: 127.0.0.1
|
||||
# metrics-interface: ::1
|
||||
# metrics-interface: lo
|
||||
|
||||
# Port number for the HTTP metrics endpoint. Default is 9100.
|
||||
# metrics-port: 9100
|
||||
|
||||
# HTTP path for the metrics endpoint. Default is "/metrics".
|
||||
# metrics-path: "/metrics"
|
||||
|
||||
|
||||
# Python config section. To enable:
|
||||
# o use --with-pythonmodule to configure before compiling.
|
||||
|
||||
@@ -168,8 +168,6 @@ 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
|
||||
|
||||
+25
-29
@@ -1139,13 +1139,9 @@ 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.
|
||||
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.
|
||||
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).
|
||||
The ports enabled implicitly or explicitly via
|
||||
\fI\%tls\-port\fP and
|
||||
\fI\%https\-port\fP do not provide normal DNS TCP
|
||||
@@ -1298,7 +1294,7 @@ Enable or disable sending the SNI extension on TLS connections.
|
||||
\fBNOTE:\fP
|
||||
.INDENT 7.0
|
||||
.INDENT 3.5
|
||||
Changing the value requires a restart.
|
||||
Changing the value requires a reload.
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
@@ -1306,19 +1302,33 @@ Default: yes
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.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.
|
||||
.B tls\-use\-system\-policy\-versions: \fI<yes or no>\fP
|
||||
Enable or disable general\-purpose 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
|
||||
If disabled Unbound only uses the latest available TLS version.
|
||||
.sp
|
||||
The default depends on a compilation choice, it is set
|
||||
at @SYSTEM_TLS_DEFAULT@ .
|
||||
.sp
|
||||
\fBCAUTION:\fP
|
||||
.INDENT 7.0
|
||||
.INDENT 3.5
|
||||
Use only if you want to support legacy TLS client connections.
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
\fBNOTE:\fP
|
||||
.INDENT 7.0
|
||||
.INDENT 3.5
|
||||
Changing the value requires a restart.
|
||||
Changing the value requires a reload.
|
||||
.UNINDENT
|
||||
.UNINDENT
|
||||
.sp
|
||||
Default: \(dqTLSv1.2 TLSv1.3\(dq
|
||||
Default: @SYSTEM_TLS_DEFAULT@
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
@@ -3769,10 +3779,6 @@ 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
|
||||
@@ -3800,16 +3806,6 @@ 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.
|
||||
@@ -3991,7 +3987,7 @@ Default: no
|
||||
.UNINDENT
|
||||
.INDENT 0.0
|
||||
.TP
|
||||
.B control\-interface: \fI<IP address or interface name[@port] or path>\fP
|
||||
.B control\-interface: \fI<IP address or interface name 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
|
||||
|
||||
+68
-27
@@ -247,6 +247,8 @@ These options are part of the ``server:`` section.
|
||||
:doc:`unbound-control(8)</manpages/unbound-control>`.
|
||||
The counters are listed in
|
||||
:doc:`unbound-control(8)</manpages/unbound-control>`.
|
||||
The counters are also available from the metrics interface,
|
||||
:ref:`metrics-enable<unbound.conf.metrics-enable>` .
|
||||
Keeping track of more statistics takes time.
|
||||
|
||||
Default: no
|
||||
@@ -1180,19 +1182,28 @@ 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 restart.
|
||||
.. note:: Changing the value requires a reload.
|
||||
|
||||
Default: yes
|
||||
|
||||
|
||||
@@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.
|
||||
@@UAHL@unbound.conf@tls-use-system-policy-versions@@: *<yes or no>*
|
||||
Enable or disable general-purpose 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.
|
||||
|
||||
.. note:: Changing the value requires a restart.
|
||||
If disabled Unbound only uses the latest available TLS version.
|
||||
|
||||
Default: "TLSv1.2 TLSv1.3"
|
||||
The default depends on a compilation choice, it is set
|
||||
at @SYSTEM_TLS_DEFAULT@ .
|
||||
|
||||
.. caution:: Use only if you want to support legacy TLS client connections.
|
||||
|
||||
.. note:: Changing the value requires a reload.
|
||||
|
||||
Default: @SYSTEM_TLS_DEFAULT@
|
||||
|
||||
|
||||
@@UAHL@unbound.conf@pad-responses@@: *<yes or no>*
|
||||
@@ -2055,13 +2066,6 @@ These options are part of the ``server:`` section.
|
||||
flushing away any poison.
|
||||
A value of 10 million is suggested.
|
||||
|
||||
It is useful to add 0.0.0.0/8 and '::' to the
|
||||
:ref:`do-not-query-address<unbound.conf.do-not-query-address>` list.
|
||||
Otherwise they may be answered, from localhost, and the different source
|
||||
makes an unwanted reply that unnecessarily ticks up.
|
||||
The :ref:`do-not-query-localhost<unbound.conf.do-not-query-localhost>`
|
||||
option includes them, the zero subnets, when it is enabled.
|
||||
|
||||
Default: 0 (disabled)
|
||||
|
||||
|
||||
@@ -3267,10 +3271,6 @@ 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.
|
||||
|
||||
@@ -3295,15 +3295,6 @@ 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.
|
||||
@@ -3444,6 +3435,56 @@ These options are part of the ``server:`` section.
|
||||
|
||||
Default: no
|
||||
|
||||
|
||||
@@UAHL@unbound.conf@metrics-enable@@: *<yes or no>*
|
||||
Enable the prometheus metrics HTTP endpoint.
|
||||
It exposes the same statistics as the
|
||||
:ref:`stats_noreset<unbound-control.commands.stats_noreset>`,
|
||||
command, but with metric names
|
||||
following the prometheus specification. (Requires libevent2)
|
||||
|
||||
Use it with settings, extended-statistics: yes that collects more
|
||||
information,
|
||||
:ref:`extended-statistics<unbound.conf.extended-statistics>` .
|
||||
And set statistics-cumulative: yes, because the metrics are
|
||||
defined as cumulative counters for the number of queries,
|
||||
:ref:`statistics-cumulative<unbound.conf.statistics-cumulative>` .
|
||||
|
||||
Access from the metrics endpoint does not reset the statistics.
|
||||
Beware, if statistics-cumulative is disabled, that when using
|
||||
:ref:`stats<unbound-control.commands.stats`
|
||||
(instead of stats_noreset), the statistics will be reset for
|
||||
the HTTP metrics endpoint as well.
|
||||
With statistics-cumulative enabled, the stats (and stats_noreset)
|
||||
command can be used to also get a look at the statistics information.
|
||||
|
||||
Default: no
|
||||
|
||||
|
||||
@@UAHL@unbound.conf@metrics-interface@@: *<ip4 or ip6[@port] | interface name>*
|
||||
Unbound will bind to the listed addresses or interfaces to serve the
|
||||
prometheus metrics.
|
||||
Can be given multiple times to bind multiple ip-addresses.
|
||||
Use 0.0.0.0 and ::0 to bind to the wildcard interface.
|
||||
|
||||
If an interface name is used instead of ip4 or ip6, the list of IP
|
||||
addresses associated with that interface is picked up and used at
|
||||
server start.
|
||||
|
||||
Default is 127.0.0.1 and ::1.
|
||||
|
||||
|
||||
@@UAHL@unbound.conf@metrics-port@@: *<number>*
|
||||
The port number for the HTTP service.
|
||||
|
||||
Default is 9100.
|
||||
|
||||
|
||||
@@UAHL@unbound.conf@metrics-path@@: *<string>*
|
||||
The HTTP path to expose the metrics at.
|
||||
|
||||
Default is "/metrics".
|
||||
|
||||
.. _unbound.conf.remote:
|
||||
|
||||
Remote Control Options
|
||||
|
||||
+1
-75
@@ -70,7 +70,6 @@ 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);
|
||||
}
|
||||
|
||||
@@ -85,8 +84,6 @@ 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;
|
||||
}
|
||||
|
||||
@@ -203,18 +200,12 @@ 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
|
||||
@@ -436,35 +427,6 @@ 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);
|
||||
@@ -508,21 +470,6 @@ 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)
|
||||
@@ -551,20 +498,12 @@ 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;
|
||||
}
|
||||
@@ -573,16 +512,11 @@ 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. */
|
||||
@@ -718,12 +652,6 @@ 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;
|
||||
}
|
||||
|
||||
@@ -973,11 +901,9 @@ 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,18 +69,8 @@ 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 {
|
||||
|
||||
@@ -132,18 +132,6 @@ donotq_apply_cfg(struct iter_donotq* dq, struct config_file* cfg)
|
||||
if(cfg->do_ip6) {
|
||||
if(!donotq_str_cfg(dq, "::1"))
|
||||
return 0;
|
||||
if(!donotq_str_cfg(dq, "::ffff:127.0.0.0/104"))
|
||||
return 0;
|
||||
}
|
||||
/* RFC 1122 3.2.1.3 / RFC 6890 / RFC 4291 2.5.2: not valid as
|
||||
* destination; on Linux these route to the local host. */
|
||||
if(!donotq_str_cfg(dq, "0.0.0.0/8"))
|
||||
return 0;
|
||||
if(cfg->do_ip6) {
|
||||
if(!donotq_str_cfg(dq, "::"))
|
||||
return 0;
|
||||
if(!donotq_str_cfg(dq, "::ffff:0:0/96"))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
addr_tree_init_parents(&dq->tree);
|
||||
|
||||
+1
-50
@@ -419,43 +419,6 @@ 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
|
||||
@@ -493,8 +456,6 @@ 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
|
||||
@@ -670,8 +631,6 @@ 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 */
|
||||
@@ -777,13 +736,7 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
|
||||
rrset->rrset_all_next = NULL;
|
||||
return 1;
|
||||
}
|
||||
/* 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);
|
||||
mark_additional_rrset(pkt, msg, rrset);
|
||||
prev = rrset;
|
||||
rrset = rrset->rrset_all_next;
|
||||
}
|
||||
@@ -820,8 +773,6 @@ 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;
|
||||
}
|
||||
|
||||
+22
-61
@@ -81,8 +81,7 @@ int BLACKLIST_PENALTY = (120000*4);
|
||||
/** Timeout when only a single probe query per IP is allowed. */
|
||||
int PROBE_MAXRTO = PROBE_MAXRTO_DEFAULT; /* in msec */
|
||||
|
||||
static void target_count_increase_nx(struct module_qstate* qstate,
|
||||
struct iter_qstate* iq, int num);
|
||||
static void target_count_increase_nx(struct iter_qstate* iq, int num);
|
||||
|
||||
int
|
||||
iter_init(struct module_env* env, int id)
|
||||
@@ -251,7 +250,7 @@ error_supers(struct module_qstate* qstate, int id, struct module_qstate* super)
|
||||
if((dpns->got4 == 2 || (!ie->supports_ipv4 && !ie->nat64.use_nat64)) &&
|
||||
(dpns->got6 == 2 || !ie->supports_ipv6)) {
|
||||
dpns->resolved = 1; /* mark as failed */
|
||||
target_count_increase_nx(super, super_iq, 1);
|
||||
target_count_increase_nx(super_iq, 1);
|
||||
}
|
||||
}
|
||||
if(qstate->qinfo.qtype == LDNS_RR_TYPE_NS) {
|
||||
@@ -298,7 +297,6 @@ 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) {
|
||||
@@ -735,7 +733,7 @@ is_caps_whitelisted(struct iter_env* ie, struct iter_qstate* iq)
|
||||
* created for the parent query.
|
||||
*/
|
||||
static void
|
||||
target_count_create(struct module_qstate* qstate, struct iter_qstate* iq)
|
||||
target_count_create(struct iter_qstate* iq)
|
||||
{
|
||||
if(!iq->target_count) {
|
||||
iq->target_count = (int*)calloc(TARGET_COUNT_MAX, sizeof(int));
|
||||
@@ -743,57 +741,33 @@ target_count_create(struct module_qstate* qstate, struct iter_qstate* iq)
|
||||
if(iq->target_count) {
|
||||
iq->target_count[TARGET_COUNT_REF] = 1;
|
||||
iq->nxns_dp = (uint8_t**)calloc(1, sizeof(uint8_t*));
|
||||
/* continue global quota from where it was. */
|
||||
if(qstate->global_quota_reached >
|
||||
iq->target_count[TARGET_COUNT_GLOBAL_QUOTA])
|
||||
iq->target_count[TARGET_COUNT_GLOBAL_QUOTA] =
|
||||
qstate->global_quota_reached;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
target_count_store(struct module_qstate* qstate, struct iter_qstate* iq)
|
||||
target_count_increase(struct iter_qstate* iq, int num)
|
||||
{
|
||||
if(iq->target_count) {
|
||||
/* By storing the global quota counter, it stays
|
||||
* there to be picked up if the module is restarted,
|
||||
* eg. due to a validator retry, and then the
|
||||
* target_count_create routine picks it up. */
|
||||
if(iq->target_count[TARGET_COUNT_GLOBAL_QUOTA] >
|
||||
qstate->global_quota_reached)
|
||||
qstate->global_quota_reached =
|
||||
iq->target_count[TARGET_COUNT_GLOBAL_QUOTA];
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
target_count_increase(struct module_qstate* qstate,
|
||||
struct iter_qstate* iq, int num)
|
||||
{
|
||||
target_count_create(qstate, iq);
|
||||
target_count_create(iq);
|
||||
if(iq->target_count)
|
||||
iq->target_count[TARGET_COUNT_QUERIES] += num;
|
||||
iq->dp_target_count++;
|
||||
}
|
||||
|
||||
static void
|
||||
target_count_increase_nx(struct module_qstate* qstate,
|
||||
struct iter_qstate* iq, int num)
|
||||
target_count_increase_nx(struct iter_qstate* iq, int num)
|
||||
{
|
||||
target_count_create(qstate, iq);
|
||||
target_count_create(iq);
|
||||
if(iq->target_count)
|
||||
iq->target_count[TARGET_COUNT_NX] += num;
|
||||
}
|
||||
|
||||
static void
|
||||
target_count_increase_global_quota(struct module_qstate* qstate,
|
||||
struct iter_qstate* iq, int num)
|
||||
target_count_increase_global_quota(struct iter_qstate* iq, int num)
|
||||
{
|
||||
target_count_create(qstate, iq);
|
||||
target_count_create(iq);
|
||||
if(iq->target_count)
|
||||
iq->target_count[TARGET_COUNT_GLOBAL_QUOTA] += num;
|
||||
target_count_store(qstate, iq);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -886,7 +860,7 @@ generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype,
|
||||
subiq = (struct iter_qstate*)subq->minfo[id];
|
||||
memset(subiq, 0, sizeof(*subiq));
|
||||
subiq->num_target_queries = 0;
|
||||
target_count_create(qstate, iq);
|
||||
target_count_create(iq);
|
||||
subiq->target_count = iq->target_count;
|
||||
if(iq->target_count) {
|
||||
iq->target_count[TARGET_COUNT_REF] ++; /* extra reference */
|
||||
@@ -2259,7 +2233,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
iq->num_target_queries += qs;
|
||||
target_count_increase(qstate, iq, qs);
|
||||
target_count_increase(iq, qs);
|
||||
if(qs != 0) {
|
||||
qstate->ext_state[id] = module_wait_subquery;
|
||||
return 0; /* and wait for them */
|
||||
@@ -2315,7 +2289,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
* lookups at a time. */
|
||||
verbose(VERB_ALGO, "try parent-side glue lookup");
|
||||
iq->num_target_queries += query_count;
|
||||
target_count_increase(qstate, iq, query_count);
|
||||
target_count_increase(iq, query_count);
|
||||
qstate->ext_state[id] = module_wait_subquery;
|
||||
return 0;
|
||||
}
|
||||
@@ -2335,7 +2309,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
if(query_count != 0) { /* suspend to await results */
|
||||
verbose(VERB_ALGO, "try parent-side glue lookup");
|
||||
iq->num_target_queries += query_count;
|
||||
target_count_increase(qstate, iq, query_count);
|
||||
target_count_increase(iq, query_count);
|
||||
qstate->ext_state[id] = module_wait_subquery;
|
||||
return 0;
|
||||
}
|
||||
@@ -2813,7 +2787,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
iq->num_target_queries += extra;
|
||||
target_count_increase(qstate, iq, extra);
|
||||
target_count_increase(iq, extra);
|
||||
if(iq->num_target_queries > 0) {
|
||||
/* wait to get all targets, we want to try em */
|
||||
verbose(VERB_ALGO, "wait for all targets for fallback");
|
||||
@@ -2864,7 +2838,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
/* errors ignored, these targets are not strictly necessary for
|
||||
* this result, we do not have to reply with SERVFAIL */
|
||||
iq->num_target_queries += extra;
|
||||
target_count_increase(qstate, iq, extra);
|
||||
target_count_increase(iq, extra);
|
||||
}
|
||||
|
||||
/* Add the current set of unused targets to our queue. */
|
||||
@@ -2987,7 +2961,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
iq->num_target_queries += qs;
|
||||
target_count_increase(qstate, iq, qs);
|
||||
target_count_increase(iq, qs);
|
||||
}
|
||||
/* Since a target query might have been made, we
|
||||
* need to check again. */
|
||||
@@ -3047,7 +3021,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
* this result, we do not have to reply with SERVFAIL */
|
||||
if(extra > 0) {
|
||||
iq->num_target_queries += extra;
|
||||
target_count_increase(qstate, iq, extra);
|
||||
target_count_increase(iq, extra);
|
||||
check_waiting_queries(iq, qstate, id);
|
||||
/* undo qname minimise step because we'll get back here
|
||||
* to do it again */
|
||||
@@ -3060,7 +3034,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
}
|
||||
}
|
||||
|
||||
target_count_increase_global_quota(qstate, iq, 1);
|
||||
target_count_increase_global_quota(iq, 1);
|
||||
if(iq->target_count && iq->target_count[TARGET_COUNT_GLOBAL_QUOTA]
|
||||
> MAX_GLOBAL_QUOTA) {
|
||||
char s[LDNS_MAX_DOMAINLEN];
|
||||
@@ -3249,19 +3223,8 @@ 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 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;
|
||||
}
|
||||
}
|
||||
/* YXDOMAIN is a permanent error, no need to retry */
|
||||
type = RESPONSE_TYPE_ANSWER;
|
||||
}
|
||||
if(type == RESPONSE_TYPE_CNAME)
|
||||
origtypecname = 1;
|
||||
@@ -3904,7 +3867,7 @@ processTargetResponse(struct module_qstate* qstate, int id,
|
||||
/* no new addresses, increase the nxns counter, like
|
||||
* this could be a list of wildcards with no new
|
||||
* addresses */
|
||||
target_count_increase_nx(qstate, foriq, 1);
|
||||
target_count_increase_nx(foriq, 1);
|
||||
}
|
||||
verbose(VERB_ALGO, "added target response");
|
||||
delegpt_log(VERB_ALGO, foriq->dp);
|
||||
@@ -3916,7 +3879,7 @@ processTargetResponse(struct module_qstate* qstate, int id,
|
||||
dpns->resolved = 1; /* fail the target */
|
||||
/* do not count cached answers */
|
||||
if(qstate->reply_origin && qstate->reply_origin->len != 0) {
|
||||
target_count_increase_nx(qstate, foriq, 1);
|
||||
target_count_increase_nx(foriq, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4141,7 +4104,6 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
iter_store_parentside_neg(qstate->env, &qstate->qinfo,
|
||||
iq->deleg_msg?iq->deleg_msg->rep:
|
||||
(iq->response?iq->response->rep:NULL));
|
||||
target_count_store(qstate, iq);
|
||||
if(!iq->response) {
|
||||
verbose(VERB_ALGO, "No response is set, servfail");
|
||||
errinf(qstate, "(no response found at query finish)");
|
||||
@@ -4557,7 +4519,6 @@ iter_clear(struct module_qstate* qstate, int id)
|
||||
iq = (struct iter_qstate*)qstate->minfo[id];
|
||||
if(iq) {
|
||||
outbound_list_clear(&iq->outlist);
|
||||
target_count_store(qstate, iq);
|
||||
if(iq->target_count && --iq->target_count[TARGET_COUNT_REF] == 0) {
|
||||
free(iq->target_count);
|
||||
if(*iq->nxns_dp) free(*iq->nxns_dp);
|
||||
|
||||
+2
-11
@@ -105,7 +105,6 @@ libworker_delete_env(struct libworker* w)
|
||||
SSL_CTX_free(w->sslctx);
|
||||
#endif
|
||||
outside_network_delete(w->back);
|
||||
shared_ports_delete(w->shared_ports);
|
||||
}
|
||||
|
||||
/** delete libworker struct */
|
||||
@@ -220,25 +219,17 @@ libworker_setup(struct ub_ctx* ctx, int is_bg, struct ub_event_base* eb)
|
||||
libworker_delete(w);
|
||||
return NULL;
|
||||
}
|
||||
if(!(w->shared_ports = shared_ports_create(cfg->out_ifs,
|
||||
cfg->num_out_ifs, cfg->do_ip4, cfg->do_ip6, ports, numports))) {
|
||||
if(!w->is_bg || w->is_bg_thread) {
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
}
|
||||
libworker_delete(w);
|
||||
return NULL;
|
||||
}
|
||||
w->back = outside_network_create(w->base, cfg->msg_buffer_size,
|
||||
(size_t)cfg->outgoing_num_ports, cfg->out_ifs,
|
||||
cfg->num_out_ifs, cfg->do_ip4, cfg->do_ip6,
|
||||
cfg->do_tcp?cfg->outgoing_num_tcp:0, cfg->ip_dscp,
|
||||
w->env->infra_cache, w->env->rnd, cfg->use_caps_bits_for_id,
|
||||
cfg->unwanted_threshold,
|
||||
ports, numports, cfg->unwanted_threshold,
|
||||
cfg->outgoing_tcp_mss, &libworker_alloc_cleanup, w,
|
||||
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, w->shared_ports);
|
||||
cfg->tcp_auth_query_timeout);
|
||||
w->env->outnet = w->back;
|
||||
if(!w->is_bg || w->is_bg_thread) {
|
||||
lock_basic_unlock(&ctx->cfglock);
|
||||
|
||||
@@ -60,7 +60,6 @@ struct tube;
|
||||
struct sldns_buffer;
|
||||
struct ub_event_base;
|
||||
struct query_info;
|
||||
struct shared_ports;
|
||||
|
||||
/**
|
||||
* The library-worker status structure
|
||||
@@ -85,8 +84,6 @@ struct libworker {
|
||||
struct comm_base* base;
|
||||
/** the backside outside network interface to the auth servers */
|
||||
struct outside_network* back;
|
||||
/** shared ports structure */
|
||||
struct shared_ports* shared_ports;
|
||||
/** random() table for this worker. */
|
||||
struct ub_randstate* rndstate;
|
||||
/** sslcontext for SSL wrapped DNS over TCP queries */
|
||||
|
||||
+17
-12
@@ -649,6 +649,22 @@ int ub_ctx_data_remove(struct ub_ctx* ctx, const char *data);
|
||||
*/
|
||||
const char* ub_version(void);
|
||||
|
||||
/**
|
||||
* Memory statistics values. The values describe memory usage (in bytes).
|
||||
*/
|
||||
struct ub_mem_stat_info {
|
||||
long long msg;
|
||||
long long rrset;
|
||||
long long val;
|
||||
long long iter;
|
||||
long long subnet;
|
||||
long long ipsecmod;
|
||||
long long respip;
|
||||
long long dnscrypt_shared_secret;
|
||||
long long dnscrypt_nonce;
|
||||
long long dynlib;
|
||||
};
|
||||
|
||||
/**
|
||||
* Some global statistics that are not in struct stats_info,
|
||||
* this struct is shared on a shm segment (shm-key in unbound.conf)
|
||||
@@ -662,18 +678,7 @@ struct ub_shm_stat_info {
|
||||
long long elapsed_sec, elapsed_usec;
|
||||
} time;
|
||||
|
||||
struct {
|
||||
long long msg;
|
||||
long long rrset;
|
||||
long long val;
|
||||
long long iter;
|
||||
long long subnet;
|
||||
long long ipsecmod;
|
||||
long long respip;
|
||||
long long dnscrypt_shared_secret;
|
||||
long long dnscrypt_nonce;
|
||||
long long dynlib;
|
||||
} mem;
|
||||
struct ub_mem_stat_info mem;
|
||||
};
|
||||
|
||||
/** number of qtype that is stored for in array */
|
||||
|
||||
+1
-7
@@ -1114,13 +1114,7 @@ respip_operate(struct module_qstate* qstate, enum module_ev event, int id,
|
||||
if((qstate->qinfo.qtype == LDNS_RR_TYPE_A ||
|
||||
qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA ||
|
||||
qstate->qinfo.qtype == LDNS_RR_TYPE_ANY) &&
|
||||
qstate->return_msg && qstate->return_msg->rep &&
|
||||
!(qstate->env->need_to_validate &&
|
||||
(!(qstate->query_flags & BIT_CD)
|
||||
|| qstate->env->cfg->ignore_cd) &&
|
||||
(qstate->return_msg->rep->security <= sec_status_bogus
|
||||
|| qstate->return_msg->rep->security ==
|
||||
sec_status_secure_sentinel_fail))) {
|
||||
qstate->return_msg && qstate->return_msg->rep) {
|
||||
struct reply_info* new_rep = qstate->return_msg->rep;
|
||||
struct ub_packed_rrset_key* alias_rrset = NULL;
|
||||
struct respip_action_info actinfo = {0, 0, 0, 0, NULL, 0, NULL};
|
||||
|
||||
+8
-44
@@ -1369,10 +1369,6 @@ 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 */
|
||||
@@ -1380,6 +1376,8 @@ 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--;
|
||||
@@ -2005,21 +2003,12 @@ 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;
|
||||
@@ -2032,21 +2021,12 @@ 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;
|
||||
@@ -5745,7 +5725,8 @@ xfr_master_add_addrs(struct auth_master* m, struct ub_packed_rrset_key* rrset,
|
||||
|
||||
/** callback for task_transfer lookup of host name, of A or AAAA */
|
||||
void auth_xfer_transfer_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
|
||||
enum sec_status sec, char* why_bogus, int ATTR_UNUSED(was_ratelimited))
|
||||
enum sec_status ATTR_UNUSED(sec), char* ATTR_UNUSED(why_bogus),
|
||||
int ATTR_UNUSED(was_ratelimited))
|
||||
{
|
||||
struct auth_xfer* xfr = (struct auth_xfer*)arg;
|
||||
struct module_env* env;
|
||||
@@ -5758,16 +5739,7 @@ void auth_xfer_transfer_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
|
||||
}
|
||||
|
||||
/* process result */
|
||||
if(sec == sec_status_bogus || sec == sec_status_secure_sentinel_fail) {
|
||||
if(verbosity >= VERB_OPS) {
|
||||
char zname[LDNS_MAX_DOMAINLEN];
|
||||
dname_str(xfr->name, zname);
|
||||
verbose(VERB_OPS, "auth zone %s: primary %s address lookup is DNSSEC bogus: %s",
|
||||
zname, xfr->task_transfer->lookup_target->host,
|
||||
(why_bogus?why_bogus:""));
|
||||
}
|
||||
/* fall through to next-lookup / next-master */
|
||||
} else if(rcode == LDNS_RCODE_NOERROR) {
|
||||
if(rcode == LDNS_RCODE_NOERROR) {
|
||||
uint16_t wanted_qtype = LDNS_RR_TYPE_A;
|
||||
struct regional* temp = env->scratch;
|
||||
struct query_info rq;
|
||||
@@ -6838,7 +6810,8 @@ xfr_probe_send_or_end(struct auth_xfer* xfr, struct module_env* env)
|
||||
|
||||
/** callback for task_probe lookup of host name, of A or AAAA */
|
||||
void auth_xfer_probe_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
|
||||
enum sec_status sec, char* why_bogus, int ATTR_UNUSED(was_ratelimited))
|
||||
enum sec_status ATTR_UNUSED(sec), char* ATTR_UNUSED(why_bogus),
|
||||
int ATTR_UNUSED(was_ratelimited))
|
||||
{
|
||||
struct auth_xfer* xfr = (struct auth_xfer*)arg;
|
||||
struct module_env* env;
|
||||
@@ -6851,16 +6824,7 @@ void auth_xfer_probe_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
|
||||
}
|
||||
|
||||
/* process result */
|
||||
if(sec == sec_status_bogus || sec == sec_status_secure_sentinel_fail) {
|
||||
if(verbosity >= VERB_OPS) {
|
||||
char zname[LDNS_MAX_DOMAINLEN];
|
||||
dname_str(xfr->name, zname);
|
||||
verbose(VERB_OPS, "auth zone %s: primary %s address probe lookup is DNSSEC bogus: %s",
|
||||
zname, xfr->task_transfer->lookup_target->host,
|
||||
(why_bogus?why_bogus:""));
|
||||
}
|
||||
/* fall through to next-lookup / next-master */
|
||||
} else if(rcode == LDNS_RCODE_NOERROR) {
|
||||
if(rcode == LDNS_RCODE_NOERROR) {
|
||||
uint16_t wanted_qtype = LDNS_RR_TYPE_A;
|
||||
struct regional* temp = env->scratch;
|
||||
struct query_info rq;
|
||||
|
||||
Vendored
+2
-10
@@ -277,8 +277,6 @@ find_closest_of_type(struct module_env* env, uint8_t* qname, size_t qnamelen,
|
||||
|
||||
/* snip off front label */
|
||||
lablen = *qname;
|
||||
if(lablen == 0)
|
||||
break;
|
||||
qname += lablen + 1;
|
||||
qnamelen -= lablen + 1;
|
||||
}
|
||||
@@ -714,16 +712,10 @@ 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;
|
||||
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;
|
||||
*res->rep = *origin->rep;
|
||||
if(origin->rep->reason_bogus_str) {
|
||||
res->rep->reason_bogus_str = regional_strdup(region,
|
||||
origin->rep->reason_bogus_str);
|
||||
@@ -1067,7 +1059,7 @@ dns_cache_lookup(struct module_env* env,
|
||||
if(env->cfg->harden_below_nxdomain) {
|
||||
while(!dname_is_root(k.qname)) {
|
||||
if(dpname && dpnamelen
|
||||
&& !dname_strict_subdomain_c(k.qname, dpname))
|
||||
&& !dname_subdomain_c(k.qname, dpname))
|
||||
break; /* no synth nxdomain above the stub */
|
||||
dname_remove_label(&k.qname, &k.qname_len);
|
||||
h = query_info_hash(&k, flags);
|
||||
|
||||
Vendored
+2
-50
@@ -50,7 +50,6 @@
|
||||
#include "util/regional.h"
|
||||
#include "util/alloc.h"
|
||||
#include "util/net_help.h"
|
||||
#include "validator/val_utils.h"
|
||||
|
||||
void
|
||||
rrset_markdel(void* key)
|
||||
@@ -127,8 +126,7 @@ rrset_cache_touch(struct rrset_cache* r, struct ub_packed_rrset_key* key,
|
||||
|
||||
/** see if rrset needs to be updated in the cache */
|
||||
static int
|
||||
need_to_update_rrset(void* nd, void* cd, time_t timenow, int equal, int ns,
|
||||
int a_aaaa)
|
||||
need_to_update_rrset(void* nd, void* cd, time_t timenow, int equal, int ns)
|
||||
{
|
||||
struct packed_rrset_data* newd = (struct packed_rrset_data*)nd;
|
||||
struct packed_rrset_data* cached = (struct packed_rrset_data*)cd;
|
||||
@@ -151,20 +149,6 @@ 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. */
|
||||
/* Also for A/AAAA and it is glue. */
|
||||
if((ns ||
|
||||
(a_aaaa && cached->trust==rrset_trust_add_noAA))
|
||||
&& !TTL_IS_EXPIRED(cached->ttl, timenow) &&
|
||||
newd->ttl > cached->ttl) {
|
||||
size_t i;
|
||||
if(a_aaaa) newd->trust=rrset_trust_add_noAA;
|
||||
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 */
|
||||
@@ -229,8 +213,7 @@ rrset_cache_update(struct rrset_cache* r, struct rrset_ref* ref,
|
||||
equal = rrsetdata_equal((struct packed_rrset_data*)k->entry.
|
||||
data, (struct packed_rrset_data*)e->data);
|
||||
if(!need_to_update_rrset(k->entry.data, e->data, timenow,
|
||||
equal, (rrset_type==LDNS_RR_TYPE_NS),
|
||||
(rrset_type==LDNS_RR_TYPE_A || rrset_type==LDNS_RR_TYPE_AAAA))) {
|
||||
equal, (rrset_type==LDNS_RR_TYPE_NS))) {
|
||||
/* cache is superior, return that value */
|
||||
lock_rw_unlock(&e->lock);
|
||||
ub_packed_rrset_parsedelete(k, alloc);
|
||||
@@ -262,43 +245,12 @@ rrset_cache_update(struct rrset_cache* r, struct rrset_ref* ref,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** See if the name is a within signer authority */
|
||||
static int
|
||||
dname_subdomain_rrsig_signers(uint8_t* dname,
|
||||
struct ub_packed_rrset_key* rrset)
|
||||
{
|
||||
struct packed_rrset_data* d = (struct packed_rrset_data*)
|
||||
rrset->entry.data;
|
||||
size_t i;
|
||||
if(!d || !d->rrsig_count)
|
||||
return 0;
|
||||
for(i=0; i<d->rrsig_count; i++) {
|
||||
uint8_t* sname = NULL;
|
||||
size_t slen = 0;
|
||||
rrsig_get_signer(d->rr_data[d->count+i], d->rr_len[d->count+i],
|
||||
&sname, &slen);
|
||||
if(!sname || !slen)
|
||||
return 0; /* malformed */
|
||||
if(!dname_subdomain_c(dname, sname))
|
||||
return 0; /* not a subdomain */
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void rrset_cache_update_wildcard(struct rrset_cache* rrset_cache,
|
||||
struct ub_packed_rrset_key* rrset, uint8_t* ce, size_t ce_len,
|
||||
struct alloc_cache* alloc, time_t timenow)
|
||||
{
|
||||
struct rrset_ref ref;
|
||||
uint8_t wc_dname[LDNS_MAX_DOMAINLEN+3];
|
||||
|
||||
/* See if the RRSIG signer name allows this wildcard,
|
||||
* the new rrset should fall within the zone of the RRSIG signer(s). */
|
||||
if(!dname_subdomain_rrsig_signers(ce, rrset)) {
|
||||
verbose(VERB_ALGO, "wildcard canonical parent outside signer authority");
|
||||
return;
|
||||
}
|
||||
|
||||
rrset = packed_rrset_copy_alloc(rrset, alloc, timenow);
|
||||
if(!rrset) {
|
||||
log_err("malloc failure in rrset_cache_update_wildcard");
|
||||
|
||||
+92
-163
@@ -42,6 +42,7 @@
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
#include <sys/time.h>
|
||||
#include <limits.h>
|
||||
#ifdef USE_TCP_FASTOPEN
|
||||
#include <netinet/tcp.h>
|
||||
@@ -2166,8 +2167,7 @@ void tcp_req_info_clear(struct tcp_req_info* req)
|
||||
open = req->open_req_list;
|
||||
while(open) {
|
||||
nopen = open->next;
|
||||
mesh_state_remove_reply(open->mesh, open->mesh_state, req->cp,
|
||||
NULL);
|
||||
mesh_state_remove_reply(open->mesh, open->mesh_state, req->cp);
|
||||
free(open);
|
||||
open = nopen;
|
||||
}
|
||||
@@ -2300,8 +2300,21 @@ int
|
||||
tcp_req_info_handle_read_close(struct tcp_req_info* req)
|
||||
{
|
||||
verbose(VERB_ALGO, "tcp channel read side closed %d", req->cp->fd);
|
||||
/* RFC 7766 6.2.4 says to drop pending replies when client closes. */
|
||||
return 0; /* drop connection */
|
||||
/* 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;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -3399,13 +3412,14 @@ doq_table_delete(struct doq_table* table)
|
||||
}
|
||||
|
||||
struct doq_timer*
|
||||
doq_timer_find_time(struct doq_table* table, ngtcp2_tstamp ts)
|
||||
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_mono = ts;
|
||||
key.time.tv_sec = tv->tv_sec;
|
||||
key.time.tv_usec = tv->tv_usec;
|
||||
node = rbtree_search(table->timer_tree, &key);
|
||||
if(node)
|
||||
return (struct doq_timer*)node->key;
|
||||
@@ -3453,7 +3467,7 @@ doq_timer_list_remove(struct doq_table* table, struct doq_timer* timer)
|
||||
if(!timer->timer_in_list)
|
||||
return;
|
||||
/* The item in the rbtree has the list start and end. */
|
||||
rb_timer = doq_timer_find_time(table, timer->time_mono);
|
||||
rb_timer = doq_timer_find_time(table, &timer->time);
|
||||
if(rb_timer) {
|
||||
if(timer->setlist_prev)
|
||||
timer->setlist_prev->setlist_next = timer->setlist_next;
|
||||
@@ -3499,8 +3513,7 @@ doq_timer_unset(struct doq_table* table, struct doq_timer* timer)
|
||||
}
|
||||
|
||||
void doq_timer_set(struct doq_table* table, struct doq_timer* timer,
|
||||
struct doq_server_socket* worker_doq_socket, struct timeval* tv,
|
||||
ngtcp2_tstamp ts)
|
||||
struct doq_server_socket* worker_doq_socket, struct timeval* tv)
|
||||
{
|
||||
struct doq_timer* rb_timer;
|
||||
if(verbosity >= VERB_ALGO && timer->conn) {
|
||||
@@ -3514,14 +3527,14 @@ void doq_timer_set(struct doq_table* table, struct doq_timer* timer,
|
||||
(int)rel.tv_sec, (int)rel.tv_usec);
|
||||
}
|
||||
if(timer->timer_in_tree || timer->timer_in_list) {
|
||||
if(timer->time_mono == ts)
|
||||
if(timer->time.tv_sec == tv->tv_sec &&
|
||||
timer->time.tv_usec == tv->tv_usec)
|
||||
return; /* already set on that time */
|
||||
doq_timer_unset(table, timer);
|
||||
}
|
||||
timer->time_real.tv_sec = tv->tv_sec;
|
||||
timer->time_real.tv_usec = tv->tv_usec;
|
||||
timer->time_mono = ts;
|
||||
rb_timer = doq_timer_find_time(table, ts);
|
||||
timer->time.tv_sec = tv->tv_sec;
|
||||
timer->time.tv_usec = tv->tv_usec;
|
||||
rb_timer = doq_timer_find_time(table, tv);
|
||||
if(rb_timer) {
|
||||
/* There is a timeout already with this value. Timer is
|
||||
* added to the setlist. */
|
||||
@@ -3597,29 +3610,15 @@ doq_conn_create(struct comm_point* c, struct doq_pkt_addr* paddr,
|
||||
return conn;
|
||||
}
|
||||
|
||||
/** The arguments for doq stream tree del. */
|
||||
struct doq_stream_tree_del_args {
|
||||
/** The doq table. */
|
||||
struct doq_table* table;
|
||||
/** The doq connection for the stream. */
|
||||
struct doq_conn* conn;
|
||||
};
|
||||
|
||||
/** delete stream tree node */
|
||||
static void
|
||||
stream_tree_del(rbnode_type* node, void* arg)
|
||||
{
|
||||
struct doq_stream_tree_del_args* args = (struct doq_stream_tree_del_args*)arg;
|
||||
struct doq_table* table = args->table;
|
||||
struct doq_table* table = (struct doq_table*)arg;
|
||||
struct doq_stream* stream;
|
||||
if(!node)
|
||||
return;
|
||||
stream = (struct doq_stream*)node;
|
||||
if(stream->mesh_state) {
|
||||
mesh_state_remove_reply(stream->mesh, stream->mesh_state,
|
||||
args->conn->doq_socket->cp, stream);
|
||||
stream->mesh_state = NULL;
|
||||
}
|
||||
if(stream->in)
|
||||
doq_table_quic_size_subtract(table, stream->inlen);
|
||||
if(stream->out)
|
||||
@@ -3641,11 +3640,7 @@ doq_conn_delete(struct doq_conn* conn, struct doq_table* table)
|
||||
* because the ngtcp2 conn is deleted. */
|
||||
SSL_set_app_data(conn->ssl, NULL);
|
||||
if(conn->stream_tree.count != 0) {
|
||||
struct doq_stream_tree_del_args args;
|
||||
memset(&args, 0, sizeof(args));
|
||||
args.table = table;
|
||||
args.conn = conn;
|
||||
traverse_postorder(&conn->stream_tree, stream_tree_del, &args);
|
||||
traverse_postorder(&conn->stream_tree, stream_tree_del, table);
|
||||
}
|
||||
free(conn->key.dcid);
|
||||
SSL_free(conn->ssl);
|
||||
@@ -3718,9 +3713,13 @@ int doq_timer_cmp(const void* key1, const void* key2)
|
||||
{
|
||||
struct doq_timer* e = (struct doq_timer*)key1;
|
||||
struct doq_timer* f = (struct doq_timer*)key2;
|
||||
if(e->time_mono < f->time_mono)
|
||||
if(e->time.tv_sec < f->time.tv_sec)
|
||||
return -1;
|
||||
if(e->time_mono > f->time_mono)
|
||||
if(e->time.tv_sec > f->time.tv_sec)
|
||||
return 1;
|
||||
if(e->time.tv_usec < f->time.tv_usec)
|
||||
return -1;
|
||||
if(e->time.tv_usec > f->time.tv_usec)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
@@ -3781,7 +3780,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,
|
||||
sizeof(struct in6_addr));
|
||||
*localaddrlen);
|
||||
sa6->sin6_port = repinfo->doq_srcport;
|
||||
#endif
|
||||
} else {
|
||||
@@ -3791,7 +3790,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,
|
||||
sizeof(struct in_addr));
|
||||
*localaddrlen);
|
||||
sa->sin_port = repinfo->doq_srcport;
|
||||
#elif defined(IP_RECVDSTADDR)
|
||||
struct sockaddr_in* sa = (struct sockaddr_in*)localaddr;
|
||||
@@ -3954,11 +3953,6 @@ doq_stream_close(struct doq_conn* conn, struct doq_stream* stream,
|
||||
if(stream->is_closed)
|
||||
return 1;
|
||||
stream->is_closed = 1;
|
||||
if(stream->mesh_state) {
|
||||
mesh_state_remove_reply(stream->mesh, stream->mesh_state,
|
||||
conn->doq_socket->cp, stream);
|
||||
stream->mesh_state = NULL;
|
||||
}
|
||||
doq_stream_off_write_list(conn, stream);
|
||||
if(send_shutdown) {
|
||||
verbose(VERB_ALGO, "doq: shutdown stream_id %d with app_error_code %d",
|
||||
@@ -3988,8 +3982,7 @@ doq_stream_close(struct doq_conn* conn, struct doq_stream* stream,
|
||||
|
||||
/** doq stream pick up answer data from buffer */
|
||||
static int
|
||||
doq_stream_pickup_answer(struct doq_conn* conn, struct doq_stream* stream,
|
||||
struct sldns_buffer* buf)
|
||||
doq_stream_pickup_answer(struct doq_stream* stream, struct sldns_buffer* buf)
|
||||
{
|
||||
stream->is_answer_available = 1;
|
||||
if(stream->out) {
|
||||
@@ -3999,11 +3992,6 @@ doq_stream_pickup_answer(struct doq_conn* conn, struct doq_stream* stream,
|
||||
}
|
||||
stream->nwrite = 0;
|
||||
stream->outlen = sldns_buffer_limit(buf);
|
||||
if(!doq_table_quic_size_available(conn->doq_socket->table,
|
||||
conn->doq_socket->cfg, stream->outlen)) {
|
||||
verbose(VERB_ALGO, "doq stream: no space for reply length");
|
||||
return 0;
|
||||
}
|
||||
/* For quic the output bytes have to stay allocated and available,
|
||||
* for potential resends, until the remote end has acknowledged them.
|
||||
* This includes the tcplen start uint16_t, in outlen_wire. */
|
||||
@@ -4030,56 +4018,24 @@ doq_stream_send_reply(struct doq_conn* conn, struct doq_stream* stream,
|
||||
if(stream->out)
|
||||
doq_table_quic_size_subtract(conn->doq_socket->table,
|
||||
stream->outlen);
|
||||
if(!doq_stream_pickup_answer(conn, stream, buf))
|
||||
if(!doq_stream_pickup_answer(stream, buf))
|
||||
return 0;
|
||||
doq_table_quic_size_add(conn->doq_socket->table, stream->outlen);
|
||||
doq_stream_on_write_list(conn, stream);
|
||||
doq_conn_write_enable(conn);
|
||||
return 1;
|
||||
}
|
||||
#endif /* HAVE_NGTCP2 */
|
||||
|
||||
void
|
||||
doq_stream_add_meshstate(struct doq_stream* stream,
|
||||
struct mesh_area* mesh, struct mesh_state* m)
|
||||
{
|
||||
#ifdef HAVE_NGTCP2
|
||||
stream->mesh = mesh;
|
||||
stream->mesh_state = m;
|
||||
#else
|
||||
(void)stream; (void)mesh; (void)m;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
doq_stream_remove_mesh_state(struct doq_stream* stream)
|
||||
{
|
||||
#ifdef HAVE_NGTCP2
|
||||
if(!stream)
|
||||
return;
|
||||
stream->mesh_state = NULL;
|
||||
#else
|
||||
(void)stream;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAVE_NGTCP2
|
||||
/** doq stream data length has completed, allocations can be done. False on
|
||||
* allocation failure. */
|
||||
static int
|
||||
doq_stream_datalen_complete(struct doq_conn* conn, struct doq_stream* stream,
|
||||
struct doq_table* table)
|
||||
doq_stream_datalen_complete(struct doq_stream* stream, struct doq_table* table)
|
||||
{
|
||||
if(stream->inlen > 1024*1024) {
|
||||
log_err("doq stream in length too large %d",
|
||||
(int)stream->inlen);
|
||||
return 0;
|
||||
}
|
||||
if(!doq_table_quic_size_available(table, conn->doq_socket->cfg,
|
||||
stream->inlen)) {
|
||||
verbose(VERB_ALGO, "doq stream: no space for query length");
|
||||
return 0;
|
||||
}
|
||||
stream->in = calloc(1, stream->inlen);
|
||||
if(!stream->in) {
|
||||
log_err("doq could not read stream, calloc failed: "
|
||||
@@ -4124,7 +4080,6 @@ doq_stream_data_complete(struct doq_conn* conn, struct doq_stream* stream)
|
||||
return 0;
|
||||
}
|
||||
c->repinfo.doq_streamid = stream->stream_id;
|
||||
c->repinfo.doq_stream = stream;
|
||||
conn->doq_socket->current_conn = conn;
|
||||
fptr_ok(fptr_whitelist_comm_point(c->callback));
|
||||
if( (*c->callback)(c, c->cb_arg, NETEVENT_NOERROR, &c->repinfo)) {
|
||||
@@ -4141,9 +4096,8 @@ doq_stream_data_complete(struct doq_conn* conn, struct doq_stream* stream)
|
||||
|
||||
/** doq receive data for a stream, more bytes of the incoming data */
|
||||
static int
|
||||
doq_stream_recv_data(struct doq_conn* conn, struct doq_stream* stream,
|
||||
const uint8_t* data, size_t datalen, int* recv_done,
|
||||
struct doq_table* table)
|
||||
doq_stream_recv_data(struct doq_stream* stream, const uint8_t* data,
|
||||
size_t datalen, int* recv_done, struct doq_table* table)
|
||||
{
|
||||
int got_data = 0;
|
||||
/* read the tcplength uint16_t at the start */
|
||||
@@ -4164,7 +4118,7 @@ doq_stream_recv_data(struct doq_conn* conn, struct doq_stream* stream,
|
||||
if(stream->nread == 2) {
|
||||
/* the initial length value is completed */
|
||||
stream->inlen = ntohs(tcplen);
|
||||
if(!doq_stream_datalen_complete(conn, stream, table))
|
||||
if(!doq_stream_datalen_complete(stream, table))
|
||||
return 0;
|
||||
} else {
|
||||
/* store for later */
|
||||
@@ -4313,11 +4267,12 @@ doq_submit_new_token(struct doq_conn* conn)
|
||||
ngtcp2_ssize tokenlen;
|
||||
int ret;
|
||||
const ngtcp2_path* path = ngtcp2_conn_get_path(conn->conn);
|
||||
ngtcp2_tstamp ts = doq_get_timestamp_nanosec();
|
||||
|
||||
tokenlen = ngtcp2_crypto_generate_regular_token(token,
|
||||
conn->doq_socket->static_secret,
|
||||
conn->doq_socket->static_secret_len, path->remote.addr,
|
||||
path->remote.addrlen, doq_get_timestamp_nanosec());
|
||||
path->remote.addrlen, ts);
|
||||
if(tokenlen < 0) {
|
||||
log_err("doq ngtcp2_crypto_generate_regular_token failed");
|
||||
return 1;
|
||||
@@ -4380,7 +4335,8 @@ doq_stream_open_cb(ngtcp2_conn* ATTR_UNUSED(conn), int64_t stream_id,
|
||||
verbose(VERB_ALGO, "doq: stream with this id already exists");
|
||||
return 0;
|
||||
}
|
||||
if(!doq_table_quic_size_available(doq_conn->doq_socket->table,
|
||||
if(stream_id != 0 && stream_id != 4 && /* allow one stream on a new connection */
|
||||
!doq_table_quic_size_available(doq_conn->doq_socket->table,
|
||||
doq_conn->doq_socket->cfg, sizeof(*stream)
|
||||
+ 100 /* estimated query in */
|
||||
+ 512 /* estimated response out */
|
||||
@@ -4438,8 +4394,8 @@ doq_recv_stream_data_cb(ngtcp2_conn* ATTR_UNUSED(conn), uint32_t flags,
|
||||
return 0;
|
||||
}
|
||||
if(datalen != 0) {
|
||||
if(!doq_stream_recv_data(doq_conn, stream, data, datalen,
|
||||
&recv_done, doq_conn->doq_socket->table))
|
||||
if(!doq_stream_recv_data(stream, data, datalen, &recv_done,
|
||||
doq_conn->doq_socket->table))
|
||||
return NGTCP2_ERR_CALLBACK_FAILURE;
|
||||
}
|
||||
if((flags&NGTCP2_STREAM_DATA_FLAG_FIN)!=0) {
|
||||
@@ -4508,29 +4464,6 @@ doq_stream_reset_cb(ngtcp2_conn* ATTR_UNUSED(conn), int64_t stream_id,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** ngtcp2 extend_max_stream_data function */
|
||||
int doq_extend_max_stream_data_cb(ngtcp2_conn* ATTR_UNUSED(conn),
|
||||
int64_t stream_id, uint64_t max_data, void* user_data,
|
||||
void* ATTR_UNUSED(stream_user_data))
|
||||
{
|
||||
struct doq_conn* doq_conn = (struct doq_conn*)user_data;
|
||||
struct doq_stream* stream;
|
||||
verbose(VERB_ALGO, "doq extend_max_stream_data stream id %d "
|
||||
"max_data %d ", (int)stream_id, (int)max_data);
|
||||
if(max_data == 0)
|
||||
return 0;
|
||||
stream = doq_stream_find(doq_conn, stream_id);
|
||||
if(!stream) {
|
||||
verbose(VERB_ALGO, "doq: unknown stream %d", (int)stream_id);
|
||||
return 0;
|
||||
}
|
||||
if(!stream->is_answer_available)
|
||||
return 0;
|
||||
doq_stream_on_write_list(doq_conn, stream);
|
||||
doq_conn_write_enable(doq_conn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** ngtcp2 acked_stream_data_offset callback function */
|
||||
static int
|
||||
doq_acked_stream_data_offset_cb(ngtcp2_conn* ATTR_UNUSED(conn),
|
||||
@@ -4905,7 +4838,6 @@ doq_conn_setup(struct doq_conn* conn, uint8_t* scid, size_t scidlen,
|
||||
callbacks.stream_open = doq_stream_open_cb;
|
||||
callbacks.stream_close = doq_stream_close_cb;
|
||||
callbacks.stream_reset = doq_stream_reset_cb;
|
||||
callbacks.extend_max_stream_data = doq_extend_max_stream_data_cb;
|
||||
callbacks.acked_stream_data_offset = doq_acked_stream_data_offset_cb;
|
||||
callbacks.recv_stream_data = doq_recv_stream_data_cb;
|
||||
|
||||
@@ -5182,30 +5114,23 @@ doq_conn_clear_conids(struct doq_conn* conn)
|
||||
|
||||
ngtcp2_tstamp doq_get_timestamp_nanosec(void)
|
||||
{
|
||||
#ifdef CLOCK_REALTIME
|
||||
struct timespec tp;
|
||||
memset(&tp, 0, sizeof(tp));
|
||||
#ifdef CLOCK_BOOTTIME
|
||||
if(clock_gettime(CLOCK_BOOTTIME, &tp) == -1) {
|
||||
#endif
|
||||
if(clock_gettime(CLOCK_MONOTONIC, &tp) == -1) {
|
||||
log_err("clock_gettime failed: %s", strerror(errno));
|
||||
}
|
||||
#ifdef CLOCK_BOOTTIME
|
||||
/* Get a nanosecond time, that can be compared with the event base. */
|
||||
if(clock_gettime(CLOCK_REALTIME, &tp) == -1) {
|
||||
log_err("clock_gettime failed: %s", strerror(errno));
|
||||
}
|
||||
#endif
|
||||
return ((uint64_t)tp.tv_sec)*((uint64_t)1000000000) +
|
||||
((uint64_t)tp.tv_nsec);
|
||||
}
|
||||
|
||||
static struct timeval doq_get_timevalue(void)
|
||||
{
|
||||
#else
|
||||
struct timeval tv;
|
||||
memset(&tv, 0, sizeof(tv));
|
||||
if(gettimeofday(&tv, NULL) < 0) {
|
||||
log_err("gettimeofday failed: %s", strerror(errno));
|
||||
memset(&tv, 0, sizeof(tv));
|
||||
}
|
||||
return tv;
|
||||
return ((uint64_t)tv.tv_sec)*((uint64_t)1000000000) +
|
||||
((uint64_t)tv.tv_usec)*((uint64_t)1000);
|
||||
#endif /* CLOCK_REALTIME */
|
||||
}
|
||||
|
||||
/** doq start the closing period for the connection. */
|
||||
@@ -5328,17 +5253,18 @@ doq_conn_recv(struct comm_point* c, struct doq_pkt_addr* paddr,
|
||||
int* err_drop)
|
||||
{
|
||||
int ret;
|
||||
ngtcp2_tstamp ts;
|
||||
struct ngtcp2_path path;
|
||||
memset(&path, 0, sizeof(path));
|
||||
path.remote.addr = (struct sockaddr*)&paddr->addr;
|
||||
path.remote.addrlen = paddr->addrlen;
|
||||
path.local.addr = (struct sockaddr*)&paddr->localaddr;
|
||||
path.local.addrlen = paddr->localaddrlen;
|
||||
ts = doq_get_timestamp_nanosec();
|
||||
|
||||
ret = ngtcp2_conn_read_pkt(conn->conn, &path, pi,
|
||||
sldns_buffer_begin(c->doq_socket->pkt_buf),
|
||||
sldns_buffer_limit(c->doq_socket->pkt_buf),
|
||||
doq_get_timestamp_nanosec());
|
||||
sldns_buffer_limit(c->doq_socket->pkt_buf), ts);
|
||||
if(ret != 0) {
|
||||
if(err_retry)
|
||||
*err_retry = 0;
|
||||
@@ -5426,6 +5352,7 @@ doq_conn_write_streams(struct comm_point* c, struct doq_conn* conn,
|
||||
{
|
||||
struct doq_stream* stream = conn->stream_write_first;
|
||||
ngtcp2_path_storage ps;
|
||||
ngtcp2_tstamp ts = doq_get_timestamp_nanosec();
|
||||
size_t num_packets = 0, max_packets = 65535;
|
||||
ngtcp2_path_storage_zero(&ps);
|
||||
|
||||
@@ -5478,8 +5405,7 @@ doq_conn_write_streams(struct comm_point* c, struct doq_conn* conn,
|
||||
ret = ngtcp2_conn_writev_stream(conn->conn, &ps.path, &pi,
|
||||
sldns_buffer_begin(c->doq_socket->pkt_buf),
|
||||
sldns_buffer_remaining(c->doq_socket->pkt_buf),
|
||||
&ndatalen, flags, stream_id, datav, datav_count,
|
||||
doq_get_timestamp_nanosec());
|
||||
&ndatalen, flags, stream_id, datav, datav_count, ts);
|
||||
if(ret < 0) {
|
||||
if(ret == NGTCP2_ERR_WRITE_MORE) {
|
||||
verbose(VERB_ALGO, "doq: write more, ndatalen %d", (int)ndatalen);
|
||||
@@ -5494,20 +5420,26 @@ doq_conn_write_streams(struct comm_point* c, struct doq_conn* conn,
|
||||
continue;
|
||||
} else if(ret == NGTCP2_ERR_STREAM_DATA_BLOCKED) {
|
||||
verbose(VERB_ALGO, "doq: ngtcp2_conn_writev_stream returned NGTCP2_ERR_STREAM_DATA_BLOCKED");
|
||||
if(stream) {
|
||||
doq_stream_off_write_list(conn, stream);
|
||||
stream = stream->write_next;
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
#ifdef HAVE_NGTCP2_CCERR_DEFAULT
|
||||
ngtcp2_ccerr_set_application_error(
|
||||
&conn->ccerr, -1, NULL, 0);
|
||||
#else
|
||||
ngtcp2_connection_close_error_set_application_error(&conn->last_error, -1, NULL, 0);
|
||||
#endif
|
||||
if(err_drop)
|
||||
*err_drop = 0;
|
||||
if(!doq_conn_close_error(c, conn)) {
|
||||
if(err_drop)
|
||||
*err_drop = 1;
|
||||
}
|
||||
return 0;
|
||||
} else if(ret == NGTCP2_ERR_STREAM_SHUT_WR) {
|
||||
verbose(VERB_ALGO, "doq: ngtcp2_conn_writev_stream returned NGTCP2_ERR_STREAM_SHUT_WR");
|
||||
#ifdef HAVE_NGTCP2_CCERR_DEFAULT
|
||||
ngtcp2_ccerr_set_application_error(
|
||||
&conn->ccerr, DOQ_APP_ERROR_CODE, NULL, 0);
|
||||
&conn->ccerr, -1, NULL, 0);
|
||||
#else
|
||||
ngtcp2_connection_close_error_set_application_error(&conn->last_error, DOQ_APP_ERROR_CODE, NULL, 0);
|
||||
ngtcp2_connection_close_error_set_application_error(&conn->last_error, -1, NULL, 0);
|
||||
#endif
|
||||
if(err_drop)
|
||||
*err_drop = 0;
|
||||
@@ -5545,8 +5477,7 @@ doq_conn_write_streams(struct comm_point* c, struct doq_conn* conn,
|
||||
if(ret == 0) {
|
||||
/* congestion limited */
|
||||
doq_conn_write_disable(conn);
|
||||
ngtcp2_conn_update_pkt_tx_time(conn->conn,
|
||||
doq_get_timestamp_nanosec());
|
||||
ngtcp2_conn_update_pkt_tx_time(conn->conn, ts);
|
||||
return 1;
|
||||
}
|
||||
sldns_buffer_set_position(c->doq_socket->pkt_buf, ret);
|
||||
@@ -5560,7 +5491,7 @@ doq_conn_write_streams(struct comm_point* c, struct doq_conn* conn,
|
||||
if(stream)
|
||||
stream = stream->write_next;
|
||||
}
|
||||
ngtcp2_conn_update_pkt_tx_time(conn->conn, doq_get_timestamp_nanosec());
|
||||
ngtcp2_conn_update_pkt_tx_time(conn->conn, ts);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -5637,35 +5568,32 @@ doq_table_pop_first(struct doq_table* table)
|
||||
}
|
||||
|
||||
int
|
||||
doq_conn_check_timer(struct doq_conn* conn, struct timeval* tv, ngtcp2_tstamp* ts)
|
||||
doq_conn_check_timer(struct doq_conn* conn, struct timeval* tv)
|
||||
{
|
||||
ngtcp2_tstamp doq_expiry = ngtcp2_conn_get_expiry(conn->conn);
|
||||
ngtcp2_tstamp doq_now = doq_get_timestamp_nanosec();
|
||||
ngtcp2_tstamp expiry = ngtcp2_conn_get_expiry(conn->conn);
|
||||
ngtcp2_tstamp now = doq_get_timestamp_nanosec();
|
||||
ngtcp2_tstamp t;
|
||||
struct timeval now = doq_get_timevalue();
|
||||
|
||||
if(doq_expiry <= doq_now || doq_expiry == UINT64_MAX) {
|
||||
/* UINT64_MAX means there is no next expiry. */
|
||||
if(expiry <= now) {
|
||||
/* The timer has already expired, add with zero timeout.
|
||||
* This should call the callback straight away. Calling it
|
||||
* from the event callbacks is cleaner than calling it here,
|
||||
* because then it is always called with the same locks and
|
||||
* so on. This routine only has the conn.lock. */
|
||||
t = doq_now;
|
||||
memcpy(tv, &now, sizeof(*tv));
|
||||
t = now;
|
||||
} else {
|
||||
t = doq_expiry;
|
||||
memset(tv, 0, sizeof(*tv));
|
||||
tv->tv_sec = (doq_expiry - doq_now) / NGTCP2_SECONDS;
|
||||
tv->tv_usec = ((doq_expiry - doq_now) / NGTCP2_MICROSECONDS)%1000000;
|
||||
timeval_add(tv, &now);
|
||||
t = expiry;
|
||||
}
|
||||
|
||||
*ts = t;
|
||||
/* convert to timeval */
|
||||
memset(tv, 0, sizeof(*tv));
|
||||
tv->tv_sec = t / NGTCP2_SECONDS;
|
||||
tv->tv_usec = (t / NGTCP2_MICROSECONDS)%1000000;
|
||||
|
||||
/* If we already have a timer, is it the right value? */
|
||||
if(conn->timer.timer_in_tree || conn->timer.timer_in_list) {
|
||||
if(conn->timer.time_mono == *ts)
|
||||
if(conn->timer.time.tv_sec == tv->tv_sec &&
|
||||
conn->timer.time.tv_usec == tv->tv_usec)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
@@ -5686,12 +5614,13 @@ doq_conn_log_line(struct doq_conn* conn, char* s)
|
||||
int
|
||||
doq_conn_handle_timeout(struct doq_conn* conn)
|
||||
{
|
||||
ngtcp2_tstamp now = doq_get_timestamp_nanosec();
|
||||
int rv;
|
||||
|
||||
if(verbosity >= VERB_ALGO)
|
||||
doq_conn_log_line(conn, "timeout");
|
||||
|
||||
rv = ngtcp2_conn_handle_expiry(conn->conn, doq_get_timestamp_nanosec());
|
||||
rv = ngtcp2_conn_handle_expiry(conn->conn, now);
|
||||
if(rv != 0) {
|
||||
verbose(VERB_ALGO, "ngtcp2_conn_handle_expiry failed: %s",
|
||||
ngtcp2_strerror(rv));
|
||||
|
||||
@@ -61,8 +61,6 @@ struct config_file;
|
||||
struct addrinfo;
|
||||
struct sldns_buffer;
|
||||
struct tcl_list;
|
||||
struct mesh_area;
|
||||
struct mesh_state;
|
||||
|
||||
/**
|
||||
* Listening for queries structure.
|
||||
@@ -540,11 +538,8 @@ void doq_table_delete(struct doq_table* table);
|
||||
struct doq_timer {
|
||||
/** The rbnode in the tree sorted by timeout value. Key this struct. */
|
||||
struct rbnode_type node;
|
||||
/** The timeout value. Monotonic value used with ngtcp2.
|
||||
* This time value is used for the tree operations. */
|
||||
ngtcp2_tstamp time_mono;
|
||||
/** The timeout value. Absolute time value. */
|
||||
struct timeval time_real;
|
||||
struct timeval time;
|
||||
/** If the timer is in the time tree, with the node. */
|
||||
int timer_in_tree;
|
||||
/** If there are more timers with the exact same timeout value,
|
||||
@@ -694,11 +689,6 @@ struct doq_stream {
|
||||
uint8_t* out;
|
||||
/** if the stream is on the write list */
|
||||
uint8_t on_write_list;
|
||||
/** The mesh area and mesh state, set when this stream's query was
|
||||
* dispatched into the mesh; used to detach the reply on stream close */
|
||||
struct mesh_area* mesh;
|
||||
/** the mesh state for the query, is nonNULL when there is one. */
|
||||
struct mesh_state* mesh_state;
|
||||
/** the prev and next on the write list, if on the list */
|
||||
struct doq_stream* write_prev, *write_next;
|
||||
};
|
||||
@@ -801,16 +791,7 @@ int doq_stream_close(struct doq_conn* conn, struct doq_stream* stream,
|
||||
/** send reply for a connection */
|
||||
int doq_stream_send_reply(struct doq_conn* conn, struct doq_stream* stream,
|
||||
struct sldns_buffer* buf);
|
||||
#endif /* HAVE_NGTCP2 */
|
||||
|
||||
/** add mesh state to doq stream */
|
||||
void doq_stream_add_meshstate(struct doq_stream* stream,
|
||||
struct mesh_area* mesh, struct mesh_state* m);
|
||||
|
||||
/** remove mesh state from doq stream */
|
||||
void doq_stream_remove_mesh_state(struct doq_stream* stream);
|
||||
|
||||
#ifdef HAVE_NGTCP2
|
||||
/** the connection has write interest, wants to write packets */
|
||||
void doq_conn_write_enable(struct doq_conn* conn);
|
||||
|
||||
@@ -832,12 +813,10 @@ struct doq_conn* doq_table_pop_first(struct doq_table* table);
|
||||
* doq check if the timer for the conn needs to be changed.
|
||||
* @param conn: connection, caller must hold lock on it.
|
||||
* @param tv: time value, absolute time, returned.
|
||||
* @param ts: time stamp, absolute time, returned.
|
||||
* @return true if timer needs to be set to tv, false if no change is needed
|
||||
* to the timer. The timer is already set to the right time in that case.
|
||||
*/
|
||||
int doq_conn_check_timer(struct doq_conn* conn, struct timeval* tv,
|
||||
ngtcp2_tstamp* ts);
|
||||
int doq_conn_check_timer(struct doq_conn* conn, struct timeval* tv);
|
||||
|
||||
/** doq remove timer from tree */
|
||||
void doq_timer_tree_remove(struct doq_table* table, struct doq_timer* timer);
|
||||
@@ -850,12 +829,11 @@ void doq_timer_unset(struct doq_table* table, struct doq_timer* timer);
|
||||
|
||||
/** doq set the timer and add it. */
|
||||
void doq_timer_set(struct doq_table* table, struct doq_timer* timer,
|
||||
struct doq_server_socket* worker_doq_socket, struct timeval* tv,
|
||||
ngtcp2_tstamp ts);
|
||||
struct doq_server_socket* worker_doq_socket, struct timeval* tv);
|
||||
|
||||
/** doq find a timeout in the timer tree */
|
||||
struct doq_timer* doq_timer_find_time(struct doq_table* table,
|
||||
ngtcp2_tstamp ts);
|
||||
struct timeval* tv);
|
||||
|
||||
/** doq handle timeout for a connection. Pass conn locked. Returns false for
|
||||
* deletion. */
|
||||
@@ -873,9 +851,6 @@ int doq_table_quic_size_available(struct doq_table* table,
|
||||
|
||||
/** doq get the quic size value */
|
||||
size_t doq_table_quic_size_get(struct doq_table* table);
|
||||
|
||||
/** get a timestamp in nanoseconds */
|
||||
ngtcp2_tstamp doq_get_timestamp_nanosec(void);
|
||||
#endif /* HAVE_NGTCP2 */
|
||||
|
||||
char* set_ip_dscp(int socket, int addrfamily, int ds);
|
||||
@@ -891,4 +866,8 @@ void doq_client_event_cb(int fd, short event, void* arg);
|
||||
/** timer event callback for testcode/doqclient */
|
||||
void doq_client_timer_cb(int fd, short event, void* arg);
|
||||
|
||||
#ifdef HAVE_NGTCP2
|
||||
/** get a timestamp in nanoseconds */
|
||||
ngtcp2_tstamp doq_get_timestamp_nanosec(void);
|
||||
#endif
|
||||
#endif /* LISTEN_DNSPORT_H */
|
||||
|
||||
@@ -573,7 +573,7 @@ enum respip_action {
|
||||
respip_always_nxdomain = local_zone_always_nxdomain,
|
||||
/** answer with nodata response */
|
||||
respip_always_nodata = local_zone_always_nodata,
|
||||
/** drop query */
|
||||
/** answer with nodata response */
|
||||
respip_always_deny = local_zone_always_deny,
|
||||
/** RPZ: truncate answer in order to force switch to tcp */
|
||||
respip_truncate = local_zone_truncate,
|
||||
|
||||
+20
-75
@@ -297,14 +297,12 @@ 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->list_select == mesh_jostle_list) {
|
||||
if(m && m->reply_list && m->list_select == mesh_jostle_list) {
|
||||
/* how old is it? */
|
||||
struct timeval 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)) {
|
||||
timeval_subtract(&age, mesh->env->now_tv,
|
||||
&m->reply_list->start_time);
|
||||
if(timeval_smaller(&mesh->jostle_max, &age)) {
|
||||
/* its a goner */
|
||||
log_nametypeclass(VERB_ALGO, "query jostled out to "
|
||||
"make space for a new one",
|
||||
@@ -467,8 +465,6 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
"incoming query.");
|
||||
if(rep->c->use_h2)
|
||||
http2_stream_remove_mesh_state(rep->c->h2_stream);
|
||||
else if(rep->c->type == comm_doq && rep->doq_stream)
|
||||
doq_stream_remove_mesh_state(rep->doq_stream);
|
||||
comm_point_drop_reply(rep);
|
||||
mesh->stats_dropped++;
|
||||
return;
|
||||
@@ -482,8 +478,6 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
"dropping incoming query.");
|
||||
if(rep->c->use_h2)
|
||||
http2_stream_remove_mesh_state(rep->c->h2_stream);
|
||||
else if(rep->c->type == comm_doq && rep->doq_stream)
|
||||
doq_stream_remove_mesh_state(rep->doq_stream);
|
||||
comm_point_drop_reply(rep);
|
||||
mesh->num_queries_replyaddr_limit++;
|
||||
return;
|
||||
@@ -556,8 +550,6 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
}
|
||||
if(rep->c->use_h2) {
|
||||
http2_stream_add_meshstate(rep->c->h2_stream, mesh, s);
|
||||
} else if(rep->c->type == comm_doq && rep->doq_stream) {
|
||||
doq_stream_add_meshstate(rep->doq_stream, mesh, s);
|
||||
}
|
||||
/* add serve expired timer if required and not already there */
|
||||
if(timeout && !mesh_serve_expired_init(s, timeout)) {
|
||||
@@ -611,8 +603,6 @@ servfail_mem:
|
||||
qinfo, qid, qflags, edns);
|
||||
if(rep->c->use_h2)
|
||||
http2_stream_remove_mesh_state(rep->c->h2_stream);
|
||||
else if(rep->c->type == comm_doq && rep->doq_stream)
|
||||
doq_stream_remove_mesh_state(rep->doq_stream);
|
||||
comm_point_send_reply(rep);
|
||||
if(added)
|
||||
mesh_state_delete(&s->s);
|
||||
@@ -933,7 +923,8 @@ cfg_region_strlist_copy(struct regional* region, struct config_strlist* list)
|
||||
return result;
|
||||
}
|
||||
|
||||
struct respip_client_info*
|
||||
/** Copy the client info to the query region. */
|
||||
static struct respip_client_info*
|
||||
mesh_copy_client_info(struct regional* region, struct respip_client_info* cinfo)
|
||||
{
|
||||
size_t i;
|
||||
@@ -978,11 +969,6 @@ mesh_copy_client_info(struct regional* region, struct respip_client_info* cinfo)
|
||||
cinfo->view->name);
|
||||
if(!client_info->view_name)
|
||||
return NULL;
|
||||
} else if(cinfo->view_name) {
|
||||
client_info->view_name = regional_strdup(region,
|
||||
cinfo->view_name);
|
||||
if(!client_info->view_name)
|
||||
return NULL;
|
||||
}
|
||||
return client_info;
|
||||
}
|
||||
@@ -1050,7 +1036,6 @@ 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 */
|
||||
@@ -1090,14 +1075,6 @@ 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 */
|
||||
@@ -1105,6 +1082,8 @@ 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--;
|
||||
@@ -1496,10 +1475,6 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
|
||||
* for HTTP/2 stream to refer to mesh state, in case
|
||||
* connection gets cleanup before HTTP/2 stream close. */
|
||||
r->h2_stream->mesh_state = NULL;
|
||||
#ifdef HAVE_NGTCP2
|
||||
} else if(r->query_reply.doq_stream) {
|
||||
r->query_reply.doq_stream->mesh_state = NULL;
|
||||
#endif
|
||||
}
|
||||
/* send the reply */
|
||||
/* We don't reuse the encoded answer if:
|
||||
@@ -1654,9 +1629,9 @@ static void dns_error_reporting(struct module_qstate* qstate,
|
||||
opt = edns_opt_list_find(qstate->edns_opts_back_in,
|
||||
LDNS_EDNS_REPORT_CHANNEL);
|
||||
if(!opt) return;
|
||||
agent_domain_len = opt->opt_len;
|
||||
agent_domain = opt->opt_data;
|
||||
agent_domain_len = dname_valid(agent_domain, opt->opt_len);
|
||||
if(agent_domain_len < 3) {
|
||||
if(dname_valid(agent_domain, agent_domain_len) < 3) {
|
||||
/* The agent domain needs to be a valid dname that is not the
|
||||
* root; from RFC9567. */
|
||||
return;
|
||||
@@ -1793,8 +1768,6 @@ void mesh_query_done(struct mesh_state* mstate)
|
||||
mstate->reply_list = NULL;
|
||||
if(r->query_reply.c->use_h2)
|
||||
http2_stream_remove_mesh_state(r->h2_stream);
|
||||
else if(r->query_reply.doq_stream)
|
||||
doq_stream_remove_mesh_state(r->query_reply.doq_stream);
|
||||
comm_point_drop_reply(&r->query_reply);
|
||||
mstate->reply_list = reply_list;
|
||||
log_assert(mstate->s.env->mesh->num_reply_addrs > 0);
|
||||
@@ -1832,8 +1805,6 @@ void mesh_query_done(struct mesh_state* mstate)
|
||||
mstate->reply_list = NULL;
|
||||
if(r->query_reply.c->use_h2) {
|
||||
http2_stream_remove_mesh_state(r->h2_stream);
|
||||
} else if(r->query_reply.doq_stream) {
|
||||
doq_stream_remove_mesh_state(r->query_reply.doq_stream);
|
||||
}
|
||||
comm_point_drop_reply(&r->query_reply);
|
||||
mstate->reply_list = reply_list;
|
||||
@@ -2017,10 +1988,6 @@ 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);
|
||||
@@ -2029,8 +1996,6 @@ int mesh_state_add_reply(struct mesh_state* s, struct edns_data* edns,
|
||||
if(rep->c->use_h2)
|
||||
r->h2_stream = rep->c->h2_stream;
|
||||
else r->h2_stream = NULL;
|
||||
if(rep->c->type != comm_doq)
|
||||
r->query_reply.doq_stream = NULL;
|
||||
|
||||
/* Data related to local alias stored in 'qinfo' (if any) is ephemeral
|
||||
* and can be different for different original queries (even if the
|
||||
@@ -2388,7 +2353,7 @@ void mesh_list_remove(struct mesh_state* m, struct mesh_state** fp,
|
||||
}
|
||||
|
||||
void mesh_state_remove_reply(struct mesh_area* mesh, struct mesh_state* m,
|
||||
struct comm_point* cp, struct doq_stream* doq_stream)
|
||||
struct comm_point* cp)
|
||||
{
|
||||
struct mesh_reply* n, *prev = NULL;
|
||||
n = m->reply_list;
|
||||
@@ -2396,8 +2361,7 @@ void mesh_state_remove_reply(struct mesh_area* mesh, struct mesh_state* m,
|
||||
* there is no accounting twice */
|
||||
if(!n) return; /* nothing to remove, also no accounting needed */
|
||||
while(n) {
|
||||
if(n->query_reply.c == cp
|
||||
&& (!doq_stream || n->query_reply.doq_stream == doq_stream)) {
|
||||
if(n->query_reply.c == cp) {
|
||||
/* unlink it */
|
||||
if(prev) prev->next = n->next;
|
||||
else m->reply_list = n->next;
|
||||
@@ -2406,14 +2370,6 @@ 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;
|
||||
#ifdef HAVE_NGTCP2
|
||||
if(n->query_reply.doq_stream)
|
||||
n->query_reply.doq_stream->mesh_state = NULL;
|
||||
#endif
|
||||
|
||||
/* prev = prev; */
|
||||
n = n->next;
|
||||
@@ -2454,10 +2410,9 @@ apply_respip_action(struct module_qstate* qstate,
|
||||
|
||||
/* xxx_deny actions mean dropping the reply, unless the original reply
|
||||
* was redirected to response-ip data. */
|
||||
if(actinfo->action == respip_always_deny ||
|
||||
((actinfo->action == respip_deny ||
|
||||
if((actinfo->action == respip_deny ||
|
||||
actinfo->action == respip_inform_deny) &&
|
||||
*encode_repp == rep))
|
||||
*encode_repp == rep)
|
||||
*encode_repp = NULL;
|
||||
|
||||
return 1;
|
||||
@@ -2522,15 +2477,12 @@ mesh_serve_expired_callback(void* arg)
|
||||
qstate->client_info, &actinfo, msg->rep, &alias_rrset, &encode_rep,
|
||||
qstate->env->auth_zones)) {
|
||||
return;
|
||||
} else if(partial_rep) {
|
||||
if(!respip_merge_cname(partial_rep, &qstate->qinfo, msg->rep,
|
||||
} else if(partial_rep &&
|
||||
!respip_merge_cname(partial_rep, &qstate->qinfo, msg->rep,
|
||||
qstate->client_info, must_validate, &encode_rep, qstate->region,
|
||||
qstate->env->auth_zones, qstate->env->views,
|
||||
qstate->env->respip_set)) {
|
||||
return;
|
||||
}
|
||||
/* merge succeeded; final reply, no further alias pass */
|
||||
partial_rep = NULL;
|
||||
return;
|
||||
}
|
||||
if(!encode_rep || alias_rrset) {
|
||||
if(!encode_rep) {
|
||||
@@ -2541,7 +2493,6 @@ mesh_serve_expired_callback(void* arg)
|
||||
partial_rep = encode_rep;
|
||||
}
|
||||
}
|
||||
msg->rep = encode_rep;
|
||||
/* We've found a partial reply ending with an
|
||||
* alias. Replace the lookup qinfo for the
|
||||
* alias target and lookup the cache again to
|
||||
@@ -2568,10 +2519,9 @@ mesh_serve_expired_callback(void* arg)
|
||||
log_dns_msg("Serve expired lookup", &qstate->qinfo, msg->rep);
|
||||
|
||||
for(r = mstate->reply_list; r; r = r->next) {
|
||||
if(mesh_is_udp(r)) {
|
||||
struct timeval old;
|
||||
timeval_subtract(&old, mstate->s.env->now_tv, &r->start_time);
|
||||
if(mstate->s.env->cfg->discard_timeout != 0 &&
|
||||
struct timeval old;
|
||||
timeval_subtract(&old, mstate->s.env->now_tv, &r->start_time);
|
||||
if(mstate->s.env->cfg->discard_timeout != 0 &&
|
||||
((int)old.tv_sec)*1000+((int)old.tv_usec)/1000 >
|
||||
mstate->s.env->cfg->discard_timeout) {
|
||||
/* Drop the reply, it is too old */
|
||||
@@ -2587,15 +2537,10 @@ mesh_serve_expired_callback(void* arg)
|
||||
mstate->reply_list = NULL;
|
||||
if(r->query_reply.c->use_h2)
|
||||
http2_stream_remove_mesh_state(r->h2_stream);
|
||||
else if(r->query_reply.doq_stream)
|
||||
doq_stream_remove_mesh_state(r->query_reply.doq_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;
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
|
||||
+1
-13
@@ -191,12 +191,6 @@ 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)
|
||||
@@ -683,11 +677,9 @@ void mesh_list_remove(struct mesh_state* m, struct mesh_state** fp,
|
||||
* @param mesh: to update the counters.
|
||||
* @param m: the mesh state.
|
||||
* @param cp: the comm_point to remove from the list.
|
||||
* @param doq_stream: if not NULL, it specifies the doq_stream to match
|
||||
* for the delete.
|
||||
*/
|
||||
void mesh_state_remove_reply(struct mesh_area* mesh, struct mesh_state* m,
|
||||
struct comm_point* cp, struct doq_stream* doq_stream);
|
||||
struct comm_point* cp);
|
||||
|
||||
/** Callback for when the serve expired client timer has run out. Tries to
|
||||
* find an expired answer in the cache and reply that to the client.
|
||||
@@ -738,8 +730,4 @@ void mesh_respond_serve_expired(struct mesh_state* mstate);
|
||||
void mesh_remove_callback(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
uint16_t qflags, mesh_cb_func_type cb, void* cb_arg);
|
||||
|
||||
/** Copy the client info to the query region. */
|
||||
struct respip_client_info* mesh_copy_client_info(struct regional* region,
|
||||
struct respip_client_info* cinfo);
|
||||
|
||||
#endif /* SERVICES_MESH_H */
|
||||
|
||||
+75
-380
@@ -160,19 +160,6 @@ 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;
|
||||
}
|
||||
|
||||
@@ -208,7 +195,6 @@ static void
|
||||
waiting_tcp_delete(struct waiting_tcp* w)
|
||||
{
|
||||
if(!w) return;
|
||||
free(w->tls_auth_name);
|
||||
if(w->timer)
|
||||
comm_timer_delete(w->timer);
|
||||
free(w);
|
||||
@@ -545,7 +531,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, char* tls_auth_name)
|
||||
socklen_t addrlen, int use_ssl)
|
||||
{
|
||||
struct waiting_tcp key_w;
|
||||
struct pending_tcp key_p;
|
||||
@@ -559,10 +545,8 @@ 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);
|
||||
@@ -662,7 +646,6 @@ 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);
|
||||
@@ -763,22 +746,7 @@ 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(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,
|
||||
if(!set_auth_name_on_ssl(pend->c->ssl, w->tls_auth_name,
|
||||
w->outnet->tls_use_sni)) {
|
||||
pend->c->fd = s;
|
||||
#ifdef HAVE_SSL
|
||||
@@ -786,7 +754,6 @@ 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;
|
||||
}
|
||||
}
|
||||
@@ -811,20 +778,9 @@ 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;
|
||||
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);
|
||||
else pend->reuse.is_ssl = 0;
|
||||
/* 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);
|
||||
@@ -1013,7 +969,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->tls_auth_name);
|
||||
w->ssl_upstream);
|
||||
/* 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);
|
||||
@@ -1242,10 +1198,6 @@ 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) {
|
||||
@@ -1481,7 +1433,7 @@ portcomm_loweruse(struct outside_network* outnet, struct port_comm* pc)
|
||||
pif = pc->pif;
|
||||
log_assert(pif->inuse > 0);
|
||||
#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION
|
||||
shared_ports_return_port(outnet->shared_ports, pif->shpif, pc->number);
|
||||
pif->avail_ports[pif->avail_total - pif->inuse] = pc->number;
|
||||
#endif
|
||||
pif->inuse--;
|
||||
pif->out[pc->index] = pif->out[pif->inuse];
|
||||
@@ -1695,19 +1647,19 @@ create_pending_tcp(struct outside_network* outnet, size_t bufsize)
|
||||
}
|
||||
|
||||
/** setup an outgoing interface, ready address */
|
||||
static int setup_if(struct port_if* pif, const char* addrstr, size_t numfd,
|
||||
struct shared_ports* shp)
|
||||
static int setup_if(struct port_if* pif, const char* addrstr,
|
||||
int* avail, int numavail, size_t numfd)
|
||||
{
|
||||
#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION
|
||||
pif->avail_total = numavail;
|
||||
pif->avail_ports = (int*)memdup(avail, (size_t)numavail*sizeof(int));
|
||||
if(!pif->avail_ports)
|
||||
return 0;
|
||||
#endif
|
||||
if(!ipstrtoaddr(addrstr, UNBOUND_DNS_PORT, &pif->addr, &pif->addrlen) &&
|
||||
!netblockstrtoaddr(addrstr, UNBOUND_DNS_PORT,
|
||||
&pif->addr, &pif->addrlen, &pif->pfxlen))
|
||||
return 0;
|
||||
#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION
|
||||
pif->shpif = shared_ports_find_if(shp, &pif->addr, pif->addrlen,
|
||||
pif->pfxlen);
|
||||
#else
|
||||
(void)shp;
|
||||
#endif
|
||||
pif->maxout = (int)numfd;
|
||||
pif->inuse = 0;
|
||||
pif->out = (struct port_comm**)calloc(numfd,
|
||||
@@ -1721,12 +1673,12 @@ struct outside_network*
|
||||
outside_network_create(struct comm_base *base, size_t bufsize,
|
||||
size_t num_ports, char** ifs, int num_ifs, int do_ip4,
|
||||
int do_ip6, size_t num_tcp, int dscp, struct infra_cache* infra,
|
||||
struct ub_randstate* rnd, int use_caps_for_id,
|
||||
size_t unwanted_threshold, int tcp_mss,
|
||||
struct ub_randstate* rnd, int use_caps_for_id, int* availports,
|
||||
int numavailports, size_t unwanted_threshold, int tcp_mss,
|
||||
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, struct shared_ports* shared_ports)
|
||||
int tcp_auth_query_timeout)
|
||||
{
|
||||
struct outside_network* outnet = (struct outside_network*)
|
||||
calloc(1, sizeof(struct outside_network));
|
||||
@@ -1761,7 +1713,6 @@ outside_network_create(struct comm_base *base, size_t bufsize,
|
||||
outnet->do_udp = do_udp;
|
||||
outnet->tcp_mss = tcp_mss;
|
||||
outnet->ip_dscp = dscp;
|
||||
outnet->shared_ports = shared_ports;
|
||||
#ifndef S_SPLINT_S
|
||||
if(delayclose) {
|
||||
outnet->delayclose = 1;
|
||||
@@ -1772,7 +1723,7 @@ outside_network_create(struct comm_base *base, size_t bufsize,
|
||||
if(udp_connect) {
|
||||
outnet->udp_connect = 1;
|
||||
}
|
||||
if(num_ports == 0) {
|
||||
if(numavailports == 0 || num_ports == 0) {
|
||||
log_err("no outgoing ports available");
|
||||
outside_network_delete(outnet);
|
||||
return NULL;
|
||||
@@ -1833,13 +1784,13 @@ outside_network_create(struct comm_base *base, size_t bufsize,
|
||||
/* allocate interfaces */
|
||||
if(num_ifs == 0) {
|
||||
if(do_ip4 && !setup_if(&outnet->ip4_ifs[0], "0.0.0.0",
|
||||
num_ports, outnet->shared_ports)) {
|
||||
availports, numavailports, num_ports)) {
|
||||
log_err("malloc failed");
|
||||
outside_network_delete(outnet);
|
||||
return NULL;
|
||||
}
|
||||
if(do_ip6 && !setup_if(&outnet->ip6_ifs[0], "::",
|
||||
num_ports, outnet->shared_ports)) {
|
||||
availports, numavailports, num_ports)) {
|
||||
log_err("malloc failed");
|
||||
outside_network_delete(outnet);
|
||||
return NULL;
|
||||
@@ -1850,7 +1801,7 @@ outside_network_create(struct comm_base *base, size_t bufsize,
|
||||
for(i=0; i<num_ifs; i++) {
|
||||
if(str_is_ip6(ifs[i]) && do_ip6) {
|
||||
if(!setup_if(&outnet->ip6_ifs[done_6], ifs[i],
|
||||
num_ports, outnet->shared_ports)){
|
||||
availports, numavailports, num_ports)){
|
||||
log_err("malloc failed");
|
||||
outside_network_delete(outnet);
|
||||
return NULL;
|
||||
@@ -1859,7 +1810,7 @@ outside_network_create(struct comm_base *base, size_t bufsize,
|
||||
}
|
||||
if(!str_is_ip6(ifs[i]) && do_ip4) {
|
||||
if(!setup_if(&outnet->ip4_ifs[done_4], ifs[i],
|
||||
num_ports, outnet->shared_ports)){
|
||||
availports, numavailports, num_ports)){
|
||||
log_err("malloc failed");
|
||||
outside_network_delete(outnet);
|
||||
return NULL;
|
||||
@@ -1937,6 +1888,9 @@ outside_network_delete(struct outside_network* outnet)
|
||||
comm_point_delete(pc->cp);
|
||||
free(pc);
|
||||
}
|
||||
#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION
|
||||
free(outnet->ip4_ifs[i].avail_ports);
|
||||
#endif
|
||||
free(outnet->ip4_ifs[i].out);
|
||||
}
|
||||
free(outnet->ip4_ifs);
|
||||
@@ -1950,6 +1904,9 @@ outside_network_delete(struct outside_network* outnet)
|
||||
comm_point_delete(pc->cp);
|
||||
free(pc);
|
||||
}
|
||||
#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION
|
||||
free(outnet->ip6_ifs[i].avail_ports);
|
||||
#endif
|
||||
free(outnet->ip6_ifs[i].out);
|
||||
}
|
||||
free(outnet->ip6_ifs);
|
||||
@@ -1965,10 +1922,6 @@ 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;
|
||||
@@ -2159,10 +2112,7 @@ static int
|
||||
select_ifport(struct outside_network* outnet, struct pending* pend,
|
||||
int num_if, struct port_if* ifs)
|
||||
{
|
||||
int my_if, fd, portno, inuse, tries=0;
|
||||
#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION
|
||||
int reused;
|
||||
#endif
|
||||
int my_if, my_port, fd, portno, inuse, tries=0;
|
||||
struct port_if* pif;
|
||||
/* randomly select interface and port */
|
||||
if(num_if == 0) {
|
||||
@@ -2176,35 +2126,37 @@ select_ifport(struct outside_network* outnet, struct pending* pend,
|
||||
my_if = ub_random_max(outnet->rnd, num_if);
|
||||
pif = &ifs[my_if];
|
||||
#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION
|
||||
if(!shared_ports_fetch_random(outnet->shared_ports,
|
||||
pif->shpif, outnet->rnd, outnet->udp_connect,
|
||||
pif->inuse, &portno, &reused)) {
|
||||
tries++;
|
||||
if(tries < MAX_PORT_RETRY)
|
||||
continue;
|
||||
log_err("failed to find an open port, drop msg");
|
||||
return 0;
|
||||
if(outnet->udp_connect) {
|
||||
/* if we connect() we cannot reuse fds for a port */
|
||||
if(pif->inuse >= pif->avail_total) {
|
||||
tries++;
|
||||
if(tries < MAX_PORT_RETRY)
|
||||
continue;
|
||||
log_err("failed to find an open port, drop msg");
|
||||
return 0;
|
||||
}
|
||||
my_port = pif->inuse + ub_random_max(outnet->rnd,
|
||||
pif->avail_total - pif->inuse);
|
||||
} else {
|
||||
my_port = ub_random_max(outnet->rnd, pif->avail_total);
|
||||
if(my_port < pif->inuse) {
|
||||
/* port already open */
|
||||
pend->pc = pif->out[my_port];
|
||||
verbose(VERB_ALGO, "using UDP if=%d port=%d",
|
||||
my_if, pend->pc->number);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(reused) {
|
||||
/* port already open */
|
||||
log_assert(portno < pif->inuse);
|
||||
pend->pc = pif->out[portno];
|
||||
verbose(VERB_ALGO, "using UDP if=%d port=%d",
|
||||
my_if, pend->pc->number);
|
||||
break;
|
||||
}
|
||||
#else
|
||||
portno = 0;
|
||||
#endif
|
||||
/* try to open new port, if fails, loop to try again */
|
||||
log_assert(pif->inuse < pif->maxout);
|
||||
portno = pif->avail_ports[my_port - pif->inuse];
|
||||
#else
|
||||
my_port = portno = 0;
|
||||
#endif
|
||||
fd = udp_sockport(&pif->addr, pif->addrlen, pif->pfxlen,
|
||||
portno, &inuse, outnet->rnd, outnet->ip_dscp);
|
||||
if(fd == -1 && !inuse) {
|
||||
/* nonrecoverable error making socket */
|
||||
#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION
|
||||
shared_ports_return_port(outnet->shared_ports,
|
||||
pif->shpif, portno);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
if(fd != -1) {
|
||||
@@ -2221,11 +2173,6 @@ select_ifport(struct outside_network* outnet, struct pending* pend,
|
||||
pend->addrlen);
|
||||
}
|
||||
sock_close(fd);
|
||||
#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION
|
||||
shared_ports_return_port(
|
||||
outnet->shared_ports,
|
||||
pif->shpif, portno);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -2243,14 +2190,14 @@ select_ifport(struct outside_network* outnet, struct pending* pend,
|
||||
|
||||
/* grab port in interface */
|
||||
pif->out[pif->inuse] = pend->pc;
|
||||
#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION
|
||||
pif->avail_ports[my_port - pif->inuse] =
|
||||
pif->avail_ports[pif->avail_total-pif->inuse-1];
|
||||
#endif
|
||||
pif->inuse++;
|
||||
break;
|
||||
}
|
||||
/* failed, already in use */
|
||||
#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION
|
||||
shared_ports_return_port(outnet->shared_ports, pif->shpif,
|
||||
portno);
|
||||
#endif
|
||||
verbose(VERB_QUERY, "port %d in use, trying another", portno);
|
||||
tries++;
|
||||
if(tries == MAX_PORT_RETRY) {
|
||||
@@ -2500,7 +2447,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->tls_auth_name);
|
||||
sq->ssl_upstream);
|
||||
if(reuse) {
|
||||
log_reuse_tcp(VERB_CLIENT, "pending_tcp_query: found reuse", reuse);
|
||||
log_assert(reuse->pending);
|
||||
@@ -2542,16 +2489,7 @@ pending_tcp_query(struct serviced_query* sq, sldns_buffer* packet,
|
||||
w->cb = callback;
|
||||
w->cb_arg = callback_arg;
|
||||
w->ssl_upstream = sq->ssl_upstream;
|
||||
if(sq->tls_auth_name) {
|
||||
w->tls_auth_name = strdup(sq->tls_auth_name);
|
||||
if(!w->tls_auth_name) {
|
||||
comm_timer_delete(w->timer);
|
||||
free(w);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
w->tls_auth_name = NULL;
|
||||
}
|
||||
w->tls_auth_name = sq->tls_auth_name;
|
||||
w->timeout = timeout;
|
||||
w->id_node.key = NULL;
|
||||
w->write_wait_prev = NULL;
|
||||
@@ -3641,16 +3579,13 @@ fd_for_dest(struct outside_network* outnet, struct sockaddr_storage* to_addr,
|
||||
{
|
||||
struct sockaddr_storage* addr;
|
||||
socklen_t addrlen;
|
||||
int i, try, dscp;
|
||||
int i, try, pnum, dscp;
|
||||
struct port_if* pif;
|
||||
|
||||
/* create fd */
|
||||
dscp = outnet->ip_dscp;
|
||||
for(try = 0; try<1000; try++) {
|
||||
int port = 0;
|
||||
#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION
|
||||
int reused = 0;
|
||||
#endif
|
||||
int freebind = 0;
|
||||
int noproto = 0;
|
||||
int inuse = 0;
|
||||
@@ -3679,18 +3614,16 @@ fd_for_dest(struct outside_network* outnet, struct sockaddr_storage* to_addr,
|
||||
addr = &pif->addr;
|
||||
addrlen = pif->addrlen;
|
||||
#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION
|
||||
if(!shared_ports_fetch_random(outnet->shared_ports,
|
||||
pif->shpif, outnet->rnd, 0, pif->inuse,
|
||||
&port, &reused)) {
|
||||
/* try again, perhaps another interface. */
|
||||
continue;
|
||||
}
|
||||
if(reused) {
|
||||
log_assert(port < pif->inuse);
|
||||
port = pif->out[port]->number;
|
||||
pnum = ub_random_max(outnet->rnd, pif->avail_total);
|
||||
if(pnum < pif->inuse) {
|
||||
/* port already open */
|
||||
port = pif->out[pnum]->number;
|
||||
} else {
|
||||
/* unused ports in start part of array */
|
||||
port = pif->avail_ports[pnum - pif->inuse];
|
||||
}
|
||||
#else
|
||||
port = 0;
|
||||
pnum = port = 0;
|
||||
#endif
|
||||
if(addr_is_ip6(to_addr, to_addrlen)) {
|
||||
struct sockaddr_in6 sa = *(struct sockaddr_in6*)addr;
|
||||
@@ -3705,14 +3638,6 @@ fd_for_dest(struct outside_network* outnet, struct sockaddr_storage* to_addr,
|
||||
(struct sockaddr*)addr, addrlen, 1, &inuse, &noproto,
|
||||
0, 0, 0, NULL, 0, freebind, 0, dscp);
|
||||
}
|
||||
#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION
|
||||
if(!reused) {
|
||||
/* Return the port to the pool, since the caller does
|
||||
* not keep track of it, also have done fd, and bind. */
|
||||
shared_ports_return_port(outnet->shared_ports,
|
||||
pif->shpif, port);
|
||||
}
|
||||
#endif
|
||||
if(fd != -1) {
|
||||
return fd;
|
||||
}
|
||||
@@ -3943,7 +3868,11 @@ if_get_mem(struct port_if* pif)
|
||||
{
|
||||
size_t s;
|
||||
int i;
|
||||
s = sizeof(*pif) + sizeof(struct port_comm*)*pif->maxout;
|
||||
s = sizeof(*pif) +
|
||||
#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION
|
||||
sizeof(int)*pif->avail_total +
|
||||
#endif
|
||||
sizeof(struct port_comm*)*pif->maxout;
|
||||
for(i=0; i<pif->inuse; i++)
|
||||
s += sizeof(*pif->out[i]) +
|
||||
comm_point_get_mem(pif->out[i]->cp);
|
||||
@@ -4031,237 +3960,3 @@ serviced_get_mem(struct serviced_query* sq)
|
||||
return s;
|
||||
}
|
||||
|
||||
#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION
|
||||
/** Setup shared port interface */
|
||||
static int shared_ports_setup_if(struct shared_ports_if* shpif, char* str,
|
||||
int* availports, int numavailports)
|
||||
{
|
||||
shpif->avail_ports = (int*)memdup(availports,
|
||||
(size_t)numavailports*sizeof(int));
|
||||
if(!shpif->avail_ports)
|
||||
return 0;
|
||||
shpif->avail_total = numavailports;
|
||||
shpif->inuse = 0;
|
||||
shpif->pfxlen = 0;
|
||||
if(!ipstrtoaddr(str, UNBOUND_DNS_PORT, &shpif->addr, &shpif->addrlen) &&
|
||||
!netblockstrtoaddr(str, UNBOUND_DNS_PORT, &shpif->addr,
|
||||
&shpif->addrlen, &shpif->pfxlen))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION
|
||||
/** Allocate shared ports interfaces */
|
||||
static int shared_ports_alloc_ifs(struct shared_ports* shp, char** ifs,
|
||||
int num_ifs, int do_ip4, int do_ip6, int* availports,
|
||||
int numavailports)
|
||||
{
|
||||
#ifndef INET6
|
||||
do_ip6 = 0;
|
||||
#endif
|
||||
calc_num46(ifs, num_ifs, do_ip4, do_ip6,
|
||||
&shp->num_ip4, &shp->num_ip6);
|
||||
if(shp->num_ip4 != 0) {
|
||||
if(!(shp->ip4_ifs = (struct shared_ports_if*)calloc(
|
||||
(size_t)shp->num_ip4,
|
||||
sizeof(struct shared_ports_if))))
|
||||
return 0;
|
||||
}
|
||||
if(shp->num_ip6 != 0) {
|
||||
if(!(shp->ip6_ifs = (struct shared_ports_if*)calloc(
|
||||
(size_t)shp->num_ip6,
|
||||
sizeof(struct shared_ports_if))))
|
||||
return 0;
|
||||
}
|
||||
if(num_ifs == 0) {
|
||||
if(do_ip4 && !shared_ports_setup_if(&shp->ip4_ifs[0],
|
||||
"0.0.0.0", availports, numavailports))
|
||||
return 0;
|
||||
if(do_ip6 && !shared_ports_setup_if(&shp->ip6_ifs[0],
|
||||
"::", availports, numavailports))
|
||||
return 0;
|
||||
} else {
|
||||
size_t done_4 = 0, done_6 = 0;
|
||||
int i;
|
||||
for(i=0; i<num_ifs; i++) {
|
||||
if(str_is_ip6(ifs[i]) && do_ip6) {
|
||||
if(!shared_ports_setup_if(&shp->ip6_ifs[done_6],
|
||||
ifs[i], availports, numavailports))
|
||||
return 0;
|
||||
done_6++;
|
||||
}
|
||||
if(!str_is_ip6(ifs[i]) && do_ip4) {
|
||||
if(!shared_ports_setup_if(&shp->ip4_ifs[done_4],
|
||||
ifs[i], availports, numavailports))
|
||||
return 0;
|
||||
done_4++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct shared_ports* shared_ports_create(char** ifs, int num_ifs, int do_ip4,
|
||||
int do_ip6, int* availports, int numavailports)
|
||||
{
|
||||
struct shared_ports* shp = calloc(1, sizeof(*shp));
|
||||
if(!shp) {
|
||||
log_err("malloc failed");
|
||||
return NULL;
|
||||
}
|
||||
lock_basic_init(&shp->lock);
|
||||
lock_protect(&shp->lock, shp, sizeof(*shp));
|
||||
|
||||
#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION
|
||||
/* Allocate interfaces */
|
||||
if(!shared_ports_alloc_ifs(shp, ifs, num_ifs, do_ip4, do_ip6,
|
||||
availports, numavailports)) {
|
||||
log_err("malloc failed");
|
||||
shared_ports_delete(shp);
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
(void)ifs; (void)num_ifs; (void)do_ip4; (void)do_ip6;
|
||||
(void)availports; (void)numavailports;
|
||||
#endif
|
||||
return shp;
|
||||
}
|
||||
|
||||
#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION
|
||||
/** Delete shared ports interface structure */
|
||||
static void shared_ports_if_delete(struct shared_ports_if* shpif)
|
||||
{
|
||||
if(!shpif)
|
||||
return;
|
||||
free(shpif->avail_ports);
|
||||
}
|
||||
#endif
|
||||
|
||||
void shared_ports_delete(struct shared_ports* shp)
|
||||
{
|
||||
#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION
|
||||
int i;
|
||||
#endif
|
||||
if(!shp)
|
||||
return;
|
||||
lock_basic_destroy(&shp->lock);
|
||||
#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION
|
||||
for(i=0; i<shp->num_ip4; i++) {
|
||||
shared_ports_if_delete(&shp->ip4_ifs[i]);
|
||||
}
|
||||
free(shp->ip4_ifs);
|
||||
for(i=0; i<shp->num_ip6; i++) {
|
||||
shared_ports_if_delete(&shp->ip6_ifs[i]);
|
||||
}
|
||||
free(shp->ip6_ifs);
|
||||
#endif
|
||||
free(shp);
|
||||
}
|
||||
|
||||
struct shared_ports_if* shared_ports_find_if(struct shared_ports* shp,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, int pfxlen)
|
||||
{
|
||||
#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION
|
||||
struct shared_ports_if* ret, *ifs = NULL;
|
||||
int i, num_ifs = 0;
|
||||
lock_basic_lock(&shp->lock);
|
||||
if(addr_is_ip6(addr, addrlen)) {
|
||||
ifs = shp->ip6_ifs;
|
||||
num_ifs = shp->num_ip6;
|
||||
} else {
|
||||
ifs = shp->ip4_ifs;
|
||||
num_ifs = shp->num_ip4;
|
||||
}
|
||||
for(i=0; i<num_ifs; i++) {
|
||||
if(sockaddr_cmp(addr, addrlen, &ifs[i].addr,
|
||||
ifs[i].addrlen) == 0
|
||||
&& pfxlen == ifs[i].pfxlen) {
|
||||
ret = &ifs[i];
|
||||
lock_basic_unlock(&shp->lock);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
lock_basic_unlock(&shp->lock);
|
||||
return NULL;
|
||||
#else
|
||||
(void)shp; (void)addr; (void)addrlen; (void)pfxlen;
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
int shared_ports_fetch_random(struct shared_ports* shp,
|
||||
struct shared_ports_if* shpif, struct ub_randstate* rnd,
|
||||
int udp_connect, int reusenum, int* port, int* reused)
|
||||
{
|
||||
#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION
|
||||
int portno = 0, my_port = 0;
|
||||
if(!shpif)
|
||||
return 0;
|
||||
lock_basic_lock(&shp->lock);
|
||||
if(udp_connect) {
|
||||
/* if we connect() we cannot reuse fds for a port. */
|
||||
if(shpif->inuse >= shpif->avail_total) {
|
||||
lock_basic_unlock(&shp->lock);
|
||||
return 0;
|
||||
}
|
||||
my_port = ub_random_max(rnd,
|
||||
shpif->avail_total - shpif->inuse);
|
||||
} else {
|
||||
/* select from free ports and open ports on this thread. */
|
||||
if(shpif->inuse >= shpif->avail_total) {
|
||||
lock_basic_unlock(&shp->lock);
|
||||
if(reusenum == 0) {
|
||||
return 0;
|
||||
}
|
||||
my_port = ub_random_max(rnd, reusenum);
|
||||
*port = my_port;
|
||||
*reused = 1;
|
||||
return 1;
|
||||
}
|
||||
my_port = ub_random_max(rnd, shpif->avail_total - shpif->inuse
|
||||
+ reusenum);
|
||||
if(my_port < reusenum) {
|
||||
/* port already open */
|
||||
lock_basic_unlock(&shp->lock);
|
||||
*port = my_port;
|
||||
*reused = 1;
|
||||
return 1;
|
||||
}
|
||||
my_port -= reusenum;
|
||||
}
|
||||
log_assert(shpif->inuse < shpif->avail_total);
|
||||
log_assert(my_port >= 0 && my_port < shpif->avail_total);
|
||||
portno = shpif->avail_ports[my_port];
|
||||
shpif->avail_ports[my_port] =
|
||||
shpif->avail_ports[shpif->avail_total-shpif->inuse-1];
|
||||
shpif->inuse++;
|
||||
lock_basic_unlock(&shp->lock);
|
||||
*port = portno;
|
||||
*reused = 0;
|
||||
return 1;
|
||||
#else
|
||||
(void)shp; (void)shpif; (void)rnd; (void)udp_connect;
|
||||
(void)reusenum;
|
||||
*port = 0;
|
||||
*reused = 0;
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
void shared_ports_return_port(struct shared_ports* shp,
|
||||
struct shared_ports_if* shpif, int port)
|
||||
{
|
||||
#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION
|
||||
if(!shpif)
|
||||
return;
|
||||
lock_basic_lock(&shp->lock);
|
||||
log_assert(shpif->inuse > 0);
|
||||
shpif->avail_ports[shpif->avail_total - shpif->inuse] = port;
|
||||
shpif->inuse--;
|
||||
lock_basic_unlock(&shp->lock);
|
||||
#else
|
||||
(void)shp; (void)shpif; (void)port;
|
||||
#endif
|
||||
}
|
||||
|
||||
+11
-99
@@ -70,8 +70,6 @@ struct module_env;
|
||||
struct module_qstate;
|
||||
struct query_info;
|
||||
struct config_file;
|
||||
struct shared_ports;
|
||||
struct shared_ports_if;
|
||||
|
||||
/**
|
||||
* Send queries to outside servers and wait for answers from servers.
|
||||
@@ -121,9 +119,6 @@ struct outside_network {
|
||||
int udp_connect;
|
||||
/** number of udp packets sent. */
|
||||
size_t num_udp_outgoing;
|
||||
/** the shared ports structure, with random ports numbers.
|
||||
* This is a reference to the member in the daemon structure. */
|
||||
struct shared_ports* shared_ports;
|
||||
|
||||
/** array of outgoing IP4 interfaces */
|
||||
struct port_if* ip4_ifs;
|
||||
@@ -216,8 +211,11 @@ struct port_if {
|
||||
int pfxlen;
|
||||
|
||||
#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION
|
||||
/** the shared port numbers for this interface. */
|
||||
struct shared_ports_if* shpif;
|
||||
/** the available ports array. These are unused.
|
||||
* Only the first total-inuse part is filled. */
|
||||
int* avail_ports;
|
||||
/** the total number of available ports (size of the array) */
|
||||
int avail_total;
|
||||
#endif
|
||||
|
||||
/** array of the commpoints currently in use.
|
||||
@@ -247,42 +245,6 @@ struct port_comm {
|
||||
struct comm_point* cp;
|
||||
};
|
||||
|
||||
/**
|
||||
* Shared ports, the list of ports shared across threads
|
||||
*/
|
||||
struct shared_ports {
|
||||
/** mutex on the ports */
|
||||
lock_basic_type lock;
|
||||
/** array of IP4 interfaces */
|
||||
struct shared_ports_if* ip4_ifs;
|
||||
/** number of outgoing IP4 interfaces */
|
||||
int num_ip4;
|
||||
/** array of IP6 interfaces */
|
||||
struct shared_ports_if* ip6_ifs;
|
||||
/** number of outgoing IP6 interfaces */
|
||||
int num_ip6;
|
||||
};
|
||||
|
||||
/**
|
||||
* Shared ports for an interface.
|
||||
*/
|
||||
struct shared_ports_if {
|
||||
/** address ready to allocate new socket (except port no). */
|
||||
struct sockaddr_storage addr;
|
||||
/** length of addr field */
|
||||
socklen_t addrlen;
|
||||
/** if a netblock, the prefix */
|
||||
int pfxlen;
|
||||
|
||||
/** the available ports array. These are unused.
|
||||
* Only the first total-inuse part is filled. */
|
||||
int* avail_ports;
|
||||
/** the total number of available ports (size of the array) */
|
||||
int avail_total;
|
||||
/** the number in use. */
|
||||
int inuse;
|
||||
};
|
||||
|
||||
/**
|
||||
* Reuse TCP connection, still open can be used again.
|
||||
*/
|
||||
@@ -302,9 +264,6 @@ 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,
|
||||
@@ -457,7 +416,7 @@ struct waiting_tcp {
|
||||
void* cb_arg;
|
||||
/** if it uses ssl upstream */
|
||||
int ssl_upstream;
|
||||
/** owned copy of the tls_auth_name (malloced) */
|
||||
/** ref to the tls_auth_name from the serviced_query */
|
||||
char* tls_auth_name;
|
||||
/** the packet was involved in an error, to stop looping errors */
|
||||
int error_count;
|
||||
@@ -589,6 +548,8 @@ struct serviced_query {
|
||||
* @param infra: pointer to infra cached used for serviced queries.
|
||||
* @param rnd: stored to create random numbers for serviced queries.
|
||||
* @param use_caps_for_id: enable to use 0x20 bits to encode id randomness.
|
||||
* @param availports: array of available ports.
|
||||
* @param numavailports: number of available ports in array.
|
||||
* @param unwanted_threshold: when to take defensive action.
|
||||
* @param unwanted_action: the action to take.
|
||||
* @param unwanted_param: user parameter to action.
|
||||
@@ -603,18 +564,17 @@ struct serviced_query {
|
||||
* @param max_reuse_tcp_queries: max number of queries on a reuse connection.
|
||||
* @param tcp_reuse_timeout: timeout for REUSE entries in milliseconds.
|
||||
* @param tcp_auth_query_timeout: timeout in milliseconds for TCP queries to auth servers.
|
||||
* @param shared_ports: the shared_ports structure.
|
||||
* @return: the new structure (with no pending answers) or NULL on error.
|
||||
*/
|
||||
struct outside_network* outside_network_create(struct comm_base* base,
|
||||
size_t bufsize, size_t num_ports, char** ifs, int num_ifs,
|
||||
int do_ip4, int do_ip6, size_t num_tcp, int dscp, struct infra_cache* infra,
|
||||
struct ub_randstate* rnd, int use_caps_for_id,
|
||||
size_t unwanted_threshold, int tcp_mss,
|
||||
struct ub_randstate* rnd, int use_caps_for_id, int* availports,
|
||||
int numavailports, size_t unwanted_threshold, int tcp_mss,
|
||||
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, struct shared_ports* shared_ports);
|
||||
int tcp_auth_query_timeout);
|
||||
|
||||
/**
|
||||
* Delete outside_network structure.
|
||||
@@ -856,54 +816,6 @@ struct comm_point* outnet_comm_point_for_http(struct outside_network* outnet,
|
||||
/** connect tcp connection to addr, 0 on failure */
|
||||
int outnet_tcp_connect(int s, struct sockaddr_storage* addr, socklen_t addrlen);
|
||||
|
||||
/**
|
||||
* Create new shared ports structure.
|
||||
* @param ifs: interface names (or NULL for default interface).
|
||||
* These interfaces must be able to access all authoritative servers.
|
||||
* @param num_ifs: number of names in array ifs.
|
||||
* @param do_ip4: service IP4.
|
||||
* @param do_ip6: service IP6.
|
||||
* @param availports: array of available ports.
|
||||
* @param numavailports: number of available ports in array.
|
||||
* @return new, or NULL on failure.
|
||||
*/
|
||||
struct shared_ports* shared_ports_create(char** ifs, int num_ifs, int do_ip4,
|
||||
int do_ip6, int* availports, int numavailports);
|
||||
|
||||
/**
|
||||
* Delete shared ports structure.
|
||||
* @param shp: shared ports structure.
|
||||
*/
|
||||
void shared_ports_delete(struct shared_ports* shp);
|
||||
|
||||
/** Find interface in shared ports. */
|
||||
struct shared_ports_if* shared_ports_find_if(struct shared_ports* shp,
|
||||
struct sockaddr_storage* addr, socklen_t addrlen, int pfxlen);
|
||||
|
||||
/**
|
||||
* Get a shared port from the list of random ports.
|
||||
* @param shp: shared ports structure.
|
||||
* @param shpif: the shared ports interface.
|
||||
* @param rnd: used to make random numbers.
|
||||
* @param udp_connect: set to true if no reuse is possible.
|
||||
* @param reusenum: number of ports that can be reused (already open).
|
||||
* @param port: the port number is returned.
|
||||
* @param reused: if the port numer is reused, returned.
|
||||
* @return false on failure. That can mean no more free ports to use.
|
||||
*/
|
||||
int shared_ports_fetch_random(struct shared_ports* shp,
|
||||
struct shared_ports_if* shpif, struct ub_randstate* rnd,
|
||||
int udp_connect, int reusenum, int* port, int* reused);
|
||||
|
||||
/**
|
||||
* Return a shared port to the list of random ports.
|
||||
* @param shp: shared ports structure.
|
||||
* @param shpif: the shared ports interface.
|
||||
* @param port: port number to return to be used again.
|
||||
*/
|
||||
void shared_ports_return_port(struct shared_ports* shp,
|
||||
struct shared_ports_if* shpif, int port);
|
||||
|
||||
/** callback for incoming udp answers from the network */
|
||||
int outnet_udp_cb(struct comm_point* c, void* arg, int error,
|
||||
struct comm_reply *reply_info);
|
||||
|
||||
+4
-6
@@ -2469,7 +2469,6 @@ 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;
|
||||
@@ -2513,11 +2512,13 @@ 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,12 +2533,9 @@ rpz_callback_from_iterator_module(struct module_qstate* ms, struct iter_qstate*
|
||||
if(z) {
|
||||
lock_rw_unlock(&z->lock);
|
||||
}
|
||||
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_nsip_trigger(ms, &is->qchase, r, raddr, a);
|
||||
}
|
||||
lock_rw_unlock(&a->lock);
|
||||
return ret;
|
||||
return rpz_apply_nsdname_trigger(ms, &is->qchase, r, z, &match, a);
|
||||
}
|
||||
|
||||
struct dns_msg* rpz_callback_from_iterator_cname(struct module_qstate* ms,
|
||||
|
||||
@@ -128,12 +128,6 @@ worker_alloc_cleanup(void* ATTR_UNUSED(arg))
|
||||
log_assert(0);
|
||||
}
|
||||
|
||||
void
|
||||
libworker_alloc_cleanup(void* ATTR_UNUSED(arg))
|
||||
{
|
||||
log_assert(0);
|
||||
}
|
||||
|
||||
struct outbound_entry* libworker_send_query(
|
||||
struct query_info* ATTR_UNUSED(qinfo), uint16_t ATTR_UNUSED(flags),
|
||||
int ATTR_UNUSED(dnssec), int ATTR_UNUSED(want_dnssec),
|
||||
|
||||
@@ -360,7 +360,6 @@ 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 */
|
||||
|
||||
@@ -1519,9 +1519,9 @@ doq_client_send_pkt(struct doq_client_data* data, uint32_t ecn, uint8_t* buf,
|
||||
}
|
||||
log_err("doq sendmsg: %s", strerror(errno));
|
||||
#ifdef HAVE_NGTCP2_CCERR_DEFAULT
|
||||
ngtcp2_ccerr_set_application_error(&data->ccerr, 1, NULL, 0);
|
||||
ngtcp2_ccerr_set_application_error(&data->ccerr, -1, NULL, 0);
|
||||
#else
|
||||
ngtcp2_connection_close_error_set_application_error(&data->last_error, 1, NULL, 0);
|
||||
ngtcp2_connection_close_error_set_application_error(&data->last_error, -1, NULL, 0);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
@@ -2671,11 +2671,6 @@ void libworker_event_done_cb(void* ATTR_UNUSED(arg), int ATTR_UNUSED(rcode),
|
||||
log_assert(0);
|
||||
}
|
||||
|
||||
void libworker_alloc_cleanup(void* ATTR_UNUSED(arg))
|
||||
{
|
||||
log_assert(0);
|
||||
}
|
||||
|
||||
int context_query_cmp(const void* ATTR_UNUSED(a), const void* ATTR_UNUSED(b))
|
||||
{
|
||||
log_assert(0);
|
||||
|
||||
+3
-27
@@ -1126,16 +1126,15 @@ outside_network_create(struct comm_base* base, size_t bufsize,
|
||||
int ATTR_UNUSED(dscp),
|
||||
struct infra_cache* infra,
|
||||
struct ub_randstate* ATTR_UNUSED(rnd),
|
||||
int ATTR_UNUSED(use_caps_for_id),
|
||||
size_t ATTR_UNUSED(unwanted_threshold),
|
||||
int ATTR_UNUSED(use_caps_for_id), int* ATTR_UNUSED(availports),
|
||||
int ATTR_UNUSED(numavailports), size_t ATTR_UNUSED(unwanted_threshold),
|
||||
int ATTR_UNUSED(outgoing_tcp_mss),
|
||||
void (*unwanted_action)(void*), void* ATTR_UNUSED(unwanted_param),
|
||||
int ATTR_UNUSED(do_udp), void* ATTR_UNUSED(sslctx),
|
||||
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),
|
||||
struct shared_ports* ATTR_UNUSED(shared_ports))
|
||||
int ATTR_UNUSED(tcp_auth_query_timeout))
|
||||
{
|
||||
struct replay_runtime* runtime = (struct replay_runtime*)base;
|
||||
struct outside_network* outnet = calloc(1,
|
||||
@@ -1981,20 +1980,6 @@ int outnet_tcp_connect(int ATTR_UNUSED(s), struct sockaddr_storage* ATTR_UNUSED(
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct shared_ports* shared_ports_create(char** ATTR_UNUSED(ifs),
|
||||
int ATTR_UNUSED(num_ifs), int ATTR_UNUSED(do_ip4),
|
||||
int ATTR_UNUSED(do_ip6), int* ATTR_UNUSED(availports),
|
||||
int ATTR_UNUSED(numavailports))
|
||||
{
|
||||
return calloc(1, sizeof(struct shared_ports));
|
||||
}
|
||||
|
||||
void shared_ports_delete(struct shared_ports* shp)
|
||||
{
|
||||
if(!shp) return;
|
||||
free(shp);
|
||||
}
|
||||
|
||||
int tcp_req_info_add_meshstate(struct tcp_req_info* ATTR_UNUSED(req),
|
||||
struct mesh_area* ATTR_UNUSED(mesh), struct mesh_state* ATTR_UNUSED(m))
|
||||
{
|
||||
@@ -2036,15 +2021,6 @@ void http2_stream_remove_mesh_state(struct http2_stream* ATTR_UNUSED(h2_stream))
|
||||
{
|
||||
}
|
||||
|
||||
void doq_stream_add_meshstate(struct doq_stream* ATTR_UNUSED(stream),
|
||||
struct mesh_area* ATTR_UNUSED(mesh), struct mesh_state* ATTR_UNUSED(m))
|
||||
{
|
||||
}
|
||||
|
||||
void doq_stream_remove_mesh_state(struct doq_stream* ATTR_UNUSED(stream))
|
||||
{
|
||||
}
|
||||
|
||||
void fast_reload_service_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(event),
|
||||
void* ATTR_UNUSED(arg))
|
||||
{
|
||||
|
||||
+2
-17
@@ -160,26 +160,11 @@ read_ssl_line(SSL* ssl, char* buf, size_t len)
|
||||
return 0;
|
||||
}
|
||||
if((r = SSL_read(ssl, buf+n, 1)) <= 0) {
|
||||
int e = SSL_get_error(ssl, r);
|
||||
if(e == SSL_ERROR_ZERO_RETURN) {
|
||||
if(SSL_get_error(ssl, r) == 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') {
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "daemon/remote.h"
|
||||
#include "libunbound/worker.h"
|
||||
#include "daemon/worker.h"
|
||||
#include "daemon/metrics.h"
|
||||
#include "util/config_file.h"
|
||||
#include "sldns/keyraw.h"
|
||||
#ifdef UB_ON_WINDOWS
|
||||
@@ -664,6 +665,42 @@ void remote_get_opt_ssl(char* ATTR_UNUSED(str), void* ATTR_UNUSED(arg))
|
||||
log_assert(0);
|
||||
}
|
||||
|
||||
/* fake metrics */
|
||||
struct daemon_metrics* daemon_metrics_create(void)
|
||||
{
|
||||
return (struct daemon_metrics*)calloc(1, sizeof(struct daemon_metrics));
|
||||
}
|
||||
|
||||
void daemon_metrics_delete(struct daemon_metrics* m)
|
||||
{
|
||||
if(!m) return;
|
||||
free(m);
|
||||
}
|
||||
|
||||
void daemon_metrics_close_ports(struct daemon_metrics* ATTR_UNUSED(m))
|
||||
{
|
||||
/* nothing */
|
||||
}
|
||||
|
||||
void daemon_metrics_detach(struct daemon_metrics* ATTR_UNUSED(m))
|
||||
{
|
||||
/* nothing */
|
||||
}
|
||||
|
||||
int daemon_metrics_open_ports(struct daemon_metrics* ATTR_UNUSED(m),
|
||||
struct config_file* ATTR_UNUSED(cfg))
|
||||
{
|
||||
/* nothing */
|
||||
return 1;
|
||||
}
|
||||
|
||||
int daemon_metrics_attach(struct daemon_metrics* ATTR_UNUSED(m),
|
||||
struct worker* ATTR_UNUSED(worker))
|
||||
{
|
||||
/* nothing */
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef UB_ON_WINDOWS
|
||||
void wsvc_command_option(const char* ATTR_UNUSED(wopt),
|
||||
const char* ATTR_UNUSED(cfgfile), int ATTR_UNUSED(v),
|
||||
|
||||
+2
-58
@@ -1092,7 +1092,7 @@ static void edns_ede_encode_notxt_fit_test( struct query_info* qinfo,
|
||||
{
|
||||
struct edns_data edns;
|
||||
sldns_buffer* pkt;
|
||||
size_t edns_field_size, ede_txt_size;
|
||||
uint16_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;
|
||||
size_t edns_field_size, ede_size, ede_txt_size;
|
||||
uint16_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);
|
||||
@@ -1282,61 +1282,6 @@ static void localzone_test(void)
|
||||
localzone_parents_test();
|
||||
}
|
||||
|
||||
#include "services/mesh.h"
|
||||
/** mesh unit tests */
|
||||
static void mesh_test(void)
|
||||
{
|
||||
struct regional* r2, *r3;
|
||||
struct respip_client_info* c1, *c2, *c3;
|
||||
unit_show_func("services/mesh.c", "mesh_copy_client_info");
|
||||
r2 = regional_create();
|
||||
r3 = regional_create();
|
||||
if(!r2 || !r3) fatal_exit("out of memory");
|
||||
|
||||
c1 = calloc(1, sizeof(*c1));
|
||||
if(!c1) fatal_exit("out of memory");
|
||||
c1->view = calloc(1, sizeof(*c1->view));
|
||||
if(!c1->view) fatal_exit("out of memory");
|
||||
c1->view->name = strdup("view1");
|
||||
if(!c1->view->name) fatal_exit("out of memory");
|
||||
|
||||
c2 = mesh_copy_client_info(r2, c1);
|
||||
if(!c2) fatal_exit("out of memory");
|
||||
c3 = mesh_copy_client_info(r3, c2);
|
||||
if(!c3) fatal_exit("out of memory");
|
||||
|
||||
unit_assert(strcmp(c1->view->name, c2->view_name) == 0);
|
||||
unit_assert(strcmp(c1->view->name, c3->view_name) == 0);
|
||||
|
||||
/* make sure that the c3 view_name is in the r3 region. */
|
||||
unit_assert(r3->next == NULL); /* only the first chunk present atm */
|
||||
if(strlen(c3->view_name) >= r3->large_object_size) {
|
||||
char* a = r3->large_list;
|
||||
int found = 0;
|
||||
while(a) {
|
||||
if(strcmp(c3->view_name,
|
||||
a + /* ALIGNEMENT */ sizeof(uint64_t)) == 0) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
a = *(char**)a;
|
||||
}
|
||||
unit_assert(found == 1);
|
||||
} else {
|
||||
/* The allocation is expected in the r3 region first chunk */
|
||||
unit_assert((uint8_t*)c3->view_name < ((uint8_t*)r3)+r3->first_size);
|
||||
}
|
||||
|
||||
regional_destroy(r2);
|
||||
/* ASAN should complain for the freed access below */
|
||||
unit_assert(strcmp(c1->view->name, c3->view_name) == 0);
|
||||
|
||||
regional_destroy(r3);
|
||||
free(c1->view->name);
|
||||
free(c1->view);
|
||||
free(c1);
|
||||
}
|
||||
|
||||
void unit_show_func(const char* file, const char* func)
|
||||
{
|
||||
printf("test %s:%s\n", file, func);
|
||||
@@ -1411,7 +1356,6 @@ main(int argc, char* argv[])
|
||||
msgparse_test();
|
||||
edns_ede_answer_encode_test();
|
||||
localzone_test();
|
||||
mesh_test();
|
||||
#ifdef CLIENT_SUBNET
|
||||
ecs_test();
|
||||
#endif /* CLIENT_SUBNET */
|
||||
|
||||
@@ -41,7 +41,6 @@
|
||||
#include "config.h"
|
||||
#include "testcode/unitmain.h"
|
||||
#include "util/log.h"
|
||||
#include "util/net_help.h"
|
||||
#include "util/random.h"
|
||||
#include "services/outside_network.h"
|
||||
|
||||
@@ -480,278 +479,6 @@ static void reuse_write_wait_test(void)
|
||||
check_reuse_write_wait_removal(1, &reuse, store, 0, 1);
|
||||
}
|
||||
|
||||
static void shared_port_test_ifs(void)
|
||||
{
|
||||
struct shared_ports* shp;
|
||||
struct shared_ports_if* shpif;
|
||||
char* ifs[] = {"1.2.3.4", "1.2.3.5", "::1:2", "::1:3"};
|
||||
int availports[] = {1, 2, 3, 4};
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addrlen;
|
||||
|
||||
shp = shared_ports_create(ifs, 4, 1, 1, availports, 4);
|
||||
unit_assert(shp);
|
||||
|
||||
if(!ipstrtoaddr("1.2.3.4", UNBOUND_DNS_PORT, &addr, &addrlen))
|
||||
log_err("could not parse");
|
||||
shpif = shared_ports_find_if(shp, &addr, addrlen, 0);
|
||||
unit_assert(shpif);
|
||||
|
||||
if(!ipstrtoaddr("1.2.3.5", UNBOUND_DNS_PORT, &addr, &addrlen))
|
||||
log_err("could not parse");
|
||||
shpif = shared_ports_find_if(shp, &addr, addrlen, 0);
|
||||
unit_assert(shpif);
|
||||
|
||||
if(!ipstrtoaddr("::1:2", UNBOUND_DNS_PORT, &addr, &addrlen))
|
||||
log_err("could not parse");
|
||||
shpif = shared_ports_find_if(shp, &addr, addrlen, 0);
|
||||
unit_assert(shpif);
|
||||
|
||||
if(!ipstrtoaddr("::1:3", UNBOUND_DNS_PORT, &addr, &addrlen))
|
||||
log_err("could not parse");
|
||||
shpif = shared_ports_find_if(shp, &addr, addrlen, 0);
|
||||
unit_assert(shpif);
|
||||
|
||||
shared_ports_delete(shp);
|
||||
}
|
||||
|
||||
/** See if a port is on the shared_ports ports list */
|
||||
static int
|
||||
pif_list_contains(struct shared_ports_if* shpif, int item)
|
||||
{
|
||||
int i;
|
||||
unit_assert(shpif->inuse >= 0 && shpif->inuse <= shpif->avail_total);
|
||||
for(i=0; i< shpif->avail_total - shpif->inuse; i++) {
|
||||
if(shpif->avail_ports[i] == item)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** See if a number of ports are on the shared_ports list */
|
||||
static int
|
||||
pif_list_contains_items(struct shared_ports_if* shpif, int item1,
|
||||
int item2, int item3, int item4)
|
||||
{
|
||||
if(item1 != -1 && !pif_list_contains(shpif, item1))
|
||||
return 0;
|
||||
if(item2 != -1 && !pif_list_contains(shpif, item2))
|
||||
return 0;
|
||||
if(item3 != -1 && !pif_list_contains(shpif, item3))
|
||||
return 0;
|
||||
if(item4 != -1 && !pif_list_contains(shpif, item4))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void shared_port_test_port(void)
|
||||
{
|
||||
struct shared_ports* shp;
|
||||
struct shared_ports_if* shpif;
|
||||
char* ifs[] = {"1.2.3.4", "1.2.3.5"};
|
||||
int availports[] = {1, 2, 3, 4};
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addrlen;
|
||||
int p1, p2, p3, reused;
|
||||
struct ub_randstate* rnd;
|
||||
|
||||
rnd = ub_initstate(NULL);
|
||||
unit_assert(rnd);
|
||||
|
||||
shp = shared_ports_create(ifs, 2, 1, 1, availports, 4);
|
||||
unit_assert(shp);
|
||||
|
||||
if(!ipstrtoaddr("1.2.3.4", UNBOUND_DNS_PORT, &addr, &addrlen))
|
||||
log_err("could not parse");
|
||||
shpif = shared_ports_find_if(shp, &addr, addrlen, 0);
|
||||
unit_assert(shpif);
|
||||
|
||||
unit_assert(shpif->avail_total == 4);
|
||||
unit_assert(shpif->inuse == 0);
|
||||
unit_assert(pif_list_contains_items(shpif, 1, 2, 3, 4));
|
||||
|
||||
if(!shared_ports_fetch_random(shp, shpif, rnd,
|
||||
0, 0, &p1, &reused)) {
|
||||
unit_assert(0); /* should succeed */
|
||||
}
|
||||
unit_assert(reused == 0);
|
||||
unit_assert(p1 != 0);
|
||||
unit_assert(!pif_list_contains(shpif, p1));
|
||||
if(p1 != 1) unit_assert(pif_list_contains(shpif, 1));
|
||||
if(p1 != 2) unit_assert(pif_list_contains(shpif, 2));
|
||||
if(p1 != 3) unit_assert(pif_list_contains(shpif, 3));
|
||||
if(p1 != 4) unit_assert(pif_list_contains(shpif, 4));
|
||||
unit_assert(shpif->avail_total == 4);
|
||||
unit_assert(shpif->inuse == 1);
|
||||
|
||||
shared_ports_return_port(shp, shpif, p1);
|
||||
unit_assert(shpif->avail_total == 4);
|
||||
unit_assert(shpif->inuse == 0);
|
||||
unit_assert(pif_list_contains_items(shpif, 1, 2, 3, 4));
|
||||
|
||||
/* pick up two items */
|
||||
if(!shared_ports_fetch_random(shp, shpif, rnd,
|
||||
0, 0, &p1, &reused)) {
|
||||
unit_assert(0); /* should succeed */
|
||||
}
|
||||
unit_assert(reused == 0);
|
||||
unit_assert(p1 != 0);
|
||||
if(!shared_ports_fetch_random(shp, shpif, rnd,
|
||||
0, 0, &p2, &reused)) {
|
||||
unit_assert(0); /* should succeed */
|
||||
}
|
||||
unit_assert(reused == 0);
|
||||
unit_assert(p2 != 0);
|
||||
unit_assert(!pif_list_contains(shpif, p1));
|
||||
unit_assert(!pif_list_contains(shpif, p2));
|
||||
if(p1 != 1 && p2 != 1) unit_assert(pif_list_contains(shpif, 1));
|
||||
if(p1 != 2 && p2 != 2) unit_assert(pif_list_contains(shpif, 2));
|
||||
if(p1 != 3 && p2 != 3) unit_assert(pif_list_contains(shpif, 3));
|
||||
if(p1 != 4 && p2 != 4) unit_assert(pif_list_contains(shpif, 4));
|
||||
unit_assert(shpif->avail_total == 4);
|
||||
unit_assert(shpif->inuse == 2);
|
||||
|
||||
shared_ports_return_port(shp, shpif, p1);
|
||||
unit_assert(pif_list_contains(shpif, p1));
|
||||
unit_assert(shpif->avail_total == 4);
|
||||
unit_assert(shpif->inuse == 1);
|
||||
|
||||
shared_ports_return_port(shp, shpif, p2);
|
||||
unit_assert(pif_list_contains(shpif, p2));
|
||||
unit_assert(shpif->avail_total == 4);
|
||||
unit_assert(shpif->inuse == 0);
|
||||
unit_assert(pif_list_contains_items(shpif, 1, 2, 3, 4));
|
||||
|
||||
/* pick up three items */
|
||||
if(!shared_ports_fetch_random(shp, shpif, rnd,
|
||||
0, 0, &p1, &reused)) {
|
||||
unit_assert(0); /* should succeed */
|
||||
}
|
||||
unit_assert(reused == 0);
|
||||
unit_assert(p1 != 0);
|
||||
if(!shared_ports_fetch_random(shp, shpif, rnd,
|
||||
0, 0, &p2, &reused)) {
|
||||
unit_assert(0); /* should succeed */
|
||||
}
|
||||
unit_assert(reused == 0);
|
||||
unit_assert(p2 != 0);
|
||||
if(!shared_ports_fetch_random(shp, shpif, rnd,
|
||||
0, 0, &p3, &reused)) {
|
||||
unit_assert(0); /* should succeed */
|
||||
}
|
||||
unit_assert(reused == 0);
|
||||
unit_assert(p3 != 0);
|
||||
unit_assert(!pif_list_contains(shpif, p1));
|
||||
unit_assert(!pif_list_contains(shpif, p2));
|
||||
unit_assert(!pif_list_contains(shpif, p3));
|
||||
if(p1 != 1 && p2 != 1 && p3 != 1)
|
||||
unit_assert(pif_list_contains(shpif, 1));
|
||||
if(p1 != 2 && p2 != 2 && p3 != 2)
|
||||
unit_assert(pif_list_contains(shpif, 2));
|
||||
if(p1 != 3 && p2 != 3 && p3 != 3)
|
||||
unit_assert(pif_list_contains(shpif, 3));
|
||||
if(p1 != 4 && p2 != 4 && p3 != 4)
|
||||
unit_assert(pif_list_contains(shpif, 4));
|
||||
unit_assert(shpif->avail_total == 4);
|
||||
unit_assert(shpif->inuse == 3);
|
||||
|
||||
shared_ports_return_port(shp, shpif, p1);
|
||||
unit_assert(pif_list_contains(shpif, p1));
|
||||
unit_assert(shpif->avail_total == 4);
|
||||
unit_assert(shpif->inuse == 2);
|
||||
|
||||
shared_ports_return_port(shp, shpif, p2);
|
||||
unit_assert(pif_list_contains(shpif, p2));
|
||||
unit_assert(shpif->avail_total == 4);
|
||||
unit_assert(shpif->inuse == 1);
|
||||
|
||||
shared_ports_return_port(shp, shpif, p3);
|
||||
unit_assert(pif_list_contains(shpif, p3));
|
||||
unit_assert(shpif->avail_total == 4);
|
||||
unit_assert(shpif->inuse == 0);
|
||||
unit_assert(pif_list_contains_items(shpif, 1, 2, 3, 4));
|
||||
|
||||
/* pick up all four items */
|
||||
if(!shared_ports_fetch_random(shp, shpif, rnd,
|
||||
0, 0, &p1, &reused)) {
|
||||
unit_assert(0); /* should succeed */
|
||||
}
|
||||
unit_assert(reused == 0);
|
||||
unit_assert(p1 != 0);
|
||||
|
||||
if(!shared_ports_fetch_random(shp, shpif, rnd,
|
||||
0, 0, &p1, &reused)) {
|
||||
unit_assert(0); /* should succeed */
|
||||
}
|
||||
unit_assert(reused == 0);
|
||||
unit_assert(p1 != 0);
|
||||
|
||||
if(!shared_ports_fetch_random(shp, shpif, rnd,
|
||||
0, 0, &p1, &reused)) {
|
||||
unit_assert(0); /* should succeed */
|
||||
}
|
||||
unit_assert(reused == 0);
|
||||
unit_assert(p1 != 0);
|
||||
|
||||
if(!shared_ports_fetch_random(shp, shpif, rnd,
|
||||
0, 0, &p1, &reused)) {
|
||||
unit_assert(0); /* should succeed */
|
||||
}
|
||||
unit_assert(reused == 0);
|
||||
unit_assert(p1 != 0);
|
||||
unit_assert(!pif_list_contains(shpif, 1));
|
||||
unit_assert(!pif_list_contains(shpif, 2));
|
||||
unit_assert(!pif_list_contains(shpif, 3));
|
||||
unit_assert(!pif_list_contains(shpif, 4));
|
||||
unit_assert(shpif->avail_total == 4);
|
||||
unit_assert(shpif->inuse == 4);
|
||||
|
||||
/* more fetches fail, it is fully inuse. */
|
||||
unit_assert(!shared_ports_fetch_random(shp, shpif, rnd, 0, 0, &p2,
|
||||
&reused));
|
||||
unit_assert(!shared_ports_fetch_random(shp, shpif, rnd, 0, 0, &p3,
|
||||
&reused));
|
||||
unit_assert(shpif->avail_total == 4);
|
||||
unit_assert(shpif->inuse == 4);
|
||||
|
||||
/* reuse is then always the case */
|
||||
if(!shared_ports_fetch_random(shp, shpif, rnd,
|
||||
0 /* can reuse */, 4 /* reusenum */, &p1, &reused)) {
|
||||
unit_assert(0); /* should succeed */
|
||||
}
|
||||
unit_assert(reused == 1);
|
||||
unit_assert(p1 >= 0 && p1 < 4 /* reusenum */);
|
||||
|
||||
if(!shared_ports_fetch_random(shp, shpif, rnd,
|
||||
0 /* can reuse */, 4 /* reusenum */, &p1, &reused)) {
|
||||
unit_assert(0); /* should succeed */
|
||||
}
|
||||
unit_assert(reused == 1);
|
||||
unit_assert(p1 >= 0 && p1 < 4 /* reusenum */);
|
||||
|
||||
/* return all the ports */
|
||||
shared_ports_return_port(shp, shpif, 1);
|
||||
unit_assert(pif_list_contains(shpif, 1));
|
||||
unit_assert(shpif->avail_total == 4);
|
||||
unit_assert(shpif->inuse == 3);
|
||||
shared_ports_return_port(shp, shpif, 2);
|
||||
unit_assert(pif_list_contains(shpif, 2));
|
||||
unit_assert(shpif->avail_total == 4);
|
||||
unit_assert(shpif->inuse == 2);
|
||||
shared_ports_return_port(shp, shpif, 3);
|
||||
unit_assert(pif_list_contains(shpif, 3));
|
||||
unit_assert(shpif->avail_total == 4);
|
||||
unit_assert(shpif->inuse == 1);
|
||||
shared_ports_return_port(shp, shpif, 4);
|
||||
unit_assert(pif_list_contains(shpif, 4));
|
||||
unit_assert(shpif->avail_total == 4);
|
||||
unit_assert(shpif->inuse == 0);
|
||||
unit_assert(pif_list_contains_items(shpif, 1, 2, 3, 4));
|
||||
|
||||
shared_ports_delete(shp);
|
||||
ub_randfree(rnd);
|
||||
}
|
||||
|
||||
void tcpreuse_test(void)
|
||||
{
|
||||
unit_show_feature("tcp_reuse");
|
||||
@@ -759,7 +486,4 @@ void tcpreuse_test(void)
|
||||
tcp_reuse_tree_list_test();
|
||||
waiting_tcp_list_test();
|
||||
reuse_write_wait_test();
|
||||
unit_show_feature("shared_ports");
|
||||
shared_port_test_ifs();
|
||||
shared_port_test_port();
|
||||
}
|
||||
|
||||
Vendored
-297
@@ -1,297 +0,0 @@
|
||||
; config options
|
||||
; The island of trust is at test.
|
||||
server:
|
||||
trust-anchor: "test. DS 1444 8 2 8a87d067fd09a5965244fe2e317dd26d182c468e0a7f26ecc4c7b479bf89db9b"
|
||||
val-override-date: "20201020135527"
|
||||
target-fetch-policy: "0 0 0 0 0"
|
||||
qname-minimisation: "no"
|
||||
fake-sha1: yes
|
||||
trust-anchor-signaling: no
|
||||
minimal-responses: no
|
||||
iter-scrub-promiscuous: no
|
||||
aggressive-nsec: yes
|
||||
local-zone: test. nodefault
|
||||
log-servfail: yes
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
|
||||
CONFIG_END
|
||||
|
||||
SCENARIO_BEGIN Test DNAME with an unsigned CNAME that mismatches the DNAME.
|
||||
; The CNAME occurs later in a list of redirections.
|
||||
|
||||
; 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
|
||||
test. IN NS
|
||||
SECTION AUTHORITY
|
||||
test. IN NS ns.test.
|
||||
SECTION ADDITIONAL
|
||||
ns.test. IN A 1.2.3.5
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; ns.test
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 1.2.3.5
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
test. IN NS
|
||||
SECTION ANSWER
|
||||
test. IN NS ns.test
|
||||
test. 3600 IN RRSIG NS 8 1 3600 20201116135527 20201019135527 1444 test. RGCxIO32TbbLTk6xZmTr+fjYPH50hntBxeOQ2DIj2pDsmjALcHYtVkOfpfk2EhOhHZd+9PLuoJPbJh6a9NqLSFeBvr0XZoCZoQ2g0tCHUNHcH5EVjA2TuYBQem6DVYnPLJ3914aRx0uA1j42b8dC2xsam/XkOo7U+dLbUW2Os1s=
|
||||
SECTION ADDITIONAL
|
||||
ns.test. IN A 1.2.3.5
|
||||
ns.test. 3600 IN RRSIG A 8 2 3600 20201116135527 20201019135527 1444 test. GskCc4/k6GjH9V9Jz2V5L2XLiizbOeWkB0feSbf+aN859S3vxVvtuqkvIgwY4LafUO1QAn/pUcv9zA7rcFO++rlg+8t6gvZTo9p3v0bfeIv2uJDsfSBD5jDh0WXlxjekfnrKrQp7zE+GiA93tWwKUWKPvxXDgP+n886e6WcbHJw=
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
ns.test. IN A
|
||||
SECTION ANSWER
|
||||
ns.test. IN A 1.2.3.5
|
||||
ns.test. 3600 IN RRSIG A 8 2 3600 20201116135527 20201019135527 1444 test. GskCc4/k6GjH9V9Jz2V5L2XLiizbOeWkB0feSbf+aN859S3vxVvtuqkvIgwY4LafUO1QAn/pUcv9zA7rcFO++rlg+8t6gvZTo9p3v0bfeIv2uJDsfSBD5jDh0WXlxjekfnrKrQp7zE+GiA93tWwKUWKPvxXDgP+n886e6WcbHJw=
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
ns.test. IN AAAA
|
||||
SECTION AUTHORITY
|
||||
test. 3600 IN SOA ns.test. host.test. 20201 3600 1800 604800 3600
|
||||
test. 3600 IN RRSIG SOA 8 1 3600 20201116135527 20201019135527 1444 test. IZJIDmEgf0W7A5G7hvvZ2hUqJ9Trbv1/i7ySapDmPbYV9lVCmHHobySxO01yDhI2/Pvpsvxqrm1Tiv3BxH8uzZ4keKgiQjBsSy4htAsFct9I4E7ly2glPj/Fm3oun3PsjJDv5QYhx0KS7w4IQKU7Nc9pfJc92uoUI5bdoC1pRGw=
|
||||
ns.test. 3600 IN NSEC nz.test. A RRSIG
|
||||
ns.test. 3600 IN RRSIG NSEC 8 2 3600 20201116135527 20201019135527 1444 test. PElArVB3KPg8KHAP7lzcNbhFuXNxTsHNTn1dZVncB5qmWRdIaeKpaXDjpH0JSXMaelGFS+/QhuQ6Hmw9+4VyZFRqMzGhw4agUR/2bxABHcDIG4ZpUwyeSP61ATTfHUkQVxaH2wjCWI/tfmesdP2xVE4GXyUvCIBxU914MkZbULU=
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
test. IN DNSKEY
|
||||
SECTION ANSWER
|
||||
test. 3600 IN DNSKEY 257 3 8 AwEAAbd9WqjzE2Pynz21OG5doSf9hFzMr5dhzz2waZ3vTa+0o5r7AjTAqmA1yH/B3+aAMihUm5ucZSfVqo7+kOaRE8yFj9aivOmA1n1+JLevJq/oyvQyjxQN2Qb89LyaNUT5oKZIiL+uyyhNW3KDR3SSbQ/GBwQNDHVcZi+JDR3RC0r7 ;{id = 1444 (ksk), size = 1024b}
|
||||
test. 3600 IN RRSIG DNSKEY 8 1 3600 20201116135527 20201019135527 1444 test. UmRMS4iG9NBBHZYOtpwFFcJgbEb5SfHSgHd9XRe/8pTWM31WSDayn5ViPOBMqI1T5TXg2amc13dDI574xIM2oKMus3b5cBW72jJLW13jprBtslO6P8BMWb4HNnvLrJtQjwf3ErRirtTxinLmywQtmyr1cdthyG3Gp4N7i90fHSc=
|
||||
SECTION ADDITIONAL
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qname qtype
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
example.test. IN DS
|
||||
SECTION ANSWER
|
||||
example.test. 3600 IN DS 55567 8 2 a2d578906330a10a57d40462257b6ce038bad3f7bf4a45c46c46086e20a94b39
|
||||
example.test. 3600 IN RRSIG DS 8 2 3600 20201116135527 20201019135527 1444 test. P7+FTYW2qHuJ4I1YbuvseEz5X1lOYAraGEHB3C5y0OOCQFmhmSiFRdquNi2NlpcS6FXLdsE0EU+Bo1+0atTG4EkMWXbpF21lrtbB51BdsnlX4Mzc/o375fvjiOMwmF6wPCUaOUN62jrVrhsE/hedaVyDphDToqL17ETohwgUO2I=
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode subdomain
|
||||
ADJUST copy_id copy_query
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.test. IN NS
|
||||
SECTION AUTHORITY
|
||||
example.test. IN NS ns.example.test.
|
||||
example.test. 3600 IN DS 55567 8 2 a2d578906330a10a57d40462257b6ce038bad3f7bf4a45c46c46086e20a94b39
|
||||
example.test. 3600 IN RRSIG DS 8 2 3600 20201116135527 20201019135527 1444 test. P7+FTYW2qHuJ4I1YbuvseEz5X1lOYAraGEHB3C5y0OOCQFmhmSiFRdquNi2NlpcS6FXLdsE0EU+Bo1+0atTG4EkMWXbpF21lrtbB51BdsnlX4Mzc/o375fvjiOMwmF6wPCUaOUN62jrVrhsE/hedaVyDphDToqL17ETohwgUO2I=
|
||||
SECTION ADDITIONAL
|
||||
ns.example.test. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode subdomain
|
||||
ADJUST copy_id copy_query
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
fox.test. IN NS
|
||||
SECTION AUTHORITY
|
||||
fox.test. IN NS ns.fox.test.
|
||||
fox.test. 3600 IN DS 29332 8 2 5b06f16c7b8cc07ba7b8e1ab0a40a40ecf89e1e94da2f0b1d2159b64dba80d96
|
||||
fox.test. 3600 IN RRSIG DS 8 2 3600 20201116135527 20201019135527 1444 test. B9bKqUJgJcGlKSWyGkdGGS6unKUwNJteTq08caL40QEZcAy836vwypGzOIQJNUw+mYIEecvtrF9H4mG+EjzDKv+n+36DCNvJMn6b8+FC9COw4mqITAjYPZjDwtOXAKVbuBuZJsbP2ztacJ98tXcORozaaKDGH/3fmsUlaKcuPmo=
|
||||
SECTION ADDITIONAL
|
||||
ns.fox.test. IN A 1.2.3.6
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; ns.example.test.
|
||||
RANGE_BEGIN 0 15
|
||||
ADDRESS 1.2.3.4
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.test. IN NS
|
||||
SECTION ANSWER
|
||||
example.test. IN NS ns.example.test.
|
||||
example.test. 3600 IN RRSIG NS 8 2 3600 20201116135527 20201019135527 55567 example.test. l1JT0wMlK0YI7/CWHzexf/k0iafUhCgN+BdgjBXIRXmSQNf4HDTiAkbcWL2/15qtnp12nQy9JeiTdSQ3vtPoHAJX4C5uTWaze4ms+Wrrf+n92sLCjacP9x50uuicH3URT6cKb1QCAPwlvlWxIlZjAMYFScSns7+C441NMJT8aE4=
|
||||
SECTION ADDITIONAL
|
||||
ns.example.test. IN A 1.2.3.4
|
||||
ns.example.test. 3600 IN RRSIG A 8 3 3600 20201116135527 20201019135527 55567 example.test. 2PWaVaccZFQgfPKXNsdEGYUVaashCAj1ZhBo9XRt5eQKUFvZcauBjMnXIuxZFyWeootn1fZGw6GuPI5W48Y0FDx38H6adprkFgQikso2Y64jDdDMWznSo38Z/XqP+U0+kq4vmwonvmEMpm7hKnNEXvhqGKyGzyBwb+CZVJ2L8Eo=
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
ns.example.test. IN A
|
||||
SECTION ANSWER
|
||||
ns.example.test. IN A 1.2.3.4
|
||||
ns.example.test. 3600 IN RRSIG A 8 3 3600 20201116135527 20201019135527 55567 example.test. 2PWaVaccZFQgfPKXNsdEGYUVaashCAj1ZhBo9XRt5eQKUFvZcauBjMnXIuxZFyWeootn1fZGw6GuPI5W48Y0FDx38H6adprkFgQikso2Y64jDdDMWznSo38Z/XqP+U0+kq4vmwonvmEMpm7hKnNEXvhqGKyGzyBwb+CZVJ2L8Eo=
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
ns.example.test. IN AAAA
|
||||
SECTION AUTHORITY
|
||||
example.test. 3600 IN SOA ns.example.test. host.example.test. 20301 3600 1800 604800 3600
|
||||
example.test. 3600 IN RRSIG SOA 8 2 3600 20201116135527 20201019135527 55567 example.test. 2UUkScBAN37fJpSrelhE8DotKvmOzj3q9wicaanCIaCv95DE4nQnePih5B+ek3FIRjB/Uv2+z4Ro5Uxy94XAnlK0rCkDLSa0U9U7KP0ytc88sevO0x1SCPAMoZoJO6JqHkv42pdh54WSz+Zb/D8npY0j/tksHe/uX+VQnMymgb8=
|
||||
ns.example.test. 3600 IN NSEC nz.example.test. A RRSIG
|
||||
ns.example.test. 3600 IN RRSIG NSEC 8 3 3600 20201116135527 20201019135527 55567 example.test. v/5aO/n8Ow21y7LE7JKZsFkUJU5MjIfadVRm2Tdb8f3RLwYDdBTs3aWeeEQdCRSUF61TmfJM1jIxlWQPuHbqzGnjSk7adw9gFpP7wFwoqG3/xdCFHoxo/3/1F/4Ankey3sDgKgOFsgnu40TlL36mGPYszeK+/2o3SAx2GM+3BdU=
|
||||
ENTRY_END
|
||||
|
||||
; response to DNSKEY priming query
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.test. IN DNSKEY
|
||||
SECTION ANSWER
|
||||
example.test. 3600 IN DNSKEY 257 3 8 AwEAAdug/L739i0mgN2nuK/bhxu3wFn5Ud9nK2+XUmZQlPUEZUC5YZvm1rfMmEWTGBn87fFxEu/kjFZHJ55JLzqsbbpVHLbmKCTT2gYR2FV2WDKROGKuYbVkJIXdKAjJ0ONuK507NinYvlWXIoxHn22KAWOd9wKgSTNHBlmGkX+ts3hh ;{id = 55567 (ksk), size = 1024b}
|
||||
example.test. 3600 IN RRSIG DNSKEY 8 2 3600 20201116135527 20201019135527 55567 example.test. IbWMC6quOuZFNPAVxQLqCJ9nLhindBo826rnLcg5yMgs9dGUSPOCXAfHTmbgJAUNs9HTFfrJWNvasnETs0UOpmEuifGwWdH1OlME7Gny4RL2QmITUFeMW81Jz1tiVQxFXl6yxT0jxOxvz+bqMHlrz+8IeWQXcO+GZTPu8ueq30g=
|
||||
ENTRY_END
|
||||
|
||||
; response to query of interest
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
a.d.example.test. IN A
|
||||
SECTION ANSWER
|
||||
d.example.test. 3600 IN DNAME tgt.example.test.
|
||||
d.example.test. 3600 IN RRSIG DNAME 8 3 3600 20201116135527 20201019135527 55567 example.test. EGpXUnJuzkETAO2OWyZDrTeInnyxF7CXPXGDfFt2x3CBUeckUUZcgQQ3yMh+BATKph2nOhBfk8klvZ35C9sQO7Z32REAnqGjpHiR86xRPYxG62Nk9kXv1Odeh/adz2QhB93N8U7W57FM0P/VQDkP0GQXTSRGTuj+7ihfYVd4HWI=
|
||||
; with CNAME signature
|
||||
a.d.example.test. 3600 IN CNAME a.tgt.example.test.
|
||||
a.d.example.test. 3600 IN RRSIG CNAME 8 4 3600 20201116135527 20201019135527 55567 example.test. efnytLE7P95kLr/tA9H0Z77VTOUQk24ci2bDgdVe8EuodTXtgg5PVHVLljD3QQ1Cpyme50odH/fhn2j1ORQpJTMk24Un/VRhVNquf+kj1nawJ59J0hjag4i0FIwZEG3/P7ogTB3Yd2y0Osb42Aawp48KvtVkUeBukk/GSutaTVQ=
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
a.tgt.example.test. IN A
|
||||
SECTION ANSWER
|
||||
a.tgt.example.test. 3600 IN CNAME b.d.example.test.
|
||||
a.tgt.example.test. 3600 IN RRSIG CNAME 8 4 3600 20201116135527 20201019135527 55567 example.test. XHYWSHIm9J8j8T1qMh1tHZS71UguXYUVescKPFtoGHRuyRhHNob+NAqdn3I4/+8HSSGrJDqhTX/Vo3rcc3/g5HOHScwzZByB/diyJWpG9IA7pm7c7FnHnHpGBVdHq9wXlkgCPiaJShpE1zg1nNy3p99ca9/wh4y9XWSfcl0L8aw=
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
b.d.example.test. IN A
|
||||
SECTION ANSWER
|
||||
; This answer is injected
|
||||
; Without an RRSIG.
|
||||
b.d.example.test. 3600 IN CNAME www.fox.test.
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; ns.fox.test.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 1.2.3.6
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
ns.fox.test. IN AAAA
|
||||
SECTION AUTHORITY
|
||||
fox.test. 3600 IN SOA ns.fox.test. host.fox.test. 20601 3600 1800 604800 3600
|
||||
fox.test. 3600 IN RRSIG SOA 8 2 3600 20201116135527 20201019135527 29332 fox.test. QScf+vyis5/Km03ALuLQDfUDagA9/UG/oIQw6LnvmsVoqJSNXa3LIObWT9zfWgdJT0qFayWR4K9hnd9rT1enuVmXX8k47s7AjPZmE0qQxms5xz7jOhj/XLFplXOE9/GkgvAZKPb42qkU3Xf6Bevxzfy4/qW7+yXflWsjLV1vAhz38M4ESeWp0MDme8+DND0f7aoprGcC5saAPfa35nQhHS40q4IwiUDBBk1uwhCBF9ZGsjRfXmECOxIc1/0hBOv+Hhwog4K5b8rdl7LA2VggNiVOUuLFpXEH0XxknEspbQwWppP4TWC1H2QYGaKCc2Hu7NBhM/Ly7caGK+2u1MZvsg==
|
||||
ns.fox.test. 3600 IN NSEC nz.fox.test. A RRSIG
|
||||
ns.fox.test. 3600 IN RRSIG NSEC 8 3 3600 20201116135527 20201019135527 29332 fox.test. RQjV2PHbBVdGhvSRl0lutzoIZ9KezBAAwvI5sQoIGLdlMeQxj/BOy16auYRLTxvB9xehkrTTeL5xYUwcbi4uFS/kr3IUmlVXeldHOk4T42huV9MGfWzguUsB2jjsrcdt11qEnLo27SVVcvQReswwfpOPRPHg52fS6vt50AIWwttLOLvZEGiGIjRGb4lBaCnoO6YYzOnwcRCV0UScTjlPxS1SBEKsdbPvzfUUyp+wOVnIVAXrd0xEChB7QrTIrcBt4mutXVUNBDcfkZCXgEwu3scWQQS8rNO6O3PvpLgs6PIHX191WjovkJ9/PL+8MO/7UUatSWhZUwuQBUq6VofCYw==
|
||||
ENTRY_END
|
||||
|
||||
; response to DNSKEY priming query
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
fox.test. IN DNSKEY
|
||||
SECTION ANSWER
|
||||
fox.test. IN DNSKEY 257 3 8 AwEAAb4WMOTBLTFvmBra5m6SK4VfViOzmvyUAU0qv861ZQXeEFvwlndqNU9rwRsMxrSWAYs5nHErKDn49usC/HyxxW1477iGFHhfgL4mjNreJm9zft2QFB1VLbRbEPYdDMLCn4co0qnG7/KG8W2i8Pym1L7f+aREwbLo+/716AS2PbaKMhfWLKLiq5wnBcUClQMNzCiwhqxDJp1oePqfkVdeUgXOtgi0dYRIKyQFhJ5VWJ22npoi/Gif0XLCADAlAwRLKc8o/yJkCxskzgpHpw5Cki1lclg0aq4ssOuPRQ+ne6IHYCz9D2mwzulblhLFamKdq7aHzNt4NlyxhpANVFiKLD8= ;{id = 29332 (ksk), size = 2048b}
|
||||
fox.test. 3600 IN RRSIG DNSKEY 8 2 3600 20201116135527 20201019135527 29332 fox.test. bTslCQKai9U9EWkBPnMiO+Rb34qMAZSzfgEb68x+ZKi2DDyzK7v8TCX8unTlqeQCnTqqgJ7cCUcqrbSV3ip9WGNe5fUy5j9hxH04ddLcDhygnjLi4C7iQX67ratRGu1JM3Evk/gVF76a5J2RSQk340jOFHC0nnjWOMHlDDxBeK4Zr6lYvAMJB2uy08xbi1FuGUSPcrbRFnVb74QMAPLS9Uj5JM8lMsOMtrhHX9zBN8Euo4M1X0sinBdJse3P/fIZ+ZvSnOEpVvur3bcUl+bqFJ18nM/Mj/e3XW3WBWE1dI6p6HdAXLrJyjJINzm+YnNzj11tzu/e4BQCjOutY9XkKA==
|
||||
ENTRY_END
|
||||
|
||||
; response to query of interest
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
www.fox.test. IN A
|
||||
SECTION ANSWER
|
||||
www.fox.test. 3600 IN A 10.20.30.43
|
||||
www.fox.test. 3600 IN RRSIG A 8 3 3600 20201116135527 20201019135527 29332 fox.test. ehPLws7Jnlx5Trm7Z8Hxr0WkLdkxyif+E1aGzFMib4eP0nvLV89WOQ2Fpm1xT/VaNJBXjXhWPB0Oo/gAKVs1znqmyjutFdXi2+9rXnK73jD2+rWBGW/sgBl/9cr458j7441nEK18Mq4SserQcLBqM38IivTlK1J5uXUpEPKMCSA82waf0Z+LUk8czFqeYy+KlJSsiu33mrVWrjyNLIXCbZ2dxfdaVSKyAoQafiokp1NGnw3onQkXXOPqJ7GRsN8Ml4c2nOrEYIG6otoZXXjtkoNCOHzBBkPVEP82JjzQchq0fDWQ2UHOXXZYBG/B6m5PuOXmgKJVDKZ/iVNQofPp8w==
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
STEP 1 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
a.d.example.test. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 10 TRAFFIC
|
||||
; The unsigned CNAME should make SERVFAIL.
|
||||
|
||||
STEP 20 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
a.d.example.test. IN A
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
Vendored
-1
@@ -12,7 +12,6 @@ server:
|
||||
ede: no # It is not needed for dns-error-reporting; only for clients to receive EDEs
|
||||
dns-error-reporting: yes
|
||||
do-ip6: no
|
||||
do-not-query-localhost: no
|
||||
|
||||
stub-zone:
|
||||
name: domain
|
||||
|
||||
+8
-9
@@ -9,21 +9,20 @@ PRE="../.."
|
||||
|
||||
# do the test
|
||||
|
||||
# Query plain request over DNSCrypt.
|
||||
# This used to close the channel; now it returns SERVFAIL.
|
||||
# Old: We use TCP to avoid hanging on waiting for UDP.
|
||||
# We expect `outfile` to contain no DNS payload
|
||||
echo "> dig www.example.com. DNSCrypt port"
|
||||
dig @127.0.0.1 -p $DNSCRYPT_PORT www.example.com. A | tee outfile
|
||||
# Query plain request over DNSCrypt channel get closed
|
||||
# We use TCP to avoid hanging on waiting for UDP.
|
||||
# We expect `outfile` to contain no DNS payload
|
||||
echo "> dig TCP www.example.com. DNSCrypt port"
|
||||
dig +tcp @127.0.0.1 -p $DNSCRYPT_PORT www.example.com. A | tee outfile
|
||||
echo "> cat logfiles"
|
||||
cat fwd.log
|
||||
cat unbound.log
|
||||
echo "> check answer"
|
||||
if grep "SERVFAIL" outfile; then
|
||||
echo "OK"
|
||||
else
|
||||
if grep "QUESTION SECTION" outfile; then
|
||||
echo "NOK"
|
||||
exit 1
|
||||
else
|
||||
echo "OK"
|
||||
fi
|
||||
|
||||
|
||||
|
||||
@@ -9,21 +9,20 @@ PRE="../.."
|
||||
|
||||
# do the test
|
||||
|
||||
# Query plain request over DNSCrypt.
|
||||
# This used to close the channel; now it returns SERVFAIL.
|
||||
# Old: We use TCP to avoid hanging on waiting for UDP.
|
||||
# We expect `outfile` to contain no DNS payload
|
||||
echo "> dig www.example.com. DNSCrypt port"
|
||||
dig @127.0.0.1 -p $DNSCRYPT_PORT www.example.com. A | tee outfile
|
||||
# Query plain request over DNSCrypt channel get closed
|
||||
# We use TCP to avoid hanging on waiting for UDP.
|
||||
# We expect `outfile` to contain no DNS payload
|
||||
echo "> dig TCP www.example.com. DNSCrypt port"
|
||||
dig +tcp @127.0.0.1 -p $DNSCRYPT_PORT www.example.com. A | tee outfile
|
||||
echo "> cat logfiles"
|
||||
cat fwd.log
|
||||
cat unbound.log
|
||||
echo "> check answer"
|
||||
if grep "SERVFAIL" outfile; then
|
||||
echo "OK"
|
||||
else
|
||||
if grep "QUESTION SECTION" outfile; then
|
||||
echo "NOK"
|
||||
exit 1
|
||||
else
|
||||
echo "OK"
|
||||
fi
|
||||
|
||||
|
||||
|
||||
Vendored
-374
@@ -1,374 +0,0 @@
|
||||
; config options
|
||||
; The island of trust is at test.
|
||||
server:
|
||||
trust-anchor: "test. DS 1444 8 2 8a87d067fd09a5965244fe2e317dd26d182c468e0a7f26ecc4c7b479bf89db9b"
|
||||
val-override-date: "20201020135527"
|
||||
target-fetch-policy: "0 0 0 0 0"
|
||||
qname-minimisation: "no"
|
||||
fake-sha1: yes
|
||||
trust-anchor-signaling: no
|
||||
minimal-responses: no
|
||||
iter-scrub-promiscuous: no
|
||||
aggressive-nsec: yes
|
||||
local-zone: test. nodefault
|
||||
log-servfail: yes
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
|
||||
CONFIG_END
|
||||
|
||||
SCENARIO_BEGIN Test DS response with wildcard CNAME
|
||||
|
||||
; 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
|
||||
test. IN NS
|
||||
SECTION AUTHORITY
|
||||
test. IN NS ns.test.
|
||||
SECTION ADDITIONAL
|
||||
ns.test. IN A 1.2.3.5
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; ns.test
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 1.2.3.5
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
test. IN NS
|
||||
SECTION ANSWER
|
||||
test. IN NS ns.test
|
||||
test. 3600 IN RRSIG NS 8 1 3600 20201116135527 20201019135527 1444 test. RGCxIO32TbbLTk6xZmTr+fjYPH50hntBxeOQ2DIj2pDsmjALcHYtVkOfpfk2EhOhHZd+9PLuoJPbJh6a9NqLSFeBvr0XZoCZoQ2g0tCHUNHcH5EVjA2TuYBQem6DVYnPLJ3914aRx0uA1j42b8dC2xsam/XkOo7U+dLbUW2Os1s=
|
||||
SECTION ADDITIONAL
|
||||
ns.test. IN A 1.2.3.5
|
||||
ns.test. 3600 IN RRSIG A 8 2 3600 20201116135527 20201019135527 1444 test. GskCc4/k6GjH9V9Jz2V5L2XLiizbOeWkB0feSbf+aN859S3vxVvtuqkvIgwY4LafUO1QAn/pUcv9zA7rcFO++rlg+8t6gvZTo9p3v0bfeIv2uJDsfSBD5jDh0WXlxjekfnrKrQp7zE+GiA93tWwKUWKPvxXDgP+n886e6WcbHJw=
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
ns.test. IN A
|
||||
SECTION ANSWER
|
||||
ns.test. IN A 1.2.3.5
|
||||
ns.test. 3600 IN RRSIG A 8 2 3600 20201116135527 20201019135527 1444 test. GskCc4/k6GjH9V9Jz2V5L2XLiizbOeWkB0feSbf+aN859S3vxVvtuqkvIgwY4LafUO1QAn/pUcv9zA7rcFO++rlg+8t6gvZTo9p3v0bfeIv2uJDsfSBD5jDh0WXlxjekfnrKrQp7zE+GiA93tWwKUWKPvxXDgP+n886e6WcbHJw=
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
ns.test. IN AAAA
|
||||
SECTION AUTHORITY
|
||||
test. 3600 IN SOA ns.test. host.test. 20201 3600 1800 604800 3600
|
||||
test. 3600 IN RRSIG SOA 8 1 3600 20201116135527 20201019135527 1444 test. IZJIDmEgf0W7A5G7hvvZ2hUqJ9Trbv1/i7ySapDmPbYV9lVCmHHobySxO01yDhI2/Pvpsvxqrm1Tiv3BxH8uzZ4keKgiQjBsSy4htAsFct9I4E7ly2glPj/Fm3oun3PsjJDv5QYhx0KS7w4IQKU7Nc9pfJc92uoUI5bdoC1pRGw=
|
||||
ns.test. 3600 IN NSEC nz.test. A RRSIG
|
||||
ns.test. 3600 IN RRSIG NSEC 8 2 3600 20201116135527 20201019135527 1444 test. PElArVB3KPg8KHAP7lzcNbhFuXNxTsHNTn1dZVncB5qmWRdIaeKpaXDjpH0JSXMaelGFS+/QhuQ6Hmw9+4VyZFRqMzGhw4agUR/2bxABHcDIG4ZpUwyeSP61ATTfHUkQVxaH2wjCWI/tfmesdP2xVE4GXyUvCIBxU914MkZbULU=
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
test. IN DNSKEY
|
||||
SECTION ANSWER
|
||||
test. 3600 IN DNSKEY 257 3 8 AwEAAbd9WqjzE2Pynz21OG5doSf9hFzMr5dhzz2waZ3vTa+0o5r7AjTAqmA1yH/B3+aAMihUm5ucZSfVqo7+kOaRE8yFj9aivOmA1n1+JLevJq/oyvQyjxQN2Qb89LyaNUT5oKZIiL+uyyhNW3KDR3SSbQ/GBwQNDHVcZi+JDR3RC0r7 ;{id = 1444 (ksk), size = 1024b}
|
||||
test. 3600 IN RRSIG DNSKEY 8 1 3600 20201116135527 20201019135527 1444 test. UmRMS4iG9NBBHZYOtpwFFcJgbEb5SfHSgHd9XRe/8pTWM31WSDayn5ViPOBMqI1T5TXg2amc13dDI574xIM2oKMus3b5cBW72jJLW13jprBtslO6P8BMWb4HNnvLrJtQjwf3ErRirtTxinLmywQtmyr1cdthyG3Gp4N7i90fHSc=
|
||||
SECTION ADDITIONAL
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qname qtype
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
example.test. IN DS
|
||||
SECTION ANSWER
|
||||
example.test. 3600 IN DS 55567 8 2 a2d578906330a10a57d40462257b6ce038bad3f7bf4a45c46c46086e20a94b39
|
||||
example.test. 3600 IN RRSIG DS 8 2 3600 20201116135527 20201019135527 1444 test. P7+FTYW2qHuJ4I1YbuvseEz5X1lOYAraGEHB3C5y0OOCQFmhmSiFRdquNi2NlpcS6FXLdsE0EU+Bo1+0atTG4EkMWXbpF21lrtbB51BdsnlX4Mzc/o375fvjiOMwmF6wPCUaOUN62jrVrhsE/hedaVyDphDToqL17ETohwgUO2I=
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode subdomain
|
||||
ADJUST copy_id copy_query
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.test. IN NS
|
||||
SECTION AUTHORITY
|
||||
example.test. IN NS ns.example.test.
|
||||
example.test. 3600 IN DS 55567 8 2 a2d578906330a10a57d40462257b6ce038bad3f7bf4a45c46c46086e20a94b39
|
||||
example.test. 3600 IN RRSIG DS 8 2 3600 20201116135527 20201019135527 1444 test. P7+FTYW2qHuJ4I1YbuvseEz5X1lOYAraGEHB3C5y0OOCQFmhmSiFRdquNi2NlpcS6FXLdsE0EU+Bo1+0atTG4EkMWXbpF21lrtbB51BdsnlX4Mzc/o375fvjiOMwmF6wPCUaOUN62jrVrhsE/hedaVyDphDToqL17ETohwgUO2I=
|
||||
SECTION ADDITIONAL
|
||||
ns.example.test. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; ns.example.test.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 1.2.3.4
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.test. IN NS
|
||||
SECTION ANSWER
|
||||
example.test. IN NS ns.example.test.
|
||||
example.test. 3600 IN RRSIG NS 8 2 3600 20201116135527 20201019135527 55567 example.test. l1JT0wMlK0YI7/CWHzexf/k0iafUhCgN+BdgjBXIRXmSQNf4HDTiAkbcWL2/15qtnp12nQy9JeiTdSQ3vtPoHAJX4C5uTWaze4ms+Wrrf+n92sLCjacP9x50uuicH3URT6cKb1QCAPwlvlWxIlZjAMYFScSns7+C441NMJT8aE4=
|
||||
SECTION ADDITIONAL
|
||||
ns.example.test. IN A 1.2.3.4
|
||||
ns.example.test. 3600 IN RRSIG A 8 3 3600 20201116135527 20201019135527 55567 example.test. 2PWaVaccZFQgfPKXNsdEGYUVaashCAj1ZhBo9XRt5eQKUFvZcauBjMnXIuxZFyWeootn1fZGw6GuPI5W48Y0FDx38H6adprkFgQikso2Y64jDdDMWznSo38Z/XqP+U0+kq4vmwonvmEMpm7hKnNEXvhqGKyGzyBwb+CZVJ2L8Eo=
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
ns.example.test. IN A
|
||||
SECTION ANSWER
|
||||
ns.example.test. IN A 1.2.3.4
|
||||
ns.example.test. 3600 IN RRSIG A 8 3 3600 20201116135527 20201019135527 55567 example.test. 2PWaVaccZFQgfPKXNsdEGYUVaashCAj1ZhBo9XRt5eQKUFvZcauBjMnXIuxZFyWeootn1fZGw6GuPI5W48Y0FDx38H6adprkFgQikso2Y64jDdDMWznSo38Z/XqP+U0+kq4vmwonvmEMpm7hKnNEXvhqGKyGzyBwb+CZVJ2L8Eo=
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
ns.example.test. IN AAAA
|
||||
SECTION ANSWER
|
||||
ns.example.test. 3600 IN AAAA 2001::1:2:3:4
|
||||
ns.example.test. 3600 IN RRSIG AAAA 8 3 3600 20201116135527 20201019135527 55567 example.test. IuFmNUqxRjWSw/Ua2A0XmeKbsVkw6Yzd/D4TGBZ5pyKtbYIFvmF/QfcqzONiwqG3KEW2tAeyEjZOYjrM37NqgIwwk56LJ16fFA7e2tShjSjPhgNzjHZW9zvFTjPyTTVpMVb3SGV59RQTm3jJwlQCq7qVHyKQ+HT3pa+XZQJEzdw=
|
||||
SECTION AUTHORITY
|
||||
;example.test. 3600 IN SOA ns.example.test. host.example.test. 20301 3600 1800 604800 3600
|
||||
;example.test. 3600 IN RRSIG SOA 8 2 3600 20201116135527 20201019135527 55567 example.test. 2UUkScBAN37fJpSrelhE8DotKvmOzj3q9wicaanCIaCv95DE4nQnePih5B+ek3FIRjB/Uv2+z4Ro5Uxy94XAnlK0rCkDLSa0U9U7KP0ytc88sevO0x1SCPAMoZoJO6JqHkv42pdh54WSz+Zb/D8npY0j/tksHe/uX+VQnMymgb8=
|
||||
;ns.example.test. 3600 IN NSEC nz.example.test. A RRSIG
|
||||
;ns.example.test. 3600 IN RRSIG NSEC 8 3 3600 20201116135527 20201019135527 55567 example.test. v/5aO/n8Ow21y7LE7JKZsFkUJU5MjIfadVRm2Tdb8f3RLwYDdBTs3aWeeEQdCRSUF61TmfJM1jIxlWQPuHbqzGnjSk7adw9gFpP7wFwoqG3/xdCFHoxo/3/1F/4Ankey3sDgKgOFsgnu40TlL36mGPYszeK+/2o3SAx2GM+3BdU=
|
||||
ENTRY_END
|
||||
|
||||
; response to DNSKEY priming query
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.test. IN DNSKEY
|
||||
SECTION ANSWER
|
||||
example.test. 3600 IN DNSKEY 257 3 8 AwEAAdug/L739i0mgN2nuK/bhxu3wFn5Ud9nK2+XUmZQlPUEZUC5YZvm1rfMmEWTGBn87fFxEu/kjFZHJ55JLzqsbbpVHLbmKCTT2gYR2FV2WDKROGKuYbVkJIXdKAjJ0ONuK507NinYvlWXIoxHn22KAWOd9wKgSTNHBlmGkX+ts3hh ;{id = 55567 (ksk), size = 1024b}
|
||||
example.test. 3600 IN RRSIG DNSKEY 8 2 3600 20201116135527 20201019135527 55567 example.test. IbWMC6quOuZFNPAVxQLqCJ9nLhindBo826rnLcg5yMgs9dGUSPOCXAfHTmbgJAUNs9HTFfrJWNvasnETs0UOpmEuifGwWdH1OlME7Gny4RL2QmITUFeMW81Jz1tiVQxFXl6yxT0jxOxvz+bqMHlrz+8IeWQXcO+GZTPu8ueq30g=
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
tgt.example.test. DS
|
||||
SECTION ANSWER
|
||||
SECTION AUTHORITY
|
||||
; denial of the DS record for tgt.example.test.
|
||||
example.test. 3600 IN SOA ns.example.test. host.example.test. 20301 3600 1800 604800 3600
|
||||
example.test. 3600 IN RRSIG SOA 8 2 3600 20201116135527 20201019135527 55567 example.test. 2UUkScBAN37fJpSrelhE8DotKvmOzj3q9wicaanCIaCv95DE4nQnePih5B+ek3FIRjB/Uv2+z4Ro5Uxy94XAnlK0rCkDLSa0U9U7KP0ytc88sevO0x1SCPAMoZoJO6JqHkv42pdh54WSz+Zb/D8npY0j/tksHe/uX+VQnMymgb8=
|
||||
tgt.example.test. 3600 IN NSEC tgz.example.test. A RRSIG
|
||||
tgt.example.test. 3600 IN RRSIG NSEC 8 3 3600 20201116135527 20201019135527 55567 example.test. R9v8k/M56dLOUbrTP/m2XnKsOjIj1kAfwCQvHW4KPdDn3XJIvCLs4mTjxvyQ70uP+zA8WxrPgbqPZv//Ms3Sher2j41VKIBRFkJpyJn6/D9/QmOOhWzoPYXuujHJAkB9IDit3YOgJutirFnB7reTTav42P5x7PzQDSt+crUnXkw=
|
||||
ENTRY_END
|
||||
|
||||
; when there is a re-query for the DS record, this answer is used.
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
sub.example.test. IN DS
|
||||
SECTION ANSWER
|
||||
; This reply is an injected reply.
|
||||
sub.example.test. 300 IN CNAME tgt.example.test.
|
||||
; signature for wildcard, *.example.test. 300 IN CNAME tgt.example.test.
|
||||
sub.example.test. 300 IN RRSIG CNAME 8 2 300 20201116135527 20201019135527 55567 example.test. fz+xLPcRAbGUcnF7hITQHRT6AeA/I/dSjyLWb3it+cHSMY7dN4Jpw7Dk0GJh0y71HXFwaWgk1If0O4IOVo4mfkm1RrRhBnxJT8R88AQlN69SXLZrlHIhoupBpZADz/J15hOcHG+/1svsEpAA5qkOrgZwf581X9ygwPGFkIHgS+o=
|
||||
ENTRY_END
|
||||
|
||||
; The referral to sub.example.test, for other queries than type DS.
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode subdomain
|
||||
ADJUST copy_id copy_query
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
sub.example.test. IN NS
|
||||
SECTION ANSWER
|
||||
SECTION AUTHORITY
|
||||
sub.example.test. 3600 NS ns.sub.example.test.
|
||||
; Smaller TTL 300 for the DS.
|
||||
sub.example.test. 300 IN DS 29332 8 2 69c8a09889e377fb1d1af78cc55984152adf25f4643b26d42654657a171e92aa
|
||||
sub.example.test. 300 IN RRSIG DS 8 3 300 20201116135527 20201019135527 55567 example.test. vyjkyx1UMCI5KftU7BQWxDkxNj25A60haEIR/Sy7JUkG2UnE0tNIVNE4mEmUGX6ICsddKGwba2xFQFYBMyfpnzsNxEMKv8VpOGObpiTlK4ICRaq6m+pVND1Benk6grzkb+6T2xogHEEMYqnMUF4bDGRe5tcftS9XdAl77pG6W7Q=
|
||||
SECTION ADDITIONAL
|
||||
ns.sub.example.test. IN A 1.2.3.7
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; ns.sub.example.test.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 1.2.3.7
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
ns.sub.example.test. IN AAAA
|
||||
SECTION ANSWER
|
||||
SECTION AUTHORITY
|
||||
sub.example.test. 3600 IN SOA ns.sub.example.test. host.sub.example.test. 20701 3600 1800 604800 3600
|
||||
sub.example.test. 3600 IN RRSIG SOA 8 3 3600 20201116135527 20201019135527 29332 sub.example.test. EEeC/XlG/XuItqRphAOREwHPzqSsJSs9TEhPnqOzXU4/+j0Eq05WN8ZE+GxHnmrxzaLiqAT6pLYLaQxCFcpkMVKUFYfMFyK6jOkTHZ1ODXNIdAA/ZGMCOQQUco3rcrY6F2U8ETHSxiFQkEl8iQntWM6wUoUF37Yd4hab+o1eD/HZXKLwgNXbXC1iY40ZzqwAlxLcCt0SexiTI9BNfyDy3iROeT3XuloC2x9o2zclAqz3m42n8UKAs8Gh7sAkoTua2fqtNfWZtQctlp1tZgdJFXbI4vuxMEldD+Rh5kUJ72aXvD2W7vd042G7z3n+d+I4vtnH2qKNbVA4YHMXzA/3ug==
|
||||
ns.sub.example.test. 3600 IN NSEC nz.sub.example.test. A RRSIG
|
||||
ns.sub.example.test. 3600 IN RRSIG NSEC 8 4 3600 20201116135527 20201019135527 29332 sub.example.test. CqaJIHttjfPIdBM1Ty8RDGRnrkaoC7Y7pzS/Kbzjn3lsEJg2XPWZGRln75imsoVOdi46YG95HZdgvnndTAAH3dE0eZHycvo2O7zR0f+Ty3v/HWpvOsRp/XE/8/7g45DHLuyTXxiO6cDSu0bW/qTC4xyix7vMFNEyOmGMGIZEnvkoRWJvUToj8VW6r+a8dU1KIGQXKSXg3lRcXc0Zfk2lk5P0XGrGzdLcITbZbVP3aFgusoi6uCTqhPmwZRVJjuh1E0qXTTE2A67vloVBvwVxfhNajHNkVhEYtxqZyiRLPs1tRyWit4J2Kkk5qoWuPwNRoTHsgzmPJoDGxheUxGEvbA==
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
sub.example.test. IN DNSKEY
|
||||
SECTION ANSWER
|
||||
sub.example.test. 300 IN DNSKEY 257 3 8 AwEAAb4WMOTBLTFvmBra5m6SK4VfViOzmvyUAU0qv861ZQXeEFvwlndqNU9rwRsMxrSWAYs5nHErKDn49usC/HyxxW1477iGFHhfgL4mjNreJm9zft2QFB1VLbRbEPYdDMLCn4co0qnG7/KG8W2i8Pym1L7f+aREwbLo+/716AS2PbaKMhfWLKLiq5wnBcUClQMNzCiwhqxDJp1oePqfkVdeUgXOtgi0dYRIKyQFhJ5VWJ22npoi/Gif0XLCADAlAwRLKc8o/yJkCxskzgpHpw5Cki1lclg0aq4ssOuPRQ+ne6IHYCz9D2mwzulblhLFamKdq7aHzNt4NlyxhpANVFiKLD8= ;{id = 29332 (ksk), size = 2048b}
|
||||
sub.example.test. 300 IN RRSIG DNSKEY 8 3 300 20201116135527 20201019135527 29332 sub.example.test. j8lyYKogmlBon1WsYJp2H4DSdXZIGkzKHplH2hs9b5D2I+4kZ7jiwHz5/OZca5aOOE1QbhcPNRyhenSmtwePjhvBLSDDYC4OhowVpWW5o5aRQMnsTYZgmgqX0zPtUWBoK8P+GZRd1VO/Jam0qWoHjHY9lQlDnblN6f2yDRHQI2CVrSal8x12zl1s/QHVNpodb4MwowvL4WeGxDVxBOiS3v+9SobnfPa9oecu9onrcPryr4KDQHi6i5BNvHVPqE9eBkHnRe3DcvfEbOke6vZY7CCNgfGttaJL64ubCVUv2xu3okTQS5gSX9pRbjaxKlw1ZWmJR0HSq/dn2HDuWjzxkQ==
|
||||
SECTION ADDITIONAL
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
a.sub.example.test. IN A
|
||||
SECTION ANSWER
|
||||
a.sub.example.test. 300 IN A 10.20.30.40
|
||||
a.sub.example.test. 300 IN RRSIG A 8 4 300 20201116135527 20201019135527 29332 sub.example.test. lElblJBqr+LbNDO8mlyh9PbBzfC6LU5K8nh/fOHu9dFur5xuqtItw+D0/oo2ve6WIUnqblXKhfbZcKMa40DONog/uThmwyp6cBow7oZdfZSt5YTn74QwJb1M/yaJgU+OWNkM7RfG+VcvpB04+KH+g2qwEpHC5Jm5+e66beoiGHZuKle0qAxNAgM1kkJ5EdTngKk80YOciBv705xSSvySmCDktcIceV8zMgD9YFW1Q2I2SXtPCsVaJTA1jaf3Cm8rZfY1GrBW18JyLPOqf6eIBqdyXg/w/mi/pxgakIM3r9iKaDsEz01ZiN0jaEloteT+NhpjEJA/sFzu1nhV0Y3fJw==
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
b.sub.example.test. IN A
|
||||
SECTION ANSWER
|
||||
b.sub.example.test. 300 IN A 10.20.30.41
|
||||
b.sub.example.test. 300 IN RRSIG A 8 4 300 20201116135527 20201019135527 29332 sub.example.test. KimigOgfAWic9JVbuqMc0cE2aUlfzBaG+LjZl5IqZr7RLeImG74cpBMbTyzWJ1h3IhCKnLde3KMYz+viVEwsirxlY70i3cDObl5t9XlBKombQzCJBMv5MNCGH1iYfsBL6JVhVX849J1fRTK7E6mW2v9eN0GUFplTsThodnRnh/R3KYsn7wdYFAQ3VAkGzdrxcsS9Lmua1hYhJtjMFBuJn/pmoWpOWQePN9u9P1jh3IkvKN7XuwSYvoGjhE1ZM0OtpsWbHdYmFbUePu4Ruqk0Yg+eW1tkWBsj1AHq1x75BDxOShypi+8zb9zGeatF+A65PSOH1WjmpWNdbAYz97gssw==
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
www.sub.example.test. IN A
|
||||
SECTION ANSWER
|
||||
www.sub.example.test. 300 IN A 10.20.30.42
|
||||
www.sub.example.test. 300 IN RRSIG A 8 4 300 20201116135527 20201019135527 29332 sub.example.test. YuV5CADfhJ6yjxLrIZ243RvJmDJv0NgZKVZ9k5TorSY/O8fvPDzIMJFDjVs2gk6dZV81I6MmMbbcK5I3DEeBIHMswOZEhJYgfX7TiKi4sNfJQmyJJSx1SS1YQ38Asxst4cWgg5L6aoehsIlHvAqEz+JlObNus30nO7S6zMd+rFoThdbCpADK3AhbSI8xhO1u7Q8qgBchX7JZNIt5eiKnSrLSi5UAtuNMkczWv74ckFtd5PERpBGqpJRj50z0+7qiAbdahT3YQ7y2PkiBpZTtxG8Cmza4CkGPd1qzD/DRUsWOzZyiWwX5niD51sgqMj6ApGs8wbVSsk/vBudYw1/CIA==
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; ns.example.test.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 2001::1:2:3:4
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
sub.example.test. IN DS
|
||||
SECTION ANSWER
|
||||
; This is the correct reply.
|
||||
sub.example.test. 300 IN DS 29332 8 2 69c8a09889e377fb1d1af78cc55984152adf25f4643b26d42654657a171e92aa
|
||||
sub.example.test. 300 IN RRSIG DS 8 3 300 20201116135527 20201019135527 55567 example.test. vyjkyx1UMCI5KftU7BQWxDkxNj25A60haEIR/Sy7JUkG2UnE0tNIVNE4mEmUGX6ICsddKGwba2xFQFYBMyfpnzsNxEMKv8VpOGObpiTlK4ICRaq6m+pVND1Benk6grzkb+6T2xogHEEMYqnMUF4bDGRe5tcftS9XdAl77pG6W7Q=
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
STEP 1 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
a.sub.example.test. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA AD DO NOERROR
|
||||
SECTION QUESTION
|
||||
a.sub.example.test. IN A
|
||||
SECTION ANSWER
|
||||
a.sub.example.test. 300 IN A 10.20.30.40
|
||||
a.sub.example.test. 300 IN RRSIG A 8 4 300 20201116135527 20201019135527 29332 sub.example.test. lElblJBqr+LbNDO8mlyh9PbBzfC6LU5K8nh/fOHu9dFur5xuqtItw+D0/oo2ve6WIUnqblXKhfbZcKMa40DONog/uThmwyp6cBow7oZdfZSt5YTn74QwJb1M/yaJgU+OWNkM7RfG+VcvpB04+KH+g2qwEpHC5Jm5+e66beoiGHZuKle0qAxNAgM1kkJ5EdTngKk80YOciBv705xSSvySmCDktcIceV8zMgD9YFW1Q2I2SXtPCsVaJTA1jaf3Cm8rZfY1GrBW18JyLPOqf6eIBqdyXg/w/mi/pxgakIM3r9iKaDsEz01ZiN0jaEloteT+NhpjEJA/sFzu1nhV0Y3fJw==
|
||||
ENTRY_END
|
||||
|
||||
STEP 20 TIME_PASSES ELAPSE 320
|
||||
; The DS record has expired, but the NS record for sub.example.test. is in
|
||||
; cache.
|
||||
|
||||
; The DS lookup fails with wildcard CNAME.
|
||||
; Then it should blacklist the parent (1.2.3.4) not the sub zone (1.2.3.7)
|
||||
; the AAAA for the parent can then be retrieved, and it is used.
|
||||
|
||||
STEP 30 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
www.sub.example.test. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 40 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA AD DO NOERROR
|
||||
SECTION QUESTION
|
||||
www.sub.example.test. IN A
|
||||
SECTION ANSWER
|
||||
www.sub.example.test. 300 IN A 10.20.30.42
|
||||
www.sub.example.test. 300 IN RRSIG A 8 4 300 20201116135527 20201019135527 29332 sub.example.test. YuV5CADfhJ6yjxLrIZ243RvJmDJv0NgZKVZ9k5TorSY/O8fvPDzIMJFDjVs2gk6dZV81I6MmMbbcK5I3DEeBIHMswOZEhJYgfX7TiKi4sNfJQmyJJSx1SS1YQ38Asxst4cWgg5L6aoehsIlHvAqEz+JlObNus30nO7S6zMd+rFoThdbCpADK3AhbSI8xhO1u7Q8qgBchX7JZNIt5eiKnSrLSi5UAtuNMkczWv74ckFtd5PERpBGqpJRj50z0+7qiAbdahT3YQ7y2PkiBpZTtxG8Cmza4CkGPd1qzD/DRUsWOzZyiWwX5niD51sgqMj6ApGs8wbVSsk/vBudYw1/CIA==
|
||||
ENTRY_END
|
||||
|
||||
STEP 50 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
b.sub.example.test. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 60 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA AD DO NOERROR
|
||||
SECTION QUESTION
|
||||
b.sub.example.test. IN A
|
||||
SECTION ANSWER
|
||||
b.sub.example.test. 300 IN A 10.20.30.41
|
||||
b.sub.example.test. 300 IN RRSIG A 8 4 300 20201116135527 20201019135527 29332 sub.example.test. KimigOgfAWic9JVbuqMc0cE2aUlfzBaG+LjZl5IqZr7RLeImG74cpBMbTyzWJ1h3IhCKnLde3KMYz+viVEwsirxlY70i3cDObl5t9XlBKombQzCJBMv5MNCGH1iYfsBL6JVhVX849J1fRTK7E6mW2v9eN0GUFplTsThodnRnh/R3KYsn7wdYFAQ3VAkGzdrxcsS9Lmua1hYhJtjMFBuJn/pmoWpOWQePN9u9P1jh3IkvKN7XuwSYvoGjhE1ZM0OtpsWbHdYmFbUePu4Ruqk0Yg+eW1tkWBsj1AHq1x75BDxOShypi+8zb9zGeatF+A65PSOH1WjmpWNdbAYz97gssw==
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
+1
-1
@@ -8,7 +8,7 @@
|
||||
if nc -h 2>&1 | grep "q secs"; then
|
||||
ncopt="-q 3 -i 2"
|
||||
else
|
||||
ncopt="-i 2 --no-shutdown"
|
||||
ncopt="-i 2"
|
||||
fi
|
||||
|
||||
PRE="../.."
|
||||
|
||||
Vendored
-93
@@ -1,93 +0,0 @@
|
||||
; This is a comment
|
||||
server:
|
||||
|
||||
forward-zone: name: "." forward-addr: 216.0.0.1
|
||||
CONFIG_END
|
||||
|
||||
SCENARIO_BEGIN Test scrub of RRSIG amount
|
||||
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 216.0.0.1
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. IN A 10.20.30.40
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MQ== ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . Mg== ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . Mw== ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . NA== ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . NQ== ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . Ng== ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . Nw== ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . OA== ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . OQ== ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MTA= ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MTE= ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MTI= ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MTM= ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MTQ= ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MTU= ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MTY= ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MTc= ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MTg= ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MTk= ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MjA= ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MjE= ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MjI= ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MjM= ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MjQ= ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MjU= ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MjY= ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . Mjc= ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . Mjg= ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . Mjk= ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MzA= ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MzE= ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MzI= ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MzM= ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MzQ= ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MzU= ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MzY= ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . Mzc= ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . Mzg= ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . Mzk= ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . NDA= ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . NDE= ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . NDI= ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . NDM= ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . NDQ= ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . NDU= ;{id = 12345}
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
STEP 1 QUERY
|
||||
ENTRY_BEGIN
|
||||
MATCH TCP
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 4 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qname qtype all
|
||||
REPLY QR RD DO RA
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. IN A 10.20.30.40
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . MQ== ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . Mg== ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . Mw== ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . NA== ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . NQ== ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . Ng== ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . Nw== ;{id = 12345}
|
||||
www.example.com. 300 IN RRSIG A 8 3 300 20330518033320 20010909014640 12345 . OA== ;{id = 12345}
|
||||
ENTRY_END
|
||||
SCENARIO_END
|
||||
Vendored
+4
-4
@@ -319,7 +319,7 @@ example.com. 360 IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
; this is picked up from the parent (because this simulation has the
|
||||
; parent respond with servfail, not actually timeout)
|
||||
ns.example.com. 360 IN A 1.2.3.4
|
||||
ns.example.com. 3600 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; another query to see if there is another lookup towards the authority
|
||||
@@ -342,7 +342,7 @@ www.example.com. 360 IN A 10.20.30.40
|
||||
SECTION AUTHORITY
|
||||
example.com. 360 IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. 360 IN A 1.2.3.4
|
||||
ns.example.com. 3600 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; some time later another query, and now it is fine to bother the authority
|
||||
@@ -367,7 +367,7 @@ www.example.com. 330 IN A 10.20.30.40
|
||||
SECTION AUTHORITY
|
||||
example.com. 330 IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. 330 IN A 1.2.3.4
|
||||
ns.example.com. 3570 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
; now the just-looked-up entry
|
||||
STEP 190 QUERY
|
||||
@@ -388,7 +388,7 @@ www.example.com. 3600 IN A 10.20.30.40
|
||||
SECTION AUTHORITY
|
||||
example.com. 3600 IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. 3600 IN A 1.2.3.4
|
||||
ns.example.com. 3570 IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
|
||||
|
||||
Vendored
+6
-29
@@ -204,25 +204,6 @@ RANGE_END
|
||||
; ns.pollute4.mesa
|
||||
RANGE_BEGIN 0 400
|
||||
ADDRESS 1.2.4.4
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
ns.pollute4.mesa. IN A
|
||||
SECTION ANSWER
|
||||
ns.pollute4.mesa. IN A 1.2.4.4
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
ns.pollute4.mesa. IN AAAA
|
||||
SECTION AUTHORITY
|
||||
pollute4.mesa. IN SOA ns.pollute4.mesa. host.pollute4.mesa 20701 3600 3600 604800 3600
|
||||
ENTRY_END
|
||||
|
||||
; This is the spoofed answer that is returned.
|
||||
ENTRY_BEGIN
|
||||
@@ -442,18 +423,14 @@ ENTRY_END
|
||||
STEP 130 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA SERVFAIL
|
||||
REPLY QR RD RA YXDOMAIN
|
||||
SECTION QUESTION
|
||||
test4.atkr.pollute4.mesa. IN A
|
||||
; Since the reply does not contain a DNAME, it is rejected as YXDOMAIN answer.
|
||||
;REPLY QR RD RA YXDOMAIN
|
||||
;SECTION QUESTION
|
||||
;test4.atkr.pollute4.mesa. IN A
|
||||
;SECTION ANSWER
|
||||
;test4.atkr.pollute4.mesa. 86400 IN A 1.2.3.4
|
||||
;SECTION AUTHORITY
|
||||
;; removed record
|
||||
;;pollute4.mesa. 0 IN NS ns.attacker.mesa.
|
||||
SECTION ANSWER
|
||||
test4.atkr.pollute4.mesa. 86400 IN A 1.2.3.4
|
||||
SECTION AUTHORITY
|
||||
; removed record
|
||||
;pollute4.mesa. 0 IN NS ns.attacker.mesa.
|
||||
ENTRY_END
|
||||
|
||||
; Check the cache contents, for query 4.
|
||||
|
||||
Vendored
-200
@@ -1,200 +0,0 @@
|
||||
; config options
|
||||
server:
|
||||
target-fetch-policy: "0 0 0 0 0"
|
||||
qname-minimisation: "no"
|
||||
minimal-responses: no
|
||||
iter-scrub-promiscuous: no
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
|
||||
CONFIG_END
|
||||
|
||||
SCENARIO_BEGIN Test lookup of malformed SVCB
|
||||
|
||||
; K.ROOT-SERVERS.NET.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 193.0.14.129
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
. IN NS
|
||||
SECTION ANSWER
|
||||
. IN NS K.ROOT-SERVERS.NET.
|
||||
SECTION ADDITIONAL
|
||||
K.ROOT-SERVERS.NET. IN A 193.0.14.129
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode subdomain
|
||||
ADJUST copy_id copy_query
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
com. IN NS
|
||||
SECTION AUTHORITY
|
||||
com. IN NS a.gtld-servers.net.
|
||||
SECTION ADDITIONAL
|
||||
a.gtld-servers.net. IN A 192.5.6.30
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; a.gtld-servers.net.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 192.5.6.30
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
com. IN NS
|
||||
SECTION ANSWER
|
||||
com. IN NS a.gtld-servers.net.
|
||||
SECTION ADDITIONAL
|
||||
a.gtld-servers.net. IN A 192.5.6.30
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode subdomain
|
||||
ADJUST copy_id copy_query
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN NS
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; ns.example.com.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 1.2.3.4
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN NS
|
||||
SECTION ANSWER
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN HTTPS
|
||||
SECTION ANSWER
|
||||
www.example.com. IN HTTPS \# 17 00 01 00 00 01 00 03 02 68 32 00 01 00 03 02 68 33
|
||||
; Duplicate `alpn` key (17 bytes)
|
||||
; Decoded:
|
||||
; SvcPriority = 1 (service mode)
|
||||
; TargetName = . (root label, 0x00)
|
||||
; SvcParam[0]: key=1 (alpn), value_len=3, value=\x02h2 ← "h2"
|
||||
; SvcParam[1]: key=1 (alpn), value_len=3, value=\x02h3 ← DUPLICATE KEY
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
testb.example.com. IN HTTPS
|
||||
SECTION ANSWER
|
||||
; The parser for testbound does allow this.
|
||||
;testb.example.com. IN HTTPS \# 9 00 01 00 00 01 00 04 02 68
|
||||
; Truncated `alpn` value (9 bytes)
|
||||
; Decoded:
|
||||
; SvcPriority = 1
|
||||
; TargetName = .
|
||||
; SvcParam[0]: key=1 (alpn), value_len=4 (claims 4 bytes), value=\x02h (only 2 bytes present)
|
||||
; placeholder for hex: testb.example.com. IN HTTPS \# 9 00 01 00 00 01 00 02 01 68
|
||||
HEX_ANSWER_BEGIN
|
||||
000084000001000100000000057465737462076578616D706C6503636F6D0000410001057465737462076578616D706C6503636F6D000041000100000E10
|
||||
0009
|
||||
0001
|
||||
00
|
||||
000100040268
|
||||
HEX_ANSWER_END
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
testc.example.com. IN HTTPS
|
||||
SECTION ANSWER
|
||||
testc.example.com. IN HTTPS \# 21 00 01 00 00 01 00 06 02 68 32 02 68 33 00 04 00 04 01 02 03 04
|
||||
; valid HTTPS RDATA
|
||||
; SvcPriority=1, TargetName=., alpn=h2+h3, ipv4hint=1.2.3.4
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
STEP 1 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
www.example.com. IN HTTPS
|
||||
ENTRY_END
|
||||
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN HTTPS
|
||||
SECTION ANSWER
|
||||
www.example.com. 0 IN HTTPS 1 . alpn="h2" alpn="h3"
|
||||
ENTRY_END
|
||||
|
||||
STEP 20 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
testb.example.com. IN HTTPS
|
||||
ENTRY_END
|
||||
|
||||
; recursion happens here.
|
||||
STEP 30 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH rcode
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
testb.example.com. IN HTTPS
|
||||
SECTION ANSWER
|
||||
; testb.example.com. 0 IN HTTPS \# 9 000100000100040268
|
||||
HEX_ANSWER_BEGIN
|
||||
000084000001000100000000057465737462076578616D706C6503636F6D0000410001057465737462076578616D706C6503636F6D000041000100000E10
|
||||
0009
|
||||
0001
|
||||
00
|
||||
000100040268
|
||||
HEX_ANSWER_END
|
||||
ENTRY_END
|
||||
|
||||
STEP 40 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
testc.example.com. IN HTTPS
|
||||
ENTRY_END
|
||||
|
||||
; recursion happens here.
|
||||
STEP 50 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
testc.example.com. IN HTTPS
|
||||
SECTION ANSWER
|
||||
testc.example.com. 0 IN HTTPS 1 . alpn="h2,h3" ipv4hint=1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
Vendored
-73
@@ -1,73 +0,0 @@
|
||||
; config options
|
||||
server:
|
||||
target-fetch-policy: "0 0 0 0 0"
|
||||
qname-minimisation: "no"
|
||||
minimal-responses: no
|
||||
iter-scrub-promiscuous: no
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
stub-addr: 1.2.3.4
|
||||
CONFIG_END
|
||||
|
||||
SCENARIO_BEGIN Test long query name.
|
||||
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 1.2.3.4
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qname qtype
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
. IN NS
|
||||
SECTION ANSWER
|
||||
. IN NS ns.root.
|
||||
SECTION ADDITIONAL
|
||||
ns.root. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
; matched anything
|
||||
MATCH opcode
|
||||
ADJUST copy_id copy_query
|
||||
REPLY QR AA NXDOMAIN
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION AUTHORITY
|
||||
. SOA ns.root. host.invalid. 1 2 3 4 5
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
STEP 10 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
HEX_ANSWER_BEGIN
|
||||
00 00 01 00 ; RD
|
||||
00 01 00 00 00 00 00 00 ; QDCOUNT=1, ANCOUNT=0, NSCOUNT=0, ARCOUNT=0.
|
||||
; www.example.com.
|
||||
;03 77 77 77
|
||||
;07 65 78 61 6d 70 6c 65
|
||||
;03 63 6f 6d
|
||||
;00
|
||||
;
|
||||
; a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.a.ab.example.com.
|
||||
01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62 01 61 02 61 62
|
||||
07 65 78 61 6d 70 6c 65
|
||||
03 63 6f 6d
|
||||
00
|
||||
00 01 00 01
|
||||
HEX_ANSWER_END
|
||||
ENTRY_END
|
||||
|
||||
; recursion happens here.
|
||||
STEP 20 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD FORMERR
|
||||
SECTION QUESTION
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
@@ -0,0 +1,33 @@
|
||||
server:
|
||||
verbosity: 5
|
||||
num-threads: 1
|
||||
interface: 127.0.0.1@@PORT@
|
||||
use-syslog: no
|
||||
directory: ""
|
||||
pidfile: "unbound.pid"
|
||||
chroot: ""
|
||||
username: ""
|
||||
do-not-query-localhost: no
|
||||
|
||||
metrics-enable: yes
|
||||
metrics-path: "/metrics"
|
||||
metrics-interface: 127.0.0.1
|
||||
metrics-port: @METRICSPORT@
|
||||
|
||||
statistics-cumulative: yes
|
||||
extended-statistics: yes
|
||||
statistics-inhibit-zero: yes
|
||||
statistics-interval: 0
|
||||
|
||||
local-data: "www.example.com. IN A 192.0.2.10"
|
||||
local-data: 'a.example.com. IN TXT "abcdef text"'
|
||||
|
||||
remote-control:
|
||||
control-enable: yes
|
||||
control-interface: 127.0.0.1
|
||||
# control-interface: ::1
|
||||
control-port: @CONTROL_PORT@
|
||||
server-key-file: "unbound_server.key"
|
||||
server-cert-file: "unbound_server.pem"
|
||||
control-key-file: "unbound_control.key"
|
||||
control-cert-file: "unbound_control.pem"
|
||||
@@ -0,0 +1,16 @@
|
||||
BaseName: prometheus_metrics
|
||||
Version: 1.0
|
||||
Description: Test prometheus metrics
|
||||
CreationDate: Fri 30 Jan 13:22:03 CET 2026
|
||||
Maintainer: dr. Wouter Wijngaards
|
||||
Category:
|
||||
Component:
|
||||
CmdDepends:
|
||||
Depends:
|
||||
Help:
|
||||
Pre: prometheus_metrics.pre
|
||||
Post: prometheus_metrics.post
|
||||
Test: prometheus_metrics.test
|
||||
AuxFiles: prometheus_metrics.conf, prometheus_metrics.zone
|
||||
Passed:
|
||||
Failure:
|
||||
@@ -0,0 +1,11 @@
|
||||
# #-- prometheus_metrics.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 $UNBOUND_PID
|
||||
cat unbound.log
|
||||
exit 0
|
||||
@@ -0,0 +1,33 @@
|
||||
# #-- prometheus_metrics.pre--#
|
||||
# source the master var file when it's there
|
||||
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
|
||||
# use .tpkg.var.test for in test variable passing
|
||||
[ -f .tpkg.var.test ] && source .tpkg.var.test
|
||||
|
||||
. ../common.sh
|
||||
PRE="../.."
|
||||
if grep "define USE_METRICS" $PRE/config.h; then echo test enabled; else skip_test "test skipped"; fi
|
||||
# Is curl available
|
||||
if test -f "$(which curl 2>&1)"; then
|
||||
echo "curl available, do test"
|
||||
else
|
||||
skip_test "curl not available, skip test"
|
||||
fi
|
||||
|
||||
get_random_port 3
|
||||
UNBOUND_PORT=$RND_PORT
|
||||
CONTROL_PORT=$(($RND_PORT + 1))
|
||||
METRICS_PORT=$(($RND_PORT + 2))
|
||||
echo "UNBOUND_PORT=$UNBOUND_PORT" >> .tpkg.var.test
|
||||
echo "CONTROL_PORT=$CONTROL_PORT" >> .tpkg.var.test
|
||||
echo "METRICS_PORT=$METRICS_PORT" >> .tpkg.var.test
|
||||
|
||||
# make config file
|
||||
sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@METRICSPORT\@/'$METRICS_PORT'/' -e 's/@CONTROL_PORT\@/'$CONTROL_PORT'/' < prometheus_metrics.conf > ub.conf
|
||||
# start unbound in the background
|
||||
$PRE/unbound -d -c ub.conf >unbound.log 2>&1 &
|
||||
UNBOUND_PID=$!
|
||||
echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test
|
||||
|
||||
cat .tpkg.var.test
|
||||
wait_unbound_up unbound.log
|
||||
@@ -0,0 +1,113 @@
|
||||
# #-- prometheus_metrics.test --#
|
||||
# source the master var file when it's there
|
||||
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
|
||||
# use .tpkg.var.test for in test variable passing
|
||||
[ -f .tpkg.var.test ] && source .tpkg.var.test
|
||||
|
||||
. ../common.sh
|
||||
PRE="../.."
|
||||
|
||||
NUM_A_QUERIES=5
|
||||
NUM_TXT_QUERIES=3
|
||||
|
||||
# query server a few times
|
||||
for i in $(seq 1 $NUM_A_QUERIES); do
|
||||
dig @127.0.0.1 -p "$UNBOUND_PORT" www.example.com. A IN | tee out2
|
||||
if grep "192.0.2.10" out2; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "data not present"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
for i in $(seq 1 $NUM_TXT_QUERIES); do
|
||||
dig @127.0.0.1 -p "$UNBOUND_PORT" a.example.com. TXT IN | tee out2
|
||||
if grep "abcdef text" out2; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "data not present"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
# stats no reset for comparison
|
||||
echo ""
|
||||
echo ">> unbound-control stats"
|
||||
$PRE/unbound-control -c ub.conf stats_noreset | tee stats
|
||||
|
||||
# check metrics
|
||||
if ! curl -Ssi "http://127.0.0.1:$METRICS_PORT/metrics" -o metrics.out; then
|
||||
echo "FAIL curl failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo ">> metrics output"
|
||||
cat metrics.out
|
||||
|
||||
echo ""
|
||||
echo ">> checks"
|
||||
|
||||
# more tests
|
||||
if grep -Fx "unbound_hits_queries{type=\"total.num.queries\"} $((NUM_TXT_QUERIES+NUM_A_QUERIES))" metrics.out; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "FAIL total num"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if grep -Fx "unbound_by_type_queries{type=\"TXT\"} $NUM_TXT_QUERIES" metrics.out; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "FAIL txt num"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if grep -Fx "unbound_by_type_queries{type=\"A\"} $NUM_A_QUERIES" metrics.out; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "FAIL A num"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# and check statistics are the same as metrics
|
||||
if grep "total.num.queries=$((NUM_TXT_QUERIES+NUM_A_QUERIES))" stats; then echo "OK"; else echo "FAIL"; exit 1; fi
|
||||
if grep "num.query.type.TXT=$NUM_TXT_QUERIES" stats; then echo "OK"; else echo "FAIL"; exit 1; fi
|
||||
if grep "num.query.type.A=$NUM_A_QUERIES" stats; then echo "OK"; else echo "FAIL"; exit 1; fi
|
||||
|
||||
# check that metrics shows no reset to stats after using nsd-control stats
|
||||
# check metrics again
|
||||
if ! curl -Ssi "http://127.0.0.1:$METRICS_PORT/metrics" -o metrics.out2; then
|
||||
echo "FAIL to curl again"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo ">> metrics output"
|
||||
cat metrics.out2
|
||||
echo ""
|
||||
echo ">> checks"
|
||||
|
||||
if grep -Fx "unbound_hits_queries{type=\"total.num.queries\"} $((NUM_TXT_QUERIES+NUM_A_QUERIES))" metrics.out2; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "FAIL total num again"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if grep -Fx "unbound_by_flags_queries{flag=\"RD\"} $((NUM_TXT_QUERIES+NUM_A_QUERIES))" metrics.out2; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "FAIL RD num again"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if grep -Fx "unbound_hits_queries{type=\"total.num.cachehits\"} $((NUM_TXT_QUERIES+NUM_A_QUERIES))" metrics.out2; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "FAIL cachehits num again"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
Vendored
+4
-5
@@ -28,11 +28,10 @@ STEP 4 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR FORMERR
|
||||
; The SOA RR should not be echoed back.
|
||||
; The question section is absent, because it gives a formerr because of the
|
||||
; authority section contents.
|
||||
;SECTION QUESTION
|
||||
;nlnetlabs.nl. IN IXFR
|
||||
SECTION QUESTION
|
||||
nlnetlabs.nl. IN IXFR
|
||||
SECTION AUTHORITY
|
||||
nlnetlabs.nl. IN SOA mr. op. 12 0 0 0 0
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
|
||||
-239
@@ -1,239 +0,0 @@
|
||||
; Check if an SERVFAIL answer is not stored in the global cache, and
|
||||
; does not block ECS queries to reach the ECS cache.
|
||||
|
||||
server:
|
||||
trust-anchor-signaling: no
|
||||
target-fetch-policy: "0 0 0 0 0"
|
||||
;send-client-subnet: 1.2.3.4
|
||||
client-subnet-zone: "example.com"
|
||||
max-client-subnet-ipv4: 21
|
||||
module-config: "subnetcache iterator"
|
||||
verbosity: 3
|
||||
access-control: 127.0.0.1 allow_snoop
|
||||
qname-minimisation: no
|
||||
minimal-responses: yes
|
||||
prefetch: yes
|
||||
outbound-msg-retry: 3
|
||||
ede: yes
|
||||
log-servfail: yes
|
||||
|
||||
stub-zone:
|
||||
name: "example.com."
|
||||
stub-addr: 1.2.3.4
|
||||
CONFIG_END
|
||||
|
||||
SCENARIO_BEGIN Test that SERVFAIL after timeout does not block clients to reach the ECS cache
|
||||
; And that withing the servfail time a couple of seconds have cached servfail
|
||||
; for the subnet queries for that name.
|
||||
|
||||
; ns.example.com.
|
||||
RANGE_BEGIN 1 20
|
||||
ADDRESS 1.2.3.4
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN NS
|
||||
SECTION ANSWER
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
; response to query of interest
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname ednsdata
|
||||
ADJUST copy_id copy_ednsdata_assume_clientsubnet
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 10 IN A 10.20.30.40
|
||||
SECTION AUTHORITY
|
||||
SECTION ADDITIONAL
|
||||
HEX_EDNSDATA_BEGIN
|
||||
; client is 127.0.0.1
|
||||
00 08 ; OPC
|
||||
00 05 ; option length
|
||||
00 01 ; Family
|
||||
08 00 ; source mask, scopemask
|
||||
7f ; address
|
||||
HEX_EDNSDATA_END
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; ns.example.com.
|
||||
RANGE_BEGIN 100 120
|
||||
ADDRESS 1.2.3.4
|
||||
|
||||
; response to query of interest
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname ednsdata
|
||||
ADJUST copy_id copy_ednsdata_assume_clientsubnet
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 10 IN A 10.20.30.41
|
||||
SECTION AUTHORITY
|
||||
SECTION ADDITIONAL
|
||||
HEX_EDNSDATA_BEGIN
|
||||
; client is 1.0.0.0
|
||||
00 08 ; OPC
|
||||
00 05 ; option length
|
||||
00 01 ; Family
|
||||
08 00 ; source mask, scopemask
|
||||
01 ; address
|
||||
HEX_EDNSDATA_END
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; Put an item in subnet cache
|
||||
STEP 10 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ADDITIONAL
|
||||
HEX_EDNSDATA_BEGIN
|
||||
00 08 00 05 ; OPC, optlen
|
||||
00 01 08 08 ; ip4, source 8, scope 8
|
||||
7f ; 127.0.0.0/8
|
||||
HEX_EDNSDATA_END
|
||||
ENTRY_END
|
||||
|
||||
STEP 20 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA DO NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 10 IN A 10.20.30.40
|
||||
SECTION AUTHORITY
|
||||
SECTION ADDITIONAL
|
||||
HEX_EDNSDATA_BEGIN
|
||||
00 08 00 05 ; OPC, optlen
|
||||
00 01 08 08 ; ip4, source 8, scope 8
|
||||
7f ; 127.0.0.0/8
|
||||
HEX_EDNSDATA_END
|
||||
ENTRY_END
|
||||
|
||||
; There is a valid subnet query in cache.
|
||||
; this query timeouts.
|
||||
STEP 30 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ADDITIONAL
|
||||
HEX_EDNSDATA_BEGIN
|
||||
00 08 00 05 ; OPC, optlen
|
||||
00 01 08 00 ; ip4, source 8, scope 0
|
||||
01 ; 1.0.0.0/8
|
||||
HEX_EDNSDATA_END
|
||||
ENTRY_END
|
||||
|
||||
; This query faces timeouts during the resolution.
|
||||
; The timeouted query is the 1.0.0.0/8 subnet lookup of www.example.com. A.
|
||||
STEP 31 TIMEOUT
|
||||
STEP 32 TIMEOUT
|
||||
STEP 33 TIMEOUT
|
||||
|
||||
STEP 40 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD DO RA SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
; Check if subnet cache item can be accessed.
|
||||
STEP 50 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ADDITIONAL
|
||||
HEX_EDNSDATA_BEGIN
|
||||
00 08 00 05 ; OPC, optlen
|
||||
00 01 08 00 ; ip4, source 8, scope 0
|
||||
7f ; 127.0.0.0/8
|
||||
HEX_EDNSDATA_END
|
||||
ENTRY_END
|
||||
|
||||
STEP 60 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA DO NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 10 IN A 10.20.30.40
|
||||
SECTION AUTHORITY
|
||||
SECTION ADDITIONAL
|
||||
HEX_EDNSDATA_BEGIN
|
||||
00 08 00 05 ; OPC, optlen
|
||||
00 01 08 08 ; ip4, source 8, scope 8
|
||||
7f ; 127.0.0.0/8
|
||||
HEX_EDNSDATA_END
|
||||
ENTRY_END
|
||||
|
||||
; the existing subnet cache item can be accessed.
|
||||
; but another resolution, is now not cached at all?
|
||||
STEP 70 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ADDITIONAL
|
||||
HEX_EDNSDATA_BEGIN
|
||||
00 08 00 05 ; OPC, optlen
|
||||
00 01 08 00 ; ip4, source 8, scope 0
|
||||
01 ; 1.0.0.0/8
|
||||
HEX_EDNSDATA_END
|
||||
ENTRY_END
|
||||
|
||||
STEP 80 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD DO RA SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
; after a couple of seconds, the servfail entry should have cleared.
|
||||
STEP 90 TIME_PASSES ELAPSE 10
|
||||
|
||||
STEP 100 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ADDITIONAL
|
||||
HEX_EDNSDATA_BEGIN
|
||||
00 08 00 05 ; OPC, optlen
|
||||
00 01 08 00 ; ip4, source 8, scope 0
|
||||
01 ; 1.0.0.0/8
|
||||
HEX_EDNSDATA_END
|
||||
ENTRY_END
|
||||
|
||||
STEP 110 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA DO NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. 10 IN A 10.20.30.41
|
||||
SECTION AUTHORITY
|
||||
SECTION ADDITIONAL
|
||||
HEX_EDNSDATA_BEGIN
|
||||
00 08 00 05 ; OPC, optlen
|
||||
00 01 08 08 ; ip4, source 8, scope 8
|
||||
01 ; 1.0.0.0/8
|
||||
HEX_EDNSDATA_END
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
Vendored
+1
-20
@@ -15,29 +15,10 @@ ENTRY_END
|
||||
; entry to test
|
||||
ENTRY_BEGIN
|
||||
SECTION QUESTION
|
||||
bogus.example.com. IN SOA
|
||||
secure.example.com. IN SOA
|
||||
SECTION ANSWER
|
||||
; The REVOKE key is not allowed to sign other data
|
||||
example.com. 43200 IN SOA home.kuroiwa.eng.br. hostmaster.cesar.sec3.br. 2008040903 86400 86400 8640000 600
|
||||
example.com. 43200 IN RRSIG SOA 5 2 43200 20081010000000 20080410122550 31027 example.com. af7nqRak6cEeQLytqLHMIUKPsOECA4Cu/Zpm7vdnKSh2q2+/8ZwIxwHLyCEGdiu/mTYffZEHTZytJyzxnB0oxA== ;{id = 31027}
|
||||
ENTRY_END
|
||||
|
||||
; entry to test
|
||||
ENTRY_BEGIN
|
||||
SECTION QUESTION
|
||||
bogus.a.example.com. IN DNSKEY
|
||||
SECTION ANSWER
|
||||
a.example.com. 3600 IN DNSKEY 384 3 5 AQPQ41chR9DEHt/aIzIFAqanbDlRflJoRs5yz1jFsoRIT7dWf0r+PeDuewdxkszNH6wnU4QL8pfKFRh5PIYVBLK3
|
||||
a.example.com. 3600 IN RRSIG DNSKEY 5 3 3600 20081010000000 20080410122550 31027 example.com. MdkvlzXlNEUrnk7jTXZ0whEjYLp1bGjOevL4yyzWAl+/LgaQqbFVApXbAQhHvouFQeoMp2+NvEGTLW8unBzJEw==
|
||||
ENTRY_END
|
||||
|
||||
; entry to test
|
||||
ENTRY_BEGIN
|
||||
SECTION QUESTION
|
||||
secure.example.com. IN DNSKEY
|
||||
SECTION ANSWER
|
||||
; the REVOKE key can sign itself
|
||||
example.com. 3600 IN DNSKEY 384 3 5 AQPQ41chR9DEHt/aIzIFAqanbDlRflJoRs5yz1jFsoRIT7dWf0r+PeDuewdxkszNH6wnU4QL8pfKFRh5PIYVBLK3 ;{id = 31027 (zsk), size = 512b}
|
||||
example.com. 3600 IN RRSIG DNSKEY 5 2 3600 20081010000000 20080410122550 31027 example.com. NEEY7W2F0XGUo9pVhiLALoz1ToM1gIS4TwUvVBPlIQMF+ZRGtB7PMthV0BN+aR+AEurxYsMfVmXEH2vKUVepgw==
|
||||
ENTRY_END
|
||||
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
server:
|
||||
verbosity: 5
|
||||
# num-threads: 1
|
||||
interface: 127.0.0.1
|
||||
port: @PORT@
|
||||
use-syslog: no
|
||||
directory: .
|
||||
pidfile: "unbound.pid"
|
||||
chroot: ""
|
||||
username: ""
|
||||
do-not-query-localhost: no
|
||||
|
||||
tls-cert-bundle: "unbound_server.pem"
|
||||
tls-upstream: yes
|
||||
|
||||
forward-zone:
|
||||
name: "."
|
||||
forward-addr: "127.0.0.1@@TOPORT@#unbound"
|
||||
|
||||
forward-zone:
|
||||
name: "example.org."
|
||||
forward-addr: "127.0.0.1@@TOPORT@#badname"
|
||||
@@ -1,40 +0,0 @@
|
||||
# this is the upstream server that has pipelining and responds to queries.
|
||||
server:
|
||||
verbosity: 1
|
||||
# num-threads: 1
|
||||
interface: 127.0.0.1@@PORT@
|
||||
port: @PORT@
|
||||
use-syslog: no
|
||||
directory: .
|
||||
pidfile: "unbound2.pid"
|
||||
chroot: ""
|
||||
username: ""
|
||||
do-not-query-localhost: no
|
||||
tls-port: @PORT@
|
||||
tls-service-key: "unbound_server.key"
|
||||
tls-service-pem: "unbound_server.pem"
|
||||
tcp-idle-timeout: 10000
|
||||
|
||||
log-queries: yes
|
||||
log-replies: yes
|
||||
log-identity: "upstream"
|
||||
|
||||
local-zone: "." refuse
|
||||
local-zone: "example.com" static
|
||||
local-data: "www.example.com A 10.20.30.40"
|
||||
local-data: "www1.example.com A 10.20.30.41"
|
||||
local-data: "www2.example.com A 10.20.30.42"
|
||||
local-data: "www3.example.com A 10.20.30.43"
|
||||
local-data: "www4.example.com A 10.20.30.44"
|
||||
local-data: "www5.example.com A 10.20.30.45"
|
||||
local-data: "www6.example.com A 10.20.30.46"
|
||||
local-data: "www7.example.com A 10.20.30.47"
|
||||
|
||||
local-data: "www.example.org A 10.20.31.40"
|
||||
local-data: "badname.example.org A 10.20.31.41"
|
||||
|
||||
# if queries escape, send them to localhost
|
||||
forward-zone:
|
||||
name: "."
|
||||
forward-tls-upstream: yes
|
||||
forward-addr: "127.0.0.1@@TOPORT@"
|
||||
-16
@@ -1,16 +0,0 @@
|
||||
BaseName: tls_reuse_auth
|
||||
Version: 1.0
|
||||
Description: Test tls stream reuse with tls auth name.
|
||||
CreationDate: Thu Apr 02 11:11:00 CEST 2026
|
||||
Maintainer: Wouter Wijngaards
|
||||
Category:
|
||||
Component:
|
||||
CmdDepends:
|
||||
Depends:
|
||||
Help:
|
||||
Pre: tls_reuse_auth.pre
|
||||
Post: tls_reuse_auth.post
|
||||
Test: tls_reuse_auth.test
|
||||
AuxFiles:
|
||||
Passed:
|
||||
Failure:
|
||||
@@ -1,19 +0,0 @@
|
||||
# #-- tls_reuse_auth.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_from_pidfile "unbound2.pid"
|
||||
if test -f unbound2.log; then
|
||||
echo ">>> upstream log"
|
||||
cat unbound2.log
|
||||
fi
|
||||
#kill_pid $UNBOUND_PID
|
||||
kill_from_pidfile "unbound.pid"
|
||||
if test -f unbound.log; then
|
||||
echo ">>> unbound log"
|
||||
cat unbound.log
|
||||
fi
|
||||
-34
@@ -1,34 +0,0 @@
|
||||
# #-- tls_reuse_auth.pre--#
|
||||
# source the master var file when it's there
|
||||
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
|
||||
# use .tpkg.var.test for in test variable passing
|
||||
[ -f .tpkg.var.test ] && source .tpkg.var.test
|
||||
|
||||
PRE="../.."
|
||||
. ../common.sh
|
||||
get_random_port 2
|
||||
UNBOUND_PORT=$RND_PORT
|
||||
UPSTREAM_PORT=$(($RND_PORT + 1))
|
||||
echo "UNBOUND_PORT=$UNBOUND_PORT" >> .tpkg.var.test
|
||||
echo "UPSTREAM_PORT=$UPSTREAM_PORT" >> .tpkg.var.test
|
||||
|
||||
# make config file
|
||||
sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@TOPORT\@/'$UPSTREAM_PORT'/' < tls_reuse_auth.conf > ub.conf
|
||||
# start unbound in the background
|
||||
#$PRE/unbound -d -c ub.conf >unbound.log 2>&1 &
|
||||
$PRE/unbound -d -c ub.conf 2>&1 | tee unbound.log &
|
||||
UNBOUND_PID=$!
|
||||
echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test
|
||||
wait_unbound_up unbound.log
|
||||
|
||||
# make upstream config file
|
||||
sed -e 's/@PORT\@/'$UPSTREAM_PORT'/' -e 's/@TOPORT\@/'$UPSTREAM_PORT'/' < tls_reuse_auth.conf2 > ub2.conf
|
||||
# start upstream unbound in the background
|
||||
#$PRE/unbound -d -c ub2.conf >unbound2.log 2>&1 &
|
||||
$PRE/unbound -d -c ub2.conf 2>&1 | tee unbound2.log &
|
||||
UPSTREAM_PID=$!
|
||||
echo "UPSTREAM_PID=$UPSTREAM_PID" >> .tpkg.var.test
|
||||
wait_unbound_up unbound2.log
|
||||
|
||||
cat .tpkg.var.test
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
# #-- tls_reuse_auth.test --#
|
||||
# source the master var file when it's there
|
||||
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
|
||||
# use .tpkg.var.test for in test variable passing
|
||||
[ -f .tpkg.var.test ] && source .tpkg.var.test
|
||||
|
||||
PRE="../.."
|
||||
. ../common.sh
|
||||
|
||||
get_make
|
||||
(cd $PRE; $MAKE streamtcp)
|
||||
|
||||
echo "> query www1.example.com."
|
||||
$PRE/streamtcp -f 127.0.0.1@$UNBOUND_PORT www1.example.com. A IN >outfile 2>&1
|
||||
cat outfile
|
||||
if test "$?" -ne 0; then
|
||||
echo "exit status not OK"
|
||||
echo "> cat logfiles"
|
||||
cat outfile
|
||||
cat unbound2.log
|
||||
cat unbound.log
|
||||
echo "Not OK"
|
||||
exit 1
|
||||
fi
|
||||
if grep "www1.example.com" outfile | grep "10.20.30.41"; then
|
||||
echo "content OK"
|
||||
else
|
||||
echo "result contents not OK, for www1.example.com"
|
||||
echo "> cat logfiles"
|
||||
cat outfile
|
||||
cat unbound2.log
|
||||
cat unbound.log
|
||||
echo "result contents not OK, for www1.example.com"
|
||||
exit 1
|
||||
fi
|
||||
echo "OK"
|
||||
echo ""
|
||||
|
||||
# this should be reused on the same tcp stream:
|
||||
echo "> query www2.example.com."
|
||||
$PRE/streamtcp -f 127.0.0.1@$UNBOUND_PORT www2.example.com. A IN >outfile 2>&1
|
||||
cat outfile
|
||||
if test "$?" -ne 0; then
|
||||
echo "exit status not OK"
|
||||
echo "> cat logfiles"
|
||||
cat outfile
|
||||
cat unbound2.log
|
||||
cat unbound.log
|
||||
echo "Not OK"
|
||||
exit 1
|
||||
fi
|
||||
if grep "www2.example.com" outfile | grep "10.20.30.42"; then
|
||||
echo "content OK"
|
||||
else
|
||||
echo "result contents not OK, for www2.example.com"
|
||||
echo "> cat logfiles"
|
||||
cat outfile
|
||||
cat unbound2.log
|
||||
cat unbound.log
|
||||
echo "result contents not OK, for www2.example.com"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# bad query with different auth name.
|
||||
echo "> query badname.example.org."
|
||||
$PRE/streamtcp -f 127.0.0.1@$UNBOUND_PORT badname.example.org. A IN >outfile 2>&1
|
||||
cat outfile
|
||||
if test "$?" -ne 0; then
|
||||
echo "exit status not OK"
|
||||
echo "> cat logfiles"
|
||||
cat outfile
|
||||
cat unbound2.log
|
||||
cat unbound.log
|
||||
echo "Not OK"
|
||||
exit 1
|
||||
fi
|
||||
if grep "badname.example.org" outfile | grep "10.20.31.41"; then
|
||||
echo "result contents not OK, for badname.example.org"
|
||||
echo "> cat logfiles"
|
||||
cat outfile
|
||||
cat unbound2.log
|
||||
cat unbound.log
|
||||
echo "result contents not OK, for badname.example.org"
|
||||
exit 1
|
||||
else
|
||||
echo "content OK"
|
||||
fi
|
||||
|
||||
echo "OK"
|
||||
exit 0
|
||||
Vendored
+2
-2
@@ -199,7 +199,7 @@ ENTRY_END
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ede=6
|
||||
MATCH all ede=10
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
@@ -215,7 +215,7 @@ ENTRY_END
|
||||
|
||||
STEP 12 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ede=6
|
||||
MATCH all ede=10
|
||||
REPLY QR RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
|
||||
Vendored
+9
-9
@@ -120,12 +120,12 @@ example.com. IN SOA ns.example.com. hostmaster.example.com. 2007090400 28800 720
|
||||
example.com. 3600 IN RRSIG SOA 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFCNGZ+/OfElYQMCZ77O9Lw9rhk7PAhUAmDcvTAst6Bq83qPq3r6c/Dm1nFc= ;{id = 2854}
|
||||
|
||||
; closest encloser, H(example.com).
|
||||
b6fuorg741ufili49mg9j4328ig53sqg.example.com. NSEC3 1 1 123 aabb00123456bbccdd b6fuorg741ufili49mg9j4328ig53sqh SOA NS MX DNSKEY RRSIG
|
||||
b6fuorg741ufili49mg9j4328ig53sqg.example.com. 3600 IN RRSIG NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. AJlV5car66lq5f0ASx7W47A/OADkARAXzKt9ZLojXze+FWK9JjAX+eA=
|
||||
6md8numosa4q9ugkffdo1bmm82t5j39s.example.com. NSEC3 1 1 8 - 6md8numosa4q9ugkffdo1bmm82t5j49s SOA NS MX DNSKEY RRSIG
|
||||
6md8numosa4q9ugkffdo1bmm82t5j39s.example.com. 3600 IN RRSIG NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCz/LkFOFcaQzVnyySW9ZoVUnxh7gIUdxyS9vqVDzo8pGhFU+3YogN2ZRk= ;{id = 2854}
|
||||
|
||||
; wildcard denial, H(*.example.com.) = k1a2vr9c269jummpru5d68qllbfmtdcb.
|
||||
k1a2vr9c269jummpru5d68qllbfmtacb.example.com. NSEC3 1 1 123 aabb00123456bbccdd k1a2vr9c269jummpru5d68qllbfmtgcb A MX RRSIG
|
||||
k1a2vr9c269jummpru5d68qllbfmtacb.example.com. 3600 IN RRSIG NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. AARB9z4C1WZUI3WP3QAR7RJXFnN0qEBkEt8ocudxXzms4/7/2l6NNWc=
|
||||
; wildcard denial, H(*.example.com.) = 4f3cnt8cu22tngec382jj4gde4rb47ub
|
||||
4f3cnt8cu22tngec382jj4gde4rb46ub.example.com. NSEC3 1 1 0 - 4f3cnt8cu22tngec382jj4gde4rb48ub A MX RRSIG
|
||||
4f3cnt8cu22tngec382jj4gde4rb46ub.example.com. 3600 IN RRSIG NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. MCwCFHS+i/OB/V/gYmS1eQTXieXIXGjsAhQQ0Ql7TW/hsUklrb0DfoyhVPG95Q== ;{id = 2854}
|
||||
|
||||
; next closer name, H(www.example.com.) = s1unhcti19bkdr98fegs0v46mbu3t4m3.
|
||||
s1unhcti19bkdr98fegs0v46mbu3t4m2.example.com. NSEC3 1 1 123 aabb00123456bbccdd s1unhcti19bkdr98fegs0v46mbu3t4m4 A MX RRSIG
|
||||
@@ -152,10 +152,10 @@ SECTION ANSWER
|
||||
SECTION AUTHORITY
|
||||
example.com. IN SOA ns.example.com. hostmaster.example.com. 2007090400 28800 7200 604800 18000
|
||||
example.com. 3600 IN RRSIG SOA 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFCNGZ+/OfElYQMCZ77O9Lw9rhk7PAhUAmDcvTAst6Bq83qPq3r6c/Dm1nFc= ;{id = 2854}
|
||||
b6fuorg741ufili49mg9j4328ig53sqg.example.com. NSEC3 1 1 123 aabb00123456bbccdd b6fuorg741ufili49mg9j4328ig53sqh SOA NS MX DNSKEY RRSIG
|
||||
b6fuorg741ufili49mg9j4328ig53sqg.example.com. 3600 IN RRSIG NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. AJlV5car66lq5f0ASx7W47A/OADkARAXzKt9ZLojXze+FWK9JjAX+eA=
|
||||
k1a2vr9c269jummpru5d68qllbfmtacb.example.com. NSEC3 1 1 123 aabb00123456bbccdd k1a2vr9c269jummpru5d68qllbfmtgcb A MX RRSIG
|
||||
k1a2vr9c269jummpru5d68qllbfmtacb.example.com. 3600 IN RRSIG NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. AARB9z4C1WZUI3WP3QAR7RJXFnN0qEBkEt8ocudxXzms4/7/2l6NNWc=
|
||||
6md8numosa4q9ugkffdo1bmm82t5j39s.example.com. NSEC3 1 1 8 - 6md8numosa4q9ugkffdo1bmm82t5j49s SOA NS MX DNSKEY RRSIG
|
||||
6md8numosa4q9ugkffdo1bmm82t5j39s.example.com. 3600 IN RRSIG NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCz/LkFOFcaQzVnyySW9ZoVUnxh7gIUdxyS9vqVDzo8pGhFU+3YogN2ZRk= ;{id = 2854}
|
||||
4f3cnt8cu22tngec382jj4gde4rb46ub.example.com. NSEC3 1 1 0 - 4f3cnt8cu22tngec382jj4gde4rb48ub A MX RRSIG
|
||||
4f3cnt8cu22tngec382jj4gde4rb46ub.example.com. 3600 IN RRSIG NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. MCwCFHS+i/OB/V/gYmS1eQTXieXIXGjsAhQQ0Ql7TW/hsUklrb0DfoyhVPG95Q== ;{id = 2854}
|
||||
s1unhcti19bkdr98fegs0v46mbu3t4m2.example.com. NSEC3 1 1 123 aabb00123456bbccdd s1unhcti19bkdr98fegs0v46mbu3t4m4 A MX RRSIG
|
||||
s1unhcti19bkdr98fegs0v46mbu3t4m2.example.com. 3600 IN RRSIG NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFFSH4klZKke48dYyddYDj17gjTS0AhUAltWicpFLWqW98/Af9Qlx70MH8o4= ;{id = 2854}
|
||||
|
||||
|
||||
Vendored
+19
-12
@@ -89,17 +89,6 @@ ns.example.com. IN A 1.2.3.4
|
||||
ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
ns.example.com. IN AAAA
|
||||
SECTION AUTHORITY
|
||||
example.com. IN SOA ns.example.com. hostmaster.example.com. 2007090400 28800 7200 604800 18000
|
||||
example.com. 3600 IN RRSIG SOA 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFCNGZ+/OfElYQMCZ77O9Lw9rhk7PAhUAmDcvTAst6Bq83qPq3r6c/Dm1nFc= ;{id = 2854}
|
||||
ENTRY_END
|
||||
|
||||
; response to DNSKEY priming query
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
@@ -174,11 +163,29 @@ STEP 2 TIME_PASSES ELAPSE 0.05
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
REPLY QR RD RA DO NXDOMAIN
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
SECTION AUTHORITY
|
||||
example.com. IN SOA ns.example.com. hostmaster.example.com. 2007090400 28800 7200 604800 18000
|
||||
example.com. 3600 IN RRSIG SOA 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFCNGZ+/OfElYQMCZ77O9Lw9rhk7PAhUAmDcvTAst6Bq83qPq3r6c/Dm1nFc= ;{id = 2854}
|
||||
6md8numosa4q9ugkffdo1bmm82t5j39s.example.com. NSEC3 1 1 123 aabb00123456bbccdd 6md8numosa4q9ugkffdo1bmm82t5j49s A RRSIG
|
||||
6md8numosa4q9ugkffdo1bmm82t5j39s.example.com. NSEC3 1 1 8 - 6md8numosa4q9ugkffdo1bmm82t5j49s SOA NS MX DNSKEY RRSIG
|
||||
6md8numosa4q9ugkffdo1bmm82t5j39s.example.com. 3600 IN RRSIG NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. MCwCFHndWrEEbuzezs/4lxeiMgEuUsUbAhR72gJgd/Zmhf80yoxCauw9k5OkCw== ;{id = 2854}
|
||||
4f3cnt8cu22tngec382jj4gde4rb46ub.example.com. NSEC3 1 1 18 - 4f3cnt8cu22tngec382jj4gde4rb87ub A RRSIG
|
||||
4f3cnt8cu22tngec382jj4gde4rb46ub.example.com. NSEC3 1 1 0 - 4f3cnt8cu22tngec382jj4gde4rb48ub A MX RRSIG
|
||||
4f3cnt8cu22tngec382jj4gde4rb46ub.example.com. NSEC3 1 1 19 - 4f3cnt8cu22tngec382jj4gde4rb87ub A RRSIG
|
||||
4f3cnt8cu22tngec382jj4gde4rb46ub.example.com. 3600 IN RRSIG NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. MCwCFDRwji51WCXJg7W/3+Jx586af5qgAhQPxHegtzu1I/QbvCNrOOON05N1rw== ;{id = 2854}
|
||||
s1unhcti19bkdr98fegs0v46mbu3t4m2.example.com. NSEC3 1 1 18 - s1unhcti19bkdr98fegs0v46mbu3t4m4 A RRSIG
|
||||
s1unhcti19bkdr98fegs0v46mbu3t4m2.example.com. NSEC3 1 1 19 - s1unhcti19bkdr98fegs0v46mbu3t4m4 A RRSIG
|
||||
s1unhcti19bkdr98fegs0v46mbu3t4m2.example.com. NSEC3 1 1 20 00 s1unhcti19bkdr98fegs0v46mbu3t4m4 A RRSIG
|
||||
s1unhcti19bkdr98fegs0v46mbu3t4m2.example.com. NSEC3 1 1 123 aabb00123456bbccdd s1unhcti19bkdr98fegs0v46mbu3t4m4 A MX RRSIG
|
||||
s1unhcti19bkdr98fegs0v46mbu3t4m2.example.com. NSEC3 1 1 20 01 s1unhcti19bkdr98fegs0v46mbu3t4m4 A RRSIG
|
||||
s1unhcti19bkdr98fegs0v46mbu3t4m2.example.com. NSEC3 1 1 20 02 s1unhcti19bkdr98fegs0v46mbu3t4m4 A RRSIG
|
||||
s1unhcti19bkdr98fegs0v46mbu3t4m2.example.com. NSEC3 1 1 20 03 s1unhcti19bkdr98fegs0v46mbu3t4m4 A RRSIG
|
||||
s1unhcti19bkdr98fegs0v46mbu3t4m2.example.com. 3600 IN RRSIG NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. MCwCFDLy4GbR8ZaKHATVJGnGxzpsuq60AhQ1/pRbXi1ZbcYohzHgWzNC50fC5A== ;{id = 2854}
|
||||
|
||||
SECTION ADDITIONAL
|
||||
ENTRY_END
|
||||
|
||||
|
||||
Vendored
+10
-12
@@ -88,17 +88,6 @@ ns.example.com. IN A 1.2.3.4
|
||||
ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
ns.example.com. IN AAAA
|
||||
SECTION AUTHORITY
|
||||
example.com. IN SOA ns.example.com. hostmaster.example.com. 2007090400 28800 7200 604800 18000
|
||||
example.com. 3600 IN RRSIG SOA 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFCNGZ+/OfElYQMCZ77O9Lw9rhk7PAhUAmDcvTAst6Bq83qPq3r6c/Dm1nFc= ;{id = 2854}
|
||||
ENTRY_END
|
||||
|
||||
; response to DNSKEY priming query
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
@@ -155,11 +144,20 @@ ENTRY_END
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
REPLY QR RD RA DO NXDOMAIN
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
SECTION AUTHORITY
|
||||
example.com. IN SOA ns.example.com. hostmaster.example.com. 2007090400 28800 7200 604800 18000
|
||||
example.com. 3600 IN RRSIG SOA 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFCNGZ+/OfElYQMCZ77O9Lw9rhk7PAhUAmDcvTAst6Bq83qPq3r6c/Dm1nFc= ;{id = 2854}
|
||||
6md8numosa4q9ugkffdo1bmm82t5j39s.example.com. NSEC3 1 1 8 - 6md8numosa4q9ugkffdo1bmm82t5j49s SOA NS MX DNSKEY RRSIG
|
||||
6md8numosa4q9ugkffdo1bmm82t5j39s.example.com. 3600 IN RRSIG NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCz/LkFOFcaQzVnyySW9ZoVUnxh7gIUdxyS9vqVDzo8pGhFU+3YogN2ZRk= ;{id = 2854}
|
||||
4f3cnt8cu22tngec382jj4gde4rb46ub.example.com. NSEC3 1 1 0 - 4f3cnt8cu22tngec382jj4gde4rb48ub A MX RRSIG
|
||||
4f3cnt8cu22tngec382jj4gde4rb46ub.example.com. 3600 IN RRSIG NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. MCwCFHS+i/OB/V/gYmS1eQTXieXIXGjsAhQQ0Ql7TW/hsUklrb0DfoyhVPG95Q== ;{id = 2854}
|
||||
s1unhcti19bkdr98fegs0v46mbu3t4m2.example.com. NSEC3 1 1 123 aabb00123456bbccdd s1unhcti19bkdr98fegs0v46mbu3t4m4 A MX RRSIG
|
||||
s1unhcti19bkdr98fegs0v46mbu3t4m2.example.com. 3600 IN RRSIG NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFFSH4klZKke48dYyddYDj17gjTS0AhUAltWicpFLWqW98/Af9Qlx70MH8o4= ;{id = 2854}
|
||||
|
||||
SECTION ADDITIONAL
|
||||
ENTRY_END
|
||||
|
||||
|
||||
+1
-1
@@ -328,7 +328,7 @@ size_t alloc_get_mem(struct alloc_cache* alloc)
|
||||
struct regional*
|
||||
alloc_reg_obtain(struct alloc_cache* alloc)
|
||||
{
|
||||
if(alloc->num_reg_blocks > 0 && alloc->reg_list) {
|
||||
if(alloc->num_reg_blocks > 0) {
|
||||
struct regional* r = alloc->reg_list;
|
||||
alloc->reg_list = (struct regional*)r->next;
|
||||
r->next = NULL;
|
||||
|
||||
+30
-59
@@ -74,6 +74,9 @@
|
||||
#ifdef HAVE_PWD_H
|
||||
#include <pwd.h>
|
||||
#endif
|
||||
#ifndef USE_SYSTEM_TLS
|
||||
#define USE_SYSTEM_TLS 0
|
||||
#endif
|
||||
|
||||
/** from cfg username, after daemonize setup performed */
|
||||
uid_t cfg_uid = (uid_t)-1;
|
||||
@@ -132,7 +135,7 @@ config_create(void)
|
||||
cfg->tls_cert_bundle = NULL;
|
||||
cfg->tls_win_cert = 0;
|
||||
cfg->tls_use_sni = 1;
|
||||
if(!(cfg->tls_protocols = strdup("TLSv1.2 TLSv1.3"))) goto error_exit;
|
||||
cfg->tls_use_system_policy_versions = USE_SYSTEM_TLS;
|
||||
cfg->https_port = UNBOUND_DNS_OVER_HTTPS_PORT;
|
||||
if(!(cfg->http_endpoint = strdup("/dns-query"))) goto error_exit;
|
||||
cfg->http_max_streams = 100;
|
||||
@@ -343,6 +346,14 @@ config_create(void)
|
||||
cfg->dnstap_bidirectional = 1;
|
||||
cfg->dnstap_tls = 1;
|
||||
cfg->disable_dnssec_lame_check = 0;
|
||||
#ifdef USE_METRICS
|
||||
cfg->metrics_enable = 0;
|
||||
cfg->metrics_ifs.first = NULL;
|
||||
cfg->metrics_ifs.last = NULL;
|
||||
cfg->metrics_port = UNBOUND_METRICS_PORT;
|
||||
if(!(cfg->metrics_path = strdup("/metrics")))
|
||||
goto error_exit;
|
||||
#endif /* USE_METRICS */
|
||||
cfg->ip_ratelimit_cookie = 0;
|
||||
cfg->ip_ratelimit = 0;
|
||||
cfg->ratelimit = 0;
|
||||
@@ -426,7 +437,6 @@ config_create(void)
|
||||
cfg->dns_error_reporting = 0;
|
||||
cfg->iter_scrub_ns = 20;
|
||||
cfg->iter_scrub_cname = 11;
|
||||
cfg->iter_scrub_rrsig = 8;
|
||||
cfg->iter_scrub_promiscuous = 1;
|
||||
cfg->max_global_quota = 200;
|
||||
return cfg;
|
||||
@@ -635,11 +645,7 @@ int config_set_option(struct config_file* cfg, const char* opt,
|
||||
else S_STR("tls-ciphers:", tls_ciphers)
|
||||
else S_STR("tls-ciphersuites:", tls_ciphersuites)
|
||||
else S_YNO("tls-use-sni:", tls_use_sni)
|
||||
else if(strcmp(opt, "tls-protocols:") == 0) {
|
||||
if(!cfg_tls_protocols_is_valid(val)) return 0;
|
||||
free(cfg->tls_protocols);
|
||||
return (cfg->tls_protocols = strdup(val)) != NULL;
|
||||
}
|
||||
else S_YNO("tls-use-system-policy-versions:", tls_use_system_policy_versions)
|
||||
else S_NUMBER_NONZERO("https-port:", https_port)
|
||||
else S_STR("http-endpoint:", http_endpoint)
|
||||
else S_NUMBER_NONZERO("http-max-streams:", http_max_streams)
|
||||
@@ -778,7 +784,6 @@ int config_set_option(struct config_file* cfg, const char* opt,
|
||||
else S_YNO("dns-error-reporting:", dns_error_reporting)
|
||||
else S_NUMBER_OR_ZERO("iter-scrub-ns:", iter_scrub_ns)
|
||||
else S_NUMBER_OR_ZERO("iter-scrub-cname:", iter_scrub_cname)
|
||||
else S_NUMBER_OR_ZERO("iter-scrub-rrsig:", iter_scrub_rrsig)
|
||||
else S_YNO("iter-scrub-promiscuous:", iter_scrub_promiscuous)
|
||||
else S_NUMBER_OR_ZERO("max-global-quota:", max_global_quota)
|
||||
else S_YNO("serve-original-ttl:", serve_original_ttl)
|
||||
@@ -848,6 +853,12 @@ int config_set_option(struct config_file* cfg, const char* opt,
|
||||
else S_YNO("dnstap-log-forwarder-response-messages:",
|
||||
dnstap_log_forwarder_response_messages)
|
||||
#endif
|
||||
#ifdef USE_METRICS
|
||||
else S_YNO("metrics-enable:", metrics_enable)
|
||||
else S_STRLIST_APPEND("metrics-interface:", metrics_ifs)
|
||||
else S_NUMBER_NONZERO("metrics-port:", metrics_port)
|
||||
else S_STR("metrics-path:", metrics_path)
|
||||
#endif /* USE_METRICS */
|
||||
#ifdef USE_DNSCRYPT
|
||||
else S_YNO("dnscrypt-enable:", dnscrypt)
|
||||
else S_NUMBER_NONZERO("dnscrypt-port:", dnscrypt_port)
|
||||
@@ -1194,7 +1205,7 @@ config_get_option(struct config_file* cfg, const char* opt,
|
||||
else O_STR(opt, "tls-ciphers", tls_ciphers)
|
||||
else O_STR(opt, "tls-ciphersuites", tls_ciphersuites)
|
||||
else O_YNO(opt, "tls-use-sni", tls_use_sni)
|
||||
else O_STR(opt, "tls-protocols", tls_protocols)
|
||||
else O_YNO(opt, "tls-use-system-policy-versions", tls_use_system_policy_versions)
|
||||
else O_DEC(opt, "https-port", https_port)
|
||||
else O_STR(opt, "http-endpoint", http_endpoint)
|
||||
else O_UNS(opt, "http-max-streams", http_max_streams)
|
||||
@@ -1258,7 +1269,6 @@ config_get_option(struct config_file* cfg, const char* opt,
|
||||
else O_YNO(opt, "dns-error-reporting", dns_error_reporting)
|
||||
else O_DEC(opt, "iter-scrub-ns", iter_scrub_ns)
|
||||
else O_DEC(opt, "iter-scrub-cname", iter_scrub_cname)
|
||||
else O_DEC(opt, "iter-scrub-rrsig", iter_scrub_rrsig)
|
||||
else O_YNO(opt, "iter-scrub-promiscuous", iter_scrub_promiscuous)
|
||||
else O_DEC(opt, "max-global-quota", max_global_quota)
|
||||
else O_YNO(opt, "serve-original-ttl", serve_original_ttl)
|
||||
@@ -1342,6 +1352,12 @@ config_get_option(struct config_file* cfg, const char* opt,
|
||||
else O_YNO(opt, "dnstap-log-forwarder-response-messages",
|
||||
dnstap_log_forwarder_response_messages)
|
||||
#endif
|
||||
#ifdef USE_METRICS
|
||||
else O_YNO(opt, "metrics-enable", metrics_enable)
|
||||
else O_LST(opt, "metrics-interface", metrics_ifs.first)
|
||||
else O_DEC(opt, "metrics-port", metrics_port)
|
||||
else O_STR(opt, "metrics-path", metrics_path)
|
||||
#endif /* USE_METRICS */
|
||||
#ifdef USE_DNSCRYPT
|
||||
else O_YNO(opt, "dnscrypt-enable", dnscrypt)
|
||||
else O_DEC(opt, "dnscrypt-port", dnscrypt_port)
|
||||
@@ -1766,7 +1782,6 @@ config_delete(struct config_file* cfg)
|
||||
config_delstrlist(cfg->tls_session_ticket_keys.first);
|
||||
free(cfg->tls_ciphers);
|
||||
free(cfg->tls_ciphersuites);
|
||||
free(cfg->tls_protocols);
|
||||
free(cfg->http_endpoint);
|
||||
if(cfg->log_identity) {
|
||||
log_ident_revert_to_default();
|
||||
@@ -1840,6 +1855,10 @@ config_delete(struct config_file* cfg)
|
||||
free(cfg->dnstap_tls_client_cert_file);
|
||||
free(cfg->dnstap_identity);
|
||||
free(cfg->dnstap_version);
|
||||
#ifdef USE_METRICS
|
||||
config_delstrlist(cfg->metrics_ifs.first);
|
||||
free(cfg->metrics_path);
|
||||
#endif /* USE_METRICS */
|
||||
config_deldblstrlist(cfg->ratelimit_for_domain);
|
||||
config_deldblstrlist(cfg->ratelimit_below_domain);
|
||||
config_delstrlist(cfg->python_script);
|
||||
@@ -2993,54 +3012,6 @@ cfg_has_quic(struct config_file* cfg)
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
cfg_tls_protocols_is_valid(const char* tls_protocols)
|
||||
{
|
||||
const char* s = tls_protocols;
|
||||
while(*s && isspace((unsigned char)*s)) s++;
|
||||
while(*s && !isspace((unsigned char)*s)) {
|
||||
if(strncmp(s, "TLSv1.2", 7) == 0 ||
|
||||
strncmp(s, "TLSv1.3", 7) == 0) {
|
||||
s += 7;
|
||||
if(*s && !isspace((unsigned char)*s)) {
|
||||
/* something is attached; fail */
|
||||
return 0;
|
||||
}
|
||||
while(*s && isspace((unsigned char)*s))
|
||||
s++;
|
||||
continue;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
cfg_tls_protocols_allowed(const char* tls_protocols, int* allow12, int* allow13)
|
||||
{
|
||||
const char* s = tls_protocols;
|
||||
*allow12 = 0;
|
||||
*allow13 = 0;
|
||||
if(tls_protocols == NULL) return;
|
||||
while(*s && isspace((unsigned char)*s)) s++;
|
||||
while(*s && !isspace((unsigned char)*s)) {
|
||||
if(strncmp(s, "TLSv1.2", 7) == 0) {
|
||||
*allow12 = 1;
|
||||
s += 7;
|
||||
} else if(strncmp(s, "TLSv1.3", 7) == 0) {
|
||||
*allow13 = 1;
|
||||
s += 7;
|
||||
} else {
|
||||
/* Unknown word, this should never happen but skip to
|
||||
* be safe */
|
||||
while(*s && !isspace((unsigned char)*s))
|
||||
s++;
|
||||
}
|
||||
while(*s && isspace((unsigned char)*s))
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
file_get_mtime(const char* file, time_t* mtime, long* ns, int* nonexist)
|
||||
{
|
||||
|
||||
+13
-19
@@ -148,8 +148,8 @@ struct config_file {
|
||||
char* tls_ciphersuites;
|
||||
/** if SNI is to be used */
|
||||
int tls_use_sni;
|
||||
/** TLS protocols */
|
||||
char* tls_protocols;
|
||||
/** if all TLS versions can be used; based on system policy (if any) */
|
||||
int tls_use_system_policy_versions;
|
||||
|
||||
/** port on which to provide DNS over HTTPS service */
|
||||
int https_port;
|
||||
@@ -625,6 +625,17 @@ struct config_file {
|
||||
/** true to disable DNSSEC lameness check in iterator */
|
||||
int disable_dnssec_lame_check;
|
||||
|
||||
#ifdef USE_METRICS
|
||||
/** metrics section. enable toggle. */
|
||||
int metrics_enable;
|
||||
/** the interfaces the metrics endpoint should listen on */
|
||||
struct config_strlist_head metrics_ifs;
|
||||
/** port number for the metrics endpoint */
|
||||
int metrics_port;
|
||||
/** HTTP path for the metrics endpoint */
|
||||
char* metrics_path;
|
||||
#endif /* USE_METRICS */
|
||||
|
||||
/** ratelimit for ip addresses. 0 is off, otherwise qps (unless overridden) */
|
||||
int ip_ratelimit;
|
||||
/** ratelimit for ip addresses with a valid DNS Cookie. 0 is off,
|
||||
@@ -794,8 +805,6 @@ struct config_file {
|
||||
size_t iter_scrub_ns;
|
||||
/** limit on CNAME, DNAME RRs in answer for the iterator scrubber. */
|
||||
int iter_scrub_cname;
|
||||
/** limit on RRSIGs for an RRset for the iterator scrubber. */
|
||||
int iter_scrub_rrsig;
|
||||
/** limit on upstream queries for an incoming query and subqueries. */
|
||||
int max_global_quota;
|
||||
/** Should the iterator scrub promiscuous NS rrsets, from positive
|
||||
@@ -1495,21 +1504,6 @@ size_t getmem_str(char* str);
|
||||
*/
|
||||
int cfg_ports_list_contains(char* ports, int p);
|
||||
|
||||
/**
|
||||
* Check if the configured string contains supported TLS protocols.
|
||||
* @param tls_protocols: String with TLS protocols.
|
||||
* @return true if all options are valid, else false.
|
||||
*/
|
||||
int cfg_tls_protocols_is_valid(const char* tls_protocols);
|
||||
|
||||
/**
|
||||
* Based on the configured TLS protocols fill which ones are allowed.
|
||||
* @param tls_protocols: String with TLS protocols.
|
||||
* @param allow12: will be true if TLSv1.2 is configured.
|
||||
* @param allow13: will be true if TLSv1.3 is configured.
|
||||
*/
|
||||
void cfg_tls_protocols_allowed(const char* tls_protocols, int* allow12, int* allow13);
|
||||
|
||||
/** get the file mtime stat (or error, with errno and nonexist) */
|
||||
int file_get_mtime(const char* file, time_t* mtime, long* ns, int* nonexist);
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#pragma GCC diagnostic ignored "-Wsign-compare"
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include <strings.h>
|
||||
#ifdef HAVE_GLOB_H
|
||||
# include <glob.h>
|
||||
@@ -261,7 +262,7 @@ tls-session-ticket-keys{COLON} { YDVAR(1, VAR_TLS_SESSION_TICKET_KEYS) }
|
||||
tls-ciphers{COLON} { YDVAR(1, VAR_TLS_CIPHERS) }
|
||||
tls-ciphersuites{COLON} { YDVAR(1, VAR_TLS_CIPHERSUITES) }
|
||||
tls-use-sni{COLON} { YDVAR(1, VAR_TLS_USE_SNI) }
|
||||
tls-protocols{COLON} { YDVAR(1, VAR_TLS_PROTOCOLS) }
|
||||
tls-use-system-policy-versions{COLON} { YDVAR(1, VAR_TLS_USE_SYSTEM_POLICY_VERSIONS) }
|
||||
https-port{COLON} { YDVAR(1, VAR_HTTPS_PORT) }
|
||||
http-endpoint{COLON} { YDVAR(1, VAR_HTTP_ENDPOINT) }
|
||||
http-max-streams{COLON} { YDVAR(1, VAR_HTTP_MAX_STREAMS) }
|
||||
@@ -490,6 +491,10 @@ interface-tag-action{COLON} { YDVAR(3, VAR_INTERFACE_TAG_ACTION) }
|
||||
interface-tag-data{COLON} { YDVAR(3, VAR_INTERFACE_TAG_DATA) }
|
||||
interface-view{COLON} { YDVAR(2, VAR_INTERFACE_VIEW) }
|
||||
local-zone-override{COLON} { YDVAR(3, VAR_LOCAL_ZONE_OVERRIDE) }
|
||||
metrics-enable{COLON} { YDVAR(1, VAR_METRICS_ENABLE) }
|
||||
metrics-interface{COLON} { YDVAR(1, VAR_METRICS_INTERFACE) }
|
||||
metrics-port{COLON} { YDVAR(1, VAR_METRICS_PORT) }
|
||||
metrics-path{COLON} { YDVAR(1, VAR_METRICS_PATH) }
|
||||
dnstap{COLON} { YDVAR(0, VAR_DNSTAP) }
|
||||
dnstap-enable{COLON} { YDVAR(1, VAR_DNSTAP_ENABLE) }
|
||||
dnstap-bidirectional{COLON} { YDVAR(1, VAR_DNSTAP_BIDIRECTIONAL) }
|
||||
@@ -606,7 +611,6 @@ dns-error-reporting{COLON} { YDVAR(1, VAR_DNS_ERROR_REPORTING ) }
|
||||
proxy-protocol-port{COLON} { YDVAR(1, VAR_PROXY_PROTOCOL_PORT) }
|
||||
iter-scrub-ns{COLON} { YDVAR(1, VAR_ITER_SCRUB_NS) }
|
||||
iter-scrub-cname{COLON} { YDVAR(1, VAR_ITER_SCRUB_CNAME) }
|
||||
iter-scrub-rrsig{COLON} { YDVAR(1, VAR_ITER_SCRUB_RRSIG) }
|
||||
max-global-quota{COLON} { YDVAR(1, VAR_MAX_GLOBAL_QUOTA) }
|
||||
iter-scrub-promiscuous{COLON} { YDVAR(1, VAR_ITER_SCRUB_PROMISCUOUS) }
|
||||
<INITIAL,val>{NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++; }
|
||||
|
||||
+60
-20
@@ -126,6 +126,8 @@ extern struct config_parser_state* cfg_parser;
|
||||
%token VAR_INFRA_CACHE_MIN_RTT VAR_INFRA_CACHE_MAX_RTT VAR_INFRA_KEEP_PROBING
|
||||
%token VAR_DNS64_PREFIX VAR_DNS64_SYNTHALL VAR_DNS64_IGNORE_AAAA
|
||||
%token VAR_NAT64_PREFIX
|
||||
%token VAR_METRICS_ENABLE VAR_METRICS_INTERFACE VAR_METRICS_PORT
|
||||
%token VAR_METRICS_PATH
|
||||
%token VAR_DNSTAP VAR_DNSTAP_ENABLE VAR_DNSTAP_SOCKET_PATH VAR_DNSTAP_IP
|
||||
%token VAR_DNSTAP_TLS VAR_DNSTAP_TLS_SERVER_NAME VAR_DNSTAP_TLS_CERT_BUNDLE
|
||||
%token VAR_DNSTAP_TLS_CLIENT_KEY_FILE VAR_DNSTAP_TLS_CLIENT_CERT_FILE
|
||||
@@ -199,7 +201,7 @@ extern struct config_parser_state* cfg_parser;
|
||||
%token VAR_DISCARD_TIMEOUT VAR_WAIT_LIMIT VAR_WAIT_LIMIT_COOKIE
|
||||
%token VAR_WAIT_LIMIT_NETBLOCK VAR_WAIT_LIMIT_COOKIE_NETBLOCK
|
||||
%token VAR_STREAM_WAIT_SIZE VAR_TLS_CIPHERS VAR_TLS_CIPHERSUITES VAR_TLS_USE_SNI
|
||||
%token VAR_TLS_PROTOCOLS
|
||||
%token VAR_TLS_USE_SYSTEM_POLICY_VERSIONS
|
||||
%token VAR_IPSET VAR_IPSET_NAME_V4 VAR_IPSET_NAME_V6
|
||||
%token VAR_TLS_SESSION_TICKET_KEYS VAR_RPZ VAR_TAGS VAR_RPZ_ACTION_OVERRIDE
|
||||
%token VAR_RPZ_CNAME_OVERRIDE VAR_RPZ_LOG VAR_RPZ_LOG_NAME
|
||||
@@ -215,7 +217,6 @@ extern struct config_parser_state* cfg_parser;
|
||||
%token VAR_HARDEN_UNKNOWN_ADDITIONAL VAR_DISABLE_EDNS_DO VAR_CACHEDB_NO_STORE
|
||||
%token VAR_LOG_DESTADDR VAR_CACHEDB_CHECK_WHEN_SERVE_EXPIRED
|
||||
%token VAR_COOKIE_SECRET_FILE VAR_ITER_SCRUB_NS VAR_ITER_SCRUB_CNAME
|
||||
%token VAR_ITER_SCRUB_RRSIG
|
||||
%token VAR_MAX_GLOBAL_QUOTA VAR_HARDEN_UNVERIFIED_GLUE VAR_LOG_TIME_ISO
|
||||
%token VAR_ITER_SCRUB_PROMISCUOUS VAR_LOG_THREAD_ID
|
||||
|
||||
@@ -348,7 +349,8 @@ content_server: server_num_threads | server_verbosity | server_port |
|
||||
server_stream_wait_size | server_tls_ciphers |
|
||||
server_tls_ciphersuites | server_tls_session_ticket_keys |
|
||||
server_answer_cookie | server_cookie_secret | server_ip_ratelimit_cookie |
|
||||
server_tls_use_sni | server_edns_client_string | server_tls_protocols |
|
||||
server_tls_use_sni | server_edns_client_string |
|
||||
server_tls_use_system_policy_versions |
|
||||
server_edns_client_string_opcode | server_nsid |
|
||||
server_zonemd_permissive_mode | server_max_reuse_tcp_queries |
|
||||
server_tcp_reuse_timeout | server_tcp_auth_query_timeout |
|
||||
@@ -359,8 +361,9 @@ content_server: server_num_threads | server_verbosity | server_port |
|
||||
server_harden_unknown_additional | server_disable_edns_do |
|
||||
server_log_destaddr | server_cookie_secret_file |
|
||||
server_iter_scrub_ns | server_iter_scrub_cname | server_max_global_quota |
|
||||
server_iter_scrub_rrsig |
|
||||
server_harden_unverified_glue | server_log_time_iso | server_iter_scrub_promiscuous
|
||||
server_harden_unverified_glue | server_log_time_iso | server_iter_scrub_promiscuous |
|
||||
server_metrics_enable | server_metrics_interface |
|
||||
server_metrics_port | server_metrics_path
|
||||
;
|
||||
stub_clause: stubstart contents_stub
|
||||
{
|
||||
@@ -1158,13 +1161,13 @@ server_tls_use_sni: VAR_TLS_USE_SNI STRING_ARG
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
server_tls_protocols: VAR_TLS_PROTOCOLS STRING_ARG
|
||||
server_tls_use_system_policy_versions: VAR_TLS_USE_SYSTEM_POLICY_VERSIONS STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_tls_protocols:%s)\n", $2));
|
||||
if(!cfg_tls_protocols_is_valid($2))
|
||||
yyerror("tls-protocols: valid values are 'TLSv1.2' and 'TLSv1.3'.");
|
||||
free(cfg_parser->cfg->tls_protocols);
|
||||
cfg_parser->cfg->tls_protocols = $2;
|
||||
OUTYY(("P(server_tls_use_system_policy_versions:%s)\n", $2));
|
||||
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
|
||||
yyerror("expected yes or no.");
|
||||
else cfg_parser->cfg->tls_use_system_policy_versions = (strcmp($2, "yes")==0);
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
server_https_port: VAR_HTTPS_PORT STRING_ARG
|
||||
@@ -2749,6 +2752,52 @@ server_response_ip_tag: VAR_RESPONSE_IP_TAG STRING_ARG STRING_ARG
|
||||
}
|
||||
}
|
||||
;
|
||||
server_metrics_enable: VAR_METRICS_ENABLE STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_metrics_enable:%s)\n", $2));
|
||||
#ifdef USE_METRICS
|
||||
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
|
||||
yyerror("expected yes or no.");
|
||||
else cfg_parser->cfg->metrics_enable = (strcmp($2, "yes")==0);
|
||||
#else
|
||||
if(strcmp($2, "yes")==0)
|
||||
log_warn("%s:%d the server is not compiled with "
|
||||
"prometheus metrics.", cfg_parser->filename,
|
||||
cfg_parser->line);
|
||||
#endif
|
||||
free($2);
|
||||
};
|
||||
server_metrics_interface: VAR_METRICS_INTERFACE STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_metrics_interface:%s)\n", $2));
|
||||
#ifdef USE_METRICS
|
||||
if(!cfg_strlist_append(&cfg_parser->cfg->metrics_ifs, $2))
|
||||
yyerror("out of memory");
|
||||
#else
|
||||
free($2);
|
||||
#endif
|
||||
};
|
||||
server_metrics_port: VAR_METRICS_PORT STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_metrics_port:%s)\n", $2));
|
||||
#ifdef USE_METRICS
|
||||
if(atoi($2) == 0 && strcmp($2,"0")!=0)
|
||||
yyerror("port number expected");
|
||||
else
|
||||
cfg_parser->cfg->metrics_port = atoi($2);
|
||||
#endif
|
||||
free($2);
|
||||
};
|
||||
server_metrics_path: VAR_METRICS_PATH STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_metrics_path:%s)\n", $2));
|
||||
#ifdef USE_METRICS
|
||||
free(cfg_parser->cfg->metrics_path);
|
||||
cfg_parser->cfg->metrics_path = $2;
|
||||
#else
|
||||
free($2);
|
||||
#endif
|
||||
};
|
||||
server_ip_ratelimit: VAR_IP_RATELIMIT STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_ip_ratelimit:%s)\n", $2));
|
||||
@@ -4256,15 +4305,6 @@ server_iter_scrub_cname: VAR_ITER_SCRUB_CNAME STRING_ARG
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
server_iter_scrub_rrsig: VAR_ITER_SCRUB_RRSIG STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_iter_scrub_rrsig:%s)\n", $2));
|
||||
if(atoi($2) == 0 && strcmp($2, "0") != 0)
|
||||
yyerror("number expected");
|
||||
else cfg_parser->cfg->iter_scrub_rrsig = atoi($2);
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
server_max_global_quota: VAR_MAX_GLOBAL_QUOTA STRING_ARG
|
||||
{
|
||||
OUTYY(("P(server_max_global_quota:%s)\n", $2));
|
||||
|
||||
+14
-24
@@ -352,6 +352,7 @@ compress_any_dname(uint8_t* dname, sldns_buffer* pkt, int labs,
|
||||
(p = compress_tree_lookup(tree, dname, labs, &insertpt))) {
|
||||
if(!write_compressed_dname(pkt, dname, labs, p))
|
||||
return RETVAL_TRUNC;
|
||||
(*compress_count)++;
|
||||
} else {
|
||||
if(!dname_buffer_write(pkt, dname))
|
||||
return RETVAL_TRUNC;
|
||||
@@ -359,7 +360,6 @@ compress_any_dname(uint8_t* dname, sldns_buffer* pkt, int labs,
|
||||
if(*compress_count < MAX_COMPRESSION_PER_MESSAGE &&
|
||||
!compress_tree_store(dname, labs, pos, region, p, insertpt))
|
||||
return RETVAL_OUTMEM;
|
||||
(*compress_count)++;
|
||||
return RETVAL_OK;
|
||||
}
|
||||
|
||||
@@ -820,7 +820,7 @@ reply_info_encode(struct query_info* qinfo, struct reply_info* rep,
|
||||
return 1;
|
||||
}
|
||||
|
||||
size_t
|
||||
uint16_t
|
||||
calc_edns_field_size(struct edns_data* edns)
|
||||
{
|
||||
size_t rdatalen = 0;
|
||||
@@ -856,7 +856,7 @@ calc_edns_option_size(struct edns_data* edns, uint16_t code)
|
||||
}
|
||||
|
||||
uint16_t
|
||||
calc_ede_option_size(struct edns_data* edns, size_t* txt_size)
|
||||
calc_ede_option_size(struct edns_data* edns, uint16_t* txt_size)
|
||||
{
|
||||
size_t rdatalen = 0;
|
||||
struct edns_option* opt;
|
||||
@@ -958,10 +958,6 @@ attach_edns_record_max_msg_sz(sldns_buffer* pkt, struct edns_data* edns,
|
||||
padding_option = opt;
|
||||
continue;
|
||||
}
|
||||
if(sldns_buffer_position(pkt) + opt->opt_len + 4 > max_msg_sz)
|
||||
break; /* no space for it */
|
||||
if(!sldns_buffer_available(pkt, 4 + opt->opt_len))
|
||||
break;
|
||||
sldns_buffer_write_u16(pkt, opt->opt_code);
|
||||
sldns_buffer_write_u16(pkt, opt->opt_len);
|
||||
if(opt->opt_len != 0)
|
||||
@@ -972,18 +968,12 @@ attach_edns_record_max_msg_sz(sldns_buffer* pkt, struct edns_data* edns,
|
||||
padding_option = opt;
|
||||
continue;
|
||||
}
|
||||
if(sldns_buffer_position(pkt) + opt->opt_len + 4 > max_msg_sz)
|
||||
break; /* no space for it */
|
||||
if(!sldns_buffer_available(pkt, 4 + opt->opt_len))
|
||||
break;
|
||||
sldns_buffer_write_u16(pkt, opt->opt_code);
|
||||
sldns_buffer_write_u16(pkt, opt->opt_len);
|
||||
if(opt->opt_len != 0)
|
||||
sldns_buffer_write(pkt, opt->opt_data, opt->opt_len);
|
||||
}
|
||||
if (padding_option && edns->padding_block_size &&
|
||||
sldns_buffer_position(pkt)+4 <= max_msg_sz &&
|
||||
sldns_buffer_available(pkt, 4) /* if there is space for it */) {
|
||||
if (padding_option && edns->padding_block_size ) {
|
||||
size_t pad_pos = sldns_buffer_position(pkt);
|
||||
size_t msg_sz = ((pad_pos + 3) / edns->padding_block_size + 1)
|
||||
* edns->padding_block_size;
|
||||
@@ -1027,7 +1017,7 @@ reply_info_answer_encode(struct query_info* qinf, struct reply_info* rep,
|
||||
{
|
||||
uint16_t flags;
|
||||
unsigned int attach_edns = 0;
|
||||
size_t edns_field_size, ede_size, ede_txt_size;
|
||||
uint16_t edns_field_size, ede_size, ede_txt_size;
|
||||
|
||||
if(!cached || rep->authoritative) {
|
||||
/* original flags, copy RD and CD bits from query. */
|
||||
@@ -1054,12 +1044,12 @@ reply_info_answer_encode(struct query_info* qinf, struct reply_info* rep,
|
||||
* calculate sizes once here */
|
||||
edns_field_size = calc_edns_field_size(edns);
|
||||
ede_size = calc_ede_option_size(edns, &ede_txt_size);
|
||||
if(sldns_buffer_capacity(pkt) < (size_t)udpsize)
|
||||
if(sldns_buffer_capacity(pkt) < udpsize)
|
||||
udpsize = sldns_buffer_capacity(pkt);
|
||||
if(!edns || !edns->edns_present) {
|
||||
attach_edns = 0;
|
||||
/* EDEs are optional, try to fit anything else before them */
|
||||
} else if((size_t)udpsize < (size_t)LDNS_HEADER_SIZE + edns_field_size - ede_size) {
|
||||
} else if(udpsize < LDNS_HEADER_SIZE + edns_field_size - ede_size) {
|
||||
/* packet too small to contain edns, omit it. */
|
||||
attach_edns = 0;
|
||||
} else {
|
||||
@@ -1073,13 +1063,13 @@ reply_info_answer_encode(struct query_info* qinf, struct reply_info* rep,
|
||||
return 0;
|
||||
}
|
||||
if(attach_edns) {
|
||||
if((size_t)udpsize >= sldns_buffer_limit(pkt) + edns_field_size)
|
||||
if(udpsize >= sldns_buffer_limit(pkt) + edns_field_size)
|
||||
attach_edns_record_max_msg_sz(pkt, edns, udpsize);
|
||||
else if((size_t)udpsize >= sldns_buffer_limit(pkt) + edns_field_size - ede_txt_size) {
|
||||
else if(udpsize >= sldns_buffer_limit(pkt) + edns_field_size - ede_txt_size) {
|
||||
ede_trim_text(&edns->opt_list_inplace_cb_out);
|
||||
ede_trim_text(&edns->opt_list_out);
|
||||
attach_edns_record_max_msg_sz(pkt, edns, udpsize);
|
||||
} else if((size_t)udpsize >= sldns_buffer_limit(pkt) + edns_field_size - ede_size) {
|
||||
} else if(udpsize >= sldns_buffer_limit(pkt) + edns_field_size - ede_size) {
|
||||
edns_opt_list_remove(&edns->opt_list_inplace_cb_out, LDNS_EDNS_EDE);
|
||||
edns_opt_list_remove(&edns->opt_list_out, LDNS_EDNS_EDE);
|
||||
attach_edns_record_max_msg_sz(pkt, edns, udpsize);
|
||||
@@ -1142,7 +1132,7 @@ extended_error_encode(sldns_buffer* buf, uint16_t rcode,
|
||||
}
|
||||
sldns_buffer_flip(buf);
|
||||
if(edns && edns->edns_present) {
|
||||
size_t edns_field_size, ede_size, ede_txt_size;
|
||||
uint16_t edns_field_size, ede_size, ede_txt_size;
|
||||
struct edns_data es = *edns;
|
||||
es.edns_version = EDNS_ADVERTISED_VERSION;
|
||||
es.udp_size = EDNS_ADVERTISED_SIZE;
|
||||
@@ -1154,13 +1144,13 @@ extended_error_encode(sldns_buffer* buf, uint16_t rcode,
|
||||
* to see if EDNS can fit. */
|
||||
edns_field_size = calc_edns_field_size(&es);
|
||||
ede_size = calc_ede_option_size(&es, &ede_txt_size);
|
||||
if((size_t)edns->udp_size >= sldns_buffer_limit(buf) + edns_field_size)
|
||||
if(edns->udp_size >= sldns_buffer_limit(buf) + edns_field_size)
|
||||
attach_edns_record_max_msg_sz(buf, &es, edns->udp_size);
|
||||
else if((size_t)edns->udp_size >= sldns_buffer_limit(buf) + edns_field_size - ede_txt_size) {
|
||||
else if(edns->udp_size >= sldns_buffer_limit(buf) + edns_field_size - ede_txt_size) {
|
||||
ede_trim_text(&es.opt_list_inplace_cb_out);
|
||||
ede_trim_text(&es.opt_list_out);
|
||||
attach_edns_record_max_msg_sz(buf, &es, edns->udp_size);
|
||||
} else if((size_t)edns->udp_size >= sldns_buffer_limit(buf) + edns_field_size - ede_size) {
|
||||
} else if(edns->udp_size >= sldns_buffer_limit(buf) + edns_field_size - ede_size) {
|
||||
edns_opt_list_remove(&es.opt_list_inplace_cb_out, LDNS_EDNS_EDE);
|
||||
edns_opt_list_remove(&es.opt_list_out, LDNS_EDNS_EDE);
|
||||
attach_edns_record_max_msg_sz(buf, &es, edns->udp_size);
|
||||
|
||||
@@ -106,7 +106,7 @@ void qinfo_query_encode(struct sldns_buffer* pkt, struct query_info* qinfo);
|
||||
* @param edns: edns data or NULL.
|
||||
* @return octets to reserve for EDNS.
|
||||
*/
|
||||
size_t calc_edns_field_size(struct edns_data* edns);
|
||||
uint16_t calc_edns_field_size(struct edns_data* edns);
|
||||
|
||||
/**
|
||||
* Calculate the size of a specific EDNS option in packet.
|
||||
@@ -127,7 +127,7 @@ uint16_t calc_edns_option_size(struct edns_data* edns, uint16_t code);
|
||||
* extra text.
|
||||
* @return octets the option will take up.
|
||||
*/
|
||||
uint16_t calc_ede_option_size(struct edns_data* edns, size_t* txt_size);
|
||||
uint16_t calc_ede_option_size(struct edns_data* edns, uint16_t* txt_size);
|
||||
|
||||
/**
|
||||
* Attach EDNS record to buffer. Buffer has complete packet. There must
|
||||
|
||||
+8
-20
@@ -53,8 +53,6 @@
|
||||
#include "sldns/parseutil.h"
|
||||
#include "sldns/wire2str.h"
|
||||
|
||||
#define MAX_PARSED_EDNS_OPTIONS 100
|
||||
|
||||
/** smart comparison of (compressed, valid) dnames from packet */
|
||||
static int
|
||||
smart_compare(sldns_buffer* pkt, uint8_t* dnow,
|
||||
@@ -687,9 +685,6 @@ calc_size(sldns_buffer* pkt, uint16_t type, struct rr_parse* rr)
|
||||
}
|
||||
rdf++;
|
||||
}
|
||||
/* rdata ended before all _dname_count names were seen */
|
||||
if(count != 0)
|
||||
return 0; /* the rdata is too short. */
|
||||
}
|
||||
/* remaining rdata */
|
||||
rr->size += pkt_len;
|
||||
@@ -955,7 +950,6 @@ parse_edns_options_from_query(uint8_t* rdata_ptr, size_t rdata_len,
|
||||
struct comm_reply* repinfo, uint32_t now, struct regional* region,
|
||||
struct cookie_secrets* cookie_secrets)
|
||||
{
|
||||
int i = 0, nsid_seen = 0, cookie_seen = 0, padding_seen = 0;
|
||||
/* To respond with a Keepalive option, the client connection must have
|
||||
* received one message with a TCP Keepalive EDNS option, and that
|
||||
* option must have 0 length data. Subsequent messages sent on that
|
||||
@@ -975,7 +969,7 @@ parse_edns_options_from_query(uint8_t* rdata_ptr, size_t rdata_len,
|
||||
|
||||
/* while still more options, and have code+len to read */
|
||||
/* ignores partial content (i.e. rdata len 3) */
|
||||
while(rdata_len >= 4 && i < MAX_PARSED_EDNS_OPTIONS) {
|
||||
while(rdata_len >= 4) {
|
||||
uint16_t opt_code = sldns_read_uint16(rdata_ptr);
|
||||
uint16_t opt_len = sldns_read_uint16(rdata_ptr+2);
|
||||
uint8_t server_cookie[40];
|
||||
@@ -990,9 +984,8 @@ parse_edns_options_from_query(uint8_t* rdata_ptr, size_t rdata_len,
|
||||
/* handle parse time edns options here */
|
||||
switch(opt_code) {
|
||||
case LDNS_EDNS_NSID:
|
||||
if (!cfg || !cfg->nsid || nsid_seen)
|
||||
if (!cfg || !cfg->nsid)
|
||||
break;
|
||||
nsid_seen = 1;
|
||||
if(!edns_opt_list_append(&edns->opt_list_out,
|
||||
LDNS_EDNS_NSID, cfg->nsid_len,
|
||||
cfg->nsid, region)) {
|
||||
@@ -1034,9 +1027,8 @@ parse_edns_options_from_query(uint8_t* rdata_ptr, size_t rdata_len,
|
||||
|
||||
case LDNS_EDNS_PADDING:
|
||||
if(!cfg || !cfg->pad_responses ||
|
||||
!c || c->type != comm_tcp ||!c->ssl || padding_seen)
|
||||
!c || c->type != comm_tcp ||!c->ssl)
|
||||
break;
|
||||
padding_seen = 1;
|
||||
if(!edns_opt_list_append(&edns->opt_list_out,
|
||||
LDNS_EDNS_PADDING,
|
||||
0, NULL, region)) {
|
||||
@@ -1047,9 +1039,8 @@ parse_edns_options_from_query(uint8_t* rdata_ptr, size_t rdata_len,
|
||||
break;
|
||||
|
||||
case LDNS_EDNS_COOKIE:
|
||||
if(!cfg || !cfg->do_answer_cookie || !repinfo || cookie_seen)
|
||||
if(!cfg || !cfg->do_answer_cookie || !repinfo)
|
||||
break;
|
||||
cookie_seen = 1;
|
||||
if(opt_len != 8 && (opt_len < 16 || opt_len > 40)) {
|
||||
verbose(VERB_ALGO, "worker request: "
|
||||
"badly formatted cookie");
|
||||
@@ -1071,13 +1062,13 @@ parse_edns_options_from_query(uint8_t* rdata_ptr, size_t rdata_len,
|
||||
* purposes. It will be overwritten if (re)creation
|
||||
* is needed.
|
||||
*/
|
||||
if(repinfo->client_addr.ss_family == AF_INET) {
|
||||
if(repinfo->remote_addr.ss_family == AF_INET) {
|
||||
memcpy(server_cookie + 16,
|
||||
&((struct sockaddr_in*)&repinfo->client_addr)->sin_addr, 4);
|
||||
&((struct sockaddr_in*)&repinfo->remote_addr)->sin_addr, 4);
|
||||
} else {
|
||||
cookie_is_v4 = 0;
|
||||
memcpy(server_cookie + 16,
|
||||
&((struct sockaddr_in6*)&repinfo->client_addr)->sin6_addr, 16);
|
||||
&((struct sockaddr_in6*)&repinfo->remote_addr)->sin6_addr, 16);
|
||||
}
|
||||
|
||||
if(cfg->cookie_secret_file &&
|
||||
@@ -1155,7 +1146,6 @@ parse_edns_options_from_query(uint8_t* rdata_ptr, size_t rdata_len,
|
||||
}
|
||||
rdata_ptr += opt_len;
|
||||
rdata_len -= opt_len;
|
||||
i++;
|
||||
}
|
||||
return LDNS_RCODE_NOERROR;
|
||||
}
|
||||
@@ -1170,7 +1160,6 @@ parse_extract_edns_from_response_msg(struct msg_parse* msg,
|
||||
struct rrset_parse* found_prev = 0;
|
||||
size_t rdata_len;
|
||||
uint8_t* rdata_ptr;
|
||||
int i = 0;
|
||||
/* since the class encodes the UDP size, we cannot use hash table to
|
||||
* find the EDNS OPT record. Scan the packet. */
|
||||
while(rrset) {
|
||||
@@ -1230,7 +1219,7 @@ parse_extract_edns_from_response_msg(struct msg_parse* msg,
|
||||
|
||||
/* while still more options, and have code+len to read */
|
||||
/* ignores partial content (i.e. rdata len 3) */
|
||||
while(rdata_len >= 4 && i < MAX_PARSED_EDNS_OPTIONS) {
|
||||
while(rdata_len >= 4) {
|
||||
uint16_t opt_code = sldns_read_uint16(rdata_ptr);
|
||||
uint16_t opt_len = sldns_read_uint16(rdata_ptr+2);
|
||||
rdata_ptr += 4;
|
||||
@@ -1245,7 +1234,6 @@ parse_extract_edns_from_response_msg(struct msg_parse* msg,
|
||||
}
|
||||
rdata_ptr += opt_len;
|
||||
rdata_len -= opt_len;
|
||||
i++;
|
||||
}
|
||||
/* ignore rrsigs */
|
||||
return LDNS_RCODE_NOERROR;
|
||||
|
||||
+10
-10
@@ -261,25 +261,25 @@ rdata_copy(sldns_buffer* pkt, struct packed_rrset_data* data, uint8_t* to,
|
||||
if(ttl > soa_find_minttl(rr)) ttl = soa_find_minttl(rr);
|
||||
if(!SERVE_ORIGINAL_TTL) {
|
||||
/* If MIN_NEG_TTL is configured skip setting MIN_TTL */
|
||||
if(MIN_NEG_TTL <= 0 && ttl < (uint32_t)MIN_TTL) {
|
||||
ttl = (uint32_t)MIN_TTL;
|
||||
if(MIN_NEG_TTL <= 0 && ttl < MIN_TTL) {
|
||||
ttl = MIN_TTL;
|
||||
}
|
||||
if(ttl > (uint32_t)MAX_TTL) ttl = (uint32_t)MAX_TTL;
|
||||
if(ttl > MAX_TTL) ttl = MAX_TTL;
|
||||
}
|
||||
/* MAX_NEG_TTL overrides the min and max ttl of everything
|
||||
* else; it is for a more specific record */
|
||||
if(ttl > (uint32_t)MAX_NEG_TTL) ttl = (uint32_t)MAX_NEG_TTL;
|
||||
if(ttl > MAX_NEG_TTL) ttl = MAX_NEG_TTL;
|
||||
/* MIN_NEG_TTL overrides the min and max ttl of everything
|
||||
* else if configured; it is for a more specific record */
|
||||
if(MIN_NEG_TTL > 0 && ttl < (uint32_t)MIN_NEG_TTL) {
|
||||
ttl = (uint32_t)MIN_NEG_TTL;
|
||||
if(MIN_NEG_TTL > 0 && ttl < MIN_NEG_TTL) {
|
||||
ttl = MIN_NEG_TTL;
|
||||
}
|
||||
} else if(!SERVE_ORIGINAL_TTL) {
|
||||
if(ttl < (uint32_t)MIN_TTL) ttl = (uint32_t)MIN_TTL;
|
||||
if(ttl > (uint32_t)MAX_TTL) ttl = (uint32_t)MAX_TTL;
|
||||
if(ttl < MIN_TTL) ttl = MIN_TTL;
|
||||
if(ttl > MAX_TTL) ttl = MAX_TTL;
|
||||
}
|
||||
if((time_t)ttl < data->ttl)
|
||||
data->ttl = (time_t)ttl;
|
||||
if(ttl < data->ttl)
|
||||
data->ttl = ttl;
|
||||
/* We have concluded the TTL checks */
|
||||
*rr_ttl = (time_t)ttl;
|
||||
|
||||
|
||||
@@ -198,7 +198,6 @@ get_cname_target(struct ub_packed_rrset_key* rrset, uint8_t** dname,
|
||||
{
|
||||
struct packed_rrset_data* d;
|
||||
size_t len;
|
||||
if(!rrset) return;
|
||||
if(ntohs(rrset->rk.type) != LDNS_RR_TYPE_CNAME &&
|
||||
ntohs(rrset->rk.type) != LDNS_RR_TYPE_DNAME)
|
||||
return;
|
||||
|
||||
@@ -610,7 +610,6 @@ int
|
||||
fptr_whitelist_alloc_cleanup(void (*fptr)(void*))
|
||||
{
|
||||
if(fptr == &worker_alloc_cleanup) return 1;
|
||||
else if(fptr == &libworker_alloc_cleanup) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -4171,7 +4171,6 @@
|
||||
5313,
|
||||
5314,
|
||||
5315,
|
||||
5319,
|
||||
5343,
|
||||
5344,
|
||||
5349,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user