MFV r367082:

Update unbound 1.11.0 --> 1.12.0.

MFC after:	1 month.
This commit is contained in:
Cy Schubert 2020-10-27 23:03:15 +00:00
commit c0caa2e24e
72 changed files with 3316 additions and 1506 deletions

View File

@ -231,6 +231,10 @@ STREAMTCP_SRC=testcode/streamtcp.c
STREAMTCP_OBJ=streamtcp.lo
STREAMTCP_OBJ_LINK=$(STREAMTCP_OBJ) worker_cb.lo $(COMMON_OBJ) $(COMPAT_OBJ) \
$(SLDNS_OBJ)
DOHCLIENT_SRC=testcode/dohclient.c
DOHCLIENT_OBJ=dohclient.lo
DOHCLIENT_OBJ_LINK=$(DOHCLIENT_OBJ) worker_cb.lo $(COMMON_OBJ) $(COMPAT_OBJ) \
$(SLDNS_OBJ)
PERF_SRC=testcode/perf.c
PERF_OBJ=perf.lo
PERF_OBJ_LINK=$(PERF_OBJ) worker_cb.lo $(COMMON_OBJ) $(COMPAT_OBJ) $(SLDNS_OBJ)
@ -272,7 +276,8 @@ ALL_SRC=$(COMMON_SRC) $(UNITTEST_SRC) $(DAEMON_SRC) \
$(ASYNCLOOK_SRC) $(STREAMTCP_SRC) $(PERF_SRC) $(DELAYER_SRC) \
$(CONTROL_SRC) $(UBANCHOR_SRC) $(PETAL_SRC) $(DNSTAP_SOCKET_SRC)\
$(PYTHONMOD_SRC) $(PYUNBOUND_SRC) $(WIN_DAEMON_THE_SRC) \
$(SVCINST_SRC) $(SVCUNINST_SRC) $(ANCHORUPD_SRC) $(SLDNS_SRC)
$(SVCINST_SRC) $(SVCUNINST_SRC) $(ANCHORUPD_SRC) $(SLDNS_SRC) \
$(DOHCLIENT_SRC)
ALL_OBJ=$(COMMON_OBJ) $(UNITTEST_OBJ) $(DAEMON_OBJ) \
$(TESTBOUND_OBJ) $(LOCKVERIFY_OBJ) $(PKTVIEW_OBJ) \
@ -280,7 +285,8 @@ ALL_OBJ=$(COMMON_OBJ) $(UNITTEST_OBJ) $(DAEMON_OBJ) \
$(ASYNCLOOK_OBJ) $(STREAMTCP_OBJ) $(PERF_OBJ) $(DELAYER_OBJ) \
$(CONTROL_OBJ) $(UBANCHOR_OBJ) $(PETAL_OBJ) $(DNSTAP_SOCKET_OBJ)\
$(COMPAT_OBJ) $(PYUNBOUND_OBJ) \
$(SVCINST_OBJ) $(SVCUNINST_OBJ) $(ANCHORUPD_OBJ) $(SLDNS_OBJ)
$(SVCINST_OBJ) $(SVCUNINST_OBJ) $(ANCHORUPD_OBJ) $(SLDNS_OBJ) \
$(DOHCLIENT_OBJ)
COMPILE=$(LIBTOOL) --tag=CC --mode=compile $(CC) $(CPPFLAGS) $(CFLAGS) @PTHREAD_CFLAGS_ONLY@
LINK=$(LIBTOOL) --tag=CC --mode=link $(CC) $(staticexe) $(RUNTIME_PATH) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS)
@ -317,7 +323,7 @@ rsrc_unbound_checkconf.o: $(srcdir)/winrc/rsrc_unbound_checkconf.rc config.h
TEST_BIN=asynclook$(EXEEXT) delayer$(EXEEXT) \
lock-verify$(EXEEXT) memstats$(EXEEXT) perf$(EXEEXT) \
petal$(EXEEXT) pktview$(EXEEXT) streamtcp$(EXEEXT) \
unbound-dnstap-socket$(EXEEXT) \
unbound-dnstap-socket$(EXEEXT) dohclient$(EXEEXT) \
testbound$(EXEEXT) unittest$(EXEEXT)
tests: all $(TEST_BIN)
@ -387,6 +393,9 @@ asynclook$(EXEEXT): $(ASYNCLOOK_OBJ_LINK) libunbound.la
streamtcp$(EXEEXT): $(STREAMTCP_OBJ_LINK)
$(LINK) -o $@ $(STREAMTCP_OBJ_LINK) $(SSLLIB) $(LIBS) $(DYNLIBMOD_EXTRALIBS)
dohclient$(EXEEXT): $(DOHCLIENT_OBJ_LINK)
$(LINK) -o $@ $(DOHCLIENT_OBJ_LINK) $(SSLLIB) $(LIBS) $(DYNLIBMOD_EXTRALIBS)
perf$(EXEEXT): $(PERF_OBJ_LINK)
$(LINK) -o $@ $(PERF_OBJ_LINK) $(SSLLIB) $(LIBS) $(DYNLIBMOD_EXTRALIBS)
@ -672,7 +681,7 @@ dns.lo dns.o: $(srcdir)/services/cache/dns.c config.h $(srcdir)/iterator/iter_de
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
$(srcdir)/validator/val_utils.h $(srcdir)/sldns/pkthdr.h $(srcdir)/services/cache/dns.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \
$(srcdir)/util/data/dname.h $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/rrdef.h \
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/dname.h $(srcdir)/util/module.h \
$(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/sldns/sbuffer.h
infra.lo infra.o: $(srcdir)/services/cache/infra.c config.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/str2wire.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h $(srcdir)/services/cache/infra.h \
@ -713,10 +722,11 @@ msgreply.lo msgreply.o: $(srcdir)/util/data/msgreply.c config.h $(srcdir)/util/d
$(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/util/config_file.h \
$(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \
$(srcdir)/respip/respip.h
packed_rrset.lo packed_rrset.o: $(srcdir)/util/data/packed_rrset.c config.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/util/data/dname.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/alloc.h $(srcdir)/util/regional.h \
$(srcdir)/util/net_help.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h
packed_rrset.lo packed_rrset.o: $(srcdir)/util/data/packed_rrset.c config.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/dname.h \
$(srcdir)/util/storage/lookup3.h $(srcdir)/util/alloc.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h
iterator.lo iterator.o: $(srcdir)/iterator/iterator.c config.h $(srcdir)/iterator/iterator.h \
$(srcdir)/services/outbound_list.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/module.h \
@ -785,7 +795,7 @@ listen_dnsport.lo listen_dnsport.o: $(srcdir)/services/listen_dnsport.c config.h
$(srcdir)/services/listen_dnsport.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/services/outside_network.h $(srcdir)/util/rbtree.h \
$(srcdir)/util/log.h $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/services/mesh.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/parseutil.h $(srcdir)/services/mesh.h $(srcdir)/util/data/msgparse.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
$(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
$(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
@ -808,10 +818,10 @@ mesh.lo mesh.o: $(srcdir)/services/mesh.c config.h $(srcdir)/services/mesh.h $(s
$(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h \
$(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h \
$(srcdir)/services/outbound_list.h $(srcdir)/services/cache/dns.h $(srcdir)/util/net_help.h \
$(srcdir)/util/regional.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h \
$(srcdir)/util/alloc.h $(srcdir)/util/edns.h $(srcdir)/sldns/wire2str.h $(srcdir)/util/data/dname.h \
$(srcdir)/services/listen_dnsport.h
$(srcdir)/services/outbound_list.h $(srcdir)/services/cache/dns.h $(srcdir)/services/cache/rrset.h \
$(srcdir)/util/storage/slabhash.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h \
$(srcdir)/util/data/msgencode.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/alloc.h \
$(srcdir)/util/edns.h $(srcdir)/sldns/wire2str.h $(srcdir)/util/data/dname.h $(srcdir)/services/listen_dnsport.h
modstack.lo modstack.o: $(srcdir)/services/modstack.c config.h $(srcdir)/services/modstack.h \
$(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
@ -1204,7 +1214,8 @@ testpkts.lo testpkts.o: $(srcdir)/testcode/testpkts.c config.h $(srcdir)/testcod
$(srcdir)/util/net_help.h $(srcdir)/util/log.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/pkthdr.h \
$(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h
unitldns.lo unitldns.o: $(srcdir)/testcode/unitldns.c config.h $(srcdir)/util/log.h $(srcdir)/testcode/unitmain.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/wire2str.h
$(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/wire2str.h \
$(srcdir)/sldns/parseutil.h
unitecs.lo unitecs.o: $(srcdir)/testcode/unitecs.c config.h
unitauth.lo unitauth.o: $(srcdir)/testcode/unitauth.c config.h $(srcdir)/services/authzone.h \
$(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/services/mesh.h $(srcdir)/util/netevent.h \
@ -1310,7 +1321,8 @@ worker.lo worker.o: $(srcdir)/daemon/worker.c config.h $(srcdir)/util/log.h $(sr
$(srcdir)/util/data/dname.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/edns.h \
$(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h $(srcdir)/validator/autotrust.h \
$(srcdir)/validator/val_anchor.h $(srcdir)/libunbound/context.h $(srcdir)/libunbound/unbound-event.h \
$(srcdir)/libunbound/libworker.h $(srcdir)/sldns/wire2str.h $(srcdir)/util/shm_side/shm_main.h
$(srcdir)/libunbound/libworker.h $(srcdir)/sldns/wire2str.h $(srcdir)/util/shm_side/shm_main.h \
$(srcdir)/dnstap/dtstream.h
testbound.lo testbound.o: $(srcdir)/testcode/testbound.c config.h $(srcdir)/testcode/testpkts.h \
$(srcdir)/testcode/replay.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/util/rbtree.h $(srcdir)/testcode/fake_event.h \
@ -1344,7 +1356,8 @@ worker.lo worker.o: $(srcdir)/daemon/worker.c config.h $(srcdir)/util/log.h $(sr
$(srcdir)/util/data/dname.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/edns.h \
$(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h $(srcdir)/validator/autotrust.h \
$(srcdir)/validator/val_anchor.h $(srcdir)/libunbound/context.h $(srcdir)/libunbound/unbound-event.h \
$(srcdir)/libunbound/libworker.h $(srcdir)/sldns/wire2str.h $(srcdir)/util/shm_side/shm_main.h
$(srcdir)/libunbound/libworker.h $(srcdir)/sldns/wire2str.h $(srcdir)/util/shm_side/shm_main.h \
$(srcdir)/dnstap/dtstream.h
acl_list.lo acl_list.o: $(srcdir)/daemon/acl_list.c config.h $(srcdir)/daemon/acl_list.h \
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h $(srcdir)/util/locks.h \
$(srcdir)/util/log.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h \
@ -1507,6 +1520,12 @@ unbound-control.lo unbound-control.o: $(srcdir)/smallapp/unbound-control.c confi
unbound-anchor.lo unbound-anchor.o: $(srcdir)/smallapp/unbound-anchor.c config.h $(srcdir)/libunbound/unbound.h \
$(srcdir)/sldns/rrdef.h $(srcdir)/sldns/parseutil.h
petal.lo petal.o: $(srcdir)/testcode/petal.c config.h
unbound-dnstap-socket.lo unbound-dnstap-socket.o: $(srcdir)/dnstap/unbound-dnstap-socket.c config.h \
$(srcdir)/dnstap/dtstream.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/dnstap/dnstap_fstrm.h \
$(srcdir)/util/ub_event.h $(srcdir)/util/net_help.h $(srcdir)/services/listen_dnsport.h \
$(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h $(srcdir)/util/config_file.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h
pythonmod_utils.lo pythonmod_utils.o: $(srcdir)/pythonmod/pythonmod_utils.c config.h $(srcdir)/util/module.h \
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/msgreply.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
@ -1542,6 +1561,10 @@ parseutil.lo parseutil.o: $(srcdir)/sldns/parseutil.c config.h $(srcdir)/sldns/p
rrdef.lo rrdef.o: $(srcdir)/sldns/rrdef.c config.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/parseutil.h
str2wire.lo str2wire.o: $(srcdir)/sldns/str2wire.c config.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h \
$(srcdir)/sldns/wire2str.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/parse.h $(srcdir)/sldns/parseutil.h
dohclient.lo dohclient.o: $(srcdir)/testcode/dohclient.c config.h $(srcdir)/sldns/wire2str.h \
$(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgencode.h \
$(srcdir)/util/data/msgreply.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/net_help.h
ctime_r.lo ctime_r.o: $(srcdir)/compat/ctime_r.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h
fake-rfc2553.lo fake-rfc2553.o: $(srcdir)/compat/fake-rfc2553.c $(srcdir)/compat/fake-rfc2553.h config.h
gmtime_r.lo gmtime_r.o: $(srcdir)/compat/gmtime_r.c config.h

View File

@ -9,7 +9,7 @@ fast and lean and incorporates modern features based on open standards. If you
have any feedback, we would love to hear from you. Dont hesitate to
[create an issue on Github](https://github.com/NLnetLabs/unbound/issues/new)
or post a message on the [Unbound mailing list](https://lists.nlnetlabs.nl/mailman/listinfo/unbound-users).
You can lean more about Unbound by reading our
You can learn more about Unbound by reading our
[documentation](https://nlnetlabs.nl/documentation/unbound/).
## Compiling

View File

@ -2,7 +2,8 @@
# Copyright 2009, Wouter Wijngaards, NLnet Labs.
# BSD licensed.
#
# Version 34
# Version 35
# 2020-08-24 Use EVP_sha256 instead of HMAC_Update (for openssl-3.0.0).
# 2016-03-21 Check -ldl -pthread for libcrypto for ldns and openssl 1.1.0.
# 2016-03-21 Use HMAC_Update instead of HMAC_CTX_Init (for openssl-1.1.0).
# 2016-01-04 -D_DEFAULT_SOURCE defined with -D_BSD_SOURCE for Linux glibc 2.20
@ -673,16 +674,16 @@ AC_DEFUN([ACX_SSL_CHECKS], [
ACX_RUNTIME_PATH_ADD([$ssldir/lib])
fi
AC_MSG_CHECKING([for HMAC_Update in -lcrypto])
AC_MSG_CHECKING([for EVP_sha256 in -lcrypto])
LIBS="$LIBS -lcrypto"
LIBSSL_LIBS="$LIBSSL_LIBS -lcrypto"
AC_TRY_LINK(, [
int HMAC_Update(void);
(void)HMAC_Update();
int EVP_sha256(void);
(void)EVP_sha256();
], [
AC_MSG_RESULT(yes)
AC_DEFINE([HAVE_HMAC_UPDATE], 1,
[If you have HMAC_Update])
AC_DEFINE([HAVE_EVP_SHA256], 1,
[If you have EVP_sha256])
], [
AC_MSG_RESULT(no)
# check if -lwsock32 or -lgdi32 are needed.
@ -692,11 +693,11 @@ AC_DEFUN([ACX_SSL_CHECKS], [
LIBSSL_LIBS="$LIBSSL_LIBS -lgdi32 -lws2_32"
AC_MSG_CHECKING([if -lcrypto needs -lgdi32])
AC_TRY_LINK([], [
int HMAC_Update(void);
(void)HMAC_Update();
int EVP_sha256(void);
(void)EVP_sha256();
],[
AC_DEFINE([HAVE_HMAC_UPDATE], 1,
[If you have HMAC_Update])
AC_DEFINE([HAVE_EVP_SHA256], 1,
[If you have EVP_sha256])
AC_MSG_RESULT(yes)
],[
AC_MSG_RESULT(no)
@ -706,11 +707,11 @@ AC_DEFUN([ACX_SSL_CHECKS], [
LIBSSL_LIBS="$LIBSSL_LIBS -ldl"
AC_MSG_CHECKING([if -lcrypto needs -ldl])
AC_TRY_LINK([], [
int HMAC_Update(void);
(void)HMAC_Update();
int EVP_sha256(void);
(void)EVP_sha256();
],[
AC_DEFINE([HAVE_HMAC_UPDATE], 1,
[If you have HMAC_Update])
AC_DEFINE([HAVE_EVP_SHA256], 1,
[If you have EVP_sha256])
AC_MSG_RESULT(yes)
],[
AC_MSG_RESULT(no)
@ -720,11 +721,11 @@ AC_DEFUN([ACX_SSL_CHECKS], [
LIBSSL_LIBS="$LIBSSL_LIBS -ldl -pthread"
AC_MSG_CHECKING([if -lcrypto needs -ldl -pthread])
AC_TRY_LINK([], [
int HMAC_Update(void);
(void)HMAC_Update();
int EVP_sha256(void);
(void)EVP_sha256();
],[
AC_DEFINE([HAVE_HMAC_UPDATE], 1,
[If you have HMAC_Update])
AC_DEFINE([HAVE_EVP_SHA256], 1,
[If you have EVP_sha256])
AC_MSG_RESULT(yes)
],[
AC_MSG_RESULT(no)

View File

@ -2,7 +2,7 @@
# Attempt to guess a canonical system name.
# Copyright 1992-2020 Free Software Foundation, Inc.
timestamp='2020-07-12'
timestamp='2020-09-19'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@ -150,17 +150,15 @@ Linux|GNU|GNU/*)
#elif defined(__dietlibc__)
LIBC=dietlibc
#else
#include <stdarg.h>
#ifdef __DEFINED_va_list
LIBC=musl
#else
LIBC=gnu
#endif
#endif
EOF
eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`"
# If ldd exists, use it to detect musl libc.
if command -v ldd >/dev/null && \
ldd --version 2>&1 | grep -q ^musl
then
LIBC=musl
fi
;;
esac
@ -404,7 +402,7 @@ case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
# If there is a compiler, see if it is configured for 64-bit objects.
# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
# This test works for both compilers.
if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
if test "$CC_FOR_BUILD" != no_compiler_found; then
if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
(CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
grep IS_64BIT_ARCH >/dev/null
@ -544,10 +542,10 @@ EOF
AViiON:dgux:*:*)
# DG/UX returns AViiON for all architectures
UNAME_PROCESSOR=`/usr/bin/uname -p`
if [ "$UNAME_PROCESSOR" = mc88100 ] || [ "$UNAME_PROCESSOR" = mc88110 ]
if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110
then
if [ "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx ] || \
[ "$TARGET_BINARY_INTERFACE"x = x ]
if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \
test "$TARGET_BINARY_INTERFACE"x = x
then
echo m88k-dg-dgux"$UNAME_RELEASE"
else
@ -580,7 +578,7 @@ EOF
echo i386-ibm-aix
exit ;;
ia64:AIX:*:*)
if [ -x /usr/bin/oslevel ] ; then
if test -x /usr/bin/oslevel ; then
IBM_REV=`/usr/bin/oslevel`
else
IBM_REV="$UNAME_VERSION.$UNAME_RELEASE"
@ -620,7 +618,7 @@ EOF
else
IBM_ARCH=powerpc
fi
if [ -x /usr/bin/lslpp ] ; then
if test -x /usr/bin/lslpp ; then
IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
else
@ -655,7 +653,7 @@ EOF
9000/31?) HP_ARCH=m68000 ;;
9000/[34]??) HP_ARCH=m68k ;;
9000/[678][0-9][0-9])
if [ -x /usr/bin/getconf ]; then
if test -x /usr/bin/getconf; then
sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
case "$sc_cpu_version" in
@ -669,7 +667,7 @@ EOF
esac ;;
esac
fi
if [ "$HP_ARCH" = "" ]; then
if test "$HP_ARCH" = ""; then
set_cc_for_build
sed 's/^ //' << EOF > "$dummy.c"
@ -708,7 +706,7 @@ EOF
test -z "$HP_ARCH" && HP_ARCH=hppa
fi ;;
esac
if [ "$HP_ARCH" = hppa2.0w ]
if test "$HP_ARCH" = hppa2.0w
then
set_cc_for_build
@ -782,7 +780,7 @@ EOF
echo hppa1.0-hp-osf
exit ;;
i*86:OSF1:*:*)
if [ -x /usr/sbin/sysversion ] ; then
if test -x /usr/sbin/sysversion ; then
echo "$UNAME_MACHINE"-unknown-osf1mk
else
echo "$UNAME_MACHINE"-unknown-osf1
@ -1097,7 +1095,7 @@ EOF
x86_64:Linux:*:*)
set_cc_for_build
LIBCABI=$LIBC
if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
if test "$CC_FOR_BUILD" != no_compiler_found; then
if (echo '#ifdef __ILP32__'; echo IS_X32; echo '#endif') | \
(CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
grep IS_X32 >/dev/null
@ -1294,7 +1292,7 @@ EOF
echo mips-sony-newsos6
exit ;;
R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
if [ -d /usr/nec ]; then
if test -d /usr/nec; then
echo mips-nec-sysv"$UNAME_RELEASE"
else
echo mips-unknown-sysv"$UNAME_RELEASE"
@ -1359,7 +1357,7 @@ EOF
else
set_cc_for_build
fi
if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
if test "$CC_FOR_BUILD" != no_compiler_found; then
if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
(CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
grep IS_64BIT_ARCH >/dev/null

View File

@ -113,6 +113,10 @@
don't. */
#undef HAVE_DECL_INET_PTON
/* Define to 1 if you have the declaration of `nghttp2_session_server_new',
and to 0 if you don't. */
#undef HAVE_DECL_NGHTTP2_SESSION_SERVER_NEW
/* Define to 1 if you have the declaration of `NID_ED25519', and to 0 if you
don't. */
#undef HAVE_DECL_NID_ED25519
@ -221,6 +225,9 @@
/* Define to 1 if you have the `EVP_EncryptInit_ex' function. */
#undef HAVE_EVP_ENCRYPTINIT_EX
/* Define to 1 if you have the `EVP_MAC_CTX_set_params' function. */
#undef HAVE_EVP_MAC_CTX_SET_PARAMS
/* Define to 1 if you have the `EVP_MD_CTX_new' function. */
#undef HAVE_EVP_MD_CTX_NEW
@ -269,6 +276,9 @@
/* Define to 1 if you have the `getentropy' function. */
#undef HAVE_GETENTROPY
/* Define to 1 if you have the `getifaddrs' function. */
#undef HAVE_GETIFADDRS
/* Define to 1 if you have the <getopt.h> header file. */
#undef HAVE_GETOPT_H
@ -296,12 +306,12 @@
/* Define to 1 if you have the `HMAC_Init_ex' function. */
#undef HAVE_HMAC_INIT_EX
/* If you have HMAC_Update */
#undef HAVE_HMAC_UPDATE
/* If we have htobe64 */
#undef HAVE_HTOBE64
/* Define to 1 if you have the <ifaddrs.h> header file. */
#undef HAVE_IFADDRS_H
/* Define to 1 if you have the `inet_aton' function. */
#undef HAVE_INET_ATON
@ -371,6 +381,15 @@
/* Define to 1 if you have the <nettle/eddsa.h> header file. */
#undef HAVE_NETTLE_EDDSA_H
/* Define to 1 if you have the <net/if.h> header file. */
#undef HAVE_NET_IF_H
/* Define this to use nghttp2 client. */
#undef HAVE_NGHTTP2
/* Define to 1 if you have the <nghttp2/nghttp2.h> header file. */
#undef HAVE_NGHTTP2_NGHTTP2_H
/* Use libnss for crypto */
#undef HAVE_NSS
@ -497,6 +516,9 @@
/* Define if you have the SSL libraries installed. */
#undef HAVE_SSL
/* Define to 1 if you have the `SSL_CTX_set_alpn_select_cb' function. */
#undef HAVE_SSL_CTX_SET_ALPN_SELECT_CB
/* Define to 1 if you have the `SSL_CTX_set_ciphersuites' function. */
#undef HAVE_SSL_CTX_SET_CIPHERSUITES
@ -573,6 +595,9 @@
/* Define to 1 if you have the <sys/resource.h> header file. */
#undef HAVE_SYS_RESOURCE_H
/* Define to 1 if you have the <sys/select.h> header file. */
#undef HAVE_SYS_SELECT_H
/* Define to 1 if you have the <sys/sha2.h> header file. */
#undef HAVE_SYS_SHA2_H
@ -1358,6 +1383,8 @@ void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
#define UNBOUND_DNS_PORT 53
/** default port for DNS over TLS traffic. */
#define UNBOUND_DNS_OVER_TLS_PORT 853
/** default port for DNS over HTTPS traffic. */
#define UNBOUND_DNS_OVER_HTTPS_PORT 443
/** default port for unbound control traffic, registered port with IANA,
ub-dns-control 8953/tcp unbound dns nameserver control */
#define UNBOUND_CONTROL_PORT 8953

View File

@ -2,7 +2,7 @@
# Configuration validation subroutine script.
# Copyright 1992-2020 Free Software Foundation, Inc.
timestamp='2020-07-10'
timestamp='2020-09-08'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@ -1278,7 +1278,7 @@ esac
# Decode manufacturer-specific aliases for certain operating systems.
if [ x$basic_os != x ]
if test x$basic_os != x
then
# First recognize some ad-hoc caes, or perhaps split kernel-os, or else just
@ -1367,13 +1367,7 @@ case $os in
os=psos
;;
qnx*)
case $cpu in
x86 | i*86)
;;
*)
os=nto-$os
;;
esac
os=qnx
;;
hiux*)
os=hiuxwe2
@ -1722,7 +1716,7 @@ case $os in
| skyos* | haiku* | rdos* | toppers* | drops* | es* \
| onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \
| midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \
| nsk* | powerunix* | genode* | zvmoe* )
| nsk* | powerunix* | genode* | zvmoe* | qnx* )
;;
# This one is extra strict with allowed versions
sco3.2v2 | sco3.2v[4-9]* | sco5v6*)
@ -1741,6 +1735,8 @@ esac
case $kernel-$os in
linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* | linux-musl* | linux-uclibc* )
;;
uclinux-uclibc* )
;;
-dietlibc* | -newlib* | -musl* | -uclibc* )
# These are just libc implementations, not actual OSes, and thus
# require a kernel.

View File

@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for unbound 1.11.0.
# Generated by GNU Autoconf 2.69 for unbound 1.12.0.
#
# Report bugs to <unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues>.
#
@ -591,8 +591,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='unbound'
PACKAGE_TARNAME='unbound'
PACKAGE_VERSION='1.11.0'
PACKAGE_STRING='unbound 1.11.0'
PACKAGE_VERSION='1.12.0'
PACKAGE_STRING='unbound 1.12.0'
PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues'
PACKAGE_URL=''
@ -882,6 +882,7 @@ enable_tfo_server
with_libevent
with_libexpat
with_libhiredis
with_libnghttp2
enable_static_exe
enable_fully_static
enable_lock_checks
@ -1458,7 +1459,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.11.0 to adapt to many kinds of systems.
\`configure' configures unbound 1.12.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1523,7 +1524,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of unbound 1.11.0:";;
short | recursive ) echo "Configuration of unbound 1.12.0:";;
esac
cat <<\_ACEOF
@ -1642,6 +1643,7 @@ Optional Packages:
outgoing port ranges.
--with-libexpat=path specify explicit path for libexpat.
--with-libhiredis=path specify explicit path for libhiredis.
--with-libnghttp2=path specify explicit path for libnghttp2.
--with-dnstap-socket-path=pathname
set default dnstap socket path
--with-protobuf-c=path Path where protobuf-c is installed, for dnstap
@ -1750,7 +1752,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
unbound configure 1.11.0
unbound configure 1.12.0
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@ -2459,7 +2461,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.11.0, which was
It was created by unbound $as_me 1.12.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@ -2809,13 +2811,13 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
UNBOUND_VERSION_MAJOR=1
UNBOUND_VERSION_MINOR=11
UNBOUND_VERSION_MINOR=12
UNBOUND_VERSION_MICRO=0
LIBUNBOUND_CURRENT=9
LIBUNBOUND_REVISION=9
LIBUNBOUND_REVISION=10
LIBUNBOUND_AGE=1
# 1.0.0 had 0:12:0
# 1.0.1 had 0:13:0
@ -2892,6 +2894,7 @@ LIBUNBOUND_AGE=1
# 1.10.0 had 9:7:1
# 1.10.1 had 9:8:1
# 1.11.0 had 9:9:1
# 1.12.0 had 9:10:1
# Current -- the number of the binary API that we're implementing
# Revision -- which iteration of the implementation of the binary
@ -14725,7 +14728,7 @@ $as_echo "no" >&6; }
fi
# Checks for header files.
for ac_header in stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/endian.h libkern/OSByteOrder.h sys/ipc.h sys/shm.h
for ac_header in stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/select.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/endian.h libkern/OSByteOrder.h sys/ipc.h sys/shm.h ifaddrs.h net/if.h
do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
@ -17942,8 +17945,8 @@ $as_echo "found in $ssldir" >&6; }
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for HMAC_Update in -lcrypto" >&5
$as_echo_n "checking for HMAC_Update in -lcrypto... " >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for EVP_sha256 in -lcrypto" >&5
$as_echo_n "checking for EVP_sha256 in -lcrypto... " >&6; }
LIBS="$LIBS -lcrypto"
LIBSSL_LIBS="$LIBSSL_LIBS -lcrypto"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@ -17953,8 +17956,8 @@ int
main ()
{
int HMAC_Update(void);
(void)HMAC_Update();
int EVP_sha256(void);
(void)EVP_sha256();
;
return 0;
@ -17965,7 +17968,7 @@ if ac_fn_c_try_link "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
$as_echo "#define HAVE_HMAC_UPDATE 1" >>confdefs.h
$as_echo "#define HAVE_EVP_SHA256 1" >>confdefs.h
else
@ -17986,8 +17989,8 @@ int
main ()
{
int HMAC_Update(void);
(void)HMAC_Update();
int EVP_sha256(void);
(void)EVP_sha256();
;
return 0;
@ -17996,7 +17999,7 @@ _ACEOF
if ac_fn_c_try_link "$LINENO"; then :
$as_echo "#define HAVE_HMAC_UPDATE 1" >>confdefs.h
$as_echo "#define HAVE_EVP_SHA256 1" >>confdefs.h
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
@ -18018,8 +18021,8 @@ int
main ()
{
int HMAC_Update(void);
(void)HMAC_Update();
int EVP_sha256(void);
(void)EVP_sha256();
;
return 0;
@ -18028,7 +18031,7 @@ _ACEOF
if ac_fn_c_try_link "$LINENO"; then :
$as_echo "#define HAVE_HMAC_UPDATE 1" >>confdefs.h
$as_echo "#define HAVE_EVP_SHA256 1" >>confdefs.h
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
@ -18050,8 +18053,8 @@ int
main ()
{
int HMAC_Update(void);
(void)HMAC_Update();
int EVP_sha256(void);
(void)EVP_sha256();
;
return 0;
@ -18060,7 +18063,7 @@ _ACEOF
if ac_fn_c_try_link "$LINENO"; then :
$as_echo "#define HAVE_HMAC_UPDATE 1" >>confdefs.h
$as_echo "#define HAVE_EVP_SHA256 1" >>confdefs.h
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
@ -18245,11 +18248,11 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
#ifdef __cplusplus
extern "C"
#endif
char HMAC_Update ();
char EVP_sha256 ();
int
main ()
{
return HMAC_Update ();
return EVP_sha256 ();
;
return 0;
}
@ -18340,7 +18343,7 @@ fi
done
for ac_func in OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ENGINE_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex CRYPTO_THREADID_set_callback
for ac_func in OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ENGINE_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex CRYPTO_THREADID_set_callback EVP_MAC_CTX_set_params
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@ -18356,7 +18359,7 @@ done
# these check_funcs need -lssl
BAKLIBS="$LIBS"
LIBS="-lssl $LIBS"
for ac_func in OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername X509_VERIFY_PARAM_set1_host SSL_CTX_set_ciphersuites SSL_CTX_set_tlsext_ticket_key_evp_cb
for ac_func in OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername X509_VERIFY_PARAM_set1_host SSL_CTX_set_ciphersuites SSL_CTX_set_tlsext_ticket_key_evp_cb SSL_CTX_set_alpn_select_cb
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@ -19668,6 +19671,70 @@ _ACEOF
fi
# nghttp2
# Check whether --with-libnghttp2 was given.
if test "${with_libnghttp2+set}" = set; then :
withval=$with_libnghttp2;
else
withval="no"
fi
found_libnghttp2="no"
if test x_$withval = x_yes -o x_$withval != x_no; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libnghttp2" >&5
$as_echo_n "checking for libnghttp2... " >&6; }
if test x_$withval = x_ -o x_$withval = x_yes; then
withval="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr"
fi
for dir in $withval ; do
if test -f "$dir/include/nghttp2/nghttp2.h"; then
found_libnghttp2="yes"
if test "$dir" != "/usr"; then
CPPFLAGS="$CPPFLAGS -I$dir/include"
LDFLAGS="$LDFLAGS -L$dir/lib"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: found in $dir" >&5
$as_echo "found in $dir" >&6; }
$as_echo "#define HAVE_NGHTTP2 1" >>confdefs.h
LIBS="$LIBS -lnghttp2"
break;
fi
done
if test x_$found_libnghttp2 != x_yes; then
as_fn_error $? "Could not find libnghttp2, nghttp2.h" "$LINENO" 5
fi
for ac_header in nghttp2/nghttp2.h
do :
ac_fn_c_check_header_compile "$LINENO" "nghttp2/nghttp2.h" "ac_cv_header_nghttp2_nghttp2_h" "$ac_includes_default
"
if test "x$ac_cv_header_nghttp2_nghttp2_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_NGHTTP2_NGHTTP2_H 1
_ACEOF
fi
done
ac_fn_c_check_decl "$LINENO" "nghttp2_session_server_new" "ac_cv_have_decl_nghttp2_session_server_new" "$ac_includes_default
#include <nghttp2/nghttp2.h>
"
if test "x$ac_cv_have_decl_nghttp2_session_server_new" = xyes; then :
ac_have_decl=1
else
ac_have_decl=0
fi
cat >>confdefs.h <<_ACEOF
#define HAVE_DECL_NGHTTP2_SESSION_SERVER_NEW $ac_have_decl
_ACEOF
fi
# set static linking for uninstalled libraries if requested
staticexe=""
@ -20223,7 +20290,7 @@ if test "$ac_res" != no; then :
fi
for ac_func in tzset sigprocmask fcntl getpwnam endpwent getrlimit setrlimit setsid chroot kill chown sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent fsync shmget accept4
for ac_func in tzset sigprocmask fcntl getpwnam endpwent getrlimit setrlimit setsid chroot kill chown sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent fsync shmget accept4 getifaddrs
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@ -21619,7 +21686,7 @@ _ACEOF
version=1.11.0
version=1.12.0
date=`date +'%b %e, %Y'`
@ -22138,7 +22205,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.11.0, which was
This file was extended by unbound $as_me 1.12.0, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@ -22204,7 +22271,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
unbound config.status 1.11.0
unbound config.status 1.12.0
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"

View File

@ -10,7 +10,7 @@ sinclude(dnscrypt/dnscrypt.m4)
# must be numbers. ac_defun because of later processing
m4_define([VERSION_MAJOR],[1])
m4_define([VERSION_MINOR],[11])
m4_define([VERSION_MINOR],[12])
m4_define([VERSION_MICRO],[0])
AC_INIT(unbound, m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]), unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues, unbound)
AC_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR])
@ -18,7 +18,7 @@ AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR])
AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO])
LIBUNBOUND_CURRENT=9
LIBUNBOUND_REVISION=9
LIBUNBOUND_REVISION=10
LIBUNBOUND_AGE=1
# 1.0.0 had 0:12:0
# 1.0.1 had 0:13:0
@ -95,6 +95,7 @@ LIBUNBOUND_AGE=1
# 1.10.0 had 9:7:1
# 1.10.1 had 9:8:1
# 1.11.0 had 9:9:1
# 1.12.0 had 9:10:1
# Current -- the number of the binary API that we're implementing
# Revision -- which iteration of the implementation of the binary
@ -398,7 +399,7 @@ ACX_LIBTOOL_C_ONLY
PKG_PROG_PKG_CONFIG
# Checks for header files.
AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/endian.h libkern/OSByteOrder.h sys/ipc.h sys/shm.h],,, [AC_INCLUDES_DEFAULT])
AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/select.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/endian.h libkern/OSByteOrder.h sys/ipc.h sys/shm.h ifaddrs.h net/if.h],,, [AC_INCLUDES_DEFAULT])
# Check for Apple header. This uncovers TARGET_OS_IPHONE, TARGET_OS_TV or TARGET_OS_WATCH
AC_CHECK_HEADERS([TargetConditionals.h])
@ -831,7 +832,7 @@ AC_SUBST(PC_CRYPTO_DEPENDENCY)
BAKLIBS="$LIBS"
LIBS="-lssl $LIBS"
AC_MSG_CHECKING([if libssl needs -lcrypt32])
AC_TRY_LINK_FUNC([HMAC_Update], [
AC_TRY_LINK_FUNC([EVP_sha256], [
AC_MSG_RESULT([no])
LIBS="$BAKLIBS"
], [
@ -851,12 +852,12 @@ else
AC_MSG_RESULT([no])
fi
AC_CHECK_HEADERS([openssl/conf.h openssl/engine.h openssl/bn.h openssl/dh.h openssl/dsa.h openssl/rsa.h openssl/core_names.h],,, [AC_INCLUDES_DEFAULT])
AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ENGINE_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex CRYPTO_THREADID_set_callback])
AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ENGINE_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex CRYPTO_THREADID_set_callback EVP_MAC_CTX_set_params])
# these check_funcs need -lssl
BAKLIBS="$LIBS"
LIBS="-lssl $LIBS"
AC_CHECK_FUNCS([OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername X509_VERIFY_PARAM_set1_host SSL_CTX_set_ciphersuites SSL_CTX_set_tlsext_ticket_key_evp_cb])
AC_CHECK_FUNCS([OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername X509_VERIFY_PARAM_set1_host SSL_CTX_set_ciphersuites SSL_CTX_set_tlsext_ticket_key_evp_cb SSL_CTX_set_alpn_select_cb])
LIBS="$BAKLIBS"
AC_CHECK_DECLS([SSL_COMP_get_compression_methods,sk_SSL_COMP_pop_free,SSL_CTX_set_ecdh_auto], [], [], [
@ -1395,6 +1396,39 @@ if test x_$withval = x_yes -o x_$withval != x_no; then
])
fi
# nghttp2
AC_ARG_WITH(libnghttp2, AC_HELP_STRING([--with-libnghttp2=path],
[specify explicit path for libnghttp2.]),
[ ],[ withval="no" ])
found_libnghttp2="no"
if test x_$withval = x_yes -o x_$withval != x_no; then
AC_MSG_CHECKING(for libnghttp2)
if test x_$withval = x_ -o x_$withval = x_yes; then
withval="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr"
fi
for dir in $withval ; do
if test -f "$dir/include/nghttp2/nghttp2.h"; then
found_libnghttp2="yes"
dnl assume /usr is in default path.
if test "$dir" != "/usr"; then
CPPFLAGS="$CPPFLAGS -I$dir/include"
LDFLAGS="$LDFLAGS -L$dir/lib"
fi
AC_MSG_RESULT(found in $dir)
AC_DEFINE([HAVE_NGHTTP2], [1], [Define this to use nghttp2 client.])
LIBS="$LIBS -lnghttp2"
break;
fi
done
if test x_$found_libnghttp2 != x_yes; then
AC_ERROR([Could not find libnghttp2, nghttp2.h])
fi
AC_CHECK_HEADERS([nghttp2/nghttp2.h],,, [AC_INCLUDES_DEFAULT])
AC_CHECK_DECLS([nghttp2_session_server_new], [], [], [AC_INCLUDES_DEFAULT
#include <nghttp2/nghttp2.h>
])
fi
# set static linking for uninstalled libraries if requested
AC_SUBST(staticexe)
staticexe=""
@ -1551,7 +1585,7 @@ AC_LINK_IFELSE([AC_LANG_PROGRAM([
AC_MSG_RESULT(no))
AC_SEARCH_LIBS([setusercontext], [util])
AC_CHECK_FUNCS([tzset sigprocmask fcntl getpwnam endpwent getrlimit setrlimit setsid chroot kill chown sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent fsync shmget accept4])
AC_CHECK_FUNCS([tzset sigprocmask fcntl getpwnam endpwent getrlimit setrlimit setsid chroot kill chown sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent fsync shmget accept4 getifaddrs])
AC_CHECK_FUNCS([setresuid],,[AC_CHECK_FUNCS([setreuid])])
AC_CHECK_FUNCS([setresgid],,[AC_CHECK_FUNCS([setregid])])
@ -2131,6 +2165,8 @@ void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
#define UNBOUND_DNS_PORT 53
/** default port for DNS over TLS traffic. */
#define UNBOUND_DNS_OVER_TLS_PORT 853
/** default port for DNS over HTTPS traffic. */
#define UNBOUND_DNS_OVER_HTTPS_PORT 443
/** default port for unbound control traffic, registered port with IANA,
ub-dns-control 8953/tcp unbound dns nameserver control */
#define UNBOUND_CONTROL_PORT 8953

View File

@ -1,10 +1,10 @@
Index: trunk/doc/unbound.conf.5.in
===================================================================
--- trunk/doc/unbound.conf.5.in (revision 4357)
+++ trunk/doc/unbound.conf.5.in (working copy)
@@ -701,6 +701,13 @@
diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in
index f426ac5f..147fbfa9 100644
--- a/doc/unbound.conf.5.in
+++ b/doc/unbound.conf.5.in
@@ -872,6 +872,13 @@ potentially broken nameservers. A lot of domains will not be resolvable when
this option in enabled. Only use if you know what you are doing.
This option only has effect when qname-minimisation is enabled. Default is off.
This option only has effect when qname-minimisation is enabled. Default is no.
.TP
+.B aaaa\-filter: \fI<yes or no>
+Activate behavior similar to BIND's AAAA-filter.
@ -16,14 +16,15 @@ Index: trunk/doc/unbound.conf.5.in
.B aggressive\-nsec: \fI<yes or no>
Aggressive NSEC uses the DNSSEC NSEC chain to synthesize NXDOMAIN
and other denials, using information from previous NXDOMAINs answers.
Index: trunk/iterator/iter_scrub.c
===================================================================
--- trunk/iterator/iter_scrub.c (revision 4357)
+++ trunk/iterator/iter_scrub.c (working copy)
@@ -617,6 +617,32 @@
diff --git a/iterator/iter_scrub.c b/iterator/iter_scrub.c
index aae934dd..55c55de0 100644
--- a/iterator/iter_scrub.c
+++ b/iterator/iter_scrub.c
@@ -667,6 +667,32 @@ static int sanitize_nsec_is_overreach(struct rrset_parse* rrset,
return 0;
}
/**
+/**
+ * ASN: Lookup A records from rrset cache.
+ * @param qinfo: the question originally asked.
+ * @param env: module environment with config and cache.
@ -49,11 +50,10 @@ Index: trunk/iterator/iter_scrub.c
+ return 0;
+}
+
+/**
/**
* Given a response event, remove suspect RRsets from the response.
* "Suspect" rrsets are potentially poison. Note that this routine expects
* the response to be in a "normalized" state -- that is, all "irrelevant"
@@ -635,6 +661,7 @@
@@ -686,6 +712,7 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg,
struct query_info* qinfo, uint8_t* zonename, struct module_env* env,
struct iter_env* ie)
{
@ -61,7 +61,7 @@ Index: trunk/iterator/iter_scrub.c
int del_addi = 0; /* if additional-holding rrsets are deleted, we
do not trust the normalized additional-A-AAAA any more */
struct rrset_parse* rrset, *prev;
@@ -670,6 +697,13 @@
@@ -721,6 +748,13 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg,
rrset = rrset->rrset_all_next;
}
@ -75,11 +75,10 @@ Index: trunk/iterator/iter_scrub.c
/* At this point, we brutally remove ALL rrsets that aren't
* children of the originating zone. The idea here is that,
* as far as we know, the server that we contacted is ONLY
@@ -680,6 +714,24 @@
prev = NULL;
@@ -732,6 +766,24 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg,
rrset = msg->rrset_first;
while(rrset) {
+
+ /* ASN: For AAAA records only... */
+ if((ie->aaaa_filter) && (rrset->type == LDNS_RR_TYPE_AAAA)) {
+ /* ASN: If this is not a AAAA query, then remove AAAA
@ -97,14 +96,15 @@ Index: trunk/iterator/iter_scrub.c
+ LDNS_RR_TYPE_AAAA, qinfo->qclass);
+ }
+ /* ASN: End of added code */
+
/* remove private addresses */
if( (rrset->type == LDNS_RR_TYPE_A ||
Index: trunk/iterator/iter_utils.c
===================================================================
--- trunk/iterator/iter_utils.c (revision 4357)
+++ trunk/iterator/iter_utils.c (working copy)
@@ -175,6 +175,7 @@
rrset->type == LDNS_RR_TYPE_AAAA)) {
diff --git a/iterator/iter_utils.c b/iterator/iter_utils.c
index 7bc67da6..e10f547a 100644
--- a/iterator/iter_utils.c
+++ b/iterator/iter_utils.c
@@ -175,6 +175,7 @@ iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg)
}
iter_env->supports_ipv6 = cfg->do_ip6;
iter_env->supports_ipv4 = cfg->do_ip4;
@ -112,11 +112,11 @@ Index: trunk/iterator/iter_utils.c
return 1;
}
Index: trunk/iterator/iterator.c
===================================================================
--- trunk/iterator/iterator.c (revision 4357)
+++ trunk/iterator/iterator.c (working copy)
@@ -1847,6 +1847,53 @@
diff --git a/iterator/iterator.c b/iterator/iterator.c
index 23b07ea9..ca29b48c 100644
--- a/iterator/iterator.c
+++ b/iterator/iterator.c
@@ -2127,6 +2127,53 @@ processDSNSFind(struct module_qstate* qstate, struct iter_qstate* iq, int id)
return 0;
}
@ -170,7 +170,7 @@ Index: trunk/iterator/iterator.c
/**
* This is the request event state where the request will be sent to one of
@@ -1894,6 +1941,13 @@
@@ -2186,6 +2233,13 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
@ -184,7 +184,7 @@ Index: trunk/iterator/iterator.c
/* Make sure we have a delegation point, otherwise priming failed
* or another failure occurred */
if(!iq->dp) {
@@ -3095,6 +3149,61 @@
@@ -3574,6 +3628,61 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
return 0;
}
@ -246,7 +246,7 @@ Index: trunk/iterator/iterator.c
/*
* Return priming query results to interested super querystates.
*
@@ -3114,6 +3223,9 @@
@@ -3593,6 +3702,9 @@ iter_inform_super(struct module_qstate* qstate, int id,
else if(super->qinfo.qtype == LDNS_RR_TYPE_DS && ((struct iter_qstate*)
super->minfo[id])->state == DSNS_FIND_STATE)
processDSNSResponse(qstate, id, super);
@ -256,7 +256,7 @@ Index: trunk/iterator/iterator.c
else if(qstate->return_rcode != LDNS_RCODE_NOERROR)
error_supers(qstate, id, super);
else if(qstate->is_priming)
@@ -3151,6 +3263,9 @@
@@ -3630,6 +3742,9 @@ iter_handle(struct module_qstate* qstate, struct iter_qstate* iq,
case INIT_REQUEST_3_STATE:
cont = processInitRequest3(qstate, iq, id);
break;
@ -266,7 +266,7 @@ Index: trunk/iterator/iterator.c
case QUERYTARGETS_STATE:
cont = processQueryTargets(qstate, iq, ie, id);
break;
@@ -3460,6 +3575,8 @@
@@ -3961,6 +4076,8 @@ iter_state_to_string(enum iter_state state)
return "INIT REQUEST STATE (stage 2)";
case INIT_REQUEST_3_STATE:
return "INIT REQUEST STATE (stage 3)";
@ -275,7 +275,7 @@ Index: trunk/iterator/iterator.c
case QUERYTARGETS_STATE :
return "QUERY TARGETS STATE";
case PRIME_RESP_STATE :
@@ -3484,6 +3601,7 @@
@@ -3985,6 +4102,7 @@ iter_state_is_responsestate(enum iter_state s)
case INIT_REQUEST_STATE :
case INIT_REQUEST_2_STATE :
case INIT_REQUEST_3_STATE :
@ -283,11 +283,11 @@ Index: trunk/iterator/iterator.c
case QUERYTARGETS_STATE :
case COLLECT_CLASS_STATE :
return 0;
Index: trunk/iterator/iterator.h
===================================================================
--- trunk/iterator/iterator.h (revision 4357)
+++ trunk/iterator/iterator.h (working copy)
@@ -130,6 +130,9 @@
diff --git a/iterator/iterator.h b/iterator/iterator.h
index 342ac207..731948d1 100644
--- a/iterator/iterator.h
+++ b/iterator/iterator.h
@@ -135,6 +135,9 @@ struct iter_env {
*/
int* target_fetch_policy;
@ -297,10 +297,11 @@ Index: trunk/iterator/iterator.h
/** lock on ratelimit counter */
lock_basic_type queries_ratelimit_lock;
/** number of queries that have been ratelimited */
@@ -182,6 +185,14 @@
@@ -186,6 +189,14 @@ enum iter_state {
*/
INIT_REQUEST_3_STATE,
/**
+ /**
+ * This state is responsible for intercepting AAAA queries,
+ * and launch a A subquery on the same target, to populate the
+ * cache with A records, so the AAAA filter scrubbing logic can
@ -308,29 +309,28 @@ Index: trunk/iterator/iterator.h
+ */
+ ASN_FETCH_A_FOR_AAAA_STATE,
+
+ /**
/**
* Each time a delegation point changes for a given query or a
* query times out and/or wakes up, this state is (re)visited.
* This state is responsible for iterating through a list of
@@ -364,6 +375,13 @@
* be used when creating the state. A higher one will be attempted.
@@ -375,6 +386,13 @@ struct iter_qstate {
*/
int refetch_glue;
+
+ /**
+ * ASN: This is a flag that, if true, means that this query is
+ * for fetching A records to populate cache and determine if we must
+ * return AAAA records or not.
+ */
+ int fetch_a_for_aaaa;
+
/** list of pending queries to authoritative servers. */
struct outbound_list outlist;
Index: trunk/pythonmod/interface.i
===================================================================
--- trunk/pythonmod/interface.i (revision 4357)
+++ trunk/pythonmod/interface.i (working copy)
@@ -851,6 +851,7 @@
diff --git a/pythonmod/interface.i b/pythonmod/interface.i
index f08b575d..47f1bb2e 100644
--- a/pythonmod/interface.i
+++ b/pythonmod/interface.i
@@ -975,6 +975,7 @@ struct config_file {
int harden_dnssec_stripped;
int harden_referral_path;
int use_caps_bits_for_id;
@ -338,11 +338,11 @@ Index: trunk/pythonmod/interface.i
struct config_strlist* private_address;
struct config_strlist* private_domain;
size_t unwanted_threshold;
Index: trunk/util/config_file.c
===================================================================
--- trunk/util/config_file.c (revision 4357)
+++ trunk/util/config_file.c (working copy)
@@ -195,6 +195,7 @@
diff --git a/util/config_file.c b/util/config_file.c
index 0ab8614a..729fb147 100644
--- a/util/config_file.c
+++ b/util/config_file.c
@@ -218,6 +218,7 @@ config_create(void)
cfg->harden_referral_path = 0;
cfg->harden_algo_downgrade = 0;
cfg->use_caps_bits_for_id = 0;
@ -350,11 +350,11 @@ Index: trunk/util/config_file.c
cfg->caps_whitelist = NULL;
cfg->private_address = NULL;
cfg->private_domain = NULL;
Index: trunk/util/config_file.h
===================================================================
--- trunk/util/config_file.h (revision 4357)
+++ trunk/util/config_file.h (working copy)
@@ -209,6 +209,8 @@
diff --git a/util/config_file.h b/util/config_file.h
index e61257a3..dabaa7bb 100644
--- a/util/config_file.h
+++ b/util/config_file.h
@@ -260,6 +260,8 @@ struct config_file {
int harden_algo_downgrade;
/** use 0x20 bits in query as random ID bits */
int use_caps_bits_for_id;
@ -363,11 +363,11 @@ Index: trunk/util/config_file.h
/** 0x20 whitelist, domains that do not use capsforid */
struct config_strlist* caps_whitelist;
/** strip away these private addrs from answers, no DNS Rebinding */
Index: trunk/util/configlexer.lex
===================================================================
--- trunk/util/configlexer.lex (revision 4357)
+++ trunk/util/configlexer.lex (working copy)
@@ -279,6 +279,7 @@
diff --git a/util/configlexer.lex b/util/configlexer.lex
index 79a0edca..4eaec678 100644
--- a/util/configlexer.lex
+++ b/util/configlexer.lex
@@ -304,6 +304,7 @@ harden-algo-downgrade{COLON} { YDVAR(1, VAR_HARDEN_ALGO_DOWNGRADE) }
use-caps-for-id{COLON} { YDVAR(1, VAR_USE_CAPS_FOR_ID) }
caps-whitelist{COLON} { YDVAR(1, VAR_CAPS_WHITELIST) }
unwanted-reply-threshold{COLON} { YDVAR(1, VAR_UNWANTED_REPLY_THRESHOLD) }
@ -375,11 +375,11 @@ Index: trunk/util/configlexer.lex
private-address{COLON} { YDVAR(1, VAR_PRIVATE_ADDRESS) }
private-domain{COLON} { YDVAR(1, VAR_PRIVATE_DOMAIN) }
prefetch-key{COLON} { YDVAR(1, VAR_PREFETCH_KEY) }
Index: trunk/util/configparser.y
===================================================================
--- trunk/util/configparser.y (revision 4357)
+++ trunk/util/configparser.y (working copy)
@@ -95,6 +95,7 @@
diff --git a/util/configparser.y b/util/configparser.y
index 1d0e8658..f284dd43 100644
--- a/util/configparser.y
+++ b/util/configparser.y
@@ -97,6 +97,7 @@ extern struct config_parser_state* cfg_parser;
%token VAR_STATISTICS_CUMULATIVE VAR_OUTGOING_PORT_PERMIT
%token VAR_OUTGOING_PORT_AVOID VAR_DLV_ANCHOR_FILE VAR_DLV_ANCHOR
%token VAR_NEG_CACHE_SIZE VAR_HARDEN_REFERRAL_PATH VAR_PRIVATE_ADDRESS
@ -387,7 +387,7 @@ Index: trunk/util/configparser.y
%token VAR_PRIVATE_DOMAIN VAR_REMOTE_CONTROL VAR_CONTROL_ENABLE
%token VAR_CONTROL_INTERFACE VAR_CONTROL_PORT VAR_SERVER_KEY_FILE
%token VAR_SERVER_CERT_FILE VAR_CONTROL_KEY_FILE VAR_CONTROL_CERT_FILE
@@ -203,6 +204,7 @@
@@ -233,6 +234,7 @@ content_server: server_num_threads | server_verbosity | server_port |
server_dlv_anchor_file | server_dlv_anchor | server_neg_cache_size |
server_harden_referral_path | server_private_address |
server_private_domain | server_extended_statistics |
@ -395,12 +395,10 @@ Index: trunk/util/configparser.y
server_local_data_ptr | server_jostle_timeout |
server_unwanted_reply_threshold | server_log_time_ascii |
server_domain_insecure | server_val_sig_skew_min |
@@ -1183,6 +1185,15 @@
OUTYY(("P(server_caps_whitelist:%s)\n", $2));
if(!cfg_strlist_insert(&cfg_parser->cfg->caps_whitelist, $2))
@@ -1563,6 +1565,15 @@ server_caps_whitelist: VAR_CAPS_WHITELIST STRING_ARG
yyerror("out of memory");
+ }
+ ;
}
;
+server_aaaa_filter: VAR_AAAA_FILTER STRING_ARG
+ {
+ OUTYY(("P(server_aaaa_filter:%s)\n", $2));
@ -408,6 +406,8 @@ Index: trunk/util/configparser.y
+ yyerror("expected yes or no.");
+ else cfg_parser->cfg->aaaa_filter = (strcmp($2, "yes")==0);
+ free($2);
}
;
+ }
+ ;
server_private_address: VAR_PRIVATE_ADDRESS STRING_ARG
{
OUTYY(("P(server_private_address:%s)\n", $2));

View File

@ -42,9 +42,9 @@
[Unit]
Description=Validating, recursive, and caching DNS resolver
Documentation=man:unbound(8)
After=network.target
Before=network-online.target nss-lookup.target
Wants=nss-lookup.target
After=network-online.target
Before=nss-lookup.target
Wants=network-online.target nss-lookup.target
[Install]
WantedBy=multi-user.target

View File

@ -174,11 +174,11 @@ get_state ( ) {
if test "$1" = "autoconf" ; then
if test ! -f $conf; then
echo no "($conf does not exist)"
exit 1
exit 0
fi
if test ! -d `dirname $state`; then
echo no "(`dirname $state` directory does not exist)"
exit 1
exit 0
fi
echo yes
exit 0

View File

@ -77,6 +77,7 @@
#include "util/storage/lookup3.h"
#include "util/storage/slabhash.h"
#include "util/tcp_conn_limit.h"
#include "util/edns.h"
#include "services/listen_dnsport.h"
#include "services/cache/rrset.h"
#include "services/cache/infra.h"
@ -290,6 +291,15 @@ daemon_init(void)
free(daemon);
return NULL;
}
if(!(daemon->env->edns_tags = edns_tags_create())) {
auth_zones_delete(daemon->env->auth_zones);
acl_list_delete(daemon->acl);
tcl_list_delete(daemon->tcl);
edns_known_options_delete(daemon->env);
free(daemon->env);
free(daemon);
return NULL;
}
return daemon;
}
@ -298,6 +308,8 @@ daemon_open_shared_ports(struct daemon* daemon)
{
log_assert(daemon);
if(daemon->cfg->port != daemon->listening_port) {
char** resif = NULL;
int num_resif = 0;
size_t i;
struct listen_port* p0;
daemon->reuseport = 0;
@ -308,15 +320,18 @@ daemon_open_shared_ports(struct daemon* daemon)
free(daemon->ports);
daemon->ports = NULL;
}
if(!resolve_interface_names(daemon->cfg, &resif, &num_resif))
return 0;
/* see if we want to reuseport */
#ifdef SO_REUSEPORT
if(daemon->cfg->so_reuseport && daemon->cfg->num_threads > 0)
daemon->reuseport = 1;
#endif
/* try to use reuseport */
p0 = listening_ports_open(daemon->cfg, &daemon->reuseport);
p0 = listening_ports_open(daemon->cfg, resif, num_resif, &daemon->reuseport);
if(!p0) {
listening_ports_free(p0);
config_del_strarray(resif, num_resif);
return 0;
}
if(daemon->reuseport) {
@ -330,6 +345,7 @@ daemon_open_shared_ports(struct daemon* daemon)
if(!(daemon->ports = (struct listen_port**)calloc(
daemon->num_ports, sizeof(*daemon->ports)))) {
listening_ports_free(p0);
config_del_strarray(resif, num_resif);
return 0;
}
daemon->ports[0] = p0;
@ -338,16 +354,19 @@ daemon_open_shared_ports(struct daemon* daemon)
for(i=1; i<daemon->num_ports; i++) {
if(!(daemon->ports[i]=
listening_ports_open(daemon->cfg,
resif, num_resif,
&daemon->reuseport))
|| !daemon->reuseport ) {
for(i=0; i<daemon->num_ports; i++)
listening_ports_free(daemon->ports[i]);
free(daemon->ports);
daemon->ports = NULL;
config_del_strarray(resif, num_resif);
return 0;
}
}
}
config_del_strarray(resif, num_resif);
daemon->listening_port = daemon->cfg->port;
}
if(!daemon->cfg->remote_control_enable && daemon->rc_port) {
@ -619,6 +638,10 @@ daemon_fork(struct daemon* daemon)
&daemon->use_rpz))
fatal_exit("auth_zones could not be setup");
/* Set-up EDNS tags */
if(!edns_tags_apply_cfg(daemon->env->edns_tags, daemon->cfg))
fatal_exit("Could not set up EDNS tags");
/* setup modules */
daemon_setup_modules(daemon);
@ -750,6 +773,7 @@ daemon_delete(struct daemon* daemon)
rrset_cache_delete(daemon->env->rrset_cache);
infra_delete(daemon->env->infra_cache);
edns_known_options_delete(daemon->env);
edns_tags_delete(daemon->env->edns_tags);
auth_zones_delete(daemon->env->auth_zones);
}
ub_randfree(daemon->rand);

View File

@ -329,7 +329,8 @@ add_open(const char* ip, int nr, struct listen_port** list, int noproto_is_err,
/* open fd */
fd = create_tcp_accept_sock(res, 1, &noproto, 0,
cfg->ip_transparent, 0, cfg->ip_freebind, cfg->use_systemd, cfg->ip_dscp);
cfg->ip_transparent, 0, 0, cfg->ip_freebind,
cfg->use_systemd, cfg->ip_dscp);
freeaddrinfo(res);
}
@ -348,11 +349,7 @@ add_open(const char* ip, int nr, struct listen_port** list, int noproto_is_err,
/* alloc */
n = (struct listen_port*)calloc(1, sizeof(*n));
if(!n) {
#ifndef USE_WINSOCK
close(fd);
#else
closesocket(fd);
#endif
sock_close(fd);
log_err("out of memory");
return 0;
}
@ -461,11 +458,7 @@ int remote_accept_callback(struct comm_point* c, void* arg, int err,
if(rc->active >= rc->max_active) {
log_warn("drop incoming remote control: too many connections");
close_exit:
#ifndef USE_WINSOCK
close(newfd);
#else
closesocket(newfd);
#endif
sock_close(newfd);
return 0;
}
@ -574,11 +567,8 @@ ssl_print_text(RES* res, const char* text)
if(r == -1) {
if(errno == EAGAIN || errno == EINTR)
continue;
#ifndef USE_WINSOCK
log_err("could not send: %s", strerror(errno));
#else
log_err("could not send: %s", wsa_strerror(WSAGetLastError()));
#endif
log_err("could not send: %s",
sock_strerror(errno));
return 0;
}
at += r;
@ -635,11 +625,8 @@ ssl_read_line(RES* res, char* buf, size_t max)
}
if(errno == EINTR || errno == EAGAIN)
continue;
#ifndef USE_WINSOCK
log_err("could not recv: %s", strerror(errno));
#else
log_err("could not recv: %s", wsa_strerror(WSAGetLastError()));
#endif
log_err("could not recv: %s",
sock_strerror(errno));
return 0;
}
break;
@ -862,6 +849,12 @@ print_mem(RES* ssl, struct worker* worker, struct daemon* daemon,
if(!print_longnum(ssl, "mem.streamwait"SQ,
(size_t)s->svr.mem_stream_wait))
return 0;
if(!print_longnum(ssl, "mem.http.query_buffer"SQ,
(size_t)s->svr.mem_http2_query_buffer))
return 0;
if(!print_longnum(ssl, "mem.http.response_buffer"SQ,
(size_t)s->svr.mem_http2_response_buffer))
return 0;
return 1;
}
@ -988,6 +981,8 @@ print_ext(RES* ssl, struct ub_stats_info* s)
(unsigned long)s->svr.qtls_resume)) return 0;
if(!ssl_printf(ssl, "num.query.ipv6"SQ"%lu\n",
(unsigned long)s->svr.qipv6)) return 0;
if(!ssl_printf(ssl, "num.query.https"SQ"%lu\n",
(unsigned long)s->svr.qhttps)) return 0;
/* flags */
if(!ssl_printf(ssl, "num.query.flags.QR"SQ"%lu\n",
(unsigned long)s->svr.qbit_QR)) return 0;
@ -3116,11 +3111,7 @@ handle_req(struct daemon_remote* rc, struct rc_state* s, RES* res)
if(rr == 0) return;
if(errno == EINTR || errno == EAGAIN)
continue;
#ifndef USE_WINSOCK
log_err("could not recv: %s", strerror(errno));
#else
log_err("could not recv: %s", wsa_strerror(WSAGetLastError()));
#endif
log_err("could not recv: %s", sock_strerror(errno));
return;
}
r = (int)rr;

View File

@ -271,6 +271,7 @@ server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset)
s->svr.ans_secure += (long long)worker->env.mesh->ans_secure;
s->svr.ans_bogus += (long long)worker->env.mesh->ans_bogus;
s->svr.ans_rcode_nodata += (long long)worker->env.mesh->ans_nodata;
s->svr.ans_expired += (long long)worker->env.mesh->ans_expired;
for(i=0; i<UB_STATS_RCODE_NUM; i++)
s->svr.ans_rcode[i] += (long long)worker->env.mesh->ans_rcode[i];
for(i=0; i<UB_STATS_RPZ_ACTION_NUM; i++)
@ -335,6 +336,10 @@ server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset)
}
s->svr.mem_stream_wait =
(long long)tcp_req_info_get_stream_buffer_size();
s->svr.mem_http2_query_buffer =
(long long)http2_get_query_buffer_size();
s->svr.mem_http2_response_buffer =
(long long)http2_get_response_buffer_size();
/* Set neg cache usage numbers */
set_neg_cache_stats(worker, &s->svr, reset);
@ -421,6 +426,7 @@ void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a)
total->svr.qtcp_outgoing += a->svr.qtcp_outgoing;
total->svr.qtls += a->svr.qtls;
total->svr.qtls_resume += a->svr.qtls_resume;
total->svr.qhttps += a->svr.qhttps;
total->svr.qipv6 += a->svr.qipv6;
total->svr.qbit_QR += a->svr.qbit_QR;
total->svr.qbit_AA += a->svr.qbit_AA;
@ -484,6 +490,8 @@ void server_stats_insquery(struct ub_server_stats* stats, struct comm_point* c,
if(SSL_session_reused(c->ssl))
stats->qtls_resume++;
#endif
if(c->type == comm_http)
stats->qhttps++;
}
}
if(repinfo && addr_is_ip6(&repinfo->addr, repinfo->addrlen))

View File

@ -92,7 +92,7 @@
#include <TargetConditionals.h>
#endif
#if defined(TARGET_OS_TV) || defined(TARGET_OS_WATCH)
#if (defined(TARGET_OS_TV) && TARGET_OS_TV) || (defined(TARGET_OS_WATCH) && TARGET_OS_WATCH)
#undef HAVE_FORK
#endif

View File

@ -1109,7 +1109,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
struct respip_client_info* cinfo = NULL, cinfo_tmp;
memset(&qinfo, 0, sizeof(qinfo));
if(error != NETEVENT_NOERROR || !repinfo) {
if((error != NETEVENT_NOERROR && error != NETEVENT_DONE)|| !repinfo) {
/* some bad tcp query DNS formats give these error calls */
verbose(VERB_ALGO, "handle request called with err=%d", error);
return 0;
@ -1219,7 +1219,6 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
LDNS_RCODE_FORMERR);
server_stats_insrcode(&worker->stats, c->buffer);
goto send_reply;
}
if(worker->env.cfg->log_queries) {
@ -1237,7 +1236,6 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
LDNS_RCODE_REFUSED);
if(worker->stats.extended) {
worker->stats.qtype[qinfo.qtype]++;
server_stats_insrcode(&worker->stats, c->buffer);
}
goto send_reply;
}
@ -1259,7 +1257,6 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
LDNS_RCODE_FORMERR);
if(worker->stats.extended) {
worker->stats.qtype[qinfo.qtype]++;
server_stats_insrcode(&worker->stats, c->buffer);
}
goto send_reply;
}
@ -1275,7 +1272,6 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
sldns_buffer_read_u16_at(c->buffer, 2), &reply_edns);
regional_free_all(worker->scratchpad);
server_stats_insrcode(&worker->stats, c->buffer);
goto send_reply;
}
if(edns.edns_present) {
@ -1354,7 +1350,6 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
edns.udp_size = 65535; /* max size for TCP replies */
if(qinfo.qclass == LDNS_RR_CLASS_CH && answer_chaos(worker, &qinfo,
&edns, repinfo, c->buffer)) {
server_stats_insrcode(&worker->stats, c->buffer);
regional_free_all(worker->scratchpad);
goto send_reply;
}
@ -1375,7 +1370,6 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
comm_point_drop_reply(repinfo);
return 0;
}
server_stats_insrcode(&worker->stats, c->buffer);
goto send_reply;
}
if(worker->env.auth_zones &&
@ -1387,7 +1381,6 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
comm_point_drop_reply(repinfo);
return 0;
}
server_stats_insrcode(&worker->stats, c->buffer);
goto send_reply;
}
if(worker->env.auth_zones &&
@ -1403,7 +1396,6 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
if(LDNS_RD_WIRE(sldns_buffer_begin(c->buffer)) &&
acl != acl_deny_non_local && acl != acl_refuse_non_local)
LDNS_RA_SET(sldns_buffer_begin(c->buffer));
server_stats_insrcode(&worker->stats, c->buffer);
goto send_reply;
}
@ -1432,7 +1424,6 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
sldns_buffer_read_u16_at(c->buffer, 2), NULL);
regional_free_all(worker->scratchpad);
server_stats_insrcode(&worker->stats, c->buffer);
log_addr(VERB_ALGO, "refused nonrec (cache snoop) query from",
&repinfo->addr, repinfo->addrlen);
goto send_reply;
@ -1588,9 +1579,9 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
if(is_expired_answer) {
worker->stats.ans_expired++;
}
server_stats_insrcode(&worker->stats, c->buffer);
if(worker->stats.extended) {
if(is_secure_answer) worker->stats.ans_secure++;
server_stats_insrcode(&worker->stats, repinfo->c->buffer);
}
#ifdef USE_DNSTAP
if(worker->dtenv.log_client_response_messages)
@ -1726,14 +1717,6 @@ worker_create(struct daemon* daemon, int id, int* ports, int n)
return NULL;
}
explicit_bzero(&seed, sizeof(seed));
#ifdef USE_DNSTAP
if(daemon->cfg->dnstap) {
log_assert(daemon->dtenv != NULL);
memcpy(&worker->dtenv, daemon->dtenv, sizeof(struct dt_env));
if(!dt_init(&worker->dtenv))
fatal_exit("dt_init failed");
}
#endif
return worker;
}
@ -1792,12 +1775,21 @@ worker_init(struct worker* worker, struct config_file *cfg,
} else { /* !do_sigs */
worker->comsig = NULL;
}
#ifdef USE_DNSTAP
if(cfg->dnstap) {
log_assert(worker->daemon->dtenv != NULL);
memcpy(&worker->dtenv, worker->daemon->dtenv, sizeof(struct dt_env));
if(!dt_init(&worker->dtenv, worker->base))
fatal_exit("dt_init failed");
}
#endif
worker->front = listen_create(worker->base, ports,
cfg->msg_buffer_size, (int)cfg->incoming_num_tcp,
cfg->do_tcp_keepalive
? cfg->tcp_keepalive_timeout
: cfg->tcp_idle_timeout,
worker->daemon->tcl,
cfg->harden_large_queries, cfg->http_max_streams,
cfg->http_endpoint, worker->daemon->tcl,
worker->daemon->listen_sslctx,
dtenv, worker_handle_request, worker);
if(!worker->front) {

View File

@ -134,9 +134,15 @@ dt_create(struct config_file* cfg)
if(cfg->dnstap && cfg->dnstap_socket_path && cfg->dnstap_socket_path[0] &&
(cfg->dnstap_ip==NULL || cfg->dnstap_ip[0]==0)) {
char* p = fname_after_chroot(cfg->dnstap_socket_path, cfg, 1);
if(!p) {
log_err("malloc failure");
return NULL;
}
verbose(VERB_OPS, "attempting to connect to dnstap socket %s",
cfg->dnstap_socket_path);
check_socket_file(cfg->dnstap_socket_path);
p);
check_socket_file(p);
free(p);
}
env = (struct dt_env *) calloc(1, sizeof(struct dt_env));
@ -240,9 +246,9 @@ dt_apply_cfg(struct dt_env *env, struct config_file *cfg)
}
int
dt_init(struct dt_env *env)
dt_init(struct dt_env *env, struct comm_base* base)
{
env->msgqueue = dt_msg_queue_create();
env->msgqueue = dt_msg_queue_create(base);
if(!env->msgqueue) {
log_err("malloc failure");
return 0;

View File

@ -101,10 +101,11 @@ dt_apply_cfg(struct dt_env *env, struct config_file *cfg);
/**
* Initialize per-worker state in dnstap environment object.
* @param env: dnstap environment object to initialize, created with dt_create().
* @param base: event base for wakeup timer.
* @return: true on success, false on failure.
*/
int
dt_init(struct dt_env *env);
dt_init(struct dt_env *env, struct comm_base* base);
/**
* Deletes the per-worker state created by dt_init

View File

@ -68,6 +68,8 @@
#define DTIO_RECONNECT_TIMEOUT_MAX 1000
/** the msec to wait for reconnect slow, to stop busy spinning on reconnect */
#define DTIO_RECONNECT_TIMEOUT_SLOW 1000
/** number of messages before wakeup of thread */
#define DTIO_MSG_FOR_WAKEUP 32
/** maximum length of received frame */
#define DTIO_RECV_FRAME_MAX_LEN 1000
@ -99,13 +101,18 @@ static int dtio_enable_brief_write(struct dt_io_thread* dtio);
#endif
struct dt_msg_queue*
dt_msg_queue_create(void)
dt_msg_queue_create(struct comm_base* base)
{
struct dt_msg_queue* mq = calloc(1, sizeof(*mq));
if(!mq) return NULL;
mq->maxsize = 1*1024*1024; /* set max size of buffer, per worker,
about 1 M should contain 64K messages with some overhead,
or a whole bunch smaller ones */
mq->wakeup_timer = comm_timer_create(base, mq_wakeup_cb, mq);
if(!mq->wakeup_timer) {
free(mq);
return NULL;
}
lock_basic_init(&mq->lock);
lock_protect(&mq->lock, mq, sizeof(*mq));
return mq;
@ -125,6 +132,7 @@ dt_msg_queue_clear(struct dt_msg_queue* mq)
mq->first = NULL;
mq->last = NULL;
mq->cursize = 0;
mq->msgcount = 0;
}
void
@ -133,6 +141,7 @@ dt_msg_queue_delete(struct dt_msg_queue* mq)
if(!mq) return;
lock_basic_destroy(&mq->lock);
dt_msg_queue_clear(mq);
comm_timer_delete(mq->wakeup_timer);
free(mq);
}
@ -149,25 +158,71 @@ static void dtio_wakeup(struct dt_io_thread* dtio)
#ifndef USE_WINSOCK
if(errno == EINTR || errno == EAGAIN)
continue;
log_err("dnstap io wakeup: write: %s", strerror(errno));
#else
if(WSAGetLastError() == WSAEINPROGRESS)
continue;
if(WSAGetLastError() == WSAEWOULDBLOCK)
continue;
log_err("dnstap io stop: write: %s",
wsa_strerror(WSAGetLastError()));
#endif
log_err("dnstap io wakeup: write: %s",
sock_strerror(errno));
break;
}
break;
}
}
void
mq_wakeup_cb(void* arg)
{
struct dt_msg_queue* mq = (struct dt_msg_queue*)arg;
/* even if the dtio is already active, because perhaps much
* traffic suddenly, we leave the timer running to save on
* managing it, the once a second timer is less work then
* starting and stopping the timer frequently */
lock_basic_lock(&mq->dtio->wakeup_timer_lock);
mq->dtio->wakeup_timer_enabled = 0;
lock_basic_unlock(&mq->dtio->wakeup_timer_lock);
dtio_wakeup(mq->dtio);
}
/** start timer to wakeup dtio because there is content in the queue */
static void
dt_msg_queue_start_timer(struct dt_msg_queue* mq)
{
struct timeval tv;
/* Start a timer to process messages to be logged.
* If we woke up the dtio thread for every message, the wakeup
* messages take up too much processing power. If the queue
* fills up the wakeup happens immediately. The timer wakes it up
* if there are infrequent messages to log. */
/* we cannot start a timer in dtio thread, because it is a different
* thread and its event base is in use by the other thread, it would
* give race conditions if we tried to modify its event base,
* and locks would wait until it woke up, and this is what we do. */
/* do not start the timer if a timer already exists, perhaps
* in another worker. So this variable is protected by a lock in
* dtio */
lock_basic_lock(&mq->dtio->wakeup_timer_lock);
if(mq->dtio->wakeup_timer_enabled) {
lock_basic_unlock(&mq->dtio->wakeup_timer_lock);
return;
}
mq->dtio->wakeup_timer_enabled = 1; /* we are going to start one */
lock_basic_unlock(&mq->dtio->wakeup_timer_lock);
/* start the timer, in mq, in the event base of our worker */
tv.tv_sec = 1;
tv.tv_usec = 0;
comm_timer_set(mq->wakeup_timer, &tv);
}
void
dt_msg_queue_submit(struct dt_msg_queue* mq, void* buf, size_t len)
{
int wakeup = 0;
int wakeupnow = 0, wakeupstarttimer = 0;
struct dt_msg_entry* entry;
/* check conditions */
@ -198,9 +253,15 @@ dt_msg_queue_submit(struct dt_msg_queue* mq, void* buf, size_t len)
/* aqcuire lock */
lock_basic_lock(&mq->lock);
/* list was empty, wakeup dtio */
/* if list was empty, start timer for (eventual) wakeup */
if(mq->first == NULL)
wakeup = 1;
wakeupstarttimer = 1;
/* if list contains more than wakeupnum elements, wakeup now,
* or if list is (going to be) almost full */
if(mq->msgcount == DTIO_MSG_FOR_WAKEUP ||
(mq->cursize < mq->maxsize * 9 / 10 &&
mq->cursize+len >= mq->maxsize * 9 / 10))
wakeupnow = 1;
/* see if it is going to fit */
if(mq->cursize + len > mq->maxsize) {
/* buffer full, or congested. */
@ -211,6 +272,7 @@ dt_msg_queue_submit(struct dt_msg_queue* mq, void* buf, size_t len)
return;
}
mq->cursize += len;
mq->msgcount ++;
/* append to list */
if(mq->last) {
mq->last->next = entry;
@ -221,13 +283,19 @@ dt_msg_queue_submit(struct dt_msg_queue* mq, void* buf, size_t len)
/* release lock */
lock_basic_unlock(&mq->lock);
if(wakeup)
if(wakeupnow) {
dtio_wakeup(mq->dtio);
} else if(wakeupstarttimer) {
dt_msg_queue_start_timer(mq);
}
}
struct dt_io_thread* dt_io_thread_create(void)
{
struct dt_io_thread* dtio = calloc(1, sizeof(*dtio));
lock_basic_init(&dtio->wakeup_timer_lock);
lock_protect(&dtio->wakeup_timer_lock, &dtio->wakeup_timer_enabled,
sizeof(dtio->wakeup_timer_enabled));
return dtio;
}
@ -235,6 +303,7 @@ void dt_io_thread_delete(struct dt_io_thread* dtio)
{
struct dt_io_list_item* item, *nextitem;
if(!dtio) return;
lock_basic_destroy(&dtio->wakeup_timer_lock);
item=dtio->io_list;
while(item) {
nextitem = item->next;
@ -279,7 +348,8 @@ int dt_io_thread_apply_cfg(struct dt_io_thread* dtio, struct config_file *cfg)
return 0;
}
free(dtio->socket_path);
dtio->socket_path = strdup(cfg->dnstap_socket_path);
dtio->socket_path = fname_after_chroot(cfg->dnstap_socket_path,
cfg, 1);
if(!dtio->socket_path) {
log_err("dnstap setup: malloc failure");
return 0;
@ -416,6 +486,7 @@ static int dt_msg_queue_pop(struct dt_msg_queue* mq, void** buf,
mq->first = entry->next;
if(!entry->next) mq->last = NULL;
mq->cursize -= entry->len;
mq->msgcount --;
lock_basic_unlock(&mq->lock);
*buf = entry->buf;
@ -587,11 +658,7 @@ static void dtio_del_output_event(struct dt_io_thread* dtio)
/** close dtio socket and set it to -1 */
static void dtio_close_fd(struct dt_io_thread* dtio)
{
#ifndef USE_WINSOCK
close(dtio->fd);
#else
closesocket(dtio->fd);
#endif
sock_close(dtio->fd);
dtio->fd = -1;
}
@ -659,13 +726,8 @@ static int dtio_check_nb_connect(struct dt_io_thread* dtio)
char* to = dtio->socket_path;
if(!to) to = dtio->ip_str;
if(!to) to = "";
#ifndef USE_WINSOCK
log_err("dnstap io: failed to connect to \"%s\": %s",
to, strerror(error));
#else
log_err("dnstap io: failed to connect to \"%s\": %s",
to, wsa_strerror(error));
#endif
to, sock_strerror(error));
return -1; /* error, close it */
}
@ -742,7 +804,6 @@ static int dtio_write_buf(struct dt_io_thread* dtio, uint8_t* buf,
#ifndef USE_WINSOCK
if(errno == EINTR || errno == EAGAIN)
return 0;
log_err("dnstap io: failed send: %s", strerror(errno));
#else
if(WSAGetLastError() == WSAEINPROGRESS)
return 0;
@ -752,9 +813,8 @@ static int dtio_write_buf(struct dt_io_thread* dtio, uint8_t* buf,
UB_EV_WRITE);
return 0;
}
log_err("dnstap io: failed send: %s",
wsa_strerror(WSAGetLastError()));
#endif
log_err("dnstap io: failed send: %s", sock_strerror(errno));
return -1;
}
return ret;
@ -778,7 +838,6 @@ static int dtio_write_with_writev(struct dt_io_thread* dtio)
#ifndef USE_WINSOCK
if(errno == EINTR || errno == EAGAIN)
return 0;
log_err("dnstap io: failed writev: %s", strerror(errno));
#else
if(WSAGetLastError() == WSAEINPROGRESS)
return 0;
@ -788,9 +847,8 @@ static int dtio_write_with_writev(struct dt_io_thread* dtio)
UB_EV_WRITE);
return 0;
}
log_err("dnstap io: failed writev: %s",
wsa_strerror(WSAGetLastError()));
#endif
log_err("dnstap io: failed writev: %s", sock_strerror(errno));
/* close the channel */
dtio_del_output_event(dtio);
dtio_close_output(dtio);
@ -1115,6 +1173,8 @@ static int dtio_read_accept_frame(struct dt_io_thread* dtio)
goto close_connection;
}
dtio->accept_frame_received = 1;
if(!dtio_add_output_event_write(dtio))
goto close_connection;
return 1;
} else {
/* unknow content type */
@ -1482,15 +1542,13 @@ void dtio_cmd_cb(int fd, short ATTR_UNUSED(bits), void* arg)
#ifndef USE_WINSOCK
if(errno == EINTR || errno == EAGAIN)
return; /* ignore this */
log_err("dnstap io: failed to read: %s", strerror(errno));
#else
if(WSAGetLastError() == WSAEINPROGRESS)
return;
if(WSAGetLastError() == WSAEWOULDBLOCK)
return;
log_err("dnstap io: failed to read: %s",
wsa_strerror(WSAGetLastError()));
#endif
log_err("dnstap io: failed to read: %s", sock_strerror(errno));
/* and then fall through to quit the thread */
} else if(r == 0) {
verbose(VERB_ALGO, "dnstap io: cmd channel closed");
@ -1852,13 +1910,8 @@ static int dtio_open_output_local(struct dt_io_thread* dtio)
struct sockaddr_un s;
dtio->fd = socket(AF_LOCAL, SOCK_STREAM, 0);
if(dtio->fd == -1) {
#ifndef USE_WINSOCK
log_err("dnstap io: failed to create socket: %s",
strerror(errno));
#else
log_err("dnstap io: failed to create socket: %s",
wsa_strerror(WSAGetLastError()));
#endif
sock_strerror(errno));
return 0;
}
memset(&s, 0, sizeof(s));
@ -1873,13 +1926,13 @@ static int dtio_open_output_local(struct dt_io_thread* dtio)
if(connect(dtio->fd, (struct sockaddr*)&s, (socklen_t)sizeof(s))
== -1) {
char* to = dtio->socket_path;
#ifndef USE_WINSOCK
if(dtio->reconnect_timeout > DTIO_RECONNECT_TIMEOUT_MIN &&
verbosity < 4) {
dtio_close_fd(dtio);
return 0; /* no log retries on low verbosity */
}
log_err("dnstap io: failed to connect to \"%s\": %s",
to, strerror(errno));
#else
log_err("dnstap io: failed to connect to \"%s\": %s",
to, wsa_strerror(WSAGetLastError()));
#endif
to, sock_strerror(errno));
dtio_close_fd(dtio);
return 0;
}
@ -1904,18 +1957,18 @@ static int dtio_open_output_tcp(struct dt_io_thread* dtio)
}
dtio->fd = socket(addr.ss_family, SOCK_STREAM, 0);
if(dtio->fd == -1) {
#ifndef USE_WINSOCK
log_err("can't create socket: %s", strerror(errno));
#else
log_err("can't create socket: %s",
wsa_strerror(WSAGetLastError()));
#endif
log_err("can't create socket: %s", sock_strerror(errno));
return 0;
}
fd_set_nonblock(dtio->fd);
if(connect(dtio->fd, (struct sockaddr*)&addr, addrlen) == -1) {
if(errno == EINPROGRESS)
return 1; /* wait until connect done*/
if(dtio->reconnect_timeout > DTIO_RECONNECT_TIMEOUT_MIN &&
verbosity < 4) {
dtio_close_fd(dtio);
return 0; /* no log retries on low verbosity */
}
#ifndef USE_WINSOCK
if(tcp_connect_errno_needs_log(
(struct sockaddr *)&addr, addrlen)) {
@ -2097,15 +2150,14 @@ void dt_io_thread_stop(struct dt_io_thread* dtio)
#ifndef USE_WINSOCK
if(errno == EINTR || errno == EAGAIN)
continue;
log_err("dnstap io stop: write: %s", strerror(errno));
#else
if(WSAGetLastError() == WSAEINPROGRESS)
continue;
if(WSAGetLastError() == WSAEWOULDBLOCK)
continue;
log_err("dnstap io stop: write: %s",
wsa_strerror(WSAGetLastError()));
#endif
log_err("dnstap io stop: write: %s",
sock_strerror(errno));
break;
}
break;

View File

@ -49,6 +49,7 @@ struct dt_msg_entry;
struct dt_io_list_item;
struct dt_io_thread;
struct config_file;
struct comm_base;
/**
* A message buffer with dnstap messages queued up. It is per-worker.
@ -68,11 +69,15 @@ struct dt_msg_queue {
/** current size of the buffer, in bytes. data bytes of messages.
* If a new message make it more than maxsize, the buffer is full */
size_t cursize;
/** number of messages in the queue */
int msgcount;
/** list of messages. The messages are added to the back and taken
* out from the front. */
struct dt_msg_entry* first, *last;
/** reference to the io thread to wakeup */
struct dt_io_thread* dtio;
/** the wakeup timer for dtio, on worker event base */
struct comm_timer* wakeup_timer;
};
/**
@ -166,6 +171,10 @@ struct dt_io_thread {
* for the current message length that precedes the frame */
size_t cur_msg_len_done;
/** lock on wakeup_timer_enabled */
lock_basic_type wakeup_timer_lock;
/** if wakeup timer is enabled in some thread */
int wakeup_timer_enabled;
/** command pipe that stops the pipe if closed. Used to quit
* the program. [0] is read, [1] is written to. */
int commandpipe[2];
@ -233,9 +242,10 @@ struct dt_io_list_item {
/**
* Create new (empty) worker message queue. Limit set to default on max.
* @param base: event base for wakeup timer.
* @return NULL on malloc failure or a new queue (not locked).
*/
struct dt_msg_queue* dt_msg_queue_create(void);
struct dt_msg_queue* dt_msg_queue_create(struct comm_base* base);
/**
* Delete a worker message queue. It has to be unlinked from access,
@ -258,6 +268,9 @@ void dt_msg_queue_delete(struct dt_msg_queue* mq);
*/
void dt_msg_queue_submit(struct dt_msg_queue* mq, void* buf, size_t len);
/** timer callback to wakeup dtio thread to process messages */
void mq_wakeup_cb(void* arg);
/**
* Create IO thread.
* @return new io thread object. not yet started. or NULL malloc failure.

View File

@ -278,57 +278,31 @@ static int make_tcp_accept(char* ip)
}
if((s = socket(addr.ss_family, SOCK_STREAM, 0)) == -1) {
#ifndef USE_WINSOCK
log_err("can't create socket: %s", strerror(errno));
#else
log_err("can't create socket: %s",
wsa_strerror(WSAGetLastError()));
#endif
log_err("can't create socket: %s", sock_strerror(errno));
return -1;
}
#ifdef SO_REUSEADDR
if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void*)&on,
(socklen_t)sizeof(on)) < 0) {
#ifndef USE_WINSOCK
log_err("setsockopt(.. SO_REUSEADDR ..) failed: %s",
strerror(errno));
close(s);
#else
log_err("setsockopt(.. SO_REUSEADDR ..) failed: %s",
wsa_strerror(WSAGetLastError()));
closesocket(s);
#endif
sock_strerror(errno));
sock_close(s);
return -1;
}
#endif /* SO_REUSEADDR */
if(bind(s, (struct sockaddr*)&addr, len) != 0) {
#ifndef USE_WINSOCK
log_err_addr("can't bind socket", strerror(errno),
log_err_addr("can't bind socket", sock_strerror(errno),
&addr, len);
close(s);
#else
log_err_addr("can't bind socket",
wsa_strerror(WSAGetLastError()), &addr, len);
closesocket(s);
#endif
sock_close(s);
return -1;
}
if(!fd_set_nonblock(s)) {
#ifndef USE_WINSOCK
close(s);
#else
closesocket(s);
#endif
sock_close(s);
return -1;
}
if(listen(s, LISTEN_BACKLOG) == -1) {
#ifndef USE_WINSOCK
log_err("can't listen: %s", strerror(errno));
close(s);
#else
log_err("can't listen: %s", wsa_strerror(WSAGetLastError()));
closesocket(s);
#endif
log_err("can't listen: %s", sock_strerror(errno));
sock_close(s);
return -1;
}
return s;
@ -654,7 +628,6 @@ static ssize_t receive_bytes(struct tap_data* data, int fd, void* buf,
#ifndef USE_WINSOCK
if(errno == EINTR || errno == EAGAIN)
return -1;
log_err("could not recv: %s", strerror(errno));
#else /* USE_WINSOCK */
if(WSAGetLastError() == WSAEINPROGRESS)
return -1;
@ -662,9 +635,8 @@ static ssize_t receive_bytes(struct tap_data* data, int fd, void* buf,
ub_winsock_tcp_wouldblock(data->ev, UB_EV_READ);
return -1;
}
log_err("could not recv: %s",
wsa_strerror(WSAGetLastError()));
#endif
log_err("could not recv: %s", sock_strerror(errno));
if(verbosity) log_info("dnstap client stream closed from %s",
(data->id?data->id:""));
return 0;
@ -796,12 +768,7 @@ static int reply_with_accept(struct tap_data* data)
}
} else {
if(send(data->fd, acceptframe, len, 0) == -1) {
#ifndef USE_WINSOCK
log_err("send failed: %s", strerror(errno));
#else
log_err("send failed: %s",
wsa_strerror(WSAGetLastError()));
#endif
log_err("send failed: %s", sock_strerror(errno));
fd_set_nonblock(data->fd);
free(acceptframe);
return 0;
@ -834,11 +801,7 @@ static int reply_with_finish(int fd)
fd_set_block(fd);
if(send(fd, finishframe, len, 0) == -1) {
#ifndef USE_WINSOCK
log_err("send failed: %s", strerror(errno));
#else
log_err("send failed: %s", wsa_strerror(WSAGetLastError()));
#endif
log_err("send failed: %s", sock_strerror(errno));
fd_set_nonblock(fd);
free(finishframe);
return 0;
@ -1094,7 +1057,6 @@ void dtio_mainfdcallback(int fd, short ATTR_UNUSED(bits), void* arg)
#endif /* EPROTO */
)
return;
log_err_addr("accept failed", strerror(errno), &addr, addrlen);
#else /* USE_WINSOCK */
if(WSAGetLastError() == WSAEINPROGRESS ||
WSAGetLastError() == WSAECONNRESET)
@ -1103,9 +1065,9 @@ void dtio_mainfdcallback(int fd, short ATTR_UNUSED(bits), void* arg)
ub_winsock_tcp_wouldblock(maindata->ev, UB_EV_READ);
return;
}
log_err_addr("accept failed", wsa_strerror(WSAGetLastError()),
&addr, addrlen);
#endif
log_err_addr("accept failed", sock_strerror(errno), &addr,
addrlen);
return;
}
fd_set_nonblock(s);
@ -1205,8 +1167,10 @@ int sig_quit = 0;
static RETSIGTYPE main_sigh(int sig)
{
verbose(VERB_ALGO, "exit on signal %d\n", sig);
if(sig_base)
if(sig_base) {
ub_event_base_loopexit(sig_base);
sig_base = NULL;
}
sig_quit = 1;
}
@ -1247,9 +1211,9 @@ setup_and_run(struct config_strlist_head* local_list,
if(verbosity) log_info("start of service");
ub_event_base_dispatch(base);
sig_base = NULL;
if(verbosity) log_info("end of service");
sig_base = NULL;
tap_socket_list_delete(maindata->acceptlist);
ub_event_base_free(base);
free(maindata);

View File

@ -1,3 +1,133 @@
1 October 2020: Wouter
- Current repo is version 1.12.0 for release. Tag for 1.12.0rc1.
30 September 2020: Wouter
- Fix doh tests when not compiled in.
- Add dohclient test executable to gitignore.
- Fix stream_ssl, ssl_req_order and ssl_req_timeout tests for
alloc check debug output.
- Easier kill of unbound-dnstap-socket tool in test.
- Fix memory leak of edns tags at libunbound context delete.
- Fix double loopexit for unbound-dnstap-socket after sigterm.
29 September 2020: Ralph
- DNS Flag Day 2020: change edns-buffer-size default to 1232.
28 September 2020: Wouter
- Fix unit test for dnstap changes, so that it waits for the timer.
23 September 2020: Wouter
- Fix #305: dnstap logging significantly affects unbound performance
(regression in 1.11).
- Fix #305: only wake up thread when threshold reached.
- Fix to ifdef fptr wlist item for dnstap.
23 September 2020: Ralph
- Fix edns-client-tags get_option typo
- Add edns-client-tag-opcode option
- Use inclusive language in configuration
21 September 2020: Ralph
- Fix #304: dnstap logging not recovering after dnstap process restarts
21 September 2020: Wouter
- Merge PR #311 by luismerino: Dynlibmod leak.
- Error message is logged for dynlibmod malloc failures.
- iana portlist updated.
18 September 2020: Wouter
- Fix that prefer-ip4 and prefer-ip6 can be get and set with
unbound-control, with libunbound and the unbound-checkconf option
output function.
- iana portlist updated.
15 September 2020: George
- Introduce test for statistics.
15 September 2020: Wouter
- Spelling fix.
11 September 2020: Wouter
- Remove x file mode on ipset/ipset.c and h files.
9 September 2020: Wouter
- Fix num.expired statistics output.
31 August 2020: Wouter
- Merge PR #293: Add missing prototype. Also refactor to use the new
shorthand function to clean up the code.
- Refactor to use sock_strerr shorthand function.
- Fix #296: systemd nss-lookup.target is reached before unbound can
successfully answer queries. Changed contrib/unbound.service.in.
27 August 2020: Wouter
- Similar to NSD PR#113, implement that interface names can be used,
eg. something like interface: eth0 is resolved at server start and
uses the IP addresses for that named interface.
- Review fix, doxygen and assign null in case of error free.
26 August 2020: George
- Update documentation in python example code.
24 August 2020: Wouter
- Fix that dnstap reconnects do not spam the log with the repeated
attempts. Attempts on the timer are only logged on high verbosity,
if they produce a connection failure error.
- Fix to apply chroot to dnstap-socket-path, if chroot is enabled.
- Change configure to use EVP_sha256 instead of HMAC_Update for
openssl-3.0.0.
20 August 2020: Ralph
- Fix stats double count issue (#289).
13 August 2020: Ralph
- Create and init edns tags data for libunbound.
10 August 2020: Ralph
- Merge (modified) PR #277, use EVP_MAC_CTX_set_params if available,
by Vítězslav Čížek.
10 August 2020: Wouter
- Fix #287: doc typo: "Additionaly".
- Rerun autoconf
6 August 2020: Wouter
- Merge PR #284 and Fix #246: Remove DLV entirely from Unbound.
The DLV has been decommisioned and in unbound 1.5.4, in 2015, there
was advise to stop using it. The current code base does not contain
DLV code any more. The use of dlv options displays a warning.
5 August 2020: Wouter
- contrib/aaaa-filter-iterator.patch file renewed diff content to
apply cleanly to the current coderepo for the current code version.
5 August 2020: Ralph
- Merge PR #272: Add EDNS client tag functionality.
4 August 2020: George
- Improve error log message when inserting rpz RR.
- Merge PR #280, Make tvOS & watchOS checks verify truthiness as well as
definedness, by Felipe Gasper.
4 August 2020: Wouter
- Fix mini_event.h on OpenBSD cannot find fd_set.
31 July 2020: Wouter
- Fix doxygen comment for no ssl for tls session ticket key callback
routine.
27 July 2020: George
- Merge PR #268, draft-ietf-dnsop-serve-stale-10 has become RFC 8767 on
March 2020, by and0x000.
27 July 2020: Ralph
- Merge PR #269, Fix python module len() implementations, by Torbjörn
Lönnemark
27 July 2020: Wouter
- branch now named 1.11.1. 1.11.0rc1 became the 1.11.0 release.
- Merge PR #270 from cgzones: munin plugin: always exit 0 in autoconf
20 July 2020: Wouter
- Fix streamtcp to print packet data to stdout. This makes the
stdout and stderr not mix together lines, when parsing its output.

View File

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

View File

@ -1,7 +1,7 @@
#
# Example configuration file.
#
# See unbound.conf(5) man page, version 1.11.0.
# See unbound.conf(5) man page, version 1.12.0.
#
# this is a comment.
@ -129,8 +129,8 @@ server:
# ip-dscp: 0
# EDNS reassembly buffer to advertise to UDP peers (the actual buffer
# is set with msg-buffer-size). 1472 can solve fragmentation (timeouts)
# edns-buffer-size: 4096
# is set with msg-buffer-size).
# edns-buffer-size: 1232
# Maximum UDP response size (not applied to TCP response).
# Suggested values are 512 to 4096. Default is 4096. 65536 disables it.
@ -431,8 +431,8 @@ server:
# Domains (and domains in them) without support for dns-0x20 and
# the fallback fails because they keep sending different answers.
# caps-whitelist: "licdn.com"
# caps-whitelist: "senderbase.org"
# caps-exempt: "licdn.com"
# caps-exempt: "senderbase.org"
# Enforce privacy of these addresses. Strips them away from answers.
# It may cause DNSSEC validation to additionally mark it as bogus.
@ -509,11 +509,6 @@ server:
# Root key trust anchor sentinel (draft-ietf-dnsop-kskroll-sentinel)
# root-key-sentinel: yes
# File with DLV trusted keys. Same format as trust-anchor-file.
# There can be only one DLV configured, it is trusted from root down.
# DLV is going to be decommissioned. Please do not use it any more.
# dlv-anchor-file: "dlv.isc.org.key"
# File with trusted keys for validation. Specify more than one file
# with several entries, one file per entry.
# Zone file format, with DS and DNSKEY entries.
@ -589,7 +584,7 @@ server:
#
# Time in milliseconds before replying to the client with expired data.
# This essentially enables the serve-stale behavior as specified in
# draft-ietf-dnsop-serve-stale-10 that first tries to resolve before
# RFC 8767 that first tries to resolve before
# immediately responding with expired data. 0 disables this behavior.
# A recommended value is 1800.
# serve-expired-client-timeout: 0
@ -627,7 +622,7 @@ server:
# more slabs reduce lock contention, but fragment memory usage.
# key-cache-slabs: 4
# the amount of memory to use for the negative cache (used for DLV).
# the amount of memory to use for the negative cache.
# plain value in bytes or you can append k, m or G. default is "1Mb".
# neg-cache-size: 1m
@ -738,12 +733,14 @@ server:
# add a netblock specific override to a localzone, with zone type
# local-zone-override: "example.com" 192.0.2.0/24 refuse
# service clients over TLS (on the TCP sockets), with plain DNS inside
# the TLS stream. Give the certificate to use and private key.
# service clients over TLS (on the TCP sockets) with plain DNS inside
# the TLS stream, and over HTTPS using HTTP/2 as specified in RFC8484.
# Give the certificate to use and private key.
# default is "" (disabled). requires restart to take effect.
# tls-service-key: "path/to/privatekeyfile.key"
# tls-service-pem: "path/to/publiccertfile.pem"
# tls-port: 853
# https-port: 443
# cipher setting for TLSv1.2
# tls-ciphers: "DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256"
@ -775,6 +772,22 @@ server:
# Also serve tls on these port numbers (eg. 443, ...), by listing
# tls-additional-port: portno for each of the port numbers.
# HTTP endpoint to provide DNS-over-HTTPS service on.
# http-endpoint: "/dns-query"
# HTTP/2 SETTINGS_MAX_CONCURRENT_STREAMS value to use.
# http-max-streams: 100
# Maximum number of bytes used for all HTTP/2 query buffers.
# http-query-buffer-size: 4m
# Maximum number of bytes used for all HTTP/2 response buffers.
# http-response-buffer-size: 4m
# Set TCP_NODELAY socket option on sockets used for DNS-over-HTTPS
# service.
# http-nodelay: yes
# DNS64 prefix. Must be specified when DNS64 is use.
# Enable dns64 in module-config. Used to synthesize IPv6 from IPv4.
# dns64-prefix: 64:ff9b::0/96
@ -848,9 +861,9 @@ server:
# ipsecmod-ignore-bogus: no
#
# Domains for which ipsecmod will be triggered. If not defined (default)
# all domains are treated as being whitelisted.
# ipsecmod-whitelist: "example.com"
# ipsecmod-whitelist: "nlnetlabs.nl"
# all domains are treated as being allowed.
# ipsecmod-allow: "example.com"
# ipsecmod-allow: "nlnetlabs.nl"
# Python config section. To enable:
@ -948,27 +961,27 @@ remote-control:
# upstream (which saves a lookup to the upstream). The first example
# has a copy of the root for local usage. The second serves example.org
# authoritatively. zonefile: reads from file (and writes to it if you also
# download it), master: fetches with AXFR and IXFR, or url to zonefile.
# With allow-notify: you can give additional (apart from masters) sources of
# download it), primary: fetches with AXFR and IXFR, or url to zonefile.
# With allow-notify: you can give additional (apart from primaries) sources of
# notifies.
# auth-zone:
# name: "."
# master: 199.9.14.201 # b.root-servers.net
# master: 192.33.4.12 # c.root-servers.net
# master: 199.7.91.13 # d.root-servers.net
# master: 192.5.5.241 # f.root-servers.net
# master: 192.112.36.4 # g.root-servers.net
# master: 193.0.14.129 # k.root-servers.net
# master: 192.0.47.132 # xfr.cjr.dns.icann.org
# master: 192.0.32.132 # xfr.lax.dns.icann.org
# master: 2001:500:200::b # b.root-servers.net
# master: 2001:500:2::c # c.root-servers.net
# master: 2001:500:2d::d # d.root-servers.net
# master: 2001:500:2f::f # f.root-servers.net
# master: 2001:500:12::d0d # g.root-servers.net
# master: 2001:7fd::1 # k.root-servers.net
# master: 2620:0:2830:202::132 # xfr.cjr.dns.icann.org
# master: 2620:0:2d0:202::132 # xfr.lax.dns.icann.org
# primary: 199.9.14.201 # b.root-servers.net
# primary: 192.33.4.12 # c.root-servers.net
# primary: 199.7.91.13 # d.root-servers.net
# primary: 192.5.5.241 # f.root-servers.net
# primary: 192.112.36.4 # g.root-servers.net
# primary: 193.0.14.129 # k.root-servers.net
# primary: 192.0.47.132 # xfr.cjr.dns.icann.org
# primary: 192.0.32.132 # xfr.lax.dns.icann.org
# primary: 2001:500:200::b # b.root-servers.net
# primary: 2001:500:2::c # c.root-servers.net
# primary: 2001:500:2d::d # d.root-servers.net
# primary: 2001:500:2f::f # f.root-servers.net
# primary: 2001:500:12::d0d # g.root-servers.net
# primary: 2001:7fd::1 # k.root-servers.net
# primary: 2620:0:2830:202::132 # xfr.cjr.dns.icann.org
# primary: 2620:0:2d0:202::132 # xfr.lax.dns.icann.org
# fallback-enabled: yes
# for-downstream: no
# for-upstream: yes
@ -1088,7 +1101,7 @@ remote-control:
# rpz:
# name: "rpz.example.com"
# zonefile: "rpz.example.com"
# master: 192.0.2.0
# primary: 192.0.2.0
# allow-notify: 192.0.2.0/32
# url: http://www.example.com/rpz.example.org.zone
# rpz-action-override: cname

View File

@ -1,4 +1,4 @@
.TH "libunbound" "3" "Jul 27, 2020" "NLnet Labs" "unbound 1.11.0"
.TH "libunbound" "3" "Oct 8, 2020" "NLnet Labs" "unbound 1.12.0"
.\"
.\" libunbound.3 -- unbound library functions manual
.\"
@ -44,7 +44,7 @@
.B ub_ctx_zone_remove,
.B ub_ctx_data_add,
.B ub_ctx_data_remove
\- Unbound DNS validating resolver 1.11.0 functions.
\- Unbound DNS validating resolver 1.12.0 functions.
.SH "SYNOPSIS"
.B #include <unbound.h>
.LP

View File

@ -1,4 +1,4 @@
.TH "unbound-anchor" "8" "Jul 27, 2020" "NLnet Labs" "unbound 1.11.0"
.TH "unbound-anchor" "8" "Oct 8, 2020" "NLnet Labs" "unbound 1.12.0"
.\"
.\" unbound-anchor.8 -- unbound anchor maintenance utility manual
.\"

View File

@ -1,4 +1,4 @@
.TH "unbound-checkconf" "8" "Jul 27, 2020" "NLnet Labs" "unbound 1.11.0"
.TH "unbound-checkconf" "8" "Oct 8, 2020" "NLnet Labs" "unbound 1.12.0"
.\"
.\" unbound-checkconf.8 -- unbound configuration checker manual
.\"

View File

@ -1,4 +1,4 @@
.TH "unbound-control" "8" "Jul 27, 2020" "NLnet Labs" "unbound 1.11.0"
.TH "unbound-control" "8" "Oct 8, 2020" "NLnet Labs" "unbound 1.12.0"
.\"
.\" unbound-control.8 -- unbound remote control manual
.\"
@ -506,6 +506,14 @@ negative cache.
Memory in bytes in used by the TCP and TLS stream wait buffers. These are
answers waiting to be written back to the clients.
.TP
.I mem.http.query_buffer
Memory in bytes used by the HTTP/2 query buffers. Containing (partial) DNS
queries waiting for request stream completion.
.TP
.I mem.http.response_buffer
Memory in bytes used by the HTTP/2 response buffers. Containing DNS responses
waiting to be written back to the clients.
.TP
.I histogram.<sec>.<usec>.to.<sec>.<usec>
Shows a histogram, summed over all threads. Every element counts the
recursive queries whose reply time fit between the lower and upper bound.
@ -545,6 +553,11 @@ These are also counted in num.query.tcp, because TLS uses TCP.
Number of TLS session resumptions, these are queries over TLS towards
the unbound server where the client negotiated a TLS session resumption key.
.TP
.I num.query.https
Number of queries that were made using HTTPS towards the unbound server.
These are also counted in num.query.tcp and num.query.tls, because HTTPS
uses TLS and TCP.
.TP
.I num.query.ipv6
Number of queries that were made using IPv6 towards the unbound server.
.TP

View File

@ -1,4 +1,4 @@
.TH "unbound\-host" "1" "Jul 27, 2020" "NLnet Labs" "unbound 1.11.0"
.TH "unbound\-host" "1" "Oct 8, 2020" "NLnet Labs" "unbound 1.12.0"
.\"
.\" unbound-host.1 -- unbound DNS lookup utility
.\"

View File

@ -1,4 +1,4 @@
.TH "unbound" "8" "Jul 27, 2020" "NLnet Labs" "unbound 1.11.0"
.TH "unbound" "8" "Oct 8, 2020" "NLnet Labs" "unbound 1.12.0"
.\"
.\" unbound.8 -- unbound manual
.\"
@ -9,7 +9,7 @@
.\"
.SH "NAME"
.B unbound
\- Unbound DNS validating resolver 1.11.0.
\- Unbound DNS validating resolver 1.12.0.
.SH "SYNOPSIS"
.B unbound
.RB [ \-h ]

View File

@ -1,4 +1,4 @@
.TH "unbound.conf" "5" "Jul 27, 2020" "NLnet Labs" "unbound 1.11.0"
.TH "unbound.conf" "5" "Oct 8, 2020" "NLnet Labs" "unbound 1.12.0"
.\"
.\" unbound.conf.5 -- unbound.conf manual
.\"
@ -122,7 +122,8 @@ The port number, default 53, on which the server responds to queries.
Interface to use to connect to the network. This interface is listened to
for queries from clients, and answers to clients are given from it.
Can be given multiple times to work on several interfaces. If none are
given the default is to listen to localhost.
given the default is to listen to localhost. If an interface name is used
instead of an ip address, the list of ip addresses on that interface are used.
The interfaces are not changed on a reload (kill \-HUP) but only on restart.
A port number can be specified with @port (without spaces between
interface and port number), if not specified the default port (from
@ -206,12 +207,11 @@ accepted. For larger installations increasing this value is a good idea.
Number of bytes size to advertise as the EDNS reassembly buffer size.
This is the value put into datagrams over UDP towards peers. The actual
buffer size is determined by msg\-buffer\-size (both for TCP and UDP). Do
not set higher than that value. Default is 4096 which is RFC recommended.
If you have fragmentation reassembly problems, usually seen as timeouts,
then a value of 1472 can fix it. Setting to 512 bypasses even the most
stringent path MTU problems, but is seen as extreme, since the amount
of TCP fallback generated is excessive (probably also for this resolver,
consider tuning the outgoing tcp number).
not set higher than that value. Default is 1232 which is the DNS Flag Day 2020
recommendation. Setting to 512 bypasses even the most stringent path MTU
problems, but is seen as extreme, since the amount of TCP fallback generated is
excessive (probably also for this resolver, consider tuning the outgoing tcp
number).
.TP
.B max\-udp\-size: \fI<number>
Maximum UDP response size (not applied to TCP response). 65536 disables the
@ -484,15 +484,16 @@ Alternate syntax for \fBtls\-upstream\fR. If both are present in the config
file the last is used.
.TP
.B tls\-service\-key: \fI<file>
If enabled, the server provides TLS service on the TCP ports marked
implicitly or explicitly for TLS service with tls\-port. The file must
contain the private key for the TLS session, the public certificate is in
the tls\-service\-pem file and it must also be specified if tls\-service\-key
is specified. The default is "", turned off. 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 \fBtls\-port:\fR do not provide
normal DNS TCP service.
If enabled, the server provides DNS-over-TLS or DNS-over-HTTPS service on the
TCP ports marked implicitly or explicitly for these services with tls\-port or
https\-port. The file must contain the private key for the TLS session, the
public certificate is in the tls\-service\-pem file and it must also be
specified if tls\-service\-key is specified. The default is "", turned off.
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 \fBtls\-port:\fR and
\fBhttps\-port:\fR do not provide normal DNS TCP service. Unbound needs to be
compiled with libnghttp2 in order to provide DNS-over-HTTPS.
.TP
.B ssl\-service\-key: \fI<file>
Alternate syntax for \fBtls\-service\-key\fR.
@ -557,6 +558,35 @@ Enable or disable sending the SNI extension on TLS connections.
Default is yes.
Changing the value requires a reload.
.TP
.B https\-port: \fI<number>
The port number on which to provide DNS-over-HTTPS service, default 443, only
interfaces configured with that port number as @number get the HTTPS service.
.TP
.B http\-endpoint: \fI<endpoint string>
The HTTP endpoint to provide DNS-over-HTTPS service on. Default "/dns-query".
.TP
.B http\-max\-streams: \fI<number of streams>
Number used in the SETTINGS_MAX_CONCURRENT_STREAMS parameter in the HTTP/2
SETTINGS frame for DNS-over-HTTPS connections. Default 100.
.TP
.B http\-query\-buffer\-size: \fI<size in bytes>
Maximum number of bytes used for all HTTP/2 query buffers combined. These
buffers contain (partial) DNS queries waiting for request stream completion.
An RST_STREAM frame will be send to streams exceeding this limit. Default is 4
megabytes. A plain number is in bytes, append 'k', 'm' or 'g' for kilobytes,
megabytes or gigabytes (1024*1024 bytes in a megabyte).
.TP
.B http\-response\-buffer\-size: \fI<size in bytes>
Maximum number of bytes used for all HTTP/2 response buffers combined. These
buffers contain DNS responses waiting to be written back to the clients.
An RST_STREAM frame will be send to streams exceeding this limit. Default is 4
megabytes. A plain number is in bytes, append 'k', 'm' or 'g' for kilobytes,
megabytes or gigabytes (1024*1024 bytes in a megabyte).
.TP
.B http\-nodelay: \fI<yes or no>
Set TCP_NODELAY socket option on sockets used to provide DNS-over-HTTPS service.
Ignored if the option is not available. Default is yes.
.TP
.B use\-systemd: \fI<yes or no>
Enable or disable systemd socket activation.
Default is no.
@ -853,12 +883,15 @@ authority servers and checks if the reply still has the correct casing.
Disabled by default.
This feature is an experimental implementation of draft dns\-0x20.
.TP
.B caps\-whitelist: \fI<domain>
Whitelist the domain so that it does not receive caps\-for\-id perturbed
.B caps\-exempt: \fI<domain>
Exempt the domain so that it does not receive caps\-for\-id perturbed
queries. For domains that do not support 0x20 and also fail with fallback
because they keep sending different answers, like some load balancers.
Can be given multiple times, for different domains.
.TP
.B caps\-whitelist: \fI<yes or no>
Alternate syntax for \fBcaps\-exempt\fR.
.TP
.B qname\-minimisation: \fI<yes or no>
Send minimum amount of information to upstream servers to enhance privacy.
Only send minimum required labels of the QNAME and set QTYPE to A when
@ -1010,26 +1043,11 @@ Send RFC8145 key tag query after trust anchor priming. Default is yes.
.B root\-key\-sentinel: \fI<yes or no>
Root key trust anchor sentinel. Default is yes.
.TP
.B dlv\-anchor\-file: \fI<filename>
This option was used during early days DNSSEC deployment when no parent-side
DS record registrations were easily available. Nowadays, it is best to have
DS records registered with the parent zone (many top level zones are signed).
File with trusted keys for DLV (DNSSEC Lookaside Validation). Both DS and
DNSKEY entries can be used in the file, in the same format as for
\fItrust\-anchor\-file:\fR statements. Only one DLV can be configured, more
would be slow. The DLV configured is used as a root trusted DLV, this
means that it is a lookaside for the root. Default is "", or no dlv anchor
file. DLV is going to be decommissioned. Please do not use it any more.
.TP
.B dlv\-anchor: \fI<"Resource Record">
Much like trust\-anchor, this is a DLV anchor with the DS or DNSKEY inline.
DLV is going to be decommissioned. Please do not use it any more.
.TP
.B domain\-insecure: \fI<domain name>
Sets domain name to be insecure, DNSSEC chain of trust is ignored towards
the domain name. So a trust anchor above the domain name can not make the
domain secure with a DS record, such a DS record is then ignored.
Also keys from DLV are ignored for the domain. Can be given multiple times
Can be given multiple times
to specify multiple domains that are treated as if unsigned. If you set
trust anchors for the domain they override this setting (and the domain
is secured).
@ -1108,7 +1126,7 @@ later on. Default is "no".
.B serve\-expired\-ttl: \fI<seconds>
Limit serving of expired responses to configured seconds after expiration. 0
disables the limit. This option only applies when \fBserve\-expired\fR is
enabled. A suggested value per draft-ietf-dnsop-serve-stale-10 is between
enabled. A suggested value per RFC 8767 is between
86400 (1 day) and 259200 (3 days). The default is 0.
.TP
.B serve\-expired\-ttl\-reset: \fI<yes or no>
@ -1120,14 +1138,14 @@ expired records will be served as long as there are queries for it. Default is
.B serve\-expired\-reply\-ttl: \fI<seconds>
TTL value to use when replying with expired data. If
\fBserve\-expired\-client\-timeout\fR is also used then it is RECOMMENDED to
use 30 as the value (draft-ietf-dnsop-serve-stale-10). The default is 30.
use 30 as the value (RFC 8767). The default is 30.
.TP
.B serve\-expired\-client\-timeout: \fI<msec>
Time in milliseconds before replying to the client with expired data. This
essentially enables the serve-stale behavior as specified in
draft-ietf-dnsop-serve-stale-10 that first tries to resolve before immediately
RFC 8767 that first tries to resolve before immediately
responding with expired data. A recommended value per
draft-ietf-dnsop-serve-stale-10 is 1800. Setting this to 0 will disable this
RFC 8767 is 1800. Setting this to 0 will disable this
behavior. Default is 0.
.TP
.B val\-nsec3\-keysize\-iterations: \fI<"list of values">
@ -1516,6 +1534,16 @@ servers set. The default for fast\-server\-permil is 0.
Set the number of servers that should be used for fast server selection. Only
use the fastest specified number of servers with the fast\-server\-permil
option, that turns this on or off. The default is to use the fastest 3 servers.
.TP 5
.B edns\-client\-tag: \fI<IP netblock> <tag data>
Include an edns-client-tag option in queries with destination address matching
the configured IP netblock. This configuration option can be used multiple
times. The most specific match will be used. The tag data is configured in
decimal format, from 0 to 65535.
.TP 5
.B edns\-client\-tag\-opcode: \fI<opcode>
EDNS0 option code for the edns-client-tag option, from 0 to 65535. Default is
16, as assigned by IANA.
.SS "Remote Control Options"
In the
.B remote\-control:
@ -1718,16 +1746,16 @@ uses the SOA timer values and performs SOA UDP queries to detect zone changes.
If the update fetch fails, the timers in the SOA record are used to time
another fetch attempt. Until the SOA expiry timer is reached. Then the
zone is expired. When a zone is expired, queries are SERVFAIL, and
any new serial number is accepted from the master (even if older), and if
any new serial number is accepted from the primary (even if older), and if
fallback is enabled, the fallback activates to fetch from the upstream instead
of the SERVFAIL.
.TP
.B name: \fI<zone name>
Name of the authority zone.
.TP
.B master: \fI<IP address or host name>
.B primary: \fI<IP address or host name>
Where to download a copy of the zone from, with AXFR and IXFR. Multiple
masters can be specified. They are all tried if one fails.
primaries can be specified. They are all tried if one fails.
With the "ip#name" notation a AXFR over TLS can be used.
If you point it at another Unbound instance, it would not work because
that does not support AXFR/IXFR for the zone, but if you used \fBurl:\fR to download
@ -1736,27 +1764,31 @@ If you specify the hostname, you cannot use the domain from the zonefile,
because it may not have that when retrieving that data, instead use a plain
IP address to avoid a circular dependency on retrieving that IP address.
.TP
.B master: \fI<IP address or host name>
Alternate syntax for \fBprimary\fR.
.TP
.B url: \fI<url to zonefile>
Where to download a zonefile for the zone. With http or https. An example
for the url is "http://www.example.com/example.org.zone". Multiple url
statements can be given, they are tried in turn. If only urls are given
the SOA refresh timer is used to wait for making new downloads. If also
masters are listed, the masters are first probed with UDP SOA queries to
primaries are listed, the primaries are first probed with UDP SOA queries to
see if the SOA serial number has changed, reducing the number of downloads.
If none of the urls work, the masters are tried with IXFR and AXFR.
If none of the urls work, the primaries are tried with IXFR and AXFR.
For https, the \fBtls\-cert\-bundle\fR and the hostname from the url are used
to authenticate the connection.
If you specify a hostname in the URL, you cannot use the domain from the
zonefile, because it may not have that when retrieving that data, instead
use a plain IP address to avoid a circular dependency on retrieving that IP
address. Avoid dependencies on name lookups by using a notation like "http://192.0.2.1/unbound-master/example.com.zone", with an explicit IP address.
address. Avoid dependencies on name lookups by using a notation like
"http://192.0.2.1/unbound-primaries/example.com.zone", with an explicit IP address.
.TP
.B allow\-notify: \fI<IP address or host name or netblockIP/prefix>
With allow\-notify you can specify additional sources of notifies.
When notified, the server attempts to first probe and then zone transfer.
If the notify is from a master, it first attempts that master. Otherwise
other masters are attempted. If there are no masters, but only urls, the
file is downloaded when notified. The masters from master: statements are
If the notify is from a primary, it first attempts that primary. Otherwise
other primaries are attempted. If there are no primaries, but only urls, the
file is downloaded when notified. The primaries from primary: statements are
allowed notify by default.
.TP
.B fallback\-enabled: \fI<yes or no>
@ -1784,7 +1816,7 @@ downstream clients, and use the zone data as a local copy to speed up lookups.
.B zonefile: \fI<filename>
The filename where the zone is stored. If not given then no zonefile is used.
If the file does not exist or is empty, unbound will attempt to fetch zone
data (eg. from the master servers).
data (eg. from the primary servers).
.SS "View Options"
.LP
There may be multiple
@ -1951,14 +1983,16 @@ The ECS module must be configured in the \fBmodule\-config:\fR "subnetcache
validator iterator" directive and be compiled into the daemon to be
enabled. These settings go in the \fBserver:\fR section.
.LP
If the destination address is whitelisted with Unbound will add the EDNS0
option to the query containing the relevant part of the client's address. When
an answer contains the ECS option the response and the option are placed in a
specialized cache. If the authority indicated no support, the response is
If the destination address is allowed in the configuration Unbound will add the
EDNS0 option to the query containing the relevant part of the client's address.
When an answer contains the ECS option the response and the option are placed in
a specialized cache. If the authority indicated no support, the response is
stored in the regular cache.
.LP
Additionally, when a client includes the option in its queries, Unbound will
forward the option to the authority if present in the whitelist, or
forward the option when sending the query to addresses that are explicitly
allowed in the configuration using \fBsend\-client\-subnet\fR. The option will
always be forwarded, regardless the allowed addresses, if
\fBclient\-subnet\-always\-forward\fR is set to yes. In this case the lookup in
the regular cache is skipped.
.LP
@ -1979,11 +2013,11 @@ given multiple times. Zones not listed will not receive edns-subnet information,
unless hosted by authority specified in \fBsend\-client\-subnet\fR.
.TP
.B client\-subnet\-always\-forward: \fI<yes or no>\fR
Specify whether the ECS whitelist check (configured using
Specify whether the ECS address check (configured using
\fBsend\-client\-subnet\fR) is applied for all queries, even if the triggering
query contains an ECS record, or only for queries for which the ECS record is
generated using the querier address (and therefore did not contain ECS data in
the client query). If enabled, the whitelist check is skipped when the client
the client query). If enabled, the address check is skipped when the client
query contains an ECS record. Default is no.
.TP
.B max\-client\-subnet\-ipv6: \fI<number>\fR
@ -2073,10 +2107,13 @@ to yes, the hook will be called and the A/AAAA answer will be returned to the
client. If set to no, the hook will not be called and the answer to the
A/AAAA query will be SERVFAIL. Mainly used for testing. Defaults to no.
.TP
.B ipsecmod\-whitelist: \fI<domain>\fR
Whitelist the domain so that the module logic will be executed. Can
be given multiple times, for different domains. If the option is not
specified, all domains are treated as being whitelisted (default).
.B ipsecmod\-allow: \fI<domain>\fR
Allow the ipsecmod functionality for the domain so that the module logic will be
executed. Can be given multiple times, for different domains. If the option is
not specified, all domains are treated as being allowed (default).
.TP
.B ipsecmod\-whitelist: \fI<yes or no>
Alternate syntax for \fBipsecmod\-allow\fR.
.SS "Cache DB Module Options"
.LP
The Cache DB module must be configured in the \fBmodule\-config:\fR
@ -2110,7 +2147,7 @@ even if some data have expired in terms of DNS TTL or the Redis server has
cached too much data;
if necessary the Redis server must be configured to limit the cache size,
preferably with some kind of least-recently-used eviction policy.
Additionaly, the \fBredis\-expire\-records\fR option can be used in order to
Additionally, the \fBredis\-expire\-records\fR option can be used in order to
set the relative DNS TTL of the message as timeout to the Redis records; keep
in mind that some additional memory is used per key and that the expire
information is stored as absolute Unix timestamps in Redis (computer time must
@ -2273,33 +2310,36 @@ are applied after
.B name: \fI<zone name>
Name of the authority zone.
.TP
.B master: \fI<IP address or host name>
.B primary: \fI<IP address or host name>
Where to download a copy of the zone from, with AXFR and IXFR. Multiple
masters can be specified. They are all tried if one fails.
primaries can be specified. They are all tried if one fails.
.TP
.B master: \fI<IP address or host name>
Alternate syntax for \fBprimary\fR.
.TP
.B url: \fI<url to zonefile>
Where to download a zonefile for the zone. With http or https. An example
for the url is "http://www.example.com/example.org.zone". Multiple url
statements can be given, they are tried in turn. If only urls are given
the SOA refresh timer is used to wait for making new downloads. If also
masters are listed, the masters are first probed with UDP SOA queries to
primaries are listed, the primaries are first probed with UDP SOA queries to
see if the SOA serial number has changed, reducing the number of downloads.
If none of the urls work, the masters are tried with IXFR and AXFR.
If none of the urls work, the primaries are tried with IXFR and AXFR.
For https, the \fBtls\-cert\-bundle\fR and the hostname from the url are used
to authenticate the connection.
.TP
.B allow\-notify: \fI<IP address or host name or netblockIP/prefix>
With allow\-notify you can specify additional sources of notifies.
When notified, the server attempts to first probe and then zone transfer.
If the notify is from a master, it first attempts that master. Otherwise
other masters are attempted. If there are no masters, but only urls, the
file is downloaded when notified. The masters from master: statements are
If the notify is from a primary, it first attempts that primary. Otherwise
other primaries are attempted. If there are no primaries, but only urls, the
file is downloaded when notified. The primaries from primary: statements are
allowed notify by default.
.TP
.B zonefile: \fI<filename>
The filename where the zone is stored. If not given then no zonefile is used.
If the file does not exist or is empty, unbound will attempt to fetch zone
data (eg. from the master servers).
data (eg. from the primary servers).
.TP
.B rpz\-action\-override: \fI<action>
Always use this RPZ action for matching triggers from this zone. Possible action

View File

@ -242,6 +242,10 @@ int
inplace_cb_register_wrapped(void* cb, enum inplace_cb_list_type type, void* cbarg,
struct module_env* env, int id) {
struct cb_pair* cb_pair = malloc(sizeof(struct cb_pair));
if(cb_pair == NULL) {
log_err("dynlibmod[%d]: malloc failure", id);
return 0;
}
cb_pair->cb = cb;
cb_pair->cb_arg = cbarg;
if(type >= inplace_cb_reply && type <= inplace_cb_reply_servfail) {
@ -253,6 +257,7 @@ inplace_cb_register_wrapped(void* cb, enum inplace_cb_list_type type, void* cbar
} else if(type == inplace_cb_edns_back_parsed) {
return inplace_cb_register(&dynlib_inplace_cb_edns_back_parsed, type, (void*) cb_pair, env, id);
} else {
free(cb_pair);
return 0;
}
}

View File

@ -3191,7 +3191,7 @@ processPrimeResponse(struct module_qstate* qstate, int id)
/* validate the root or stub after priming (if enabled).
* This is the same query as the prime query, but with validation.
* Now that we are primed, the additional queries that validation
* may need can be resolved, such as DLV. */
* may need can be resolved. */
if(qstate->env->cfg->harden_referral_path) {
struct module_qstate* subq = NULL;
log_nametypeclass(VERB_ALGO, "schedule prime validation",

View File

@ -50,6 +50,7 @@
#include "services/authzone.h"
#include "util/data/msgreply.h"
#include "util/storage/slabhash.h"
#include "util/edns.h"
#include "sldns/sbuffer.h"
int
@ -79,6 +80,8 @@ context_finalize(struct ub_ctx* ctx)
return UB_INITFAIL;
if(!auth_zones_apply_cfg(ctx->env->auth_zones, cfg, 1, &is_rpz))
return UB_INITFAIL;
if(!edns_tags_apply_cfg(ctx->env->edns_tags, cfg))
return UB_INITFAIL;
if(!slabhash_is_size(ctx->env->msg_cache, cfg->msg_cache_size,
cfg->msg_cache_slabs)) {
slabhash_delete(ctx->env->msg_cache);

View File

@ -58,6 +58,7 @@
#include "util/net_help.h"
#include "util/tube.h"
#include "util/ub_event.h"
#include "util/edns.h"
#include "services/modstack.h"
#include "services/localzone.h"
#include "services/cache/infra.h"
@ -153,6 +154,18 @@ static struct ub_ctx* ub_ctx_create_nopipe(void)
errno = ENOMEM;
return NULL;
}
ctx->env->edns_tags = edns_tags_create();
if(!ctx->env->edns_tags) {
auth_zones_delete(ctx->env->auth_zones);
edns_known_options_delete(ctx->env);
config_delete(ctx->env->cfg);
free(ctx->env);
ub_randfree(ctx->seed_rnd);
free(ctx);
errno = ENOMEM;
return NULL;
}
ctx->env->alloc = &ctx->superalloc;
ctx->env->worker = NULL;
ctx->env->need_to_validate = 0;
@ -173,6 +186,7 @@ ub_ctx_create(void)
config_delete(ctx->env->cfg);
modstack_desetup(&ctx->mods, ctx->env);
edns_known_options_delete(ctx->env);
edns_tags_delete(ctx->env->edns_tags);
free(ctx->env);
free(ctx);
errno = e;
@ -185,6 +199,7 @@ ub_ctx_create(void)
config_delete(ctx->env->cfg);
modstack_desetup(&ctx->mods, ctx->env);
edns_known_options_delete(ctx->env);
edns_tags_delete(ctx->env->edns_tags);
free(ctx->env);
free(ctx);
errno = e;
@ -323,6 +338,7 @@ ub_ctx_delete(struct ub_ctx* ctx)
infra_delete(ctx->env->infra_cache);
config_delete(ctx->env->cfg);
edns_known_options_delete(ctx->env);
edns_tags_delete(ctx->env->edns_tags);
auth_zones_delete(ctx->env->auth_zones);
free(ctx->env);
}

View File

@ -78,7 +78,7 @@
#include <TargetConditionals.h>
#endif
#if defined(TARGET_OS_TV) || defined(TARGET_OS_WATCH)
#if (defined(TARGET_OS_TV) && TARGET_OS_TV) || (defined(TARGET_OS_WATCH) && TARGET_OS_WATCH)
#undef HAVE_FORK
#endif

View File

@ -697,6 +697,8 @@ struct ub_server_stats {
long long qtcp_outgoing;
/** number of queries over (DNS over) TLS */
long long qtls;
/** number of queries over (DNS over) HTTPS */
long long qhttps;
/** number of queries over IPv6 */
long long qipv6;
/** number of queries with QR bit */
@ -787,6 +789,10 @@ struct ub_server_stats {
long long num_query_subnet_cache;
/** number of bytes in the stream wait buffers */
long long mem_stream_wait;
/** number of bytes in the HTTP2 query buffers */
long long mem_http2_query_buffer;
/** number of bytes in the HTTP2 response buffers */
long long mem_http2_response_buffer;
/** number of TLS connection resume */
long long qtls_resume;
/** RPZ action stats */

View File

@ -890,9 +890,8 @@ dns_cache_lookup(struct module_env* env,
lock_rw_unlock(&rrset->entry.lock);
}
/* construct DS, DNSKEY, DLV messages from rrset cache. */
if((qtype == LDNS_RR_TYPE_DS || qtype == LDNS_RR_TYPE_DNSKEY ||
qtype == LDNS_RR_TYPE_DLV) &&
/* construct DS, DNSKEY messages from rrset cache. */
if((qtype == LDNS_RR_TYPE_DS || qtype == LDNS_RR_TYPE_DNSKEY) &&
(rrset=rrset_cache_lookup(env->rrset_cache, qname, qnamelen,
qtype, qclass, 0, now, 0))) {
/* if the rrset is from the additional section, and the

File diff suppressed because it is too large Load Diff

View File

@ -43,6 +43,9 @@
#define LISTEN_DNSPORT_H
#include "util/netevent.h"
#ifdef HAVE_NGHTTP2_NGHTTP2_H
#include <nghttp2/nghttp2.h>
#endif
struct listen_list;
struct config_file;
struct addrinfo;
@ -94,8 +97,9 @@ enum listen_type {
/** tcp type + dnscrypt */
listen_type_tcp_dnscrypt,
/** udp ipv6 (v4mapped) for use with ancillary data + dnscrypt*/
listen_type_udpancil_dnscrypt
listen_type_udpancil_dnscrypt,
/** HTTP(2) over TLS over TCP */
listen_type_http
};
/**
@ -117,19 +121,32 @@ struct listen_port {
* interfaces for IP4 and/or IP6, for UDP and/or TCP.
* On the given port number. It creates the sockets.
* @param cfg: settings on what ports to open.
* @param ifs: interfaces to open, array of IP addresses, "ip[@port]".
* @param num_ifs: length of ifs.
* @param reuseport: set to true if you want reuseport, or NULL to not have it,
* set to false on exit if reuseport failed to apply (because of no
* kernel support).
* @return: linked list of ports or NULL on error.
*/
struct listen_port* listening_ports_open(struct config_file* cfg,
int* reuseport);
char** ifs, int num_ifs, int* reuseport);
/**
* Close and delete the (list of) listening ports.
*/
void listening_ports_free(struct listen_port* list);
/**
* Resolve interface names in config and store result IP addresses
* @param cfg: config
* @param resif: string array (malloced array of malloced strings) with
* result. NULL if cfg has none.
* @param num_resif: length of resif. Zero if cfg has zero num_ifs.
* @return 0 on failure.
*/
int resolve_interface_names(struct config_file* cfg, char*** resif,
int* num_resif);
/**
* Create commpoints with for this thread for the shared ports.
* @param base: the comm_base that provides event functionality.
@ -139,6 +156,9 @@ void listening_ports_free(struct listen_port* list);
* @param tcp_accept_count: max number of simultaneous TCP connections
* from clients.
* @param tcp_idle_timeout: idle timeout for TCP connections in msec.
* @param harden_large_queries: whether query size should be limited.
* @param http_max_streams: maximum number of HTTP/2 streams per connection.
* @param http_endpoint: HTTP endpoint to service queries on
* @param tcp_conn_limit: TCP connection limit info.
* @param sslctx: nonNULL if ssl context.
* @param dtenv: nonNULL if dnstap enabled.
@ -147,11 +167,12 @@ void listening_ports_free(struct listen_port* list);
* @param cb_arg: user data argument for callback function.
* @return: the malloced listening structure, ready for use. NULL on error.
*/
struct listen_dnsport* listen_create(struct comm_base* base,
struct listen_port* ports, size_t bufsize,
int tcp_accept_count, int tcp_idle_timeout,
struct tcl_list* tcp_conn_limit, void* sslctx,
struct dt_env *dtenv, comm_point_callback_type* cb, void* cb_arg);
struct listen_dnsport*
listen_create(struct comm_base* base, struct listen_port* ports,
size_t bufsize, int tcp_accept_count, int tcp_idle_timeout,
int harden_large_queries, uint32_t http_max_streams,
char* http_endpoint, struct tcl_list* tcp_conn_limit, void* sslctx,
struct dt_env* dtenv, comm_point_callback_type* cb, void *cb_arg);
/**
* delete the listening structure
@ -221,13 +242,15 @@ int create_udp_sock(int family, int socktype, struct sockaddr* addr,
* listening UDP port. Set to false on return if it failed to do so.
* @param transparent: set IP_TRANSPARENT socket option.
* @param mss: maximum segment size of the socket. if zero, leaves the default.
* @param nodelay: if true set TCP_NODELAY and TCP_QUICKACK socket options.
* @param freebind: set IP_FREEBIND socket option.
* @param use_systemd: if true, fetch sockets from systemd.
* @param dscp: DSCP to use.
* @return: the socket. -1 on error.
*/
int create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto,
int* reuseport, int transparent, int mss, int freebind, int use_systemd, int dscp);
int* reuseport, int transparent, int mss, int nodelay, int freebind,
int use_systemd, int dscp);
/**
* Create and bind local listening socket
@ -369,7 +392,34 @@ int tcp_req_info_handle_read_close(struct tcp_req_info* req);
/** get the size of currently used tcp stream wait buffers (in bytes) */
size_t tcp_req_info_get_stream_buffer_size(void);
/** get the size of currently used HTTP2 query buffers (in bytes) */
size_t http2_get_query_buffer_size(void);
/** get the size of currently used HTTP2 response buffers (in bytes) */
size_t http2_get_response_buffer_size(void);
#ifdef HAVE_NGHTTP2
/**
* Create nghttp2 callbacks to handle HTTP2 requests.
* @return malloc'ed struct, NULL on failure
*/
nghttp2_session_callbacks* http2_req_callbacks_create();
/** Free http2 stream buffers and decrease buffer counters */
void http2_req_stream_clear(struct http2_stream* h2_stream);
/**
* DNS response ready to be submitted to nghttp2, to be prepared for sending
* out. Response is stored in c->buffer. Copy to rbuffer because the c->buffer
* might be used before this will be send out.
* @param h2_session: http2 session, containing c->buffer which contains answer
* @param h2_stream: http2 stream, containing buffer to store answer in
* @return 0 on error, 1 otherwise
*/
int http2_submit_dns_response(struct http2_session* h2_session);
#else
int http2_submit_dns_response(void* v);
#endif /* HAVE_NGHTTP2 */
char* set_ip_dscp(int socket, int addrfamily, int ds);
char* sock_strerror(int errn);
#endif /* LISTEN_DNSPORT_H */

View File

@ -551,6 +551,9 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
goto servfail_mem;
}
}
if(rep->c->use_h2) {
http2_stream_add_meshstate(rep->c->h2_stream, mesh, s);
}
/* add serve expired timer if required and not already there */
if(timeout && !mesh_serve_expired_init(s, timeout)) {
log_err("mesh_new_client: out of memory initializing serve expired");
@ -1207,6 +1210,13 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
else secure = 0;
if(!rep && rcode == LDNS_RCODE_NOERROR)
rcode = LDNS_RCODE_SERVFAIL;
if(r->query_reply.c->use_h2) {
r->query_reply.c->h2_stream = r->h2_stream;
/* Mesh reply won't exist for long anymore. Make it impossible
* 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;
}
/* send the reply */
/* We don't reuse the encoded answer if either the previous or current
* response has a local alias. We could compare the alias records
@ -1495,6 +1505,8 @@ int mesh_state_add_reply(struct mesh_state* s, struct edns_data* edns,
s->s.qinfo.qname_len);
if(!r->qname)
return 0;
if(rep->c->use_h2)
r->h2_stream = rep->c->h2_stream;
/* Data related to local alias stored in 'qinfo' (if any) is ephemeral
* and can be different for different original queries (even if the

View File

@ -230,6 +230,8 @@ struct mesh_reply {
uint8_t* qname;
/** same as that in query_info. */
struct local_rrset* local_alias;
/** send query to this http2 stream, if set */
struct http2_stream* h2_stream;
};
/**

View File

@ -58,6 +58,7 @@
#include "util/net_help.h"
#include "util/random.h"
#include "util/fptr_wlist.h"
#include "util/edns.h"
#include "sldns/sbuffer.h"
#include "dnstap/dnstap.h"
#ifdef HAVE_OPENSSL_SSL_H
@ -165,11 +166,7 @@ pick_outgoing_tcp(struct waiting_tcp* w, int s)
if(num == 0) {
log_err("no TCP outgoing interfaces of family");
log_addr(VERB_OPS, "for addr", &w->addr, w->addrlen);
#ifndef USE_WINSOCK
close(s);
#else
closesocket(s);
#endif
sock_close(s);
return 0;
}
#ifdef INET6
@ -188,14 +185,8 @@ pick_outgoing_tcp(struct waiting_tcp* w, int s)
((struct sockaddr_in6*)&pi->addr)->sin6_port = 0;
else ((struct sockaddr_in*)&pi->addr)->sin_port = 0;
if(bind(s, (struct sockaddr*)&pi->addr, pi->addrlen) != 0) {
#ifndef USE_WINSOCK
log_err("outgoing tcp: bind: %s", strerror(errno));
close(s);
#else
log_err("outgoing tcp: bind: %s",
wsa_strerror(WSAGetLastError()));
closesocket(s);
#endif
log_err("outgoing tcp: bind: %s", sock_strerror(errno));
sock_close(s);
return 0;
}
log_addr(VERB_ALGO, "tcp bound to src", &pi->addr, pi->addrlen);
@ -225,13 +216,8 @@ outnet_get_tcp_fd(struct sockaddr_storage* addr, socklen_t addrlen, int tcp_mss,
s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
}
if(s == -1) {
#ifndef USE_WINSOCK
log_err_addr("outgoing tcp: socket", strerror(errno),
log_err_addr("outgoing tcp: socket", sock_strerror(errno),
addr, addrlen);
#else
log_err_addr("outgoing tcp: socket",
wsa_strerror(WSAGetLastError()), addr, addrlen);
#endif
return -1;
}
@ -2111,9 +2097,20 @@ outnet_serviced_query(struct outside_network* outnet,
{
struct serviced_query* sq;
struct service_callback* cb;
struct edns_tag_addr* client_tag_addr;
if(!inplace_cb_query_call(env, qinfo, flags, addr, addrlen, zone, zonelen,
qstate, qstate->region))
return NULL;
if((client_tag_addr = edns_tag_addr_lookup(&env->edns_tags->client_tags,
addr, addrlen))) {
uint16_t client_tag = htons(client_tag_addr->tag_data);
edns_opt_list_append(&qstate->edns_opts_back_out,
env->edns_tags->client_tag_opcode, 2,
(uint8_t*)&client_tag, qstate->region);
}
serviced_gen_query(buff, qinfo->qname, qinfo->qname_len, qinfo->qtype,
qinfo->qclass, flags);
sq = lookup_serviced(outnet, buff, dnssec, addr, addrlen,

View File

@ -597,8 +597,18 @@ rpz_insert_rr(struct rpz* r, uint8_t* azname, size_t aznamelen, uint8_t* dname,
uint8_t* policydname;
if(!dname_subdomain_c(dname, azname)) {
log_err("RPZ: name of record to insert into RPZ is not a "
"subdomain of the configured name of the RPZ zone");
char* dname_str = sldns_wire2str_dname(dname, dnamelen);
char* azname_str = sldns_wire2str_dname(azname, aznamelen);
if(dname_str && azname_str) {
log_err("RPZ: name of record (%s) to insert into RPZ is not a "
"subdomain of the configured name of the RPZ zone (%s)",
dname_str, azname_str);
} else {
log_err("RPZ: name of record to insert into RPZ is not a "
"subdomain of the configured name of the RPZ zone");
}
free(dname_str);
free(azname_str);
return 0;
}

View File

@ -619,13 +619,18 @@ size_t sldns_b64_ntop_calculate_size(size_t srcsize)
*
* This routine does not insert spaces or linebreaks after 76 characters.
*/
int sldns_b64_ntop(uint8_t const *src, size_t srclength,
char *target, size_t targsize)
static int sldns_b64_ntop_base(uint8_t const *src, size_t srclength,
char *target, size_t targsize, int base64url, int padding)
{
const char* b64 =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
char* b64;
const char pad64 = '=';
size_t i = 0, o = 0;
if(base64url)
b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123"
"456789-_";
else
b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123"
"456789+/";
if(targsize < sldns_b64_ntop_calculate_size(srclength))
return -1;
/* whole chunks: xxxxxxyy yyyyzzzz zzwwwwww */
@ -645,18 +650,26 @@ int sldns_b64_ntop(uint8_t const *src, size_t srclength,
target[o] = b64[src[i] >> 2];
target[o+1] = b64[ ((src[i]&0x03)<<4) | (src[i+1]>>4) ];
target[o+2] = b64[ ((src[i+1]&0x0f)<<2) ];
target[o+3] = pad64;
/* i += 2; */
o += 4;
if(padding) {
target[o+3] = pad64;
/* i += 2; */
o += 4;
} else {
o += 3;
}
break;
case 1:
/* one at end, converted into A B = = */
target[o] = b64[src[i] >> 2];
target[o+1] = b64[ ((src[i]&0x03)<<4) ];
target[o+2] = pad64;
target[o+3] = pad64;
/* i += 1; */
o += 4;
if(padding) {
target[o+2] = pad64;
target[o+3] = pad64;
/* i += 1; */
o += 4;
} else {
o += 2;
}
break;
case 0:
default:
@ -669,19 +682,36 @@ int sldns_b64_ntop(uint8_t const *src, size_t srclength,
return (int)o;
}
int sldns_b64_ntop(uint8_t const *src, size_t srclength, char *target,
size_t targsize)
{
return sldns_b64_ntop_base(src, srclength, target, targsize,
0 /* no base64url */, 1 /* padding */);
}
int sldns_b64url_ntop(uint8_t const *src, size_t srclength, char *target,
size_t targsize)
{
return sldns_b64_ntop_base(src, srclength, target, targsize,
1 /* base64url */, 0 /* no padding */);
}
size_t sldns_b64_pton_calculate_size(size_t srcsize)
{
return (((((srcsize + 3) / 4) * 3)) + 1);
}
int sldns_b64_pton(char const *src, uint8_t *target, size_t targsize)
/* padding not required if srcsize is set */
static int sldns_b64_pton_base(char const *src, size_t srcsize, uint8_t *target,
size_t targsize, int base64url)
{
const uint8_t pad64 = 64; /* is 64th in the b64 array */
const char* s = src;
uint8_t in[4];
size_t o = 0, incount = 0;
int check_padding = (srcsize) ? 0 : 1;
while(*s) {
while(*s && (check_padding || srcsize)) {
/* skip any character that is not base64 */
/* conceptually we do:
const char* b64 = pad'=' is appended to array
@ -690,30 +720,43 @@ int sldns_b64_pton(char const *src, uint8_t *target, size_t targsize)
and use d-b64;
*/
char d = *s++;
srcsize--;
if(d <= 'Z' && d >= 'A')
d -= 'A';
else if(d <= 'z' && d >= 'a')
d = d - 'a' + 26;
else if(d <= '9' && d >= '0')
d = d - '0' + 52;
else if(d == '+')
else if(!base64url && d == '+')
d = 62;
else if(d == '/')
else if(base64url && d == '-')
d = 62;
else if(!base64url && d == '/')
d = 63;
else if(d == '=')
else if(base64url && d == '_')
d = 63;
else if(d == '=') {
if(!check_padding)
continue;
d = 64;
else continue;
} else continue;
in[incount++] = (uint8_t)d;
if(incount != 4)
/* work on block of 4, unless padding is not used and there are
* less than 4 chars left */
if(incount != 4 && (check_padding || srcsize))
continue;
assert(!check_padding || incount==4);
/* process whole block of 4 characters into 3 output bytes */
if(in[3] == pad64 && in[2] == pad64) { /* A B = = */
if((incount == 2 ||
(incount == 4 && in[3] == pad64 && in[2] == pad64))) { /* A B = = */
if(o+1 > targsize)
return -1;
target[o] = (in[0]<<2) | ((in[1]&0x30)>>4);
o += 1;
break; /* we are done */
} else if(in[3] == pad64) { /* A B C = */
} else if(incount == 3 ||
(incount == 4 && in[3] == pad64)) { /* A B C = */
if(o+2 > targsize)
return -1;
target[o] = (in[0]<<2) | ((in[1]&0x30)>>4);
@ -721,7 +764,7 @@ int sldns_b64_pton(char const *src, uint8_t *target, size_t targsize)
o += 2;
break; /* we are done */
} else {
if(o+3 > targsize)
if(incount != 4 || o+3 > targsize)
return -1;
/* write xxxxxxyy yyyyzzzz zzwwwwww */
target[o] = (in[0]<<2) | ((in[1]&0x30)>>4);
@ -733,3 +776,17 @@ int sldns_b64_pton(char const *src, uint8_t *target, size_t targsize)
}
return (int)o;
}
int sldns_b64_pton(char const *src, uint8_t *target, size_t targsize)
{
return sldns_b64_pton_base(src, 0, target, targsize, 0);
}
int sldns_b64url_pton(char const *src, size_t srcsize, uint8_t *target,
size_t targsize)
{
if(!srcsize) {
return 0;
}
return sldns_b64_pton_base(src, srcsize, target, targsize, 1);
}

View File

@ -92,13 +92,16 @@ size_t sldns_b64_ntop_calculate_size(size_t srcsize);
int sldns_b64_ntop(uint8_t const *src, size_t srclength,
char *target, size_t targsize);
int sldns_b64url_ntop(uint8_t const *src, size_t srclength, char *target,
size_t targsize);
/**
* calculates the size needed to store the result of sldns_b64_pton
*/
size_t sldns_b64_pton_calculate_size(size_t srcsize);
int sldns_b64_pton(char const *src, uint8_t *target, size_t targsize);
int sldns_b64url_pton(char const *src, size_t srcsize, uint8_t *target,
size_t targsize);
/**
* calculates the size needed to store the result of b32_ntop

View File

@ -426,7 +426,8 @@ enum sldns_enum_edns_option
LDNS_EDNS_N3U = 7, /* RFC6975 */
LDNS_EDNS_CLIENT_SUBNET = 8, /* RFC7871 */
LDNS_EDNS_KEEPALIVE = 11, /* draft-ietf-dnsop-edns-tcp-keepalive*/
LDNS_EDNS_PADDING = 12 /* RFC7830 */
LDNS_EDNS_PADDING = 12, /* RFC7830 */
LDNS_EDNS_CLIENT_TAG = 16 /* draft-bellis-dnsop-edns-tags-01 */
};
typedef enum sldns_enum_edns_option sldns_edns_option;

View File

@ -624,8 +624,6 @@ morechecks(struct config_file* cfg)
cfg->auto_trust_anchor_file_list, cfg->chrootdir, cfg);
check_chroot_filelist_wild("trusted-keys-file",
cfg->trusted_keys_file_list, cfg->chrootdir, cfg);
check_chroot_string("dlv-anchor-file", &cfg->dlv_anchor_file,
cfg->chrootdir, cfg);
#ifdef USE_IPSECMOD
if(cfg->ipsecmod_enabled && strstr(cfg->module_conf, "ipsecmod")) {
/* only check hook if enabled */

View File

@ -278,6 +278,8 @@ static void print_mem(struct ub_shm_stat_info* shm_stat,
shm_stat->mem.dnscrypt_nonce);
#endif
PR_LL("mem.streamwait", s->svr.mem_stream_wait);
PR_LL("mem.http.query_buffer", s->svr.mem_http2_query_buffer);
PR_LL("mem.http.response_buffer", s->svr.mem_http2_response_buffer);
}
/** print histogram */
@ -342,6 +344,7 @@ static void print_extended(struct ub_stats_info* s)
PR_UL("num.query.tls", s->svr.qtls);
PR_UL("num.query.tls_resume", s->svr.qtls_resume);
PR_UL("num.query.ipv6", s->svr.qipv6);
PR_UL("num.query.https", s->svr.qhttps);
/* flags */
PR_UL("num.query.flags.QR", s->svr.qbit_QR);
@ -593,11 +596,7 @@ contact_server(const char* svr, struct config_file* cfg, int statuscmd)
addrfamily = addr_is_ip6(&addr, addrlen)?PF_INET6:PF_INET;
fd = socket(addrfamily, SOCK_STREAM, proto);
if(fd == -1) {
#ifndef USE_WINSOCK
fatal_exit("socket: %s", strerror(errno));
#else
fatal_exit("socket: %s", wsa_strerror(WSAGetLastError()));
#endif
fatal_exit("socket: %s", sock_strerror(errno));
}
if(connect(fd, (struct sockaddr*)&addr, addrlen) < 0) {
#ifndef USE_WINSOCK
@ -681,11 +680,7 @@ remote_read(SSL* ssl, int fd, char* buf, size_t len)
/* EOF */
return 0;
}
#ifndef USE_WINSOCK
fatal_exit("could not recv: %s", strerror(errno));
#else
fatal_exit("could not recv: %s", wsa_strerror(WSAGetLastError()));
#endif
fatal_exit("could not recv: %s", sock_strerror(errno));
}
buf[rr] = 0;
}
@ -701,11 +696,7 @@ remote_write(SSL* ssl, int fd, const char* buf, size_t len)
ssl_err("could not SSL_write");
} else {
if(send(fd, buf, len, 0) < (ssize_t)len) {
#ifndef USE_WINSOCK
fatal_exit("could not send: %s", strerror(errno));
#else
fatal_exit("could not send: %s", wsa_strerror(WSAGetLastError()));
#endif
fatal_exit("could not send: %s", sock_strerror(errno));
}
}
}
@ -824,11 +815,7 @@ go(const char* cfgfile, char* svr, int quiet, int argc, char* argv[])
ret = go_cmd(ssl, fd, quiet, argc, argv);
if(ssl) SSL_free(ssl);
#ifndef USE_WINSOCK
close(fd);
#else
closesocket(fd);
#endif
sock_close(fd);
if(ctx) SSL_CTX_free(ctx);
config_delete(cfg);
return ret;
@ -886,7 +873,7 @@ int main(int argc, char* argv[])
if(argc == 0)
usage();
if(argc >= 1 && strcmp(argv[0], "start")==0) {
#if defined(TARGET_OS_TV) || defined(TARGET_OS_WATCH)
#if (defined(TARGET_OS_TV) && TARGET_OS_TV) || (defined(TARGET_OS_WATCH) && TARGET_OS_WATCH)
fatal_exit("could not exec unbound: %s",
strerror(ENOSYS));
#else

View File

@ -78,6 +78,8 @@ gid_t cfg_gid = (gid_t)-1;
int autr_permit_small_holddown = 0;
/** size (in bytes) of stream wait buffers max */
size_t stream_wait_max = 4 * 1024 * 1024;
size_t http2_query_buffer_max = 4 * 1024 * 1024;
size_t http2_response_buffer_max = 4 * 1024 * 1024;
/** global config during parsing */
struct config_parser_state* cfg_parser = 0;
@ -117,6 +119,12 @@ config_create(void)
cfg->tls_cert_bundle = NULL;
cfg->tls_win_cert = 0;
cfg->tls_use_sni = 1;
cfg->https_port = UNBOUND_DNS_OVER_HTTPS_PORT;
if(!(cfg->http_endpoint = strdup("/dns-query"))) goto error_exit;
cfg->http_max_streams = 100;
cfg->http_query_buffer_size = 4*1024*1024;
cfg->http_response_buffer_size = 4*1024*1024;
cfg->http_nodelay = 1;
cfg->use_syslog = 1;
cfg->log_identity = NULL; /* changed later with argv[0] */
cfg->log_time_ascii = 0;
@ -144,7 +152,7 @@ config_create(void)
cfg->incoming_num_tcp = 2;
#endif
cfg->stream_wait_size = 4 * 1024 * 1024;
cfg->edns_buffer_size = 4096; /* 4k from rfc recommendation */
cfg->edns_buffer_size = 1232; /* from DNS flagday recommendation */
cfg->msg_buffer_size = 65552; /* 64 k + a small margin */
cfg->msg_cache_size = 4 * 1024 * 1024;
cfg->msg_cache_slabs = 4;
@ -233,8 +241,6 @@ config_create(void)
cfg->trusted_keys_file_list = NULL;
cfg->trust_anchor_signaling = 1;
cfg->root_key_sentinel = 1;
cfg->dlv_anchor_file = NULL;
cfg->dlv_anchor_list = NULL;
cfg->domain_insecure = NULL;
cfg->val_date_override = 0;
cfg->val_sig_skew_min = 3600; /* at least daylight savings trouble */
@ -315,6 +321,8 @@ config_create(void)
cfg->qname_minimisation_strict = 0;
cfg->shm_enable = 0;
cfg->shm_key = 11777;
cfg->edns_client_tags = NULL;
cfg->edns_client_tag_opcode = LDNS_EDNS_CLIENT_TAG;
cfg->dnscrypt = 0;
cfg->dnscrypt_port = 0;
cfg->dnscrypt_provider = NULL;
@ -490,6 +498,8 @@ int config_set_option(struct config_file* cfg, const char* opt,
else S_YNO("do-ip6:", do_ip6)
else S_YNO("do-udp:", do_udp)
else S_YNO("do-tcp:", do_tcp)
else S_YNO("prefer-ip4:", prefer_ip4)
else S_YNO("prefer-ip6:", prefer_ip6)
else S_YNO("tcp-upstream:", tcp_upstream)
else S_YNO("udp-upstream-without-downstream:",
udp_upstream_without_downstream)
@ -511,6 +521,12 @@ 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 S_NUMBER_NONZERO("https-port:", https_port)
else S_STR("http-endpoint", http_endpoint)
else S_NUMBER_NONZERO("http-max-streams", http_max_streams)
else S_MEMSIZE("http-query-buffer-size", http_query_buffer_size)
else S_MEMSIZE("http-response-buffer-size", http_response_buffer_size)
else S_YNO("http-nodelay", http_nodelay)
else S_YNO("interface-automatic:", if_automatic)
else S_YNO("use-systemd:", use_systemd)
else S_YNO("do-daemonize:", do_daemonize)
@ -581,8 +597,6 @@ int config_set_option(struct config_file* cfg, const char* opt,
else S_STRLIST("trusted-keys-file:", trusted_keys_file_list)
else S_YNO("trust-anchor-signaling:", trust_anchor_signaling)
else S_YNO("root-key-sentinel:", root_key_sentinel)
else S_STR("dlv-anchor-file:", dlv_anchor_file)
else S_STRLIST("dlv-anchor:", dlv_anchor_list)
else S_STRLIST("domain-insecure:", domain_insecure)
else S_NUMBER_OR_ZERO("val-bogus-ttl:", bogus_ttl)
else S_YNO("val-clean-additional:", val_clean_additional)
@ -950,6 +964,8 @@ config_get_option(struct config_file* cfg, const char* opt,
else O_YNO(opt, "do-ip6", do_ip6)
else O_YNO(opt, "do-udp", do_udp)
else O_YNO(opt, "do-tcp", do_tcp)
else O_YNO(opt, "prefer-ip4", prefer_ip4)
else O_YNO(opt, "prefer-ip6", prefer_ip6)
else O_YNO(opt, "tcp-upstream", tcp_upstream)
else O_YNO(opt, "udp-upstream-without-downstream", udp_upstream_without_downstream)
else O_DEC(opt, "tcp-mss", tcp_mss)
@ -968,6 +984,12 @@ 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_DEC(opt, "https-port", https_port)
else O_STR(opt, "http-endpoint", http_endpoint)
else O_UNS(opt, "http-max-streams", http_max_streams)
else O_MEM(opt, "http-query-buffer-size", http_query_buffer_size)
else O_MEM(opt, "http-response-buffer-size", http_response_buffer_size)
else O_YNO(opt, "http-nodelay", http_nodelay)
else O_YNO(opt, "use-systemd", use_systemd)
else O_YNO(opt, "do-daemonize", do_daemonize)
else O_STR(opt, "chroot", chrootdir)
@ -998,7 +1020,6 @@ config_get_option(struct config_file* cfg, const char* opt,
else O_DEC(opt, "unwanted-reply-threshold", unwanted_threshold)
else O_YNO(opt, "do-not-query-localhost", donotquery_localhost)
else O_STR(opt, "module-config", module_conf)
else O_STR(opt, "dlv-anchor-file", dlv_anchor_file)
else O_DEC(opt, "val-bogus-ttl", bogus_ttl)
else O_YNO(opt, "val-clean-additional", val_clean_additional)
else O_DEC(opt, "val-log-level", val_log_level)
@ -1036,7 +1057,6 @@ config_get_option(struct config_file* cfg, const char* opt,
else O_LST(opt, "trusted-keys-file", trusted_keys_file_list)
else O_YNO(opt, "trust-anchor-signaling", trust_anchor_signaling)
else O_YNO(opt, "root-key-sentinel", root_key_sentinel)
else O_LST(opt, "dlv-anchor", dlv_anchor_list)
else O_LST(opt, "control-interface", control_ifs.first)
else O_LST(opt, "domain-insecure", domain_insecure)
else O_UNS(opt, "val-override-date", val_date_override)
@ -1130,6 +1150,7 @@ config_get_option(struct config_file* cfg, const char* opt,
else O_LS3(opt, "access-control-tag-action", acl_tag_actions)
else O_LS3(opt, "access-control-tag-data", acl_tag_datas)
else O_LS2(opt, "access-control-view", acl_view)
else O_LS2(opt, "edns-client-tags", edns_client_tags)
#ifdef USE_IPSECMOD
else O_YNO(opt, "ipsecmod-enabled", ipsecmod_enabled)
else O_YNO(opt, "ipsecmod-ignore-bogus", ipsecmod_ignore_bogus)
@ -1391,8 +1412,8 @@ config_delviews(struct config_view* p)
p = np;
}
}
/** delete string array */
static void
void
config_del_strarray(char** array, int num)
{
int i;
@ -1434,6 +1455,7 @@ config_delete(struct config_file* cfg)
config_delstrlist(cfg->tls_session_ticket_keys.first);
free(cfg->tls_ciphers);
free(cfg->tls_ciphersuites);
free(cfg->http_endpoint);
if(cfg->log_identity) {
log_ident_revert_to_default();
free(cfg->log_identity);
@ -1462,8 +1484,6 @@ config_delete(struct config_file* cfg)
config_delstrlist(cfg->trusted_keys_file_list);
config_delstrlist(cfg->trust_anchor_list);
config_delstrlist(cfg->domain_insecure);
free(cfg->dlv_anchor_file);
config_delstrlist(cfg->dlv_anchor_list);
config_deldblstrlist(cfg->acls);
config_deldblstrlist(cfg->tcp_connection_limits);
free(cfg->val_nsec3_key_iterations);
@ -1499,6 +1519,7 @@ config_delete(struct config_file* cfg)
config_deldblstrlist(cfg->ratelimit_below_domain);
config_delstrlist(cfg->python_script);
config_delstrlist(cfg->dynlib_file);
config_deldblstrlist(cfg->edns_client_tags);
#ifdef USE_IPSECMOD
free(cfg->ipsecmod_hook);
config_delstrlist(cfg->ipsecmod_whitelist);
@ -2043,6 +2064,8 @@ config_apply(struct config_file* config)
log_set_time_asc(config->log_time_ascii);
autr_permit_small_holddown = config->permit_small_holddown;
stream_wait_max = config->stream_wait_size;
http2_query_buffer_max = config->http_query_buffer_size;
http2_response_buffer_max = config->http_response_buffer_size;
}
void config_lookup_uid(struct config_file* cfg)

View File

@ -131,6 +131,19 @@ struct config_file {
/** if SNI is to be used */
int tls_use_sni;
/** port on which to provide DNS over HTTPS service */
int https_port;
/** endpoint for HTTP service */
char* http_endpoint;
/** MAX_CONCURRENT_STREAMS HTTP/2 setting */
uint32_t http_max_streams;
/** maximum size of all HTTP2 query buffers combined. */
size_t http_query_buffer_size;
/** maximum size of all HTTP2 response buffers combined. */
size_t http_response_buffer_size;
/** set TCP_NODELAY option for http sockets */
int http_nodelay;
/** outgoing port range number of ports (per thread) */
int outgoing_num_ports;
/** number of outgoing tcp buffers per (per thread) */
@ -331,10 +344,6 @@ struct config_file {
struct config_strlist* auto_trust_anchor_file_list;
/** files with trusted DNSKEYs in named.conf format, list */
struct config_strlist* trusted_keys_file_list;
/** DLV anchor file */
char* dlv_anchor_file;
/** DLV anchor inline */
struct config_strlist* dlv_anchor_list;
/** insecure domain list */
struct config_strlist* domain_insecure;
/** send key tag query */
@ -553,6 +562,11 @@ struct config_file {
/** SHM data - key for the shm */
int shm_key;
/** list of EDNS client tag entries, linked list */
struct config_str2list* edns_client_tags;
/** EDNS opcode to use for EDNS client tags */
uint16_t edns_client_tag_opcode;
/** DNSCrypt */
/** true to enable dnscrypt */
int dnscrypt;
@ -625,6 +639,10 @@ extern gid_t cfg_gid;
extern int autr_permit_small_holddown;
/** size (in bytes) of stream wait buffers max */
extern size_t stream_wait_max;
/** size (in bytes) of all total HTTP2 query buffers max */
extern size_t http2_query_buffer_max;
/** size (in bytes) of all total HTTP2 response buffers max */
extern size_t http2_response_buffer_max;
/**
* Stub config options
@ -970,6 +988,9 @@ void config_deldblstrlist(struct config_str2list* list);
*/
void config_deltrplstrlist(struct config_str3list* list);
/** delete string array */
void config_del_strarray(char** array, int num);
/** delete stringbytelist */
void config_del_strbytelist(struct config_strbytelist* list);

View File

@ -257,6 +257,12 @@ 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) }
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) }
http-query-buffer-size{COLON} { YDVAR(1, VAR_HTTP_QUERY_BUFFER_SIZE) }
http-response-buffer-size{COLON} { YDVAR(1, VAR_HTTP_RESPONSE_BUFFER_SIZE) }
http-nodelay{COLON} { YDVAR(1, VAR_HTTP_NODELAY) }
use-systemd{COLON} { YDVAR(1, VAR_USE_SYSTEMD) }
do-daemonize{COLON} { YDVAR(1, VAR_DO_DAEMONIZE) }
interface{COLON} { YDVAR(1, VAR_INTERFACE) }
@ -304,6 +310,7 @@ harden-referral-path{COLON} { YDVAR(1, VAR_HARDEN_REFERRAL_PATH) }
harden-algo-downgrade{COLON} { YDVAR(1, VAR_HARDEN_ALGO_DOWNGRADE) }
use-caps-for-id{COLON} { YDVAR(1, VAR_USE_CAPS_FOR_ID) }
caps-whitelist{COLON} { YDVAR(1, VAR_CAPS_WHITELIST) }
caps-exempt{COLON} { YDVAR(1, VAR_CAPS_WHITELIST) }
unwanted-reply-threshold{COLON} { YDVAR(1, VAR_UNWANTED_REPLY_THRESHOLD) }
private-address{COLON} { YDVAR(1, VAR_PRIVATE_ADDRESS) }
private-domain{COLON} { YDVAR(1, VAR_PRIVATE_DOMAIN) }
@ -335,6 +342,7 @@ rpz-log{COLON} { YDVAR(1, VAR_RPZ_LOG) }
rpz-log-name{COLON} { YDVAR(1, VAR_RPZ_LOG_NAME) }
zonefile{COLON} { YDVAR(1, VAR_ZONEFILE) }
master{COLON} { YDVAR(1, VAR_MASTER) }
primary{COLON} { YDVAR(1, VAR_MASTER) }
url{COLON} { YDVAR(1, VAR_URL) }
allow-notify{COLON} { YDVAR(1, VAR_ALLOW_NOTIFY) }
for-downstream{COLON} { YDVAR(1, VAR_FOR_DOWNSTREAM) }
@ -505,6 +513,7 @@ ipsecmod-ignore-bogus{COLON} { YDVAR(1, VAR_IPSECMOD_IGNORE_BOGUS) }
ipsecmod-hook{COLON} { YDVAR(1, VAR_IPSECMOD_HOOK) }
ipsecmod-max-ttl{COLON} { YDVAR(1, VAR_IPSECMOD_MAX_TTL) }
ipsecmod-whitelist{COLON} { YDVAR(1, VAR_IPSECMOD_WHITELIST) }
ipsecmod-allow{COLON} { YDVAR(1, VAR_IPSECMOD_WHITELIST) }
ipsecmod-strict{COLON} { YDVAR(1, VAR_IPSECMOD_STRICT) }
cachedb{COLON} { YDVAR(0, VAR_CACHEDB) }
backend{COLON} { YDVAR(1, VAR_CACHEDB_BACKEND) }
@ -518,6 +527,8 @@ name-v4{COLON} { YDVAR(1, VAR_IPSET_NAME_V4) }
name-v6{COLON} { YDVAR(1, VAR_IPSET_NAME_V6) }
udp-upstream-without-downstream{COLON} { YDVAR(1, VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM) }
tcp-connection-limit{COLON} { YDVAR(2, VAR_TCP_CONNECTION_LIMIT) }
edns-client-tag{COLON} { YDVAR(2, VAR_EDNS_CLIENT_TAG) }
edns-client-tag-opcode{COLON} { YDVAR(1, VAR_EDNS_CLIENT_TAG_OPCODE) }
<INITIAL,val>{NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++; }
/* Quoted strings. Strip leading and ending quotes */

View File

@ -112,6 +112,9 @@ extern struct config_parser_state* cfg_parser;
%token VAR_TCP_UPSTREAM VAR_SSL_UPSTREAM
%token VAR_SSL_SERVICE_KEY VAR_SSL_SERVICE_PEM VAR_SSL_PORT VAR_FORWARD_FIRST
%token VAR_STUB_SSL_UPSTREAM VAR_FORWARD_SSL_UPSTREAM VAR_TLS_CERT_BUNDLE
%token VAR_HTTPS_PORT VAR_HTTP_ENDPOINT VAR_HTTP_MAX_STREAMS
%token VAR_HTTP_QUERY_BUFFER_SIZE VAR_HTTP_RESPONSE_BUFFER_SIZE
%token VAR_HTTP_NODELAY
%token VAR_STUB_FIRST VAR_MINIMAL_RESPONSES VAR_RRSET_ROUNDROBIN
%token VAR_MAX_UDP_SIZE VAR_DELAY_CLOSE
%token VAR_UNBLOCK_LAN_ZONES VAR_INSECURE_LAN_ZONES
@ -175,7 +178,7 @@ extern struct config_parser_state* cfg_parser;
%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
%token VAR_DYNLIB VAR_DYNLIB_FILE
%token VAR_DYNLIB VAR_DYNLIB_FILE VAR_EDNS_CLIENT_TAG VAR_EDNS_CLIENT_TAG_OPCODE
%%
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
@ -244,6 +247,9 @@ content_server: server_num_threads | server_verbosity | server_port |
server_log_queries | server_log_replies | server_tcp_upstream | server_ssl_upstream |
server_log_local_actions |
server_ssl_service_key | server_ssl_service_pem | server_ssl_port |
server_https_port | server_http_endpoint | server_http_max_streams |
server_http_query_buffer_size | server_http_response_buffer_size |
server_http_nodelay |
server_minimal_responses | server_rrset_roundrobin | server_max_udp_size |
server_so_reuseport | server_delay_close |
server_unblock_lan_zones | server_insecure_lan_zones |
@ -285,7 +291,8 @@ content_server: server_num_threads | server_verbosity | server_port |
server_unknown_server_time_limit | server_log_tag_queryreply |
server_stream_wait_size | server_tls_ciphers |
server_tls_ciphersuites | server_tls_session_ticket_keys |
server_tls_use_sni
server_tls_use_sni | server_edns_client_tag |
server_edns_client_tag_opcode
;
stubstart: VAR_STUB_ZONE
{
@ -969,6 +976,61 @@ server_tls_use_sni: VAR_TLS_USE_SNI STRING_ARG
free($2);
}
;
server_https_port: VAR_HTTPS_PORT STRING_ARG
{
OUTYY(("P(server_https_port:%s)\n", $2));
if(atoi($2) == 0)
yyerror("port number expected");
else cfg_parser->cfg->https_port = atoi($2);
};
server_http_endpoint: VAR_HTTP_ENDPOINT STRING_ARG
{
OUTYY(("P(server_http_endpoint:%s)\n", $2));
free(cfg_parser->cfg->http_endpoint);
if($2 && $2[0] != '/') {
cfg_parser->cfg->http_endpoint = malloc(strlen($2)+2);
if(!cfg_parser->cfg->http_endpoint)
yyerror("out of memory");
cfg_parser->cfg->http_endpoint[0] = '/';
memmove(cfg_parser->cfg->http_endpoint+1, $2,
strlen($2)+1);
free($2);
} else {
cfg_parser->cfg->http_endpoint = $2;
}
};
server_http_max_streams: VAR_HTTP_MAX_STREAMS STRING_ARG
{
OUTYY(("P(server_http_max_streams:%s)\n", $2));
if(atoi($2) == 0 && strcmp($2, "0") != 0)
yyerror("number expected");
else cfg_parser->cfg->http_max_streams = atoi($2);
free($2);
};
server_http_query_buffer_size: VAR_HTTP_QUERY_BUFFER_SIZE STRING_ARG
{
OUTYY(("P(server_http_query_buffer_size:%s)\n", $2));
if(!cfg_parse_memsize($2,
&cfg_parser->cfg->http_query_buffer_size))
yyerror("memory size expected");
free($2);
};
server_http_response_buffer_size: VAR_HTTP_RESPONSE_BUFFER_SIZE STRING_ARG
{
OUTYY(("P(server_http_response_buffer_size:%s)\n", $2));
if(!cfg_parse_memsize($2,
&cfg_parser->cfg->http_response_buffer_size))
yyerror("memory size expected");
free($2);
};
server_http_nodelay: VAR_HTTP_NODELAY STRING_ARG
{
OUTYY(("P(server_http_nodelay:%s)\n", $2));
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
yyerror("expected yes or no.");
else cfg_parser->cfg->http_nodelay = (strcmp($2, "yes")==0);
free($2);
};
server_use_systemd: VAR_USE_SYSTEMD STRING_ARG
{
OUTYY(("P(server_use_systemd:%s)\n", $2));
@ -1120,15 +1182,15 @@ server_root_hints: VAR_ROOT_HINTS STRING_ARG
server_dlv_anchor_file: VAR_DLV_ANCHOR_FILE STRING_ARG
{
OUTYY(("P(server_dlv_anchor_file:%s)\n", $2));
free(cfg_parser->cfg->dlv_anchor_file);
cfg_parser->cfg->dlv_anchor_file = $2;
log_warn("option dlv-anchor-file ignored: DLV is decommissioned");
free($2);
}
;
server_dlv_anchor: VAR_DLV_ANCHOR STRING_ARG
{
OUTYY(("P(server_dlv_anchor:%s)\n", $2));
if(!cfg_strlist_insert(&cfg_parser->cfg->dlv_anchor_list, $2))
yyerror("out of memory");
log_warn("option dlv-anchor ignored: DLV is decommissioned");
free($2);
}
;
server_auto_trust_anchor_file: VAR_AUTO_TRUST_ANCHOR_FILE STRING_ARG
@ -2401,6 +2463,32 @@ server_ipsecmod_strict: VAR_IPSECMOD_STRICT STRING_ARG
OUTYY(("P(Compiled without IPsec module, ignoring)\n"));
free($2);
#endif
}
;
server_edns_client_tag: VAR_EDNS_CLIENT_TAG STRING_ARG STRING_ARG
{
int tag_data;
OUTYY(("P(server_edns_client_tag:%s %s)\n", $2, $3));
tag_data = atoi($3);
if(tag_data > 65535 || tag_data < 0 ||
(tag_data == 0 && (strlen($3) != 1 || $3[0] != '0')))
yyerror("edns-client-tag data invalid, needs to be a "
"number from 0 to 65535");
if(!cfg_str2list_insert(
&cfg_parser->cfg->edns_client_tags, $2, $3))
fatal_exit("out of memory adding "
"edns-client-tag");
}
;
server_edns_client_tag_opcode: VAR_EDNS_CLIENT_TAG_OPCODE STRING_ARG
{
OUTYY(("P(edns_client_tag_opcode:%s)\n", $2));
if(atoi($2) == 0 && strcmp($2, "0") != 0)
yyerror("option code expected");
else if(atoi($2) > 65535 || atoi($2) < 0)
yyerror("option code must be in interval [0, 65535]");
else cfg_parser->cfg->edns_client_tag_opcode = atoi($2);
}
;
stub_name: VAR_NAME STRING_ARG

View File

@ -43,11 +43,92 @@
#include "util/edns.h"
#include "util/config_file.h"
#include "util/netevent.h"
#include "util/net_help.h"
#include "util/regional.h"
#include "util/data/msgparse.h"
#include "util/data/msgreply.h"
#if 0
/* XXX: remove me */
#include "edns.h"
#endif
struct edns_tags* edns_tags_create(void)
{
struct edns_tags* edns_tags = calloc(1, sizeof(struct edns_tags));
if(!edns_tags)
return NULL;
if(!(edns_tags->region = regional_create())) {
edns_tags_delete(edns_tags);
return NULL;
}
return edns_tags;
}
void edns_tags_delete(struct edns_tags* edns_tags)
{
if(!edns_tags)
return;
regional_destroy(edns_tags->region);
free(edns_tags);
}
static int
edns_tags_client_insert(struct edns_tags* edns_tags,
struct sockaddr_storage* addr, socklen_t addrlen, int net,
uint16_t tag_data)
{
struct edns_tag_addr* eta = regional_alloc_zero(edns_tags->region,
sizeof(struct edns_tag_addr));
if(!eta)
return 0;
eta->tag_data = tag_data;
if(!addr_tree_insert(&edns_tags->client_tags, &eta->node, addr, addrlen,
net)) {
verbose(VERB_QUERY, "duplicate EDNS client tag ignored.");
}
return 1;
}
int edns_tags_apply_cfg(struct edns_tags* edns_tags,
struct config_file* config)
{
struct config_str2list* c;
regional_free_all(edns_tags->region);
addr_tree_init(&edns_tags->client_tags);
for(c=config->edns_client_tags; c; c=c->next) {
struct sockaddr_storage addr;
socklen_t addrlen;
int net;
uint16_t tag_data;
log_assert(c->str && c->str2);
if(!netblockstrtoaddr(c->str, UNBOUND_DNS_PORT, &addr, &addrlen,
&net)) {
log_err("cannot parse EDNS client tag IP netblock: %s",
c->str);
return 0;
}
tag_data = atoi(c->str2); /* validated in config parser */
if(!edns_tags_client_insert(edns_tags, &addr, addrlen, net,
tag_data)) {
log_err("out of memory while adding EDNS tags");
return 0;
}
}
edns_tags->client_tag_opcode = config->edns_client_tag_opcode;
addr_tree_init_parents(&edns_tags->client_tags);
return 1;
}
struct edns_tag_addr*
edns_tag_addr_lookup(rbtree_type* tree, struct sockaddr_storage* addr,
socklen_t addrlen)
{
return (struct edns_tag_addr*)addr_tree_lookup(tree, addr, addrlen);
}
static int edns_keepalive(struct edns_data* edns_out, struct edns_data* edns_in,
struct comm_point* c, struct regional* region)

View File

@ -42,11 +42,68 @@
#ifndef UTIL_EDNS_H
#define UTIL_EDNS_H
#include "util/storage/dnstree.h"
struct edns_data;
struct config_file;
struct comm_point;
struct regional;
/**
* Structure containing all EDNS tags.
*/
struct edns_tags {
/** Tree of EDNS client tags to use in upstream queries, per address
* prefix. Contains nodes of type edns_tag_addr. */
rbtree_type client_tags;
/** EDNS opcode to use for client tags */
uint16_t client_tag_opcode;
/** region to allocate tree nodes in */
struct regional* region;
};
/**
* EDNS tag. Node of rbtree, containing tag and prefix.
*/
struct edns_tag_addr {
/** node in address tree, used for tree lookups. Need to be the first
* member of this struct. */
struct addr_tree_node node;
/** tag data, in host byte ordering */
uint16_t tag_data;
};
/**
* Create structure to hold EDNS tags
* @return: newly created edns_tags, NULL on alloc failure.
*/
struct edns_tags* edns_tags_create(void);
/** Delete EDNS tags structure
* @param edns_tags: struct to delete
*/
void edns_tags_delete(struct edns_tags* edns_tags);
/**
* Add configured EDNS tags
* @param edns_tags: edns tags to apply config to
* @param config: struct containing EDNS tags configuration
* @return 0 on error
*/
int edns_tags_apply_cfg(struct edns_tags* edns_tags,
struct config_file* config);
/**
* Find tag for address.
* @param tree: tree containing EDNS tags per address prefix.
* @param addr: address to use for tree lookup
* @param addrlen: length of address
* @return: matching tree node, NULL otherwise
*/
struct edns_tag_addr*
edns_tag_addr_lookup(rbtree_type* tree, struct sockaddr_storage* addr,
socklen_t addrlen);
/**
* Apply common EDNS options.
*

View File

@ -138,6 +138,9 @@ fptr_whitelist_comm_timer(void (*fptr)(void*))
else if(fptr == &auth_xfer_probe_timer_callback) return 1;
else if(fptr == &auth_xfer_transfer_timer_callback) return 1;
else if(fptr == &mesh_serve_expired_callback) return 1;
#ifdef USE_DNSTAP
else if(fptr == &mq_wakeup_cb) return 1;
#endif
return 0;
}

View File

@ -4516,6 +4516,7 @@
6679,
6689,
6696,
6699,
6701,
6702,
6703,
@ -4744,6 +4745,7 @@
8023,
8025,
8026,
8027,
8032,
8033,
8034,

View File

@ -54,6 +54,10 @@
#if defined(USE_MINI_EVENT) && !defined(USE_WINSOCK)
#ifdef HAVE_SYS_SELECT_H
/* for fd_set on OpenBSD */
#include <sys/select.h>
#endif
#include <sys/time.h>
#ifndef HAVE_EVENT_BASE_FREE

View File

@ -520,6 +520,8 @@ struct module_env {
struct edns_known_option* edns_known_options;
/* Number of known edns options */
size_t edns_known_options_num;
/** EDNS client tag information */
struct edns_tags* edns_tags;
/* Make every mesh state unique, do not aggregate mesh states. */
int unique_mesh;

View File

@ -61,6 +61,9 @@
#ifdef USE_WINSOCK
#include <wincrypt.h>
#endif
#ifdef HAVE_NGHTTP2_NGHTTP2_H
#include <nghttp2/nghttp2.h>
#endif
/** max length of an IP address (the address portion) that we allow */
#define MAX_ADDR_STRLEN 128 /* characters */
@ -82,6 +85,7 @@ static struct tls_session_ticket_key {
unsigned char *hmac_key;
} *ticket_keys;
#ifdef HAVE_SSL
/**
* callback TLS session ticket encrypt and decrypt
* For use with SSL_CTX_set_tlsext_ticket_key_cb or
@ -97,7 +101,6 @@ static struct tls_session_ticket_key {
* @return 0 on no ticket, 1 for okay, and 2 for okay but renew the ticket
* (the ticket is decrypt only). and <0 for failures.
*/
#ifdef HAVE_SSL
int tls_session_ticket_key_cb(SSL *s, unsigned char* key_name,
unsigned char* iv, EVP_CIPHER_CTX *evp_ctx,
#ifdef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB
@ -884,6 +887,21 @@ log_cert(unsigned level, const char* str, void* cert)
}
#endif /* HAVE_SSL */
#if defined(HAVE_SSL) && defined(HAVE_NGHTTP2)
static int alpn_select_cb(SSL* ATTR_UNUSED(ssl), const unsigned char** out,
unsigned char* outlen, const unsigned char* in, unsigned int inlen,
void* ATTR_UNUSED(arg))
{
int rv = nghttp2_select_next_protocol((unsigned char **)out, outlen, in,
inlen);
if(rv == -1) {
return SSL_TLSEXT_ERR_NOACK;
}
/* either http/1.1 or h2 selected */
return SSL_TLSEXT_ERR_OK;
}
#endif
int
listen_sslctx_setup(void* ctxt)
{
@ -942,6 +960,9 @@ listen_sslctx_setup(void* ctxt)
#ifdef HAVE_SSL_CTX_SET_SECURITY_LEVEL
SSL_CTX_set_security_level(ctx, 0);
#endif
#if defined(HAVE_SSL_CTX_SET_ALPN_SELECT_CB) && defined(HAVE_NGHTTP2)
SSL_CTX_set_alpn_select_cb(ctx, alpn_select_cb, NULL);
#endif
#else
(void)ctxt;
#endif /* HAVE_SSL */
@ -1478,7 +1499,11 @@ int tls_session_ticket_key_cb(SSL *ATTR_UNUSED(sslctx), unsigned char* key_name,
params[1] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
"sha256", 0);
params[2] = OSSL_PARAM_construct_end();
#ifdef HAVE_EVP_MAC_CTX_SET_PARAMS
EVP_MAC_CTX_set_params(hmac_ctx, params);
#else
EVP_MAC_set_ctx_params(hmac_ctx, params);
#endif
#elif !defined(HMAC_INIT_EX_RETURNS_VOID)
if (HMAC_Init_ex(hmac_ctx, ticket_keys->hmac_key, 32, digest, NULL) != 1) {
verbose(VERB_CLIENT, "HMAC_Init_ex failed");
@ -1509,7 +1534,11 @@ int tls_session_ticket_key_cb(SSL *ATTR_UNUSED(sslctx), unsigned char* key_name,
params[1] = OSSL_PARAM_construct_utf8_string(OSSL_MAC_PARAM_DIGEST,
"sha256", 0);
params[2] = OSSL_PARAM_construct_end();
#ifdef HAVE_EVP_MAC_CTX_SET_PARAMS
EVP_MAC_CTX_set_params(hmac_ctx, params);
#else
EVP_MAC_set_ctx_params(hmac_ctx, params);
#endif
#elif !defined(HMAC_INIT_EX_RETURNS_VOID)
if (HMAC_Init_ex(hmac_ctx, key->hmac_key, 32, digest, NULL) != 1) {
verbose(VERB_CLIENT, "HMAC_Init_ex failed");
@ -1554,3 +1583,31 @@ listen_sslctx_delete_ticket_keys(void)
free(ticket_keys);
ticket_keys = NULL;
}
# ifndef USE_WINSOCK
char*
sock_strerror(int errn)
{
return strerror(errn);
}
void
sock_close(int socket)
{
close(socket);
}
# else
char*
sock_strerror(int ATTR_UNUSED(errn))
{
return wsa_strerror(WSAGetLastError());
}
void
sock_close(int socket)
{
closesocket(socket);
}
# endif /* USE_WINSOCK */

View File

@ -496,4 +496,10 @@ void listen_sslctx_delete_ticket_keys(void);
*/
int netblockdnametoaddr(uint8_t* dname, size_t dnamelen,
struct sockaddr_storage* addr, socklen_t* addrlen, int* net, int* af);
/** Return strerror or wsastrerror for socket error printout */
char* sock_strerror(int errn);
/** close the socket with close, or wsa closesocket */
void sock_close(int socket);
#endif /* NET_HELP_H */

View File

@ -373,12 +373,7 @@ comm_point_send_udp_msg(struct comm_point *c, sldns_buffer* packet,
if(sent == -1) {
if(!udp_send_errno_needs_log(addr, addrlen))
return 0;
#ifndef USE_WINSOCK
verbose(VERB_OPS, "sendto failed: %s", strerror(errno));
#else
verbose(VERB_OPS, "sendto failed: %s",
wsa_strerror(WSAGetLastError()));
#endif
verbose(VERB_OPS, "sendto failed: %s", sock_strerror(errno));
log_addr(VERB_OPS, "remote address is",
(struct sockaddr_storage*)addr, addrlen);
return 0;
@ -739,7 +734,7 @@ static void
setup_tcp_handler(struct comm_point* c, int fd, int cur, int max)
{
int handler_usage;
log_assert(c->type == comm_tcp);
log_assert(c->type == comm_tcp || c->type == comm_http);
log_assert(c->fd == -1);
sldns_buffer_clear(c->buffer);
#ifdef USE_DNSCRYPT
@ -845,7 +840,6 @@ int comm_point_perform_accept(struct comm_point* c,
return -1;
}
#endif
log_err_addr("accept failed", strerror(errno), addr, *addrlen);
#else /* USE_WINSOCK */
if(WSAGetLastError() == WSAEINPROGRESS ||
WSAGetLastError() == WSAECONNRESET)
@ -854,9 +848,9 @@ int comm_point_perform_accept(struct comm_point* c,
ub_winsock_tcp_wouldblock(c->ev->ev, UB_EV_READ);
return -1;
}
log_err_addr("accept failed", wsa_strerror(WSAGetLastError()),
addr, *addrlen);
#endif
log_err_addr("accept failed", sock_strerror(errno), addr,
*addrlen);
return -1;
}
if(c->tcp_conn_limit && c->type == comm_tcp_accept) {
@ -914,6 +908,42 @@ comm_point_tcp_win_bio_cb(struct comm_point* c, void* thessl)
}
#endif
#ifdef HAVE_NGHTTP2
/** Create http2 session server. Per connection, after TCP accepted.*/
static int http2_session_server_create(struct http2_session* h2_session)
{
log_assert(h2_session->callbacks);
h2_session->is_drop = 0;
if(nghttp2_session_server_new(&h2_session->session,
h2_session->callbacks,
h2_session) == NGHTTP2_ERR_NOMEM) {
log_err("failed to create nghttp2 session server");
return 0;
}
return 1;
}
/** Submit http2 setting to session. Once per session. */
static int http2_submit_settings(struct http2_session* h2_session)
{
int ret;
nghttp2_settings_entry settings[1] = {
{NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS,
h2_session->c->http2_max_streams}};
ret = nghttp2_submit_settings(h2_session->session, NGHTTP2_FLAG_NONE,
settings, 1);
if(ret) {
verbose(VERB_QUERY, "http2: submit_settings failed, "
"error: %s", nghttp2_strerror(ret));
return 0;
}
return 1;
}
#endif /* HAVE_NGHTTP2 */
void
comm_point_tcp_accept_callback(int fd, short event, void* arg)
{
@ -935,7 +965,28 @@ comm_point_tcp_accept_callback(int fd, short event, void* arg)
/* clear leftover flags from previous use, and then set the
* correct event base for the event structure for libevent */
ub_event_free(c_hdl->ev->ev);
c_hdl->ev->ev = ub_event_new(c_hdl->ev->base->eb->base, -1, UB_EV_PERSIST | UB_EV_READ | UB_EV_TIMEOUT, comm_point_tcp_handle_callback, c_hdl);
if(c_hdl->type == comm_http) {
#ifdef HAVE_NGHTTP2
if(!c_hdl->h2_session ||
!http2_session_server_create(c_hdl->h2_session)) {
log_warn("failed to create nghttp2");
return;
}
if(!c_hdl->h2_session ||
!http2_submit_settings(c_hdl->h2_session)) {
log_warn("failed to submit http2 settings");
return;
}
#endif
c_hdl->ev->ev = ub_event_new(c_hdl->ev->base->eb->base, -1,
UB_EV_PERSIST | UB_EV_READ | UB_EV_TIMEOUT,
comm_point_http_handle_callback, c_hdl);
} else {
c_hdl->ev->ev = ub_event_new(c_hdl->ev->base->eb->base, -1,
UB_EV_PERSIST | UB_EV_READ | UB_EV_TIMEOUT,
comm_point_tcp_handle_callback, c_hdl);
}
if(!c_hdl->ev->ev) {
log_warn("could not ub_event_new, dropped tcp");
return;
@ -1169,6 +1220,18 @@ ssl_handshake(struct comm_point* c)
c->repinfo.addrlen);
}
/* check if http2 use is negotiated */
if(c->type == comm_http && c->h2_session) {
const unsigned char *alpn;
unsigned int alpnlen = 0;
SSL_get0_alpn_selected(c->ssl, &alpn, &alpnlen);
if(alpnlen == 2 && memcmp("h2", alpn, 2) == 0) {
/* connection upgraded to HTTP2 */
c->tcp_do_toggle_rw = 0;
c->use_h2 = 1;
}
}
/* setup listen rw correctly */
if(c->tcp_is_reading) {
if(c->ssl_shake_state != comm_ssl_shake_read)
@ -1435,8 +1498,6 @@ comm_point_tcp_handle_read(int fd, struct comm_point* c, int short_ok)
if(errno == ECONNRESET && verbosity < 2)
return 0; /* silence reset by peer */
#endif
log_err_addr("read (in tcp s)", strerror(errno),
&c->repinfo.addr, c->repinfo.addrlen);
#else /* USE_WINSOCK */
if(WSAGetLastError() == WSAECONNRESET)
return 0;
@ -1447,10 +1508,9 @@ comm_point_tcp_handle_read(int fd, struct comm_point* c, int short_ok)
UB_EV_READ);
return 1;
}
log_err_addr("read (in tcp s)",
wsa_strerror(WSAGetLastError()),
&c->repinfo.addr, c->repinfo.addrlen);
#endif
log_err_addr("read (in tcp s)", sock_strerror(errno),
&c->repinfo.addr, c->repinfo.addrlen);
return 0;
}
c->tcp_byte_count += r;
@ -1483,8 +1543,6 @@ comm_point_tcp_handle_read(int fd, struct comm_point* c, int short_ok)
#ifndef USE_WINSOCK
if(errno == EINTR || errno == EAGAIN)
return 1;
log_err_addr("read (in tcp r)", strerror(errno),
&c->repinfo.addr, c->repinfo.addrlen);
#else /* USE_WINSOCK */
if(WSAGetLastError() == WSAECONNRESET)
return 0;
@ -1494,10 +1552,9 @@ comm_point_tcp_handle_read(int fd, struct comm_point* c, int short_ok)
ub_winsock_tcp_wouldblock(c->ev->ev, UB_EV_READ);
return 1;
}
log_err_addr("read (in tcp r)",
wsa_strerror(WSAGetLastError()),
&c->repinfo.addr, c->repinfo.addrlen);
#endif
log_err_addr("read (in tcp r)", sock_strerror(errno),
&c->repinfo.addr, c->repinfo.addrlen);
return 0;
}
sldns_buffer_skip(c->buffer, r);
@ -1716,8 +1773,6 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c)
if(errno == ECONNRESET && verbosity < 2)
return 0; /* silence reset by peer */
#endif
log_err_addr("tcp send r", strerror(errno),
&c->repinfo.addr, c->repinfo.addrlen);
#else
if(WSAGetLastError() == WSAEINPROGRESS)
return 1;
@ -1727,9 +1782,9 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c)
}
if(WSAGetLastError() == WSAECONNRESET && verbosity < 2)
return 0; /* silence reset by peer */
log_err_addr("tcp send r", wsa_strerror(WSAGetLastError()),
&c->repinfo.addr, c->repinfo.addrlen);
#endif
log_err_addr("tcp send r", sock_strerror(errno),
&c->repinfo.addr, c->repinfo.addrlen);
return 0;
}
sldns_buffer_skip(buffer, r);
@ -1914,8 +1969,6 @@ http_read_more(int fd, struct comm_point* c)
#ifndef USE_WINSOCK
if(errno == EINTR || errno == EAGAIN)
return 1;
log_err_addr("read (in http r)", strerror(errno),
&c->repinfo.addr, c->repinfo.addrlen);
#else /* USE_WINSOCK */
if(WSAGetLastError() == WSAECONNRESET)
return 0;
@ -1925,10 +1978,9 @@ http_read_more(int fd, struct comm_point* c)
ub_winsock_tcp_wouldblock(c->ev->ev, UB_EV_READ);
return 1;
}
log_err_addr("read (in http r)",
wsa_strerror(WSAGetLastError()),
&c->repinfo.addr, c->repinfo.addrlen);
#endif
log_err_addr("read (in http r)", sock_strerror(errno),
&c->repinfo.addr, c->repinfo.addrlen);
return 0;
}
sldns_buffer_skip(c->buffer, r);
@ -2186,11 +2238,209 @@ http_chunked_segment(struct comm_point* c)
return 1;
}
#ifdef HAVE_NGHTTP2
/** Create new http2 session. Called when creating handling comm point. */
struct http2_session* http2_session_create(struct comm_point* c)
{
struct http2_session* session = calloc(1, sizeof(*session));
if(!session) {
log_err("malloc failure while creating http2 session");
return NULL;
}
session->c = c;
return session;
}
#endif
/** Delete http2 session. After closing connection or on error */
void http2_session_delete(struct http2_session* h2_session)
{
#ifdef HAVE_NGHTTP2
if(h2_session->callbacks)
nghttp2_session_callbacks_del(h2_session->callbacks);
free(h2_session);
#else
(void)h2_session;
#endif
}
#ifdef HAVE_NGHTTP2
struct http2_stream* http2_stream_create(int32_t stream_id)
{
struct http2_stream* h2_stream = calloc(1, sizeof(*h2_stream));
if(!h2_stream) {
log_err("malloc failure while creating http2 stream");
return NULL;
}
h2_stream->stream_id = stream_id;
return h2_stream;
}
/** Delete http2 stream. After session delete or stream close callback */
static void http2_stream_delete(struct http2_session* h2_session,
struct http2_stream* h2_stream)
{
if(h2_stream->mesh_state) {
mesh_state_remove_reply(h2_stream->mesh, h2_stream->mesh_state,
h2_session->c);
h2_stream->mesh_state = NULL;
}
http2_req_stream_clear(h2_stream);
free(h2_stream);
}
#endif
void http2_stream_add_meshstate(struct http2_stream* h2_stream,
struct mesh_area* mesh, struct mesh_state* m)
{
h2_stream->mesh = mesh;
h2_stream->mesh_state = m;
}
/** delete http2 session server. After closing connection. */
static void http2_session_server_delete(struct http2_session* h2_session)
{
#ifdef HAVE_NGHTTP2
struct http2_stream* h2_stream, *next;
nghttp2_session_del(h2_session->session); /* NULL input is fine */
h2_session->session = NULL;
for(h2_stream = h2_session->first_stream; h2_stream;) {
next = h2_stream->next;
http2_stream_delete(h2_session, h2_stream);
h2_stream = next;
}
h2_session->first_stream = NULL;
h2_session->is_drop = 0;
h2_session->postpone_drop = 0;
h2_session->c->h2_stream = NULL;
#endif
(void)h2_session;
}
#ifdef HAVE_NGHTTP2
void http2_session_add_stream(struct http2_session* h2_session,
struct http2_stream* h2_stream)
{
if(h2_session->first_stream)
h2_session->first_stream->prev = h2_stream;
h2_stream->next = h2_session->first_stream;
h2_session->first_stream = h2_stream;
}
/** remove stream from session linked list. After stream close callback or
* closing connection */
void http2_session_remove_stream(struct http2_session* h2_session,
struct http2_stream* h2_stream)
{
if(h2_stream->prev)
h2_stream->prev->next = h2_stream->next;
else
h2_session->first_stream = h2_stream->next;
if(h2_stream->next)
h2_stream->next->prev = h2_stream->prev;
}
int http2_stream_close_cb(nghttp2_session* ATTR_UNUSED(session),
int32_t stream_id, uint32_t ATTR_UNUSED(error_code), void* cb_arg)
{
struct http2_stream* h2_stream;
struct http2_session* h2_session = (struct http2_session*)cb_arg;
if(!(h2_stream = nghttp2_session_get_stream_user_data(
h2_session->session, stream_id))) {
return 0;
}
http2_session_remove_stream(h2_session, h2_stream);
http2_stream_delete(h2_session, h2_stream);
return 0;
}
ssize_t http2_recv_cb(nghttp2_session* ATTR_UNUSED(session), uint8_t* buf,
size_t len, int ATTR_UNUSED(flags), void* cb_arg)
{
#ifdef HAVE_SSL
struct http2_session* h2_session = (struct http2_session*)cb_arg;
int r;
log_assert(h2_session->c->type == comm_http);
log_assert(h2_session->c->h2_session);
if(!h2_session->c->ssl)
return 0;
ERR_clear_error();
r = SSL_read(h2_session->c->ssl, buf, len);
if(r <= 0) {
int want = SSL_get_error(h2_session->c->ssl, r);
if(want == SSL_ERROR_ZERO_RETURN) {
return NGHTTP2_ERR_EOF;
} else if(want == SSL_ERROR_WANT_READ) {
return NGHTTP2_ERR_WOULDBLOCK;
} else if(want == SSL_ERROR_WANT_WRITE) {
h2_session->c->ssl_shake_state = comm_ssl_shake_hs_write;
comm_point_listen_for_rw(h2_session->c, 0, 1);
return NGHTTP2_ERR_WOULDBLOCK;
} else if(want == SSL_ERROR_SYSCALL) {
#ifdef ECONNRESET
if(errno == ECONNRESET && verbosity < 2)
return NGHTTP2_ERR_CALLBACK_FAILURE;
#endif
if(errno != 0)
log_err("SSL_read syscall: %s",
strerror(errno));
return NGHTTP2_ERR_CALLBACK_FAILURE;
}
log_crypto_err("could not SSL_read");
return NGHTTP2_ERR_CALLBACK_FAILURE;
}
return r;
#else
(void)buf;
(void)len;
(void)cb_arg;
return -1;
#endif
}
#endif /* HAVE_NGHTTP2 */
/** Handle http2 read */
static int
comm_point_http2_handle_read(int ATTR_UNUSED(fd), struct comm_point* c)
{
#ifdef HAVE_NGHTTP2
int ret;
log_assert(c->h2_session);
log_assert(c->ssl);
/* reading until recv cb returns NGHTTP2_ERR_WOULDBLOCK */
ret = nghttp2_session_recv(c->h2_session->session);
if(ret) {
if(ret != NGHTTP2_ERR_EOF &&
ret != NGHTTP2_ERR_CALLBACK_FAILURE) {
verbose(VERB_QUERY, "http2: session_recv failed, "
"error: %s", nghttp2_strerror(ret));
}
return 0;
}
if(nghttp2_session_want_write(c->h2_session->session)) {
c->tcp_is_reading = 0;
comm_point_stop_listening(c);
comm_point_start_listening(c, -1, c->tcp_timeout_msec);
} else if(!nghttp2_session_want_read(c->h2_session->session))
return 0; /* connection can be closed */
return 1;
#else
(void)c;
return 0;
#endif
}
/**
* Handle http reading callback.
* Handle http reading callback.
* @param fd: file descriptor of socket.
* @param c: comm point to read from into buffer.
* @return: 0 on error
* @return: 0 on error
*/
static int
comm_point_http_handle_read(int fd, struct comm_point* c)
@ -2210,6 +2460,18 @@ comm_point_http_handle_read(int fd, struct comm_point* c)
if(!c->tcp_is_reading)
return 1;
if(c->use_h2) {
return comm_point_http2_handle_read(fd, c);
}
/* http version is <= http/1.1 */
if(c->http_min_version >= http_version_2) {
/* HTTP/2 failed, not allowed to use lower version. */
return 0;
}
/* read more data */
if(c->ssl) {
if(!ssl_http_read_more(c))
@ -2220,7 +2482,9 @@ comm_point_http_handle_read(int fd, struct comm_point* c)
}
sldns_buffer_flip(c->buffer);
while(sldns_buffer_remaining(c->buffer) > 0) {
/* Handle HTTP/1.x data */
/* if we are reading headers, read more headers */
if(c->http_in_headers || c->http_in_chunk_headers) {
/* if header is done, process the header */
@ -2364,8 +2628,6 @@ http_write_more(int fd, struct comm_point* c)
#ifndef USE_WINSOCK
if(errno == EINTR || errno == EAGAIN)
return 1;
log_err_addr("http send r", strerror(errno),
&c->repinfo.addr, c->repinfo.addrlen);
#else
if(WSAGetLastError() == WSAEINPROGRESS)
return 1;
@ -2373,15 +2635,92 @@ http_write_more(int fd, struct comm_point* c)
ub_winsock_tcp_wouldblock(c->ev->ev, UB_EV_WRITE);
return 1;
}
log_err_addr("http send r", wsa_strerror(WSAGetLastError()),
&c->repinfo.addr, c->repinfo.addrlen);
#endif
log_err_addr("http send r", sock_strerror(errno),
&c->repinfo.addr, c->repinfo.addrlen);
return 0;
}
sldns_buffer_skip(c->buffer, r);
return 1;
}
#ifdef HAVE_NGHTTP2
ssize_t http2_send_cb(nghttp2_session* ATTR_UNUSED(session), const uint8_t* buf,
size_t len, int ATTR_UNUSED(flags), void* cb_arg)
{
#ifdef HAVE_SSL
int r;
struct http2_session* h2_session = (struct http2_session*)cb_arg;
log_assert(h2_session->c->type == comm_http);
log_assert(h2_session->c->h2_session);
if(!h2_session->c->ssl)
return 0;
ERR_clear_error();
r = SSL_write(h2_session->c->ssl, buf, len);
if(r <= 0) {
int want = SSL_get_error(h2_session->c->ssl, r);
if(want == SSL_ERROR_ZERO_RETURN) {
return NGHTTP2_ERR_CALLBACK_FAILURE;
} else if(want == SSL_ERROR_WANT_READ) {
h2_session->c->ssl_shake_state = comm_ssl_shake_hs_read;
comm_point_listen_for_rw(h2_session->c, 1, 0);
return NGHTTP2_ERR_WOULDBLOCK;
} else if(want == SSL_ERROR_WANT_WRITE) {
return NGHTTP2_ERR_WOULDBLOCK;
} else if(want == SSL_ERROR_SYSCALL) {
#ifdef EPIPE
if(errno == EPIPE && verbosity < 2)
return NGHTTP2_ERR_CALLBACK_FAILURE;
#endif
if(errno != 0)
log_err("SSL_write syscall: %s",
strerror(errno));
return NGHTTP2_ERR_CALLBACK_FAILURE;
}
log_crypto_err("could not SSL_write");
return NGHTTP2_ERR_CALLBACK_FAILURE;
}
return r;
#else
(void)buf;
(void)len;
(void)cb_arg;
return -1;
#endif
}
#endif /* HAVE_NGHTTP2 */
/** Handle http2 writing */
static int
comm_point_http2_handle_write(int ATTR_UNUSED(fd), struct comm_point* c)
{
#ifdef HAVE_NGHTTP2
int ret;
log_assert(c->h2_session);
log_assert(c->ssl);
ret = nghttp2_session_send(c->h2_session->session);
if(ret) {
verbose(VERB_QUERY, "http2: session_send failed, "
"error: %s", nghttp2_strerror(ret));
return 0;
}
if(nghttp2_session_want_read(c->h2_session->session)) {
c->tcp_is_reading = 1;
comm_point_stop_listening(c);
comm_point_start_listening(c, -1, c->tcp_timeout_msec);
} else if(!nghttp2_session_want_write(c->h2_session->session))
return 0; /* connection can be closed */
return 1;
#else
(void)c;
return 0;
#endif
}
/**
* Handle http writing callback.
* @param fd: file descriptor of socket.
@ -2413,6 +2752,18 @@ comm_point_http_handle_write(int fd, struct comm_point* c)
#endif /* HAVE_SSL */
if(c->tcp_is_reading)
return 1;
if(c->use_h2) {
return comm_point_http2_handle_write(fd, c);
}
/* http version is <= http/1.1 */
if(c->http_min_version >= http_version_2) {
/* HTTP/2 failed, not allowed to use lower version. */
return 0;
}
/* if we are writing, write more */
if(c->ssl) {
if(!ssl_http_write_more(c))
@ -2724,11 +3075,129 @@ comm_point_create_tcp_handler(struct comm_base *base,
return c;
}
static struct comm_point*
comm_point_create_http_handler(struct comm_base *base,
struct comm_point* parent, size_t bufsize, int harden_large_queries,
uint32_t http_max_streams, char* http_endpoint,
comm_point_callback_type* callback, void* callback_arg)
{
struct comm_point* c = (struct comm_point*)calloc(1,
sizeof(struct comm_point));
short evbits;
if(!c)
return NULL;
c->ev = (struct internal_event*)calloc(1,
sizeof(struct internal_event));
if(!c->ev) {
free(c);
return NULL;
}
c->ev->base = base;
c->fd = -1;
c->buffer = sldns_buffer_new(bufsize);
if(!c->buffer) {
free(c->ev);
free(c);
return NULL;
}
c->timeout = (struct timeval*)malloc(sizeof(struct timeval));
if(!c->timeout) {
sldns_buffer_free(c->buffer);
free(c->ev);
free(c);
return NULL;
}
c->tcp_is_reading = 0;
c->tcp_byte_count = 0;
c->tcp_parent = parent;
c->tcp_timeout_msec = parent->tcp_timeout_msec;
c->tcp_conn_limit = parent->tcp_conn_limit;
c->tcl_addr = NULL;
c->tcp_keepalive = 0;
c->max_tcp_count = 0;
c->cur_tcp_count = 0;
c->tcp_handlers = NULL;
c->tcp_free = NULL;
c->type = comm_http;
c->tcp_do_close = 1;
c->do_not_close = 0;
c->tcp_do_toggle_rw = 1; /* will be set to 0 after http2 upgrade */
c->tcp_check_nb_connect = 0;
#ifdef USE_MSG_FASTOPEN
c->tcp_do_fastopen = 0;
#endif
#ifdef USE_DNSCRYPT
c->dnscrypt = 0;
c->dnscrypt_buffer = NULL;
#endif
c->repinfo.c = c;
c->callback = callback;
c->cb_arg = callback_arg;
c->http_min_version = http_version_2;
c->http2_stream_max_qbuffer_size = bufsize;
if(harden_large_queries && bufsize > 512)
c->http2_stream_max_qbuffer_size = 512;
c->http2_max_streams = http_max_streams;
if(!(c->http_endpoint = strdup(http_endpoint))) {
log_err("could not strdup http_endpoint");
sldns_buffer_free(c->buffer);
free(c->timeout);
free(c->ev);
free(c);
return NULL;
}
c->use_h2 = 0;
#ifdef HAVE_NGHTTP2
if(!(c->h2_session = http2_session_create(c))) {
log_err("could not create http2 session");
free(c->http_endpoint);
sldns_buffer_free(c->buffer);
free(c->timeout);
free(c->ev);
free(c);
return NULL;
}
if(!(c->h2_session->callbacks = http2_req_callbacks_create())) {
log_err("could not create http2 callbacks");
http2_session_delete(c->h2_session);
free(c->http_endpoint);
sldns_buffer_free(c->buffer);
free(c->timeout);
free(c->ev);
free(c);
return NULL;
}
#endif
/* add to parent free list */
c->tcp_free = parent->tcp_free;
parent->tcp_free = c;
/* ub_event stuff */
evbits = UB_EV_PERSIST | UB_EV_READ | UB_EV_TIMEOUT;
c->ev->ev = ub_event_new(base->eb->base, c->fd, evbits,
comm_point_http_handle_callback, c);
if(c->ev->ev == NULL)
{
log_err("could not set http handler event");
parent->tcp_free = c->tcp_free;
http2_session_delete(c->h2_session);
sldns_buffer_free(c->buffer);
free(c->timeout);
free(c->ev);
free(c);
return NULL;
}
return c;
}
struct comm_point*
comm_point_create_tcp(struct comm_base *base, int fd, int num,
int idle_timeout, struct tcl_list* tcp_conn_limit, size_t bufsize,
struct sldns_buffer* spoolbuf, comm_point_callback_type* callback,
void* callback_arg)
int idle_timeout, int harden_large_queries,
uint32_t http_max_streams, char* http_endpoint,
struct tcl_list* tcp_conn_limit, size_t bufsize,
struct sldns_buffer* spoolbuf, enum listen_type port_type,
comm_point_callback_type* callback, void* callback_arg)
{
struct comm_point* c = (struct comm_point*)calloc(1,
sizeof(struct comm_point));
@ -2792,10 +3261,24 @@ comm_point_create_tcp(struct comm_base *base, int fd, int num,
comm_point_delete(c);
return NULL;
}
/* now prealloc the tcp handlers */
/* now prealloc the handlers */
for(i=0; i<num; i++) {
c->tcp_handlers[i] = comm_point_create_tcp_handler(base,
c, bufsize, spoolbuf, callback, callback_arg);
if(port_type == listen_type_tcp ||
port_type == listen_type_ssl ||
port_type == listen_type_tcp_dnscrypt) {
c->tcp_handlers[i] = comm_point_create_tcp_handler(base,
c, bufsize, spoolbuf, callback, callback_arg);
} else if(port_type == listen_type_http) {
c->tcp_handlers[i] = comm_point_create_http_handler(
base, c, bufsize, harden_large_queries,
http_max_streams, http_endpoint,
callback, callback_arg);
}
else {
log_err("could not create tcp handler, unknown listen "
"type");
return NULL;
}
if(!c->tcp_handlers[i]) {
comm_point_delete(c);
return NULL;
@ -3079,6 +3562,9 @@ comm_point_close(struct comm_point* c)
tcl_close_connection(c->tcl_addr);
if(c->tcp_req_info)
tcp_req_info_clear(c->tcp_req_info);
if(c->h2_session)
http2_session_server_delete(c->h2_session);
/* close fd after removing from event lists, or epoll.. is messed up */
if(c->fd != -1 && !c->do_not_close) {
if(c->type == comm_tcp || c->type == comm_http) {
@ -3087,11 +3573,7 @@ comm_point_close(struct comm_point* c)
ub_winsock_tcp_wouldblock(c->ev->ev, UB_EV_WRITE);
}
verbose(VERB_ALGO, "close fd %d", c->fd);
#ifndef USE_WINSOCK
close(c->fd);
#else
closesocket(c->fd);
#endif
sock_close(c->fd);
}
c->fd = -1;
}
@ -3107,6 +3589,10 @@ comm_point_delete(struct comm_point* c)
SSL_free(c->ssl);
#endif
}
if(c->type == comm_http && c->http_endpoint) {
free(c->http_endpoint);
c->http_endpoint = NULL;
}
comm_point_close(c);
if(c->tcp_handlers) {
int i;
@ -3125,6 +3611,9 @@ comm_point_delete(struct comm_point* c)
if(c->tcp_req_info) {
tcp_req_info_delete(c->tcp_req_info);
}
if(c->h2_session) {
http2_session_delete(c->h2_session);
}
}
ub_event_free(c->ev->ev);
free(c->ev);
@ -3170,6 +3659,17 @@ comm_point_send_reply(struct comm_reply *repinfo)
#endif
if(repinfo->c->tcp_req_info) {
tcp_req_info_send_reply(repinfo->c->tcp_req_info);
} else if(repinfo->c->use_h2) {
if(!http2_submit_dns_response(repinfo->c->h2_session)) {
comm_point_drop_reply(repinfo);
return;
}
repinfo->c->h2_stream = NULL;
repinfo->c->tcp_is_reading = 0;
comm_point_stop_listening(repinfo->c);
comm_point_start_listening(repinfo->c, -1,
repinfo->c->tcp_timeout_msec);
return;
} else {
comm_point_start_listening(repinfo->c, -1,
repinfo->c->tcp_timeout_msec);
@ -3188,6 +3688,16 @@ comm_point_drop_reply(struct comm_reply* repinfo)
return;
if(repinfo->c->tcp_req_info)
repinfo->c->tcp_req_info->is_drop = 1;
if(repinfo->c->type == comm_http) {
if(repinfo->c->h2_session) {
repinfo->c->h2_session->is_drop = 1;
if(!repinfo->c->h2_session->postpone_drop)
reclaim_http_handler(repinfo->c);
return;
}
reclaim_http_handler(repinfo->c);
return;
}
reclaim_tcp_handler(repinfo->c);
}
@ -3232,11 +3742,7 @@ comm_point_start_listening(struct comm_point* c, int newfd, int msec)
}
if(newfd != -1) {
if(c->fd != -1) {
#ifndef USE_WINSOCK
close(c->fd);
#else
closesocket(c->fd);
#endif
sock_close(c->fd);
}
c->fd = newfd;
ub_event_set_fd(c->ev->ev, c->fd);

View File

@ -61,6 +61,9 @@
#define NET_EVENT_H
#include "dnscrypt/dnscrypt.h"
#ifdef HAVE_NGHTTP2_NGHTTP2_H
#include <nghttp2/nghttp2.h>
#endif
struct sldns_buffer;
struct comm_point;
@ -68,11 +71,16 @@ struct comm_reply;
struct tcl_list;
struct ub_event_base;
struct mesh_state;
struct mesh_area;
/* internal event notification data storage structure. */
struct internal_event;
struct internal_base;
struct internal_timer; /* A sub struct of the comm_timer super struct */
enum listen_type;
/** callback from communication point function type */
typedef int comm_point_callback_type(struct comm_point*, void*, int,
struct comm_reply*);
@ -205,6 +213,15 @@ struct comm_point {
} ssl_shake_state;
/* -------- HTTP ------- */
/** Do not allow connection to use HTTP version lower than this. 0=no
* minimum. */
enum {
http_version_none = 0,
http_version_2 = 2
} http_min_version;
/** http endpoint */
char* http_endpoint;
/* -------- HTTP/1.1 ------- */
/** Currently reading in http headers */
int http_in_headers;
/** Currently reading in chunk headers, 0=not, 1=firstline, 2=unused
@ -216,6 +233,18 @@ struct comm_point {
struct sldns_buffer* http_temp;
/** http stored content in buffer */
size_t http_stored;
/* -------- HTTP/2 ------- */
/** http2 session */
struct http2_session* h2_session;
/** set to 1 if h2 is negotiated to be used (using alpn) */
int use_h2;
/** stream currently being handled */
struct http2_stream* h2_stream;
/** maximum allowed query buffer size, per stream */
size_t http2_stream_max_qbuffer_size;
/** maximum number of HTTP/2 streams per connection. Send in HTTP/2
* SETTINGS frame. */
uint32_t http2_max_streams;
/* -------- dnstap ------- */
/** the dnstap environment */
@ -456,10 +485,15 @@ struct comm_point* comm_point_create_udp_ancil(struct comm_base* base,
* @param num: becomes max_tcp_count, the routine allocates that
* many tcp handler commpoints.
* @param idle_timeout: TCP idle timeout in ms.
* @param harden_large_queries: whether query size should be limited.
* @param http_max_streams: maximum number of HTTP/2 streams per connection.
* @param http_endpoint: HTTP endpoint to service queries on
* @param tcp_conn_limit: TCP connection limit info.
* @param bufsize: size of buffer to create for handlers.
* @param spoolbuf: shared spool buffer for tcp_req_info structures.
* or NULL to not create those structures in the tcp handlers.
* @param port_type: the type of port we are creating a TCP listener for. Used
* to select handler type to use.
* @param callback: callback function pointer for TCP handlers.
* @param callback_arg: will be passed to your callback function.
* @return: returns the TCP listener commpoint. You can find the
@ -468,8 +502,11 @@ struct comm_point* comm_point_create_udp_ancil(struct comm_base* base,
* Inits timeout to NULL. All handlers are on the free list.
*/
struct comm_point* comm_point_create_tcp(struct comm_base* base,
int fd, int num, int idle_timeout, struct tcl_list* tcp_conn_limit,
int fd, int num, int idle_timeout, int harden_large_queries,
uint32_t http_max_streams, char* http_endpoint,
struct tcl_list* tcp_conn_limit,
size_t bufsize, struct sldns_buffer* spoolbuf,
enum listen_type port_type,
comm_point_callback_type* callback, void* callback_arg);
/**
@ -723,6 +760,110 @@ void comm_point_tcp_handle_callback(int fd, short event, void* arg);
*/
void comm_point_http_handle_callback(int fd, short event, void* arg);
/**
* HTTP2 session. HTTP2 related info per comm point.
*/
struct http2_session {
/** first item in list of streams */
struct http2_stream* first_stream;
#ifdef HAVE_NGHTTP2
/** nghttp2 session */
nghttp2_session *session;
/** store nghttp2 callbacks for easy reuse */
nghttp2_session_callbacks* callbacks;
#endif
/** comm point containing buffer used to build answer in worker or
* module */
struct comm_point* c;
/** session is instructed to get dropped (comm port will be closed) */
int is_drop;
/** postpone dropping the session, can be used to prevent dropping
* while being in a callback */
int postpone_drop;
};
/** enum of HTTP status */
enum http_status {
HTTP_STATUS_OK = 200,
HTTP_STATUS_BAD_REQUEST = 400,
HTTP_STATUS_NOT_FOUND = 404,
HTTP_STATUS_PAYLOAD_TOO_LARGE = 413,
HTTP_STATUS_URI_TOO_LONG = 414,
HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE = 415,
HTTP_STATUS_NOT_IMPLEMENTED = 501
};
/**
* HTTP stream. Part of list of HTTP2 streams per session.
*/
struct http2_stream {
/** next stream in list per session */
struct http2_stream* next;
/** previous stream in list per session */
struct http2_stream* prev;
/** HTTP2 stream ID is an unsigned 31-bit integer */
int32_t stream_id;
/** HTTP method used for this stream */
enum {
HTTP_METHOD_POST = 1,
HTTP_METHOD_GET,
HTTP_METHOD_UNSUPPORTED
} http_method;
/** message contains invalid content type */
int invalid_content_type;
/** message body content type */
size_t content_length;
/** HTTP response status */
enum http_status status;
/** request for non existing endpoint */
int invalid_endpoint;
/** query in request is too large */
int query_too_large;
/** buffer to store query into. Can't use session shared buffer as query
* can arrive in parts, intertwined with frames for other queries. */
struct sldns_buffer* qbuffer;
/** buffer to store response into. Can't use shared buffer as a next
* query read callback can overwrite it before it is send out. */
struct sldns_buffer* rbuffer;
/** mesh area containing mesh state */
struct mesh_area* mesh;
/** mesh state for query. Used to remove mesh reply before closing
* stream. */
struct mesh_state* mesh_state;
};
#ifdef HAVE_NGHTTP2
/** nghttp2 receive cb. Read from SSL connection into nghttp2 buffer */
ssize_t http2_recv_cb(nghttp2_session* session, uint8_t* buf,
size_t len, int flags, void* cb_arg);
/** nghttp2 send callback. Send from nghttp2 buffer to ssl socket */
ssize_t http2_send_cb(nghttp2_session* session, const uint8_t* buf,
size_t len, int flags, void* cb_arg);
/** nghttp2 callback on closing stream */
int http2_stream_close_cb(nghttp2_session* session, int32_t stream_id,
uint32_t error_code, void* cb_arg);
#endif
/**
* Create new http2 stream
* @param stream_id: ID for stream to create.
* @return malloc'ed stream, NULL on error
*/
struct http2_stream* http2_stream_create(int32_t stream_id);
/**
* Add new stream to session linked list
* @param h2_session: http2 session to add stream to
* @param h2_stream: stream to add to session list
*/
void http2_session_add_stream(struct http2_session* h2_session,
struct http2_stream* h2_stream);
/** Add mesh state to stream. To be able to remove mesh reply on stream closure
*/
void http2_stream_add_meshstate(struct http2_stream* h2_stream,
struct mesh_area* mesh, struct mesh_state* m);
/**
* This routine is published for checks and tests, and is only used internally.
* handle libevent callback for timer comm.

View File

@ -1030,8 +1030,6 @@ anchors_assemble_rrsets(struct val_anchors* anchors)
")", b);
(void)rbtree_delete(anchors->tree, &ta->node);
lock_basic_unlock(&ta->lock);
if(anchors->dlv_anchor == ta)
anchors->dlv_anchor = NULL;
anchors_delfunc(&ta->node, NULL);
ta = next;
continue;
@ -1103,37 +1101,6 @@ anchors_apply_cfg(struct val_anchors* anchors, struct config_file* cfg)
return 0;
}
}
if(cfg->dlv_anchor_file && cfg->dlv_anchor_file[0] != 0) {
struct trust_anchor* dlva;
nm = cfg->dlv_anchor_file;
if(cfg->chrootdir && cfg->chrootdir[0] && strncmp(nm,
cfg->chrootdir, strlen(cfg->chrootdir)) == 0)
nm += strlen(cfg->chrootdir);
if(!(dlva = anchor_read_file(anchors, parsebuf,
nm, 1))) {
log_err("error reading dlv-anchor-file: %s",
cfg->dlv_anchor_file);
sldns_buffer_free(parsebuf);
return 0;
}
lock_basic_lock(&anchors->lock);
anchors->dlv_anchor = dlva;
lock_basic_unlock(&anchors->lock);
}
for(f = cfg->dlv_anchor_list; f; f = f->next) {
struct trust_anchor* dlva;
if(!f->str || f->str[0] == 0) /* empty "" */
continue;
if(!(dlva = anchor_store_str(
anchors, parsebuf, f->str))) {
log_err("error in dlv-anchor: \"%s\"", f->str);
sldns_buffer_free(parsebuf);
return 0;
}
lock_basic_lock(&anchors->lock);
anchors->dlv_anchor = dlva;
lock_basic_unlock(&anchors->lock);
}
/* do autr last, so that it sees what anchors are filled by other
* means can can print errors about double config for the name */
for(f = cfg->auto_trust_anchor_file_list; f; f = f->next) {

View File

@ -67,8 +67,6 @@ struct val_anchors {
* contents of type trust_anchor.
*/
rbtree_type* tree;
/** The DLV trust anchor (if one is configured, else NULL) */
struct trust_anchor* dlv_anchor;
/** Autotrust global data, anchors sorted by next probe time */
struct autr_global_data* autr;
};

View File

@ -965,108 +965,6 @@ static int neg_closest_data(struct val_neg_zone* zone,
}
}
int val_neg_dlvlookup(struct val_neg_cache* neg, uint8_t* qname, size_t len,
uint16_t qclass, struct rrset_cache* rrset_cache, time_t now)
{
/* lookup closest zone */
struct val_neg_zone* zone;
struct val_neg_data* data;
int labs;
struct ub_packed_rrset_key* nsec;
struct packed_rrset_data* d;
uint32_t flags;
uint8_t* wc;
struct query_info qinfo;
if(!neg) return 0;
log_nametypeclass(VERB_ALGO, "negcache dlvlookup", qname,
LDNS_RR_TYPE_DLV, qclass);
labs = dname_count_labels(qname);
lock_basic_lock(&neg->lock);
zone = neg_closest_zone_parent(neg, qname, len, labs, qclass);
while(zone && !zone->in_use)
zone = zone->parent;
if(!zone) {
lock_basic_unlock(&neg->lock);
return 0;
}
log_nametypeclass(VERB_ALGO, "negcache zone", zone->name, 0,
zone->dclass);
/* DLV is defined to use NSEC only */
if(zone->nsec3_hash) {
lock_basic_unlock(&neg->lock);
return 0;
}
/* lookup closest data record */
(void)neg_closest_data(zone, qname, len, labs, &data);
while(data && !data->in_use)
data = data->parent;
if(!data) {
lock_basic_unlock(&neg->lock);
return 0;
}
log_nametypeclass(VERB_ALGO, "negcache rr", data->name,
LDNS_RR_TYPE_NSEC, zone->dclass);
/* lookup rrset in rrset cache */
flags = 0;
if(query_dname_compare(data->name, zone->name) == 0)
flags = PACKED_RRSET_NSEC_AT_APEX;
nsec = rrset_cache_lookup(rrset_cache, data->name, data->len,
LDNS_RR_TYPE_NSEC, zone->dclass, flags, now, 0);
/* check if secure and TTL ok */
if(!nsec) {
lock_basic_unlock(&neg->lock);
return 0;
}
d = (struct packed_rrset_data*)nsec->entry.data;
if(!d || now > d->ttl) {
lock_rw_unlock(&nsec->entry.lock);
/* delete data record if expired */
neg_delete_data(neg, data);
lock_basic_unlock(&neg->lock);
return 0;
}
if(d->security != sec_status_secure) {
lock_rw_unlock(&nsec->entry.lock);
neg_delete_data(neg, data);
lock_basic_unlock(&neg->lock);
return 0;
}
verbose(VERB_ALGO, "negcache got secure rrset");
/* check NSEC security */
/* check if NSEC proves no DLV type exists */
/* check if NSEC proves NXDOMAIN for qname */
qinfo.qname = qname;
qinfo.qtype = LDNS_RR_TYPE_DLV;
qinfo.qclass = qclass;
qinfo.local_alias = NULL;
if(!nsec_proves_nodata(nsec, &qinfo, &wc) &&
!val_nsec_proves_name_error(nsec, qname)) {
/* the NSEC is not a denial for the DLV */
lock_rw_unlock(&nsec->entry.lock);
lock_basic_unlock(&neg->lock);
verbose(VERB_ALGO, "negcache not proven");
return 0;
}
/* so the NSEC was a NODATA proof, or NXDOMAIN proof. */
/* no need to check for wildcard NSEC; no wildcards in DLV repos */
/* no need to lookup SOA record for client; no response message */
lock_rw_unlock(&nsec->entry.lock);
/* if OK touch the LRU for neg_data element */
neg_lru_touch(neg, data);
lock_basic_unlock(&neg->lock);
verbose(VERB_ALGO, "negcache DLV denial proven");
return 1;
}
void val_neg_addreferral(struct val_neg_cache* neg, struct reply_info* rep,
uint8_t* zone_name)
{

View File

@ -218,26 +218,6 @@ void val_neg_addreply(struct val_neg_cache* neg, struct reply_info* rep);
void val_neg_addreferral(struct val_neg_cache* neg, struct reply_info* rep,
uint8_t* zone);
/**
* Perform a DLV style lookup
* During the lookup, we could find out that data has expired. In that
* case the neg_cache entries are removed, and lookup fails.
*
* @param neg: negative cache.
* @param qname: name to look for
* @param len: length of qname.
* @param qclass: class to look in.
* @param rrset_cache: the rrset cache, for NSEC lookups.
* @param now: current time for ttl checks.
* @return
* 0 on error
* 0 if no proof of negative
* 1 if indeed negative was proven
* thus, qname DLV qclass does not exist.
*/
int val_neg_dlvlookup(struct val_neg_cache* neg, uint8_t* qname, size_t len,
uint16_t qclass, struct rrset_cache* rrset_cache, time_t now);
/**
* For the given query, try to get a reply out of the negative cache.
* The reply still needs to be validated.

View File

@ -541,86 +541,3 @@ val_nsec_proves_no_wc(struct ub_packed_rrset_key* nsec, uint8_t* qname,
}
return 0;
}
/**
* Find shared topdomain that exists
*/
static void
dlv_topdomain(struct ub_packed_rrset_key* nsec, uint8_t* qname,
uint8_t** nm, size_t* nm_len)
{
/* make sure reply is part of nm */
/* take shared topdomain with left of NSEC. */
/* because, if empty nonterminal, then right is subdomain of qname.
* and any shared topdomain would be empty nonterminals.
*
* If nxdomain, then the right is bigger, and could have an
* interesting shared topdomain, but if it does have one, it is
* an empty nonterminal. An empty nonterminal shared with the left
* one. */
int n;
uint8_t* common = dname_get_shared_topdomain(qname, nsec->rk.dname);
n = dname_count_labels(*nm) - dname_count_labels(common);
dname_remove_labels(nm, nm_len, n);
}
int val_nsec_check_dlv(struct query_info* qinfo,
struct reply_info* rep, uint8_t** nm, size_t* nm_len)
{
uint8_t* next;
size_t i, nlen;
int c;
/* we should now have a NOERROR/NODATA or NXDOMAIN message */
if(rep->an_numrrsets != 0) {
return 0;
}
/* is this NOERROR ? */
if(FLAGS_GET_RCODE(rep->flags) == LDNS_RCODE_NOERROR) {
/* it can be a plain NSEC match - go up one more level. */
/* or its an empty nonterminal - go up to nonempty level */
for(i=0; i<rep->ns_numrrsets; i++) {
if(htons(rep->rrsets[i]->rk.type)!=LDNS_RR_TYPE_NSEC ||
!nsec_get_next(rep->rrsets[i], &next, &nlen))
continue;
c = dname_canonical_compare(
rep->rrsets[i]->rk.dname, qinfo->qname);
if(c == 0) {
/* plain match */
if(nsec_has_type(rep->rrsets[i],
LDNS_RR_TYPE_DLV))
return 0;
dname_remove_label(nm, nm_len);
return 1;
} else if(c < 0 &&
dname_strict_subdomain_c(next, qinfo->qname)) {
/* ENT */
dlv_topdomain(rep->rrsets[i], qinfo->qname,
nm, nm_len);
return 1;
}
}
return 0;
}
/* is this NXDOMAIN ? */
if(FLAGS_GET_RCODE(rep->flags) == LDNS_RCODE_NXDOMAIN) {
/* find the qname denial NSEC record. It can tell us
* a closest encloser name; or that we not need bother */
for(i=0; i<rep->ns_numrrsets; i++) {
if(htons(rep->rrsets[i]->rk.type) != LDNS_RR_TYPE_NSEC)
continue;
if(val_nsec_proves_name_error(rep->rrsets[i],
qinfo->qname)) {
log_nametypeclass(VERB_ALGO, "topdomain on",
rep->rrsets[i]->rk.dname,
ntohs(rep->rrsets[i]->rk.type), 0);
dlv_topdomain(rep->rrsets[i], qinfo->qname,
nm, nm_len);
return 1;
}
}
return 0;
}
return 0;
}

View File

@ -158,19 +158,6 @@ uint8_t* nsec_closest_encloser(uint8_t* qname,
int val_nsec_proves_no_wc(struct ub_packed_rrset_key* nsec, uint8_t* qname,
size_t qnamelen);
/**
* Determine the DLV result, what to do with NSEC DLV reply.
* @param qinfo: what was queried for.
* @param rep: the nonpositive reply.
* @param nm: dlv lookup name, to adjust for new lookup name (if needed).
* @param nm_len: length of lookup name.
* @return 0 on error, 1 if a higher point is found.
* If the higher point is above the dlv repo anchor, the qname does
* not exist.
*/
int val_nsec_check_dlv(struct query_info* qinfo,
struct reply_info* rep, uint8_t** nm, size_t* nm_len);
/**
* Determine if an nsec proves an insecure delegation towards the qname.
* @param nsec: nsec rrset.

View File

@ -390,10 +390,8 @@ generate_request(struct module_qstate* qstate, int id, uint8_t* name,
ask.local_alias = NULL;
log_query_info(VERB_ALGO, "generate request", &ask);
/* enable valrec flag to avoid recursion to the same validation
* routine, this lookup is simply a lookup. DLVs need validation */
if(qtype == LDNS_RR_TYPE_DLV)
valrec = 0;
else valrec = 1;
* routine, this lookup is simply a lookup. */
valrec = 1;
fptr_ok(fptr_whitelist_modenv_detect_cycle(qstate->env->detect_cycle));
if((*qstate->env->detect_cycle)(qstate, &ask,
@ -1585,7 +1583,7 @@ processInit(struct module_qstate* qstate, struct val_qstate* vq,
vq->key_entry = key_cache_obtain(ve->kcache, lookup_name, lookup_len,
vq->qchase.qclass, qstate->region, *qstate->env->now);
/* there is no key(from DLV) and no trust anchor */
/* there is no key and no trust anchor */
if(vq->key_entry == NULL && anchor == NULL) {
/*response isn't under a trust anchor, so we cannot validate.*/
vq->chase_reply->security = sec_status_indeterminate;
@ -1603,7 +1601,6 @@ processInit(struct module_qstate* qstate, struct val_qstate* vq,
val_mark_insecure(vq->chase_reply, anchor->name,
qstate->env->rrset_cache, qstate->env);
lock_basic_unlock(&anchor->lock);
vq->dlv_checked=1; /* skip DLV check */
/* go to finished state to cache this result */
vq->state = VAL_FINISHED_STATE;
return 1;
@ -1679,9 +1676,8 @@ processFindKey(struct module_qstate* qstate, struct val_qstate* vq, int id)
/* We know that state.key_entry is not 0 or bad key -- if it were,
* then previous processing should have directed this event to
* a different state.
* It could be an isnull key, which signals that a DLV was just
* done and the DNSKEY after the DLV failed with dnssec-retry state
* and the DNSKEY has to be performed again. */
* It could be an isnull key, which signals the DNSKEY failed
* with retry and has to be looked up again. */
log_assert(vq->key_entry && !key_entry_isbad(vq->key_entry));
if(key_entry_isnull(vq->key_entry)) {
if(!generate_request(qstate, id, vq->ds_rrset->rk.dname,
@ -1985,148 +1981,6 @@ processValidate(struct module_qstate* qstate, struct val_qstate* vq,
return 1;
}
/**
* Init DLV check.
* DLV is going to be decommissioned, but the code is still here for some time.
*
* Called when a query is determined by other trust anchors to be insecure
* (or indeterminate). Then we look if there is a key in the DLV.
* Performs aggressive negative cache check to see if there is no key.
* Otherwise, spawns a DLV query, and changes to the DLV wait state.
*
* @param qstate: query state.
* @param vq: validator query state.
* @param ve: validator shared global environment.
* @param id: module id.
* @return true if there is no DLV.
* false: processing is finished for the validator operate().
* This function may exit in three ways:
* o no DLV (aggressive cache), so insecure. (true)
* o error - stop processing (false)
* o DLV lookup was started, stop processing (false)
*/
static int
val_dlv_init(struct module_qstate* qstate, struct val_qstate* vq,
struct val_env* ve, int id)
{
uint8_t* nm;
size_t nm_len;
struct module_qstate* newq = NULL;
/* there must be a DLV configured */
log_assert(qstate->env->anchors->dlv_anchor);
/* this bool is true to avoid looping in the DLV checks */
log_assert(vq->dlv_checked);
/* init the DLV lookup variables */
vq->dlv_lookup_name = NULL;
vq->dlv_lookup_name_len = 0;
vq->dlv_insecure_at = NULL;
vq->dlv_insecure_at_len = 0;
/* Determine the name for which we want to lookup DLV.
* This name is for the current message, or
* for the current RRset for CNAME, referral subtypes.
* If there is a signer, use that, otherwise the domain name */
if(vq->signer_name) {
nm = vq->signer_name;
nm_len = vq->signer_len;
} else {
/* use qchase */
nm = vq->qchase.qname;
nm_len = vq->qchase.qname_len;
if(vq->qchase.qtype == LDNS_RR_TYPE_DS)
dname_remove_label(&nm, &nm_len);
}
log_nametypeclass(VERB_ALGO, "DLV init look", nm, LDNS_RR_TYPE_DS,
vq->qchase.qclass);
log_assert(nm && nm_len);
/* sanity check: no DLV lookups below the DLV anchor itself.
* Like, an securely insecure delegation there makes no sense. */
if(dname_subdomain_c(nm, qstate->env->anchors->dlv_anchor->name)) {
verbose(VERB_ALGO, "DLV lookup within DLV repository denied");
return 1;
}
/* concat name (minus root label) + dlv name */
vq->dlv_lookup_name_len = nm_len - 1 +
qstate->env->anchors->dlv_anchor->namelen;
vq->dlv_lookup_name = regional_alloc(qstate->region,
vq->dlv_lookup_name_len);
if(!vq->dlv_lookup_name) {
log_err("Out of memory preparing DLV lookup");
return val_error(qstate, id);
}
memmove(vq->dlv_lookup_name, nm, nm_len-1);
memmove(vq->dlv_lookup_name+nm_len-1,
qstate->env->anchors->dlv_anchor->name,
qstate->env->anchors->dlv_anchor->namelen);
log_nametypeclass(VERB_ALGO, "DLV name", vq->dlv_lookup_name,
LDNS_RR_TYPE_DLV, vq->qchase.qclass);
/* determine where the insecure point was determined, the DLV must
* be equal or below that to continue building the trust chain
* down. May be NULL if no trust chain was built yet */
nm = NULL;
if(vq->key_entry && key_entry_isnull(vq->key_entry)) {
nm = vq->key_entry->name;
nm_len = vq->key_entry->namelen;
}
if(nm) {
vq->dlv_insecure_at_len = nm_len - 1 +
qstate->env->anchors->dlv_anchor->namelen;
vq->dlv_insecure_at = regional_alloc(qstate->region,
vq->dlv_insecure_at_len);
if(!vq->dlv_insecure_at) {
log_err("Out of memory preparing DLV lookup");
return val_error(qstate, id);
}
memmove(vq->dlv_insecure_at, nm, nm_len-1);
memmove(vq->dlv_insecure_at+nm_len-1,
qstate->env->anchors->dlv_anchor->name,
qstate->env->anchors->dlv_anchor->namelen);
log_nametypeclass(VERB_ALGO, "insecure_at",
vq->dlv_insecure_at, 0, vq->qchase.qclass);
}
/* If we can find the name in the aggressive negative cache,
* give up; insecure is the answer */
while(val_neg_dlvlookup(ve->neg_cache, vq->dlv_lookup_name,
vq->dlv_lookup_name_len, vq->qchase.qclass,
qstate->env->rrset_cache, *qstate->env->now)) {
/* go up */
dname_remove_label(&vq->dlv_lookup_name,
&vq->dlv_lookup_name_len);
/* too high? */
if(!dname_subdomain_c(vq->dlv_lookup_name,
qstate->env->anchors->dlv_anchor->name)) {
verbose(VERB_ALGO, "ask above dlv repo");
return 1; /* Above the repo is insecure */
}
/* above chain of trust? */
if(vq->dlv_insecure_at && !dname_subdomain_c(
vq->dlv_lookup_name, vq->dlv_insecure_at)) {
verbose(VERB_ALGO, "ask above insecure endpoint");
return 1;
}
}
/* perform a lookup for the DLV; with validation */
vq->state = VAL_DLVLOOKUP_STATE;
if(!generate_request(qstate, id, vq->dlv_lookup_name,
vq->dlv_lookup_name_len, LDNS_RR_TYPE_DLV,
vq->qchase.qclass, 0, &newq, 0)) {
return val_error(qstate, id);
}
/* Find the closest encloser DLV from the repository.
* then that is used to build another chain of trust
* This may first require a query 'too low' that has NSECs in
* the answer, from which we determine the closest encloser DLV.
* When determine the closest encloser, skip empty nonterminals,
* since we want a nonempty node in the DLV repository. */
return 0;
}
/**
* The Finished state. The validation status (good or bad) has been determined.
*
@ -2145,16 +1999,6 @@ processFinished(struct module_qstate* qstate, struct val_qstate* vq,
qstate->query_flags, &qstate->qinfo, &vq->qchase,
vq->orig_msg->rep, vq->rrset_skip);
/* if the result is insecure or indeterminate and we have not
* checked the DLV yet, check the DLV */
if((vq->chase_reply->security == sec_status_insecure ||
vq->chase_reply->security == sec_status_indeterminate) &&
qstate->env->anchors->dlv_anchor && !vq->dlv_checked) {
vq->dlv_checked = 1;
if(!val_dlv_init(qstate, vq, ve, id))
return 0;
}
/* store overall validation result in orig_msg */
if(vq->rrset_skip == 0)
vq->orig_msg->rep->security = vq->chase_reply->security;
@ -2177,7 +2021,6 @@ processFinished(struct module_qstate* qstate, struct val_qstate* vq,
/* and restart for this rrset */
verbose(VERB_ALGO, "validator: go to next rrset");
vq->chase_reply->security = sec_status_unchecked;
vq->dlv_checked = 0; /* can do DLV for this RR */
vq->state = VAL_INIT_STATE;
return 1;
}
@ -2195,7 +2038,6 @@ processFinished(struct module_qstate* qstate, struct val_qstate* vq,
log_query_info(VERB_ALGO, "validator: chased to",
&vq->qchase);
vq->chase_reply->security = sec_status_unchecked;
vq->dlv_checked = 0; /* can do DLV for this RR */
vq->state = VAL_INIT_STATE;
return 1;
}
@ -2321,119 +2163,6 @@ processFinished(struct module_qstate* qstate, struct val_qstate* vq,
return 0;
}
/**
* The DLVLookup state. Process DLV lookups.
*
* @param qstate: query state.
* @param vq: validator query state.
* @param ve: validator shared global environment.
* @param id: module id.
* @return true if the event should be processed further on return, false if
* not.
*/
static int
processDLVLookup(struct module_qstate* qstate, struct val_qstate* vq,
struct val_env* ve, int id)
{
struct module_qstate* newq = NULL;
/* see if this we are ready to continue normal resolution */
/* we may need more DLV lookups */
if(vq->dlv_status==dlv_error)
verbose(VERB_ALGO, "DLV woke up with status dlv_error");
else if(vq->dlv_status==dlv_success)
verbose(VERB_ALGO, "DLV woke up with status dlv_success");
else if(vq->dlv_status==dlv_ask_higher)
verbose(VERB_ALGO, "DLV woke up with status dlv_ask_higher");
else if(vq->dlv_status==dlv_there_is_no_dlv)
verbose(VERB_ALGO, "DLV woke up with status dlv_there_is_no_dlv");
else verbose(VERB_ALGO, "DLV woke up with status unknown");
if(vq->dlv_status == dlv_error) {
verbose(VERB_QUERY, "failed DLV lookup");
errinf(qstate, "failed DLV lookup");
return val_error(qstate, id);
} else if(vq->dlv_status == dlv_success) {
uint8_t* nm;
size_t nmlen;
/* chain continues with DNSKEY, continue in FINDKEY */
vq->state = VAL_FINDKEY_STATE;
/* strip off the DLV suffix from the name; could result in . */
log_assert(dname_subdomain_c(vq->ds_rrset->rk.dname,
qstate->env->anchors->dlv_anchor->name));
nmlen = vq->ds_rrset->rk.dname_len -
qstate->env->anchors->dlv_anchor->namelen + 1;
nm = regional_alloc_init(qstate->region,
vq->ds_rrset->rk.dname, nmlen);
if(!nm) {
log_err("Out of memory in DLVLook");
return val_error(qstate, id);
}
nm[nmlen-1] = 0;
vq->ds_rrset->rk.dname = nm;
vq->ds_rrset->rk.dname_len = nmlen;
/* create a nullentry for the key so the dnskey lookup
* can be retried after a validation failure for it */
vq->key_entry = key_entry_create_null(qstate->region,
nm, nmlen, vq->qchase.qclass, 0, 0);
if(!vq->key_entry) {
log_err("Out of memory in DLVLook");
return val_error(qstate, id);
}
if(!generate_request(qstate, id, vq->ds_rrset->rk.dname,
vq->ds_rrset->rk.dname_len, LDNS_RR_TYPE_DNSKEY,
vq->qchase.qclass, BIT_CD, &newq, 0)) {
verbose(VERB_ALGO, "error generating DNSKEY request");
return val_error(qstate, id);
}
return 0;
} else if(vq->dlv_status == dlv_there_is_no_dlv) {
/* continue with the insecure result we got */
vq->state = VAL_FINISHED_STATE;
return 1;
}
log_assert(vq->dlv_status == dlv_ask_higher);
/* ask higher, make sure we stay in DLV repo, below dlv_at */
if(!dname_subdomain_c(vq->dlv_lookup_name,
qstate->env->anchors->dlv_anchor->name)) {
/* just like, there is no DLV */
verbose(VERB_ALGO, "ask above dlv repo");
vq->state = VAL_FINISHED_STATE;
return 1;
}
if(vq->dlv_insecure_at && !dname_subdomain_c(vq->dlv_lookup_name,
vq->dlv_insecure_at)) {
/* already checked a chain lower than dlv_lookup_name */
verbose(VERB_ALGO, "ask above insecure endpoint");
log_nametypeclass(VERB_ALGO, "enpt", vq->dlv_insecure_at, 0, 0);
vq->state = VAL_FINISHED_STATE;
return 1;
}
/* check negative cache before making new request */
if(val_neg_dlvlookup(ve->neg_cache, vq->dlv_lookup_name,
vq->dlv_lookup_name_len, vq->qchase.qclass,
qstate->env->rrset_cache, *qstate->env->now)) {
/* does not exist, go up one (go higher). */
dname_remove_label(&vq->dlv_lookup_name,
&vq->dlv_lookup_name_len);
/* limit number of labels, limited number of recursion */
return processDLVLookup(qstate, vq, ve, id);
}
if(!generate_request(qstate, id, vq->dlv_lookup_name,
vq->dlv_lookup_name_len, LDNS_RR_TYPE_DLV,
vq->qchase.qclass, 0, &newq, 0)) {
return val_error(qstate, id);
}
return 0;
}
/**
* Handle validator state.
* If a method returns true, the next state is started. If false, then
@ -2464,9 +2193,6 @@ val_handle(struct module_qstate* qstate, struct val_qstate* vq,
case VAL_FINISHED_STATE:
cont = processFinished(qstate, vq, ve, id);
break;
case VAL_DLVLOOKUP_STATE:
cont = processDLVLookup(qstate, vq, ve, id);
break;
default:
log_warn("validator: invalid state %d",
vq->state);
@ -3105,99 +2831,6 @@ process_prime_response(struct module_qstate* qstate, struct val_qstate* vq,
/* the qstate will be reactivated after inform_super is done */
}
/**
* Process DLV response. Called from inform_supers.
* Because it is in inform_supers, the mesh itself is busy doing callbacks
* for a state that is to be deleted soon; don't touch the mesh; instead
* set a state in the super, as the super will be reactivated soon.
* Perform processing to determine what state to set in the super.
*
* @param qstate: query state that is validating and asked for a DLV.
* @param vq: validator query state
* @param id: module id.
* @param rcode: rcode result value.
* @param msg: result message (if rcode is OK).
* @param qinfo: from the sub query state, query info.
*/
static void
process_dlv_response(struct module_qstate* qstate, struct val_qstate* vq,
int id, int rcode, struct dns_msg* msg, struct query_info* qinfo)
{
struct val_env* ve = (struct val_env*)qstate->env->modinfo[id];
verbose(VERB_ALGO, "process dlv response to super");
if(rcode != LDNS_RCODE_NOERROR) {
/* lookup failed, set in vq to give up */
vq->dlv_status = dlv_error;
verbose(VERB_ALGO, "response is error");
return;
}
if(msg->rep->security != sec_status_secure) {
vq->dlv_status = dlv_error;
verbose(VERB_ALGO, "response is not secure, %s",
sec_status_to_string(msg->rep->security));
return;
}
/* was the lookup a success? validated DLV? */
if(FLAGS_GET_RCODE(msg->rep->flags) == LDNS_RCODE_NOERROR &&
msg->rep->an_numrrsets == 1 &&
msg->rep->security == sec_status_secure &&
ntohs(msg->rep->rrsets[0]->rk.type) == LDNS_RR_TYPE_DLV &&
ntohs(msg->rep->rrsets[0]->rk.rrset_class) == qinfo->qclass &&
query_dname_compare(msg->rep->rrsets[0]->rk.dname,
vq->dlv_lookup_name) == 0) {
/* yay! it is just like a DS */
vq->ds_rrset = (struct ub_packed_rrset_key*)
regional_alloc_init(qstate->region,
msg->rep->rrsets[0], sizeof(*vq->ds_rrset));
if(!vq->ds_rrset) {
log_err("out of memory in process_dlv");
return;
}
vq->ds_rrset->entry.key = vq->ds_rrset;
vq->ds_rrset->rk.dname = (uint8_t*)regional_alloc_init(
qstate->region, vq->ds_rrset->rk.dname,
vq->ds_rrset->rk.dname_len);
if(!vq->ds_rrset->rk.dname) {
log_err("out of memory in process_dlv");
vq->dlv_status = dlv_error;
return;
}
vq->ds_rrset->entry.data = regional_alloc_init(qstate->region,
vq->ds_rrset->entry.data,
packed_rrset_sizeof(vq->ds_rrset->entry.data));
if(!vq->ds_rrset->entry.data) {
log_err("out of memory in process_dlv");
vq->dlv_status = dlv_error;
return;
}
packed_rrset_ptr_fixup(vq->ds_rrset->entry.data);
/* make vq do a DNSKEY query next up */
vq->dlv_status = dlv_success;
return;
}
/* store NSECs into negative cache */
val_neg_addreply(ve->neg_cache, msg->rep);
/* was the lookup a failure?
* if we have to go up into the DLV for a higher DLV anchor
* then set this in the vq, so it can make queries when activated.
* See if the NSECs indicate that we should look for higher DLV
* or, that there is no DLV securely */
if(!val_nsec_check_dlv(qinfo, msg->rep, &vq->dlv_lookup_name,
&vq->dlv_lookup_name_len)) {
vq->dlv_status = dlv_error;
verbose(VERB_ALGO, "nsec error");
return;
}
if(!dname_subdomain_c(vq->dlv_lookup_name,
qstate->env->anchors->dlv_anchor->name)) {
vq->dlv_status = dlv_there_is_no_dlv;
return;
}
vq->dlv_status = dlv_ask_higher;
}
/*
* inform validator super.
*
@ -3233,10 +2866,6 @@ val_inform_super(struct module_qstate* qstate, int id,
qstate->return_msg, &qstate->qinfo,
qstate->reply_origin);
return;
} else if(qstate->qinfo.qtype == LDNS_RR_TYPE_DLV) {
process_dlv_response(super, vq, id, qstate->return_rcode,
qstate->return_msg, &qstate->qinfo);
return;
}
log_err("internal error in validator: no inform_supers possible");
}
@ -3284,7 +2913,6 @@ val_state_to_string(enum val_state state)
case VAL_FINDKEY_STATE: return "VAL_FINDKEY_STATE";
case VAL_VALIDATE_STATE: return "VAL_VALIDATE_STATE";
case VAL_FINISHED_STATE: return "VAL_FINISHED_STATE";
case VAL_DLVLOOKUP_STATE: return "VAL_DLVLOOKUP_STATE";
}
return "UNKNOWN VALIDATOR STATE";
}

View File

@ -137,8 +137,6 @@ enum val_state {
VAL_VALIDATE_STATE,
/** finish up */
VAL_FINISHED_STATE,
/** DLV lookup state, processing DLV queries */
VAL_DLVLOOKUP_STATE
};
/**
@ -217,27 +215,6 @@ struct val_qstate {
/** true if this state is waiting to prime a trust anchor */
int wait_prime_ta;
/** have we already checked the DLV? */
int dlv_checked;
/** The name for which the DLV is looked up. For the current message
* or for the current RRset (for CNAME, REFERRAL types).
* If there is signer name, that may be it, else a domain name */
uint8_t* dlv_lookup_name;
/** length of dlv lookup name */
size_t dlv_lookup_name_len;
/** Name at which chain of trust stopped with insecure, starting DLV
* DLV must result in chain going further down */
uint8_t* dlv_insecure_at;
/** length of dlv insecure point name */
size_t dlv_insecure_at_len;
/** status of DLV lookup. Indication to VAL_DLV_STATE what to do */
enum dlv_status {
dlv_error, /* server failure */
dlv_success, /* got a DLV */
dlv_ask_higher, /* ask again */
dlv_there_is_no_dlv /* got no DLV, sure of it */
} dlv_status;
};
/**

View File

@ -30,6 +30,9 @@
/* Whether daemon is deprecated */
/* #undef DEPRECATED_DAEMON */
/* Define this to enable kernel based UDP source port randomization. */
/* #undef DISABLE_EXPLICIT_PORT_RANDOMISATION */
/* default dnstap socket path */
/* #undef DNSTAP_SOCKET_PATH */
@ -65,6 +68,15 @@
/* Whether the C compiler accepts the "weak" attribute */
#define HAVE_ATTR_WEAK 1
/* If we have be64toh */
/* #undef HAVE_BE64TOH */
/* Define to 1 if you have the <bsd/stdlib.h> header file. */
/* #undef HAVE_BSD_STDLIB_H */
/* Define to 1 if you have the <bsd/string.h> header file. */
/* #undef HAVE_BSD_STRING_H */
/* Define to 1 if you have the `chown' function. */
#define HAVE_CHOWN 1
@ -103,6 +115,10 @@
don't. */
#define HAVE_DECL_INET_PTON 1
/* Define to 1 if you have the declaration of `nghttp2_session_server_new',
and to 0 if you don't. */
/* #undef HAVE_DECL_NGHTTP2_SESSION_SERVER_NEW */
/* Define to 1 if you have the declaration of `NID_ED25519', and to 0 if you
don't. */
#define HAVE_DECL_NID_ED25519 1
@ -169,6 +185,9 @@
/* Define to 1 if you have the `endservent' function. */
#define HAVE_ENDSERVENT 1
/* Define to 1 if you have the `ENGINE_cleanup' function. */
/* #undef HAVE_ENGINE_CLEANUP */
/* Define to 1 if you have the `ERR_free_strings' function. */
/* #undef HAVE_ERR_FREE_STRINGS */
@ -208,6 +227,9 @@
/* Define to 1 if you have the `EVP_EncryptInit_ex' function. */
#define HAVE_EVP_ENCRYPTINIT_EX 1
/* Define to 1 if you have the `EVP_MAC_CTX_set_params' function. */
/* #undef HAVE_EVP_MAC_CTX_SET_PARAMS */
/* Define to 1 if you have the `EVP_MD_CTX_new' function. */
#define HAVE_EVP_MD_CTX_NEW 1
@ -256,6 +278,9 @@
/* Define to 1 if you have the `getentropy' function. */
/* #undef HAVE_GETENTROPY */
/* Define to 1 if you have the `getifaddrs' function. */
#define HAVE_GETIFADDRS 1
/* Define to 1 if you have the <getopt.h> header file. */
#define HAVE_GETOPT_H 1
@ -283,8 +308,11 @@
/* Define to 1 if you have the `HMAC_Init_ex' function. */
#define HAVE_HMAC_INIT_EX 1
/* If you have HMAC_Update */
#define HAVE_HMAC_UPDATE 1
/* If we have htobe64 */
/* #undef HAVE_HTOBE64 */
/* Define to 1 if you have the <ifaddrs.h> header file. */
#define HAVE_IFADDRS_H 1
/* Define to 1 if you have the `inet_aton' function. */
#define HAVE_INET_ATON 1
@ -313,6 +341,9 @@
/* Define to 1 if you have the `kill' function. */
#define HAVE_KILL 1
/* Use portable libbsd functions */
/* #undef HAVE_LIBBSD */
/* Define to 1 if you have the <libkern/OSByteOrder.h> header file. */
/* #undef HAVE_LIBKERN_OSBYTEORDER_H */
@ -352,6 +383,15 @@
/* Define to 1 if you have the <nettle/eddsa.h> header file. */
/* #undef HAVE_NETTLE_EDDSA_H */
/* Define to 1 if you have the <net/if.h> header file. */
#define HAVE_NET_IF_H 1
/* Define this to use nghttp2 client. */
/* #undef HAVE_NGHTTP2 */
/* Define to 1 if you have the <nghttp2/nghttp2.h> header file. */
/* #undef HAVE_NGHTTP2_NGHTTP2_H */
/* Use libnss for crypto */
/* #undef HAVE_NSS */
@ -367,6 +407,9 @@
/* Define to 1 if you have the <openssl/conf.h> header file. */
#define HAVE_OPENSSL_CONF_H 1
/* Define to 1 if you have the <openssl/core_names.h> header file. */
/* #undef HAVE_OPENSSL_CORE_NAMES_H */
/* Define to 1 if you have the <openssl/dh.h> header file. */
#define HAVE_OPENSSL_DH_H 1
@ -475,14 +518,18 @@
/* Define if you have the SSL libraries installed. */
#define HAVE_SSL /**/
/* Define to 1 if you have the `SSL_CTX_set_alpn_select_cb' function. */
#define HAVE_SSL_CTX_SET_ALPN_SELECT_CB 1
/* Define to 1 if you have the `SSL_CTX_set_ciphersuites' function. */
#define HAVE_SSL_CTX_SET_CIPHERSUITES 1
/* Define to 1 if you have the `SSL_CTX_set_security_level' function. */
#define HAVE_SSL_CTX_SET_SECURITY_LEVEL 1
/* Define to 1 if you have the `SSL_CTX_set_tlsext_ticket_key_cb' function. */
/* #undef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_CB */
/* Define to 1 if you have the `SSL_CTX_set_tlsext_ticket_key_evp_cb'
function. */
/* #undef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB */
/* Define to 1 if you have the `SSL_get0_peername' function. */
#define HAVE_SSL_GET0_PEERNAME 1
@ -550,6 +597,9 @@
/* Define to 1 if you have the <sys/resource.h> header file. */
#define HAVE_SYS_RESOURCE_H 1
/* Define to 1 if you have the <sys/select.h> header file. */
#define HAVE_SYS_SELECT_H 1
/* Define to 1 if you have the <sys/sha2.h> header file. */
/* #undef HAVE_SYS_SHA2_H */
@ -577,6 +627,9 @@
/* Define to 1 if you have the <sys/wait.h> header file. */
#define HAVE_SYS_WAIT_H 1
/* Define to 1 if you have the <TargetConditionals.h> header file. */
/* #undef HAVE_TARGETCONDITIONALS_H */
/* Define to 1 if you have the <time.h> header file. */
#define HAVE_TIME_H 1
@ -678,7 +731,7 @@
#define PACKAGE_NAME "unbound"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "unbound 1.10.1"
#define PACKAGE_STRING "unbound 1.12.0"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "unbound"
@ -687,7 +740,7 @@
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION "1.11.0"
#define PACKAGE_VERSION "1.12.0"
/* default pidfile location */
#define PIDFILE "/var/unbound/unbound.pid"
@ -709,7 +762,7 @@
#define ROOT_CERT_FILE "/var/unbound/icannbundle.pem"
/* version number for resource files */
#define RSRC_PACKAGE_VERSION 1,11,0,0
#define RSRC_PACKAGE_VERSION 1,12,0,0
/* Directory to chdir to */
#define RUN_DIR "/var/unbound"
@ -800,6 +853,9 @@
/* Define to 1 to use ipset support */
/* #undef USE_IPSET */
/* Define if you enable libevent */
#define USE_LIBEVENT 1
/* Define if you want to use internal select based events */
#define USE_MINI_EVENT 1
@ -849,6 +905,9 @@
/* the version of the windows API enabled */
#define WINVER 0x0502
/* Define if you want dynlib module. */
/* #undef WITH_DYNLIBMODULE */
/* Define if you want Python module. */
/* #undef WITH_PYTHONMODULE */
@ -1241,6 +1300,11 @@ char *strptime(const char *s, const char *format, struct tm *tm);
void *reallocarray(void *ptr, size_t nmemb, size_t size);
#endif
#ifdef HAVE_LIBBSD
#include <bsd/string.h>
#include <bsd/stdlib.h>
#endif
#ifdef HAVE_LIBRESSL
# if !HAVE_DECL_STRLCPY
size_t strlcpy(char *dst, const char *src, size_t siz);
@ -1329,6 +1393,8 @@ void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
#define UNBOUND_DNS_PORT 53
/** default port for DNS over TLS traffic. */
#define UNBOUND_DNS_OVER_TLS_PORT 853
/** default port for DNS over HTTPS traffic. */
#define UNBOUND_DNS_OVER_HTTPS_PORT 443
/** default port for unbound control traffic, registered port with IANA,
ub-dns-control 8953/tcp unbound dns nameserver control */
#define UNBOUND_CONTROL_PORT 8953