unbound: Vendor import 1.16.3
Added ACL per interface, proxy protocol and bug fixes. Announcement: https://nlnetlabs.nl/news/2022/Oct/13/unbound-1.17.0-released/
This commit is contained in:
parent
0dde6f4f8e
commit
643f9a0581
@ -130,7 +130,7 @@ util/fptr_wlist.c util/locks.c util/log.c util/mini_event.c util/module.c \
|
|||||||
util/netevent.c util/net_help.c util/random.c util/rbtree.c util/regional.c \
|
util/netevent.c util/net_help.c util/random.c util/rbtree.c util/regional.c \
|
||||||
util/rtt.c util/edns.c util/storage/dnstree.c util/storage/lookup3.c \
|
util/rtt.c util/edns.c util/storage/dnstree.c util/storage/lookup3.c \
|
||||||
util/storage/lruhash.c util/storage/slabhash.c util/tcp_conn_limit.c \
|
util/storage/lruhash.c util/storage/slabhash.c util/tcp_conn_limit.c \
|
||||||
util/timehist.c util/tube.c \
|
util/timehist.c util/tube.c util/proxy_protocol.c \
|
||||||
util/ub_event.c util/ub_event_pluggable.c util/winsock_event.c \
|
util/ub_event.c util/ub_event_pluggable.c util/winsock_event.c \
|
||||||
validator/autotrust.c validator/val_anchor.c validator/validator.c \
|
validator/autotrust.c validator/val_anchor.c validator/validator.c \
|
||||||
validator/val_kcache.c validator/val_kentry.c validator/val_neg.c \
|
validator/val_kcache.c validator/val_kentry.c validator/val_neg.c \
|
||||||
@ -148,7 +148,7 @@ outbound_list.lo alloc.lo config_file.lo configlexer.lo configparser.lo \
|
|||||||
fptr_wlist.lo edns.lo locks.lo log.lo mini_event.lo module.lo net_help.lo \
|
fptr_wlist.lo edns.lo locks.lo log.lo mini_event.lo module.lo net_help.lo \
|
||||||
random.lo rbtree.lo regional.lo rtt.lo dnstree.lo lookup3.lo lruhash.lo \
|
random.lo rbtree.lo regional.lo rtt.lo dnstree.lo lookup3.lo lruhash.lo \
|
||||||
slabhash.lo tcp_conn_limit.lo timehist.lo tube.lo winsock_event.lo \
|
slabhash.lo tcp_conn_limit.lo timehist.lo tube.lo winsock_event.lo \
|
||||||
autotrust.lo val_anchor.lo rpz.lo \
|
autotrust.lo val_anchor.lo rpz.lo proxy_protocol.lo \
|
||||||
validator.lo val_kcache.lo val_kentry.lo val_neg.lo val_nsec3.lo val_nsec.lo \
|
validator.lo val_kcache.lo val_kentry.lo val_neg.lo val_nsec3.lo val_nsec.lo \
|
||||||
val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo $(CACHEDB_OBJ) authzone.lo \
|
val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo $(CACHEDB_OBJ) authzone.lo \
|
||||||
$(SUBNET_OBJ) $(PYTHONMOD_OBJ) $(CHECKLOCK_OBJ) $(DNSTAP_OBJ) $(DNSCRYPT_OBJ) \
|
$(SUBNET_OBJ) $(PYTHONMOD_OBJ) $(CHECKLOCK_OBJ) $(DNSTAP_OBJ) $(DNSCRYPT_OBJ) \
|
||||||
@ -984,6 +984,8 @@ netevent.lo netevent.o: $(srcdir)/util/netevent.c config.h $(srcdir)/util/neteve
|
|||||||
$(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.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)/sldns/str2wire.h \
|
$(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/sldns/str2wire.h \
|
||||||
$(srcdir)/dnstap/dnstap.h $(srcdir)/services/listen_dnsport.h
|
$(srcdir)/dnstap/dnstap.h $(srcdir)/services/listen_dnsport.h
|
||||||
|
proxy_protocol.lo proxy_protocol.o: $(srcdir)/util/proxy_protocol.c config.h \
|
||||||
|
$(srcdir)/util/proxy_protocol.h $(srcdir)/sldns/sbuffer.h
|
||||||
net_help.lo net_help.o: $(srcdir)/util/net_help.c config.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h \
|
net_help.lo net_help.o: $(srcdir)/util/net_help.c config.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h \
|
||||||
$(srcdir)/util/data/dname.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/module.h \
|
$(srcdir)/util/data/dname.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/module.h \
|
||||||
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
|
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
|
||||||
@ -1512,7 +1514,7 @@ asynclook.lo asynclook.o: $(srcdir)/testcode/asynclook.c config.h $(srcdir)/libu
|
|||||||
$(srcdir)/services/modstack.h $(srcdir)/libunbound/unbound-event.h $(srcdir)/util/data/packed_rrset.h \
|
$(srcdir)/services/modstack.h $(srcdir)/libunbound/unbound-event.h $(srcdir)/util/data/packed_rrset.h \
|
||||||
$(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/rrdef.h
|
$(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/rrdef.h
|
||||||
streamtcp.lo streamtcp.o: $(srcdir)/testcode/streamtcp.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
|
streamtcp.lo streamtcp.o: $(srcdir)/testcode/streamtcp.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
|
||||||
$(srcdir)/util/net_help.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/msgparse.h \
|
$(srcdir)/util/net_help.h $(srcdir)/util/proxy_protocol.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/msgparse.h \
|
||||||
$(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgreply.h \
|
$(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgreply.h \
|
||||||
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/dname.h $(srcdir)/sldns/sbuffer.h \
|
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/dname.h $(srcdir)/sldns/sbuffer.h \
|
||||||
$(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h
|
$(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h
|
||||||
|
@ -2,7 +2,8 @@
|
|||||||
# Copyright 2009, Wouter Wijngaards, NLnet Labs.
|
# Copyright 2009, Wouter Wijngaards, NLnet Labs.
|
||||||
# BSD licensed.
|
# BSD licensed.
|
||||||
#
|
#
|
||||||
# Version 43
|
# Version 44
|
||||||
|
# 2022-09-01 fix checking if nonblocking sockets work on OpenBSD.
|
||||||
# 2021-08-17 fix sed script in ssldir split handling.
|
# 2021-08-17 fix sed script in ssldir split handling.
|
||||||
# 2021-08-17 fix for openssl to detect split version, with ssldir_include
|
# 2021-08-17 fix for openssl to detect split version, with ssldir_include
|
||||||
# and ssldir_lib output directories.
|
# and ssldir_lib output directories.
|
||||||
@ -963,6 +964,9 @@ AC_LANG_SOURCE([[
|
|||||||
#ifdef HAVE_SYS_TYPES_H
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_SYS_SELECT_H
|
||||||
|
#include <sys/select.h>
|
||||||
|
#endif
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -57,6 +57,8 @@
|
|||||||
#define BLOCKSZ 64
|
#define BLOCKSZ 64
|
||||||
#define RSBUFSZ (16*BLOCKSZ)
|
#define RSBUFSZ (16*BLOCKSZ)
|
||||||
|
|
||||||
|
#define REKEY_BASE (1024*1024) /* NB. should be a power of 2 */
|
||||||
|
|
||||||
/* Marked MAP_INHERIT_ZERO, so zero'd out in fork children. */
|
/* Marked MAP_INHERIT_ZERO, so zero'd out in fork children. */
|
||||||
static struct {
|
static struct {
|
||||||
size_t rs_have; /* valid bytes at end of rs_buf */
|
size_t rs_have; /* valid bytes at end of rs_buf */
|
||||||
@ -179,6 +181,7 @@ static void
|
|||||||
_rs_stir(void)
|
_rs_stir(void)
|
||||||
{
|
{
|
||||||
u_char rnd[KEYSZ + IVSZ];
|
u_char rnd[KEYSZ + IVSZ];
|
||||||
|
uint32_t rekey_fuzz = 0;
|
||||||
|
|
||||||
if (getentropy(rnd, sizeof rnd) == -1) {
|
if (getentropy(rnd, sizeof rnd) == -1) {
|
||||||
if(errno != ENOSYS ||
|
if(errno != ENOSYS ||
|
||||||
@ -201,7 +204,10 @@ _rs_stir(void)
|
|||||||
rs->rs_have = 0;
|
rs->rs_have = 0;
|
||||||
memset(rsx->rs_buf, 0, sizeof(rsx->rs_buf));
|
memset(rsx->rs_buf, 0, sizeof(rsx->rs_buf));
|
||||||
|
|
||||||
rs->rs_count = 1600000;
|
/* rekey interval should not be predictable */
|
||||||
|
chacha_encrypt_bytes(&rsx->rs_chacha, (uint8_t *)&rekey_fuzz,
|
||||||
|
(uint8_t *)&rekey_fuzz, sizeof(rekey_fuzz));
|
||||||
|
rs->rs_count = REKEY_BASE + (rekey_fuzz % REKEY_BASE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
|
8
config.guess
vendored
8
config.guess
vendored
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
# shellcheck disable=SC2006,SC2268 # see below for rationale
|
# shellcheck disable=SC2006,SC2268 # see below for rationale
|
||||||
|
|
||||||
timestamp='2022-08-01'
|
timestamp='2022-09-17'
|
||||||
|
|
||||||
# This file is free software; you can redistribute it and/or modify it
|
# 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
|
# under the terms of the GNU General Public License as published by
|
||||||
@ -966,6 +966,12 @@ EOF
|
|||||||
GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
|
GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
|
||||||
GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC
|
GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC
|
||||||
;;
|
;;
|
||||||
|
x86_64:[Mm]anagarm:*:*|i?86:[Mm]anagarm:*:*)
|
||||||
|
GUESS="$UNAME_MACHINE-pc-managarm-mlibc"
|
||||||
|
;;
|
||||||
|
*:[Mm]anagarm:*:*)
|
||||||
|
GUESS="$UNAME_MACHINE-unknown-managarm-mlibc"
|
||||||
|
;;
|
||||||
*:Minix:*:*)
|
*:Minix:*:*)
|
||||||
GUESS=$UNAME_MACHINE-unknown-minix
|
GUESS=$UNAME_MACHINE-unknown-minix
|
||||||
;;
|
;;
|
||||||
|
15
config.h.in
15
config.h.in
@ -298,6 +298,9 @@
|
|||||||
/* Define to 1 if you have the `getrlimit' function. */
|
/* Define to 1 if you have the `getrlimit' function. */
|
||||||
#undef HAVE_GETRLIMIT
|
#undef HAVE_GETRLIMIT
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `gettid' function. */
|
||||||
|
#undef HAVE_GETTID
|
||||||
|
|
||||||
/* Define to 1 if you have the `glob' function. */
|
/* Define to 1 if you have the `glob' function. */
|
||||||
#undef HAVE_GLOB
|
#undef HAVE_GLOB
|
||||||
|
|
||||||
@ -457,6 +460,12 @@
|
|||||||
/* Define to 1 if you have the `OSSL_PARAM_BLD_new' function. */
|
/* Define to 1 if you have the `OSSL_PARAM_BLD_new' function. */
|
||||||
#undef HAVE_OSSL_PARAM_BLD_NEW
|
#undef HAVE_OSSL_PARAM_BLD_NEW
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `poll' function. */
|
||||||
|
#undef HAVE_POLL
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <poll.h> header file. */
|
||||||
|
#undef HAVE_POLL_H
|
||||||
|
|
||||||
/* Define if you have POSIX threads libraries and header files. */
|
/* Define if you have POSIX threads libraries and header files. */
|
||||||
#undef HAVE_PTHREAD
|
#undef HAVE_PTHREAD
|
||||||
|
|
||||||
@ -800,12 +809,18 @@
|
|||||||
/* Shared data */
|
/* Shared data */
|
||||||
#undef SHARE_DIR
|
#undef SHARE_DIR
|
||||||
|
|
||||||
|
/* The size of `pthread_t', as computed by sizeof. */
|
||||||
|
#undef SIZEOF_PTHREAD_T
|
||||||
|
|
||||||
/* The size of `size_t', as computed by sizeof. */
|
/* The size of `size_t', as computed by sizeof. */
|
||||||
#undef SIZEOF_SIZE_T
|
#undef SIZEOF_SIZE_T
|
||||||
|
|
||||||
/* The size of `time_t', as computed by sizeof. */
|
/* The size of `time_t', as computed by sizeof. */
|
||||||
#undef SIZEOF_TIME_T
|
#undef SIZEOF_TIME_T
|
||||||
|
|
||||||
|
/* The size of `unsigned long', as computed by sizeof. */
|
||||||
|
#undef SIZEOF_UNSIGNED_LONG
|
||||||
|
|
||||||
/* define if (v)snprintf does not return length needed, (but length used) */
|
/* define if (v)snprintf does not return length needed, (but length used) */
|
||||||
#undef SNPRINTF_RET_BROKEN
|
#undef SNPRINTF_RET_BROKEN
|
||||||
|
|
||||||
|
27
config.sub
vendored
27
config.sub
vendored
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
# shellcheck disable=SC2006,SC2268 # see below for rationale
|
# shellcheck disable=SC2006,SC2268 # see below for rationale
|
||||||
|
|
||||||
timestamp='2022-08-01'
|
timestamp='2022-09-17'
|
||||||
|
|
||||||
# This file is free software; you can redistribute it and/or modify it
|
# 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
|
# under the terms of the GNU General Public License as published by
|
||||||
@ -145,7 +145,7 @@ case $1 in
|
|||||||
nto-qnx* | linux-* | uclinux-uclibc* \
|
nto-qnx* | linux-* | uclinux-uclibc* \
|
||||||
| uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \
|
| uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \
|
||||||
| netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \
|
| netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \
|
||||||
| storm-chaos* | os2-emx* | rtmk-nova*)
|
| storm-chaos* | os2-emx* | rtmk-nova* | managarm-*)
|
||||||
basic_machine=$field1
|
basic_machine=$field1
|
||||||
basic_os=$maybe_os
|
basic_os=$maybe_os
|
||||||
;;
|
;;
|
||||||
@ -1341,6 +1341,10 @@ EOF
|
|||||||
kernel=linux
|
kernel=linux
|
||||||
os=`echo "$basic_os" | sed -e 's|linux|gnu|'`
|
os=`echo "$basic_os" | sed -e 's|linux|gnu|'`
|
||||||
;;
|
;;
|
||||||
|
managarm*)
|
||||||
|
kernel=managarm
|
||||||
|
os=`echo "$basic_os" | sed -e 's|managarm|mlibc|'`
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
kernel=
|
kernel=
|
||||||
os=$basic_os
|
os=$basic_os
|
||||||
@ -1754,7 +1758,7 @@ case $os in
|
|||||||
| onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \
|
| onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \
|
||||||
| midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \
|
| midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \
|
||||||
| nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \
|
| nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \
|
||||||
| fiwix* )
|
| fiwix* | mlibc* )
|
||||||
;;
|
;;
|
||||||
# This one is extra strict with allowed versions
|
# This one is extra strict with allowed versions
|
||||||
sco3.2v2 | sco3.2v[4-9]* | sco5v6*)
|
sco3.2v2 | sco3.2v[4-9]* | sco5v6*)
|
||||||
@ -1762,6 +1766,9 @@ case $os in
|
|||||||
;;
|
;;
|
||||||
none)
|
none)
|
||||||
;;
|
;;
|
||||||
|
kernel* )
|
||||||
|
# Restricted further below
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
echo Invalid configuration \`"$1"\': OS \`"$os"\' not recognized 1>&2
|
echo Invalid configuration \`"$1"\': OS \`"$os"\' not recognized 1>&2
|
||||||
exit 1
|
exit 1
|
||||||
@ -1772,16 +1779,26 @@ esac
|
|||||||
# (given a valid OS), if there is a kernel.
|
# (given a valid OS), if there is a kernel.
|
||||||
case $kernel-$os in
|
case $kernel-$os in
|
||||||
linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* \
|
linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* \
|
||||||
| linux-musl* | linux-relibc* | linux-uclibc* )
|
| linux-musl* | linux-relibc* | linux-uclibc* | linux-mlibc* )
|
||||||
;;
|
;;
|
||||||
uclinux-uclibc* )
|
uclinux-uclibc* )
|
||||||
;;
|
;;
|
||||||
-dietlibc* | -newlib* | -musl* | -relibc* | -uclibc* )
|
managarm-mlibc* | managarm-kernel* )
|
||||||
|
;;
|
||||||
|
-dietlibc* | -newlib* | -musl* | -relibc* | -uclibc* | -mlibc* )
|
||||||
# These are just libc implementations, not actual OSes, and thus
|
# These are just libc implementations, not actual OSes, and thus
|
||||||
# require a kernel.
|
# require a kernel.
|
||||||
echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2
|
echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2
|
||||||
exit 1
|
exit 1
|
||||||
;;
|
;;
|
||||||
|
-kernel* )
|
||||||
|
echo "Invalid configuration \`$1': \`$os' needs explicit kernel." 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
*-kernel* )
|
||||||
|
echo "Invalid configuration \`$1': \`$kernel' does not support \`$os'." 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
kfreebsd*-gnu* | kopensolaris*-gnu*)
|
kfreebsd*-gnu* | kopensolaris*-gnu*)
|
||||||
;;
|
;;
|
||||||
vxworks-simlinux | vxworks-simwindows | vxworks-spe)
|
vxworks-simlinux | vxworks-simwindows | vxworks-spe)
|
||||||
|
100
configure
vendored
100
configure
vendored
@ -1,6 +1,6 @@
|
|||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
# Guess values for system-dependent variables and create Makefiles.
|
# Guess values for system-dependent variables and create Makefiles.
|
||||||
# Generated by GNU Autoconf 2.69 for unbound 1.16.3.
|
# Generated by GNU Autoconf 2.69 for unbound 1.17.0.
|
||||||
#
|
#
|
||||||
# Report bugs to <unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues>.
|
# Report bugs to <unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues>.
|
||||||
#
|
#
|
||||||
@ -591,8 +591,8 @@ MAKEFLAGS=
|
|||||||
# Identity of this package.
|
# Identity of this package.
|
||||||
PACKAGE_NAME='unbound'
|
PACKAGE_NAME='unbound'
|
||||||
PACKAGE_TARNAME='unbound'
|
PACKAGE_TARNAME='unbound'
|
||||||
PACKAGE_VERSION='1.16.3'
|
PACKAGE_VERSION='1.17.0'
|
||||||
PACKAGE_STRING='unbound 1.16.3'
|
PACKAGE_STRING='unbound 1.17.0'
|
||||||
PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues'
|
PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues'
|
||||||
PACKAGE_URL=''
|
PACKAGE_URL=''
|
||||||
|
|
||||||
@ -1477,7 +1477,7 @@ if test "$ac_init_help" = "long"; then
|
|||||||
# Omit some internal or obsolete options to make the list less imposing.
|
# 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.
|
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||||
cat <<_ACEOF
|
cat <<_ACEOF
|
||||||
\`configure' configures unbound 1.16.3 to adapt to many kinds of systems.
|
\`configure' configures unbound 1.17.0 to adapt to many kinds of systems.
|
||||||
|
|
||||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||||
|
|
||||||
@ -1543,7 +1543,7 @@ fi
|
|||||||
|
|
||||||
if test -n "$ac_init_help"; then
|
if test -n "$ac_init_help"; then
|
||||||
case $ac_init_help in
|
case $ac_init_help in
|
||||||
short | recursive ) echo "Configuration of unbound 1.16.3:";;
|
short | recursive ) echo "Configuration of unbound 1.17.0:";;
|
||||||
esac
|
esac
|
||||||
cat <<\_ACEOF
|
cat <<\_ACEOF
|
||||||
|
|
||||||
@ -1785,7 +1785,7 @@ fi
|
|||||||
test -n "$ac_init_help" && exit $ac_status
|
test -n "$ac_init_help" && exit $ac_status
|
||||||
if $ac_init_version; then
|
if $ac_init_version; then
|
||||||
cat <<\_ACEOF
|
cat <<\_ACEOF
|
||||||
unbound configure 1.16.3
|
unbound configure 1.17.0
|
||||||
generated by GNU Autoconf 2.69
|
generated by GNU Autoconf 2.69
|
||||||
|
|
||||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||||
@ -2494,7 +2494,7 @@ cat >config.log <<_ACEOF
|
|||||||
This file contains any messages produced by compilers while
|
This file contains any messages produced by compilers while
|
||||||
running configure, to aid debugging if configure makes a mistake.
|
running configure, to aid debugging if configure makes a mistake.
|
||||||
|
|
||||||
It was created by unbound $as_me 1.16.3, which was
|
It was created by unbound $as_me 1.17.0, which was
|
||||||
generated by GNU Autoconf 2.69. Invocation command line was
|
generated by GNU Autoconf 2.69. Invocation command line was
|
||||||
|
|
||||||
$ $0 $@
|
$ $0 $@
|
||||||
@ -2844,13 +2844,13 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
|||||||
|
|
||||||
UNBOUND_VERSION_MAJOR=1
|
UNBOUND_VERSION_MAJOR=1
|
||||||
|
|
||||||
UNBOUND_VERSION_MINOR=16
|
UNBOUND_VERSION_MINOR=17
|
||||||
|
|
||||||
UNBOUND_VERSION_MICRO=3
|
UNBOUND_VERSION_MICRO=0
|
||||||
|
|
||||||
|
|
||||||
LIBUNBOUND_CURRENT=9
|
LIBUNBOUND_CURRENT=9
|
||||||
LIBUNBOUND_REVISION=19
|
LIBUNBOUND_REVISION=20
|
||||||
LIBUNBOUND_AGE=1
|
LIBUNBOUND_AGE=1
|
||||||
# 1.0.0 had 0:12:0
|
# 1.0.0 had 0:12:0
|
||||||
# 1.0.1 had 0:13:0
|
# 1.0.1 had 0:13:0
|
||||||
@ -2937,6 +2937,7 @@ LIBUNBOUND_AGE=1
|
|||||||
# 1.16.1 had 9:17:1
|
# 1.16.1 had 9:17:1
|
||||||
# 1.16.2 had 9:18:1
|
# 1.16.2 had 9:18:1
|
||||||
# 1.16.3 had 9:19:1
|
# 1.16.3 had 9:19:1
|
||||||
|
# 1.17.0 had 9:20:1
|
||||||
|
|
||||||
# Current -- the number of the binary API that we're implementing
|
# Current -- the number of the binary API that we're implementing
|
||||||
# Revision -- which iteration of the implementation of the binary
|
# Revision -- which iteration of the implementation of the binary
|
||||||
@ -14772,7 +14773,7 @@ fi
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Checks for header files.
|
# Checks for header files.
|
||||||
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
|
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 poll.h
|
||||||
do :
|
do :
|
||||||
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
|
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
|
ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
|
||||||
@ -16031,6 +16032,9 @@ else
|
|||||||
#ifdef HAVE_SYS_TYPES_H
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_SYS_SELECT_H
|
||||||
|
#include <sys/select.h>
|
||||||
|
#endif
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#endif
|
#endif
|
||||||
@ -17101,6 +17105,72 @@ _ACEOF
|
|||||||
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# The cast to long int works around a bug in the HP C Compiler
|
||||||
|
# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
|
||||||
|
# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
|
||||||
|
# This bug is HP SR number 8606223364.
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned long" >&5
|
||||||
|
$as_echo_n "checking size of unsigned long... " >&6; }
|
||||||
|
if ${ac_cv_sizeof_unsigned_long+:} false; then :
|
||||||
|
$as_echo_n "(cached) " >&6
|
||||||
|
else
|
||||||
|
if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned long))" "ac_cv_sizeof_unsigned_long" "$ac_includes_default"; then :
|
||||||
|
|
||||||
|
else
|
||||||
|
if test "$ac_cv_type_unsigned_long" = yes; then
|
||||||
|
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
|
||||||
|
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
|
||||||
|
as_fn_error 77 "cannot compute sizeof (unsigned long)
|
||||||
|
See \`config.log' for more details" "$LINENO" 5; }
|
||||||
|
else
|
||||||
|
ac_cv_sizeof_unsigned_long=0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_unsigned_long" >&5
|
||||||
|
$as_echo "$ac_cv_sizeof_unsigned_long" >&6; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
cat >>confdefs.h <<_ACEOF
|
||||||
|
#define SIZEOF_UNSIGNED_LONG $ac_cv_sizeof_unsigned_long
|
||||||
|
_ACEOF
|
||||||
|
|
||||||
|
|
||||||
|
# The cast to long int works around a bug in the HP C Compiler
|
||||||
|
# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
|
||||||
|
# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
|
||||||
|
# This bug is HP SR number 8606223364.
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of pthread_t" >&5
|
||||||
|
$as_echo_n "checking size of pthread_t... " >&6; }
|
||||||
|
if ${ac_cv_sizeof_pthread_t+:} false; then :
|
||||||
|
$as_echo_n "(cached) " >&6
|
||||||
|
else
|
||||||
|
if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (pthread_t))" "ac_cv_sizeof_pthread_t" "$ac_includes_default"; then :
|
||||||
|
|
||||||
|
else
|
||||||
|
if test "$ac_cv_type_pthread_t" = yes; then
|
||||||
|
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
|
||||||
|
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
|
||||||
|
as_fn_error 77 "cannot compute sizeof (pthread_t)
|
||||||
|
See \`config.log' for more details" "$LINENO" 5; }
|
||||||
|
else
|
||||||
|
ac_cv_sizeof_pthread_t=0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_pthread_t" >&5
|
||||||
|
$as_echo "$ac_cv_sizeof_pthread_t" >&6; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
cat >>confdefs.h <<_ACEOF
|
||||||
|
#define SIZEOF_PTHREAD_T $ac_cv_sizeof_pthread_t
|
||||||
|
_ACEOF
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if echo "$CFLAGS" | $GREP -e "-pthread" >/dev/null; then
|
if echo "$CFLAGS" | $GREP -e "-pthread" >/dev/null; then
|
||||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if -pthread unused during linking" >&5
|
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if -pthread unused during linking" >&5
|
||||||
@ -20591,7 +20661,7 @@ if test "$ac_res" != no; then :
|
|||||||
|
|
||||||
fi
|
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 getifaddrs if_nametoindex
|
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 if_nametoindex poll gettid
|
||||||
do :
|
do :
|
||||||
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||||
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
|
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
|
||||||
@ -22015,7 +22085,7 @@ _ACEOF
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
version=1.16.3
|
version=1.17.0
|
||||||
|
|
||||||
date=`date +'%b %e, %Y'`
|
date=`date +'%b %e, %Y'`
|
||||||
|
|
||||||
@ -22534,7 +22604,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
|||||||
# report actual input values of CONFIG_FILES etc. instead of their
|
# report actual input values of CONFIG_FILES etc. instead of their
|
||||||
# values after options handling.
|
# values after options handling.
|
||||||
ac_log="
|
ac_log="
|
||||||
This file was extended by unbound $as_me 1.16.3, which was
|
This file was extended by unbound $as_me 1.17.0, which was
|
||||||
generated by GNU Autoconf 2.69. Invocation command line was
|
generated by GNU Autoconf 2.69. Invocation command line was
|
||||||
|
|
||||||
CONFIG_FILES = $CONFIG_FILES
|
CONFIG_FILES = $CONFIG_FILES
|
||||||
@ -22600,7 +22670,7 @@ _ACEOF
|
|||||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||||
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
||||||
ac_cs_version="\\
|
ac_cs_version="\\
|
||||||
unbound config.status 1.16.3
|
unbound config.status 1.17.0
|
||||||
configured by $0, generated by GNU Autoconf 2.69,
|
configured by $0, generated by GNU Autoconf 2.69,
|
||||||
with options \\"\$ac_cs_config\\"
|
with options \\"\$ac_cs_config\\"
|
||||||
|
|
||||||
|
13
configure.ac
13
configure.ac
@ -10,15 +10,15 @@ sinclude(dnscrypt/dnscrypt.m4)
|
|||||||
|
|
||||||
# must be numbers. ac_defun because of later processing
|
# must be numbers. ac_defun because of later processing
|
||||||
m4_define([VERSION_MAJOR],[1])
|
m4_define([VERSION_MAJOR],[1])
|
||||||
m4_define([VERSION_MINOR],[16])
|
m4_define([VERSION_MINOR],[17])
|
||||||
m4_define([VERSION_MICRO],[3])
|
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_INIT([unbound],m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]),[unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues],[unbound])
|
||||||
AC_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR])
|
AC_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR])
|
||||||
AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR])
|
AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR])
|
||||||
AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO])
|
AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO])
|
||||||
|
|
||||||
LIBUNBOUND_CURRENT=9
|
LIBUNBOUND_CURRENT=9
|
||||||
LIBUNBOUND_REVISION=19
|
LIBUNBOUND_REVISION=20
|
||||||
LIBUNBOUND_AGE=1
|
LIBUNBOUND_AGE=1
|
||||||
# 1.0.0 had 0:12:0
|
# 1.0.0 had 0:12:0
|
||||||
# 1.0.1 had 0:13:0
|
# 1.0.1 had 0:13:0
|
||||||
@ -105,6 +105,7 @@ LIBUNBOUND_AGE=1
|
|||||||
# 1.16.1 had 9:17:1
|
# 1.16.1 had 9:17:1
|
||||||
# 1.16.2 had 9:18:1
|
# 1.16.2 had 9:18:1
|
||||||
# 1.16.3 had 9:19:1
|
# 1.16.3 had 9:19:1
|
||||||
|
# 1.17.0 had 9:20:1
|
||||||
|
|
||||||
# Current -- the number of the binary API that we're implementing
|
# Current -- the number of the binary API that we're implementing
|
||||||
# Revision -- which iteration of the implementation of the binary
|
# Revision -- which iteration of the implementation of the binary
|
||||||
@ -397,7 +398,7 @@ PKG_PROG_PKG_CONFIG
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# Checks for header files.
|
# Checks for header files.
|
||||||
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],,, [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 poll.h],,, [AC_INCLUDES_DEFAULT])
|
||||||
# net/if.h portability for Darwin see:
|
# net/if.h portability for Darwin see:
|
||||||
# https://www.gnu.org/software/autoconf/manual/autoconf-2.69/html_node/Header-Portability.html
|
# https://www.gnu.org/software/autoconf/manual/autoconf-2.69/html_node/Header-Portability.html
|
||||||
AC_CHECK_HEADERS([net/if.h],,, [
|
AC_CHECK_HEADERS([net/if.h],,, [
|
||||||
@ -607,6 +608,8 @@ if test x_$withval != x_no; then
|
|||||||
CC="$PTHREAD_CC"
|
CC="$PTHREAD_CC"
|
||||||
ub_have_pthreads=yes
|
ub_have_pthreads=yes
|
||||||
AC_CHECK_TYPES([pthread_spinlock_t, pthread_rwlock_t],,,[#include <pthread.h>])
|
AC_CHECK_TYPES([pthread_spinlock_t, pthread_rwlock_t],,,[#include <pthread.h>])
|
||||||
|
AC_CHECK_SIZEOF([unsigned long])
|
||||||
|
AC_CHECK_SIZEOF(pthread_t)
|
||||||
|
|
||||||
if echo "$CFLAGS" | $GREP -e "-pthread" >/dev/null; then
|
if echo "$CFLAGS" | $GREP -e "-pthread" >/dev/null; then
|
||||||
AC_MSG_CHECKING([if -pthread unused during linking])
|
AC_MSG_CHECKING([if -pthread unused during linking])
|
||||||
@ -1644,7 +1647,7 @@ AC_LINK_IFELSE([AC_LANG_PROGRAM([
|
|||||||
AC_MSG_RESULT(no))
|
AC_MSG_RESULT(no))
|
||||||
|
|
||||||
AC_SEARCH_LIBS([setusercontext], [util])
|
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 getifaddrs if_nametoindex])
|
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 if_nametoindex poll gettid])
|
||||||
AC_CHECK_FUNCS([setresuid],,[AC_CHECK_FUNCS([setreuid])])
|
AC_CHECK_FUNCS([setresuid],,[AC_CHECK_FUNCS([setreuid])])
|
||||||
AC_CHECK_FUNCS([setresgid],,[AC_CHECK_FUNCS([setregid])])
|
AC_CHECK_FUNCS([setresgid],,[AC_CHECK_FUNCS([setregid])])
|
||||||
|
|
||||||
|
@ -46,6 +46,7 @@
|
|||||||
#include "util/config_file.h"
|
#include "util/config_file.h"
|
||||||
#include "util/net_help.h"
|
#include "util/net_help.h"
|
||||||
#include "services/localzone.h"
|
#include "services/localzone.h"
|
||||||
|
#include "services/listen_dnsport.h"
|
||||||
#include "sldns/str2wire.h"
|
#include "sldns/str2wire.h"
|
||||||
|
|
||||||
struct acl_list*
|
struct acl_list*
|
||||||
@ -90,6 +91,31 @@ acl_list_insert(struct acl_list* acl, struct sockaddr_storage* addr,
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** parse str to acl_access enum */
|
||||||
|
static int
|
||||||
|
parse_acl_access(const char* str, enum acl_access* control)
|
||||||
|
{
|
||||||
|
if(strcmp(str, "allow") == 0)
|
||||||
|
*control = acl_allow;
|
||||||
|
else if(strcmp(str, "deny") == 0)
|
||||||
|
*control = acl_deny;
|
||||||
|
else if(strcmp(str, "refuse") == 0)
|
||||||
|
*control = acl_refuse;
|
||||||
|
else if(strcmp(str, "deny_non_local") == 0)
|
||||||
|
*control = acl_deny_non_local;
|
||||||
|
else if(strcmp(str, "refuse_non_local") == 0)
|
||||||
|
*control = acl_refuse_non_local;
|
||||||
|
else if(strcmp(str, "allow_snoop") == 0)
|
||||||
|
*control = acl_allow_snoop;
|
||||||
|
else if(strcmp(str, "allow_setrd") == 0)
|
||||||
|
*control = acl_allow_setrd;
|
||||||
|
else {
|
||||||
|
log_err("access control type %s unknown", str);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/** apply acl_list string */
|
/** apply acl_list string */
|
||||||
static int
|
static int
|
||||||
acl_list_str_cfg(struct acl_list* acl, const char* str, const char* s2,
|
acl_list_str_cfg(struct acl_list* acl, const char* str, const char* s2,
|
||||||
@ -99,22 +125,7 @@ acl_list_str_cfg(struct acl_list* acl, const char* str, const char* s2,
|
|||||||
int net;
|
int net;
|
||||||
socklen_t addrlen;
|
socklen_t addrlen;
|
||||||
enum acl_access control;
|
enum acl_access control;
|
||||||
if(strcmp(s2, "allow") == 0)
|
if(!parse_acl_access(s2, &control)) {
|
||||||
control = acl_allow;
|
|
||||||
else if(strcmp(s2, "deny") == 0)
|
|
||||||
control = acl_deny;
|
|
||||||
else if(strcmp(s2, "refuse") == 0)
|
|
||||||
control = acl_refuse;
|
|
||||||
else if(strcmp(s2, "deny_non_local") == 0)
|
|
||||||
control = acl_deny_non_local;
|
|
||||||
else if(strcmp(s2, "refuse_non_local") == 0)
|
|
||||||
control = acl_refuse_non_local;
|
|
||||||
else if(strcmp(s2, "allow_snoop") == 0)
|
|
||||||
control = acl_allow_snoop;
|
|
||||||
else if(strcmp(s2, "allow_setrd") == 0)
|
|
||||||
control = acl_allow_setrd;
|
|
||||||
else {
|
|
||||||
log_err("access control type %s unknown", str);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(!netblockstrtoaddr(str, UNBOUND_DNS_PORT, &addr, &addrlen, &net)) {
|
if(!netblockstrtoaddr(str, UNBOUND_DNS_PORT, &addr, &addrlen, &net)) {
|
||||||
@ -131,19 +142,27 @@ acl_list_str_cfg(struct acl_list* acl, const char* str, const char* s2,
|
|||||||
|
|
||||||
/** find or create node (NULL on parse or error) */
|
/** find or create node (NULL on parse or error) */
|
||||||
static struct acl_addr*
|
static struct acl_addr*
|
||||||
acl_find_or_create(struct acl_list* acl, const char* str)
|
acl_find_or_create_str2addr(struct acl_list* acl, const char* str,
|
||||||
|
int is_interface, int port)
|
||||||
{
|
{
|
||||||
struct acl_addr* node;
|
struct acl_addr* node;
|
||||||
struct sockaddr_storage addr;
|
struct sockaddr_storage addr;
|
||||||
int net;
|
|
||||||
socklen_t addrlen;
|
socklen_t addrlen;
|
||||||
|
int net = (str_is_ip6(str)?128:32);
|
||||||
|
if(is_interface) {
|
||||||
|
if(!extstrtoaddr(str, &addr, &addrlen, port)) {
|
||||||
|
log_err("cannot parse interface: %s", str);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
if(!netblockstrtoaddr(str, UNBOUND_DNS_PORT, &addr, &addrlen, &net)) {
|
if(!netblockstrtoaddr(str, UNBOUND_DNS_PORT, &addr, &addrlen, &net)) {
|
||||||
log_err("cannot parse netblock: %s", str);
|
log_err("cannot parse netblock: %s", str);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/* find or create node */
|
/* find or create node */
|
||||||
if(!(node=(struct acl_addr*)addr_tree_find(&acl->tree, &addr,
|
if(!(node=(struct acl_addr*)addr_tree_find(&acl->tree, &addr,
|
||||||
addrlen, net))) {
|
addrlen, net)) && !is_interface) {
|
||||||
/* create node, type 'allow' since otherwise tags are
|
/* create node, type 'allow' since otherwise tags are
|
||||||
* pointless, can override with specific access-control: cfg */
|
* pointless, can override with specific access-control: cfg */
|
||||||
if(!(node=(struct acl_addr*)acl_list_insert(acl, &addr,
|
if(!(node=(struct acl_addr*)acl_list_insert(acl, &addr,
|
||||||
@ -155,14 +174,65 @@ acl_find_or_create(struct acl_list* acl, const char* str)
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** find or create node (NULL on error) */
|
||||||
|
static struct acl_addr*
|
||||||
|
acl_find_or_create(struct acl_list* acl, struct sockaddr_storage* addr,
|
||||||
|
socklen_t addrlen, enum acl_access control)
|
||||||
|
{
|
||||||
|
struct acl_addr* node;
|
||||||
|
int net = (addr_is_ip6(addr, addrlen)?128:32);
|
||||||
|
/* find or create node */
|
||||||
|
if(!(node=(struct acl_addr*)addr_tree_find(&acl->tree, addr,
|
||||||
|
addrlen, net))) {
|
||||||
|
/* create node;
|
||||||
|
* can override with specific access-control: cfg */
|
||||||
|
if(!(node=(struct acl_addr*)acl_list_insert(acl, addr,
|
||||||
|
addrlen, net, control, 1))) {
|
||||||
|
log_err("out of memory");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** apply acl_interface string */
|
||||||
|
static int
|
||||||
|
acl_interface_str_cfg(struct acl_list* acl_interface, const char* iface,
|
||||||
|
const char* s2, int port)
|
||||||
|
{
|
||||||
|
struct acl_addr* node;
|
||||||
|
enum acl_access control;
|
||||||
|
if(!parse_acl_access(s2, &control)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(!(node=acl_find_or_create_str2addr(acl_interface, iface, 1, port))) {
|
||||||
|
log_err("cannot update ACL on non-configured interface: %s %d",
|
||||||
|
iface, port);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
node->control = control;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct acl_addr*
|
||||||
|
acl_interface_insert(struct acl_list* acl_interface,
|
||||||
|
struct sockaddr_storage* addr, socklen_t addrlen,
|
||||||
|
enum acl_access control)
|
||||||
|
{
|
||||||
|
return acl_find_or_create(acl_interface, addr, addrlen, control);
|
||||||
|
}
|
||||||
|
|
||||||
/** apply acl_tag string */
|
/** apply acl_tag string */
|
||||||
static int
|
static int
|
||||||
acl_list_tags_cfg(struct acl_list* acl, const char* str, uint8_t* bitmap,
|
acl_list_tags_cfg(struct acl_list* acl, const char* str, uint8_t* bitmap,
|
||||||
size_t bitmaplen)
|
size_t bitmaplen, int is_interface, int port)
|
||||||
{
|
{
|
||||||
struct acl_addr* node;
|
struct acl_addr* node;
|
||||||
if(!(node=acl_find_or_create(acl, str)))
|
if(!(node=acl_find_or_create_str2addr(acl, str, is_interface, port))) {
|
||||||
|
if(is_interface)
|
||||||
|
log_err("non-configured interface: %s", str);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
node->taglen = bitmaplen;
|
node->taglen = bitmaplen;
|
||||||
node->taglist = regional_alloc_init(acl->region, bitmap, bitmaplen);
|
node->taglist = regional_alloc_init(acl->region, bitmap, bitmaplen);
|
||||||
if(!node->taglist) {
|
if(!node->taglist) {
|
||||||
@ -175,11 +245,14 @@ acl_list_tags_cfg(struct acl_list* acl, const char* str, uint8_t* bitmap,
|
|||||||
/** apply acl_view string */
|
/** apply acl_view string */
|
||||||
static int
|
static int
|
||||||
acl_list_view_cfg(struct acl_list* acl, const char* str, const char* str2,
|
acl_list_view_cfg(struct acl_list* acl, const char* str, const char* str2,
|
||||||
struct views* vs)
|
struct views* vs, int is_interface, int port)
|
||||||
{
|
{
|
||||||
struct acl_addr* node;
|
struct acl_addr* node;
|
||||||
if(!(node=acl_find_or_create(acl, str)))
|
if(!(node=acl_find_or_create_str2addr(acl, str, is_interface, port))) {
|
||||||
|
if(is_interface)
|
||||||
|
log_err("non-configured interface: %s", str);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
node->view = views_find_view(vs, str2, 0 /* get read lock*/);
|
node->view = views_find_view(vs, str2, 0 /* get read lock*/);
|
||||||
if(!node->view) {
|
if(!node->view) {
|
||||||
log_err("no view with name: %s", str2);
|
log_err("no view with name: %s", str2);
|
||||||
@ -192,13 +265,17 @@ acl_list_view_cfg(struct acl_list* acl, const char* str, const char* str2,
|
|||||||
/** apply acl_tag_action string */
|
/** apply acl_tag_action string */
|
||||||
static int
|
static int
|
||||||
acl_list_tag_action_cfg(struct acl_list* acl, struct config_file* cfg,
|
acl_list_tag_action_cfg(struct acl_list* acl, struct config_file* cfg,
|
||||||
const char* str, const char* tag, const char* action)
|
const char* str, const char* tag, const char* action,
|
||||||
|
int is_interface, int port)
|
||||||
{
|
{
|
||||||
struct acl_addr* node;
|
struct acl_addr* node;
|
||||||
int tagid;
|
int tagid;
|
||||||
enum localzone_type t;
|
enum localzone_type t;
|
||||||
if(!(node=acl_find_or_create(acl, str)))
|
if(!(node=acl_find_or_create_str2addr(acl, str, is_interface, port))) {
|
||||||
|
if(is_interface)
|
||||||
|
log_err("non-configured interface: %s", str);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
/* allocate array if not yet */
|
/* allocate array if not yet */
|
||||||
if(!node->tag_actions) {
|
if(!node->tag_actions) {
|
||||||
node->tag_actions = (uint8_t*)regional_alloc_zero(acl->region,
|
node->tag_actions = (uint8_t*)regional_alloc_zero(acl->region,
|
||||||
@ -281,13 +358,17 @@ check_data(const char* data, const struct config_strlist* head)
|
|||||||
/** apply acl_tag_data string */
|
/** apply acl_tag_data string */
|
||||||
static int
|
static int
|
||||||
acl_list_tag_data_cfg(struct acl_list* acl, struct config_file* cfg,
|
acl_list_tag_data_cfg(struct acl_list* acl, struct config_file* cfg,
|
||||||
const char* str, const char* tag, const char* data)
|
const char* str, const char* tag, const char* data,
|
||||||
|
int is_interface, int port)
|
||||||
{
|
{
|
||||||
struct acl_addr* node;
|
struct acl_addr* node;
|
||||||
int tagid;
|
int tagid;
|
||||||
char* dupdata;
|
char* dupdata;
|
||||||
if(!(node=acl_find_or_create(acl, str)))
|
if(!(node=acl_find_or_create_str2addr(acl, str, is_interface, port))) {
|
||||||
|
if(is_interface)
|
||||||
|
log_err("non-configured interface: %s", str);
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
/* allocate array if not yet */
|
/* allocate array if not yet */
|
||||||
if(!node->tag_datas) {
|
if(!node->tag_datas) {
|
||||||
node->tag_datas = (struct config_strlist**)regional_alloc_zero(
|
node->tag_datas = (struct config_strlist**)regional_alloc_zero(
|
||||||
@ -330,10 +411,10 @@ acl_list_tag_data_cfg(struct acl_list* acl, struct config_file* cfg,
|
|||||||
|
|
||||||
/** read acl_list config */
|
/** read acl_list config */
|
||||||
static int
|
static int
|
||||||
read_acl_list(struct acl_list* acl, struct config_file* cfg)
|
read_acl_list(struct acl_list* acl, struct config_str2list* acls)
|
||||||
{
|
{
|
||||||
struct config_str2list* p;
|
struct config_str2list* p;
|
||||||
for(p = cfg->acls; p; p = p->next) {
|
for(p = acls; p; p = p->next) {
|
||||||
log_assert(p->str && p->str2);
|
log_assert(p->str && p->str2);
|
||||||
if(!acl_list_str_cfg(acl, p->str, p->str2, 1))
|
if(!acl_list_str_cfg(acl, p->str, p->str2, 1))
|
||||||
return 0;
|
return 0;
|
||||||
@ -341,16 +422,17 @@ read_acl_list(struct acl_list* acl, struct config_file* cfg)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** read acl tags config */
|
/** read acl view config */
|
||||||
static int
|
static int
|
||||||
read_acl_tags(struct acl_list* acl, struct config_file* cfg)
|
read_acl_view(struct acl_list* acl, struct config_str2list** acl_view,
|
||||||
|
struct views* v)
|
||||||
{
|
{
|
||||||
struct config_strbytelist* np, *p = cfg->acl_tags;
|
struct config_str2list* np, *p = *acl_view;
|
||||||
cfg->acl_tags = NULL;
|
*acl_view = NULL;
|
||||||
while(p) {
|
while(p) {
|
||||||
log_assert(p->str && p->str2);
|
log_assert(p->str && p->str2);
|
||||||
if(!acl_list_tags_cfg(acl, p->str, p->str2, p->str2len)) {
|
if(!acl_list_view_cfg(acl, p->str, p->str2, v, 0, 0)) {
|
||||||
config_del_strbytelist(p);
|
config_deldblstrlist(p);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* free the items as we go to free up memory */
|
/* free the items as we go to free up memory */
|
||||||
@ -363,15 +445,16 @@ read_acl_tags(struct acl_list* acl, struct config_file* cfg)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** read acl view config */
|
/** read acl tags config */
|
||||||
static int
|
static int
|
||||||
read_acl_view(struct acl_list* acl, struct config_file* cfg, struct views* v)
|
read_acl_tags(struct acl_list* acl, struct config_strbytelist** acl_tags)
|
||||||
{
|
{
|
||||||
struct config_str2list* np, *p = cfg->acl_view;
|
struct config_strbytelist* np, *p = *acl_tags;
|
||||||
cfg->acl_view = NULL;
|
*acl_tags = NULL;
|
||||||
while(p) {
|
while(p) {
|
||||||
log_assert(p->str && p->str2);
|
log_assert(p->str && p->str2);
|
||||||
if(!acl_list_view_cfg(acl, p->str, p->str2, v)) {
|
if(!acl_list_tags_cfg(acl, p->str, p->str2, p->str2len, 0, 0)) {
|
||||||
|
config_del_strbytelist(p);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* free the items as we go to free up memory */
|
/* free the items as we go to free up memory */
|
||||||
@ -386,15 +469,16 @@ read_acl_view(struct acl_list* acl, struct config_file* cfg, struct views* v)
|
|||||||
|
|
||||||
/** read acl tag actions config */
|
/** read acl tag actions config */
|
||||||
static int
|
static int
|
||||||
read_acl_tag_actions(struct acl_list* acl, struct config_file* cfg)
|
read_acl_tag_actions(struct acl_list* acl, struct config_file* cfg,
|
||||||
|
struct config_str3list** acl_tag_actions)
|
||||||
{
|
{
|
||||||
struct config_str3list* p, *np;
|
struct config_str3list* p, *np;
|
||||||
p = cfg->acl_tag_actions;
|
p = *acl_tag_actions;
|
||||||
cfg->acl_tag_actions = NULL;
|
*acl_tag_actions = NULL;
|
||||||
while(p) {
|
while(p) {
|
||||||
log_assert(p->str && p->str2 && p->str3);
|
log_assert(p->str && p->str2 && p->str3);
|
||||||
if(!acl_list_tag_action_cfg(acl, cfg, p->str, p->str2,
|
if(!acl_list_tag_action_cfg(acl, cfg, p->str, p->str2,
|
||||||
p->str3)) {
|
p->str3, 0, 0)) {
|
||||||
config_deltrplstrlist(p);
|
config_deltrplstrlist(p);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -411,14 +495,16 @@ read_acl_tag_actions(struct acl_list* acl, struct config_file* cfg)
|
|||||||
|
|
||||||
/** read acl tag datas config */
|
/** read acl tag datas config */
|
||||||
static int
|
static int
|
||||||
read_acl_tag_datas(struct acl_list* acl, struct config_file* cfg)
|
read_acl_tag_datas(struct acl_list* acl, struct config_file* cfg,
|
||||||
|
struct config_str3list** acl_tag_datas)
|
||||||
{
|
{
|
||||||
struct config_str3list* p, *np;
|
struct config_str3list* p, *np;
|
||||||
p = cfg->acl_tag_datas;
|
p = *acl_tag_datas;
|
||||||
cfg->acl_tag_datas = NULL;
|
*acl_tag_datas = NULL;
|
||||||
while(p) {
|
while(p) {
|
||||||
log_assert(p->str && p->str2 && p->str3);
|
log_assert(p->str && p->str2 && p->str3);
|
||||||
if(!acl_list_tag_data_cfg(acl, cfg, p->str, p->str2, p->str3)) {
|
if(!acl_list_tag_data_cfg(acl, cfg, p->str, p->str2, p->str3,
|
||||||
|
0, 0)) {
|
||||||
config_deltrplstrlist(p);
|
config_deltrplstrlist(p);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -439,24 +525,21 @@ acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg,
|
|||||||
{
|
{
|
||||||
regional_free_all(acl->region);
|
regional_free_all(acl->region);
|
||||||
addr_tree_init(&acl->tree);
|
addr_tree_init(&acl->tree);
|
||||||
if(!read_acl_list(acl, cfg))
|
if(!read_acl_list(acl, cfg->acls))
|
||||||
return 0;
|
return 0;
|
||||||
if(!read_acl_view(acl, cfg, v))
|
if(!read_acl_view(acl, &cfg->acl_view, v))
|
||||||
return 0;
|
return 0;
|
||||||
if(!read_acl_tags(acl, cfg))
|
if(!read_acl_tags(acl, &cfg->acl_tags))
|
||||||
return 0;
|
return 0;
|
||||||
if(!read_acl_tag_actions(acl, cfg))
|
if(!read_acl_tag_actions(acl, cfg, &cfg->acl_tag_actions))
|
||||||
return 0;
|
return 0;
|
||||||
if(!read_acl_tag_datas(acl, cfg))
|
if(!read_acl_tag_datas(acl, cfg, &cfg->acl_tag_datas))
|
||||||
return 0;
|
return 0;
|
||||||
/* insert defaults, with '0' to ignore them if they are duplicates */
|
/* insert defaults, with '0' to ignore them if they are duplicates */
|
||||||
if(!acl_list_str_cfg(acl, "0.0.0.0/0", "refuse", 0))
|
/* the 'refuse' defaults for /0 are now done per interface instead */
|
||||||
return 0;
|
|
||||||
if(!acl_list_str_cfg(acl, "127.0.0.0/8", "allow", 0))
|
if(!acl_list_str_cfg(acl, "127.0.0.0/8", "allow", 0))
|
||||||
return 0;
|
return 0;
|
||||||
if(cfg->do_ip6) {
|
if(cfg->do_ip6) {
|
||||||
if(!acl_list_str_cfg(acl, "::0/0", "refuse", 0))
|
|
||||||
return 0;
|
|
||||||
if(!acl_list_str_cfg(acl, "::1", "allow", 0))
|
if(!acl_list_str_cfg(acl, "::1", "allow", 0))
|
||||||
return 0;
|
return 0;
|
||||||
if(!acl_list_str_cfg(acl, "::ffff:127.0.0.1", "allow", 0))
|
if(!acl_list_str_cfg(acl, "::ffff:127.0.0.1", "allow", 0))
|
||||||
@ -466,6 +549,222 @@ acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
acl_interface_compare(const void* k1, const void* k2)
|
||||||
|
{
|
||||||
|
struct addr_tree_node* n1 = (struct addr_tree_node*)k1;
|
||||||
|
struct addr_tree_node* n2 = (struct addr_tree_node*)k2;
|
||||||
|
return sockaddr_cmp(&n1->addr, n1->addrlen, &n2->addr,
|
||||||
|
n2->addrlen);
|
||||||
|
/* We don't care about comparing node->net. All addresses in the
|
||||||
|
* acl_interface tree have either 32 (ipv4) or 128 (ipv6). */
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
acl_interface_init(struct acl_list* acl_interface)
|
||||||
|
{
|
||||||
|
regional_free_all(acl_interface->region);
|
||||||
|
/* We want comparison in the tree to include only address and port.
|
||||||
|
* We don't care about comparing node->net. All addresses in the
|
||||||
|
* acl_interface->tree should have either 32 (ipv4) or 128 (ipv6).
|
||||||
|
* Initialise with the appropriate compare function but keep treating
|
||||||
|
* it as an addr_tree. */
|
||||||
|
addr_tree_addrport_init(&acl_interface->tree);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
read_acl_interface_action(struct acl_list* acl_interface,
|
||||||
|
struct config_str2list* acls, int port)
|
||||||
|
{
|
||||||
|
struct config_str2list* p;
|
||||||
|
for(p = acls; p; p = p->next) {
|
||||||
|
char** resif = NULL;
|
||||||
|
int num_resif = 0;
|
||||||
|
int i;
|
||||||
|
log_assert(p->str && p->str2);
|
||||||
|
if(!resolve_interface_names(&p->str, 1, NULL, &resif, &num_resif))
|
||||||
|
return 0;
|
||||||
|
for(i = 0; i<num_resif; i++) {
|
||||||
|
if(!acl_interface_str_cfg(acl_interface, resif[i], p->str2, port)){
|
||||||
|
config_del_strarray(resif, num_resif);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
config_del_strarray(resif, num_resif);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** read acl view config for interface */
|
||||||
|
static int
|
||||||
|
read_acl_interface_view(struct acl_list* acl_interface,
|
||||||
|
struct config_str2list** acl_view,
|
||||||
|
struct views* v, int port)
|
||||||
|
{
|
||||||
|
struct config_str2list* np, *p = *acl_view;
|
||||||
|
*acl_view = NULL;
|
||||||
|
while(p) {
|
||||||
|
char** resif = NULL;
|
||||||
|
int num_resif = 0;
|
||||||
|
int i;
|
||||||
|
log_assert(p->str && p->str2);
|
||||||
|
if(!resolve_interface_names(&p->str, 1, NULL, &resif, &num_resif)) {
|
||||||
|
config_deldblstrlist(p);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
for(i = 0; i<num_resif; i++) {
|
||||||
|
if(!acl_list_view_cfg(acl_interface, resif[i], p->str2,
|
||||||
|
v, 1, port)) {
|
||||||
|
config_del_strarray(resif, num_resif);
|
||||||
|
config_deldblstrlist(p);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
config_del_strarray(resif, num_resif);
|
||||||
|
/* free the items as we go to free up memory */
|
||||||
|
np = p->next;
|
||||||
|
free(p->str);
|
||||||
|
free(p->str2);
|
||||||
|
free(p);
|
||||||
|
p = np;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** read acl tags config for interface */
|
||||||
|
static int
|
||||||
|
read_acl_interface_tags(struct acl_list* acl_interface,
|
||||||
|
struct config_strbytelist** acl_tags, int port)
|
||||||
|
{
|
||||||
|
struct config_strbytelist* np, *p = *acl_tags;
|
||||||
|
*acl_tags = NULL;
|
||||||
|
while(p) {
|
||||||
|
char** resif = NULL;
|
||||||
|
int num_resif = 0;
|
||||||
|
int i;
|
||||||
|
log_assert(p->str && p->str2);
|
||||||
|
if(!resolve_interface_names(&p->str, 1, NULL, &resif, &num_resif)) {
|
||||||
|
config_del_strbytelist(p);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
for(i = 0; i<num_resif; i++) {
|
||||||
|
if(!acl_list_tags_cfg(acl_interface, resif[i], p->str2,
|
||||||
|
p->str2len, 1, port)) {
|
||||||
|
config_del_strbytelist(p);
|
||||||
|
config_del_strarray(resif, num_resif);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
config_del_strarray(resif, num_resif);
|
||||||
|
/* free the items as we go to free up memory */
|
||||||
|
np = p->next;
|
||||||
|
free(p->str);
|
||||||
|
free(p->str2);
|
||||||
|
free(p);
|
||||||
|
p = np;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** read acl tag actions config for interface*/
|
||||||
|
static int
|
||||||
|
read_acl_interface_tag_actions(struct acl_list* acl_interface,
|
||||||
|
struct config_file* cfg,
|
||||||
|
struct config_str3list** acl_tag_actions, int port)
|
||||||
|
{
|
||||||
|
struct config_str3list* p, *np;
|
||||||
|
p = *acl_tag_actions;
|
||||||
|
*acl_tag_actions = NULL;
|
||||||
|
while(p) {
|
||||||
|
char** resif = NULL;
|
||||||
|
int num_resif = 0;
|
||||||
|
int i;
|
||||||
|
log_assert(p->str && p->str2 && p->str3);
|
||||||
|
if(!resolve_interface_names(&p->str, 1, NULL, &resif, &num_resif)) {
|
||||||
|
config_deltrplstrlist(p);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
for(i = 0; i<num_resif; i++) {
|
||||||
|
if(!acl_list_tag_action_cfg(acl_interface, cfg,
|
||||||
|
resif[i], p->str2, p->str3, 1, port)) {
|
||||||
|
config_deltrplstrlist(p);
|
||||||
|
config_del_strarray(resif, num_resif);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
config_del_strarray(resif, num_resif);
|
||||||
|
/* free the items as we go to free up memory */
|
||||||
|
np = p->next;
|
||||||
|
free(p->str);
|
||||||
|
free(p->str2);
|
||||||
|
free(p->str3);
|
||||||
|
free(p);
|
||||||
|
p = np;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** read acl tag datas config for interface */
|
||||||
|
static int
|
||||||
|
read_acl_interface_tag_datas(struct acl_list* acl_interface,
|
||||||
|
struct config_file* cfg,
|
||||||
|
struct config_str3list** acl_tag_datas, int port)
|
||||||
|
{
|
||||||
|
struct config_str3list* p, *np;
|
||||||
|
p = *acl_tag_datas;
|
||||||
|
*acl_tag_datas = NULL;
|
||||||
|
while(p) {
|
||||||
|
char** resif = NULL;
|
||||||
|
int num_resif = 0;
|
||||||
|
int i;
|
||||||
|
log_assert(p->str && p->str2 && p->str3);
|
||||||
|
if(!resolve_interface_names(&p->str, 1, NULL, &resif, &num_resif)) {
|
||||||
|
config_deltrplstrlist(p);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
for(i = 0; i<num_resif; i++) {
|
||||||
|
if(!acl_list_tag_data_cfg(acl_interface, cfg,
|
||||||
|
resif[i], p->str2, p->str3, 1, port)) {
|
||||||
|
config_deltrplstrlist(p);
|
||||||
|
config_del_strarray(resif, num_resif);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
config_del_strarray(resif, num_resif);
|
||||||
|
/* free the items as we go to free up memory */
|
||||||
|
np = p->next;
|
||||||
|
free(p->str);
|
||||||
|
free(p->str2);
|
||||||
|
free(p->str3);
|
||||||
|
free(p);
|
||||||
|
p = np;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
acl_interface_apply_cfg(struct acl_list* acl_interface, struct config_file* cfg,
|
||||||
|
struct views* v)
|
||||||
|
{
|
||||||
|
if(!read_acl_interface_action(acl_interface, cfg->interface_actions,
|
||||||
|
cfg->port))
|
||||||
|
return 0;
|
||||||
|
if(!read_acl_interface_view(acl_interface, &cfg->interface_view, v,
|
||||||
|
cfg->port))
|
||||||
|
return 0;
|
||||||
|
if(!read_acl_interface_tags(acl_interface, &cfg->interface_tags,
|
||||||
|
cfg->port))
|
||||||
|
return 0;
|
||||||
|
if(!read_acl_interface_tag_actions(acl_interface, cfg,
|
||||||
|
&cfg->interface_tag_actions, cfg->port))
|
||||||
|
return 0;
|
||||||
|
if(!read_acl_interface_tag_datas(acl_interface, cfg,
|
||||||
|
&cfg->interface_tag_datas, cfg->port))
|
||||||
|
return 0;
|
||||||
|
addr_tree_init_parents(&acl_interface->tree);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
enum acl_access
|
enum acl_access
|
||||||
acl_get_control(struct acl_addr* acl)
|
acl_get_control(struct acl_addr* acl)
|
||||||
{
|
{
|
||||||
|
@ -119,6 +119,20 @@ struct acl_list* acl_list_create(void);
|
|||||||
*/
|
*/
|
||||||
void acl_list_delete(struct acl_list* acl);
|
void acl_list_delete(struct acl_list* acl);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert interface in the acl_list. This should happen when the listening
|
||||||
|
* interface is setup.
|
||||||
|
* @param acl_interface: acl_list to insert to.
|
||||||
|
* @param addr: interface IP.
|
||||||
|
* @param addrlen: length of the interface IP.
|
||||||
|
* @param control: acl_access.
|
||||||
|
* @return new structure or NULL on error.
|
||||||
|
*/
|
||||||
|
struct acl_addr*
|
||||||
|
acl_interface_insert(struct acl_list* acl_interface,
|
||||||
|
struct sockaddr_storage* addr, socklen_t addrlen,
|
||||||
|
enum acl_access control);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process access control config.
|
* Process access control config.
|
||||||
* @param acl: where to store.
|
* @param acl: where to store.
|
||||||
@ -129,6 +143,25 @@ void acl_list_delete(struct acl_list* acl);
|
|||||||
int acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg,
|
int acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg,
|
||||||
struct views* v);
|
struct views* v);
|
||||||
|
|
||||||
|
/** compare ACL interface "addr_tree" nodes (+port) */
|
||||||
|
int acl_interface_compare(const void* k1, const void* k2);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialise (also clean) the acl_interface struct.
|
||||||
|
* @param acl_interface: where to store.
|
||||||
|
*/
|
||||||
|
void acl_interface_init(struct acl_list* acl_interface);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process interface control config.
|
||||||
|
* @param acl_interface: where to store.
|
||||||
|
* @param cfg: config options.
|
||||||
|
* @param v: views structure
|
||||||
|
* @return 0 on error.
|
||||||
|
*/
|
||||||
|
int acl_interface_apply_cfg(struct acl_list* acl_interface, struct config_file* cfg,
|
||||||
|
struct views* v);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lookup access control status for acl structure.
|
* Lookup access control status for acl structure.
|
||||||
* @param acl: structure for acl storage.
|
* @param acl: structure for acl storage.
|
||||||
|
@ -96,6 +96,9 @@
|
|||||||
#ifdef HAVE_SYSTEMD
|
#ifdef HAVE_SYSTEMD
|
||||||
#include <systemd/sd-daemon.h>
|
#include <systemd/sd-daemon.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_NETDB_H
|
||||||
|
#include <netdb.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/** How many quit requests happened. */
|
/** How many quit requests happened. */
|
||||||
static int sig_record_quit = 0;
|
static int sig_record_quit = 0;
|
||||||
@ -271,8 +274,17 @@ daemon_init(void)
|
|||||||
free(daemon);
|
free(daemon);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
daemon->acl_interface = acl_list_create();
|
||||||
|
if(!daemon->acl_interface) {
|
||||||
|
acl_list_delete(daemon->acl);
|
||||||
|
edns_known_options_delete(daemon->env);
|
||||||
|
free(daemon->env);
|
||||||
|
free(daemon);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
daemon->tcl = tcl_list_create();
|
daemon->tcl = tcl_list_create();
|
||||||
if(!daemon->tcl) {
|
if(!daemon->tcl) {
|
||||||
|
acl_list_delete(daemon->acl_interface);
|
||||||
acl_list_delete(daemon->acl);
|
acl_list_delete(daemon->acl);
|
||||||
edns_known_options_delete(daemon->env);
|
edns_known_options_delete(daemon->env);
|
||||||
free(daemon->env);
|
free(daemon->env);
|
||||||
@ -284,6 +296,7 @@ daemon_init(void)
|
|||||||
log_err("gettimeofday: %s", strerror(errno));
|
log_err("gettimeofday: %s", strerror(errno));
|
||||||
daemon->time_last_stat = daemon->time_boot;
|
daemon->time_last_stat = daemon->time_boot;
|
||||||
if((daemon->env->auth_zones = auth_zones_create()) == 0) {
|
if((daemon->env->auth_zones = auth_zones_create()) == 0) {
|
||||||
|
acl_list_delete(daemon->acl_interface);
|
||||||
acl_list_delete(daemon->acl);
|
acl_list_delete(daemon->acl);
|
||||||
tcl_list_delete(daemon->tcl);
|
tcl_list_delete(daemon->tcl);
|
||||||
edns_known_options_delete(daemon->env);
|
edns_known_options_delete(daemon->env);
|
||||||
@ -293,6 +306,7 @@ daemon_init(void)
|
|||||||
}
|
}
|
||||||
if(!(daemon->env->edns_strings = edns_strings_create())) {
|
if(!(daemon->env->edns_strings = edns_strings_create())) {
|
||||||
auth_zones_delete(daemon->env->auth_zones);
|
auth_zones_delete(daemon->env->auth_zones);
|
||||||
|
acl_list_delete(daemon->acl_interface);
|
||||||
acl_list_delete(daemon->acl);
|
acl_list_delete(daemon->acl);
|
||||||
tcl_list_delete(daemon->tcl);
|
tcl_list_delete(daemon->tcl);
|
||||||
edns_known_options_delete(daemon->env);
|
edns_known_options_delete(daemon->env);
|
||||||
@ -303,6 +317,29 @@ daemon_init(void)
|
|||||||
return daemon;
|
return daemon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int setup_acl_for_ports(struct acl_list* list,
|
||||||
|
struct listen_port* port_list)
|
||||||
|
{
|
||||||
|
struct acl_addr* acl_node;
|
||||||
|
struct addrinfo* addr;
|
||||||
|
for(; port_list; port_list=port_list->next) {
|
||||||
|
if(!port_list->socket) {
|
||||||
|
/* This is mainly for testbound where port_list is
|
||||||
|
* empty. */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
addr = port_list->socket->addr;
|
||||||
|
if(!(acl_node = acl_interface_insert(list,
|
||||||
|
(struct sockaddr_storage*)addr->ai_addr,
|
||||||
|
(socklen_t)addr->ai_addrlen,
|
||||||
|
acl_refuse))) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
port_list->socket->acl = acl_node;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
daemon_open_shared_ports(struct daemon* daemon)
|
daemon_open_shared_ports(struct daemon* daemon)
|
||||||
{
|
{
|
||||||
@ -320,6 +357,8 @@ daemon_open_shared_ports(struct daemon* daemon)
|
|||||||
free(daemon->ports);
|
free(daemon->ports);
|
||||||
daemon->ports = NULL;
|
daemon->ports = NULL;
|
||||||
}
|
}
|
||||||
|
/* clean acl_interface */
|
||||||
|
acl_interface_init(daemon->acl_interface);
|
||||||
if(!resolve_interface_names(daemon->cfg->ifs,
|
if(!resolve_interface_names(daemon->cfg->ifs,
|
||||||
daemon->cfg->num_ifs, NULL, &resif, &num_resif))
|
daemon->cfg->num_ifs, NULL, &resif, &num_resif))
|
||||||
return 0;
|
return 0;
|
||||||
@ -329,7 +368,8 @@ daemon_open_shared_ports(struct daemon* daemon)
|
|||||||
daemon->reuseport = 1;
|
daemon->reuseport = 1;
|
||||||
#endif
|
#endif
|
||||||
/* try to use reuseport */
|
/* try to use reuseport */
|
||||||
p0 = listening_ports_open(daemon->cfg, resif, num_resif, &daemon->reuseport);
|
p0 = listening_ports_open(daemon->cfg, resif, num_resif,
|
||||||
|
&daemon->reuseport);
|
||||||
if(!p0) {
|
if(!p0) {
|
||||||
listening_ports_free(p0);
|
listening_ports_free(p0);
|
||||||
config_del_strarray(resif, num_resif);
|
config_del_strarray(resif, num_resif);
|
||||||
@ -350,6 +390,12 @@ daemon_open_shared_ports(struct daemon* daemon)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
daemon->ports[0] = p0;
|
daemon->ports[0] = p0;
|
||||||
|
if(!setup_acl_for_ports(daemon->acl_interface,
|
||||||
|
daemon->ports[0])) {
|
||||||
|
listening_ports_free(p0);
|
||||||
|
config_del_strarray(resif, num_resif);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
if(daemon->reuseport) {
|
if(daemon->reuseport) {
|
||||||
/* continue to use reuseport */
|
/* continue to use reuseport */
|
||||||
for(i=1; i<daemon->num_ports; i++) {
|
for(i=1; i<daemon->num_ports; i++) {
|
||||||
@ -365,6 +411,15 @@ daemon_open_shared_ports(struct daemon* daemon)
|
|||||||
config_del_strarray(resif, num_resif);
|
config_del_strarray(resif, num_resif);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if(!setup_acl_for_ports(daemon->acl_interface,
|
||||||
|
daemon->ports[i])) {
|
||||||
|
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);
|
config_del_strarray(resif, num_resif);
|
||||||
@ -604,6 +659,9 @@ daemon_fork(struct daemon* daemon)
|
|||||||
|
|
||||||
if(!acl_list_apply_cfg(daemon->acl, daemon->cfg, daemon->views))
|
if(!acl_list_apply_cfg(daemon->acl, daemon->cfg, daemon->views))
|
||||||
fatal_exit("Could not setup access control list");
|
fatal_exit("Could not setup access control list");
|
||||||
|
if(!acl_interface_apply_cfg(daemon->acl_interface, daemon->cfg,
|
||||||
|
daemon->views))
|
||||||
|
fatal_exit("Could not setup interface control list");
|
||||||
if(!tcl_list_apply_cfg(daemon->tcl, daemon->cfg))
|
if(!tcl_list_apply_cfg(daemon->tcl, daemon->cfg))
|
||||||
fatal_exit("Could not setup TCP connection limits");
|
fatal_exit("Could not setup TCP connection limits");
|
||||||
if(daemon->cfg->dnscrypt) {
|
if(daemon->cfg->dnscrypt) {
|
||||||
@ -780,6 +838,7 @@ daemon_delete(struct daemon* daemon)
|
|||||||
ub_randfree(daemon->rand);
|
ub_randfree(daemon->rand);
|
||||||
alloc_clear(&daemon->superalloc);
|
alloc_clear(&daemon->superalloc);
|
||||||
acl_list_delete(daemon->acl);
|
acl_list_delete(daemon->acl);
|
||||||
|
acl_list_delete(daemon->acl_interface);
|
||||||
tcl_list_delete(daemon->tcl);
|
tcl_list_delete(daemon->tcl);
|
||||||
listen_desetup_locks();
|
listen_desetup_locks();
|
||||||
free(daemon->chroot);
|
free(daemon->chroot);
|
||||||
|
@ -113,6 +113,8 @@ struct daemon {
|
|||||||
struct module_stack mods;
|
struct module_stack mods;
|
||||||
/** access control, which client IPs are allowed to connect */
|
/** access control, which client IPs are allowed to connect */
|
||||||
struct acl_list* acl;
|
struct acl_list* acl;
|
||||||
|
/** access control, which interfaces are allowed to connect */
|
||||||
|
struct acl_list* acl_interface;
|
||||||
/** TCP connection limit, limit connections from client IPs */
|
/** TCP connection limit, limit connections from client IPs */
|
||||||
struct tcl_list* tcl;
|
struct tcl_list* tcl;
|
||||||
/** local authority zones */
|
/** local authority zones */
|
||||||
|
@ -494,8 +494,8 @@ int remote_accept_callback(struct comm_point* c, void* arg, int err,
|
|||||||
n->c->do_not_close = 0;
|
n->c->do_not_close = 0;
|
||||||
comm_point_stop_listening(n->c);
|
comm_point_stop_listening(n->c);
|
||||||
comm_point_start_listening(n->c, -1, REMOTE_CONTROL_TCP_TIMEOUT);
|
comm_point_start_listening(n->c, -1, REMOTE_CONTROL_TCP_TIMEOUT);
|
||||||
memcpy(&n->c->repinfo.addr, &addr, addrlen);
|
memcpy(&n->c->repinfo.remote_addr, &addr, addrlen);
|
||||||
n->c->repinfo.addrlen = addrlen;
|
n->c->repinfo.remote_addrlen = addrlen;
|
||||||
if(rc->use_cert) {
|
if(rc->use_cert) {
|
||||||
n->shake_state = rc_hs_read;
|
n->shake_state = rc_hs_read;
|
||||||
n->ssl = SSL_new(rc->ctx);
|
n->ssl = SSL_new(rc->ctx);
|
||||||
@ -3304,7 +3304,7 @@ remote_handshake_later(struct daemon_remote* rc, struct rc_state* s,
|
|||||||
if(r == 0)
|
if(r == 0)
|
||||||
log_err("remote control connection closed prematurely");
|
log_err("remote control connection closed prematurely");
|
||||||
log_addr(VERB_OPS, "failed connection from",
|
log_addr(VERB_OPS, "failed connection from",
|
||||||
&s->c->repinfo.addr, s->c->repinfo.addrlen);
|
&s->c->repinfo.remote_addr, s->c->repinfo.remote_addrlen);
|
||||||
log_crypto_err("remote control failed ssl");
|
log_crypto_err("remote control failed ssl");
|
||||||
clean_point(rc, s);
|
clean_point(rc, s);
|
||||||
}
|
}
|
||||||
|
@ -70,6 +70,9 @@
|
|||||||
#include <openssl/ssl.h>
|
#include <openssl/ssl.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/** How long to wait for threads to transmit statistics, in msec. */
|
||||||
|
#define STATS_THREAD_WAIT 60000
|
||||||
|
|
||||||
/** add timers and the values do not overflow or become negative */
|
/** add timers and the values do not overflow or become negative */
|
||||||
static void
|
static void
|
||||||
stats_timeval_add(long long* d_sec, long long* d_usec, long long add_sec, long long add_usec)
|
stats_timeval_add(long long* d_sec, long long* d_usec, long long add_sec, long long add_usec)
|
||||||
@ -380,6 +383,28 @@ void server_stats_obtain(struct worker* worker, struct worker* who,
|
|||||||
worker_send_cmd(who, worker_cmd_stats);
|
worker_send_cmd(who, worker_cmd_stats);
|
||||||
else worker_send_cmd(who, worker_cmd_stats_noreset);
|
else worker_send_cmd(who, worker_cmd_stats_noreset);
|
||||||
verbose(VERB_ALGO, "wait for stats reply");
|
verbose(VERB_ALGO, "wait for stats reply");
|
||||||
|
if(tube_wait_timeout(worker->cmd, STATS_THREAD_WAIT) == 0) {
|
||||||
|
verbose(VERB_OPS, "no response from thread %d"
|
||||||
|
#ifdef HAVE_GETTID
|
||||||
|
" LWP %u"
|
||||||
|
#endif
|
||||||
|
#if defined(HAVE_PTHREAD) && defined(SIZEOF_PTHREAD_T) && defined(SIZEOF_UNSIGNED_LONG)
|
||||||
|
# if SIZEOF_PTHREAD_T == SIZEOF_UNSIGNED_LONG
|
||||||
|
" pthread 0x%lx"
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
,
|
||||||
|
who->thread_num
|
||||||
|
#ifdef HAVE_GETTID
|
||||||
|
, (unsigned)who->thread_tid
|
||||||
|
#endif
|
||||||
|
#if defined(HAVE_PTHREAD) && defined(SIZEOF_PTHREAD_T) && defined(SIZEOF_UNSIGNED_LONG)
|
||||||
|
# if SIZEOF_PTHREAD_T == SIZEOF_UNSIGNED_LONG
|
||||||
|
, (unsigned long)*((unsigned long*)&who->thr_id)
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
}
|
||||||
if(!tube_read_msg(worker->cmd, &reply, &len, 0))
|
if(!tube_read_msg(worker->cmd, &reply, &len, 0))
|
||||||
fatal_exit("failed to read stats over cmd channel");
|
fatal_exit("failed to read stats over cmd channel");
|
||||||
if(len != (uint32_t)sizeof(*s))
|
if(len != (uint32_t)sizeof(*s))
|
||||||
@ -496,7 +521,7 @@ void server_stats_insquery(struct ub_server_stats* stats, struct comm_point* c,
|
|||||||
stats->qhttps++;
|
stats->qhttps++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(repinfo && addr_is_ip6(&repinfo->addr, repinfo->addrlen))
|
if(repinfo && addr_is_ip6(&repinfo->remote_addr, repinfo->remote_addrlen))
|
||||||
stats->qipv6++;
|
stats->qipv6++;
|
||||||
if( (flags&BIT_QR) )
|
if( (flags&BIT_QR) )
|
||||||
stats->qbit_QR++;
|
stats->qbit_QR++;
|
||||||
|
146
daemon/worker.c
146
daemon/worker.c
@ -547,7 +547,8 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
|
|||||||
static int
|
static int
|
||||||
apply_respip_action(struct worker* worker, const struct query_info* qinfo,
|
apply_respip_action(struct worker* worker, const struct query_info* qinfo,
|
||||||
struct respip_client_info* cinfo, struct reply_info* rep,
|
struct respip_client_info* cinfo, struct reply_info* rep,
|
||||||
struct comm_reply* repinfo, struct ub_packed_rrset_key** alias_rrset,
|
struct sockaddr_storage* addr, socklen_t addrlen,
|
||||||
|
struct ub_packed_rrset_key** alias_rrset,
|
||||||
struct reply_info** encode_repp, struct auth_zones* az)
|
struct reply_info** encode_repp, struct auth_zones* az)
|
||||||
{
|
{
|
||||||
struct respip_action_info actinfo = {0, 0, 0, 0, NULL, 0, NULL};
|
struct respip_action_info actinfo = {0, 0, 0, 0, NULL, 0, NULL};
|
||||||
@ -574,7 +575,7 @@ apply_respip_action(struct worker* worker, const struct query_info* qinfo,
|
|||||||
if(actinfo.addrinfo) {
|
if(actinfo.addrinfo) {
|
||||||
respip_inform_print(&actinfo, qinfo->qname,
|
respip_inform_print(&actinfo, qinfo->qname,
|
||||||
qinfo->qtype, qinfo->qclass, qinfo->local_alias,
|
qinfo->qtype, qinfo->qclass, qinfo->local_alias,
|
||||||
repinfo);
|
addr, addrlen);
|
||||||
|
|
||||||
if(worker->stats.extended && actinfo.rpz_used) {
|
if(worker->stats.extended && actinfo.rpz_used) {
|
||||||
if(actinfo.rpz_disabled)
|
if(actinfo.rpz_disabled)
|
||||||
@ -703,7 +704,7 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
|
|||||||
*alias_rrset = NULL; /* avoid confusion if caller set it to non-NULL */
|
*alias_rrset = NULL; /* avoid confusion if caller set it to non-NULL */
|
||||||
if((worker->daemon->use_response_ip || worker->daemon->use_rpz) &&
|
if((worker->daemon->use_response_ip || worker->daemon->use_rpz) &&
|
||||||
!partial_rep && !apply_respip_action(worker, qinfo, cinfo, rep,
|
!partial_rep && !apply_respip_action(worker, qinfo, cinfo, rep,
|
||||||
repinfo, alias_rrset,
|
&repinfo->client_addr, repinfo->client_addrlen, alias_rrset,
|
||||||
&encode_rep, worker->env.auth_zones)) {
|
&encode_rep, worker->env.auth_zones)) {
|
||||||
goto bail_out;
|
goto bail_out;
|
||||||
} else if(partial_rep &&
|
} else if(partial_rep &&
|
||||||
@ -991,12 +992,14 @@ answer_chaos(struct worker* w, struct query_info* qinfo,
|
|||||||
* @param w: worker
|
* @param w: worker
|
||||||
* @param qinfo: query info. Pointer into packet buffer.
|
* @param qinfo: query info. Pointer into packet buffer.
|
||||||
* @param edns: edns info from query.
|
* @param edns: edns info from query.
|
||||||
* @param repinfo: reply info with source address.
|
* @param addr: client address.
|
||||||
|
* @param addrlen: client address length.
|
||||||
* @param pkt: packet buffer.
|
* @param pkt: packet buffer.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
answer_notify(struct worker* w, struct query_info* qinfo,
|
answer_notify(struct worker* w, struct query_info* qinfo,
|
||||||
struct edns_data* edns, sldns_buffer* pkt, struct comm_reply* repinfo)
|
struct edns_data* edns, sldns_buffer* pkt,
|
||||||
|
struct sockaddr_storage* addr, socklen_t addrlen)
|
||||||
{
|
{
|
||||||
int refused = 0;
|
int refused = 0;
|
||||||
int rcode = LDNS_RCODE_NOERROR;
|
int rcode = LDNS_RCODE_NOERROR;
|
||||||
@ -1005,8 +1008,8 @@ answer_notify(struct worker* w, struct query_info* qinfo,
|
|||||||
if(!w->env.auth_zones) return;
|
if(!w->env.auth_zones) return;
|
||||||
has_serial = auth_zone_parse_notify_serial(pkt, &serial);
|
has_serial = auth_zone_parse_notify_serial(pkt, &serial);
|
||||||
if(auth_zones_notify(w->env.auth_zones, &w->env, qinfo->qname,
|
if(auth_zones_notify(w->env.auth_zones, &w->env, qinfo->qname,
|
||||||
qinfo->qname_len, qinfo->qclass, &repinfo->addr,
|
qinfo->qname_len, qinfo->qclass, addr,
|
||||||
repinfo->addrlen, has_serial, serial, &refused)) {
|
addrlen, has_serial, serial, &refused)) {
|
||||||
rcode = LDNS_RCODE_NOERROR;
|
rcode = LDNS_RCODE_NOERROR;
|
||||||
} else {
|
} else {
|
||||||
if(refused)
|
if(refused)
|
||||||
@ -1031,7 +1034,7 @@ answer_notify(struct worker* w, struct query_info* qinfo,
|
|||||||
"servfail for NOTIFY %sfor %s from", sr, zname);
|
"servfail for NOTIFY %sfor %s from", sr, zname);
|
||||||
else snprintf(buf, sizeof(buf),
|
else snprintf(buf, sizeof(buf),
|
||||||
"received NOTIFY %sfor %s from", sr, zname);
|
"received NOTIFY %sfor %s from", sr, zname);
|
||||||
log_addr(VERB_DETAIL, buf, &repinfo->addr, repinfo->addrlen);
|
log_addr(VERB_DETAIL, buf, addr, addrlen);
|
||||||
}
|
}
|
||||||
edns->edns_version = EDNS_ADVERTISED_VERSION;
|
edns->edns_version = EDNS_ADVERTISED_VERSION;
|
||||||
edns->udp_size = EDNS_ADVERTISED_SIZE;
|
edns->udp_size = EDNS_ADVERTISED_SIZE;
|
||||||
@ -1051,8 +1054,8 @@ deny_refuse(struct comm_point* c, enum acl_access acl,
|
|||||||
{
|
{
|
||||||
if(acl == deny) {
|
if(acl == deny) {
|
||||||
if(verbosity >= VERB_ALGO) {
|
if(verbosity >= VERB_ALGO) {
|
||||||
log_acl_action("dropped", &repinfo->addr,
|
log_acl_action("dropped", &repinfo->client_addr,
|
||||||
repinfo->addrlen, acl, acladdr);
|
repinfo->client_addrlen, acl, acladdr);
|
||||||
log_buf(VERB_ALGO, "dropped", c->buffer);
|
log_buf(VERB_ALGO, "dropped", c->buffer);
|
||||||
}
|
}
|
||||||
comm_point_drop_reply(repinfo);
|
comm_point_drop_reply(repinfo);
|
||||||
@ -1063,8 +1066,8 @@ deny_refuse(struct comm_point* c, enum acl_access acl,
|
|||||||
size_t opt_rr_mark;
|
size_t opt_rr_mark;
|
||||||
|
|
||||||
if(verbosity >= VERB_ALGO) {
|
if(verbosity >= VERB_ALGO) {
|
||||||
log_acl_action("refused", &repinfo->addr,
|
log_acl_action("refused", &repinfo->client_addr,
|
||||||
repinfo->addrlen, acl, acladdr);
|
repinfo->client_addrlen, acl, acladdr);
|
||||||
log_buf(VERB_ALGO, "refuse", c->buffer);
|
log_buf(VERB_ALGO, "refuse", c->buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1224,12 +1227,24 @@ deny_refuse(struct comm_point* c, enum acl_access acl,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
deny_refuse_all(struct comm_point* c, enum acl_access acl,
|
deny_refuse_all(struct comm_point* c, enum acl_access* acl,
|
||||||
struct worker* worker, struct comm_reply* repinfo,
|
struct worker* worker, struct comm_reply* repinfo,
|
||||||
struct acl_addr* acladdr, int ede)
|
struct acl_addr** acladdr, int ede, int check_proxy)
|
||||||
{
|
{
|
||||||
return deny_refuse(c, acl, acl_deny, acl_refuse, worker, repinfo,
|
if(check_proxy) {
|
||||||
acladdr, ede);
|
*acladdr = acl_addr_lookup(worker->daemon->acl,
|
||||||
|
&repinfo->remote_addr, repinfo->remote_addrlen);
|
||||||
|
} else {
|
||||||
|
*acladdr = acl_addr_lookup(worker->daemon->acl,
|
||||||
|
&repinfo->client_addr, repinfo->client_addrlen);
|
||||||
|
}
|
||||||
|
/* If there is no ACL based on client IP use the interface ACL. */
|
||||||
|
if(!(*acladdr) && c->socket) {
|
||||||
|
*acladdr = c->socket->acl;
|
||||||
|
}
|
||||||
|
*acl = acl_get_control(*acladdr);
|
||||||
|
return deny_refuse(c, *acl, acl_deny, acl_refuse, worker, repinfo,
|
||||||
|
*acladdr, ede);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -1286,16 +1301,16 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
|||||||
if(worker_check_request(c->buffer, worker) != 0) {
|
if(worker_check_request(c->buffer, worker) != 0) {
|
||||||
verbose(VERB_ALGO,
|
verbose(VERB_ALGO,
|
||||||
"dnscrypt: worker check request: bad query.");
|
"dnscrypt: worker check request: bad query.");
|
||||||
log_addr(VERB_CLIENT,"from",&repinfo->addr,
|
log_addr(VERB_CLIENT,"from",&repinfo->client_addr,
|
||||||
repinfo->addrlen);
|
repinfo->client_addrlen);
|
||||||
comm_point_drop_reply(repinfo);
|
comm_point_drop_reply(repinfo);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(!query_info_parse(&qinfo, c->buffer)) {
|
if(!query_info_parse(&qinfo, c->buffer)) {
|
||||||
verbose(VERB_ALGO,
|
verbose(VERB_ALGO,
|
||||||
"dnscrypt: worker parse request: formerror.");
|
"dnscrypt: worker parse request: formerror.");
|
||||||
log_addr(VERB_CLIENT, "from", &repinfo->addr,
|
log_addr(VERB_CLIENT, "from", &repinfo->client_addr,
|
||||||
repinfo->addrlen);
|
repinfo->client_addrlen);
|
||||||
comm_point_drop_reply(repinfo);
|
comm_point_drop_reply(repinfo);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1323,25 +1338,30 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
|||||||
* sending src (client)/dst (local service) addresses over DNSTAP from incoming request handler
|
* sending src (client)/dst (local service) addresses over DNSTAP from incoming request handler
|
||||||
*/
|
*/
|
||||||
if(worker->dtenv.log_client_query_messages) {
|
if(worker->dtenv.log_client_query_messages) {
|
||||||
log_addr(VERB_ALGO, "request from client", &repinfo->addr, repinfo->addrlen);
|
log_addr(VERB_ALGO, "request from client", &repinfo->client_addr, repinfo->client_addrlen);
|
||||||
log_addr(VERB_ALGO, "to local addr", (void*)repinfo->c->socket->addr->ai_addr, repinfo->c->socket->addr->ai_addrlen);
|
log_addr(VERB_ALGO, "to local addr", (void*)repinfo->c->socket->addr->ai_addr, repinfo->c->socket->addr->ai_addrlen);
|
||||||
dt_msg_send_client_query(&worker->dtenv, &repinfo->addr, (void*)repinfo->c->socket->addr->ai_addr, c->type, c->buffer);
|
dt_msg_send_client_query(&worker->dtenv, &repinfo->client_addr, (void*)repinfo->c->socket->addr->ai_addr, c->type, c->buffer);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
acladdr = acl_addr_lookup(worker->daemon->acl, &repinfo->addr,
|
/* Check deny/refuse ACLs */
|
||||||
repinfo->addrlen);
|
if(repinfo->is_proxied) {
|
||||||
acl = acl_get_control(acladdr);
|
if((ret=deny_refuse_all(c, &acl, worker, repinfo, &acladdr,
|
||||||
|
worker->env.cfg->ede, 1)) != -1) {
|
||||||
if((ret=deny_refuse_all(c, acl, worker, repinfo, acladdr,
|
|
||||||
worker->env.cfg->ede)) != -1)
|
|
||||||
{
|
|
||||||
if(ret == 1)
|
if(ret == 1)
|
||||||
goto send_reply;
|
goto send_reply;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if((ret=deny_refuse_all(c, &acl, worker, repinfo, &acladdr,
|
||||||
|
worker->env.cfg->ede, 0)) != -1) {
|
||||||
|
if(ret == 1)
|
||||||
|
goto send_reply;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
if((ret=worker_check_request(c->buffer, worker)) != 0) {
|
if((ret=worker_check_request(c->buffer, worker)) != 0) {
|
||||||
verbose(VERB_ALGO, "worker check request: bad query.");
|
verbose(VERB_ALGO, "worker check request: bad query.");
|
||||||
log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
|
log_addr(VERB_CLIENT,"from",&repinfo->client_addr, repinfo->client_addrlen);
|
||||||
if(ret != -1) {
|
if(ret != -1) {
|
||||||
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
|
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
|
||||||
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer), ret);
|
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer), ret);
|
||||||
@ -1353,20 +1373,24 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
|||||||
|
|
||||||
worker->stats.num_queries++;
|
worker->stats.num_queries++;
|
||||||
|
|
||||||
/* check if this query should be dropped based on source ip rate limiting */
|
/* check if this query should be dropped based on source ip rate limiting
|
||||||
if(!infra_ip_ratelimit_inc(worker->env.infra_cache, repinfo,
|
* NOTE: we always check the repinfo->client_address. IP ratelimiting is
|
||||||
|
* implicitly disabled for proxies. */
|
||||||
|
if(!infra_ip_ratelimit_inc(worker->env.infra_cache,
|
||||||
|
&repinfo->client_addr, repinfo->client_addrlen,
|
||||||
*worker->env.now,
|
*worker->env.now,
|
||||||
worker->env.cfg->ip_ratelimit_backoff, c->buffer)) {
|
worker->env.cfg->ip_ratelimit_backoff, c->buffer)) {
|
||||||
/* See if we are passed through with slip factor */
|
/* See if we are passed through with slip factor */
|
||||||
if(worker->env.cfg->ip_ratelimit_factor != 0 &&
|
if(worker->env.cfg->ip_ratelimit_factor != 0 &&
|
||||||
ub_random_max(worker->env.rnd,
|
ub_random_max(worker->env.rnd,
|
||||||
worker->env.cfg->ip_ratelimit_factor) == 0) {
|
worker->env.cfg->ip_ratelimit_factor) == 0) {
|
||||||
|
|
||||||
char addrbuf[128];
|
char addrbuf[128];
|
||||||
addr_to_str(&repinfo->addr, repinfo->addrlen,
|
addr_to_str(&repinfo->client_addr,
|
||||||
addrbuf, sizeof(addrbuf));
|
repinfo->client_addrlen, addrbuf,
|
||||||
verbose(VERB_QUERY, "ip_ratelimit allowed through for ip address %s because of slip in ip_ratelimit_factor",
|
sizeof(addrbuf));
|
||||||
addrbuf);
|
verbose(VERB_QUERY, "ip_ratelimit allowed through for "
|
||||||
|
"ip address %s because of slip in "
|
||||||
|
"ip_ratelimit_factor", addrbuf);
|
||||||
} else {
|
} else {
|
||||||
worker->stats.num_queries_ip_ratelimited++;
|
worker->stats.num_queries_ip_ratelimited++;
|
||||||
comm_point_drop_reply(repinfo);
|
comm_point_drop_reply(repinfo);
|
||||||
@ -1377,7 +1401,8 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
|||||||
/* see if query is in the cache */
|
/* see if query is in the cache */
|
||||||
if(!query_info_parse(&qinfo, c->buffer)) {
|
if(!query_info_parse(&qinfo, c->buffer)) {
|
||||||
verbose(VERB_ALGO, "worker parse request: formerror.");
|
verbose(VERB_ALGO, "worker parse request: formerror.");
|
||||||
log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
|
log_addr(VERB_CLIENT, "from", &repinfo->client_addr,
|
||||||
|
repinfo->client_addrlen);
|
||||||
memset(&qinfo, 0, sizeof(qinfo)); /* zero qinfo.qname */
|
memset(&qinfo, 0, sizeof(qinfo)); /* zero qinfo.qname */
|
||||||
if(worker_err_ratelimit(worker, LDNS_RCODE_FORMERR) == -1) {
|
if(worker_err_ratelimit(worker, LDNS_RCODE_FORMERR) == -1) {
|
||||||
comm_point_drop_reply(repinfo);
|
comm_point_drop_reply(repinfo);
|
||||||
@ -1391,13 +1416,14 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
|||||||
}
|
}
|
||||||
if(worker->env.cfg->log_queries) {
|
if(worker->env.cfg->log_queries) {
|
||||||
char ip[128];
|
char ip[128];
|
||||||
addr_to_str(&repinfo->addr, repinfo->addrlen, ip, sizeof(ip));
|
addr_to_str(&repinfo->client_addr, repinfo->client_addrlen, ip, sizeof(ip));
|
||||||
log_query_in(ip, qinfo.qname, qinfo.qtype, qinfo.qclass);
|
log_query_in(ip, qinfo.qname, qinfo.qtype, qinfo.qclass);
|
||||||
}
|
}
|
||||||
if(qinfo.qtype == LDNS_RR_TYPE_AXFR ||
|
if(qinfo.qtype == LDNS_RR_TYPE_AXFR ||
|
||||||
qinfo.qtype == LDNS_RR_TYPE_IXFR) {
|
qinfo.qtype == LDNS_RR_TYPE_IXFR) {
|
||||||
verbose(VERB_ALGO, "worker request: refused zone transfer.");
|
verbose(VERB_ALGO, "worker request: refused zone transfer.");
|
||||||
log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
|
log_addr(VERB_CLIENT, "from", &repinfo->client_addr,
|
||||||
|
repinfo->client_addrlen);
|
||||||
sldns_buffer_rewind(c->buffer);
|
sldns_buffer_rewind(c->buffer);
|
||||||
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
|
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
|
||||||
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
|
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
|
||||||
@ -1414,7 +1440,8 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
|||||||
qinfo.qtype == LDNS_RR_TYPE_MAILB ||
|
qinfo.qtype == LDNS_RR_TYPE_MAILB ||
|
||||||
(qinfo.qtype >= 128 && qinfo.qtype <= 248)) {
|
(qinfo.qtype >= 128 && qinfo.qtype <= 248)) {
|
||||||
verbose(VERB_ALGO, "worker request: formerror for meta-type.");
|
verbose(VERB_ALGO, "worker request: formerror for meta-type.");
|
||||||
log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
|
log_addr(VERB_CLIENT, "from", &repinfo->client_addr,
|
||||||
|
repinfo->client_addrlen);
|
||||||
if(worker_err_ratelimit(worker, LDNS_RCODE_FORMERR) == -1) {
|
if(worker_err_ratelimit(worker, LDNS_RCODE_FORMERR) == -1) {
|
||||||
comm_point_drop_reply(repinfo);
|
comm_point_drop_reply(repinfo);
|
||||||
return 0;
|
return 0;
|
||||||
@ -1432,7 +1459,8 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
|||||||
worker->scratchpad)) != 0) {
|
worker->scratchpad)) != 0) {
|
||||||
struct edns_data reply_edns;
|
struct edns_data reply_edns;
|
||||||
verbose(VERB_ALGO, "worker parse edns: formerror.");
|
verbose(VERB_ALGO, "worker parse edns: formerror.");
|
||||||
log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
|
log_addr(VERB_CLIENT, "from", &repinfo->client_addr,
|
||||||
|
repinfo->client_addrlen);
|
||||||
memset(&reply_edns, 0, sizeof(reply_edns));
|
memset(&reply_edns, 0, sizeof(reply_edns));
|
||||||
reply_edns.edns_present = 1;
|
reply_edns.edns_present = 1;
|
||||||
reply_edns.udp_size = EDNS_ADVERTISED_SIZE;
|
reply_edns.udp_size = EDNS_ADVERTISED_SIZE;
|
||||||
@ -1454,7 +1482,8 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
|||||||
edns.opt_list_inplace_cb_out = NULL;
|
edns.opt_list_inplace_cb_out = NULL;
|
||||||
edns.padding_block_size = 0;
|
edns.padding_block_size = 0;
|
||||||
verbose(VERB_ALGO, "query with bad edns version.");
|
verbose(VERB_ALGO, "query with bad edns version.");
|
||||||
log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
|
log_addr(VERB_CLIENT, "from", &repinfo->client_addr,
|
||||||
|
repinfo->client_addrlen);
|
||||||
error_encode(c->buffer, EDNS_RCODE_BADVERS&0xf, &qinfo,
|
error_encode(c->buffer, EDNS_RCODE_BADVERS&0xf, &qinfo,
|
||||||
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
|
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
|
||||||
sldns_buffer_read_u16_at(c->buffer, 2), NULL);
|
sldns_buffer_read_u16_at(c->buffer, 2), NULL);
|
||||||
@ -1468,7 +1497,8 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
|||||||
worker->daemon->cfg->harden_short_bufsize) {
|
worker->daemon->cfg->harden_short_bufsize) {
|
||||||
verbose(VERB_QUERY, "worker request: EDNS bufsize %d ignored",
|
verbose(VERB_QUERY, "worker request: EDNS bufsize %d ignored",
|
||||||
(int)edns.udp_size);
|
(int)edns.udp_size);
|
||||||
log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
|
log_addr(VERB_CLIENT, "from", &repinfo->client_addr,
|
||||||
|
repinfo->client_addrlen);
|
||||||
edns.udp_size = NORMAL_UDP_SIZE;
|
edns.udp_size = NORMAL_UDP_SIZE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1477,12 +1507,14 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
|||||||
verbose(VERB_QUERY,
|
verbose(VERB_QUERY,
|
||||||
"worker request: max UDP reply size modified"
|
"worker request: max UDP reply size modified"
|
||||||
" (%d to max-udp-size)", (int)edns.udp_size);
|
" (%d to max-udp-size)", (int)edns.udp_size);
|
||||||
log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
|
log_addr(VERB_CLIENT, "from", &repinfo->client_addr,
|
||||||
|
repinfo->client_addrlen);
|
||||||
edns.udp_size = worker->daemon->cfg->max_udp_size;
|
edns.udp_size = worker->daemon->cfg->max_udp_size;
|
||||||
}
|
}
|
||||||
if(edns.udp_size < LDNS_HEADER_SIZE) {
|
if(edns.udp_size < LDNS_HEADER_SIZE) {
|
||||||
verbose(VERB_ALGO, "worker request: edns is too small.");
|
verbose(VERB_ALGO, "worker request: edns is too small.");
|
||||||
log_addr(VERB_CLIENT, "from", &repinfo->addr, repinfo->addrlen);
|
log_addr(VERB_CLIENT, "from", &repinfo->client_addr,
|
||||||
|
repinfo->client_addrlen);
|
||||||
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
|
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
|
||||||
LDNS_TC_SET(sldns_buffer_begin(c->buffer));
|
LDNS_TC_SET(sldns_buffer_begin(c->buffer));
|
||||||
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
|
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
|
||||||
@ -1506,7 +1538,8 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
|||||||
}
|
}
|
||||||
if(LDNS_OPCODE_WIRE(sldns_buffer_begin(c->buffer)) ==
|
if(LDNS_OPCODE_WIRE(sldns_buffer_begin(c->buffer)) ==
|
||||||
LDNS_PACKET_NOTIFY) {
|
LDNS_PACKET_NOTIFY) {
|
||||||
answer_notify(worker, &qinfo, &edns, c->buffer, repinfo);
|
answer_notify(worker, &qinfo, &edns, c->buffer,
|
||||||
|
&repinfo->client_addr, repinfo->client_addrlen);
|
||||||
regional_free_all(worker->scratchpad);
|
regional_free_all(worker->scratchpad);
|
||||||
goto send_reply;
|
goto send_reply;
|
||||||
}
|
}
|
||||||
@ -1582,7 +1615,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
|||||||
sldns_buffer_read_u16_at(c->buffer, 2), &edns);
|
sldns_buffer_read_u16_at(c->buffer, 2), &edns);
|
||||||
regional_free_all(worker->scratchpad);
|
regional_free_all(worker->scratchpad);
|
||||||
log_addr(VERB_ALGO, "refused nonrec (cache snoop) query from",
|
log_addr(VERB_ALGO, "refused nonrec (cache snoop) query from",
|
||||||
&repinfo->addr, repinfo->addrlen);
|
&repinfo->client_addr, repinfo->client_addrlen);
|
||||||
|
|
||||||
goto send_reply;
|
goto send_reply;
|
||||||
}
|
}
|
||||||
@ -1722,9 +1755,9 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
|||||||
if(verbosity >= VERB_CLIENT) {
|
if(verbosity >= VERB_CLIENT) {
|
||||||
if(c->type == comm_udp)
|
if(c->type == comm_udp)
|
||||||
log_addr(VERB_CLIENT, "udp request from",
|
log_addr(VERB_CLIENT, "udp request from",
|
||||||
&repinfo->addr, repinfo->addrlen);
|
&repinfo->client_addr, repinfo->client_addrlen);
|
||||||
else log_addr(VERB_CLIENT, "tcp request from",
|
else log_addr(VERB_CLIENT, "tcp request from",
|
||||||
&repinfo->addr, repinfo->addrlen);
|
&repinfo->client_addr, repinfo->client_addrlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* grab a work request structure for this new request */
|
/* grab a work request structure for this new request */
|
||||||
@ -1756,8 +1789,8 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
|||||||
*/
|
*/
|
||||||
if(worker->dtenv.log_client_response_messages) {
|
if(worker->dtenv.log_client_response_messages) {
|
||||||
log_addr(VERB_ALGO, "from local addr", (void*)repinfo->c->socket->addr->ai_addr, repinfo->c->socket->addr->ai_addrlen);
|
log_addr(VERB_ALGO, "from local addr", (void*)repinfo->c->socket->addr->ai_addr, repinfo->c->socket->addr->ai_addrlen);
|
||||||
log_addr(VERB_ALGO, "response to client", &repinfo->addr, repinfo->addrlen);
|
log_addr(VERB_ALGO, "response to client", &repinfo->client_addr, repinfo->client_addrlen);
|
||||||
dt_msg_send_client_response(&worker->dtenv, &repinfo->addr, (void*)repinfo->c->socket->addr->ai_addr, c->type, c->buffer);
|
dt_msg_send_client_response(&worker->dtenv, &repinfo->client_addr, (void*)repinfo->c->socket->addr->ai_addr, c->type, c->buffer);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if(worker->env.cfg->log_replies)
|
if(worker->env.cfg->log_replies)
|
||||||
@ -1769,10 +1802,12 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
|||||||
/* log original qname, before the local alias was
|
/* log original qname, before the local alias was
|
||||||
* used to resolve that CNAME to something else */
|
* used to resolve that CNAME to something else */
|
||||||
qinfo.qname = qinfo.local_alias->rrset->rk.dname;
|
qinfo.qname = qinfo.local_alias->rrset->rk.dname;
|
||||||
log_reply_info(NO_VERBOSE, &qinfo, &repinfo->addr, repinfo->addrlen,
|
log_reply_info(NO_VERBOSE, &qinfo,
|
||||||
|
&repinfo->client_addr, repinfo->client_addrlen,
|
||||||
tv, 1, c->buffer);
|
tv, 1, c->buffer);
|
||||||
} else {
|
} else {
|
||||||
log_reply_info(NO_VERBOSE, &qinfo, &repinfo->addr, repinfo->addrlen,
|
log_reply_info(NO_VERBOSE, &qinfo,
|
||||||
|
&repinfo->client_addr, repinfo->client_addrlen,
|
||||||
tv, 1, c->buffer);
|
tv, 1, c->buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1903,6 +1938,9 @@ worker_init(struct worker* worker, struct config_file *cfg,
|
|||||||
struct dt_env* dtenv = &worker->dtenv;
|
struct dt_env* dtenv = &worker->dtenv;
|
||||||
#else
|
#else
|
||||||
void* dtenv = NULL;
|
void* dtenv = NULL;
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_GETTID
|
||||||
|
worker->thread_tid = gettid();
|
||||||
#endif
|
#endif
|
||||||
worker->need_to_exit = 0;
|
worker->need_to_exit = 0;
|
||||||
worker->base = comm_base_create(do_sigs);
|
worker->base = comm_base_create(do_sigs);
|
||||||
|
@ -86,6 +86,10 @@ struct worker {
|
|||||||
struct daemon* daemon;
|
struct daemon* daemon;
|
||||||
/** thread id */
|
/** thread id */
|
||||||
ub_thread_type thr_id;
|
ub_thread_type thr_id;
|
||||||
|
#ifdef HAVE_GETTID
|
||||||
|
/** thread tid, the LWP id. */
|
||||||
|
pid_t thread_tid;
|
||||||
|
#endif
|
||||||
/** pipe, for commands for this worker */
|
/** pipe, for commands for this worker */
|
||||||
struct tube* cmd;
|
struct tube* cmd;
|
||||||
/** the event base this worker works with */
|
/** the event base this worker works with */
|
||||||
|
@ -954,7 +954,7 @@ static int dtio_write_more(struct dt_io_thread* dtio)
|
|||||||
* -1: continue, >0: number of bytes read into buffer */
|
* -1: continue, >0: number of bytes read into buffer */
|
||||||
static ssize_t receive_bytes(struct dt_io_thread* dtio, void* buf, size_t len) {
|
static ssize_t receive_bytes(struct dt_io_thread* dtio, void* buf, size_t len) {
|
||||||
ssize_t r;
|
ssize_t r;
|
||||||
r = recv(dtio->fd, (void*)buf, len, 0);
|
r = recv(dtio->fd, (void*)buf, len, MSG_DONTWAIT);
|
||||||
if(r == -1) {
|
if(r == -1) {
|
||||||
char* to = dtio->socket_path;
|
char* to = dtio->socket_path;
|
||||||
if(!to) to = dtio->ip_str;
|
if(!to) to = dtio->ip_str;
|
||||||
@ -1960,7 +1960,7 @@ static int dtio_open_output_tcp(struct dt_io_thread* dtio)
|
|||||||
memset(&addr, 0, sizeof(addr));
|
memset(&addr, 0, sizeof(addr));
|
||||||
addrlen = (socklen_t)sizeof(addr);
|
addrlen = (socklen_t)sizeof(addr);
|
||||||
|
|
||||||
if(!extstrtoaddr(dtio->ip_str, &addr, &addrlen)) {
|
if(!extstrtoaddr(dtio->ip_str, &addr, &addrlen, UNBOUND_DNS_PORT)) {
|
||||||
log_err("could not parse IP '%s'", dtio->ip_str);
|
log_err("could not parse IP '%s'", dtio->ip_str);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -272,7 +272,7 @@ static int make_tcp_accept(char* ip)
|
|||||||
|
|
||||||
memset(&addr, 0, sizeof(addr));
|
memset(&addr, 0, sizeof(addr));
|
||||||
len = (socklen_t)sizeof(addr);
|
len = (socklen_t)sizeof(addr);
|
||||||
if(!extstrtoaddr(ip, &addr, &len)) {
|
if(!extstrtoaddr(ip, &addr, &len, UNBOUND_DNS_PORT)) {
|
||||||
log_err("could not parse IP '%s'", ip);
|
log_err("could not parse IP '%s'", ip);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -617,7 +617,7 @@ static void log_data_frame(uint8_t* pkt, size_t len)
|
|||||||
static ssize_t receive_bytes(struct tap_data* data, int fd, void* buf,
|
static ssize_t receive_bytes(struct tap_data* data, int fd, void* buf,
|
||||||
size_t len)
|
size_t len)
|
||||||
{
|
{
|
||||||
ssize_t ret = recv(fd, buf, len, 0);
|
ssize_t ret = recv(fd, buf, len, MSG_DONTWAIT);
|
||||||
if(ret == 0) {
|
if(ret == 0) {
|
||||||
/* closed */
|
/* closed */
|
||||||
if(verbosity) log_info("dnstap client stream closed from %s",
|
if(verbosity) log_info("dnstap client stream closed from %s",
|
||||||
|
107
doc/Changelog
107
doc/Changelog
@ -1,9 +1,116 @@
|
|||||||
|
11 October 2022: George
|
||||||
|
- Fix PROXYv2 header read for TCP connections when no proxied addresses
|
||||||
|
are provided.
|
||||||
|
|
||||||
|
7 October 2022: George
|
||||||
|
- Fix to stop possible loops in the tcp reuse code (write_wait list
|
||||||
|
and tcp_wait list). Based on analysis and patch from Prad Seniappan
|
||||||
|
and Karthik Umashankar.
|
||||||
|
- Fix unit test to properly test the reuse_write_wait_pop function.
|
||||||
|
|
||||||
|
6 October 2022: Wouter
|
||||||
|
- Fix to stop responses with TC flag from resulting in partial
|
||||||
|
responses. It retries to fetch the data elsewhere, or fails the
|
||||||
|
query and in depth fix removes the TC flag from the cached item.
|
||||||
|
- Fix proxy length debug output printout typecasts.
|
||||||
|
|
||||||
|
5 October 2022: Wouter
|
||||||
|
- Fix dnscrypt compile for proxy protocol code changes.
|
||||||
|
|
||||||
|
5 October 2022: George
|
||||||
|
- Use DEBUG_TDIR from environment in mini_tdir.sh for debugging.
|
||||||
|
- Fix string comparison in mini_tdir.sh.
|
||||||
|
- Make ede.tdir test more predictable by using static data.
|
||||||
|
- Fix checkconf test for dnscrypt and proxy port.
|
||||||
|
|
||||||
|
4 October 2022: George
|
||||||
|
- Merge #764: Leniency for target discovery when under load (for
|
||||||
|
NRDelegation changes).
|
||||||
|
|
||||||
|
4 October 2022: Wouter
|
||||||
|
- Fix static analysis report to remove dead code from the
|
||||||
|
rpz_callback_from_iterator_module function.
|
||||||
|
- Fix to clean up after the acl_interface unit test.
|
||||||
|
|
||||||
|
3 October 2022: George
|
||||||
|
- Merge #760: PROXYv2 downstream support. (New proxy-protocol-port
|
||||||
|
configuration option).
|
||||||
|
|
||||||
|
3 October 2022: Wouter
|
||||||
|
- Fix to remove erroneous TC flag from TCP upstream.
|
||||||
|
- Fix test tdir skip report printout.
|
||||||
|
- Fix windows compile, the identifier interface is defined in headers.
|
||||||
|
- Fix to close errno block in comm_point_tcp_handle_read outside of
|
||||||
|
ifdef.
|
||||||
|
|
||||||
|
26 September 2022: George
|
||||||
|
- Better output for skipped tdir tests.
|
||||||
|
|
||||||
21 September 2022: Wouter
|
21 September 2022: Wouter
|
||||||
- Patch for CVE-2022-3204 Non-Responsive Delegation Attack.
|
- Patch for CVE-2022-3204 Non-Responsive Delegation Attack.
|
||||||
|
- This patch was released in 1.16.3, the code repository continues
|
||||||
|
with the previous features and fixes for 1.17.0.
|
||||||
|
- Fix doxygen warning in respip.h.
|
||||||
|
|
||||||
|
20 September 2022: George
|
||||||
|
- Convert tdir tests to use the new skip_test functionality.
|
||||||
|
- Remove unused testcode/mini_tpkg.sh file.
|
||||||
|
|
||||||
|
16 September 2022: George
|
||||||
|
- Merge #753: ACL per interface. (New interface-* configuration
|
||||||
|
options).
|
||||||
|
|
||||||
|
2 September 2022: Wouter
|
||||||
|
- Remove include that was there for debug purposes.
|
||||||
|
- Fix to check pthread_t size after pthread has been detected.
|
||||||
|
|
||||||
|
1 September 2022: Wouter
|
||||||
|
- Fix to update config tests to fix checking if nonblocking sockets
|
||||||
|
work on OpenBSD.
|
||||||
|
- Slow down log frequency of write wait failures.
|
||||||
|
- Fix to set out of file descriptor warning to operational verbosity.
|
||||||
|
- Fix to log a verbose message at operational notice level if a
|
||||||
|
thread is not responding, to stats requests. It is logged with
|
||||||
|
thread identifiers.
|
||||||
|
|
||||||
|
31 August 2022: Wouter
|
||||||
|
- Fix to avoid process wide fcntl calls mixed with nonblocking
|
||||||
|
operations after a blocked write.
|
||||||
|
- Patch from Vadim Fedorenko that adds MSG_DONTWAIT to receive
|
||||||
|
operations, so that instruction reordering does not cause mistakenly
|
||||||
|
blocking socket operations.
|
||||||
|
- Fix to wait for blocked write on UDP sockets, with a timeout if it
|
||||||
|
takes too long the packet is dropped.
|
||||||
|
- Fix for wait for udp send to stop when packet is successfully sent.
|
||||||
|
|
||||||
|
22 August 2022: Wouter
|
||||||
|
- Fix #741: systemd socket activation fails on IPv6.
|
||||||
|
|
||||||
|
12 August 2022: Wouter
|
||||||
|
- Fix to log accept error ENFILE and EMFILE errno, but slowly, once
|
||||||
|
per 10 seconds. Also log accept failures when no slow down is used.
|
||||||
|
|
||||||
|
5 August 2022: Wouter
|
||||||
|
- Fix #734 [FR] enable unbound-checkconf to detect more (basic)
|
||||||
|
errors.
|
||||||
|
|
||||||
|
4 August 2022: Wouter
|
||||||
|
- Fix ratelimit inconsistency, for ip-ratelimits the value is the
|
||||||
|
amount allowed, like for ratelimits.
|
||||||
|
|
||||||
|
2 August 2022: Wouter
|
||||||
|
- Fix edns subnet so that scope 0 answers only match sourcemask 0
|
||||||
|
queries for answers from cache if from a query with sourcemask 0.
|
||||||
|
- Fix unittest for edns subnet change.
|
||||||
|
- Merge #730 from luisdallos: Fix startup failure on Windows 8.1 due
|
||||||
|
to unsupported IPV6_USER_MTU socket option being set.
|
||||||
|
|
||||||
1 August 2022: Wouter
|
1 August 2022: Wouter
|
||||||
- Fix the novel ghost domain issues CVE-2022-30698 and CVE-2022-30699.
|
- Fix the novel ghost domain issues CVE-2022-30698 and CVE-2022-30699.
|
||||||
- Tests for ghost domain fixes.
|
- Tests for ghost domain fixes.
|
||||||
|
- Tag for 1.16.2 release. The code repo continues with 1.16.3.
|
||||||
|
- Fix #728: alloc_reg_obtain() core dump. Stop double
|
||||||
|
alloc_reg_release when serviced_create fails.
|
||||||
|
|
||||||
19 July 2022: George
|
19 July 2022: George
|
||||||
- Update documentation for 'outbound-msg-retry:'.
|
- Update documentation for 'outbound-msg-retry:'.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
README for Unbound 1.16.3
|
README for Unbound 1.17.0
|
||||||
Copyright 2007 NLnet Labs
|
Copyright 2007 NLnet Labs
|
||||||
http://unbound.net
|
http://unbound.net
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#
|
#
|
||||||
# Example configuration file.
|
# Example configuration file.
|
||||||
#
|
#
|
||||||
# See unbound.conf(5) man page, version 1.16.3.
|
# See unbound.conf(5) man page, version 1.17.0.
|
||||||
#
|
#
|
||||||
# this is a comment.
|
# this is a comment.
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ server:
|
|||||||
# whitespace is not necessary, but looks cleaner.
|
# whitespace is not necessary, but looks cleaner.
|
||||||
|
|
||||||
# verbosity number, 0 is least verbose. 1 is default.
|
# verbosity number, 0 is least verbose. 1 is default.
|
||||||
verbosity: 1
|
# verbosity: 1
|
||||||
|
|
||||||
# print statistics to the log (for every thread) every N seconds.
|
# print statistics to the log (for every thread) every N seconds.
|
||||||
# Set to "" or 0 to disable. Default is disabled.
|
# Set to "" or 0 to disable. Default is disabled.
|
||||||
@ -50,6 +50,7 @@ server:
|
|||||||
# interface: 192.0.2.154
|
# interface: 192.0.2.154
|
||||||
# interface: 192.0.2.154@5003
|
# interface: 192.0.2.154@5003
|
||||||
# interface: 2001:DB8::5
|
# interface: 2001:DB8::5
|
||||||
|
# interface: eth0@5003
|
||||||
|
|
||||||
# enable this feature to copy the source address of queries to reply.
|
# enable this feature to copy the source address of queries to reply.
|
||||||
# Socket options are not supported on all platforms. experimental.
|
# Socket options are not supported on all platforms. experimental.
|
||||||
@ -217,7 +218,8 @@ server:
|
|||||||
# the maximum number of hosts that are cached (roundtrip, EDNS, lame).
|
# the maximum number of hosts that are cached (roundtrip, EDNS, lame).
|
||||||
# infra-cache-numhosts: 10000
|
# infra-cache-numhosts: 10000
|
||||||
|
|
||||||
# define a number of tags here, use with local-zone, access-control.
|
# define a number of tags here, use with local-zone, access-control,
|
||||||
|
# interface-*.
|
||||||
# repeat the define-tag statement to add additional tags.
|
# repeat the define-tag statement to add additional tags.
|
||||||
# define-tag: "tag1 tag2 tag3"
|
# define-tag: "tag1 tag2 tag3"
|
||||||
|
|
||||||
@ -273,9 +275,7 @@ server:
|
|||||||
# allow_snoop (recursive and nonrecursive ok)
|
# allow_snoop (recursive and nonrecursive ok)
|
||||||
# deny_non_local (drop queries unless can be answered from local-data)
|
# deny_non_local (drop queries unless can be answered from local-data)
|
||||||
# refuse_non_local (like deny_non_local but polite error reply).
|
# refuse_non_local (like deny_non_local but polite error reply).
|
||||||
# access-control: 0.0.0.0/0 refuse
|
|
||||||
# access-control: 127.0.0.0/8 allow
|
# access-control: 127.0.0.0/8 allow
|
||||||
# access-control: ::0/0 refuse
|
|
||||||
# access-control: ::1 allow
|
# access-control: ::1 allow
|
||||||
# access-control: ::ffff:127.0.0.1 allow
|
# access-control: ::ffff:127.0.0.1 allow
|
||||||
|
|
||||||
@ -284,7 +284,7 @@ server:
|
|||||||
# are tagged with one of these tags.
|
# are tagged with one of these tags.
|
||||||
# access-control-tag: 192.0.2.0/24 "tag2 tag3"
|
# access-control-tag: 192.0.2.0/24 "tag2 tag3"
|
||||||
|
|
||||||
# set action for particular tag for given access control element
|
# set action for particular tag for given access control element.
|
||||||
# if you have multiple tag values, the tag used to lookup the action
|
# if you have multiple tag values, the tag used to lookup the action
|
||||||
# is the first tag match between access-control-tag and local-zone-tag
|
# is the first tag match between access-control-tag and local-zone-tag
|
||||||
# where "first" comes from the order of the define-tag values.
|
# where "first" comes from the order of the define-tag values.
|
||||||
@ -296,6 +296,58 @@ server:
|
|||||||
# Set view for access control element
|
# Set view for access control element
|
||||||
# access-control-view: 192.0.2.0/24 viewname
|
# access-control-view: 192.0.2.0/24 viewname
|
||||||
|
|
||||||
|
# Similar to 'access-control:' but for interfaces.
|
||||||
|
# Control which listening interfaces are allowed to accept (recursive)
|
||||||
|
# queries for this server.
|
||||||
|
# The specified interfaces should be the same as the ones specified in
|
||||||
|
# 'interface:' followed by the action.
|
||||||
|
# The actions are the same as 'access-control:' above.
|
||||||
|
# By default all the interfaces configured are refused.
|
||||||
|
# Note: any 'access-control*:' setting overrides all 'interface-*:'
|
||||||
|
# settings for targeted clients.
|
||||||
|
# interface-action: 192.0.2.153 allow
|
||||||
|
# interface-action: 192.0.2.154 allow
|
||||||
|
# interface-action: 192.0.2.154@5003 allow
|
||||||
|
# interface-action: 2001:DB8::5 allow
|
||||||
|
# interface-action: eth0@5003 allow
|
||||||
|
|
||||||
|
# Similar to 'access-control-tag:' but for interfaces.
|
||||||
|
# Tag interfaces with a list of tags (in "" with spaces between).
|
||||||
|
# Interfaces using these tags use localzones that are tagged with one
|
||||||
|
# of these tags.
|
||||||
|
# The specified interfaces should be the same as the ones specified in
|
||||||
|
# 'interface:' followed by the list of tags.
|
||||||
|
# Note: any 'access-control*:' setting overrides all 'interface-*:'
|
||||||
|
# settings for targeted clients.
|
||||||
|
# interface-tag: eth0@5003 "tag2 tag3"
|
||||||
|
|
||||||
|
# Similar to 'access-control-tag-action:' but for interfaces.
|
||||||
|
# Set action for particular tag for a given interface element.
|
||||||
|
# If you have multiple tag values, the tag used to lookup the action
|
||||||
|
# is the first tag match between interface-tag and local-zone-tag
|
||||||
|
# where "first" comes from the order of the define-tag values.
|
||||||
|
# The specified interfaces should be the same as the ones specified in
|
||||||
|
# 'interface:' followed by the tag and action.
|
||||||
|
# Note: any 'access-control*:' setting overrides all 'interface-*:'
|
||||||
|
# settings for targeted clients.
|
||||||
|
# interface-tag-action: eth0@5003 tag3 refuse
|
||||||
|
|
||||||
|
# Similar to 'access-control-tag-data:' but for interfaces.
|
||||||
|
# Set redirect data for a particular tag for an interface element.
|
||||||
|
# The specified interfaces should be the same as the ones specified in
|
||||||
|
# 'interface:' followed by the tag and the redirect data.
|
||||||
|
# Note: any 'access-control*:' setting overrides all 'interface-*:'
|
||||||
|
# settings for targeted clients.
|
||||||
|
# interface-tag-data: eth0@5003 tag2 "A 127.0.0.1"
|
||||||
|
|
||||||
|
# Similar to 'access-control-view:' but for interfaces.
|
||||||
|
# Set view for an interface element.
|
||||||
|
# The specified interfaces should be the same as the ones specified in
|
||||||
|
# 'interface:' followed by the view name.
|
||||||
|
# Note: any 'access-control*:' setting overrides all 'interface-*:'
|
||||||
|
# settings for targeted clients.
|
||||||
|
# interface-view: eth0@5003 viewname
|
||||||
|
|
||||||
# if given, a chroot(2) is done to the given directory.
|
# if given, a chroot(2) is done to the given directory.
|
||||||
# i.e. you can chroot to the working directory, for example,
|
# i.e. you can chroot to the working directory, for example,
|
||||||
# for extra security, but make sure all files are in that directory.
|
# for extra security, but make sure all files are in that directory.
|
||||||
@ -850,6 +902,10 @@ server:
|
|||||||
# Disable TLS for DNS-over-HTTP downstream service.
|
# Disable TLS for DNS-over-HTTP downstream service.
|
||||||
# http-notls-downstream: no
|
# http-notls-downstream: no
|
||||||
|
|
||||||
|
# The interfaces that use these listed port numbers will support and
|
||||||
|
# expect PROXYv2. For UDP and TCP/TLS interfaces.
|
||||||
|
# proxy-protocol-port: portno for each of the port numbers.
|
||||||
|
|
||||||
# DNS64 prefix. Must be specified when DNS64 is use.
|
# DNS64 prefix. Must be specified when DNS64 is use.
|
||||||
# Enable dns64 in module-config. Used to synthesize IPv6 from IPv4.
|
# Enable dns64 in module-config. Used to synthesize IPv6 from IPv4.
|
||||||
# dns64-prefix: 64:ff9b::0/96
|
# dns64-prefix: 64:ff9b::0/96
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
.TH "libunbound" "3" "Sep 21, 2022" "NLnet Labs" "unbound 1.16.3"
|
.TH "libunbound" "3" "Oct 13, 2022" "NLnet Labs" "unbound 1.17.0"
|
||||||
.\"
|
.\"
|
||||||
.\" libunbound.3 -- unbound library functions manual
|
.\" libunbound.3 -- unbound library functions manual
|
||||||
.\"
|
.\"
|
||||||
@ -44,7 +44,7 @@
|
|||||||
.B ub_ctx_zone_remove,
|
.B ub_ctx_zone_remove,
|
||||||
.B ub_ctx_data_add,
|
.B ub_ctx_data_add,
|
||||||
.B ub_ctx_data_remove
|
.B ub_ctx_data_remove
|
||||||
\- Unbound DNS validating resolver 1.16.3 functions.
|
\- Unbound DNS validating resolver 1.17.0 functions.
|
||||||
.SH "SYNOPSIS"
|
.SH "SYNOPSIS"
|
||||||
.B #include <unbound.h>
|
.B #include <unbound.h>
|
||||||
.LP
|
.LP
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
.TH "unbound-anchor" "8" "Sep 21, 2022" "NLnet Labs" "unbound 1.16.3"
|
.TH "unbound-anchor" "8" "Oct 13, 2022" "NLnet Labs" "unbound 1.17.0"
|
||||||
.\"
|
.\"
|
||||||
.\" unbound-anchor.8 -- unbound anchor maintenance utility manual
|
.\" unbound-anchor.8 -- unbound anchor maintenance utility manual
|
||||||
.\"
|
.\"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
.TH "unbound-checkconf" "8" "Sep 21, 2022" "NLnet Labs" "unbound 1.16.3"
|
.TH "unbound-checkconf" "8" "Oct 13, 2022" "NLnet Labs" "unbound 1.17.0"
|
||||||
.\"
|
.\"
|
||||||
.\" unbound-checkconf.8 -- unbound configuration checker manual
|
.\" unbound-checkconf.8 -- unbound configuration checker manual
|
||||||
.\"
|
.\"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
.TH "unbound-control" "8" "Sep 21, 2022" "NLnet Labs" "unbound 1.16.3"
|
.TH "unbound-control" "8" "Oct 13, 2022" "NLnet Labs" "unbound 1.17.0"
|
||||||
.\"
|
.\"
|
||||||
.\" unbound-control.8 -- unbound remote control manual
|
.\" unbound-control.8 -- unbound remote control manual
|
||||||
.\"
|
.\"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
.TH "unbound\-host" "1" "Sep 21, 2022" "NLnet Labs" "unbound 1.16.3"
|
.TH "unbound\-host" "1" "Oct 13, 2022" "NLnet Labs" "unbound 1.17.0"
|
||||||
.\"
|
.\"
|
||||||
.\" unbound-host.1 -- unbound DNS lookup utility
|
.\" unbound-host.1 -- unbound DNS lookup utility
|
||||||
.\"
|
.\"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
.TH "unbound" "8" "Sep 21, 2022" "NLnet Labs" "unbound 1.16.3"
|
.TH "unbound" "8" "Oct 13, 2022" "NLnet Labs" "unbound 1.17.0"
|
||||||
.\"
|
.\"
|
||||||
.\" unbound.8 -- unbound manual
|
.\" unbound.8 -- unbound manual
|
||||||
.\"
|
.\"
|
||||||
@ -9,7 +9,7 @@
|
|||||||
.\"
|
.\"
|
||||||
.SH "NAME"
|
.SH "NAME"
|
||||||
.B unbound
|
.B unbound
|
||||||
\- Unbound DNS validating resolver 1.16.3.
|
\- Unbound DNS validating resolver 1.17.0.
|
||||||
.SH "SYNOPSIS"
|
.SH "SYNOPSIS"
|
||||||
.B unbound
|
.B unbound
|
||||||
.RB [ \-h ]
|
.RB [ \-h ]
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
.TH "unbound.conf" "5" "Sep 21, 2022" "NLnet Labs" "unbound 1.16.3"
|
.TH "unbound.conf" "5" "Oct 13, 2022" "NLnet Labs" "unbound 1.17.0"
|
||||||
.\"
|
.\"
|
||||||
.\" unbound.conf.5 -- unbound.conf manual
|
.\" unbound.conf.5 -- unbound.conf manual
|
||||||
.\"
|
.\"
|
||||||
@ -118,7 +118,7 @@ The number of threads to create to serve clients. Use 1 for no threading.
|
|||||||
.B port: \fI<port number>
|
.B port: \fI<port number>
|
||||||
The port number, default 53, on which the server responds to queries.
|
The port number, default 53, on which the server responds to queries.
|
||||||
.TP
|
.TP
|
||||||
.B interface: \fI<ip address[@port]>
|
.B interface: \fI<ip address or interface name [@port]>
|
||||||
Interface to use to connect to the network. This interface is listened to
|
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.
|
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
|
Can be given multiple times to work on several interfaces. If none are
|
||||||
@ -129,7 +129,7 @@ A port number can be specified with @port (without spaces between
|
|||||||
interface and port number), if not specified the default port (from
|
interface and port number), if not specified the default port (from
|
||||||
\fBport\fR) is used.
|
\fBport\fR) is used.
|
||||||
.TP
|
.TP
|
||||||
.B ip\-address: \fI<ip address[@port]>
|
.B ip\-address: \fI<ip address or interface name [@port]>
|
||||||
Same as interface: (for ease of compatibility with nsd.conf).
|
Same as interface: (for ease of compatibility with nsd.conf).
|
||||||
.TP
|
.TP
|
||||||
.B interface\-automatic: \fI<yes or no>
|
.B interface\-automatic: \fI<yes or no>
|
||||||
@ -656,6 +656,17 @@ Ignored if the option is not available. Default is yes.
|
|||||||
Disable use of TLS for the downstream DNS-over-HTTP connections. Useful for
|
Disable use of TLS for the downstream DNS-over-HTTP connections. Useful for
|
||||||
local back end servers. Default is no.
|
local back end servers. Default is no.
|
||||||
.TP
|
.TP
|
||||||
|
.B proxy\-protocol\-port: \fI<portnr>
|
||||||
|
List port numbers as proxy\-protocol\-port, and when interfaces are defined,
|
||||||
|
eg. with the @port suffix, as this port number, they support and expect PROXYv2.
|
||||||
|
In this case the proxy address will only be used for the network communication
|
||||||
|
and initial ACL (check if the proxy itself is denied/refused by configuration).
|
||||||
|
The proxied address (if any) will then be used as the true client address and
|
||||||
|
will be used where applicable for logging, ACL, DNSTAP, RPZ and IP ratelimiting.
|
||||||
|
PROXYv2 is supported for UDP and TCP/TLS listening interfaces.
|
||||||
|
There is no support for PROXYv2 on a DoH or DNSCrypt listening interface.
|
||||||
|
Can list multiple, each on a new statement.
|
||||||
|
.TP
|
||||||
.B use\-systemd: \fI<yes or no>
|
.B use\-systemd: \fI<yes or no>
|
||||||
Enable or disable systemd socket activation.
|
Enable or disable systemd socket activation.
|
||||||
Default is no.
|
Default is no.
|
||||||
@ -675,7 +686,7 @@ The netblock is given as an IP4 or IP6 address with /size appended for a
|
|||||||
classless network block. The action can be \fIdeny\fR, \fIrefuse\fR,
|
classless network block. The action can be \fIdeny\fR, \fIrefuse\fR,
|
||||||
\fIallow\fR, \fIallow_setrd\fR, \fIallow_snoop\fR, \fIdeny_non_local\fR or
|
\fIallow\fR, \fIallow_setrd\fR, \fIallow_snoop\fR, \fIdeny_non_local\fR or
|
||||||
\fIrefuse_non_local\fR.
|
\fIrefuse_non_local\fR.
|
||||||
The most specific netblock match is used, if none match \fIdeny\fR is used.
|
The most specific netblock match is used, if none match \fIrefuse\fR is used.
|
||||||
The order of the access\-control statements therefore does not matter.
|
The order of the access\-control statements therefore does not matter.
|
||||||
.IP
|
.IP
|
||||||
The action \fIdeny\fR stops queries from hosts from that netblock.
|
The action \fIdeny\fR stops queries from hosts from that netblock.
|
||||||
@ -741,6 +752,46 @@ Set redirect data for particular tag for given access control element.
|
|||||||
.B access\-control\-view: \fI<IP netblock> <view name>
|
.B access\-control\-view: \fI<IP netblock> <view name>
|
||||||
Set view for given access control element.
|
Set view for given access control element.
|
||||||
.TP
|
.TP
|
||||||
|
.B interface\-action: \fI<ip address or interface name [@port]> <action>
|
||||||
|
Similar to \fBaccess\-control:\fR but for interfaces.
|
||||||
|
.IP
|
||||||
|
The action is the same as the ones defined under \fBaccess\-control:\fR.
|
||||||
|
Interfaces are \fIrefuse\fRd by default.
|
||||||
|
By default only localhost (the IP netblock, not the loopback interface) is
|
||||||
|
\fIallow\fRed through the default \fBaccess\-control:\fR behavior.
|
||||||
|
.IP
|
||||||
|
Note that the interface needs to be already specified with \fBinterface:\fR
|
||||||
|
and that any \fBaccess-control*:\fR setting overrides all \fBinterface-*:\fR
|
||||||
|
settings for targeted clients.
|
||||||
|
.TP
|
||||||
|
.B interface\-tag: \fI<ip address or interface name [@port]> <"list of tags">
|
||||||
|
Similar to \fBaccess\-control-tag:\fR but for interfaces.
|
||||||
|
.IP
|
||||||
|
Note that the interface needs to be already specified with \fBinterface:\fR
|
||||||
|
and that any \fBaccess-control*:\fR setting overrides all \fBinterface-*:\fR
|
||||||
|
settings for targeted clients.
|
||||||
|
.TP
|
||||||
|
.B interface\-tag\-action: \fI<ip address or interface name [@port]> <tag> <action>
|
||||||
|
Similar to \fBaccess\-control-tag-action:\fR but for interfaces.
|
||||||
|
.IP
|
||||||
|
Note that the interface needs to be already specified with \fBinterface:\fR
|
||||||
|
and that any \fBaccess-control*:\fR setting overrides all \fBinterface-*:\fR
|
||||||
|
settings for targeted clients.
|
||||||
|
.TP
|
||||||
|
.B interface\-tag\-data: \fI<ip address or interface name [@port]> <tag> <"resource record string">
|
||||||
|
Similar to \fBaccess\-control-tag-data:\fR but for interfaces.
|
||||||
|
.IP
|
||||||
|
Note that the interface needs to be already specified with \fBinterface:\fR
|
||||||
|
and that any \fBaccess-control*:\fR setting overrides all \fBinterface-*:\fR
|
||||||
|
settings for targeted clients.
|
||||||
|
.TP
|
||||||
|
.B interface\-view: \fI<ip address or interface name [@port]> <view name>
|
||||||
|
Similar to \fBaccess\-control-view:\fR but for interfaces.
|
||||||
|
.IP
|
||||||
|
Note that the interface needs to be already specified with \fBinterface:\fR
|
||||||
|
and that any \fBaccess-control*:\fR setting overrides all \fBinterface-*:\fR
|
||||||
|
settings for targeted clients.
|
||||||
|
.TP
|
||||||
.B chroot: \fI<directory>
|
.B chroot: \fI<directory>
|
||||||
If chroot is enabled, you should pass the configfile (from the
|
If chroot is enabled, you should pass the configfile (from the
|
||||||
commandline) as a full path from the original root. After the
|
commandline) as a full path from the original root. After the
|
||||||
@ -1823,9 +1874,11 @@ section for options. To setup the correct self\-signed certificates use the
|
|||||||
The option is used to enable remote control, default is "no".
|
The option is used to enable remote control, default is "no".
|
||||||
If turned off, the server does not listen for control commands.
|
If turned off, the server does not listen for control commands.
|
||||||
.TP 5
|
.TP 5
|
||||||
.B control\-interface: \fI<ip address or path>
|
.B control\-interface: \fI<ip address or interface name or path>
|
||||||
Give IPv4 or IPv6 addresses or local socket path to listen on for
|
Give IPv4 or IPv6 addresses or local socket path to listen on for
|
||||||
control commands.
|
control commands.
|
||||||
|
If an interface name is used instead of an ip address, the list of ip addresses
|
||||||
|
on that interface are used.
|
||||||
By default localhost (127.0.0.1 and ::1) is listened to.
|
By default localhost (127.0.0.1 and ::1) is listened to.
|
||||||
Use 0.0.0.0 and ::0 to listen to all interfaces.
|
Use 0.0.0.0 and ::0 to listen to all interfaces.
|
||||||
If you change this and permissions have been dropped, you must restart
|
If you change this and permissions have been dropped, you must restart
|
||||||
|
@ -97,6 +97,7 @@ node_create(struct addrtree *tree, void *elem, addrlen_t scope,
|
|||||||
tree->node_count++;
|
tree->node_count++;
|
||||||
node->scope = scope;
|
node->scope = scope;
|
||||||
node->ttl = ttl;
|
node->ttl = ttl;
|
||||||
|
node->only_match_scope_zero = 0;
|
||||||
node->edge[0] = NULL;
|
node->edge[0] = NULL;
|
||||||
node->edge[1] = NULL;
|
node->edge[1] = NULL;
|
||||||
node->parent_edge = NULL;
|
node->parent_edge = NULL;
|
||||||
@ -155,6 +156,7 @@ clean_node(struct addrtree *tree, struct addrnode *node)
|
|||||||
if (!node->elem) return;
|
if (!node->elem) return;
|
||||||
tree->size_bytes -= tree->sizefunc(node->elem);
|
tree->size_bytes -= tree->sizefunc(node->elem);
|
||||||
tree->delfunc(tree->env, node->elem);
|
tree->delfunc(tree->env, node->elem);
|
||||||
|
node->only_match_scope_zero = 0;
|
||||||
node->elem = NULL;
|
node->elem = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -358,7 +360,7 @@ issub(const addrkey_t *s1, addrlen_t l1,
|
|||||||
void
|
void
|
||||||
addrtree_insert(struct addrtree *tree, const addrkey_t *addr,
|
addrtree_insert(struct addrtree *tree, const addrkey_t *addr,
|
||||||
addrlen_t sourcemask, addrlen_t scope, void *elem, time_t ttl,
|
addrlen_t sourcemask, addrlen_t scope, void *elem, time_t ttl,
|
||||||
time_t now)
|
time_t now, int only_match_scope_zero)
|
||||||
{
|
{
|
||||||
struct addrnode *newnode, *node;
|
struct addrnode *newnode, *node;
|
||||||
struct addredge *edge;
|
struct addredge *edge;
|
||||||
@ -381,6 +383,7 @@ addrtree_insert(struct addrtree *tree, const addrkey_t *addr,
|
|||||||
/* update this node's scope and data */
|
/* update this node's scope and data */
|
||||||
clean_node(tree, node);
|
clean_node(tree, node);
|
||||||
node->ttl = ttl;
|
node->ttl = ttl;
|
||||||
|
node->only_match_scope_zero = only_match_scope_zero;
|
||||||
node->elem = elem;
|
node->elem = elem;
|
||||||
node->scope = scope;
|
node->scope = scope;
|
||||||
tree->size_bytes += tree->sizefunc(elem);
|
tree->size_bytes += tree->sizefunc(elem);
|
||||||
@ -447,6 +450,7 @@ addrtree_insert(struct addrtree *tree, const addrkey_t *addr,
|
|||||||
newnode->elem = elem;
|
newnode->elem = elem;
|
||||||
newnode->scope = scope;
|
newnode->scope = scope;
|
||||||
newnode->ttl = ttl;
|
newnode->ttl = ttl;
|
||||||
|
newnode->only_match_scope_zero = only_match_scope_zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
tree->size_bytes += node_size(tree, newnode);
|
tree->size_bytes += node_size(tree, newnode);
|
||||||
@ -483,7 +487,8 @@ addrtree_find(struct addrtree *tree, const addrkey_t *addr,
|
|||||||
/* Current node more specific then question. */
|
/* Current node more specific then question. */
|
||||||
log_assert(depth <= sourcemask);
|
log_assert(depth <= sourcemask);
|
||||||
/* does this node have data? if yes, see if we have a match */
|
/* does this node have data? if yes, see if we have a match */
|
||||||
if (node->elem && node->ttl >= now) {
|
if (node->elem && node->ttl >= now &&
|
||||||
|
!(sourcemask != 0 && node->only_match_scope_zero)) {
|
||||||
/* saved at wrong depth */;
|
/* saved at wrong depth */;
|
||||||
log_assert(node->scope >= depth);
|
log_assert(node->scope >= depth);
|
||||||
if (depth == node->scope ||
|
if (depth == node->scope ||
|
||||||
|
@ -95,6 +95,10 @@ struct addrnode {
|
|||||||
time_t ttl;
|
time_t ttl;
|
||||||
/** Number of significant bits in address. */
|
/** Number of significant bits in address. */
|
||||||
addrlen_t scope;
|
addrlen_t scope;
|
||||||
|
/** Only use the element for queries for subnet/0. Set if the query
|
||||||
|
* for /0 was answered with scope 0. For query /x answer scope 0,
|
||||||
|
* they can match anything and this is false. */
|
||||||
|
int only_match_scope_zero;
|
||||||
/** A node can have 0-2 edges, set to NULL for unused */
|
/** A node can have 0-2 edges, set to NULL for unused */
|
||||||
struct addredge *edge[2];
|
struct addredge *edge[2];
|
||||||
/** edge between this node and parent */
|
/** edge between this node and parent */
|
||||||
@ -157,11 +161,12 @@ void addrtree_delete(struct addrtree *tree);
|
|||||||
* @param scope: Number of significant bits in addr.
|
* @param scope: Number of significant bits in addr.
|
||||||
* @param elem: data to store in the tree.
|
* @param elem: data to store in the tree.
|
||||||
* @param ttl: elem is valid up to this time, seconds.
|
* @param ttl: elem is valid up to this time, seconds.
|
||||||
|
* @param only_match_scope_zero: set for when query /0 has scope /0 answer.
|
||||||
* @param now: Current time in seconds.
|
* @param now: Current time in seconds.
|
||||||
*/
|
*/
|
||||||
void addrtree_insert(struct addrtree *tree, const addrkey_t *addr,
|
void addrtree_insert(struct addrtree *tree, const addrkey_t *addr,
|
||||||
addrlen_t sourcemask, addrlen_t scope, void *elem, time_t ttl,
|
addrlen_t sourcemask, addrlen_t scope, void *elem, time_t ttl,
|
||||||
time_t now);
|
time_t now, int only_match_scope_zero);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find a node containing an element in the tree.
|
* Find a node containing an element in the tree.
|
||||||
|
@ -55,6 +55,7 @@
|
|||||||
#include "util/config_file.h"
|
#include "util/config_file.h"
|
||||||
#include "util/data/msgreply.h"
|
#include "util/data/msgreply.h"
|
||||||
#include "sldns/sbuffer.h"
|
#include "sldns/sbuffer.h"
|
||||||
|
#include "sldns/wire2str.h"
|
||||||
#include "iterator/iter_utils.h"
|
#include "iterator/iter_utils.h"
|
||||||
|
|
||||||
/** externally called */
|
/** externally called */
|
||||||
@ -331,6 +332,7 @@ update_cache(struct module_qstate *qstate, int id)
|
|||||||
struct slabhash *subnet_msg_cache = sne->subnet_msg_cache;
|
struct slabhash *subnet_msg_cache = sne->subnet_msg_cache;
|
||||||
struct ecs_data *edns = &sq->ecs_client_in;
|
struct ecs_data *edns = &sq->ecs_client_in;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
int only_match_scope_zero;
|
||||||
|
|
||||||
/* We already calculated hash upon lookup (lookup_and_reply) if we were
|
/* We already calculated hash upon lookup (lookup_and_reply) if we were
|
||||||
* allowed to look in the ECS cache */
|
* allowed to look in the ECS cache */
|
||||||
@ -392,9 +394,12 @@ update_cache(struct module_qstate *qstate, int id)
|
|||||||
reply_info_set_ttls(rep, *qstate->env->now);
|
reply_info_set_ttls(rep, *qstate->env->now);
|
||||||
rep->flags |= (BIT_RA | BIT_QR); /* fix flags to be sensible for */
|
rep->flags |= (BIT_RA | BIT_QR); /* fix flags to be sensible for */
|
||||||
rep->flags &= ~(BIT_AA | BIT_CD);/* a reply based on the cache */
|
rep->flags &= ~(BIT_AA | BIT_CD);/* a reply based on the cache */
|
||||||
|
if(edns->subnet_source_mask == 0 && edns->subnet_scope_mask == 0)
|
||||||
|
only_match_scope_zero = 1;
|
||||||
|
else only_match_scope_zero = 0;
|
||||||
addrtree_insert(tree, (addrkey_t*)edns->subnet_addr,
|
addrtree_insert(tree, (addrkey_t*)edns->subnet_addr,
|
||||||
edns->subnet_source_mask, sq->max_scope, rep,
|
edns->subnet_source_mask, sq->max_scope, rep,
|
||||||
rep->ttl, *qstate->env->now);
|
rep->ttl, *qstate->env->now, only_match_scope_zero);
|
||||||
|
|
||||||
lock_rw_unlock(&lru_entry->lock);
|
lock_rw_unlock(&lru_entry->lock);
|
||||||
if (need_to_insert) {
|
if (need_to_insert) {
|
||||||
@ -674,6 +679,24 @@ ecs_query_response(struct module_qstate* qstate, struct dns_msg* response,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** verbose print edns subnet option in pretty print */
|
||||||
|
static void
|
||||||
|
subnet_log_print(const char* s, struct edns_option* ecs_opt)
|
||||||
|
{
|
||||||
|
if(verbosity >= VERB_ALGO) {
|
||||||
|
char buf[256];
|
||||||
|
char* str = buf;
|
||||||
|
size_t str_len = sizeof(buf);
|
||||||
|
if(!ecs_opt) {
|
||||||
|
verbose(VERB_ALGO, "%s (null)", s);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
(void)sldns_wire2str_edns_subnet_print(&str, &str_len,
|
||||||
|
ecs_opt->opt_data, ecs_opt->opt_len);
|
||||||
|
verbose(VERB_ALGO, "%s %s", s, buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ecs_edns_back_parsed(struct module_qstate* qstate, int id,
|
ecs_edns_back_parsed(struct module_qstate* qstate, int id,
|
||||||
void* ATTR_UNUSED(cbargs))
|
void* ATTR_UNUSED(cbargs))
|
||||||
@ -688,6 +711,7 @@ ecs_edns_back_parsed(struct module_qstate* qstate, int id,
|
|||||||
qstate->env->cfg->client_subnet_opcode)) &&
|
qstate->env->cfg->client_subnet_opcode)) &&
|
||||||
parse_subnet_option(ecs_opt, &sq->ecs_server_in) &&
|
parse_subnet_option(ecs_opt, &sq->ecs_server_in) &&
|
||||||
sq->subnet_sent && sq->ecs_server_in.subnet_validdata) {
|
sq->subnet_sent && sq->ecs_server_in.subnet_validdata) {
|
||||||
|
subnet_log_print("answer has edns subnet", ecs_opt);
|
||||||
/* Only skip global cache store if we sent an ECS option
|
/* Only skip global cache store if we sent an ECS option
|
||||||
* and received one back. Answers from non-whitelisted
|
* and received one back. Answers from non-whitelisted
|
||||||
* servers will end up in global cache. Answers for
|
* servers will end up in global cache. Answers for
|
||||||
@ -736,11 +760,12 @@ subnetmod_operate(struct module_qstate *qstate, enum module_ev event,
|
|||||||
qstate->ext_state[id] = module_finished;
|
qstate->ext_state[id] = module_finished;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
subnet_log_print("query has edns subnet", ecs_opt);
|
||||||
sq->subnet_downstream = 1;
|
sq->subnet_downstream = 1;
|
||||||
}
|
}
|
||||||
else if(qstate->mesh_info->reply_list) {
|
else if(qstate->mesh_info->reply_list) {
|
||||||
subnet_option_from_ss(
|
subnet_option_from_ss(
|
||||||
&qstate->mesh_info->reply_list->query_reply.addr,
|
&qstate->mesh_info->reply_list->query_reply.client_addr,
|
||||||
&sq->ecs_client_in, qstate->env->cfg);
|
&sq->ecs_client_in, qstate->env->cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -775,6 +800,13 @@ subnetmod_operate(struct module_qstate *qstate, enum module_ev event,
|
|||||||
subnet_ecs_opt_list_append(&sq->ecs_client_out,
|
subnet_ecs_opt_list_append(&sq->ecs_client_out,
|
||||||
&qstate->edns_opts_front_out, qstate,
|
&qstate->edns_opts_front_out, qstate,
|
||||||
qstate->region);
|
qstate->region);
|
||||||
|
if(verbosity >= VERB_ALGO) {
|
||||||
|
subnet_log_print("reply has edns subnet",
|
||||||
|
edns_opt_list_find(
|
||||||
|
qstate->edns_opts_front_out,
|
||||||
|
qstate->env->cfg->
|
||||||
|
client_subnet_opcode));
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
lock_rw_unlock(&sne->biglock);
|
lock_rw_unlock(&sne->biglock);
|
||||||
@ -823,6 +855,13 @@ subnetmod_operate(struct module_qstate *qstate, enum module_ev event,
|
|||||||
subnet_ecs_opt_list_append(&sq->ecs_client_out,
|
subnet_ecs_opt_list_append(&sq->ecs_client_out,
|
||||||
&qstate->edns_opts_front_out, qstate,
|
&qstate->edns_opts_front_out, qstate,
|
||||||
qstate->region);
|
qstate->region);
|
||||||
|
if(verbosity >= VERB_ALGO) {
|
||||||
|
subnet_log_print("reply has edns subnet",
|
||||||
|
edns_opt_list_find(
|
||||||
|
qstate->edns_opts_front_out,
|
||||||
|
qstate->env->cfg->
|
||||||
|
client_subnet_opcode));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
qstate->no_cache_store = sq->started_no_cache_store;
|
qstate->no_cache_store = sq->started_no_cache_store;
|
||||||
qstate->no_cache_lookup = sq->started_no_cache_lookup;
|
qstate->no_cache_lookup = sq->started_no_cache_lookup;
|
||||||
|
@ -100,7 +100,7 @@ ah(struct delegpt* dp, const char* sv, const char* ip)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(!delegpt_add_ns_mlc(dp, dname, 0, NULL, UNBOUND_DNS_PORT) ||
|
if(!delegpt_add_ns_mlc(dp, dname, 0, NULL, UNBOUND_DNS_PORT) ||
|
||||||
!extstrtoaddr(ip, &addr, &addrlen) ||
|
!extstrtoaddr(ip, &addr, &addrlen, UNBOUND_DNS_PORT) ||
|
||||||
!delegpt_add_target_mlc(dp, dname, dname_len,
|
!delegpt_add_target_mlc(dp, dname, dname_len,
|
||||||
&addr, addrlen, 0, 0)) {
|
&addr, addrlen, 0, 0)) {
|
||||||
free(dname);
|
free(dname);
|
||||||
|
@ -113,6 +113,10 @@ response_type_from_server(int rdset,
|
|||||||
|
|
||||||
if(!msg || !request)
|
if(!msg || !request)
|
||||||
return RESPONSE_TYPE_THROWAWAY;
|
return RESPONSE_TYPE_THROWAWAY;
|
||||||
|
/* If the TC flag is set, the response is incomplete. Too large to
|
||||||
|
* fit even in TCP or so. Discard it, it cannot be retrieved here. */
|
||||||
|
if((msg->rep->flags & BIT_TC))
|
||||||
|
return RESPONSE_TYPE_THROWAWAY;
|
||||||
|
|
||||||
/* If the message is NXDOMAIN, then it answers the question. */
|
/* If the message is NXDOMAIN, then it answers the question. */
|
||||||
if(FLAGS_GET_RCODE(msg->rep->flags) == LDNS_RCODE_NXDOMAIN) {
|
if(FLAGS_GET_RCODE(msg->rep->flags) == LDNS_RCODE_NXDOMAIN) {
|
||||||
|
@ -255,9 +255,9 @@ error_supers(struct module_qstate* qstate, int id, struct module_qstate* super)
|
|||||||
log_err("out of memory adding missing");
|
log_err("out of memory adding missing");
|
||||||
}
|
}
|
||||||
delegpt_mark_neg(dpns, qstate->qinfo.qtype);
|
delegpt_mark_neg(dpns, qstate->qinfo.qtype);
|
||||||
dpns->resolved = 1; /* mark as failed */
|
|
||||||
if((dpns->got4 == 2 || !ie->supports_ipv4) &&
|
if((dpns->got4 == 2 || !ie->supports_ipv4) &&
|
||||||
(dpns->got6 == 2 || !ie->supports_ipv6)) {
|
(dpns->got6 == 2 || !ie->supports_ipv6)) {
|
||||||
|
dpns->resolved = 1; /* mark as failed */
|
||||||
target_count_increase_nx(super_iq, 1);
|
target_count_increase_nx(super_iq, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -596,15 +596,17 @@ errinf_reply(struct module_qstate* qstate, struct iter_qstate* iq)
|
|||||||
{
|
{
|
||||||
if(qstate->env->cfg->val_log_level < 2 && !qstate->env->cfg->log_servfail)
|
if(qstate->env->cfg->val_log_level < 2 && !qstate->env->cfg->log_servfail)
|
||||||
return;
|
return;
|
||||||
if((qstate->reply && qstate->reply->addrlen != 0) ||
|
if((qstate->reply && qstate->reply->remote_addrlen != 0) ||
|
||||||
(iq->fail_reply && iq->fail_reply->addrlen != 0)) {
|
(iq->fail_reply && iq->fail_reply->remote_addrlen != 0)) {
|
||||||
char from[256], frm[512];
|
char from[256], frm[512];
|
||||||
if(qstate->reply && qstate->reply->addrlen != 0)
|
if(qstate->reply && qstate->reply->remote_addrlen != 0)
|
||||||
addr_to_str(&qstate->reply->addr, qstate->reply->addrlen,
|
addr_to_str(&qstate->reply->remote_addr,
|
||||||
from, sizeof(from));
|
qstate->reply->remote_addrlen, from,
|
||||||
|
sizeof(from));
|
||||||
else
|
else
|
||||||
addr_to_str(&iq->fail_reply->addr, iq->fail_reply->addrlen,
|
addr_to_str(&iq->fail_reply->remote_addr,
|
||||||
from, sizeof(from));
|
iq->fail_reply->remote_addrlen, from,
|
||||||
|
sizeof(from));
|
||||||
snprintf(frm, sizeof(frm), "from %s", from);
|
snprintf(frm, sizeof(frm), "from %s", from);
|
||||||
errinf(qstate, frm);
|
errinf(qstate, frm);
|
||||||
}
|
}
|
||||||
@ -2262,6 +2264,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||||||
size_t qout_orig_len = 0;
|
size_t qout_orig_len = 0;
|
||||||
int sq_check_ratelimit = 1;
|
int sq_check_ratelimit = 1;
|
||||||
int sq_was_ratelimited = 0;
|
int sq_was_ratelimited = 0;
|
||||||
|
int can_do_promisc = 0;
|
||||||
|
|
||||||
/* NOTE: a request will encounter this state for each target it
|
/* NOTE: a request will encounter this state for each target it
|
||||||
* needs to send a query to. That is, at least one per referral,
|
* needs to send a query to. That is, at least one per referral,
|
||||||
@ -2589,12 +2592,12 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||||||
if(iq->depth < ie->max_dependency_depth
|
if(iq->depth < ie->max_dependency_depth
|
||||||
&& iq->num_target_queries == 0
|
&& iq->num_target_queries == 0
|
||||||
&& (!iq->target_count || iq->target_count[TARGET_COUNT_NX]==0)
|
&& (!iq->target_count || iq->target_count[TARGET_COUNT_NX]==0)
|
||||||
&& iq->sent_count < TARGET_FETCH_STOP
|
&& iq->sent_count < TARGET_FETCH_STOP) {
|
||||||
/* if the mesh query list is full, then do not waste cpu
|
can_do_promisc = 1;
|
||||||
* and sockets to fetch promiscuous targets. They can be
|
}
|
||||||
* looked up when needed. */
|
/* if the mesh query list is full, then do not waste cpu and sockets to
|
||||||
&& !mesh_jostle_exceeded(qstate->env->mesh)
|
* fetch promiscuous targets. They can be looked up when needed. */
|
||||||
) {
|
if(can_do_promisc && !mesh_jostle_exceeded(qstate->env->mesh)) {
|
||||||
tf_policy = ie->target_fetch_policy[iq->depth];
|
tf_policy = ie->target_fetch_policy[iq->depth];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2766,6 +2769,37 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We have a target. We could have created promiscuous target
|
||||||
|
* queries but we are currently under pressure (mesh_jostle_exceeded).
|
||||||
|
* If we are configured to allow promiscuous target queries and haven't
|
||||||
|
* gone out to the network for a target query for this delegation, then
|
||||||
|
* it is possible to slip in a promiscuous one with a 1/10 chance. */
|
||||||
|
if(can_do_promisc && tf_policy == 0 && iq->depth == 0
|
||||||
|
&& iq->depth < ie->max_dependency_depth
|
||||||
|
&& ie->target_fetch_policy[iq->depth] != 0
|
||||||
|
&& iq->dp_target_count == 0
|
||||||
|
&& !ub_random_max(qstate->env->rnd, 10)) {
|
||||||
|
int extra = 0;
|
||||||
|
verbose(VERB_ALGO, "available target exists in cache but "
|
||||||
|
"attempt to get extra 1 target");
|
||||||
|
(void)query_for_targets(qstate, iq, ie, id, 1, &extra);
|
||||||
|
/* errors ignored, these targets are not strictly necessary for
|
||||||
|
* this result, we do not have to reply with SERVFAIL */
|
||||||
|
if(extra > 0) {
|
||||||
|
iq->num_target_queries += extra;
|
||||||
|
target_count_increase(iq, extra);
|
||||||
|
check_waiting_queries(iq, qstate, id);
|
||||||
|
/* undo qname minimise step because we'll get back here
|
||||||
|
* to do it again */
|
||||||
|
if(qout_orig && iq->minimise_count > 0) {
|
||||||
|
iq->minimise_count--;
|
||||||
|
iq->qinfo_out.qname = qout_orig;
|
||||||
|
iq->qinfo_out.qname_len = qout_orig_len;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Do not check ratelimit for forwarding queries or if we already got a
|
/* Do not check ratelimit for forwarding queries or if we already got a
|
||||||
* pass. */
|
* pass. */
|
||||||
sq_check_ratelimit = (!(iq->chase_flags & BIT_RD) && !iq->ratelimit_ok);
|
sq_check_ratelimit = (!(iq->chase_flags & BIT_RD) && !iq->ratelimit_ok);
|
||||||
@ -2873,6 +2907,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||||||
(int)((iq->chase_flags&BIT_RD) || iq->chase_to_rd),
|
(int)((iq->chase_flags&BIT_RD) || iq->chase_to_rd),
|
||||||
iq->response, &iq->qinfo_out, iq->dp);
|
iq->response, &iq->qinfo_out, iq->dp);
|
||||||
iq->chase_to_rd = 0;
|
iq->chase_to_rd = 0;
|
||||||
|
/* remove TC flag, if this is erroneously set by TCP upstream */
|
||||||
|
iq->response->rep->flags &= ~BIT_TC;
|
||||||
if(type == RESPONSE_TYPE_REFERRAL && (iq->chase_flags&BIT_RD) &&
|
if(type == RESPONSE_TYPE_REFERRAL && (iq->chase_flags&BIT_RD) &&
|
||||||
!iq->auth_zone_response) {
|
!iq->auth_zone_response) {
|
||||||
/* When forwarding (RD bit is set), we handle referrals
|
/* When forwarding (RD bit is set), we handle referrals
|
||||||
@ -2896,8 +2932,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||||||
* use dnssec-lame-bypass if it needs to query there.*/
|
* use dnssec-lame-bypass if it needs to query there.*/
|
||||||
if(qstate->reply) {
|
if(qstate->reply) {
|
||||||
struct delegpt_addr* a = delegpt_find_addr(
|
struct delegpt_addr* a = delegpt_find_addr(
|
||||||
iq->dp, &qstate->reply->addr,
|
iq->dp, &qstate->reply->remote_addr,
|
||||||
qstate->reply->addrlen);
|
qstate->reply->remote_addrlen);
|
||||||
if(a) a->dnsseclame = 1;
|
if(a) a->dnsseclame = 1;
|
||||||
}
|
}
|
||||||
/* test the answer is from the zone we expected,
|
/* test the answer is from the zone we expected,
|
||||||
@ -2994,8 +3030,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||||||
iq->num_target_queries = 0;
|
iq->num_target_queries = 0;
|
||||||
if(qstate->reply)
|
if(qstate->reply)
|
||||||
sock_list_insert(&qstate->reply_origin,
|
sock_list_insert(&qstate->reply_origin,
|
||||||
&qstate->reply->addr, qstate->reply->addrlen,
|
&qstate->reply->remote_addr,
|
||||||
qstate->region);
|
qstate->reply->remote_addrlen, qstate->region);
|
||||||
if(iq->minimisation_state != DONOT_MINIMISE_STATE
|
if(iq->minimisation_state != DONOT_MINIMISE_STATE
|
||||||
&& !(iq->chase_flags & BIT_RD)) {
|
&& !(iq->chase_flags & BIT_RD)) {
|
||||||
if(FLAGS_GET_RCODE(iq->response->rep->flags) !=
|
if(FLAGS_GET_RCODE(iq->response->rep->flags) !=
|
||||||
@ -3251,8 +3287,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||||||
iq->num_target_queries = 0;
|
iq->num_target_queries = 0;
|
||||||
if(qstate->reply)
|
if(qstate->reply)
|
||||||
sock_list_insert(&qstate->reply_origin,
|
sock_list_insert(&qstate->reply_origin,
|
||||||
&qstate->reply->addr, qstate->reply->addrlen,
|
&qstate->reply->remote_addr,
|
||||||
qstate->region);
|
qstate->reply->remote_addrlen, qstate->region);
|
||||||
verbose(VERB_ALGO, "cleared outbound list for query restart");
|
verbose(VERB_ALGO, "cleared outbound list for query restart");
|
||||||
/* go to INIT_REQUEST_STATE for new qname. */
|
/* go to INIT_REQUEST_STATE for new qname. */
|
||||||
return next_state(iq, INIT_REQUEST_STATE);
|
return next_state(iq, INIT_REQUEST_STATE);
|
||||||
@ -3267,7 +3303,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||||||
/* need addr for lameness cache, but we may have
|
/* need addr for lameness cache, but we may have
|
||||||
* gotten this from cache, so test to be sure */
|
* gotten this from cache, so test to be sure */
|
||||||
if(!infra_set_lame(qstate->env->infra_cache,
|
if(!infra_set_lame(qstate->env->infra_cache,
|
||||||
&qstate->reply->addr, qstate->reply->addrlen,
|
&qstate->reply->remote_addr,
|
||||||
|
qstate->reply->remote_addrlen,
|
||||||
iq->dp->name, iq->dp->namelen,
|
iq->dp->name, iq->dp->namelen,
|
||||||
*qstate->env->now, dnsseclame, 0,
|
*qstate->env->now, dnsseclame, 0,
|
||||||
iq->qchase.qtype))
|
iq->qchase.qtype))
|
||||||
@ -3285,7 +3322,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||||||
* gotten this from cache, so test to be sure */
|
* gotten this from cache, so test to be sure */
|
||||||
verbose(VERB_DETAIL, "mark as REC_LAME");
|
verbose(VERB_DETAIL, "mark as REC_LAME");
|
||||||
if(!infra_set_lame(qstate->env->infra_cache,
|
if(!infra_set_lame(qstate->env->infra_cache,
|
||||||
&qstate->reply->addr, qstate->reply->addrlen,
|
&qstate->reply->remote_addr,
|
||||||
|
qstate->reply->remote_addrlen,
|
||||||
iq->dp->name, iq->dp->namelen,
|
iq->dp->name, iq->dp->namelen,
|
||||||
*qstate->env->now, 0, 1, iq->qchase.qtype))
|
*qstate->env->now, 0, 1, iq->qchase.qtype))
|
||||||
log_err("mark host lame: out of memory");
|
log_err("mark host lame: out of memory");
|
||||||
@ -3527,14 +3565,15 @@ processTargetResponse(struct module_qstate* qstate, int id,
|
|||||||
} else {
|
} else {
|
||||||
verbose(VERB_ALGO, "iterator TargetResponse failed");
|
verbose(VERB_ALGO, "iterator TargetResponse failed");
|
||||||
delegpt_mark_neg(dpns, qstate->qinfo.qtype);
|
delegpt_mark_neg(dpns, qstate->qinfo.qtype);
|
||||||
dpns->resolved = 1; /* fail the target */
|
|
||||||
if((dpns->got4 == 2 || !ie->supports_ipv4) &&
|
if((dpns->got4 == 2 || !ie->supports_ipv4) &&
|
||||||
(dpns->got6 == 2 || !ie->supports_ipv6) &&
|
(dpns->got6 == 2 || !ie->supports_ipv6)) {
|
||||||
|
dpns->resolved = 1; /* fail the target */
|
||||||
/* do not count cached answers */
|
/* do not count cached answers */
|
||||||
(qstate->reply_origin && qstate->reply_origin->len != 0)) {
|
if(qstate->reply_origin && qstate->reply_origin->len != 0) {
|
||||||
target_count_increase_nx(foriq, 1);
|
target_count_increase_nx(foriq, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -4015,7 +4054,7 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
|
|||||||
goto handle_it;
|
goto handle_it;
|
||||||
log_query_info(VERB_DETAIL, "response for", &qstate->qinfo);
|
log_query_info(VERB_DETAIL, "response for", &qstate->qinfo);
|
||||||
log_name_addr(VERB_DETAIL, "reply from", iq->dp->name,
|
log_name_addr(VERB_DETAIL, "reply from", iq->dp->name,
|
||||||
&qstate->reply->addr, qstate->reply->addrlen);
|
&qstate->reply->remote_addr, qstate->reply->remote_addrlen);
|
||||||
if(verbosity >= VERB_ALGO)
|
if(verbosity >= VERB_ALGO)
|
||||||
log_dns_msg("incoming scrubbed packet:", &iq->response->qinfo,
|
log_dns_msg("incoming scrubbed packet:", &iq->response->qinfo,
|
||||||
iq->response->rep);
|
iq->response->rep);
|
||||||
|
@ -324,7 +324,7 @@ struct iter_qstate {
|
|||||||
/** the number of times this query has been restarted. */
|
/** the number of times this query has been restarted. */
|
||||||
int query_restart_count;
|
int query_restart_count;
|
||||||
|
|
||||||
/** the number of times this query as followed a referral. */
|
/** the number of times this query has followed a referral. */
|
||||||
int referral_count;
|
int referral_count;
|
||||||
|
|
||||||
/** number of queries fired off */
|
/** number of queries fired off */
|
||||||
|
@ -951,7 +951,7 @@ ub_ctx_set_fwd(struct ub_ctx* ctx, const char* addr)
|
|||||||
lock_basic_unlock(&ctx->cfglock);
|
lock_basic_unlock(&ctx->cfglock);
|
||||||
|
|
||||||
/* check syntax for addr */
|
/* check syntax for addr */
|
||||||
if(!extstrtoaddr(addr, &storage, &stlen)) {
|
if(!extstrtoaddr(addr, &storage, &stlen, UNBOUND_DNS_PORT)) {
|
||||||
errno=EINVAL;
|
errno=EINVAL;
|
||||||
return UB_SYNTAX;
|
return UB_SYNTAX;
|
||||||
}
|
}
|
||||||
@ -1031,7 +1031,7 @@ int ub_ctx_set_stub(struct ub_ctx* ctx, const char* zone, const char* addr,
|
|||||||
if(addr) {
|
if(addr) {
|
||||||
struct sockaddr_storage storage;
|
struct sockaddr_storage storage;
|
||||||
socklen_t stlen;
|
socklen_t stlen;
|
||||||
if(!extstrtoaddr(addr, &storage, &stlen)) {
|
if(!extstrtoaddr(addr, &storage, &stlen, UNBOUND_DNS_PORT)) {
|
||||||
errno=EINVAL;
|
errno=EINVAL;
|
||||||
return UB_SYNTAX;
|
return UB_SYNTAX;
|
||||||
}
|
}
|
||||||
|
@ -609,9 +609,9 @@ struct mesh_reply {
|
|||||||
struct comm_reply query_reply;
|
struct comm_reply query_reply;
|
||||||
};
|
};
|
||||||
|
|
||||||
%rename(_addr) comm_reply::addr;
|
%rename(_addr) comm_reply::client_addr;
|
||||||
struct comm_reply {
|
struct comm_reply {
|
||||||
struct sockaddr_storage addr;
|
struct sockaddr_storage client_addr;
|
||||||
};
|
};
|
||||||
|
|
||||||
%extend comm_reply {
|
%extend comm_reply {
|
||||||
|
@ -172,14 +172,14 @@ int createResponse(struct module_qstate* qstate, sldns_buffer* pkt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Convert reply->addr to string */
|
/* Convert reply->client_addr to string */
|
||||||
void reply_addr2str(struct comm_reply* reply, char* dest, int maxlen)
|
void reply_addr2str(struct comm_reply* reply, char* dest, int maxlen)
|
||||||
{
|
{
|
||||||
int af = (int)((struct sockaddr_in*) &(reply->addr))->sin_family;
|
int af = (int)((struct sockaddr_in*) &(reply->client_addr))->sin_family;
|
||||||
void* sinaddr = &((struct sockaddr_in*) &(reply->addr))->sin_addr;
|
void* sinaddr = &((struct sockaddr_in*) &(reply->client_addr))->sin_addr;
|
||||||
|
|
||||||
if(af == AF_INET6)
|
if(af == AF_INET6)
|
||||||
sinaddr = &((struct sockaddr_in6*)&(reply->addr))->sin6_addr;
|
sinaddr = &((struct sockaddr_in6*)&(reply->client_addr))->sin6_addr;
|
||||||
dest[0] = 0;
|
dest[0] = 0;
|
||||||
if (inet_ntop(af, sinaddr, dest, (socklen_t)maxlen) == 0)
|
if (inet_ntop(af, sinaddr, dest, (socklen_t)maxlen) == 0)
|
||||||
return;
|
return;
|
||||||
|
@ -1290,7 +1290,7 @@ respip_set_is_empty(const struct respip_set* set)
|
|||||||
void
|
void
|
||||||
respip_inform_print(struct respip_action_info* respip_actinfo, uint8_t* qname,
|
respip_inform_print(struct respip_action_info* respip_actinfo, uint8_t* qname,
|
||||||
uint16_t qtype, uint16_t qclass, struct local_rrset* local_alias,
|
uint16_t qtype, uint16_t qclass, struct local_rrset* local_alias,
|
||||||
struct comm_reply* repinfo)
|
struct sockaddr_storage* addr, socklen_t addrlen)
|
||||||
{
|
{
|
||||||
char srcip[128], respip[128], txt[512];
|
char srcip[128], respip[128], txt[512];
|
||||||
unsigned port;
|
unsigned port;
|
||||||
@ -1300,10 +1300,10 @@ respip_inform_print(struct respip_action_info* respip_actinfo, uint8_t* qname,
|
|||||||
|
|
||||||
if(local_alias)
|
if(local_alias)
|
||||||
qname = local_alias->rrset->rk.dname;
|
qname = local_alias->rrset->rk.dname;
|
||||||
port = (unsigned)((repinfo->addr.ss_family == AF_INET) ?
|
port = (unsigned)((addr->ss_family == AF_INET) ?
|
||||||
ntohs(((struct sockaddr_in*)&repinfo->addr)->sin_port) :
|
ntohs(((struct sockaddr_in*)addr)->sin_port) :
|
||||||
ntohs(((struct sockaddr_in6*)&repinfo->addr)->sin6_port));
|
ntohs(((struct sockaddr_in6*)addr)->sin6_port));
|
||||||
addr_to_str(&repinfo->addr, repinfo->addrlen, srcip, sizeof(srcip));
|
addr_to_str(addr, addrlen, srcip, sizeof(srcip));
|
||||||
addr_to_str(&respip_addr->addr, respip_addr->addrlen,
|
addr_to_str(&respip_addr->addr, respip_addr->addrlen,
|
||||||
respip, sizeof(respip));
|
respip, sizeof(respip));
|
||||||
if(respip_actinfo->rpz_log) {
|
if(respip_actinfo->rpz_log) {
|
||||||
|
@ -251,11 +251,13 @@ int respip_set_is_empty(const struct respip_set* set);
|
|||||||
* @param local_alias: set to a local alias if the query matches an alias in
|
* @param local_alias: set to a local alias if the query matches an alias in
|
||||||
* a local zone. In this case its owner name will be considered the actual
|
* a local zone. In this case its owner name will be considered the actual
|
||||||
* query name.
|
* query name.
|
||||||
* @param repinfo: reply info containing the client's source address and port.
|
* @param addr: the client's source address and port.
|
||||||
|
* @param addrlen: the client's source address length.
|
||||||
*/
|
*/
|
||||||
void respip_inform_print(struct respip_action_info* respip_actinfo,
|
void respip_inform_print(struct respip_action_info* respip_actinfo,
|
||||||
uint8_t* qname, uint16_t qtype, uint16_t qclass,
|
uint8_t* qname, uint16_t qtype, uint16_t qclass,
|
||||||
struct local_rrset* local_alias, struct comm_reply* repinfo);
|
struct local_rrset* local_alias, struct sockaddr_storage* addr,
|
||||||
|
socklen_t addrlen);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find resp_addr in tree, create and add to tree if it does not exist.
|
* Find resp_addr in tree, create and add to tree if it does not exist.
|
||||||
|
@ -3699,7 +3699,7 @@ addr_matches_master(struct auth_master* master, struct sockaddr_storage* addr,
|
|||||||
/* compare address (but not port number, that is the destination
|
/* compare address (but not port number, that is the destination
|
||||||
* port of the master, the port number of the received notify is
|
* port of the master, the port number of the received notify is
|
||||||
* allowed to by any port on that master) */
|
* allowed to by any port on that master) */
|
||||||
if(extstrtoaddr(master->host, &a, &alen) &&
|
if(extstrtoaddr(master->host, &a, &alen, UNBOUND_DNS_PORT) &&
|
||||||
sockaddr_cmp_addr(addr, addrlen, &a, alen)==0) {
|
sockaddr_cmp_addr(addr, addrlen, &a, alen)==0) {
|
||||||
*fromhost = master;
|
*fromhost = master;
|
||||||
return 1;
|
return 1;
|
||||||
@ -5381,7 +5381,7 @@ xfr_transfer_lookup_host(struct auth_xfer* xfr, struct module_env* env)
|
|||||||
struct edns_data edns;
|
struct edns_data edns;
|
||||||
sldns_buffer* buf = env->scratch_buffer;
|
sldns_buffer* buf = env->scratch_buffer;
|
||||||
if(!master) return 0;
|
if(!master) return 0;
|
||||||
if(extstrtoaddr(master->host, &addr, &addrlen)) {
|
if(extstrtoaddr(master->host, &addr, &addrlen, UNBOUND_DNS_PORT)) {
|
||||||
/* not needed, host is in IP addr format */
|
/* not needed, host is in IP addr format */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -6572,7 +6572,7 @@ xfr_probe_lookup_host(struct auth_xfer* xfr, struct module_env* env)
|
|||||||
struct edns_data edns;
|
struct edns_data edns;
|
||||||
sldns_buffer* buf = env->scratch_buffer;
|
sldns_buffer* buf = env->scratch_buffer;
|
||||||
if(!master) return 0;
|
if(!master) return 0;
|
||||||
if(extstrtoaddr(master->host, &addr, &addrlen)) {
|
if(extstrtoaddr(master->host, &addr, &addrlen, UNBOUND_DNS_PORT)) {
|
||||||
/* not needed, host is in IP addr format */
|
/* not needed, host is in IP addr format */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
37
services/cache/infra.c
vendored
37
services/cache/infra.c
vendored
@ -834,14 +834,13 @@ static struct lruhash_entry* infra_find_ratedata(struct infra_cache* infra,
|
|||||||
|
|
||||||
/** find data item in array for ip addresses */
|
/** find data item in array for ip addresses */
|
||||||
static struct lruhash_entry* infra_find_ip_ratedata(struct infra_cache* infra,
|
static struct lruhash_entry* infra_find_ip_ratedata(struct infra_cache* infra,
|
||||||
struct comm_reply* repinfo, int wr)
|
struct sockaddr_storage* addr, socklen_t addrlen, int wr)
|
||||||
{
|
{
|
||||||
struct ip_rate_key key;
|
struct ip_rate_key key;
|
||||||
hashvalue_type h = hash_addr(&(repinfo->addr),
|
hashvalue_type h = hash_addr(addr, addrlen, 0);
|
||||||
repinfo->addrlen, 0);
|
|
||||||
memset(&key, 0, sizeof(key));
|
memset(&key, 0, sizeof(key));
|
||||||
key.addr = repinfo->addr;
|
key.addr = *addr;
|
||||||
key.addrlen = repinfo->addrlen;
|
key.addrlen = addrlen;
|
||||||
key.entry.hash = h;
|
key.entry.hash = h;
|
||||||
return slabhash_lookup(infra->client_ip_rates, h, &key, wr);
|
return slabhash_lookup(infra->client_ip_rates, h, &key, wr);
|
||||||
}
|
}
|
||||||
@ -876,10 +875,9 @@ static void infra_create_ratedata(struct infra_cache* infra,
|
|||||||
|
|
||||||
/** create rate data item for ip address */
|
/** create rate data item for ip address */
|
||||||
static void infra_ip_create_ratedata(struct infra_cache* infra,
|
static void infra_ip_create_ratedata(struct infra_cache* infra,
|
||||||
struct comm_reply* repinfo, time_t timenow)
|
struct sockaddr_storage* addr, socklen_t addrlen, time_t timenow)
|
||||||
{
|
{
|
||||||
hashvalue_type h = hash_addr(&(repinfo->addr),
|
hashvalue_type h = hash_addr(addr, addrlen, 0);
|
||||||
repinfo->addrlen, 0);
|
|
||||||
struct ip_rate_key* k = (struct ip_rate_key*)calloc(1, sizeof(*k));
|
struct ip_rate_key* k = (struct ip_rate_key*)calloc(1, sizeof(*k));
|
||||||
struct ip_rate_data* d = (struct ip_rate_data*)calloc(1, sizeof(*d));
|
struct ip_rate_data* d = (struct ip_rate_data*)calloc(1, sizeof(*d));
|
||||||
if(!k || !d) {
|
if(!k || !d) {
|
||||||
@ -887,8 +885,8 @@ static void infra_ip_create_ratedata(struct infra_cache* infra,
|
|||||||
free(d);
|
free(d);
|
||||||
return; /* alloc failure */
|
return; /* alloc failure */
|
||||||
}
|
}
|
||||||
k->addr = repinfo->addr;
|
k->addr = *addr;
|
||||||
k->addrlen = repinfo->addrlen;
|
k->addrlen = addrlen;
|
||||||
lock_rw_init(&k->entry.lock);
|
lock_rw_init(&k->entry.lock);
|
||||||
k->entry.hash = h;
|
k->entry.hash = h;
|
||||||
k->entry.key = k;
|
k->entry.key = k;
|
||||||
@ -985,8 +983,8 @@ int infra_ratelimit_inc(struct infra_cache* infra, uint8_t* name,
|
|||||||
sldns_wire2str_class_buf(qinfo->qclass, cs, sizeof(cs));
|
sldns_wire2str_class_buf(qinfo->qclass, cs, sizeof(cs));
|
||||||
ip[0]=0;
|
ip[0]=0;
|
||||||
if(replylist) {
|
if(replylist) {
|
||||||
addr_to_str((struct sockaddr_storage *)&replylist->addr,
|
addr_to_str((struct sockaddr_storage *)&replylist->remote_addr,
|
||||||
replylist->addrlen, ip, sizeof(ip));
|
replylist->remote_addrlen, ip, sizeof(ip));
|
||||||
verbose(VERB_OPS, "ratelimit exceeded %s %d query %s %s %s from %s", buf, lim, qnm, cs, ts, ip);
|
verbose(VERB_OPS, "ratelimit exceeded %s %d query %s %s %s from %s", buf, lim, qnm, cs, ts, ip);
|
||||||
} else {
|
} else {
|
||||||
verbose(VERB_OPS, "ratelimit exceeded %s %d query %s %s %s", buf, lim, qnm, cs, ts);
|
verbose(VERB_OPS, "ratelimit exceeded %s %d query %s %s %s", buf, lim, qnm, cs, ts);
|
||||||
@ -1040,7 +1038,7 @@ int infra_ratelimit_exceeded(struct infra_cache* infra, uint8_t* name,
|
|||||||
max = infra_rate_max(entry->data, timenow, backoff);
|
max = infra_rate_max(entry->data, timenow, backoff);
|
||||||
lock_rw_unlock(&entry->lock);
|
lock_rw_unlock(&entry->lock);
|
||||||
|
|
||||||
return (max >= lim);
|
return (max > lim);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
@ -1054,8 +1052,8 @@ infra_get_mem(struct infra_cache* infra)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int infra_ip_ratelimit_inc(struct infra_cache* infra,
|
int infra_ip_ratelimit_inc(struct infra_cache* infra,
|
||||||
struct comm_reply* repinfo, time_t timenow, int backoff,
|
struct sockaddr_storage* addr, socklen_t addrlen, time_t timenow,
|
||||||
struct sldns_buffer* buffer)
|
int backoff, struct sldns_buffer* buffer)
|
||||||
{
|
{
|
||||||
int max;
|
int max;
|
||||||
struct lruhash_entry* entry;
|
struct lruhash_entry* entry;
|
||||||
@ -1065,7 +1063,7 @@ int infra_ip_ratelimit_inc(struct infra_cache* infra,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
/* find or insert ratedata */
|
/* find or insert ratedata */
|
||||||
entry = infra_find_ip_ratedata(infra, repinfo, 1);
|
entry = infra_find_ip_ratedata(infra, addr, addrlen, 1);
|
||||||
if(entry) {
|
if(entry) {
|
||||||
int premax = infra_rate_max(entry->data, timenow, backoff);
|
int premax = infra_rate_max(entry->data, timenow, backoff);
|
||||||
int* cur = infra_rate_give_second(entry->data, timenow);
|
int* cur = infra_rate_give_second(entry->data, timenow);
|
||||||
@ -1073,10 +1071,9 @@ int infra_ip_ratelimit_inc(struct infra_cache* infra,
|
|||||||
max = infra_rate_max(entry->data, timenow, backoff);
|
max = infra_rate_max(entry->data, timenow, backoff);
|
||||||
lock_rw_unlock(&entry->lock);
|
lock_rw_unlock(&entry->lock);
|
||||||
|
|
||||||
if(premax < infra_ip_ratelimit && max >= infra_ip_ratelimit) {
|
if(premax <= infra_ip_ratelimit && max > infra_ip_ratelimit) {
|
||||||
char client_ip[128], qnm[LDNS_MAX_DOMAINLEN+1+12+12];
|
char client_ip[128], qnm[LDNS_MAX_DOMAINLEN+1+12+12];
|
||||||
addr_to_str((struct sockaddr_storage *)&repinfo->addr,
|
addr_to_str(addr, addrlen, client_ip, sizeof(client_ip));
|
||||||
repinfo->addrlen, client_ip, sizeof(client_ip));
|
|
||||||
qnm[0]=0;
|
qnm[0]=0;
|
||||||
if(sldns_buffer_limit(buffer)>LDNS_HEADER_SIZE &&
|
if(sldns_buffer_limit(buffer)>LDNS_HEADER_SIZE &&
|
||||||
LDNS_QDCOUNT(sldns_buffer_begin(buffer))!=0) {
|
LDNS_QDCOUNT(sldns_buffer_begin(buffer))!=0) {
|
||||||
@ -1101,6 +1098,6 @@ int infra_ip_ratelimit_inc(struct infra_cache* infra,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* create */
|
/* create */
|
||||||
infra_ip_create_ratedata(infra, repinfo, timenow);
|
infra_ip_create_ratedata(infra, addr, addrlen, timenow);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
7
services/cache/infra.h
vendored
7
services/cache/infra.h
vendored
@ -416,15 +416,16 @@ int infra_find_ratelimit(struct infra_cache* infra, uint8_t* name,
|
|||||||
/** Update query ratelimit hash and decide
|
/** Update query ratelimit hash and decide
|
||||||
* whether or not a query should be dropped.
|
* whether or not a query should be dropped.
|
||||||
* @param infra: infra cache
|
* @param infra: infra cache
|
||||||
* @param repinfo: information about client
|
* @param addr: client address
|
||||||
|
* @param addrlen: client address length
|
||||||
* @param timenow: what time it is now.
|
* @param timenow: what time it is now.
|
||||||
* @param backoff: if backoff is enabled.
|
* @param backoff: if backoff is enabled.
|
||||||
* @param buffer: with query for logging.
|
* @param buffer: with query for logging.
|
||||||
* @return 1 if it could be incremented. 0 if the increment overshot the
|
* @return 1 if it could be incremented. 0 if the increment overshot the
|
||||||
* ratelimit and the query should be dropped. */
|
* ratelimit and the query should be dropped. */
|
||||||
int infra_ip_ratelimit_inc(struct infra_cache* infra,
|
int infra_ip_ratelimit_inc(struct infra_cache* infra,
|
||||||
struct comm_reply* repinfo, time_t timenow, int backoff,
|
struct sockaddr_storage* addr, socklen_t addrlen, time_t timenow,
|
||||||
struct sldns_buffer* buffer);
|
int backoff, struct sldns_buffer* buffer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get memory used by the infra cache.
|
* Get memory used by the infra cache.
|
||||||
|
@ -140,7 +140,9 @@ verbose_print_unbound_socket(struct unbound_socket* ub_sock)
|
|||||||
if(verbosity >= VERB_ALGO) {
|
if(verbosity >= VERB_ALGO) {
|
||||||
log_info("listing of unbound_socket structure:");
|
log_info("listing of unbound_socket structure:");
|
||||||
verbose_print_addr(ub_sock->addr);
|
verbose_print_addr(ub_sock->addr);
|
||||||
log_info("s is: %d, fam is: %s", ub_sock->s, ub_sock->fam == AF_INET?"AF_INET":"AF_INET6");
|
log_info("s is: %d, fam is: %s, acl: %s", ub_sock->s,
|
||||||
|
ub_sock->fam == AF_INET?"AF_INET":"AF_INET6",
|
||||||
|
ub_sock->acl?"yes":"no");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -458,7 +460,14 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
|
|||||||
int action;
|
int action;
|
||||||
# endif
|
# endif
|
||||||
# if defined(IPV6_V6ONLY)
|
# if defined(IPV6_V6ONLY)
|
||||||
if(v6only) {
|
if(v6only
|
||||||
|
# ifdef HAVE_SYSTEMD
|
||||||
|
/* Systemd wants to control if the socket is v6 only
|
||||||
|
* or both, with BindIPv6Only=default, ipv6-only or
|
||||||
|
* both in systemd.socket, so it is not set here. */
|
||||||
|
&& !got_fd_from_systemd
|
||||||
|
# endif
|
||||||
|
) {
|
||||||
int val=(v6only==2)?0:1;
|
int val=(v6only==2)?0:1;
|
||||||
if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY,
|
if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY,
|
||||||
(void*)&val, (socklen_t)sizeof(val)) < 0) {
|
(void*)&val, (socklen_t)sizeof(val)) < 0) {
|
||||||
@ -511,6 +520,7 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
|
|||||||
* instead which is writable; IPV6_MTU is readonly there. */
|
* instead which is writable; IPV6_MTU is readonly there. */
|
||||||
if (setsockopt(s, IPPROTO_IPV6, IPV6_USER_MTU,
|
if (setsockopt(s, IPPROTO_IPV6, IPV6_USER_MTU,
|
||||||
(void*)&mtu, (socklen_t)sizeof(mtu)) < 0) {
|
(void*)&mtu, (socklen_t)sizeof(mtu)) < 0) {
|
||||||
|
if (WSAGetLastError() != WSAENOPROTOOPT) {
|
||||||
log_err("setsockopt(..., IPV6_USER_MTU, ...) failed: %s",
|
log_err("setsockopt(..., IPV6_USER_MTU, ...) failed: %s",
|
||||||
wsa_strerror(WSAGetLastError()));
|
wsa_strerror(WSAGetLastError()));
|
||||||
sock_close(s);
|
sock_close(s);
|
||||||
@ -518,6 +528,7 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
|
|||||||
*inuse = 0;
|
*inuse = 0;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
# endif /* USE_WINSOCK */
|
# endif /* USE_WINSOCK */
|
||||||
# endif /* IPv6 MTU */
|
# endif /* IPv6 MTU */
|
||||||
# if defined(IPV6_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
|
# if defined(IPV6_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
|
||||||
@ -774,7 +785,14 @@ create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto,
|
|||||||
(void)reuseport;
|
(void)reuseport;
|
||||||
#endif /* defined(SO_REUSEPORT) */
|
#endif /* defined(SO_REUSEPORT) */
|
||||||
#if defined(IPV6_V6ONLY)
|
#if defined(IPV6_V6ONLY)
|
||||||
if(addr->ai_family == AF_INET6 && v6only) {
|
if(addr->ai_family == AF_INET6 && v6only
|
||||||
|
# ifdef HAVE_SYSTEMD
|
||||||
|
/* Systemd wants to control if the socket is v6 only
|
||||||
|
* or both, with BindIPv6Only=default, ipv6-only or
|
||||||
|
* both in systemd.socket, so it is not set here. */
|
||||||
|
&& !got_fd_from_systemd
|
||||||
|
# endif
|
||||||
|
) {
|
||||||
if(setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY,
|
if(setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY,
|
||||||
(void*)&on, (socklen_t)sizeof(on)) < 0) {
|
(void*)&on, (socklen_t)sizeof(on)) < 0) {
|
||||||
log_err("setsockopt(..., IPV6_V6ONLY, ...) failed: %s",
|
log_err("setsockopt(..., IPV6_V6ONLY, ...) failed: %s",
|
||||||
@ -1030,6 +1048,7 @@ make_sock(int stype, const char* ifname, const char* port,
|
|||||||
ub_sock->addr = res;
|
ub_sock->addr = res;
|
||||||
ub_sock->s = s;
|
ub_sock->s = s;
|
||||||
ub_sock->fam = hints->ai_family;
|
ub_sock->fam = hints->ai_family;
|
||||||
|
ub_sock->acl = NULL;
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -1074,11 +1093,13 @@ make_sock_port(int stype, const char* ifname, const char* port,
|
|||||||
* @param list: list head. changed.
|
* @param list: list head. changed.
|
||||||
* @param s: fd.
|
* @param s: fd.
|
||||||
* @param ftype: if fd is UDP.
|
* @param ftype: if fd is UDP.
|
||||||
|
* @param pp2_enabled: if PROXYv2 is enabled for this port.
|
||||||
* @param ub_sock: socket with address.
|
* @param ub_sock: socket with address.
|
||||||
* @return false on failure. list in unchanged then.
|
* @return false on failure. list in unchanged then.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
port_insert(struct listen_port** list, int s, enum listen_type ftype, struct unbound_socket* ub_sock)
|
port_insert(struct listen_port** list, int s, enum listen_type ftype,
|
||||||
|
int pp2_enabled, struct unbound_socket* ub_sock)
|
||||||
{
|
{
|
||||||
struct listen_port* item = (struct listen_port*)malloc(
|
struct listen_port* item = (struct listen_port*)malloc(
|
||||||
sizeof(struct listen_port));
|
sizeof(struct listen_port));
|
||||||
@ -1087,6 +1108,7 @@ port_insert(struct listen_port** list, int s, enum listen_type ftype, struct unb
|
|||||||
item->next = *list;
|
item->next = *list;
|
||||||
item->fd = s;
|
item->fd = s;
|
||||||
item->ftype = ftype;
|
item->ftype = ftype;
|
||||||
|
item->pp2_enabled = pp2_enabled;
|
||||||
item->socket = ub_sock;
|
item->socket = ub_sock;
|
||||||
*list = item;
|
*list = item;
|
||||||
return 1;
|
return 1;
|
||||||
@ -1182,6 +1204,7 @@ if_is_ssl(const char* ifname, const char* port, int ssl_port,
|
|||||||
* @param ssl_port: ssl service port number
|
* @param ssl_port: ssl service port number
|
||||||
* @param tls_additional_port: list of additional ssl service port numbers.
|
* @param tls_additional_port: list of additional ssl service port numbers.
|
||||||
* @param https_port: DoH service port number
|
* @param https_port: DoH service port number
|
||||||
|
* @param proxy_protocol_port: list of PROXYv2 port numbers.
|
||||||
* @param reuseport: try to set SO_REUSEPORT if nonNULL and true.
|
* @param reuseport: try to set SO_REUSEPORT if nonNULL and true.
|
||||||
* set to false on exit if reuseport failed due to no kernel support.
|
* set to false on exit if reuseport failed due to no kernel support.
|
||||||
* @param transparent: set IP_TRANSPARENT socket option.
|
* @param transparent: set IP_TRANSPARENT socket option.
|
||||||
@ -1198,25 +1221,30 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
|
|||||||
struct addrinfo *hints, const char* port, struct listen_port** list,
|
struct addrinfo *hints, const char* port, struct listen_port** list,
|
||||||
size_t rcv, size_t snd, int ssl_port,
|
size_t rcv, size_t snd, int ssl_port,
|
||||||
struct config_strlist* tls_additional_port, int https_port,
|
struct config_strlist* tls_additional_port, int https_port,
|
||||||
|
struct config_strlist* proxy_protocol_port,
|
||||||
int* reuseport, int transparent, int tcp_mss, int freebind,
|
int* reuseport, int transparent, int tcp_mss, int freebind,
|
||||||
int http2_nodelay, int use_systemd, int dnscrypt_port, int dscp)
|
int http2_nodelay, int use_systemd, int dnscrypt_port, int dscp)
|
||||||
{
|
{
|
||||||
int s, noip6=0;
|
int s, noip6=0;
|
||||||
int is_https = if_is_https(ifname, port, https_port);
|
int is_https = if_is_https(ifname, port, https_port);
|
||||||
|
int is_dnscrypt = if_is_dnscrypt(ifname, port, dnscrypt_port);
|
||||||
|
int is_pp2 = if_is_pp2(ifname, port, proxy_protocol_port);
|
||||||
int nodelay = is_https && http2_nodelay;
|
int nodelay = is_https && http2_nodelay;
|
||||||
struct unbound_socket* ub_sock;
|
struct unbound_socket* ub_sock;
|
||||||
#ifdef USE_DNSCRYPT
|
|
||||||
int is_dnscrypt = ((strchr(ifname, '@') &&
|
|
||||||
atoi(strchr(ifname, '@')+1) == dnscrypt_port) ||
|
|
||||||
(!strchr(ifname, '@') && atoi(port) == dnscrypt_port));
|
|
||||||
#else
|
|
||||||
int is_dnscrypt = 0;
|
|
||||||
(void)dnscrypt_port;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(!do_udp && !do_tcp)
|
if(!do_udp && !do_tcp)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if(is_pp2) {
|
||||||
|
if(is_dnscrypt) {
|
||||||
|
fatal_exit("PROXYv2 and DNSCrypt combination not "
|
||||||
|
"supported!");
|
||||||
|
} else if(is_https) {
|
||||||
|
fatal_exit("PROXYv2 and DoH combination not "
|
||||||
|
"supported!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(do_auto) {
|
if(do_auto) {
|
||||||
ub_sock = calloc(1, sizeof(struct unbound_socket));
|
ub_sock = calloc(1, sizeof(struct unbound_socket));
|
||||||
if(!ub_sock)
|
if(!ub_sock)
|
||||||
@ -1239,8 +1267,9 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
|
|||||||
free(ub_sock);
|
free(ub_sock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(!port_insert(list, s,
|
if(!port_insert(list, s, is_dnscrypt
|
||||||
is_dnscrypt?listen_type_udpancil_dnscrypt:listen_type_udpancil, ub_sock)) {
|
?listen_type_udpancil_dnscrypt:listen_type_udpancil,
|
||||||
|
is_pp2, ub_sock)) {
|
||||||
sock_close(s);
|
sock_close(s);
|
||||||
freeaddrinfo(ub_sock->addr);
|
freeaddrinfo(ub_sock->addr);
|
||||||
free(ub_sock);
|
free(ub_sock);
|
||||||
@ -1262,8 +1291,9 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(!port_insert(list, s,
|
if(!port_insert(list, s, is_dnscrypt
|
||||||
is_dnscrypt?listen_type_udp_dnscrypt:listen_type_udp, ub_sock)) {
|
?listen_type_udp_dnscrypt:listen_type_udp,
|
||||||
|
is_pp2, ub_sock)) {
|
||||||
sock_close(s);
|
sock_close(s);
|
||||||
freeaddrinfo(ub_sock->addr);
|
freeaddrinfo(ub_sock->addr);
|
||||||
free(ub_sock);
|
free(ub_sock);
|
||||||
@ -1298,7 +1328,7 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
|
|||||||
}
|
}
|
||||||
if(is_ssl)
|
if(is_ssl)
|
||||||
verbose(VERB_ALGO, "setup TCP for SSL service");
|
verbose(VERB_ALGO, "setup TCP for SSL service");
|
||||||
if(!port_insert(list, s, port_type, ub_sock)) {
|
if(!port_insert(list, s, port_type, is_pp2, ub_sock)) {
|
||||||
sock_close(s);
|
sock_close(s);
|
||||||
freeaddrinfo(ub_sock->addr);
|
freeaddrinfo(ub_sock->addr);
|
||||||
free(ub_sock);
|
free(ub_sock);
|
||||||
@ -1387,14 +1417,16 @@ listen_create(struct comm_base* base, struct listen_port* ports,
|
|||||||
if(ports->ftype == listen_type_udp ||
|
if(ports->ftype == listen_type_udp ||
|
||||||
ports->ftype == listen_type_udp_dnscrypt) {
|
ports->ftype == listen_type_udp_dnscrypt) {
|
||||||
cp = comm_point_create_udp(base, ports->fd,
|
cp = comm_point_create_udp(base, ports->fd,
|
||||||
front->udp_buff, cb, cb_arg, ports->socket);
|
front->udp_buff, ports->pp2_enabled, cb,
|
||||||
|
cb_arg, ports->socket);
|
||||||
} else if(ports->ftype == listen_type_tcp ||
|
} else if(ports->ftype == listen_type_tcp ||
|
||||||
ports->ftype == listen_type_tcp_dnscrypt) {
|
ports->ftype == listen_type_tcp_dnscrypt) {
|
||||||
cp = comm_point_create_tcp(base, ports->fd,
|
cp = comm_point_create_tcp(base, ports->fd,
|
||||||
tcp_accept_count, tcp_idle_timeout,
|
tcp_accept_count, tcp_idle_timeout,
|
||||||
harden_large_queries, 0, NULL,
|
harden_large_queries, 0, NULL,
|
||||||
tcp_conn_limit, bufsize, front->udp_buff,
|
tcp_conn_limit, bufsize, front->udp_buff,
|
||||||
ports->ftype, cb, cb_arg, ports->socket);
|
ports->ftype, ports->pp2_enabled, cb, cb_arg,
|
||||||
|
ports->socket);
|
||||||
} else if(ports->ftype == listen_type_ssl ||
|
} else if(ports->ftype == listen_type_ssl ||
|
||||||
ports->ftype == listen_type_http) {
|
ports->ftype == listen_type_http) {
|
||||||
cp = comm_point_create_tcp(base, ports->fd,
|
cp = comm_point_create_tcp(base, ports->fd,
|
||||||
@ -1402,7 +1434,8 @@ listen_create(struct comm_base* base, struct listen_port* ports,
|
|||||||
harden_large_queries,
|
harden_large_queries,
|
||||||
http_max_streams, http_endpoint,
|
http_max_streams, http_endpoint,
|
||||||
tcp_conn_limit, bufsize, front->udp_buff,
|
tcp_conn_limit, bufsize, front->udp_buff,
|
||||||
ports->ftype, cb, cb_arg, ports->socket);
|
ports->ftype, ports->pp2_enabled, cb, cb_arg,
|
||||||
|
ports->socket);
|
||||||
if(ports->ftype == listen_type_http) {
|
if(ports->ftype == listen_type_http) {
|
||||||
if(!sslctx && !http_notls) {
|
if(!sslctx && !http_notls) {
|
||||||
log_warn("HTTPS port configured, but "
|
log_warn("HTTPS port configured, but "
|
||||||
@ -1428,7 +1461,8 @@ listen_create(struct comm_base* base, struct listen_port* ports,
|
|||||||
} else if(ports->ftype == listen_type_udpancil ||
|
} else if(ports->ftype == listen_type_udpancil ||
|
||||||
ports->ftype == listen_type_udpancil_dnscrypt) {
|
ports->ftype == listen_type_udpancil_dnscrypt) {
|
||||||
cp = comm_point_create_udp_ancil(base, ports->fd,
|
cp = comm_point_create_udp_ancil(base, ports->fd,
|
||||||
front->udp_buff, cb, cb_arg, ports->socket);
|
front->udp_buff, ports->pp2_enabled, cb,
|
||||||
|
cb_arg, ports->socket);
|
||||||
}
|
}
|
||||||
if(!cp) {
|
if(!cp) {
|
||||||
log_err("can't create commpoint");
|
log_err("can't create commpoint");
|
||||||
@ -1763,7 +1797,9 @@ listening_ports_open(struct config_file* cfg, char** ifs, int num_ifs,
|
|||||||
&hints, portbuf, &list,
|
&hints, portbuf, &list,
|
||||||
cfg->so_rcvbuf, cfg->so_sndbuf,
|
cfg->so_rcvbuf, cfg->so_sndbuf,
|
||||||
cfg->ssl_port, cfg->tls_additional_port,
|
cfg->ssl_port, cfg->tls_additional_port,
|
||||||
cfg->https_port, reuseport, cfg->ip_transparent,
|
cfg->https_port,
|
||||||
|
cfg->proxy_protocol_port,
|
||||||
|
reuseport, cfg->ip_transparent,
|
||||||
cfg->tcp_mss, cfg->ip_freebind,
|
cfg->tcp_mss, cfg->ip_freebind,
|
||||||
cfg->http_nodelay, cfg->use_systemd,
|
cfg->http_nodelay, cfg->use_systemd,
|
||||||
cfg->dnscrypt_port, cfg->ip_dscp)) {
|
cfg->dnscrypt_port, cfg->ip_dscp)) {
|
||||||
@ -1778,7 +1814,9 @@ listening_ports_open(struct config_file* cfg, char** ifs, int num_ifs,
|
|||||||
&hints, portbuf, &list,
|
&hints, portbuf, &list,
|
||||||
cfg->so_rcvbuf, cfg->so_sndbuf,
|
cfg->so_rcvbuf, cfg->so_sndbuf,
|
||||||
cfg->ssl_port, cfg->tls_additional_port,
|
cfg->ssl_port, cfg->tls_additional_port,
|
||||||
cfg->https_port, reuseport, cfg->ip_transparent,
|
cfg->https_port,
|
||||||
|
cfg->proxy_protocol_port,
|
||||||
|
reuseport, cfg->ip_transparent,
|
||||||
cfg->tcp_mss, cfg->ip_freebind,
|
cfg->tcp_mss, cfg->ip_freebind,
|
||||||
cfg->http_nodelay, cfg->use_systemd,
|
cfg->http_nodelay, cfg->use_systemd,
|
||||||
cfg->dnscrypt_port, cfg->ip_dscp)) {
|
cfg->dnscrypt_port, cfg->ip_dscp)) {
|
||||||
@ -1796,7 +1834,8 @@ listening_ports_open(struct config_file* cfg, char** ifs, int num_ifs,
|
|||||||
&hints, portbuf, &list,
|
&hints, portbuf, &list,
|
||||||
cfg->so_rcvbuf, cfg->so_sndbuf,
|
cfg->so_rcvbuf, cfg->so_sndbuf,
|
||||||
cfg->ssl_port, cfg->tls_additional_port,
|
cfg->ssl_port, cfg->tls_additional_port,
|
||||||
cfg->https_port, reuseport, cfg->ip_transparent,
|
cfg->https_port, cfg->proxy_protocol_port,
|
||||||
|
reuseport, cfg->ip_transparent,
|
||||||
cfg->tcp_mss, cfg->ip_freebind,
|
cfg->tcp_mss, cfg->ip_freebind,
|
||||||
cfg->http_nodelay, cfg->use_systemd,
|
cfg->http_nodelay, cfg->use_systemd,
|
||||||
cfg->dnscrypt_port, cfg->ip_dscp)) {
|
cfg->dnscrypt_port, cfg->ip_dscp)) {
|
||||||
@ -1811,7 +1850,8 @@ listening_ports_open(struct config_file* cfg, char** ifs, int num_ifs,
|
|||||||
&hints, portbuf, &list,
|
&hints, portbuf, &list,
|
||||||
cfg->so_rcvbuf, cfg->so_sndbuf,
|
cfg->so_rcvbuf, cfg->so_sndbuf,
|
||||||
cfg->ssl_port, cfg->tls_additional_port,
|
cfg->ssl_port, cfg->tls_additional_port,
|
||||||
cfg->https_port, reuseport, cfg->ip_transparent,
|
cfg->https_port, cfg->proxy_protocol_port,
|
||||||
|
reuseport, cfg->ip_transparent,
|
||||||
cfg->tcp_mss, cfg->ip_freebind,
|
cfg->tcp_mss, cfg->ip_freebind,
|
||||||
cfg->http_nodelay, cfg->use_systemd,
|
cfg->http_nodelay, cfg->use_systemd,
|
||||||
cfg->dnscrypt_port, cfg->ip_dscp)) {
|
cfg->dnscrypt_port, cfg->ip_dscp)) {
|
||||||
@ -1828,7 +1868,8 @@ listening_ports_open(struct config_file* cfg, char** ifs, int num_ifs,
|
|||||||
do_tcp, &hints, portbuf, &list,
|
do_tcp, &hints, portbuf, &list,
|
||||||
cfg->so_rcvbuf, cfg->so_sndbuf,
|
cfg->so_rcvbuf, cfg->so_sndbuf,
|
||||||
cfg->ssl_port, cfg->tls_additional_port,
|
cfg->ssl_port, cfg->tls_additional_port,
|
||||||
cfg->https_port, reuseport, cfg->ip_transparent,
|
cfg->https_port, cfg->proxy_protocol_port,
|
||||||
|
reuseport, cfg->ip_transparent,
|
||||||
cfg->tcp_mss, cfg->ip_freebind,
|
cfg->tcp_mss, cfg->ip_freebind,
|
||||||
cfg->http_nodelay, cfg->use_systemd,
|
cfg->http_nodelay, cfg->use_systemd,
|
||||||
cfg->dnscrypt_port, cfg->ip_dscp)) {
|
cfg->dnscrypt_port, cfg->ip_dscp)) {
|
||||||
@ -1843,7 +1884,8 @@ listening_ports_open(struct config_file* cfg, char** ifs, int num_ifs,
|
|||||||
do_tcp, &hints, portbuf, &list,
|
do_tcp, &hints, portbuf, &list,
|
||||||
cfg->so_rcvbuf, cfg->so_sndbuf,
|
cfg->so_rcvbuf, cfg->so_sndbuf,
|
||||||
cfg->ssl_port, cfg->tls_additional_port,
|
cfg->ssl_port, cfg->tls_additional_port,
|
||||||
cfg->https_port, reuseport, cfg->ip_transparent,
|
cfg->https_port, cfg->proxy_protocol_port,
|
||||||
|
reuseport, cfg->ip_transparent,
|
||||||
cfg->tcp_mss, cfg->ip_freebind,
|
cfg->tcp_mss, cfg->ip_freebind,
|
||||||
cfg->http_nodelay, cfg->use_systemd,
|
cfg->http_nodelay, cfg->use_systemd,
|
||||||
cfg->dnscrypt_port, cfg->ip_dscp)) {
|
cfg->dnscrypt_port, cfg->ip_dscp)) {
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
#define LISTEN_DNSPORT_H
|
#define LISTEN_DNSPORT_H
|
||||||
|
|
||||||
#include "util/netevent.h"
|
#include "util/netevent.h"
|
||||||
|
#include "daemon/acl_list.h"
|
||||||
#ifdef HAVE_NGHTTP2_NGHTTP2_H
|
#ifdef HAVE_NGHTTP2_NGHTTP2_H
|
||||||
#include <nghttp2/nghttp2.h>
|
#include <nghttp2/nghttp2.h>
|
||||||
#endif
|
#endif
|
||||||
@ -107,11 +108,13 @@ enum listen_type {
|
|||||||
*/
|
*/
|
||||||
struct unbound_socket {
|
struct unbound_socket {
|
||||||
/** socket-address structure */
|
/** socket-address structure */
|
||||||
struct addrinfo * addr;
|
struct addrinfo* addr;
|
||||||
/** socket descriptor returned by socket() syscall */
|
/** socket descriptor returned by socket() syscall */
|
||||||
int s;
|
int s;
|
||||||
/** address family (AF_INET/IF_INET6) */
|
/** address family (AF_INET/IF_INET6) */
|
||||||
int fam;
|
int fam;
|
||||||
|
/** ACL on the socket (listening interface) */
|
||||||
|
struct acl_addr* acl;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -125,7 +128,10 @@ struct listen_port {
|
|||||||
int fd;
|
int fd;
|
||||||
/** type of file descriptor, udp or tcp */
|
/** type of file descriptor, udp or tcp */
|
||||||
enum listen_type ftype;
|
enum listen_type ftype;
|
||||||
/** fill in unbpound_socket structure for every opened socket at Unbound startup */
|
/** if the port should support PROXYv2 */
|
||||||
|
int pp2_enabled;
|
||||||
|
/** fill in unbound_socket structure for every opened socket at
|
||||||
|
* Unbound startup */
|
||||||
struct unbound_socket* socket;
|
struct unbound_socket* socket;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1744,13 +1744,13 @@ local_zones_zone_answer(struct local_zone* z, struct module_env* env,
|
|||||||
/** print log information for an inform zone query */
|
/** print log information for an inform zone query */
|
||||||
static void
|
static void
|
||||||
lz_inform_print(struct local_zone* z, struct query_info* qinfo,
|
lz_inform_print(struct local_zone* z, struct query_info* qinfo,
|
||||||
struct comm_reply* repinfo)
|
struct sockaddr_storage* addr, socklen_t addrlen)
|
||||||
{
|
{
|
||||||
char ip[128], txt[512];
|
char ip[128], txt[512];
|
||||||
char zname[LDNS_MAX_DOMAINLEN+1];
|
char zname[LDNS_MAX_DOMAINLEN+1];
|
||||||
uint16_t port = ntohs(((struct sockaddr_in*)&repinfo->addr)->sin_port);
|
uint16_t port = ntohs(((struct sockaddr_in*)addr)->sin_port);
|
||||||
dname_str(z->name, zname);
|
dname_str(z->name, zname);
|
||||||
addr_to_str(&repinfo->addr, repinfo->addrlen, ip, sizeof(ip));
|
addr_to_str(addr, addrlen, ip, sizeof(ip));
|
||||||
snprintf(txt, sizeof(txt), "%s %s %s@%u", zname, local_zone_type2str(z->type), ip,
|
snprintf(txt, sizeof(txt), "%s %s %s@%u", zname, local_zone_type2str(z->type), ip,
|
||||||
(unsigned)port);
|
(unsigned)port);
|
||||||
log_nametypeclass(NO_VERBOSE, txt, qinfo->qname, qinfo->qtype, qinfo->qclass);
|
log_nametypeclass(NO_VERBOSE, txt, qinfo->qname, qinfo->qtype, qinfo->qclass);
|
||||||
@ -1765,7 +1765,8 @@ lz_type(uint8_t *taglist, size_t taglen, uint8_t *taglist2, size_t taglen2,
|
|||||||
struct local_zone_override* lzo;
|
struct local_zone_override* lzo;
|
||||||
if(repinfo && override_tree) {
|
if(repinfo && override_tree) {
|
||||||
lzo = (struct local_zone_override*)addr_tree_lookup(
|
lzo = (struct local_zone_override*)addr_tree_lookup(
|
||||||
override_tree, &repinfo->addr, repinfo->addrlen);
|
override_tree, &repinfo->client_addr,
|
||||||
|
repinfo->client_addrlen);
|
||||||
if(lzo && lzo->type) {
|
if(lzo && lzo->type) {
|
||||||
verbose(VERB_ALGO, "local zone override to type %s",
|
verbose(VERB_ALGO, "local zone override to type %s",
|
||||||
local_zone_type2str(lzo->type));
|
local_zone_type2str(lzo->type));
|
||||||
@ -1888,7 +1889,8 @@ local_zones_answer(struct local_zones* zones, struct module_env* env,
|
|||||||
lzt == local_zone_inform_deny ||
|
lzt == local_zone_inform_deny ||
|
||||||
lzt == local_zone_inform_redirect)
|
lzt == local_zone_inform_redirect)
|
||||||
&& repinfo)
|
&& repinfo)
|
||||||
lz_inform_print(z, qinfo, repinfo);
|
lz_inform_print(z, qinfo, &repinfo->client_addr,
|
||||||
|
repinfo->client_addrlen);
|
||||||
|
|
||||||
if(lzt != local_zone_always_refuse
|
if(lzt != local_zone_always_refuse
|
||||||
&& lzt != local_zone_always_transparent
|
&& lzt != local_zone_always_transparent
|
||||||
|
@ -806,7 +806,7 @@ static void mesh_schedule_prefetch_subnet(struct mesh_area* mesh,
|
|||||||
/* Fake the ECS data from the client's IP */
|
/* Fake the ECS data from the client's IP */
|
||||||
struct ecs_data ecs;
|
struct ecs_data ecs;
|
||||||
memset(&ecs, 0, sizeof(ecs));
|
memset(&ecs, 0, sizeof(ecs));
|
||||||
subnet_option_from_ss(&rep->addr, &ecs, mesh->env->cfg);
|
subnet_option_from_ss(&rep->client_addr, &ecs, mesh->env->cfg);
|
||||||
if(ecs.subnet_validdata == 0) {
|
if(ecs.subnet_validdata == 0) {
|
||||||
log_err("prefetch_subnet subnet_option_from_ss: invalid data");
|
log_err("prefetch_subnet subnet_option_from_ss: invalid data");
|
||||||
return;
|
return;
|
||||||
@ -1488,8 +1488,9 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
|
|||||||
}
|
}
|
||||||
/* Log reply sent */
|
/* Log reply sent */
|
||||||
if(m->s.env->cfg->log_replies) {
|
if(m->s.env->cfg->log_replies) {
|
||||||
log_reply_info(NO_VERBOSE, &m->s.qinfo, &r->query_reply.addr,
|
log_reply_info(NO_VERBOSE, &m->s.qinfo,
|
||||||
r->query_reply.addrlen, duration, 0, r_buffer);
|
&r->query_reply.client_addr,
|
||||||
|
r->query_reply.client_addrlen, duration, 0, r_buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1530,7 +1531,8 @@ void mesh_query_done(struct mesh_state* mstate)
|
|||||||
respip_inform_print(mstate->s.respip_action_info,
|
respip_inform_print(mstate->s.respip_action_info,
|
||||||
r->qname, mstate->s.qinfo.qtype,
|
r->qname, mstate->s.qinfo.qtype,
|
||||||
mstate->s.qinfo.qclass, r->local_alias,
|
mstate->s.qinfo.qclass, r->local_alias,
|
||||||
&r->query_reply);
|
&r->query_reply.client_addr,
|
||||||
|
r->query_reply.client_addrlen);
|
||||||
if(mstate->s.env->cfg->stat_extended &&
|
if(mstate->s.env->cfg->stat_extended &&
|
||||||
mstate->s.respip_action_info->rpz_used) {
|
mstate->s.respip_action_info->rpz_used) {
|
||||||
if(mstate->s.respip_action_info->rpz_disabled)
|
if(mstate->s.respip_action_info->rpz_disabled)
|
||||||
@ -2180,7 +2182,8 @@ mesh_serve_expired_callback(void* arg)
|
|||||||
if(actinfo.addrinfo) {
|
if(actinfo.addrinfo) {
|
||||||
respip_inform_print(&actinfo, r->qname,
|
respip_inform_print(&actinfo, r->qname,
|
||||||
qstate->qinfo.qtype, qstate->qinfo.qclass,
|
qstate->qinfo.qtype, qstate->qinfo.qclass,
|
||||||
r->local_alias, &r->query_reply);
|
r->local_alias, &r->query_reply.client_addr,
|
||||||
|
r->query_reply.client_addrlen);
|
||||||
|
|
||||||
if(qstate->env->cfg->stat_extended && actinfo.rpz_used) {
|
if(qstate->env->cfg->stat_extended && actinfo.rpz_used) {
|
||||||
if(actinfo.rpz_disabled)
|
if(actinfo.rpz_disabled)
|
||||||
|
@ -86,10 +86,6 @@ static void serviced_tcp_initiate(struct serviced_query* sq, sldns_buffer* buff)
|
|||||||
static int randomize_and_send_udp(struct pending* pend, sldns_buffer* packet,
|
static int randomize_and_send_udp(struct pending* pend, sldns_buffer* packet,
|
||||||
int timeout);
|
int timeout);
|
||||||
|
|
||||||
/** remove waiting tcp from the outnet waiting list */
|
|
||||||
static void waiting_list_remove(struct outside_network* outnet,
|
|
||||||
struct waiting_tcp* w);
|
|
||||||
|
|
||||||
/** select a DNS ID for a TCP stream */
|
/** select a DNS ID for a TCP stream */
|
||||||
static uint16_t tcp_select_id(struct outside_network* outnet,
|
static uint16_t tcp_select_id(struct outside_network* outnet,
|
||||||
struct reuse_tcp* reuse);
|
struct reuse_tcp* reuse);
|
||||||
@ -372,7 +368,8 @@ log_reuse_tcp(enum verbosity_value v, const char* msg, struct reuse_tcp* reuse)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** pop the first element from the writewait list */
|
/** pop the first element from the writewait list */
|
||||||
static struct waiting_tcp* reuse_write_wait_pop(struct reuse_tcp* reuse)
|
struct waiting_tcp*
|
||||||
|
reuse_write_wait_pop(struct reuse_tcp* reuse)
|
||||||
{
|
{
|
||||||
struct waiting_tcp* w = reuse->write_wait_first;
|
struct waiting_tcp* w = reuse->write_wait_first;
|
||||||
if(!w)
|
if(!w)
|
||||||
@ -390,8 +387,8 @@ static struct waiting_tcp* reuse_write_wait_pop(struct reuse_tcp* reuse)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** remove the element from the writewait list */
|
/** remove the element from the writewait list */
|
||||||
static void reuse_write_wait_remove(struct reuse_tcp* reuse,
|
void
|
||||||
struct waiting_tcp* w)
|
reuse_write_wait_remove(struct reuse_tcp* reuse, struct waiting_tcp* w)
|
||||||
{
|
{
|
||||||
log_assert(w);
|
log_assert(w);
|
||||||
log_assert(w->write_wait_queued);
|
log_assert(w->write_wait_queued);
|
||||||
@ -415,8 +412,8 @@ static void reuse_write_wait_remove(struct reuse_tcp* reuse,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** push the element after the last on the writewait list */
|
/** push the element after the last on the writewait list */
|
||||||
static void reuse_write_wait_push_back(struct reuse_tcp* reuse,
|
void
|
||||||
struct waiting_tcp* w)
|
reuse_write_wait_push_back(struct reuse_tcp* reuse, struct waiting_tcp* w)
|
||||||
{
|
{
|
||||||
if(!w) return;
|
if(!w) return;
|
||||||
log_assert(!w->write_wait_queued);
|
log_assert(!w->write_wait_queued);
|
||||||
@ -427,7 +424,9 @@ static void reuse_write_wait_push_back(struct reuse_tcp* reuse,
|
|||||||
w->write_wait_prev = reuse->write_wait_last;
|
w->write_wait_prev = reuse->write_wait_last;
|
||||||
} else {
|
} else {
|
||||||
reuse->write_wait_first = w;
|
reuse->write_wait_first = w;
|
||||||
|
w->write_wait_prev = NULL;
|
||||||
}
|
}
|
||||||
|
w->write_wait_next = NULL;
|
||||||
reuse->write_wait_last = w;
|
reuse->write_wait_last = w;
|
||||||
w->write_wait_queued = 1;
|
w->write_wait_queued = 1;
|
||||||
}
|
}
|
||||||
@ -721,12 +720,12 @@ outnet_tcp_take_into_use(struct waiting_tcp* w)
|
|||||||
pend->next_free = NULL;
|
pend->next_free = NULL;
|
||||||
pend->query = w;
|
pend->query = w;
|
||||||
pend->reuse.outnet = w->outnet;
|
pend->reuse.outnet = w->outnet;
|
||||||
pend->c->repinfo.addrlen = w->addrlen;
|
pend->c->repinfo.remote_addrlen = w->addrlen;
|
||||||
pend->c->tcp_more_read_again = &pend->reuse.cp_more_read_again;
|
pend->c->tcp_more_read_again = &pend->reuse.cp_more_read_again;
|
||||||
pend->c->tcp_more_write_again = &pend->reuse.cp_more_write_again;
|
pend->c->tcp_more_write_again = &pend->reuse.cp_more_write_again;
|
||||||
pend->reuse.cp_more_read_again = 0;
|
pend->reuse.cp_more_read_again = 0;
|
||||||
pend->reuse.cp_more_write_again = 0;
|
pend->reuse.cp_more_write_again = 0;
|
||||||
memcpy(&pend->c->repinfo.addr, &w->addr, w->addrlen);
|
memcpy(&pend->c->repinfo.remote_addr, &w->addr, w->addrlen);
|
||||||
pend->reuse.pending = pend;
|
pend->reuse.pending = pend;
|
||||||
|
|
||||||
/* Remove from tree in case the is_ssl will be different and causes the
|
/* Remove from tree in case the is_ssl will be different and causes the
|
||||||
@ -810,20 +809,50 @@ reuse_tcp_lru_snip(struct outside_network* outnet)
|
|||||||
return reuse;
|
return reuse;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** call callback on waiting_tcp, if not NULL */
|
/** remove waiting tcp from the outnet waiting list */
|
||||||
static void
|
void
|
||||||
waiting_tcp_callback(struct waiting_tcp* w, struct comm_point* c, int error,
|
outnet_waiting_tcp_list_remove(struct outside_network* outnet, struct waiting_tcp* w)
|
||||||
struct comm_reply* reply_info)
|
|
||||||
{
|
{
|
||||||
if(w && w->cb) {
|
struct waiting_tcp* p = outnet->tcp_wait_first, *prev = NULL;
|
||||||
fptr_ok(fptr_whitelist_pending_tcp(w->cb));
|
w->on_tcp_waiting_list = 0;
|
||||||
(void)(*w->cb)(c, w->cb_arg, error, reply_info);
|
while(p) {
|
||||||
|
if(p == w) {
|
||||||
|
/* remove w */
|
||||||
|
if(prev)
|
||||||
|
prev->next_waiting = w->next_waiting;
|
||||||
|
else outnet->tcp_wait_first = w->next_waiting;
|
||||||
|
if(outnet->tcp_wait_last == w)
|
||||||
|
outnet->tcp_wait_last = prev;
|
||||||
|
w->next_waiting = NULL;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
prev = p;
|
||||||
|
p = p->next_waiting;
|
||||||
|
}
|
||||||
|
/* outnet_waiting_tcp_list_remove is currently called only with items
|
||||||
|
* that are already in the waiting list. */
|
||||||
|
log_assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** pop the first waiting tcp from the outnet waiting list */
|
||||||
|
struct waiting_tcp*
|
||||||
|
outnet_waiting_tcp_list_pop(struct outside_network* outnet)
|
||||||
|
{
|
||||||
|
struct waiting_tcp* w = outnet->tcp_wait_first;
|
||||||
|
if(!outnet->tcp_wait_first) return NULL;
|
||||||
|
log_assert(w->on_tcp_waiting_list);
|
||||||
|
outnet->tcp_wait_first = w->next_waiting;
|
||||||
|
if(outnet->tcp_wait_last == w)
|
||||||
|
outnet->tcp_wait_last = NULL;
|
||||||
|
w->on_tcp_waiting_list = 0;
|
||||||
|
w->next_waiting = NULL;
|
||||||
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** add waiting_tcp element to the outnet tcp waiting list */
|
/** add waiting_tcp element to the outnet tcp waiting list */
|
||||||
static void
|
void
|
||||||
outnet_add_tcp_waiting(struct outside_network* outnet, struct waiting_tcp* w)
|
outnet_waiting_tcp_list_add(struct outside_network* outnet,
|
||||||
|
struct waiting_tcp* w, int set_timer)
|
||||||
{
|
{
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
log_assert(!w->on_tcp_waiting_list);
|
log_assert(!w->on_tcp_waiting_list);
|
||||||
@ -835,16 +864,18 @@ outnet_add_tcp_waiting(struct outside_network* outnet, struct waiting_tcp* w)
|
|||||||
else outnet->tcp_wait_first = w;
|
else outnet->tcp_wait_first = w;
|
||||||
outnet->tcp_wait_last = w;
|
outnet->tcp_wait_last = w;
|
||||||
w->on_tcp_waiting_list = 1;
|
w->on_tcp_waiting_list = 1;
|
||||||
|
if(set_timer) {
|
||||||
#ifndef S_SPLINT_S
|
#ifndef S_SPLINT_S
|
||||||
tv.tv_sec = w->timeout/1000;
|
tv.tv_sec = w->timeout/1000;
|
||||||
tv.tv_usec = (w->timeout%1000)*1000;
|
tv.tv_usec = (w->timeout%1000)*1000;
|
||||||
#endif
|
#endif
|
||||||
comm_timer_set(w->timer, &tv);
|
comm_timer_set(w->timer, &tv);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** add waiting_tcp element as first to the outnet tcp waiting list */
|
/** add waiting_tcp element as first to the outnet tcp waiting list */
|
||||||
static void
|
void
|
||||||
outnet_add_tcp_waiting_first(struct outside_network* outnet,
|
outnet_waiting_tcp_list_add_first(struct outside_network* outnet,
|
||||||
struct waiting_tcp* w, int reset_timer)
|
struct waiting_tcp* w, int reset_timer)
|
||||||
{
|
{
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
@ -869,6 +900,17 @@ outnet_add_tcp_waiting_first(struct outside_network* outnet,
|
|||||||
(outnet->tcp_reuse_first && outnet->tcp_reuse_last));
|
(outnet->tcp_reuse_first && outnet->tcp_reuse_last));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** call callback on waiting_tcp, if not NULL */
|
||||||
|
static void
|
||||||
|
waiting_tcp_callback(struct waiting_tcp* w, struct comm_point* c, int error,
|
||||||
|
struct comm_reply* reply_info)
|
||||||
|
{
|
||||||
|
if(w && w->cb) {
|
||||||
|
fptr_ok(fptr_whitelist_pending_tcp(w->cb));
|
||||||
|
(void)(*w->cb)(c, w->cb_arg, error, reply_info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** see if buffers can be used to service TCP queries */
|
/** see if buffers can be used to service TCP queries */
|
||||||
static void
|
static void
|
||||||
use_free_buffer(struct outside_network* outnet)
|
use_free_buffer(struct outside_network* outnet)
|
||||||
@ -879,15 +921,10 @@ use_free_buffer(struct outside_network* outnet)
|
|||||||
struct pending_tcp* pend_tcp = NULL;
|
struct pending_tcp* pend_tcp = NULL;
|
||||||
#endif
|
#endif
|
||||||
struct reuse_tcp* reuse = NULL;
|
struct reuse_tcp* reuse = NULL;
|
||||||
w = outnet->tcp_wait_first;
|
w = outnet_waiting_tcp_list_pop(outnet);
|
||||||
log_assert(w->on_tcp_waiting_list);
|
|
||||||
outnet->tcp_wait_first = w->next_waiting;
|
|
||||||
if(outnet->tcp_wait_last == w)
|
|
||||||
outnet->tcp_wait_last = NULL;
|
|
||||||
log_assert(
|
log_assert(
|
||||||
(!outnet->tcp_reuse_first && !outnet->tcp_reuse_last) ||
|
(!outnet->tcp_reuse_first && !outnet->tcp_reuse_last) ||
|
||||||
(outnet->tcp_reuse_first && outnet->tcp_reuse_last));
|
(outnet->tcp_reuse_first && outnet->tcp_reuse_last));
|
||||||
w->on_tcp_waiting_list = 0;
|
|
||||||
reuse = reuse_tcp_find(outnet, &w->addr, w->addrlen,
|
reuse = reuse_tcp_find(outnet, &w->addr, w->addrlen,
|
||||||
w->ssl_upstream);
|
w->ssl_upstream);
|
||||||
/* re-select an ID when moving to a new TCP buffer */
|
/* re-select an ID when moving to a new TCP buffer */
|
||||||
@ -934,7 +971,7 @@ use_free_buffer(struct outside_network* outnet)
|
|||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
/* no reuse and no free buffer, put back at the start */
|
/* no reuse and no free buffer, put back at the start */
|
||||||
outnet_add_tcp_waiting_first(outnet, w, 0);
|
outnet_waiting_tcp_list_add_first(outnet, w, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifdef USE_DNSTAP
|
#ifdef USE_DNSTAP
|
||||||
@ -1008,7 +1045,7 @@ reuse_move_writewait_away(struct outside_network* outnet,
|
|||||||
* fail the query */
|
* fail the query */
|
||||||
w->error_count ++;
|
w->error_count ++;
|
||||||
reuse_tree_by_id_delete(&pend->reuse, w);
|
reuse_tree_by_id_delete(&pend->reuse, w);
|
||||||
outnet_add_tcp_waiting(outnet, w);
|
outnet_waiting_tcp_list_add(outnet, w, 1);
|
||||||
}
|
}
|
||||||
while((w = reuse_write_wait_pop(&pend->reuse)) != NULL) {
|
while((w = reuse_write_wait_pop(&pend->reuse)) != NULL) {
|
||||||
if(verbosity >= VERB_CLIENT && w->pkt_len > 12+2+2 &&
|
if(verbosity >= VERB_CLIENT && w->pkt_len > 12+2+2 &&
|
||||||
@ -1019,7 +1056,7 @@ reuse_move_writewait_away(struct outside_network* outnet,
|
|||||||
verbose(VERB_CLIENT, "reuse_move_writewait_away item %s", buf);
|
verbose(VERB_CLIENT, "reuse_move_writewait_away item %s", buf);
|
||||||
}
|
}
|
||||||
reuse_tree_by_id_delete(&pend->reuse, w);
|
reuse_tree_by_id_delete(&pend->reuse, w);
|
||||||
outnet_add_tcp_waiting(outnet, w);
|
outnet_waiting_tcp_list_add(outnet, w, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1417,11 +1454,11 @@ outnet_udp_cb(struct comm_point* c, void* arg, int error,
|
|||||||
|
|
||||||
/* setup lookup key */
|
/* setup lookup key */
|
||||||
key.id = (unsigned)LDNS_ID_WIRE(sldns_buffer_begin(c->buffer));
|
key.id = (unsigned)LDNS_ID_WIRE(sldns_buffer_begin(c->buffer));
|
||||||
memcpy(&key.addr, &reply_info->addr, reply_info->addrlen);
|
memcpy(&key.addr, &reply_info->remote_addr, reply_info->remote_addrlen);
|
||||||
key.addrlen = reply_info->addrlen;
|
key.addrlen = reply_info->remote_addrlen;
|
||||||
verbose(VERB_ALGO, "Incoming reply id = %4.4x", key.id);
|
verbose(VERB_ALGO, "Incoming reply id = %4.4x", key.id);
|
||||||
log_addr(VERB_ALGO, "Incoming reply addr =",
|
log_addr(VERB_ALGO, "Incoming reply addr =",
|
||||||
&reply_info->addr, reply_info->addrlen);
|
&reply_info->remote_addr, reply_info->remote_addrlen);
|
||||||
|
|
||||||
/* find it, see if this thing is a valid query response */
|
/* find it, see if this thing is a valid query response */
|
||||||
verbose(VERB_ALGO, "lookup size is %d entries", (int)outnet->pending->count);
|
verbose(VERB_ALGO, "lookup size is %d entries", (int)outnet->pending->count);
|
||||||
@ -1690,7 +1727,7 @@ outside_network_create(struct comm_base *base, size_t bufsize,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
pc->cp = comm_point_create_udp(outnet->base, -1,
|
pc->cp = comm_point_create_udp(outnet->base, -1,
|
||||||
outnet->udp_buff, outnet_udp_cb, outnet, NULL);
|
outnet->udp_buff, 0, outnet_udp_cb, outnet, NULL);
|
||||||
if(!pc->cp) {
|
if(!pc->cp) {
|
||||||
log_err("malloc failed");
|
log_err("malloc failed");
|
||||||
free(pc);
|
free(pc);
|
||||||
@ -2237,7 +2274,7 @@ outnet_tcptimer(void* arg)
|
|||||||
verbose(VERB_CLIENT, "outnet_tcptimer");
|
verbose(VERB_CLIENT, "outnet_tcptimer");
|
||||||
if(w->on_tcp_waiting_list) {
|
if(w->on_tcp_waiting_list) {
|
||||||
/* it is on the waiting list */
|
/* it is on the waiting list */
|
||||||
waiting_list_remove(outnet, w);
|
outnet_waiting_tcp_list_remove(outnet, w);
|
||||||
waiting_tcp_callback(w, NULL, NETEVENT_TIMEOUT, NULL);
|
waiting_tcp_callback(w, NULL, NETEVENT_TIMEOUT, NULL);
|
||||||
waiting_tcp_delete(w);
|
waiting_tcp_delete(w);
|
||||||
} else {
|
} else {
|
||||||
@ -2464,7 +2501,7 @@ pending_tcp_query(struct serviced_query* sq, sldns_buffer* packet,
|
|||||||
#ifdef USE_DNSTAP
|
#ifdef USE_DNSTAP
|
||||||
w->sq = sq;
|
w->sq = sq;
|
||||||
#endif
|
#endif
|
||||||
outnet_add_tcp_waiting(sq->outnet, w);
|
outnet_waiting_tcp_list_add(sq->outnet, w, 1);
|
||||||
}
|
}
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
@ -2545,8 +2582,10 @@ serviced_create(struct outside_network* outnet, sldns_buffer* buff, int dnssec,
|
|||||||
#ifdef UNBOUND_DEBUG
|
#ifdef UNBOUND_DEBUG
|
||||||
rbnode_type* ins;
|
rbnode_type* ins;
|
||||||
#endif
|
#endif
|
||||||
if(!sq)
|
if(!sq) {
|
||||||
|
alloc_reg_release(alloc, region);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
sq->node.key = sq;
|
sq->node.key = sq;
|
||||||
sq->alloc = alloc;
|
sq->alloc = alloc;
|
||||||
sq->region = region;
|
sq->region = region;
|
||||||
@ -2610,30 +2649,6 @@ serviced_create(struct outside_network* outnet, sldns_buffer* buff, int dnssec,
|
|||||||
return sq;
|
return sq;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** remove waiting tcp from the outnet waiting list */
|
|
||||||
static void
|
|
||||||
waiting_list_remove(struct outside_network* outnet, struct waiting_tcp* w)
|
|
||||||
{
|
|
||||||
struct waiting_tcp* p = outnet->tcp_wait_first, *prev = NULL;
|
|
||||||
w->on_tcp_waiting_list = 0;
|
|
||||||
while(p) {
|
|
||||||
if(p == w) {
|
|
||||||
/* remove w */
|
|
||||||
if(prev)
|
|
||||||
prev->next_waiting = w->next_waiting;
|
|
||||||
else outnet->tcp_wait_first = w->next_waiting;
|
|
||||||
if(outnet->tcp_wait_last == w)
|
|
||||||
outnet->tcp_wait_last = prev;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
prev = p;
|
|
||||||
p = p->next_waiting;
|
|
||||||
}
|
|
||||||
/* waiting_list_remove is currently called only with items that are
|
|
||||||
* already in the waiting list. */
|
|
||||||
log_assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** reuse tcp stream, remove serviced query from stream,
|
/** reuse tcp stream, remove serviced query from stream,
|
||||||
* return true if the stream is kept, false if it is to be closed */
|
* return true if the stream is kept, false if it is to be closed */
|
||||||
static int
|
static int
|
||||||
@ -2728,7 +2743,7 @@ serviced_delete(struct serviced_query* sq)
|
|||||||
sq->pending = NULL;
|
sq->pending = NULL;
|
||||||
} else {
|
} else {
|
||||||
verbose(VERB_CLIENT, "serviced_delete: tcpwait");
|
verbose(VERB_CLIENT, "serviced_delete: tcpwait");
|
||||||
waiting_list_remove(sq->outnet, w);
|
outnet_waiting_tcp_list_remove(sq->outnet, w);
|
||||||
if(!w->in_cb_and_decommission)
|
if(!w->in_cb_and_decommission)
|
||||||
waiting_tcp_delete(w);
|
waiting_tcp_delete(w);
|
||||||
}
|
}
|
||||||
@ -3101,8 +3116,8 @@ serviced_tcp_callback(struct comm_point* c, void* arg, int error,
|
|||||||
rep = &r2;
|
rep = &r2;
|
||||||
r2.c = c;
|
r2.c = c;
|
||||||
}
|
}
|
||||||
memcpy(&rep->addr, &sq->addr, sq->addrlen);
|
memcpy(&rep->remote_addr, &sq->addr, sq->addrlen);
|
||||||
rep->addrlen = sq->addrlen;
|
rep->remote_addrlen = sq->addrlen;
|
||||||
serviced_callbacks(sq, error, c, rep);
|
serviced_callbacks(sq, error, c, rep);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -3432,7 +3447,6 @@ outnet_serviced_query(struct outside_network* outnet,
|
|||||||
infra_ratelimit_dec(env->infra_cache,
|
infra_ratelimit_dec(env->infra_cache,
|
||||||
zone, zonelen, timenow);
|
zone, zonelen, timenow);
|
||||||
}
|
}
|
||||||
alloc_reg_release(env->alloc, region);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if(!(cb = (struct service_callback*)regional_alloc(
|
if(!(cb = (struct service_callback*)regional_alloc(
|
||||||
@ -3581,7 +3595,7 @@ outnet_comm_point_for_udp(struct outside_network* outnet,
|
|||||||
if(fd == -1) {
|
if(fd == -1) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
cp = comm_point_create_udp(outnet->base, fd, outnet->udp_buff,
|
cp = comm_point_create_udp(outnet->base, fd, outnet->udp_buff, 0,
|
||||||
cb, cb_arg, NULL);
|
cb, cb_arg, NULL);
|
||||||
if(!cp) {
|
if(!cp) {
|
||||||
log_err("malloc failure");
|
log_err("malloc failure");
|
||||||
@ -3669,8 +3683,8 @@ outnet_comm_point_for_tcp(struct outside_network* outnet,
|
|||||||
close(fd);
|
close(fd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
cp->repinfo.addrlen = to_addrlen;
|
cp->repinfo.remote_addrlen = to_addrlen;
|
||||||
memcpy(&cp->repinfo.addr, to_addr, to_addrlen);
|
memcpy(&cp->repinfo.remote_addr, to_addr, to_addrlen);
|
||||||
|
|
||||||
/* setup for SSL (if needed) */
|
/* setup for SSL (if needed) */
|
||||||
if(ssl) {
|
if(ssl) {
|
||||||
@ -3745,8 +3759,8 @@ outnet_comm_point_for_http(struct outside_network* outnet,
|
|||||||
close(fd);
|
close(fd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
cp->repinfo.addrlen = to_addrlen;
|
cp->repinfo.remote_addrlen = to_addrlen;
|
||||||
memcpy(&cp->repinfo.addr, to_addr, to_addrlen);
|
memcpy(&cp->repinfo.remote_addr, to_addr, to_addrlen);
|
||||||
|
|
||||||
/* setup for SSL (if needed) */
|
/* setup for SSL (if needed) */
|
||||||
if(ssl) {
|
if(ssl) {
|
||||||
|
@ -718,6 +718,30 @@ struct reuse_tcp* reuse_tcp_lru_snip(struct outside_network* outnet);
|
|||||||
/** delete readwait waiting_tcp elements, deletes the elements in the list */
|
/** delete readwait waiting_tcp elements, deletes the elements in the list */
|
||||||
void reuse_del_readwait(rbtree_type* tree_by_id);
|
void reuse_del_readwait(rbtree_type* tree_by_id);
|
||||||
|
|
||||||
|
/** remove waiting tcp from the outnet waiting list */
|
||||||
|
void outnet_waiting_tcp_list_remove(struct outside_network* outnet,
|
||||||
|
struct waiting_tcp* w);
|
||||||
|
|
||||||
|
/** pop the first waiting tcp from the outnet waiting list */
|
||||||
|
struct waiting_tcp* outnet_waiting_tcp_list_pop(struct outside_network* outnet);
|
||||||
|
|
||||||
|
/** add waiting_tcp element to the outnet tcp waiting list */
|
||||||
|
void outnet_waiting_tcp_list_add(struct outside_network* outnet,
|
||||||
|
struct waiting_tcp* w, int set_timer);
|
||||||
|
|
||||||
|
/** add waiting_tcp element as first to the outnet tcp waiting list */
|
||||||
|
void outnet_waiting_tcp_list_add_first(struct outside_network* outnet,
|
||||||
|
struct waiting_tcp* w, int reset_timer);
|
||||||
|
|
||||||
|
/** pop the first element from the writewait list */
|
||||||
|
struct waiting_tcp* reuse_write_wait_pop(struct reuse_tcp* reuse);
|
||||||
|
|
||||||
|
/** remove the element from the writewait list */
|
||||||
|
void reuse_write_wait_remove(struct reuse_tcp* reuse, struct waiting_tcp* w);
|
||||||
|
|
||||||
|
/** push the element after the last on the writewait list */
|
||||||
|
void reuse_write_wait_push_back(struct reuse_tcp* reuse, struct waiting_tcp* w);
|
||||||
|
|
||||||
/** get TCP file descriptor for address, returns -1 on failure,
|
/** get TCP file descriptor for address, returns -1 on failure,
|
||||||
* tcp_mss is 0 or maxseg size to set for TCP packets. */
|
* tcp_mss is 0 or maxseg size to set for TCP packets. */
|
||||||
int outnet_get_tcp_fd(struct sockaddr_storage* addr, socklen_t addrlen,
|
int outnet_get_tcp_fd(struct sockaddr_storage* addr, socklen_t addrlen,
|
||||||
|
@ -1392,11 +1392,13 @@ log_rpz_apply(char* trigger, uint8_t* dname, struct addr_tree_node* addrnode,
|
|||||||
dnamestr[0]=0;
|
dnamestr[0]=0;
|
||||||
}
|
}
|
||||||
if(repinfo) {
|
if(repinfo) {
|
||||||
addr_to_str(&repinfo->addr, repinfo->addrlen, ip, sizeof(ip));
|
addr_to_str(&repinfo->client_addr, repinfo->client_addrlen, ip, sizeof(ip));
|
||||||
port = ntohs(((struct sockaddr_in*)&repinfo->addr)->sin_port);
|
port = ntohs(((struct sockaddr_in*)&repinfo->client_addr)->sin_port);
|
||||||
} else if(ms && ms->mesh_info && ms->mesh_info->reply_list) {
|
} else if(ms && ms->mesh_info && ms->mesh_info->reply_list) {
|
||||||
addr_to_str(&ms->mesh_info->reply_list->query_reply.addr, ms->mesh_info->reply_list->query_reply.addrlen, ip, sizeof(ip));
|
addr_to_str(&ms->mesh_info->reply_list->query_reply.client_addr,
|
||||||
port = ntohs(((struct sockaddr_in*)&ms->mesh_info->reply_list->query_reply.addr)->sin_port);
|
ms->mesh_info->reply_list->query_reply.client_addrlen,
|
||||||
|
ip, sizeof(ip));
|
||||||
|
port = ntohs(((struct sockaddr_in*)&ms->mesh_info->reply_list->query_reply.client_addr)->sin_port);
|
||||||
} else {
|
} else {
|
||||||
ip[0]=0;
|
ip[0]=0;
|
||||||
port = 0;
|
port = 0;
|
||||||
@ -1468,7 +1470,9 @@ rpz_resolve_client_action_and_zone(struct auth_zones* az, struct query_info* qin
|
|||||||
}
|
}
|
||||||
z = rpz_find_zone(r->local_zones, qinfo->qname, qinfo->qname_len,
|
z = rpz_find_zone(r->local_zones, qinfo->qname, qinfo->qname_len,
|
||||||
qinfo->qclass, 0, 0, 0);
|
qinfo->qclass, 0, 0, 0);
|
||||||
node = rpz_ipbased_trigger_lookup(r->client_set, &repinfo->addr, repinfo->addrlen, "clientip");
|
node = rpz_ipbased_trigger_lookup(r->client_set,
|
||||||
|
&repinfo->client_addr, repinfo->client_addrlen,
|
||||||
|
"clientip");
|
||||||
if((z || node) && r->action_override == RPZ_DISABLED_ACTION) {
|
if((z || node) && r->action_override == RPZ_DISABLED_ACTION) {
|
||||||
if(r->log)
|
if(r->log)
|
||||||
log_rpz_apply((node?"clientip":"qname"),
|
log_rpz_apply((node?"clientip":"qname"),
|
||||||
@ -2164,18 +2168,16 @@ rpz_callback_from_iterator_module(struct module_qstate* ms, struct iter_qstate*
|
|||||||
|
|
||||||
lock_rw_unlock(&az->rpz_lock);
|
lock_rw_unlock(&az->rpz_lock);
|
||||||
|
|
||||||
if(raddr == NULL && z == NULL) { return NULL; }
|
if(raddr == NULL && z == NULL)
|
||||||
else if(raddr != NULL) {
|
return NULL;
|
||||||
|
|
||||||
|
if(raddr != NULL) {
|
||||||
if(z) {
|
if(z) {
|
||||||
lock_rw_unlock(&z->lock);
|
lock_rw_unlock(&z->lock);
|
||||||
}
|
}
|
||||||
return rpz_apply_nsip_trigger(ms, r, raddr, a);
|
return rpz_apply_nsip_trigger(ms, r, raddr, a);
|
||||||
} else if(z != NULL) {
|
|
||||||
if(raddr) {
|
|
||||||
lock_rw_unlock(&raddr->lock);
|
|
||||||
}
|
}
|
||||||
return rpz_apply_nsdname_trigger(ms, r, z, &match, a);
|
return rpz_apply_nsdname_trigger(ms, r, z, &match, a);
|
||||||
} else { return NULL; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct dns_msg* rpz_callback_from_iterator_cname(struct module_qstate* ms,
|
struct dns_msg* rpz_callback_from_iterator_cname(struct module_qstate* ms,
|
||||||
|
@ -66,7 +66,8 @@ views_create(void)
|
|||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** This prototype is defined in in respip.h, but we want to avoid
|
/* \noop (ignore this comment for doxygen)
|
||||||
|
* This prototype is defined in in respip.h, but we want to avoid
|
||||||
* unnecessary dependencies */
|
* unnecessary dependencies */
|
||||||
void respip_set_delete(struct respip_set *set);
|
void respip_set_delete(struct respip_set *set);
|
||||||
|
|
||||||
|
@ -316,7 +316,7 @@ warn_hosts(const char* typ, struct config_stub* list)
|
|||||||
struct config_strlist* h;
|
struct config_strlist* h;
|
||||||
for(s=list; s; s=s->next) {
|
for(s=list; s; s=s->next) {
|
||||||
for(h=s->hosts; h; h=h->next) {
|
for(h=s->hosts; h; h=h->next) {
|
||||||
if(extstrtoaddr(h->str, &a, &alen)) {
|
if(extstrtoaddr(h->str, &a, &alen, UNBOUND_DNS_PORT)) {
|
||||||
fprintf(stderr, "unbound-checkconf: warning:"
|
fprintf(stderr, "unbound-checkconf: warning:"
|
||||||
" %s %s: \"%s\" is an IP%s address, "
|
" %s %s: \"%s\" is an IP%s address, "
|
||||||
"and when looked up as a host name "
|
"and when looked up as a host name "
|
||||||
@ -338,6 +338,8 @@ interfacechecks(struct config_file* cfg)
|
|||||||
int i, j, i2, j2;
|
int i, j, i2, j2;
|
||||||
char*** resif = NULL;
|
char*** resif = NULL;
|
||||||
int* num_resif = NULL;
|
int* num_resif = NULL;
|
||||||
|
char portbuf[32];
|
||||||
|
snprintf(portbuf, sizeof(portbuf), "%d", cfg->port);
|
||||||
|
|
||||||
if(cfg->num_ifs != 0) {
|
if(cfg->num_ifs != 0) {
|
||||||
resif = (char***)calloc(cfg->num_ifs, sizeof(char**));
|
resif = (char***)calloc(cfg->num_ifs, sizeof(char**));
|
||||||
@ -359,9 +361,21 @@ interfacechecks(struct config_file* cfg)
|
|||||||
fatal_exit("could not resolve interface names, for %s",
|
fatal_exit("could not resolve interface names, for %s",
|
||||||
cfg->ifs[i]);
|
cfg->ifs[i]);
|
||||||
}
|
}
|
||||||
|
/* check for port combinations that are not supported */
|
||||||
|
if(if_is_pp2(resif[i][0], portbuf, cfg->proxy_protocol_port)) {
|
||||||
|
if(if_is_dnscrypt(resif[i][0], portbuf,
|
||||||
|
cfg->dnscrypt_port)) {
|
||||||
|
fatal_exit("PROXYv2 and DNSCrypt combination not "
|
||||||
|
"supported!");
|
||||||
|
} else if(if_is_https(resif[i][0], portbuf,
|
||||||
|
cfg->https_port)) {
|
||||||
|
fatal_exit("PROXYv2 and DoH combination not "
|
||||||
|
"supported!");
|
||||||
|
}
|
||||||
|
}
|
||||||
/* search for duplicates in the returned addresses */
|
/* search for duplicates in the returned addresses */
|
||||||
for(j=0; j<num_resif[i]; j++) {
|
for(j=0; j<num_resif[i]; j++) {
|
||||||
if(!extstrtoaddr(resif[i][j], &a, &alen)) {
|
if(!extstrtoaddr(resif[i][j], &a, &alen, cfg->port)) {
|
||||||
if(strcmp(cfg->ifs[i], resif[i][j]) != 0)
|
if(strcmp(cfg->ifs[i], resif[i][j]) != 0)
|
||||||
fatal_exit("cannot parse interface address '%s' from the interface specified as '%s'",
|
fatal_exit("cannot parse interface address '%s' from the interface specified as '%s'",
|
||||||
resif[i][j], cfg->ifs[i]);
|
resif[i][j], cfg->ifs[i]);
|
||||||
|
@ -601,7 +601,7 @@ contact_server(const char* svr, struct config_file* cfg, int statuscmd)
|
|||||||
struct sockaddr_storage addr2;
|
struct sockaddr_storage addr2;
|
||||||
socklen_t addrlen2;
|
socklen_t addrlen2;
|
||||||
if(extstrtoaddr(cfg->control_ifs.first->str, &addr2,
|
if(extstrtoaddr(cfg->control_ifs.first->str, &addr2,
|
||||||
&addrlen2)) {
|
&addrlen2, UNBOUND_DNS_PORT)) {
|
||||||
svr = cfg->control_ifs.first->str;
|
svr = cfg->control_ifs.first->str;
|
||||||
} else {
|
} else {
|
||||||
if(!resolve_interface_names(NULL, 0,
|
if(!resolve_interface_names(NULL, 0,
|
||||||
@ -629,7 +629,7 @@ contact_server(const char* svr, struct config_file* cfg, int statuscmd)
|
|||||||
svr = "::1";
|
svr = "::1";
|
||||||
}
|
}
|
||||||
if(strchr(svr, '@')) {
|
if(strchr(svr, '@')) {
|
||||||
if(!extstrtoaddr(svr, &addr, &addrlen))
|
if(!extstrtoaddr(svr, &addr, &addrlen, UNBOUND_DNS_PORT))
|
||||||
fatal_exit("could not parse IP@port: %s", svr);
|
fatal_exit("could not parse IP@port: %s", svr);
|
||||||
#ifdef HAVE_SYS_UN_H
|
#ifdef HAVE_SYS_UN_H
|
||||||
} else if(svr[0] == '/') {
|
} else if(svr[0] == '/') {
|
||||||
|
@ -974,7 +974,7 @@ service(const char* bind_str, int bindport, const char* serv_str,
|
|||||||
dl_tv_add(&reuse, &delay);
|
dl_tv_add(&reuse, &delay);
|
||||||
if(reuse.tv_sec == 0)
|
if(reuse.tv_sec == 0)
|
||||||
reuse.tv_sec = 1;
|
reuse.tv_sec = 1;
|
||||||
if(!extstrtoaddr(serv_str, &srv_addr, &srv_len)) {
|
if(!extstrtoaddr(serv_str, &srv_addr, &srv_len, UNBOUND_DNS_PORT)) {
|
||||||
printf("cannot parse forward address: %s\n", serv_str);
|
printf("cannot parse forward address: %s\n", serv_str);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ NEED_WHOAMI='07-confroot.tdir'
|
|||||||
NEED_IPV6='fwd_ancil.tdir fwd_tcp_tc6.tdir stub_udp6.tdir edns_cache.tdir'
|
NEED_IPV6='fwd_ancil.tdir fwd_tcp_tc6.tdir stub_udp6.tdir edns_cache.tdir'
|
||||||
NEED_NOMINGW='tcp_sigpipe.tdir 07-confroot.tdir 08-host-lib.tdir fwd_ancil.tdir'
|
NEED_NOMINGW='tcp_sigpipe.tdir 07-confroot.tdir 08-host-lib.tdir fwd_ancil.tdir'
|
||||||
NEED_DNSCRYPT_PROXY='dnscrypt_queries.tdir dnscrypt_queries_chacha.tdir'
|
NEED_DNSCRYPT_PROXY='dnscrypt_queries.tdir dnscrypt_queries_chacha.tdir'
|
||||||
|
NEED_UNSHARE='acl_interface.tdir proxy_protocol.tdir'
|
||||||
|
|
||||||
# test if dig and ldns-testns are available.
|
# test if dig and ldns-testns are available.
|
||||||
test_tool_avail "dig"
|
test_tool_avail "dig"
|
||||||
@ -50,6 +51,7 @@ for test in `ls -d *.tdir`; do
|
|||||||
skip_if_in_list $test "$NEED_NC" "nc"
|
skip_if_in_list $test "$NEED_NC" "nc"
|
||||||
skip_if_in_list $test "$NEED_WHOAMI" "whoami"
|
skip_if_in_list $test "$NEED_WHOAMI" "whoami"
|
||||||
skip_if_in_list $test "$NEED_DNSCRYPT_PROXY" "dnscrypt-proxy"
|
skip_if_in_list $test "$NEED_DNSCRYPT_PROXY" "dnscrypt-proxy"
|
||||||
|
skip_if_in_list $test "$NEED_UNSHARE" "unshare"
|
||||||
|
|
||||||
if echo $NEED_IPV6 | grep $test >/dev/null; then
|
if echo $NEED_IPV6 | grep $test >/dev/null; then
|
||||||
if test "$HAVE_IPV6" = no; then
|
if test "$HAVE_IPV6" = no; then
|
||||||
|
@ -384,8 +384,8 @@ answer_callback_from_entry(struct replay_runtime* runtime,
|
|||||||
fill_buffer_with_reply(c.buffer, entry, pend->pkt, pend->pkt_len,
|
fill_buffer_with_reply(c.buffer, entry, pend->pkt, pend->pkt_len,
|
||||||
pend->tcp_pkt_counter);
|
pend->tcp_pkt_counter);
|
||||||
repinfo.c = &c;
|
repinfo.c = &c;
|
||||||
repinfo.addrlen = pend->addrlen;
|
repinfo.remote_addrlen = pend->addrlen;
|
||||||
memcpy(&repinfo.addr, &pend->addr, pend->addrlen);
|
memcpy(&repinfo.remote_addr, &pend->addr, pend->addrlen);
|
||||||
if(!pend->serviced) {
|
if(!pend->serviced) {
|
||||||
if(entry && entry->reply_list->next &&
|
if(entry && entry->reply_list->next &&
|
||||||
pend->tcp_pkt_counter < count_reply_packets(entry)) {
|
pend->tcp_pkt_counter < count_reply_packets(entry)) {
|
||||||
@ -415,7 +415,7 @@ answer_check_it(struct replay_runtime* runtime)
|
|||||||
tr = transport_udp;
|
tr = transport_udp;
|
||||||
if((runtime->now->addrlen == 0 || sockaddr_cmp(
|
if((runtime->now->addrlen == 0 || sockaddr_cmp(
|
||||||
&runtime->now->addr, runtime->now->addrlen,
|
&runtime->now->addr, runtime->now->addrlen,
|
||||||
&ans->repinfo.addr, ans->repinfo.addrlen) == 0) &&
|
&ans->repinfo.remote_addr, ans->repinfo.remote_addrlen) == 0) &&
|
||||||
find_match(runtime->now->match, ans->pkt,
|
find_match(runtime->now->match, ans->pkt,
|
||||||
ans->pkt_len, tr)) {
|
ans->pkt_len, tr)) {
|
||||||
log_info("testbound matched event entry from line %d",
|
log_info("testbound matched event entry from line %d",
|
||||||
@ -453,10 +453,12 @@ fake_front_query(struct replay_runtime* runtime, struct replay_moment *todo)
|
|||||||
repinfo.c = (struct comm_point*)calloc(1, sizeof(struct comm_point));
|
repinfo.c = (struct comm_point*)calloc(1, sizeof(struct comm_point));
|
||||||
if(!repinfo.c)
|
if(!repinfo.c)
|
||||||
fatal_exit("out of memory in fake_front_query");
|
fatal_exit("out of memory in fake_front_query");
|
||||||
repinfo.addrlen = (socklen_t)sizeof(struct sockaddr_in);
|
repinfo.remote_addrlen = (socklen_t)sizeof(struct sockaddr_in);
|
||||||
if(todo->addrlen != 0) {
|
if(todo->addrlen != 0) {
|
||||||
repinfo.addrlen = todo->addrlen;
|
repinfo.remote_addrlen = todo->addrlen;
|
||||||
memcpy(&repinfo.addr, &todo->addr, todo->addrlen);
|
memcpy(&repinfo.remote_addr, &todo->addr, todo->addrlen);
|
||||||
|
repinfo.client_addrlen = todo->addrlen;
|
||||||
|
memcpy(&repinfo.client_addr, &todo->addr, todo->addrlen);
|
||||||
}
|
}
|
||||||
repinfo.c->fd = -1;
|
repinfo.c->fd = -1;
|
||||||
repinfo.c->ev = (struct internal_event*)runtime;
|
repinfo.c->ev = (struct internal_event*)runtime;
|
||||||
@ -510,8 +512,8 @@ fake_pending_callback(struct replay_runtime* runtime,
|
|||||||
p->pkt_len, p->tcp_pkt_counter);
|
p->pkt_len, p->tcp_pkt_counter);
|
||||||
}
|
}
|
||||||
repinfo.c = &c;
|
repinfo.c = &c;
|
||||||
repinfo.addrlen = p->addrlen;
|
repinfo.remote_addrlen = p->addrlen;
|
||||||
memcpy(&repinfo.addr, &p->addr, p->addrlen);
|
memcpy(&repinfo.remote_addr, &p->addr, p->addrlen);
|
||||||
if(!p->serviced) {
|
if(!p->serviced) {
|
||||||
if(todo->match && todo->match->reply_list->next && !error &&
|
if(todo->match && todo->match->reply_list->next && !error &&
|
||||||
p->tcp_pkt_counter < count_reply_packets(todo->match)) {
|
p->tcp_pkt_counter < count_reply_packets(todo->match)) {
|
||||||
@ -1344,7 +1346,7 @@ struct listen_port* listening_ports_open(struct config_file* ATTR_UNUSED(cfg),
|
|||||||
char** ATTR_UNUSED(ifs), int ATTR_UNUSED(num_ifs),
|
char** ATTR_UNUSED(ifs), int ATTR_UNUSED(num_ifs),
|
||||||
int* ATTR_UNUSED(reuseport))
|
int* ATTR_UNUSED(reuseport))
|
||||||
{
|
{
|
||||||
return calloc(1, 1);
|
return calloc(1, sizeof(struct listen_port));
|
||||||
}
|
}
|
||||||
|
|
||||||
void listening_ports_free(struct listen_port* list)
|
void listening_ports_free(struct listen_port* list)
|
||||||
@ -1663,6 +1665,7 @@ int create_udp_sock(int ATTR_UNUSED(family), int ATTR_UNUSED(socktype),
|
|||||||
|
|
||||||
struct comm_point* comm_point_create_udp(struct comm_base *ATTR_UNUSED(base),
|
struct comm_point* comm_point_create_udp(struct comm_base *ATTR_UNUSED(base),
|
||||||
int ATTR_UNUSED(fd), sldns_buffer* ATTR_UNUSED(buffer),
|
int ATTR_UNUSED(fd), sldns_buffer* ATTR_UNUSED(buffer),
|
||||||
|
int ATTR_UNUSED(pp2_enabled),
|
||||||
comm_point_callback_type* ATTR_UNUSED(callback),
|
comm_point_callback_type* ATTR_UNUSED(callback),
|
||||||
void* ATTR_UNUSED(callback_arg),
|
void* ATTR_UNUSED(callback_arg),
|
||||||
struct unbound_socket* ATTR_UNUSED(socket))
|
struct unbound_socket* ATTR_UNUSED(socket))
|
||||||
|
@ -8,6 +8,7 @@ fi
|
|||||||
|
|
||||||
# This will keep the temporary directory around and return 1 when the test failed.
|
# This will keep the temporary directory around and return 1 when the test failed.
|
||||||
DEBUG=0
|
DEBUG=0
|
||||||
|
test -n "$DEBUG_TDIR" && DEBUG=1
|
||||||
|
|
||||||
quiet=0
|
quiet=0
|
||||||
if test "$1" = "-q"; then
|
if test "$1" = "-q"; then
|
||||||
@ -17,9 +18,9 @@ fi
|
|||||||
|
|
||||||
if test "$1" = "clean"; then
|
if test "$1" = "clean"; then
|
||||||
if test $quiet = 0; then
|
if test $quiet = 0; then
|
||||||
echo "rm -f result.* .done* .tdir.var.master .tdir.var.test"
|
echo "rm -f result.* .done* .skip* .tdir.var.master .tdir.var.test"
|
||||||
fi
|
fi
|
||||||
rm -f result.* .done* .tdir.var.master .tdir.var.test
|
rm -f result.* .done* .skip* .tdir.var.master .tdir.var.test
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
if test "$1" = "fake"; then
|
if test "$1" = "fake"; then
|
||||||
@ -54,12 +55,15 @@ if test "$1" = "-f" && test "$2" = "report"; then
|
|||||||
echo "** PASSED ** $timelen $name: $desc"
|
echo "** PASSED ** $timelen $name: $desc"
|
||||||
pass=`expr $pass + 1`
|
pass=`expr $pass + 1`
|
||||||
fi
|
fi
|
||||||
|
elif test -f ".skip-$name"; then
|
||||||
|
echo ".. SKIPPED.. $timelen $name: $desc"
|
||||||
|
skip=`expr $skip + 1`
|
||||||
else
|
else
|
||||||
if test -f "result.$name"; then
|
if test -f "result.$name"; then
|
||||||
echo "!! FAILED !! $timelen $name: $desc"
|
echo "!! FAILED !! $timelen $name: $desc"
|
||||||
fail=`expr $fail + 1`
|
fail=`expr $fail + 1`
|
||||||
else
|
else
|
||||||
echo ".> SKIPPED<< $timelen $name: $desc"
|
echo ".. SKIPPED.. $timelen $name: $desc"
|
||||||
skip=`expr $skip + 1`
|
skip=`expr $skip + 1`
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
@ -81,11 +85,17 @@ if test "$1" = "report" || test "$2" = "report"; then
|
|||||||
if test $quiet = 0; then
|
if test $quiet = 0; then
|
||||||
echo "** PASSED ** : $name"
|
echo "** PASSED ** : $name"
|
||||||
fi
|
fi
|
||||||
|
elif test -f ".skip-$name"; then
|
||||||
|
if test $quiet = 0; then
|
||||||
|
echo ".. SKIPPED.. : $name"
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
if test -f "result.$name"; then
|
if test -f "result.$name"; then
|
||||||
echo "!! FAILED !! : $name"
|
echo "!! FAILED !! : $name"
|
||||||
else
|
else
|
||||||
echo ">> SKIPPED<< : $name"
|
if test $quiet = 0; then
|
||||||
|
echo ".. SKIPPED.. : $name"
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
@ -116,6 +126,7 @@ name=`basename $1 .tdir`
|
|||||||
dir=$name.$$
|
dir=$name.$$
|
||||||
result=result.$name
|
result=result.$name
|
||||||
done=.done-$name
|
done=.done-$name
|
||||||
|
skip=.skip-$name
|
||||||
success="no"
|
success="no"
|
||||||
if test -x "`which bash`"; then
|
if test -x "`which bash`"; then
|
||||||
shell="bash"
|
shell="bash"
|
||||||
@ -124,8 +135,8 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# check already done
|
# check already done
|
||||||
if test -f .done-$name; then
|
if test -f $done; then
|
||||||
echo "minitdir .done-$name exists. skip test."
|
echo "minitdir $done exists. skip test."
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -151,11 +162,16 @@ if test -f $name.pre; then
|
|||||||
fi
|
fi
|
||||||
echo "minitdir exe $name.pre" >> $result
|
echo "minitdir exe $name.pre" >> $result
|
||||||
$shell $name.pre $args >> $result
|
$shell $name.pre $args >> $result
|
||||||
if test $? -ne 0; then
|
exit_value=$?
|
||||||
|
if test $exit_value -eq 3; then
|
||||||
|
echo "$name: SKIPPED" >> $result
|
||||||
|
echo "$name: SKIPPED" > ../$skip
|
||||||
|
echo "$name: SKIPPED"
|
||||||
|
elif test $exit_value -ne 0; then
|
||||||
echo "Warning: $name.pre did not exit successfully"
|
echo "Warning: $name.pre did not exit successfully"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
if test -f $name.test; then
|
if test -f $name.test -a ! -f ../$skip; then
|
||||||
if test $quiet = 0; then
|
if test $quiet = 0; then
|
||||||
echo "minitdir exe $name.test"
|
echo "minitdir exe $name.test"
|
||||||
fi
|
fi
|
||||||
@ -167,14 +183,14 @@ if test -f $name.test; then
|
|||||||
success="no"
|
success="no"
|
||||||
else
|
else
|
||||||
echo "$name: PASSED" >> $result
|
echo "$name: PASSED" >> $result
|
||||||
echo "$name: PASSED" > ../.done-$name
|
echo "$name: PASSED" > ../$done
|
||||||
if test $quiet = 0; then
|
if test $quiet = 0; then
|
||||||
echo "$name: PASSED"
|
echo "$name: PASSED"
|
||||||
fi
|
fi
|
||||||
success="yes"
|
success="yes"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
if test -f $name.post; then
|
if test -f $name.post -a ! -f ../$skip; then
|
||||||
if test $quiet = 0; then
|
if test $quiet = 0; then
|
||||||
echo "minitdir exe $name.post"
|
echo "minitdir exe $name.post"
|
||||||
fi
|
fi
|
||||||
@ -198,7 +214,7 @@ if test $DEBUG -eq 0; then
|
|||||||
rm -rf $dir
|
rm -rf $dir
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
if test $success == "no"; then
|
if test $success = "no"; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
exit 0
|
exit 0
|
||||||
|
@ -1,128 +0,0 @@
|
|||||||
# tpkg that only exes the files.
|
|
||||||
args="../.."
|
|
||||||
if test "$1" = "-a"; then
|
|
||||||
args=$2
|
|
||||||
shift
|
|
||||||
shift
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test "$1" = "clean"; then
|
|
||||||
echo "rm -f result.* .done* .tpkg.var.master .tpkg.var.test"
|
|
||||||
rm -f result.* .done* .tpkg.var.master .tpkg.var.test
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
if test "$1" = "fake"; then
|
|
||||||
echo "minitpkg fake $2"
|
|
||||||
echo "fake" > .done-`basename $2 .tpkg`
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
if test "$1" = "report" || test "$2" = "report"; then
|
|
||||||
echo "Minitpkg Report"
|
|
||||||
for result in *.tpkg; do
|
|
||||||
name=`basename $result .tpkg`
|
|
||||||
if test -f ".done-$name"; then
|
|
||||||
if test "$1" != "-q"; then
|
|
||||||
echo "** PASSED ** : $name"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
if test -f "result.$name"; then
|
|
||||||
echo "!! FAILED !! : $name"
|
|
||||||
else
|
|
||||||
echo ">> SKIPPED<< : $name"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test "$1" != 'exe'; then
|
|
||||||
# usage
|
|
||||||
echo "mini tpkg. Reduced functionality for old shells."
|
|
||||||
echo " tpkg exe <file>"
|
|
||||||
echo " tpkg fake <file>"
|
|
||||||
echo " tpkg clean"
|
|
||||||
echo " tpkg [-q] report"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
shift
|
|
||||||
|
|
||||||
# do not execute if the disk is too full
|
|
||||||
#DISKLIMIT=100000
|
|
||||||
# This check is not portable (to Solaris 10).
|
|
||||||
#avail=`df . | tail -1 | awk '{print $4}'`
|
|
||||||
#if test "$avail" -lt "$DISKLIMIT"; then
|
|
||||||
#echo "minitpkg: The disk is too full! Only $avail."
|
|
||||||
#exit 1
|
|
||||||
#fi
|
|
||||||
|
|
||||||
name=`basename $1 .tpkg`
|
|
||||||
dir=$name.$$
|
|
||||||
result=result.$name
|
|
||||||
done=.done-$name
|
|
||||||
success="no"
|
|
||||||
if test -x "`which bash`"; then
|
|
||||||
shell="bash"
|
|
||||||
else
|
|
||||||
shell="sh"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# check already done
|
|
||||||
if test -f .done-$name; then
|
|
||||||
echo "minitpkg .done-$name exists. skip test."
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Extract
|
|
||||||
echo "minitpkg extract $1 to $dir"
|
|
||||||
mkdir $dir
|
|
||||||
gzip -cd $name.tpkg | (cd $dir; tar xf -)
|
|
||||||
cd $dir
|
|
||||||
mv $name.dir/* .
|
|
||||||
|
|
||||||
# EXE
|
|
||||||
echo "minitpkg exe $name" > $result
|
|
||||||
grep "Description:" $name.dsc >> $result 2>&1
|
|
||||||
echo "DateRunStart: "`date "+%s" 2>/dev/null` >> $result
|
|
||||||
if test -f $name.pre; then
|
|
||||||
echo "minitpkg exe $name.pre"
|
|
||||||
echo "minitpkg exe $name.pre" >> $result
|
|
||||||
$shell $name.pre $args >> $result
|
|
||||||
if test $? -ne 0; then
|
|
||||||
echo "Warning: $name.pre did not exit successfully"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
if test -f $name.test; then
|
|
||||||
echo "minitpkg exe $name.test"
|
|
||||||
echo "minitpkg exe $name.test" >> $result
|
|
||||||
$shell $name.test $args >>$result 2>&1
|
|
||||||
if test $? -ne 0; then
|
|
||||||
echo "$name: FAILED" >> $result
|
|
||||||
echo "$name: FAILED"
|
|
||||||
success="no"
|
|
||||||
else
|
|
||||||
echo "$name: PASSED" >> $result
|
|
||||||
echo "$name: PASSED" > ../.done-$name
|
|
||||||
echo "$name: PASSED"
|
|
||||||
success="yes"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
if test -f $name.post; then
|
|
||||||
echo "minitpkg exe $name.post"
|
|
||||||
echo "minitpkg exe $name.post" >> $result
|
|
||||||
$shell $name.post $args >> $result
|
|
||||||
if test $? -ne 0; then
|
|
||||||
echo "Warning: $name.post did not exit successfully"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
echo "DateRunEnd: "`date "+%s" 2>/dev/null` >> $result
|
|
||||||
|
|
||||||
mv $result ..
|
|
||||||
cd ..
|
|
||||||
rm -rf $dir
|
|
||||||
# compat for windows where deletion may not succeed initially (files locked
|
|
||||||
# by processes that still have to exit).
|
|
||||||
if test $? -eq 1; then
|
|
||||||
echo "minitpkg waiting for processes to terminate"
|
|
||||||
sleep 2 # some time to exit, and try again
|
|
||||||
rm -rf $dir
|
|
||||||
fi
|
|
@ -618,7 +618,7 @@ int main(int argc, char* argv[])
|
|||||||
printf("error: pass server IP address on commandline.\n");
|
printf("error: pass server IP address on commandline.\n");
|
||||||
usage(nm);
|
usage(nm);
|
||||||
}
|
}
|
||||||
if(!extstrtoaddr(argv[0], &info.dest, &info.destlen)) {
|
if(!extstrtoaddr(argv[0], &info.dest, &info.destlen, UNBOUND_DNS_PORT)) {
|
||||||
printf("Could not parse ip: %s\n", argv[0]);
|
printf("Could not parse ip: %s\n", argv[0]);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
@ -179,7 +179,8 @@ replay_range_read(char* remain, FILE* in, const char* name,
|
|||||||
while(isspace((unsigned char)*parse))
|
while(isspace((unsigned char)*parse))
|
||||||
parse++;
|
parse++;
|
||||||
strip_end_white(parse);
|
strip_end_white(parse);
|
||||||
if(!extstrtoaddr(parse, &rng->addr, &rng->addrlen)) {
|
if(!extstrtoaddr(parse, &rng->addr, &rng->addrlen,
|
||||||
|
UNBOUND_DNS_PORT)) {
|
||||||
log_err("Line %d: could not read ADDRESS: %s",
|
log_err("Line %d: could not read ADDRESS: %s",
|
||||||
pstate->lineno, parse);
|
pstate->lineno, parse);
|
||||||
free(rng);
|
free(rng);
|
||||||
@ -287,7 +288,8 @@ replay_moment_read(char* remain, FILE* in, const char* name,
|
|||||||
} else if(parse_keyword(&remain, "QUERY")) {
|
} else if(parse_keyword(&remain, "QUERY")) {
|
||||||
mom->evt_type = repevt_front_query;
|
mom->evt_type = repevt_front_query;
|
||||||
readentry = 1;
|
readentry = 1;
|
||||||
if(!extstrtoaddr("127.0.0.1", &mom->addr, &mom->addrlen))
|
if(!extstrtoaddr("127.0.0.1", &mom->addr, &mom->addrlen,
|
||||||
|
UNBOUND_DNS_PORT))
|
||||||
fatal_exit("internal error");
|
fatal_exit("internal error");
|
||||||
} else if(parse_keyword(&remain, "CHECK_ANSWER")) {
|
} else if(parse_keyword(&remain, "CHECK_ANSWER")) {
|
||||||
mom->evt_type = repevt_front_reply;
|
mom->evt_type = repevt_front_reply;
|
||||||
@ -354,7 +356,7 @@ replay_moment_read(char* remain, FILE* in, const char* name,
|
|||||||
m++;
|
m++;
|
||||||
while(isspace((unsigned char)*m))
|
while(isspace((unsigned char)*m))
|
||||||
m++;
|
m++;
|
||||||
if(!extstrtoaddr(s, &mom->addr, &mom->addrlen))
|
if(!extstrtoaddr(s, &mom->addr, &mom->addrlen, UNBOUND_DNS_PORT))
|
||||||
fatal_exit("bad infra_rtt address %s", s);
|
fatal_exit("bad infra_rtt address %s", s);
|
||||||
strip_end_white(m);
|
strip_end_white(m);
|
||||||
mom->variable = strdup(remain);
|
mom->variable = strdup(remain);
|
||||||
@ -372,7 +374,8 @@ replay_moment_read(char* remain, FILE* in, const char* name,
|
|||||||
while(isspace((unsigned char)*remain))
|
while(isspace((unsigned char)*remain))
|
||||||
remain++;
|
remain++;
|
||||||
strip_end_white(remain);
|
strip_end_white(remain);
|
||||||
if(!extstrtoaddr(remain, &mom->addr, &mom->addrlen)) {
|
if(!extstrtoaddr(remain, &mom->addr, &mom->addrlen,
|
||||||
|
UNBOUND_DNS_PORT)) {
|
||||||
log_err("line %d: could not parse ADDRESS: %s",
|
log_err("line %d: could not parse ADDRESS: %s",
|
||||||
pstate->lineno, remain);
|
pstate->lineno, remain);
|
||||||
free(mom);
|
free(mom);
|
||||||
|
@ -49,6 +49,7 @@
|
|||||||
#include "util/locks.h"
|
#include "util/locks.h"
|
||||||
#include "util/log.h"
|
#include "util/log.h"
|
||||||
#include "util/net_help.h"
|
#include "util/net_help.h"
|
||||||
|
#include "util/proxy_protocol.h"
|
||||||
#include "util/data/msgencode.h"
|
#include "util/data/msgencode.h"
|
||||||
#include "util/data/msgparse.h"
|
#include "util/data/msgparse.h"
|
||||||
#include "util/data/msgreply.h"
|
#include "util/data/msgreply.h"
|
||||||
@ -71,6 +72,7 @@ static void usage(char* argv[])
|
|||||||
printf("usage: %s [options] name type class ...\n", argv[0]);
|
printf("usage: %s [options] name type class ...\n", argv[0]);
|
||||||
printf(" sends the name-type-class queries over TCP.\n");
|
printf(" sends the name-type-class queries over TCP.\n");
|
||||||
printf("-f server what ipaddr@portnr to send the queries to\n");
|
printf("-f server what ipaddr@portnr to send the queries to\n");
|
||||||
|
printf("-p client what ipaddr@portnr to include in PROXYv2\n");
|
||||||
printf("-u use UDP. No retries are attempted.\n");
|
printf("-u use UDP. No retries are attempted.\n");
|
||||||
printf("-n do not wait for an answer.\n");
|
printf("-n do not wait for an answer.\n");
|
||||||
printf("-a print answers as they arrive.\n");
|
printf("-a print answers as they arrive.\n");
|
||||||
@ -82,18 +84,17 @@ static void usage(char* argv[])
|
|||||||
|
|
||||||
/** open TCP socket to svr */
|
/** open TCP socket to svr */
|
||||||
static int
|
static int
|
||||||
open_svr(const char* svr, int udp)
|
open_svr(const char* svr, int udp, struct sockaddr_storage* addr,
|
||||||
|
socklen_t* addrlen)
|
||||||
{
|
{
|
||||||
struct sockaddr_storage addr;
|
|
||||||
socklen_t addrlen;
|
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
/* svr can be ip@port */
|
/* svr can be ip@port */
|
||||||
memset(&addr, 0, sizeof(addr));
|
memset(addr, 0, sizeof(*addr));
|
||||||
if(!extstrtoaddr(svr, &addr, &addrlen)) {
|
if(!extstrtoaddr(svr, addr, addrlen, UNBOUND_DNS_PORT)) {
|
||||||
printf("fatal: bad server specs '%s'\n", svr);
|
printf("fatal: bad server specs '%s'\n", svr);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
fd = socket(addr_is_ip6(&addr, addrlen)?PF_INET6:PF_INET,
|
fd = socket(addr_is_ip6(addr, *addrlen)?PF_INET6:PF_INET,
|
||||||
udp?SOCK_DGRAM:SOCK_STREAM, 0);
|
udp?SOCK_DGRAM:SOCK_STREAM, 0);
|
||||||
if(fd == -1) {
|
if(fd == -1) {
|
||||||
#ifndef USE_WINSOCK
|
#ifndef USE_WINSOCK
|
||||||
@ -103,7 +104,7 @@ open_svr(const char* svr, int udp)
|
|||||||
#endif
|
#endif
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
if(connect(fd, (struct sockaddr*)&addr, addrlen) < 0) {
|
if(connect(fd, (struct sockaddr*)addr, *addrlen) < 0) {
|
||||||
#ifndef USE_WINSOCK
|
#ifndef USE_WINSOCK
|
||||||
perror("connect() error");
|
perror("connect() error");
|
||||||
#else
|
#else
|
||||||
@ -117,10 +118,11 @@ open_svr(const char* svr, int udp)
|
|||||||
/** write a query over the TCP fd */
|
/** write a query over the TCP fd */
|
||||||
static void
|
static void
|
||||||
write_q(int fd, int udp, SSL* ssl, sldns_buffer* buf, uint16_t id,
|
write_q(int fd, int udp, SSL* ssl, sldns_buffer* buf, uint16_t id,
|
||||||
|
sldns_buffer* proxy_buf, int pp2_parsed,
|
||||||
const char* strname, const char* strtype, const char* strclass)
|
const char* strname, const char* strtype, const char* strclass)
|
||||||
{
|
{
|
||||||
struct query_info qinfo;
|
struct query_info qinfo;
|
||||||
uint16_t len;
|
size_t proxy_buf_limit = sldns_buffer_limit(proxy_buf);
|
||||||
/* qname */
|
/* qname */
|
||||||
qinfo.qname = sldns_str2wire_dname(strname, &qinfo.qname_len);
|
qinfo.qname = sldns_str2wire_dname(strname, &qinfo.qname_len);
|
||||||
if(!qinfo.qname) {
|
if(!qinfo.qname) {
|
||||||
@ -152,9 +154,27 @@ write_q(int fd, int udp, SSL* ssl, sldns_buffer* buf, uint16_t id,
|
|||||||
attach_edns_record(buf, &edns);
|
attach_edns_record(buf, &edns);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* we need to send the PROXYv2 information in every UDP message */
|
||||||
|
if(udp && pp2_parsed) {
|
||||||
|
/* append the proxy_buf with the buf's content
|
||||||
|
* and use that for sending */
|
||||||
|
if(sldns_buffer_capacity(proxy_buf) <
|
||||||
|
sldns_buffer_limit(proxy_buf) +
|
||||||
|
sldns_buffer_limit(buf)) {
|
||||||
|
printf("buffer too small for packet + proxy");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
sldns_buffer_clear(proxy_buf);
|
||||||
|
sldns_buffer_skip(proxy_buf, proxy_buf_limit);
|
||||||
|
sldns_buffer_write(proxy_buf, sldns_buffer_begin(buf),
|
||||||
|
sldns_buffer_limit(buf));
|
||||||
|
sldns_buffer_flip(proxy_buf);
|
||||||
|
buf = proxy_buf;
|
||||||
|
}
|
||||||
|
|
||||||
/* send it */
|
/* send it */
|
||||||
if(!udp) {
|
if(!udp) {
|
||||||
len = (uint16_t)sldns_buffer_limit(buf);
|
uint16_t len = (uint16_t)sldns_buffer_limit(buf);
|
||||||
len = htons(len);
|
len = htons(len);
|
||||||
if(ssl) {
|
if(ssl) {
|
||||||
if(SSL_write(ssl, (void*)&len, (int)sizeof(len)) <= 0) {
|
if(SSL_write(ssl, (void*)&len, (int)sizeof(len)) <= 0) {
|
||||||
@ -187,12 +207,15 @@ write_q(int fd, int udp, SSL* ssl, sldns_buffer* buf, uint16_t id,
|
|||||||
#ifndef USE_WINSOCK
|
#ifndef USE_WINSOCK
|
||||||
perror("send() data failed");
|
perror("send() data failed");
|
||||||
#else
|
#else
|
||||||
printf("send data: %s\n", wsa_strerror(WSAGetLastError()));
|
printf("send data: %s\n",
|
||||||
|
wsa_strerror(WSAGetLastError()));
|
||||||
#endif
|
#endif
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* reset the proxy_buf for next packet */
|
||||||
|
sldns_buffer_set_limit(proxy_buf, proxy_buf_limit);
|
||||||
free(qinfo.qname);
|
free(qinfo.qname);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -324,17 +347,40 @@ static int get_random(void)
|
|||||||
return (int)arc4random();
|
return (int)arc4random();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* parse the pp2_client and populate the proxy_buffer
|
||||||
|
* It doesn't populate the destination parts. */
|
||||||
|
static int parse_pp2_client(const char* pp2_client, int udp,
|
||||||
|
sldns_buffer* proxy_buf)
|
||||||
|
{
|
||||||
|
struct sockaddr_storage pp2_addr;
|
||||||
|
socklen_t pp2_addrlen = 0;
|
||||||
|
memset(&pp2_addr, 0, sizeof(pp2_addr));
|
||||||
|
if(*pp2_client == 0) return 0;
|
||||||
|
if(!extstrtoaddr(pp2_client, &pp2_addr, &pp2_addrlen, UNBOUND_DNS_PORT)) {
|
||||||
|
printf("fatal: bad proxy client specs '%s'\n", pp2_client);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
sldns_buffer_clear(proxy_buf);
|
||||||
|
pp2_write_to_buf(proxy_buf, &pp2_addr, !udp);
|
||||||
|
sldns_buffer_flip(proxy_buf);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/** send the TCP queries and print answers */
|
/** send the TCP queries and print answers */
|
||||||
static void
|
static void
|
||||||
send_em(const char* svr, int udp, int usessl, int noanswer, int onarrival,
|
send_em(const char* svr, const char* pp2_client, int udp, int usessl,
|
||||||
int delay, int num, char** qs)
|
int noanswer, int onarrival, int delay, int num, char** qs)
|
||||||
{
|
{
|
||||||
sldns_buffer* buf = sldns_buffer_new(65553);
|
sldns_buffer* buf = sldns_buffer_new(65553);
|
||||||
int fd = open_svr(svr, udp);
|
sldns_buffer* proxy_buf = sldns_buffer_new(65553);
|
||||||
int i, wait_results = 0;
|
struct sockaddr_storage svr_addr;
|
||||||
|
socklen_t svr_addrlen;
|
||||||
|
int fd = open_svr(svr, udp, &svr_addr, &svr_addrlen);
|
||||||
|
int i, wait_results = 0, pp2_parsed;
|
||||||
SSL_CTX* ctx = NULL;
|
SSL_CTX* ctx = NULL;
|
||||||
SSL* ssl = NULL;
|
SSL* ssl = NULL;
|
||||||
if(!buf) fatal_exit("out of memory");
|
if(!buf) fatal_exit("out of memory");
|
||||||
|
pp2_parsed = parse_pp2_client(pp2_client, udp, proxy_buf);
|
||||||
if(usessl) {
|
if(usessl) {
|
||||||
ctx = connect_sslctx_create(NULL, NULL, NULL, 0);
|
ctx = connect_sslctx_create(NULL, NULL, NULL, 0);
|
||||||
if(!ctx) fatal_exit("cannot create ssl ctx");
|
if(!ctx) fatal_exit("cannot create ssl ctx");
|
||||||
@ -361,6 +407,28 @@ send_em(const char* svr, int udp, int usessl, int noanswer, int onarrival,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* Send the PROXYv2 information once per stream */
|
||||||
|
if(!udp && pp2_parsed) {
|
||||||
|
if(ssl) {
|
||||||
|
if(SSL_write(ssl, (void*)sldns_buffer_begin(proxy_buf),
|
||||||
|
(int)sldns_buffer_limit(proxy_buf)) <= 0) {
|
||||||
|
log_crypto_err("cannot SSL_write");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(send(fd, (void*)sldns_buffer_begin(proxy_buf),
|
||||||
|
sldns_buffer_limit(proxy_buf), 0) <
|
||||||
|
(ssize_t)sldns_buffer_limit(proxy_buf)) {
|
||||||
|
#ifndef USE_WINSOCK
|
||||||
|
perror("send() data failed");
|
||||||
|
#else
|
||||||
|
printf("send data: %s\n",
|
||||||
|
wsa_strerror(WSAGetLastError()));
|
||||||
|
#endif
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
for(i=0; i<num; i+=3) {
|
for(i=0; i<num; i+=3) {
|
||||||
if (delay != 0) {
|
if (delay != 0) {
|
||||||
#ifdef HAVE_SLEEP
|
#ifdef HAVE_SLEEP
|
||||||
@ -370,8 +438,9 @@ send_em(const char* svr, int udp, int usessl, int noanswer, int onarrival,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
printf("\nNext query is %s %s %s\n", qs[i], qs[i+1], qs[i+2]);
|
printf("\nNext query is %s %s %s\n", qs[i], qs[i+1], qs[i+2]);
|
||||||
write_q(fd, udp, ssl, buf, (uint16_t)get_random(), qs[i],
|
write_q(fd, udp, ssl, buf, (uint16_t)get_random(), proxy_buf,
|
||||||
qs[i+1], qs[i+2]);
|
pp2_parsed,
|
||||||
|
qs[i], qs[i+1], qs[i+2]);
|
||||||
/* print at least one result */
|
/* print at least one result */
|
||||||
if(onarrival) {
|
if(onarrival) {
|
||||||
wait_results += 1; /* one more answer to fetch */
|
wait_results += 1; /* one more answer to fetch */
|
||||||
@ -390,6 +459,7 @@ send_em(const char* svr, int udp, int usessl, int noanswer, int onarrival,
|
|||||||
}
|
}
|
||||||
sock_close(fd);
|
sock_close(fd);
|
||||||
sldns_buffer_free(buf);
|
sldns_buffer_free(buf);
|
||||||
|
sldns_buffer_free(proxy_buf);
|
||||||
printf("orderly exit\n");
|
printf("orderly exit\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -422,6 +492,7 @@ int main(int argc, char** argv)
|
|||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
const char* svr = "127.0.0.1";
|
const char* svr = "127.0.0.1";
|
||||||
|
const char* pp2_client = "";
|
||||||
int udp = 0;
|
int udp = 0;
|
||||||
int noanswer = 0;
|
int noanswer = 0;
|
||||||
int onarrival = 0;
|
int onarrival = 0;
|
||||||
@ -451,11 +522,14 @@ int main(int argc, char** argv)
|
|||||||
if(argc == 1) {
|
if(argc == 1) {
|
||||||
usage(argv);
|
usage(argv);
|
||||||
}
|
}
|
||||||
while( (c=getopt(argc, argv, "af:hnsud:")) != -1) {
|
while( (c=getopt(argc, argv, "af:p:hnsud:")) != -1) {
|
||||||
switch(c) {
|
switch(c) {
|
||||||
case 'f':
|
case 'f':
|
||||||
svr = optarg;
|
svr = optarg;
|
||||||
break;
|
break;
|
||||||
|
case 'p':
|
||||||
|
pp2_client = optarg;
|
||||||
|
break;
|
||||||
case 'a':
|
case 'a':
|
||||||
onarrival = 1;
|
onarrival = 1;
|
||||||
break;
|
break;
|
||||||
@ -508,7 +582,7 @@ int main(int argc, char** argv)
|
|||||||
(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL);
|
(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
send_em(svr, udp, usessl, noanswer, onarrival, delay, argc, argv);
|
send_em(svr, pp2_client, udp, usessl, noanswer, onarrival, delay, argc, argv);
|
||||||
checklock_stop();
|
checklock_stop();
|
||||||
#ifdef USE_WINSOCK
|
#ifdef USE_WINSOCK
|
||||||
WSACleanup();
|
WSACleanup();
|
||||||
|
@ -173,7 +173,7 @@ static void consistency_test(void)
|
|||||||
for (i = 0; i < 1000; i++) {
|
for (i = 0; i < 1000; i++) {
|
||||||
l = randomkey(&k, 128);
|
l = randomkey(&k, 128);
|
||||||
elem = (struct reply_info *) calloc(1, sizeof(struct reply_info));
|
elem = (struct reply_info *) calloc(1, sizeof(struct reply_info));
|
||||||
addrtree_insert(t, k, l, 64, elem, timenow + 10, timenow);
|
addrtree_insert(t, k, l, 64, elem, timenow + 10, timenow, 0);
|
||||||
/* This should always hold because no items ever expire. They
|
/* This should always hold because no items ever expire. They
|
||||||
* could be overwritten, though. */
|
* could be overwritten, though. */
|
||||||
unit_assert( count <= t->node_count );
|
unit_assert( count <= t->node_count );
|
||||||
@ -189,7 +189,7 @@ static void consistency_test(void)
|
|||||||
for (i = 0; i < 1000; i++) {
|
for (i = 0; i < 1000; i++) {
|
||||||
l = randomkey(&k, 128);
|
l = randomkey(&k, 128);
|
||||||
elem = (struct reply_info *) calloc(1, sizeof(struct reply_info));
|
elem = (struct reply_info *) calloc(1, sizeof(struct reply_info));
|
||||||
addrtree_insert(t, k, l, 64, elem, i + 10, i);
|
addrtree_insert(t, k, l, 64, elem, i + 10, i, 0);
|
||||||
free(k);
|
free(k);
|
||||||
unit_assert( !addrtree_inconsistent(t) );
|
unit_assert( !addrtree_inconsistent(t) );
|
||||||
}
|
}
|
||||||
@ -201,7 +201,7 @@ static void consistency_test(void)
|
|||||||
for (i = 0; i < 1000; i++) {
|
for (i = 0; i < 1000; i++) {
|
||||||
l = randomkey(&k, 128);
|
l = randomkey(&k, 128);
|
||||||
elem = (struct reply_info *) calloc(1, sizeof(struct reply_info));
|
elem = (struct reply_info *) calloc(1, sizeof(struct reply_info));
|
||||||
addrtree_insert(t, k, l, 64, elem, i + 10, i);
|
addrtree_insert(t, k, l, 64, elem, i + 10, i, 0);
|
||||||
unit_assert( t->node_count <= 27);
|
unit_assert( t->node_count <= 27);
|
||||||
free(k);
|
free(k);
|
||||||
unit_assert( !addrtree_inconsistent(t) );
|
unit_assert( !addrtree_inconsistent(t) );
|
||||||
|
@ -44,6 +44,8 @@
|
|||||||
#include "util/random.h"
|
#include "util/random.h"
|
||||||
#include "services/outside_network.h"
|
#include "services/outside_network.h"
|
||||||
|
|
||||||
|
#define MAX_TCP_WAITING_NODES 5
|
||||||
|
|
||||||
/** add number of new IDs to the reuse tree, randomly chosen */
|
/** add number of new IDs to the reuse tree, randomly chosen */
|
||||||
static void tcpid_addmore(struct reuse_tcp* reuse,
|
static void tcpid_addmore(struct reuse_tcp* reuse,
|
||||||
struct outside_network* outnet, unsigned int addnum)
|
struct outside_network* outnet, unsigned int addnum)
|
||||||
@ -228,9 +230,260 @@ static void tcp_reuse_tree_list_test(void)
|
|||||||
free(outnet.tcp_conns);
|
free(outnet.tcp_conns);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void check_waiting_tcp_list(struct outside_network* outnet,
|
||||||
|
struct waiting_tcp* first, struct waiting_tcp* last, size_t total)
|
||||||
|
{
|
||||||
|
size_t i, j;
|
||||||
|
struct waiting_tcp* w = outnet->tcp_wait_first;
|
||||||
|
struct waiting_tcp* n = NULL;
|
||||||
|
if(first) unit_assert(outnet->tcp_wait_first == first);
|
||||||
|
if(last) unit_assert(outnet->tcp_wait_last == last && !last->next_waiting);
|
||||||
|
for(i=0; w; i++) {
|
||||||
|
unit_assert(i<total); /* otherwise we are looping */
|
||||||
|
unit_assert(w->on_tcp_waiting_list);
|
||||||
|
n = w->next_waiting;
|
||||||
|
for(j=0; n; j++) {
|
||||||
|
unit_assert(j<total-i-1); /* otherwise we are looping */
|
||||||
|
unit_assert(n != w);
|
||||||
|
n = n->next_waiting;
|
||||||
|
}
|
||||||
|
w = w->next_waiting;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** clear the tcp waiting list */
|
||||||
|
static void waiting_tcp_list_clear(struct outside_network* outnet)
|
||||||
|
{
|
||||||
|
struct waiting_tcp* w = outnet->tcp_wait_first, *n = NULL;
|
||||||
|
if(!w) return;
|
||||||
|
unit_assert(outnet->tcp_wait_first);
|
||||||
|
unit_assert(outnet->tcp_wait_last);
|
||||||
|
while(w) {
|
||||||
|
n = w->next_waiting;
|
||||||
|
w->on_tcp_waiting_list = 0;
|
||||||
|
w->next_waiting = (struct waiting_tcp*)1; /* In purpose faux value */
|
||||||
|
w = n;
|
||||||
|
}
|
||||||
|
outnet->tcp_wait_first = NULL;
|
||||||
|
outnet->tcp_wait_last = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** check removal of the waiting_tcp element on the given position of total
|
||||||
|
* elements */
|
||||||
|
static void check_waiting_tcp_removal(int is_pop,
|
||||||
|
struct outside_network* outnet, struct waiting_tcp* store,
|
||||||
|
size_t position, size_t total)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
struct waiting_tcp* w;
|
||||||
|
waiting_tcp_list_clear(outnet);
|
||||||
|
for(i=0; i<total; i++) {
|
||||||
|
outnet_waiting_tcp_list_add(outnet, &store[i], 0);
|
||||||
|
}
|
||||||
|
check_waiting_tcp_list(outnet, &store[0], &store[total-1], total);
|
||||||
|
|
||||||
|
if(is_pop) {
|
||||||
|
w = outnet_waiting_tcp_list_pop(outnet);
|
||||||
|
unit_assert(w); /* please clang-analyser */
|
||||||
|
} else {
|
||||||
|
w = outnet->tcp_wait_first;
|
||||||
|
for(i=0; i<position; i++) {
|
||||||
|
unit_assert(w); /* please clang-analyser */
|
||||||
|
w = w->next_waiting;
|
||||||
|
}
|
||||||
|
unit_assert(w); /* please clang-analyser */
|
||||||
|
outnet_waiting_tcp_list_remove(outnet, w);
|
||||||
|
}
|
||||||
|
unit_assert(!(w->on_tcp_waiting_list || w->next_waiting));
|
||||||
|
|
||||||
|
if(position == 0 && total == 1) {
|
||||||
|
/* the list should be empty */
|
||||||
|
check_waiting_tcp_list(outnet, NULL, NULL, total-1);
|
||||||
|
} else if(position == 0) {
|
||||||
|
/* first element should be gone */
|
||||||
|
check_waiting_tcp_list(outnet, &store[1], &store[total-1], total-1);
|
||||||
|
} else if(position == total - 1) {
|
||||||
|
/* last element should be gone */
|
||||||
|
check_waiting_tcp_list(outnet, &store[0], &store[total-2], total-1);
|
||||||
|
} else {
|
||||||
|
/* an element should be gone */
|
||||||
|
check_waiting_tcp_list(outnet, &store[0], &store[total-1], total-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void waiting_tcp_list_test(void)
|
||||||
|
{
|
||||||
|
size_t i = 0;
|
||||||
|
struct outside_network outnet;
|
||||||
|
struct waiting_tcp* w, *t = NULL;
|
||||||
|
struct waiting_tcp store[MAX_TCP_WAITING_NODES];
|
||||||
|
memset(&outnet, 0, sizeof(outnet));
|
||||||
|
memset(&store, 0, sizeof(store));
|
||||||
|
|
||||||
|
/* Check add first on empty list */
|
||||||
|
unit_show_func("services/outside_network.c", "outnet_waiting_tcp_list_add_first");
|
||||||
|
t = &store[i];
|
||||||
|
outnet_waiting_tcp_list_add_first(&outnet, t, 0);
|
||||||
|
check_waiting_tcp_list(&outnet, t, t, 1);
|
||||||
|
|
||||||
|
/* Check add */
|
||||||
|
unit_show_func("services/outside_network.c", "outnet_waiting_tcp_list_add");
|
||||||
|
for(i=1; i<MAX_TCP_WAITING_NODES-1; i++) {
|
||||||
|
w = &store[i];
|
||||||
|
outnet_waiting_tcp_list_add(&outnet, w, 0);
|
||||||
|
}
|
||||||
|
check_waiting_tcp_list(&outnet, t, w, MAX_TCP_WAITING_NODES-1);
|
||||||
|
|
||||||
|
/* Check add first on populated list */
|
||||||
|
unit_show_func("services/outside_network.c", "outnet_waiting_tcp_list_add_first");
|
||||||
|
w = &store[i];
|
||||||
|
t = outnet.tcp_wait_last;
|
||||||
|
outnet_waiting_tcp_list_add_first(&outnet, w, 0);
|
||||||
|
check_waiting_tcp_list(&outnet, w, t, MAX_TCP_WAITING_NODES);
|
||||||
|
|
||||||
|
/* Check removal */
|
||||||
|
unit_show_func("services/outside_network.c", "outnet_waiting_tcp_list_remove");
|
||||||
|
check_waiting_tcp_removal(0, &outnet, store, 2, 5);
|
||||||
|
check_waiting_tcp_removal(0, &outnet, store, 1, 3);
|
||||||
|
check_waiting_tcp_removal(0, &outnet, store, 0, 2);
|
||||||
|
check_waiting_tcp_removal(0, &outnet, store, 1, 2);
|
||||||
|
check_waiting_tcp_removal(0, &outnet, store, 0, 1);
|
||||||
|
|
||||||
|
/* Check pop */
|
||||||
|
unit_show_func("services/outside_network.c", "outnet_waiting_tcp_list_pop");
|
||||||
|
check_waiting_tcp_removal(1, &outnet, store, 0, 3);
|
||||||
|
check_waiting_tcp_removal(1, &outnet, store, 0, 2);
|
||||||
|
check_waiting_tcp_removal(1, &outnet, store, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void check_reuse_write_wait(struct reuse_tcp* reuse,
|
||||||
|
struct waiting_tcp* first, struct waiting_tcp* last, size_t total)
|
||||||
|
{
|
||||||
|
size_t i, j;
|
||||||
|
struct waiting_tcp* w = reuse->write_wait_first;
|
||||||
|
struct waiting_tcp* n = NULL;
|
||||||
|
if(first) unit_assert(reuse->write_wait_first == first && !first->write_wait_prev);
|
||||||
|
if(last) unit_assert(reuse->write_wait_last == last && !last->write_wait_next);
|
||||||
|
/* check one way */
|
||||||
|
for(i=0; w; i++) {
|
||||||
|
unit_assert(i<total); /* otherwise we are looping */
|
||||||
|
unit_assert(w->write_wait_queued);
|
||||||
|
n = w->write_wait_next;
|
||||||
|
for(j=0; n; j++) {
|
||||||
|
unit_assert(j<total-i-1); /* otherwise we are looping */
|
||||||
|
unit_assert(n != w);
|
||||||
|
n = n->write_wait_next;
|
||||||
|
}
|
||||||
|
w = w->write_wait_next;
|
||||||
|
}
|
||||||
|
/* check the other way */
|
||||||
|
w = reuse->write_wait_last;
|
||||||
|
for(i=0; w; i++) {
|
||||||
|
unit_assert(i<total); /* otherwise we are looping */
|
||||||
|
unit_assert(w->write_wait_queued);
|
||||||
|
n = w->write_wait_prev;
|
||||||
|
for(j=0; n; j++) {
|
||||||
|
unit_assert(j<total-i-1); /* otherwise we are looping */
|
||||||
|
unit_assert(n != w);
|
||||||
|
n = n->write_wait_prev;
|
||||||
|
}
|
||||||
|
w = w->write_wait_prev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** clear the tcp waiting list */
|
||||||
|
static void reuse_write_wait_clear(struct reuse_tcp* reuse)
|
||||||
|
{
|
||||||
|
struct waiting_tcp* w = reuse->write_wait_first, *n = NULL;
|
||||||
|
if(!w) return;
|
||||||
|
unit_assert(reuse->write_wait_first);
|
||||||
|
unit_assert(reuse->write_wait_last);
|
||||||
|
while(w) {
|
||||||
|
n = w->write_wait_next;
|
||||||
|
w->write_wait_queued = 0;
|
||||||
|
w->write_wait_next = (struct waiting_tcp*)1; /* In purpose faux value */
|
||||||
|
w->write_wait_prev = (struct waiting_tcp*)1; /* In purpose faux value */
|
||||||
|
w = n;
|
||||||
|
}
|
||||||
|
reuse->write_wait_first = NULL;
|
||||||
|
reuse->write_wait_last = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** check removal of the reuse_write_wait element on the given position of total
|
||||||
|
* elements */
|
||||||
|
static void check_reuse_write_wait_removal(int is_pop,
|
||||||
|
struct reuse_tcp* reuse, struct waiting_tcp* store,
|
||||||
|
size_t position, size_t total)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
struct waiting_tcp* w;
|
||||||
|
reuse_write_wait_clear(reuse);
|
||||||
|
for(i=0; i<total; i++) {
|
||||||
|
reuse_write_wait_push_back(reuse, &store[i]);
|
||||||
|
}
|
||||||
|
check_reuse_write_wait(reuse, &store[0], &store[total-1], total);
|
||||||
|
|
||||||
|
if(is_pop) {
|
||||||
|
w = reuse_write_wait_pop(reuse);
|
||||||
|
} else {
|
||||||
|
w = reuse->write_wait_first;
|
||||||
|
for(i=0; i<position; i++) w = w->write_wait_next;
|
||||||
|
reuse_write_wait_remove(reuse, w);
|
||||||
|
}
|
||||||
|
unit_assert(!(w->write_wait_queued || w->write_wait_next || w->write_wait_prev));
|
||||||
|
|
||||||
|
if(position == 0 && total == 1) {
|
||||||
|
/* the list should be empty */
|
||||||
|
check_reuse_write_wait(reuse, NULL, NULL, total-1);
|
||||||
|
} else if(position == 0) {
|
||||||
|
/* first element should be gone */
|
||||||
|
check_reuse_write_wait(reuse, &store[1], &store[total-1], total-1);
|
||||||
|
} else if(position == total - 1) {
|
||||||
|
/* last element should be gone */
|
||||||
|
check_reuse_write_wait(reuse, &store[0], &store[total-2], total-1);
|
||||||
|
} else {
|
||||||
|
/* an element should be gone */
|
||||||
|
check_reuse_write_wait(reuse, &store[0], &store[total-1], total-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void reuse_write_wait_test(void)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
struct reuse_tcp reuse;
|
||||||
|
struct waiting_tcp store[MAX_TCP_WAITING_NODES];
|
||||||
|
struct waiting_tcp* w;
|
||||||
|
memset(&reuse, 0, sizeof(reuse));
|
||||||
|
memset(&store, 0, sizeof(store));
|
||||||
|
|
||||||
|
/* Check adding */
|
||||||
|
unit_show_func("services/outside_network.c", "reuse_write_wait_push_back");
|
||||||
|
for(i=0; i<MAX_TCP_WAITING_NODES; i++) {
|
||||||
|
w = &store[i];
|
||||||
|
reuse_write_wait_push_back(&reuse, w);
|
||||||
|
}
|
||||||
|
check_reuse_write_wait(&reuse, &store[0], w, MAX_TCP_WAITING_NODES);
|
||||||
|
|
||||||
|
/* Check removal */
|
||||||
|
unit_show_func("services/outside_network.c", "reuse_write_wait_remove");
|
||||||
|
check_reuse_write_wait_removal(0, &reuse, store, 2, 5);
|
||||||
|
check_reuse_write_wait_removal(0, &reuse, store, 1, 3);
|
||||||
|
check_reuse_write_wait_removal(0, &reuse, store, 0, 2);
|
||||||
|
check_reuse_write_wait_removal(0, &reuse, store, 1, 2);
|
||||||
|
check_reuse_write_wait_removal(0, &reuse, store, 0, 1);
|
||||||
|
|
||||||
|
/* Check pop */
|
||||||
|
unit_show_func("services/outside_network.c", "reuse_write_wait_pop");
|
||||||
|
check_reuse_write_wait_removal(1, &reuse, store, 0, 3);
|
||||||
|
check_reuse_write_wait_removal(1, &reuse, store, 0, 2);
|
||||||
|
check_reuse_write_wait_removal(1, &reuse, store, 0, 1);
|
||||||
|
}
|
||||||
|
|
||||||
void tcpreuse_test(void)
|
void tcpreuse_test(void)
|
||||||
{
|
{
|
||||||
unit_show_feature("tcp_reuse");
|
unit_show_feature("tcp_reuse");
|
||||||
tcpid_test();
|
tcpid_test();
|
||||||
tcp_reuse_tree_list_test();
|
tcp_reuse_tree_list_test();
|
||||||
|
waiting_tcp_list_test();
|
||||||
|
reuse_write_wait_test();
|
||||||
}
|
}
|
||||||
|
10
testdata/04-checkconf.tdir/04-checkconf.test
vendored
10
testdata/04-checkconf.tdir/04-checkconf.test
vendored
@ -28,6 +28,12 @@ if grep "define UB_ON_WINDOWS 1" ../../config.h; then
|
|||||||
else
|
else
|
||||||
onwin=0
|
onwin=0
|
||||||
fi
|
fi
|
||||||
|
# detect dnscrypt
|
||||||
|
if grep "define USE_DNSCRYPT 1" ../../config.h; then
|
||||||
|
with_dnscrypt=1
|
||||||
|
else
|
||||||
|
with_dnscrypt=0
|
||||||
|
fi
|
||||||
|
|
||||||
# test check of config files.
|
# test check of config files.
|
||||||
for f in bad.*; do
|
for f in bad.*; do
|
||||||
@ -37,6 +43,10 @@ for f in bad.*; do
|
|||||||
echo "skipped on windows"
|
echo "skipped on windows"
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
if test $f = "bad.proxy-and-dnscrypt" -a $with_dnscrypt -eq 0; then
|
||||||
|
echo "skipped; no DNSCRYPT support"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
$PRE/unbound-checkconf $f
|
$PRE/unbound-checkconf $f
|
||||||
if test $? != 1; then
|
if test $? != 1; then
|
||||||
|
6
testdata/04-checkconf.tdir/bad.proxy-and-dnscrypt
vendored
Normal file
6
testdata/04-checkconf.tdir/bad.proxy-and-dnscrypt
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
server:
|
||||||
|
interface: 127.0.0.1
|
||||||
|
proxy-protocol-port: 53
|
||||||
|
dnscrypt:
|
||||||
|
dnscrypt-enable: yes
|
||||||
|
dnscrypt-port: 53
|
4
testdata/04-checkconf.tdir/bad.proxy-and-https
vendored
Normal file
4
testdata/04-checkconf.tdir/bad.proxy-and-https
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
server:
|
||||||
|
interface: 127.0.0.1
|
||||||
|
proxy-protocol-port: 53
|
||||||
|
https-port: 53
|
2
testdata/07-confroot.tdir/07-confroot.dsc
vendored
2
testdata/07-confroot.tdir/07-confroot.dsc
vendored
@ -8,7 +8,7 @@ Component:
|
|||||||
CmdDepends:
|
CmdDepends:
|
||||||
Depends:
|
Depends:
|
||||||
Help:
|
Help:
|
||||||
Pre:
|
Pre: 07-confroot.pre
|
||||||
Post:
|
Post:
|
||||||
Test: 07-confroot.test
|
Test: 07-confroot.test
|
||||||
AuxFiles:
|
AuxFiles:
|
||||||
|
13
testdata/07-confroot.tdir/07-confroot.pre
vendored
Normal file
13
testdata/07-confroot.tdir/07-confroot.pre
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# #-- 07-confroot.pre --#
|
||||||
|
# source the master var file when it's there
|
||||||
|
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
|
||||||
|
# use .tpkg.var.test for in test variable passing
|
||||||
|
[ -f .tpkg.var.test ] && source .tpkg.var.test
|
||||||
|
|
||||||
|
PRE="../.."
|
||||||
|
|
||||||
|
if uname | grep "MINGW" >/dev/null; then
|
||||||
|
# no chroot, no need to test.
|
||||||
|
# (test fails on / and \ comparisons, by the way).
|
||||||
|
skip_test "no chroot on windows, end test"
|
||||||
|
fi
|
7
testdata/07-confroot.tdir/07-confroot.test
vendored
7
testdata/07-confroot.tdir/07-confroot.test
vendored
@ -6,13 +6,6 @@
|
|||||||
|
|
||||||
PRE="../.."
|
PRE="../.."
|
||||||
|
|
||||||
if uname | grep "MINGW" >/dev/null; then
|
|
||||||
# no chroot, no need to test.
|
|
||||||
# (test fails on / en \ comparisons, by the way).
|
|
||||||
echo "no chroot on windows, end test"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# create config file
|
# create config file
|
||||||
cwd=`pwd -P`
|
cwd=`pwd -P`
|
||||||
subdir=$cwd/subdir
|
subdir=$cwd/subdir
|
||||||
|
9
testdata/08-host-lib.tdir/08-host-lib.pre
vendored
9
testdata/08-host-lib.tdir/08-host-lib.pre
vendored
@ -4,7 +4,16 @@
|
|||||||
# use .tpkg.var.test for in test variable passing
|
# use .tpkg.var.test for in test variable passing
|
||||||
[ -f .tpkg.var.test ] && source .tpkg.var.test
|
[ -f .tpkg.var.test ] && source .tpkg.var.test
|
||||||
|
|
||||||
|
PRE="../.."
|
||||||
. ../common.sh
|
. ../common.sh
|
||||||
|
|
||||||
|
if grep FORK $PRE/config.h | grep "define" >/dev/null 2>&1; then
|
||||||
|
# nothing
|
||||||
|
:
|
||||||
|
else
|
||||||
|
skip_test "forking is not available; test skipped."
|
||||||
|
fi
|
||||||
|
|
||||||
get_random_port 2
|
get_random_port 2
|
||||||
FWD_PORT=$(($RND_PORT + 1))
|
FWD_PORT=$(($RND_PORT + 1))
|
||||||
echo "FWD_PORT=$FWD_PORT" >> .tpkg.var.test
|
echo "FWD_PORT=$FWD_PORT" >> .tpkg.var.test
|
||||||
|
8
testdata/08-host-lib.tdir/08-host-lib.test
vendored
8
testdata/08-host-lib.tdir/08-host-lib.test
vendored
@ -7,14 +7,6 @@
|
|||||||
PRE="../.."
|
PRE="../.."
|
||||||
. ../common.sh
|
. ../common.sh
|
||||||
|
|
||||||
if grep FORK $PRE/config.h | grep "define" >/dev/null 2>&1; then
|
|
||||||
# nothing
|
|
||||||
:
|
|
||||||
else
|
|
||||||
echo "forking is not available; test skipped."
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# test if fwder is up
|
# test if fwder is up
|
||||||
echo "> dig @127.0.0.1 -p $FWD_PORT www.example.com | tee outfile"
|
echo "> dig @127.0.0.1 -p $FWD_PORT www.example.com | tee outfile"
|
||||||
dig @127.0.0.1 -p $FWD_PORT www.example.com | tee outfile
|
dig @127.0.0.1 -p $FWD_PORT www.example.com | tee outfile
|
||||||
|
140
testdata/acl_interface.tdir/acl_interface.conf
vendored
Normal file
140
testdata/acl_interface.tdir/acl_interface.conf
vendored
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
server:
|
||||||
|
verbosity: 7
|
||||||
|
use-syslog: no
|
||||||
|
directory: ""
|
||||||
|
pidfile: "unbound.pid"
|
||||||
|
chroot: ""
|
||||||
|
username: ""
|
||||||
|
do-not-query-localhost: no
|
||||||
|
use-caps-for-id: no
|
||||||
|
define-tag: "one two refuse"
|
||||||
|
|
||||||
|
# Interface configuration for IPv4
|
||||||
|
interface: @IPV4_ADDR@@@PORT_ALLOW@
|
||||||
|
interface: @IPV4_ADDR@@@PORT_DENY@
|
||||||
|
interface: @IPV4_ADDR@@@PORT_REFUSE@
|
||||||
|
interface: @IPV4_ADDR@@@PORT_TAG_1@
|
||||||
|
interface: @IPV4_ADDR@@@PORT_TAG_2@
|
||||||
|
interface: @IPV4_ADDR@@@PORT_TAG_3@
|
||||||
|
interface: @IPV4_ADDR@@@PORT_VIEW_INT@
|
||||||
|
interface: @IPV4_ADDR@@@PORT_VIEW_EXT@
|
||||||
|
interface: @IPV4_ADDR@@@PORT_VIEW_INTEXT@
|
||||||
|
|
||||||
|
interface-action: @IPV4_ADDR@@@PORT_ALLOW@ allow
|
||||||
|
interface-action: @IPV4_ADDR@@@PORT_DENY@ deny
|
||||||
|
# interface-action: @IPV4_ADDR@@@PORT_REFUSE@ refuse # This is the default action
|
||||||
|
interface-action: @IPV4_ADDR@@@PORT_TAG_1@ allow
|
||||||
|
interface-action: @IPV4_ADDR@@@PORT_TAG_2@ allow
|
||||||
|
interface-action: @IPV4_ADDR@@@PORT_TAG_3@ allow
|
||||||
|
interface-action: @IPV4_ADDR@@@PORT_VIEW_INT@ allow
|
||||||
|
interface-action: @IPV4_ADDR@@@PORT_VIEW_EXT@ allow
|
||||||
|
interface-action: @IPV4_ADDR@@@PORT_VIEW_INTEXT@ allow
|
||||||
|
|
||||||
|
interface-tag: @IPV4_ADDR@@@PORT_TAG_1@ "one"
|
||||||
|
interface-tag: @IPV4_ADDR@@@PORT_TAG_2@ "two"
|
||||||
|
interface-tag: @IPV4_ADDR@@@PORT_TAG_3@ "refuse"
|
||||||
|
interface-tag-action: @IPV4_ADDR@@@PORT_TAG_1@ one redirect
|
||||||
|
interface-tag-data: @IPV4_ADDR@@@PORT_TAG_1@ one "A 1.1.1.1"
|
||||||
|
interface-tag-action: @IPV4_ADDR@@@PORT_TAG_2@ two redirect
|
||||||
|
interface-tag-data: @IPV4_ADDR@@@PORT_TAG_2@ two "A 2.2.2.2"
|
||||||
|
interface-tag-action: @IPV4_ADDR@@@PORT_TAG_3@ refuse always_refuse
|
||||||
|
|
||||||
|
interface-view: @IPV4_ADDR@@@PORT_VIEW_INT@ "int"
|
||||||
|
interface-view: @IPV4_ADDR@@@PORT_VIEW_EXT@ "ext"
|
||||||
|
interface-view: @IPV4_ADDR@@@PORT_VIEW_INTEXT@ "intext"
|
||||||
|
|
||||||
|
# Mirrored interface configuration for IPv6
|
||||||
|
interface: @IPV6_ADDR@@@PORT_ALLOW@
|
||||||
|
interface: @IPV6_ADDR@@@PORT_DENY@
|
||||||
|
interface: @IPV6_ADDR@@@PORT_REFUSE@
|
||||||
|
interface: @IPV6_ADDR@@@PORT_TAG_1@
|
||||||
|
interface: @IPV6_ADDR@@@PORT_TAG_2@
|
||||||
|
interface: @IPV6_ADDR@@@PORT_TAG_3@
|
||||||
|
interface: @IPV6_ADDR@@@PORT_VIEW_INT@
|
||||||
|
interface: @IPV6_ADDR@@@PORT_VIEW_EXT@
|
||||||
|
interface: @IPV6_ADDR@@@PORT_VIEW_INTEXT@
|
||||||
|
|
||||||
|
interface-action: @IPV6_ADDR@@@PORT_ALLOW@ allow
|
||||||
|
interface-action: @IPV6_ADDR@@@PORT_DENY@ deny
|
||||||
|
# interface-action: @IPV6_ADDR@@@PORT_REFUSE@ refuse # This is the default action
|
||||||
|
interface-action: @IPV6_ADDR@@@PORT_TAG_1@ allow
|
||||||
|
interface-action: @IPV6_ADDR@@@PORT_TAG_2@ allow
|
||||||
|
interface-action: @IPV6_ADDR@@@PORT_TAG_3@ allow
|
||||||
|
interface-action: @IPV6_ADDR@@@PORT_VIEW_INT@ allow
|
||||||
|
interface-action: @IPV6_ADDR@@@PORT_VIEW_EXT@ allow
|
||||||
|
interface-action: @IPV6_ADDR@@@PORT_VIEW_INTEXT@ allow
|
||||||
|
|
||||||
|
interface-tag: @IPV6_ADDR@@@PORT_TAG_1@ "one"
|
||||||
|
interface-tag: @IPV6_ADDR@@@PORT_TAG_2@ "two"
|
||||||
|
interface-tag: @IPV6_ADDR@@@PORT_TAG_3@ "refuse"
|
||||||
|
interface-tag-action: @IPV6_ADDR@@@PORT_TAG_1@ one redirect
|
||||||
|
interface-tag-data: @IPV6_ADDR@@@PORT_TAG_1@ one "A 1.1.1.1"
|
||||||
|
interface-tag-action: @IPV6_ADDR@@@PORT_TAG_2@ two redirect
|
||||||
|
interface-tag-data: @IPV6_ADDR@@@PORT_TAG_2@ two "A 2.2.2.2"
|
||||||
|
interface-tag-action: @IPV6_ADDR@@@PORT_TAG_3@ refuse always_refuse
|
||||||
|
|
||||||
|
interface-view: @IPV6_ADDR@@@PORT_VIEW_INT@ "int"
|
||||||
|
interface-view: @IPV6_ADDR@@@PORT_VIEW_EXT@ "ext"
|
||||||
|
interface-view: @IPV6_ADDR@@@PORT_VIEW_INTEXT@ "intext"
|
||||||
|
|
||||||
|
# Mirrored interface configuration for interface name
|
||||||
|
interface: @INTERFACE@@@PORT_ALLOW@
|
||||||
|
interface: @INTERFACE@@@PORT_DENY@
|
||||||
|
interface: @INTERFACE@@@PORT_REFUSE@
|
||||||
|
interface: @INTERFACE@@@PORT_TAG_1@
|
||||||
|
interface: @INTERFACE@@@PORT_TAG_2@
|
||||||
|
interface: @INTERFACE@@@PORT_TAG_3@
|
||||||
|
interface: @INTERFACE@@@PORT_VIEW_INT@
|
||||||
|
interface: @INTERFACE@@@PORT_VIEW_EXT@
|
||||||
|
interface: @INTERFACE@@@PORT_VIEW_INTEXT@
|
||||||
|
|
||||||
|
interface-action: @INTERFACE@@@PORT_ALLOW@ allow
|
||||||
|
interface-action: @INTERFACE@@@PORT_DENY@ deny
|
||||||
|
# interface-action: @INTERFACE@@@PORT_REFUSE@ refuse # This is the default action
|
||||||
|
interface-action: @INTERFACE@@@PORT_TAG_1@ allow
|
||||||
|
interface-action: @INTERFACE@@@PORT_TAG_2@ allow
|
||||||
|
interface-action: @INTERFACE@@@PORT_TAG_3@ allow
|
||||||
|
interface-action: @INTERFACE@@@PORT_VIEW_INT@ allow
|
||||||
|
interface-action: @INTERFACE@@@PORT_VIEW_EXT@ allow
|
||||||
|
interface-action: @INTERFACE@@@PORT_VIEW_INTEXT@ allow
|
||||||
|
|
||||||
|
interface-tag: @INTERFACE@@@PORT_TAG_1@ "one"
|
||||||
|
interface-tag: @INTERFACE@@@PORT_TAG_2@ "two"
|
||||||
|
interface-tag: @INTERFACE@@@PORT_TAG_3@ "refuse"
|
||||||
|
interface-tag-action: @INTERFACE@@@PORT_TAG_1@ one redirect
|
||||||
|
interface-tag-data: @INTERFACE@@@PORT_TAG_1@ one "A 1.1.1.1"
|
||||||
|
interface-tag-action: @INTERFACE@@@PORT_TAG_2@ two redirect
|
||||||
|
interface-tag-data: @INTERFACE@@@PORT_TAG_2@ two "A 2.2.2.2"
|
||||||
|
interface-tag-action: @INTERFACE@@@PORT_TAG_3@ refuse always_refuse
|
||||||
|
|
||||||
|
interface-view: @INTERFACE@@@PORT_VIEW_INT@ "int"
|
||||||
|
interface-view: @INTERFACE@@@PORT_VIEW_EXT@ "ext"
|
||||||
|
interface-view: @INTERFACE@@@PORT_VIEW_INTEXT@ "intext"
|
||||||
|
|
||||||
|
# Local zones configuration
|
||||||
|
local-zone: local. transparent
|
||||||
|
local-data: "local. A 0.0.0.0"
|
||||||
|
local-zone-tag: local. "one two refuse"
|
||||||
|
|
||||||
|
# Views configuration
|
||||||
|
view:
|
||||||
|
name: "int"
|
||||||
|
view-first: yes
|
||||||
|
local-zone: "." refuse
|
||||||
|
local-zone: "internal" transparent
|
||||||
|
view:
|
||||||
|
name: "ext"
|
||||||
|
view-first: yes
|
||||||
|
local-zone: "internal" refuse
|
||||||
|
view:
|
||||||
|
name: "intext"
|
||||||
|
view-first: yes
|
||||||
|
|
||||||
|
# Stubs configuration
|
||||||
|
forward-zone:
|
||||||
|
name: "."
|
||||||
|
forward-addr: @IPV4_ADDR@@@FORWARD_PORT@
|
||||||
|
|
||||||
|
stub-zone:
|
||||||
|
name: "internal"
|
||||||
|
stub-addr: @IPV4_ADDR@@@STUB_PORT@
|
16
testdata/acl_interface.tdir/acl_interface.dsc
vendored
Normal file
16
testdata/acl_interface.tdir/acl_interface.dsc
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
BaseName: acl_interface
|
||||||
|
Version: 1.0
|
||||||
|
Description: Check the interface-* settings
|
||||||
|
CreationDate: Fri 8 Oct 18:14:40 CEST 2021
|
||||||
|
Maintainer:
|
||||||
|
Category:
|
||||||
|
Component:
|
||||||
|
CmdDepends:
|
||||||
|
Depends:
|
||||||
|
Help:
|
||||||
|
Pre: acl_interface.pre
|
||||||
|
Post: acl_interface.post
|
||||||
|
Test: acl_interface.test
|
||||||
|
AuxFiles:
|
||||||
|
Passed:
|
||||||
|
Failure:
|
11
testdata/acl_interface.tdir/acl_interface.post
vendored
Normal file
11
testdata/acl_interface.tdir/acl_interface.post
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# #-- acl_interface.post --#
|
||||||
|
# source the master var file when it's there
|
||||||
|
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
|
||||||
|
# source the test var file when it's there
|
||||||
|
[ -f .tpkg.var.test ] && source .tpkg.var.test
|
||||||
|
#
|
||||||
|
# do your teardown here
|
||||||
|
. ../common.sh
|
||||||
|
kill_pid $UNBOUND_PID
|
||||||
|
kill_pid $FWD_PID
|
||||||
|
kill_pid $STUB_PID
|
75
testdata/acl_interface.tdir/acl_interface.pre
vendored
Normal file
75
testdata/acl_interface.tdir/acl_interface.pre
vendored
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
# #-- acl_interface.pre--#
|
||||||
|
PRE="../.."
|
||||||
|
. ../common.sh
|
||||||
|
|
||||||
|
# This test uses the unshare utility
|
||||||
|
if test ! -x "`which unshare 2>&1`"; then
|
||||||
|
skip_test "no unshare (from util-linux package) available, skip test"
|
||||||
|
fi
|
||||||
|
|
||||||
|
get_random_port 11
|
||||||
|
|
||||||
|
PORT_ALLOW=$RND_PORT
|
||||||
|
PORT_DENY=$(($RND_PORT + 1))
|
||||||
|
PORT_REFUSE=$(($RND_PORT + 2))
|
||||||
|
PORT_TAG_1=$(($RND_PORT + 3))
|
||||||
|
PORT_TAG_2=$(($RND_PORT + 4))
|
||||||
|
PORT_TAG_3=$(($RND_PORT + 5))
|
||||||
|
PORT_VIEW_INT=$(($RND_PORT + 6))
|
||||||
|
PORT_VIEW_EXT=$(($RND_PORT + 7))
|
||||||
|
PORT_VIEW_INTEXT=$(($RND_PORT + 8))
|
||||||
|
FORWARD_PORT=$(($RND_PORT + 9))
|
||||||
|
STUB_PORT=$(($RND_PORT + 10))
|
||||||
|
|
||||||
|
IPV4_ADDR=192.168.1.1
|
||||||
|
IPV6_ADDR=2001:db8::1
|
||||||
|
|
||||||
|
INTERFACE=eth24
|
||||||
|
INTERFACE_ADDR_1=10.0.0.1
|
||||||
|
INTERFACE_ADDR_2=10.0.0.2
|
||||||
|
INTERFACE_ADDR_3=10.0.0.3
|
||||||
|
INTERFACE_ADDR_4=10.0.0.4
|
||||||
|
|
||||||
|
# make config file
|
||||||
|
sed \
|
||||||
|
-e 's/@PORT_ALLOW\@/'$PORT_ALLOW'/' \
|
||||||
|
-e 's/@PORT_DENY\@/'$PORT_DENY'/' \
|
||||||
|
-e 's/@PORT_REFUSE\@/'$PORT_REFUSE'/' \
|
||||||
|
-e 's/@PORT_TAG_1\@/'$PORT_TAG_1'/' \
|
||||||
|
-e 's/@PORT_TAG_2\@/'$PORT_TAG_2'/' \
|
||||||
|
-e 's/@PORT_TAG_3\@/'$PORT_TAG_3'/' \
|
||||||
|
-e 's/@PORT_VIEW_INT\@/'$PORT_VIEW_INT'/' \
|
||||||
|
-e 's/@PORT_VIEW_EXT\@/'$PORT_VIEW_EXT'/' \
|
||||||
|
-e 's/@PORT_VIEW_INTEXT\@/'$PORT_VIEW_INTEXT'/' \
|
||||||
|
-e 's/@FORWARD_PORT\@/'$FORWARD_PORT'/' \
|
||||||
|
-e 's/@STUB_PORT\@/'$STUB_PORT'/' \
|
||||||
|
-e 's/@IPV4_ADDR\@/'$IPV4_ADDR'/' \
|
||||||
|
-e 's/@IPV6_ADDR\@/'$IPV6_ADDR'/' \
|
||||||
|
-e 's/@INTERFACE\@/'$INTERFACE'/' \
|
||||||
|
< acl_interface.conf > ub.conf
|
||||||
|
|
||||||
|
if test -x "`which bash`"; then
|
||||||
|
shell="bash"
|
||||||
|
else
|
||||||
|
shell="sh"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "PORT_ALLOW=$PORT_ALLOW" >> .tpkg.var.test
|
||||||
|
echo "PORT_DENY=$PORT_DENY" >> .tpkg.var.test
|
||||||
|
echo "PORT_REFUSE=$PORT_REFUSE" >> .tpkg.var.test
|
||||||
|
echo "PORT_TAG_1=$PORT_TAG_1" >> .tpkg.var.test
|
||||||
|
echo "PORT_TAG_2=$PORT_TAG_2" >> .tpkg.var.test
|
||||||
|
echo "PORT_TAG_3=$PORT_TAG_3" >> .tpkg.var.test
|
||||||
|
echo "PORT_VIEW_INT=$PORT_VIEW_INT" >> .tpkg.var.test
|
||||||
|
echo "PORT_VIEW_EXT=$PORT_VIEW_EXT" >> .tpkg.var.test
|
||||||
|
echo "PORT_VIEW_INTEXT=$PORT_VIEW_INTEXT" >> .tpkg.var.test
|
||||||
|
echo "FORWARD_PORT=$FORWARD_PORT" >> .tpkg.var.test
|
||||||
|
echo "STUB_PORT=$STUB_PORT" >> .tpkg.var.test
|
||||||
|
echo "IPV4_ADDR=$IPV4_ADDR" >> .tpkg.var.test
|
||||||
|
echo "IPV6_ADDR=$IPV6_ADDR" >> .tpkg.var.test
|
||||||
|
echo "INTERFACE=$INTERFACE" >> .tpkg.var.test
|
||||||
|
echo "INTERFACE_ADDR_1=$INTERFACE_ADDR_1" >> .tpkg.var.test
|
||||||
|
echo "INTERFACE_ADDR_2=$INTERFACE_ADDR_2" >> .tpkg.var.test
|
||||||
|
echo "INTERFACE_ADDR_3=$INTERFACE_ADDR_3" >> .tpkg.var.test
|
||||||
|
echo "INTERFACE_ADDR_4=$INTERFACE_ADDR_4" >> .tpkg.var.test
|
||||||
|
echo "shell=$shell" >> .tpkg.var.test
|
11
testdata/acl_interface.tdir/acl_interface.test
vendored
Normal file
11
testdata/acl_interface.tdir/acl_interface.test
vendored
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
# #-- acl_interface.test --#
|
||||||
|
# source the master var file when it's there
|
||||||
|
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
|
||||||
|
# use .tpkg.var.test for in test variable passing
|
||||||
|
[ -f .tpkg.var.test ] && source .tpkg.var.test
|
||||||
|
PRE="../.."
|
||||||
|
. ../common.sh
|
||||||
|
|
||||||
|
# Run the scenario in an unshared namespace
|
||||||
|
unshare -rUn $shell acl_interface.test.scenario
|
||||||
|
exit $?
|
205
testdata/acl_interface.tdir/acl_interface.test.scenario
vendored
Normal file
205
testdata/acl_interface.tdir/acl_interface.test.scenario
vendored
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
# #-- acl_interface.test.scenario --#
|
||||||
|
# source the master var file when it's there
|
||||||
|
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
|
||||||
|
# use .tpkg.var.test for in test variable passing
|
||||||
|
[ -f .tpkg.var.test ] && source .tpkg.var.test
|
||||||
|
PRE="../.."
|
||||||
|
. ../common.sh
|
||||||
|
|
||||||
|
ip addr add $IPV4_ADDR dev lo
|
||||||
|
ip addr add $IPV6_ADDR dev lo
|
||||||
|
ip link set lo up
|
||||||
|
|
||||||
|
ip link add $INTERFACE type dummy
|
||||||
|
ip addr add $INTERFACE_ADDR_1 dev $INTERFACE
|
||||||
|
ip addr add $INTERFACE_ADDR_2 dev $INTERFACE
|
||||||
|
ip addr add $INTERFACE_ADDR_3 dev $INTERFACE
|
||||||
|
ip addr add $INTERFACE_ADDR_4 dev $INTERFACE
|
||||||
|
ip link set $INTERFACE up
|
||||||
|
|
||||||
|
# start the forwarder in the background
|
||||||
|
get_ldns_testns
|
||||||
|
$LDNS_TESTNS -p $FORWARD_PORT acl_interface.testns >fwd.log 2>&1 &
|
||||||
|
FWD_PID=$!
|
||||||
|
echo "FWD_PID=$FWD_PID" >> .tpkg.var.test
|
||||||
|
|
||||||
|
# start the stub in the background
|
||||||
|
$LDNS_TESTNS -p $STUB_PORT acl_interface.testns2 >fwd2.log 2>&1 &
|
||||||
|
STUB_PID=$!
|
||||||
|
echo "STUB_PID=$STUB_PID" >> .tpkg.var.test
|
||||||
|
|
||||||
|
# start unbound in the background
|
||||||
|
$PRE/unbound -d -c ub.conf >unbound.log 2>&1 &
|
||||||
|
UNBOUND_PID=$!
|
||||||
|
echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test
|
||||||
|
|
||||||
|
cat .tpkg.var.test
|
||||||
|
wait_ldns_testns_up fwd.log
|
||||||
|
wait_ldns_testns_up fwd2.log
|
||||||
|
wait_unbound_up unbound.log
|
||||||
|
|
||||||
|
end () {
|
||||||
|
echo "> cat logfiles"
|
||||||
|
cat fwd.log
|
||||||
|
cat fwd2.log
|
||||||
|
cat unbound.log
|
||||||
|
exit $1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Query for the given domain to the given port
|
||||||
|
# $1: address family [4, 6]
|
||||||
|
# $2: port
|
||||||
|
# $3: dname
|
||||||
|
query () {
|
||||||
|
addr=$IPV4_ADDR
|
||||||
|
if test "$1" -eq 6; then
|
||||||
|
addr=$IPV6_ADDR
|
||||||
|
fi
|
||||||
|
echo "> dig -p $2 $3"
|
||||||
|
dig @"$addr" -p $2 $3 | tee outfile
|
||||||
|
}
|
||||||
|
|
||||||
|
# Query for the given domain to the given port
|
||||||
|
# $1: address
|
||||||
|
# $2: port
|
||||||
|
# $3: dname
|
||||||
|
query_addr () {
|
||||||
|
echo "> dig @$1 -p $2 $3"
|
||||||
|
dig @"$1" -p $2 $3 | tee outfile
|
||||||
|
}
|
||||||
|
|
||||||
|
expect_refused () {
|
||||||
|
echo "> check answer for REFUSED"
|
||||||
|
if grep "REFUSED" outfile; then
|
||||||
|
echo "OK"
|
||||||
|
else
|
||||||
|
echo "Not OK"
|
||||||
|
end 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
expect_external_answer () {
|
||||||
|
echo "> check external answer"
|
||||||
|
if grep "1.2.3.4" outfile; then
|
||||||
|
echo "OK"
|
||||||
|
else
|
||||||
|
echo "Not OK"
|
||||||
|
end 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
expect_internal_answer () {
|
||||||
|
echo "> check internal answer"
|
||||||
|
if grep "10.20.30.40" outfile; then
|
||||||
|
echo "OK"
|
||||||
|
else
|
||||||
|
echo "Not OK"
|
||||||
|
end 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
expect_tag_one_answer () {
|
||||||
|
echo "> check tag 'one' answer"
|
||||||
|
if grep "1.1.1.1" outfile; then
|
||||||
|
echo "OK"
|
||||||
|
else
|
||||||
|
echo "Not OK"
|
||||||
|
end 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
expect_tag_two_answer () {
|
||||||
|
echo "> check tag 'two' answer"
|
||||||
|
if grep "2.2.2.2" outfile; then
|
||||||
|
echo "OK"
|
||||||
|
else
|
||||||
|
echo "Not OK"
|
||||||
|
end 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# do the test
|
||||||
|
|
||||||
|
for i in 4 6; do
|
||||||
|
query $i $PORT_REFUSE "www.external"
|
||||||
|
expect_refused
|
||||||
|
|
||||||
|
query $i $PORT_REFUSE "www.internal"
|
||||||
|
expect_refused
|
||||||
|
|
||||||
|
query $i $PORT_ALLOW "www.external"
|
||||||
|
expect_external_answer
|
||||||
|
|
||||||
|
query $i $PORT_ALLOW "www.internal"
|
||||||
|
expect_internal_answer
|
||||||
|
|
||||||
|
query $i $PORT_TAG_1 "local"
|
||||||
|
expect_tag_one_answer
|
||||||
|
|
||||||
|
query $i $PORT_TAG_2 "local"
|
||||||
|
expect_tag_two_answer
|
||||||
|
|
||||||
|
query $i $PORT_TAG_3 "local"
|
||||||
|
expect_refused
|
||||||
|
|
||||||
|
query $i $PORT_VIEW_INT "www.internal"
|
||||||
|
expect_internal_answer
|
||||||
|
|
||||||
|
query $i $PORT_VIEW_INT "www.external"
|
||||||
|
expect_refused
|
||||||
|
|
||||||
|
query $i $PORT_VIEW_EXT "www.internal"
|
||||||
|
expect_refused
|
||||||
|
|
||||||
|
query $i $PORT_VIEW_EXT "www.external"
|
||||||
|
expect_external_answer
|
||||||
|
|
||||||
|
query $i $PORT_VIEW_INTEXT "www.internal"
|
||||||
|
expect_internal_answer
|
||||||
|
|
||||||
|
query $i $PORT_VIEW_INTEXT "www.external"
|
||||||
|
expect_external_answer
|
||||||
|
done
|
||||||
|
|
||||||
|
for addr in $INTERFACE_ADDR_1 $INTERFACE_ADDR_2 $INTERFACE_ADDR_3 $INTERFACE_ADDR_4; do
|
||||||
|
query_addr $addr $PORT_REFUSE "www.external"
|
||||||
|
expect_refused
|
||||||
|
|
||||||
|
query_addr $addr $PORT_REFUSE "www.internal"
|
||||||
|
expect_refused
|
||||||
|
|
||||||
|
query_addr $addr $PORT_ALLOW "www.external"
|
||||||
|
expect_external_answer
|
||||||
|
|
||||||
|
query_addr $addr $PORT_ALLOW "www.internal"
|
||||||
|
expect_internal_answer
|
||||||
|
|
||||||
|
query_addr $addr $PORT_TAG_1 "local"
|
||||||
|
expect_tag_one_answer
|
||||||
|
|
||||||
|
query_addr $addr $PORT_TAG_2 "local"
|
||||||
|
expect_tag_two_answer
|
||||||
|
|
||||||
|
query_addr $addr $PORT_TAG_3 "local"
|
||||||
|
expect_refused
|
||||||
|
|
||||||
|
query_addr $addr $PORT_VIEW_INT "www.internal"
|
||||||
|
expect_internal_answer
|
||||||
|
|
||||||
|
query_addr $addr $PORT_VIEW_INT "www.external"
|
||||||
|
expect_refused
|
||||||
|
|
||||||
|
query_addr $addr $PORT_VIEW_EXT "www.internal"
|
||||||
|
expect_refused
|
||||||
|
|
||||||
|
query_addr $addr $PORT_VIEW_EXT "www.external"
|
||||||
|
expect_external_answer
|
||||||
|
|
||||||
|
query_addr $addr $PORT_VIEW_INTEXT "www.internal"
|
||||||
|
expect_internal_answer
|
||||||
|
|
||||||
|
query_addr $addr $PORT_VIEW_INTEXT "www.external"
|
||||||
|
expect_external_answer
|
||||||
|
done
|
||||||
|
|
||||||
|
end 0
|
26
testdata/acl_interface.tdir/acl_interface.testns
vendored
Normal file
26
testdata/acl_interface.tdir/acl_interface.testns
vendored
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
; nameserver test file
|
||||||
|
$ORIGIN external.
|
||||||
|
$TTL 3600
|
||||||
|
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qtype qname
|
||||||
|
REPLY QR AA NOERROR
|
||||||
|
ADJUST copy_id
|
||||||
|
SECTION QUESTION
|
||||||
|
www IN A
|
||||||
|
SECTION ANSWER
|
||||||
|
www IN A 1.2.3.4
|
||||||
|
ENTRY_END
|
||||||
|
|
||||||
|
$ORIGIN local.
|
||||||
|
$TTL 3600
|
||||||
|
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qtype qname
|
||||||
|
REPLY QR AA NOERROR
|
||||||
|
ADJUST copy_id
|
||||||
|
SECTION QUESTION
|
||||||
|
@ IN A
|
||||||
|
SECTION ANSWER
|
||||||
|
@ IN A 127.0.0.1
|
||||||
|
ENTRY_END
|
13
testdata/acl_interface.tdir/acl_interface.testns2
vendored
Normal file
13
testdata/acl_interface.tdir/acl_interface.testns2
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
; nameserver test file
|
||||||
|
$ORIGIN internal.
|
||||||
|
$TTL 3600
|
||||||
|
|
||||||
|
ENTRY_BEGIN
|
||||||
|
MATCH opcode qtype qname
|
||||||
|
REPLY QR AA NOERROR
|
||||||
|
ADJUST copy_id
|
||||||
|
SECTION QUESTION
|
||||||
|
www IN A
|
||||||
|
SECTION ANSWER
|
||||||
|
www IN A 10.20.30.40
|
||||||
|
ENTRY_END
|
@ -7,7 +7,7 @@ Category:
|
|||||||
Component:
|
Component:
|
||||||
Depends:
|
Depends:
|
||||||
Help:
|
Help:
|
||||||
Pre:
|
Pre: clang-analysis.pre
|
||||||
Post:
|
Post:
|
||||||
Test: clang-analysis.test
|
Test: clang-analysis.test
|
||||||
AuxFiles:
|
AuxFiles:
|
||||||
|
21
testdata/clang-analysis.tdir/clang-analysis.pre
vendored
Normal file
21
testdata/clang-analysis.tdir/clang-analysis.pre
vendored
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# #-- clang-analysis.pre --#
|
||||||
|
# source the master var file when it's there
|
||||||
|
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
|
||||||
|
# use .tpkg.var.test for in test variable passing
|
||||||
|
[ -f .tpkg.var.test ] && source .tpkg.var.test
|
||||||
|
# common functions
|
||||||
|
. ../common.sh
|
||||||
|
|
||||||
|
PRE="../.."
|
||||||
|
if test ! -x "`which clang 2>&1`"; then
|
||||||
|
skip_test "No clang in path"
|
||||||
|
fi
|
||||||
|
#echo "have clang"
|
||||||
|
# test if assertions are enabled
|
||||||
|
if grep "^#define UNBOUND_DEBUG" $PRE/config.h >/dev/null; then
|
||||||
|
:
|
||||||
|
else
|
||||||
|
skip_test "UNBOUND_DEBUG is not enabled, skip test"
|
||||||
|
# no unbound debug means no assertions, and clang analyzer uses
|
||||||
|
# the assertions to make inferences.
|
||||||
|
fi
|
14
testdata/clang-analysis.tdir/clang-analysis.test
vendored
14
testdata/clang-analysis.tdir/clang-analysis.test
vendored
@ -7,20 +7,6 @@
|
|||||||
. ../common.sh
|
. ../common.sh
|
||||||
|
|
||||||
PRE="../.."
|
PRE="../.."
|
||||||
if test ! -x "`which clang 2>&1`"; then
|
|
||||||
echo "No clang in path"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
#echo "have clang"
|
|
||||||
# test if assertions are enabled
|
|
||||||
if grep "^#define UNBOUND_DEBUG" $PRE/config.h >/dev/null; then
|
|
||||||
:
|
|
||||||
else
|
|
||||||
echo "UNBOUND_DEBUG is not enabled, skip test"
|
|
||||||
# no unbound debug means no assertions, and clang analyzer uses
|
|
||||||
# the assertions to make inferences.
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# read value from Makefile
|
# read value from Makefile
|
||||||
# $1: result variable name
|
# $1: result variable name
|
||||||
|
8
testdata/common.sh
vendored
8
testdata/common.sh
vendored
@ -27,6 +27,7 @@
|
|||||||
# wait_petal_up : wait for petal to come up.
|
# wait_petal_up : wait for petal to come up.
|
||||||
# wait_nsd_up : wait for nsd to come up.
|
# wait_nsd_up : wait for nsd to come up.
|
||||||
# wait_server_up_or_fail: wait for server to come up or print a failure string
|
# wait_server_up_or_fail: wait for server to come up or print a failure string
|
||||||
|
# skip_test x : print message and skip test (must be called in .pre)
|
||||||
# kill_pid : kill a server, make sure and wait for it to go down.
|
# kill_pid : kill a server, make sure and wait for it to go down.
|
||||||
|
|
||||||
|
|
||||||
@ -109,6 +110,13 @@ skip_if_in_list () {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Print a message and skip the test. Must be called in the .pre file.
|
||||||
|
# $1: message to print.
|
||||||
|
skip_test () {
|
||||||
|
echo "$1"
|
||||||
|
exit 3
|
||||||
|
}
|
||||||
|
|
||||||
# function to get a number of random port numbers.
|
# function to get a number of random port numbers.
|
||||||
# $1: number of random ports.
|
# $1: number of random ports.
|
||||||
# RND_PORT is returned as the starting port number
|
# RND_PORT is returned as the starting port number
|
||||||
|
@ -8,9 +8,6 @@
|
|||||||
PRE="../.."
|
PRE="../.."
|
||||||
. ../common.sh
|
. ../common.sh
|
||||||
|
|
||||||
# Check if we can run the test.
|
|
||||||
. ./precheck.sh
|
|
||||||
|
|
||||||
kill_pid $FWD_PID
|
kill_pid $FWD_PID
|
||||||
kill_pid $UNBOUND_PID
|
kill_pid $UNBOUND_PID
|
||||||
|
|
||||||
|
@ -8,7 +8,11 @@ PRE="../.."
|
|||||||
. ../common.sh
|
. ../common.sh
|
||||||
|
|
||||||
# Check if we can run the test.
|
# Check if we can run the test.
|
||||||
. ./precheck.sh
|
if grep "define USE_DNSCRYPT 1" $PRE/config.h; then
|
||||||
|
echo "have dnscrypt"
|
||||||
|
else
|
||||||
|
skip_test "no dnscrypt"
|
||||||
|
fi
|
||||||
|
|
||||||
get_random_port 3
|
get_random_port 3
|
||||||
UNBOUND_PORT=$RND_PORT
|
UNBOUND_PORT=$RND_PORT
|
||||||
|
@ -7,9 +7,6 @@
|
|||||||
PRE="../.."
|
PRE="../.."
|
||||||
. ../common.sh
|
. ../common.sh
|
||||||
|
|
||||||
# Check if we can run the test.
|
|
||||||
. ./precheck.sh
|
|
||||||
|
|
||||||
# do the test
|
# do the test
|
||||||
|
|
||||||
# Query plain request over DNSCrypt channel get closed
|
# Query plain request over DNSCrypt channel get closed
|
||||||
|
16
testdata/dnscrypt_cert.tdir/precheck.sh
vendored
16
testdata/dnscrypt_cert.tdir/precheck.sh
vendored
@ -1,16 +0,0 @@
|
|||||||
# dnscrypt precheck.sh
|
|
||||||
|
|
||||||
# if no dnscrypt; exit
|
|
||||||
if grep "define USE_DNSCRYPT 1" $PRE/config.h; then
|
|
||||||
echo "have dnscrypt"
|
|
||||||
else
|
|
||||||
echo "no dnscrypt"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# if no xchacha20 support in unbound; exit
|
|
||||||
if grep "define USE_DNSCRYPT_XCHACHA20 1" $PRE/config.h; then
|
|
||||||
xchacha20=1
|
|
||||||
else
|
|
||||||
xchacha20=0
|
|
||||||
fi
|
|
@ -8,10 +8,5 @@
|
|||||||
PRE="../.."
|
PRE="../.."
|
||||||
. ../common.sh
|
. ../common.sh
|
||||||
|
|
||||||
# Check if we can run the test.
|
|
||||||
. ./precheck.sh
|
|
||||||
|
|
||||||
kill_pid $FWD_PID
|
kill_pid $FWD_PID
|
||||||
if [ $xchacha20 -ne 0 ]; then
|
kill_pid $UNBOUND_PID
|
||||||
kill_pid $UNBOUND_PID
|
|
||||||
fi
|
|
||||||
|
@ -7,8 +7,17 @@
|
|||||||
PRE="../.."
|
PRE="../.."
|
||||||
. ../common.sh
|
. ../common.sh
|
||||||
|
|
||||||
# Check if we can run the test.
|
# if no dnscrypt; exit
|
||||||
. ./precheck.sh
|
if grep "define USE_DNSCRYPT 1" $PRE/config.h; then
|
||||||
|
echo "have dnscrypt"
|
||||||
|
else
|
||||||
|
skip_test "no dnscrypt"
|
||||||
|
fi
|
||||||
|
if grep "define USE_DNSCRYPT_XCHACHA20 1" $PRE/config.h; then
|
||||||
|
echo "have XChacha20 support"
|
||||||
|
else
|
||||||
|
skip_test "no XChacha20 support"
|
||||||
|
fi
|
||||||
|
|
||||||
get_random_port 3
|
get_random_port 3
|
||||||
UNBOUND_PORT=$RND_PORT
|
UNBOUND_PORT=$RND_PORT
|
||||||
@ -34,10 +43,5 @@ echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test
|
|||||||
|
|
||||||
cat .tpkg.var.test
|
cat .tpkg.var.test
|
||||||
wait_ldns_testns_up fwd.log
|
wait_ldns_testns_up fwd.log
|
||||||
if [ $xchacha20 -eq 0 ]; then
|
wait_unbound_up unbound.log
|
||||||
# no xchacha20 support, we expect unbound to exit with an error message.
|
|
||||||
wait_server_up unbound.log "Certificate for XChacha20 but libsodium does not support it"
|
|
||||||
else
|
|
||||||
wait_unbound_up unbound.log
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
@ -6,17 +6,9 @@
|
|||||||
|
|
||||||
PRE="../.."
|
PRE="../.."
|
||||||
. ../common.sh
|
. ../common.sh
|
||||||
# Check if we can run the test.
|
|
||||||
. ./precheck.sh
|
|
||||||
|
|
||||||
# do the test
|
# do the test
|
||||||
|
|
||||||
if [ $xchacha20 -eq 0 ]; then
|
|
||||||
# Unbound would exit before we can attempt any tests.
|
|
||||||
echo "OK"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Query plain request over DNSCrypt channel get closed
|
# Query plain request over DNSCrypt channel get closed
|
||||||
# We use TCP to avoid hanging on waiting for UDP.
|
# We use TCP to avoid hanging on waiting for UDP.
|
||||||
# We expect `outfile` to contain no DNS payload
|
# We expect `outfile` to contain no DNS payload
|
||||||
@ -104,7 +96,7 @@ do
|
|||||||
echo "> check answer"
|
echo "> check answer"
|
||||||
grep -F 'DNSC\000\002\000\000\1716\226\255*\244\002L\177g\025_\127tR\151\246R\203\178\153\248\006\137\"\138\173|G/,\160\152\015\010\172\184\220`\175\217\255,\162\018\178-d\007\246k0\003I[\205w\026)\204B\002\161\010\245\243W\191\189Z\216\210x\025\204\247\173\227t\138\018\162~\152\253\211\031z\\\002m5\008\254\2244\246\243W\191\189Z\216\210Y\160\2158Y\160\2158u\210\219\184' outfile
|
grep -F 'DNSC\000\002\000\000\1716\226\255*\244\002L\177g\025_\127tR\151\246R\203\178\153\248\006\137\"\138\173|G/,\160\152\015\010\172\184\220`\175\217\255,\162\018\178-d\007\246k0\003I[\205w\026)\204B\002\161\010\245\243W\191\189Z\216\210x\025\204\247\173\227t\138\018\162~\152\253\211\031z\\\002m5\008\254\2244\246\243W\191\189Z\216\210Y\160\2158Y\160\2158u\210\219\184' outfile
|
||||||
cert_found=$?
|
cert_found=$?
|
||||||
if [ \( $cert_found -eq 0 -a $xchacha20 -eq 1 \) -o \( $cert_found -ne 0 -a $xchacha20 -eq 0 \) ]; then
|
if [ \( $cert_found -eq 0 \) ]; then
|
||||||
echo "OK"
|
echo "OK"
|
||||||
else
|
else
|
||||||
echo "Not OK"
|
echo "Not OK"
|
||||||
|
16
testdata/dnscrypt_cert_chacha.tdir/precheck.sh
vendored
16
testdata/dnscrypt_cert_chacha.tdir/precheck.sh
vendored
@ -1,16 +0,0 @@
|
|||||||
# dnscrypt precheck.sh
|
|
||||||
|
|
||||||
# if no dnscrypt; exit
|
|
||||||
if grep "define USE_DNSCRYPT 1" $PRE/config.h; then
|
|
||||||
echo "have dnscrypt"
|
|
||||||
else
|
|
||||||
echo "no dnscrypt"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# if no xchacha20 support in unbound; exit
|
|
||||||
if grep "define USE_DNSCRYPT_XCHACHA20 1" $PRE/config.h; then
|
|
||||||
xchacha20=1
|
|
||||||
else
|
|
||||||
xchacha20=0
|
|
||||||
fi
|
|
1
testdata/dnstap.tdir/dnstap.post
vendored
1
testdata/dnstap.tdir/dnstap.post
vendored
@ -7,7 +7,6 @@
|
|||||||
# do your teardown here
|
# do your teardown here
|
||||||
. ../common.sh
|
. ../common.sh
|
||||||
PRE="../.."
|
PRE="../.."
|
||||||
if grep "define USE_DNSTAP 1" $PRE/config.h; then echo test enabled; else echo test skipped; exit 0; fi
|
|
||||||
kill_pid $DNSTAP_SOCKET_PID
|
kill_pid $DNSTAP_SOCKET_PID
|
||||||
kill_pid $FWD_PID
|
kill_pid $FWD_PID
|
||||||
kill $UNBOUND_PID
|
kill $UNBOUND_PID
|
||||||
|
2
testdata/dnstap.tdir/dnstap.pre
vendored
2
testdata/dnstap.tdir/dnstap.pre
vendored
@ -7,7 +7,7 @@
|
|||||||
. ../common.sh
|
. ../common.sh
|
||||||
|
|
||||||
PRE="../.."
|
PRE="../.."
|
||||||
if grep "define USE_DNSTAP 1" $PRE/config.h; then echo test enabled; else echo test skipped; exit 0; fi
|
if grep "define USE_DNSTAP 1" $PRE/config.h; then echo test enabled; else skip_test "test skipped"; fi
|
||||||
|
|
||||||
get_random_port 3
|
get_random_port 3
|
||||||
UNBOUND_PORT=$RND_PORT
|
UNBOUND_PORT=$RND_PORT
|
||||||
|
1
testdata/dnstap.tdir/dnstap.test
vendored
1
testdata/dnstap.tdir/dnstap.test
vendored
@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
. ../common.sh
|
. ../common.sh
|
||||||
PRE="../.."
|
PRE="../.."
|
||||||
if grep "define USE_DNSTAP 1" $PRE/config.h; then echo test enabled; else echo test skipped; exit 0; fi
|
|
||||||
|
|
||||||
# test if the server is up.
|
# test if the server is up.
|
||||||
echo "> dig www.example.com."
|
echo "> dig www.example.com."
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
# do your teardown here
|
# do your teardown here
|
||||||
. ../common.sh
|
. ../common.sh
|
||||||
PRE="../.."
|
PRE="../.."
|
||||||
if grep "define USE_DNSTAP 1" $PRE/config.h; then echo test enabled; else echo test skipped; exit 0; fi
|
|
||||||
kill_pid $DNSTAP_SOCKET_PID
|
kill_pid $DNSTAP_SOCKET_PID
|
||||||
kill_pid $FWD_PID
|
kill_pid $FWD_PID
|
||||||
kill $UNBOUND_PID
|
kill $UNBOUND_PID
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
. ../common.sh
|
. ../common.sh
|
||||||
|
|
||||||
PRE="../.."
|
PRE="../.."
|
||||||
if grep "define USE_DNSTAP 1" $PRE/config.h; then echo test enabled; else echo test skipped; exit 0; fi
|
if grep "define USE_DNSTAP 1" $PRE/config.h; then echo test enabled; else skip_test "test skipped"; fi
|
||||||
|
|
||||||
get_random_port 3
|
get_random_port 3
|
||||||
UNBOUND_PORT=$RND_PORT
|
UNBOUND_PORT=$RND_PORT
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
. ../common.sh
|
. ../common.sh
|
||||||
PRE="../.."
|
PRE="../.."
|
||||||
if grep "define USE_DNSTAP 1" $PRE/config.h; then echo test enabled; else echo test skipped; exit 0; fi
|
|
||||||
|
|
||||||
# test if the server is up.
|
# test if the server is up.
|
||||||
echo "> dig www.example.com."
|
echo "> dig www.example.com."
|
||||||
|
1
testdata/dnstap_tcp.tdir/dnstap_tcp.post
vendored
1
testdata/dnstap_tcp.tdir/dnstap_tcp.post
vendored
@ -7,7 +7,6 @@
|
|||||||
# do your teardown here
|
# do your teardown here
|
||||||
. ../common.sh
|
. ../common.sh
|
||||||
PRE="../.."
|
PRE="../.."
|
||||||
if grep "define USE_DNSTAP 1" $PRE/config.h; then echo test enabled; else echo test skipped; exit 0; fi
|
|
||||||
kill_pid $DNSTAP_SOCKET_PID
|
kill_pid $DNSTAP_SOCKET_PID
|
||||||
kill_pid $FWD_PID
|
kill_pid $FWD_PID
|
||||||
kill $UNBOUND_PID
|
kill $UNBOUND_PID
|
||||||
|
2
testdata/dnstap_tcp.tdir/dnstap_tcp.pre
vendored
2
testdata/dnstap_tcp.tdir/dnstap_tcp.pre
vendored
@ -7,7 +7,7 @@
|
|||||||
. ../common.sh
|
. ../common.sh
|
||||||
|
|
||||||
PRE="../.."
|
PRE="../.."
|
||||||
if grep "define USE_DNSTAP 1" $PRE/config.h; then echo test enabled; else echo test skipped; exit 0; fi
|
if grep "define USE_DNSTAP 1" $PRE/config.h; then echo test enabled; else skip_test "test skipped"; fi
|
||||||
|
|
||||||
get_random_port 4
|
get_random_port 4
|
||||||
UNBOUND_PORT=$RND_PORT
|
UNBOUND_PORT=$RND_PORT
|
||||||
|
1
testdata/dnstap_tcp.tdir/dnstap_tcp.test
vendored
1
testdata/dnstap_tcp.tdir/dnstap_tcp.test
vendored
@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
. ../common.sh
|
. ../common.sh
|
||||||
PRE="../.."
|
PRE="../.."
|
||||||
if grep "define USE_DNSTAP 1" $PRE/config.h; then echo test enabled; else echo test skipped; exit 0; fi
|
|
||||||
|
|
||||||
# test if the server is up.
|
# test if the server is up.
|
||||||
echo "> dig www.example.com."
|
echo "> dig www.example.com."
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user