mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-08-17 21:25:50 +02:00
Compare commits
86
Commits
ideleg
...
release-1.21.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b7c61d7cc2 | ||
|
|
01883fb017 | ||
|
|
79e4c57851 | ||
|
|
5abdd09095 | ||
|
|
158c1defe3 | ||
|
|
b4519012dc | ||
|
|
ed883238fd | ||
|
|
0f2f6025e7 | ||
|
|
3cbf554e3b | ||
|
|
ad21dbd1c2 | ||
|
|
50cf55bdac | ||
|
|
6106528a50 | ||
|
|
befa7d8cd8 | ||
|
|
92be76fb89 | ||
|
|
9a6b6765cc | ||
|
|
03b511b1a2 | ||
|
|
6af28bed08 | ||
|
|
f094f4ea3c | ||
|
|
c717debace | ||
|
|
7d4d21764a | ||
|
|
83e6977f06 | ||
|
|
671e11552c | ||
|
|
c4541e634b | ||
|
|
30da725e67 | ||
|
|
8de5ae3552 | ||
|
|
5bea29b01c | ||
|
|
89c9eafa44 | ||
|
|
3512eaec48 | ||
|
|
f9bd35dcfa | ||
|
|
3af4e44646 | ||
|
|
c3dd6a2dbd | ||
|
|
8fca3e7c5b | ||
|
|
8947c2c764 | ||
|
|
b1e3319a11 | ||
|
|
d52f501d90 | ||
|
|
7083d58c6b | ||
|
|
3adb9c8f92 | ||
|
|
51425b2388 | ||
|
|
d43760a8cd | ||
|
|
ea3e327006 | ||
|
|
be09350eca | ||
|
|
169acfc546 | ||
|
|
bed7cc2a90 | ||
|
|
02f4446833 | ||
|
|
c8a2289542 | ||
|
|
b53d90053e | ||
|
|
978b0696d3 | ||
|
|
ec5f86b4eb | ||
|
|
ec2f45c6fd | ||
|
|
6b319c97ee | ||
|
|
6eb3992c9e | ||
|
|
94a94fd8c8 | ||
|
|
36f9d1a2a9 | ||
|
|
d3a2264272 | ||
|
|
92b6c2a7b9 | ||
|
|
a335e601e4 | ||
|
|
a19009df1d | ||
|
|
96f8a94c19 | ||
|
|
2fe4e2ec3e | ||
|
|
e54928a628 | ||
|
|
538434186e | ||
|
|
65e7253d19 | ||
|
|
03ac902296 | ||
|
|
97ad1df343 | ||
|
|
2279cde8f7 | ||
|
|
ff653a7ef8 | ||
|
|
fd11cd9182 | ||
|
|
3953f827fb | ||
|
|
7fbc061846 | ||
|
|
70f73a33b3 | ||
|
|
b67fbb69e7 | ||
|
|
902c79608c | ||
|
|
08050dc939 | ||
|
|
9603924bb4 | ||
|
|
4c2da2b979 | ||
|
|
1974732d19 | ||
|
|
3cad5818a1 | ||
|
|
ad12109191 | ||
|
|
f611220eb8 | ||
|
|
ac609fcbfc | ||
|
|
486985fbdf | ||
|
|
caab100207 | ||
|
|
1d23e0c920 | ||
|
|
ad51795314 | ||
|
|
7d76e84953 | ||
|
|
c96e4ca121 |
@@ -10,6 +10,9 @@
|
||||
/config.status
|
||||
/dnstap/dnstap_config.h
|
||||
/dnscrypt/dnscrypt_config.h
|
||||
/util/configlexer.c
|
||||
/util/configparser.c
|
||||
/util/configparser.h
|
||||
/clubsyms.def
|
||||
/doc/example.conf
|
||||
/doc/libunbound.3
|
||||
@@ -55,6 +58,7 @@
|
||||
/pythonmod/unboundmodule.py
|
||||
/testdata/result.*
|
||||
/testdata/.done-*
|
||||
/testdata/.skip-*
|
||||
/testdata/.perfstats.txt
|
||||
/doc/html
|
||||
/doc/xml
|
||||
|
||||
+3
-2
@@ -439,7 +439,8 @@ unbound-control-setup: smallapp/unbound-control-setup.sh
|
||||
dnstap.lo dnstap.o: $(srcdir)/dnstap/dnstap.c config.h dnstap/dnstap_config.h \
|
||||
dnstap/dnstap.pb-c.c dnstap/dnstap.pb-c.h $(srcdir)/dnstap/dnstap.h \
|
||||
$(srcdir)/util/config_file.h $(srcdir)/util/log.h \
|
||||
$(srcdir)/util/netevent.h $(srcdir)/util/net_help.h
|
||||
$(srcdir)/util/netevent.h $(srcdir)/util/net_help.h \
|
||||
$(srcdir)/util/locks.h
|
||||
|
||||
dnstap/dnstap.pb-c.c dnstap/dnstap.pb-c.h: $(srcdir)/dnstap/dnstap.proto
|
||||
@-if test ! -d dnstap; then $(INSTALL) -d dnstap; fi
|
||||
@@ -1297,7 +1298,7 @@ remote.lo remote.o: $(srcdir)/daemon/remote.c config.h $(srcdir)/daemon/remote.h
|
||||
$(srcdir)/validator/val_anchor.h $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h \
|
||||
$(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h $(srcdir)/iterator/iter_delegpt.h \
|
||||
$(srcdir)/services/outside_network.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/parseutil.h \
|
||||
$(srcdir)/sldns/wire2str.h
|
||||
$(srcdir)/sldns/wire2str.h $(srcdir)/util/edns.h
|
||||
stats.lo stats.o: $(srcdir)/daemon/stats.c config.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
|
||||
$(srcdir)/libunbound/unbound.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
|
||||
$(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ AC_DEFUN([AC_PYTHON_DEVEL],[
|
||||
|
||||
AC_PATH_PROG([PYTHON],[python[$PYTHON_VERSION]])
|
||||
if test -z "$PYTHON"; then
|
||||
AC_MSG_ERROR([Cannot find python$PYTHON_VERSION in your system path])
|
||||
AC_MSG_ERROR([Cannot find 'python$PYTHON_VERSION' in your system path. You can use the environment variable 'PYTHON_VERSION=version_number' for an explicit version.])
|
||||
PYTHON_VERSION=""
|
||||
fi
|
||||
|
||||
|
||||
+1
-1
@@ -983,7 +983,7 @@ cachedb_get_mem(struct module_env* env, int id)
|
||||
*/
|
||||
static struct module_func_block cachedb_block = {
|
||||
"cachedb",
|
||||
&cachedb_init, &cachedb_deinit, &cachedb_operate,
|
||||
NULL, NULL, &cachedb_init, &cachedb_deinit, &cachedb_operate,
|
||||
&cachedb_inform_super, &cachedb_clear, &cachedb_get_mem
|
||||
};
|
||||
|
||||
|
||||
+15
@@ -1,5 +1,8 @@
|
||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* apply the fallthrough attribute. */
|
||||
#undef ATTR_FALLTHROUGH
|
||||
|
||||
/* apply the noreturn attribute to a function that exits the program */
|
||||
#undef ATTR_NORETURN
|
||||
|
||||
@@ -57,6 +60,9 @@
|
||||
/* Define to 1 if you have the <arpa/inet.h> header file. */
|
||||
#undef HAVE_ARPA_INET_H
|
||||
|
||||
/* Whether the C compiler accepts the "fallthrough" attribute */
|
||||
#undef HAVE_ATTR_FALLTHROUGH
|
||||
|
||||
/* Whether the C compiler accepts the "format" attribute */
|
||||
#undef HAVE_ATTR_FORMAT
|
||||
|
||||
@@ -406,6 +412,9 @@
|
||||
/* Define to 1 if you have the <net/if.h> header file. */
|
||||
#undef HAVE_NET_IF_H
|
||||
|
||||
/* Define to 1 if you have the <net/pfvar.h> header file. */
|
||||
#undef HAVE_NET_PFVAR_H
|
||||
|
||||
/* Define this to use nghttp2 client. */
|
||||
#undef HAVE_NGHTTP2
|
||||
|
||||
@@ -566,6 +575,9 @@
|
||||
function. */
|
||||
#undef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB
|
||||
|
||||
/* Define to 1 if you have the `SSL_CTX_set_tmp_ecdh' function. */
|
||||
#undef HAVE_SSL_CTX_SET_TMP_ECDH
|
||||
|
||||
/* Define to 1 if you have the `SSL_get0_alpn_selected' function. */
|
||||
#undef HAVE_SSL_GET0_ALPN_SELECTED
|
||||
|
||||
@@ -1484,6 +1496,7 @@ struct sockaddr_storage;
|
||||
# define calloc(n,s) unbound_stat_calloc_log(n, s, __FILE__, __LINE__, __func__)
|
||||
# define free(p) unbound_stat_free_log(p, __FILE__, __LINE__, __func__)
|
||||
# define realloc(p,s) unbound_stat_realloc_log(p, s, __FILE__, __LINE__, __func__)
|
||||
# define strdup(s) unbound_stat_strdup_log(s, __FILE__, __LINE__, __func__)
|
||||
void *unbound_stat_malloc(size_t size);
|
||||
void *unbound_stat_calloc(size_t nmemb, size_t size);
|
||||
void unbound_stat_free(void *ptr);
|
||||
@@ -1496,6 +1509,8 @@ void unbound_stat_free_log(void *ptr, const char* file, int line,
|
||||
const char* func);
|
||||
void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
|
||||
int line, const char* func);
|
||||
char *unbound_stat_strdup_log(const char *s, const char* file, int line,
|
||||
const char* func);
|
||||
#elif defined(UNBOUND_ALLOC_LITE)
|
||||
# include "util/alloc.h"
|
||||
#endif /* UNBOUND_ALLOC_LITE and UNBOUND_ALLOC_STATS */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.71 for unbound 1.20.1.
|
||||
# Generated by GNU Autoconf 2.71 for unbound 1.21.1.
|
||||
#
|
||||
# Report bugs to <unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues>.
|
||||
#
|
||||
@@ -622,8 +622,8 @@ MAKEFLAGS=
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='unbound'
|
||||
PACKAGE_TARNAME='unbound'
|
||||
PACKAGE_VERSION='1.20.1'
|
||||
PACKAGE_STRING='unbound 1.20.1'
|
||||
PACKAGE_VERSION='1.21.1'
|
||||
PACKAGE_STRING='unbound 1.21.1'
|
||||
PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues'
|
||||
PACKAGE_URL=''
|
||||
|
||||
@@ -1508,7 +1508,7 @@ if test "$ac_init_help" = "long"; then
|
||||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures unbound 1.20.1 to adapt to many kinds of systems.
|
||||
\`configure' configures unbound 1.21.1 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@@ -1574,7 +1574,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of unbound 1.20.1:";;
|
||||
short | recursive ) echo "Configuration of unbound 1.21.1:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@@ -1596,7 +1596,8 @@ Optional Features:
|
||||
--disable-libtool-lock avoid locking (might break parallel builds)
|
||||
--disable-rpath disable hardcoded rpath (default=enabled)
|
||||
--disable-largefile omit support for large files
|
||||
--enable-systemd compile with systemd support
|
||||
--enable-systemd compile with systemd support (requires libsystemd,
|
||||
pkg-config)
|
||||
--enable-alloc-checks enable to memory allocation statistics, for debug
|
||||
purposes
|
||||
--enable-alloc-lite enable for lightweight alloc assertions, for debug
|
||||
@@ -1821,7 +1822,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
unbound configure 1.20.1
|
||||
unbound configure 1.21.1
|
||||
generated by GNU Autoconf 2.71
|
||||
|
||||
Copyright (C) 2021 Free Software Foundation, Inc.
|
||||
@@ -2478,7 +2479,7 @@ cat >config.log <<_ACEOF
|
||||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by unbound $as_me 1.20.1, which was
|
||||
It was created by unbound $as_me 1.21.1, which was
|
||||
generated by GNU Autoconf 2.71. Invocation command line was
|
||||
|
||||
$ $0$ac_configure_args_raw
|
||||
@@ -3240,13 +3241,13 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
||||
|
||||
UNBOUND_VERSION_MAJOR=1
|
||||
|
||||
UNBOUND_VERSION_MINOR=20
|
||||
UNBOUND_VERSION_MINOR=21
|
||||
|
||||
UNBOUND_VERSION_MICRO=1
|
||||
|
||||
|
||||
LIBUNBOUND_CURRENT=9
|
||||
LIBUNBOUND_REVISION=28
|
||||
LIBUNBOUND_REVISION=29
|
||||
LIBUNBOUND_AGE=1
|
||||
# 1.0.0 had 0:12:0
|
||||
# 1.0.1 had 0:13:0
|
||||
@@ -3341,7 +3342,8 @@ LIBUNBOUND_AGE=1
|
||||
# 1.19.2 had 9:25:1
|
||||
# 1.19.3 had 9:26:1
|
||||
# 1.20.0 had 9:27:1
|
||||
# 1.20.1 had 9:28:1
|
||||
# 1.21.0 had 9:28:1
|
||||
# 1.21.1 had 9:29:1
|
||||
|
||||
# Current -- the number of the binary API that we're implementing
|
||||
# Revision -- which iteration of the implementation of the binary
|
||||
@@ -6975,6 +6977,10 @@ printf "%s\n" "#define HAVE_ATTR_WEAK 1" >>confdefs.h
|
||||
|
||||
printf "%s\n" "#define ATTR_WEAK __attribute__((weak))" >>confdefs.h
|
||||
|
||||
else
|
||||
|
||||
printf "%s\n" "#define ATTR_WEAK /**/" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
|
||||
@@ -7022,6 +7028,79 @@ printf "%s\n" "#define HAVE_ATTR_NORETURN 1" >>confdefs.h
|
||||
|
||||
printf "%s\n" "#define ATTR_NORETURN __attribute__((__noreturn__))" >>confdefs.h
|
||||
|
||||
else
|
||||
|
||||
printf "%s\n" "#define ATTR_NORETURN /**/" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler (${CC-cc}) accepts the \"fallthrough\" attribute" >&5
|
||||
printf %s "checking whether the C compiler (${CC-cc}) accepts the \"fallthrough\" attribute... " >&6; }
|
||||
BAKCFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS -Werror"
|
||||
if test ${ac_cv_c_fallthrough_attribute+y}
|
||||
then :
|
||||
printf %s "(cached) " >&6
|
||||
else $as_nop
|
||||
ac_cv_c_fallthrough_attribute=no
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
#include <stdio.h>
|
||||
void f(int x) {
|
||||
int y = 0;
|
||||
switch(x) {
|
||||
case 1:
|
||||
y = 1;
|
||||
__attribute__((fallthrough));
|
||||
/* fallthrough */
|
||||
case 2:
|
||||
y++;
|
||||
break;
|
||||
case 3:
|
||||
y = 3;
|
||||
break;
|
||||
}
|
||||
printf("%d", y);
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
|
||||
f(1);
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"
|
||||
then :
|
||||
ac_cv_c_fallthrough_attribute="yes"
|
||||
else $as_nop
|
||||
ac_cv_c_fallthrough_attribute="no"
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
|
||||
|
||||
fi
|
||||
|
||||
CFLAGS="$BAKCFLAGS"
|
||||
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_fallthrough_attribute" >&5
|
||||
printf "%s\n" "$ac_cv_c_fallthrough_attribute" >&6; }
|
||||
if test $ac_cv_c_fallthrough_attribute = yes; then
|
||||
|
||||
printf "%s\n" "#define HAVE_ATTR_FALLTHROUGH 1" >>confdefs.h
|
||||
|
||||
|
||||
printf "%s\n" "#define ATTR_FALLTHROUGH __attribute__((fallthrough));" >>confdefs.h
|
||||
|
||||
else
|
||||
|
||||
printf "%s\n" "#define ATTR_FALLTHROUGH /**/" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
|
||||
@@ -17624,7 +17703,8 @@ have_systemd=no
|
||||
if test "x$enable_systemd" != xno
|
||||
then :
|
||||
|
||||
|
||||
if test -n "$PKG_CONFIG"; then
|
||||
have_systemd=no
|
||||
|
||||
pkg_failed=no
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for SYSTEMD" >&5
|
||||
@@ -17684,11 +17764,31 @@ fi
|
||||
# Put the nasty error message in config.log where it belongs
|
||||
echo "$SYSTEMD_PKG_ERRORS" >&5
|
||||
|
||||
have_systemd=no
|
||||
as_fn_error $? "Package requirements (libsystemd) were not met:
|
||||
|
||||
$SYSTEMD_PKG_ERRORS
|
||||
|
||||
Consider adjusting the PKG_CONFIG_PATH environment variable if you
|
||||
installed software in a non-standard prefix.
|
||||
|
||||
Alternatively, you may set the environment variables SYSTEMD_CFLAGS
|
||||
and SYSTEMD_LIBS to avoid the need to call pkg-config.
|
||||
See the pkg-config man page for more details." "$LINENO" 5
|
||||
elif test $pkg_failed = untried; then
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
printf "%s\n" "no" >&6; }
|
||||
have_systemd=no
|
||||
{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
|
||||
printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
|
||||
as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
|
||||
is in your PATH or set the PKG_CONFIG environment variable to the full
|
||||
path to pkg-config.
|
||||
|
||||
Alternatively, you may set the environment variables SYSTEMD_CFLAGS
|
||||
and SYSTEMD_LIBS to avoid the need to call pkg-config.
|
||||
See the pkg-config man page for more details.
|
||||
|
||||
To get pkg-config, see <http://pkg-config.freedesktop.org/>.
|
||||
See \`config.log' for more details" "$LINENO" 5; }
|
||||
else
|
||||
SYSTEMD_CFLAGS=$pkg_cv_SYSTEMD_CFLAGS
|
||||
SYSTEMD_LIBS=$pkg_cv_SYSTEMD_LIBS
|
||||
@@ -17699,6 +17799,7 @@ fi
|
||||
if test "x$have_systemd" != "xyes"
|
||||
then :
|
||||
|
||||
have_systemd_daemon=no
|
||||
|
||||
pkg_failed=no
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for SYSTEMD_DAEMON" >&5
|
||||
@@ -17758,11 +17859,31 @@ fi
|
||||
# Put the nasty error message in config.log where it belongs
|
||||
echo "$SYSTEMD_DAEMON_PKG_ERRORS" >&5
|
||||
|
||||
have_systemd_daemon=no
|
||||
as_fn_error $? "Package requirements (libsystemd-daemon) were not met:
|
||||
|
||||
$SYSTEMD_DAEMON_PKG_ERRORS
|
||||
|
||||
Consider adjusting the PKG_CONFIG_PATH environment variable if you
|
||||
installed software in a non-standard prefix.
|
||||
|
||||
Alternatively, you may set the environment variables SYSTEMD_DAEMON_CFLAGS
|
||||
and SYSTEMD_DAEMON_LIBS to avoid the need to call pkg-config.
|
||||
See the pkg-config man page for more details." "$LINENO" 5
|
||||
elif test $pkg_failed = untried; then
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
printf "%s\n" "no" >&6; }
|
||||
have_systemd_daemon=no
|
||||
{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
|
||||
printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
|
||||
as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it
|
||||
is in your PATH or set the PKG_CONFIG environment variable to the full
|
||||
path to pkg-config.
|
||||
|
||||
Alternatively, you may set the environment variables SYSTEMD_DAEMON_CFLAGS
|
||||
and SYSTEMD_DAEMON_LIBS to avoid the need to call pkg-config.
|
||||
See the pkg-config man page for more details.
|
||||
|
||||
To get pkg-config, see <http://pkg-config.freedesktop.org/>.
|
||||
See \`config.log' for more details" "$LINENO" 5; }
|
||||
else
|
||||
SYSTEMD_DAEMON_CFLAGS=$pkg_cv_SYSTEMD_DAEMON_CFLAGS
|
||||
SYSTEMD_DAEMON_LIBS=$pkg_cv_SYSTEMD_DAEMON_LIBS
|
||||
@@ -17789,7 +17910,9 @@ printf "%s\n" "#define HAVE_SYSTEMD 1" >>confdefs.h
|
||||
*) :
|
||||
;;
|
||||
esac
|
||||
|
||||
else
|
||||
as_fn_error $? "systemd enabled but need pkg-config to configure for it" "$LINENO" 5
|
||||
fi
|
||||
|
||||
fi
|
||||
if test "x$have_systemd" = xyes; then
|
||||
@@ -19185,7 +19308,7 @@ fi
|
||||
|
||||
|
||||
if test -z "$PYTHON"; then
|
||||
as_fn_error $? "Cannot find python$PYTHON_VERSION in your system path" "$LINENO" 5
|
||||
as_fn_error $? "Cannot find 'python$PYTHON_VERSION' in your system path. You can use the environment variable 'PYTHON_VERSION=version_number' for an explicit version." "$LINENO" 5
|
||||
PYTHON_VERSION=""
|
||||
fi
|
||||
|
||||
@@ -20656,6 +20779,12 @@ then :
|
||||
printf "%s\n" "#define HAVE_BIO_SET_CALLBACK_EX 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
ac_fn_c_check_func "$LINENO" "SSL_CTX_set_tmp_ecdh" "ac_cv_func_SSL_CTX_set_tmp_ecdh"
|
||||
if test "x$ac_cv_func_SSL_CTX_set_tmp_ecdh" = xyes
|
||||
then :
|
||||
printf "%s\n" "#define HAVE_SSL_CTX_SET_TMP_ECDH 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
|
||||
# these check_funcs need -lssl
|
||||
@@ -21190,7 +21319,25 @@ case "$enable_ecdsa" in
|
||||
;;
|
||||
*)
|
||||
if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
|
||||
ac_fn_c_check_func "$LINENO" "ECDSA_sign" "ac_cv_func_ECDSA_sign"
|
||||
ac_fn_c_check_func "$LINENO" "EVP_PKEY_fromdata" "ac_cv_func_EVP_PKEY_fromdata"
|
||||
if test "x$ac_cv_func_EVP_PKEY_fromdata" = xyes
|
||||
then :
|
||||
|
||||
# with EVP_PKEY_fromdata, check if EC is not disabled
|
||||
ac_fn_check_decl "$LINENO" "OPENSSL_NO_EC" "ac_cv_have_decl_OPENSSL_NO_EC" "$ac_includes_default
|
||||
#include <openssl/evp.h>
|
||||
|
||||
" "$ac_c_undeclared_builtin_options" "CFLAGS"
|
||||
if test "x$ac_cv_have_decl_OPENSSL_NO_EC" = xyes
|
||||
then :
|
||||
as_fn_error $? "OpenSSL does not support ECDSA: please upgrade or rerun with --disable-ecdsa" "$LINENO" 5
|
||||
|
||||
fi
|
||||
|
||||
else $as_nop
|
||||
|
||||
# without EVP_PKEY_fromdata, older openssl, check for support
|
||||
ac_fn_c_check_func "$LINENO" "ECDSA_sign" "ac_cv_func_ECDSA_sign"
|
||||
if test "x$ac_cv_func_ECDSA_sign" = xyes
|
||||
then :
|
||||
|
||||
@@ -21198,12 +21345,15 @@ else $as_nop
|
||||
as_fn_error $? "OpenSSL does not support ECDSA: please upgrade or rerun with --disable-ecdsa" "$LINENO" 5
|
||||
fi
|
||||
|
||||
ac_fn_c_check_func "$LINENO" "SHA384_Init" "ac_cv_func_SHA384_Init"
|
||||
ac_fn_c_check_func "$LINENO" "SHA384_Init" "ac_cv_func_SHA384_Init"
|
||||
if test "x$ac_cv_func_SHA384_Init" = xyes
|
||||
then :
|
||||
|
||||
else $as_nop
|
||||
as_fn_error $? "OpenSSL does not support SHA384: please upgrade or rerun with --disable-ecdsa" "$LINENO" 5
|
||||
fi
|
||||
|
||||
|
||||
fi
|
||||
|
||||
ac_fn_check_decl "$LINENO" "NID_X9_62_prime256v1" "ac_cv_have_decl_NID_X9_62_prime256v1" "$ac_includes_default
|
||||
@@ -23733,7 +23883,7 @@ then :
|
||||
|
||||
else $as_nop
|
||||
|
||||
|
||||
if test -n "$PKG_CONFIG"; then
|
||||
|
||||
pkg_failed=no
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for PROTOBUFC" >&5
|
||||
@@ -23794,36 +23944,36 @@ fi
|
||||
echo "$PROTOBUFC_PKG_ERRORS" >&5
|
||||
|
||||
|
||||
# pkg-config failed; try falling back to known values
|
||||
# workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
|
||||
if test -f /usr/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I/usr/include/google"
|
||||
# pkg-config failed; try falling back to known values
|
||||
# workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
|
||||
if test -f /usr/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I/usr/include/google"
|
||||
else
|
||||
if test -f /usr/local/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I/usr/local/include/google"
|
||||
LDFLAGS="$LDFLAGS -L/usr/local/lib"
|
||||
else
|
||||
if test -f /usr/local/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I/usr/local/include/google"
|
||||
LDFLAGS="$LDFLAGS -L/usr/local/lib"
|
||||
else
|
||||
as_fn_error $? "The protobuf-c package was not found with pkg-config. Please install protobuf-c!" "$LINENO" 5
|
||||
fi
|
||||
as_fn_error $? "The protobuf-c package was not found with pkg-config. Please install protobuf-c!" "$LINENO" 5
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
elif test $pkg_failed = untried; then
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
printf "%s\n" "no" >&6; }
|
||||
|
||||
# pkg-config failed; try falling back to known values
|
||||
# workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
|
||||
if test -f /usr/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I/usr/include/google"
|
||||
# pkg-config failed; try falling back to known values
|
||||
# workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
|
||||
if test -f /usr/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I/usr/include/google"
|
||||
else
|
||||
if test -f /usr/local/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I/usr/local/include/google"
|
||||
LDFLAGS="$LDFLAGS -L/usr/local/lib"
|
||||
else
|
||||
if test -f /usr/local/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I/usr/local/include/google"
|
||||
LDFLAGS="$LDFLAGS -L/usr/local/lib"
|
||||
else
|
||||
as_fn_error $? "The protobuf-c package was not found with pkg-config. Please install protobuf-c!" "$LINENO" 5
|
||||
fi
|
||||
as_fn_error $? "The protobuf-c package was not found with pkg-config. Please install protobuf-c!" "$LINENO" 5
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
else
|
||||
@@ -23832,11 +23982,21 @@ else
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
printf "%s\n" "yes" >&6; }
|
||||
|
||||
CFLAGS="$CFLAGS $PROTOBUFC_CFLAGS"
|
||||
LIBS="$LIBS $PROTOBUFC_LIBS"
|
||||
CFLAGS="$CFLAGS $PROTOBUFC_CFLAGS"
|
||||
LIBS="$LIBS $PROTOBUFC_LIBS"
|
||||
|
||||
fi
|
||||
|
||||
else
|
||||
# workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
|
||||
if test -f /usr/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I/usr/include/google"
|
||||
else
|
||||
if test -f /usr/local/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I/usr/local/include/google"
|
||||
LDFLAGS="$LDFLAGS -L/usr/local/lib"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
fi
|
||||
@@ -24235,7 +24395,21 @@ printf "%s\n" "#define USE_IPSET 1" >>confdefs.h
|
||||
IPSET_OBJ="ipset.lo"
|
||||
|
||||
|
||||
# mnl
|
||||
# BSD's pf
|
||||
for ac_header in net/pfvar.h
|
||||
do :
|
||||
ac_fn_c_check_header_compile "$LINENO" "net/pfvar.h" "ac_cv_header_net_pfvar_h" "
|
||||
#include <netinet/in.h>
|
||||
#include <net/if.h>
|
||||
|
||||
"
|
||||
if test "x$ac_cv_header_net_pfvar_h" = xyes
|
||||
then :
|
||||
printf "%s\n" "#define HAVE_NET_PFVAR_H 1" >>confdefs.h
|
||||
|
||||
else $as_nop
|
||||
|
||||
# mnl
|
||||
|
||||
# Check whether --with-libmnl was given.
|
||||
if test ${with_libmnl+y}
|
||||
@@ -24245,13 +24419,13 @@ else $as_nop
|
||||
withval="yes"
|
||||
fi
|
||||
|
||||
found_libmnl="no"
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libmnl" >&5
|
||||
found_libmnl="no"
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libmnl" >&5
|
||||
printf %s "checking for libmnl... " >&6; }
|
||||
if test x_$withval = x_ -o x_$withval = x_yes; then
|
||||
if test x_$withval = x_ -o x_$withval = x_yes; then
|
||||
withval="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr"
|
||||
fi
|
||||
for dir in $withval ; do
|
||||
fi
|
||||
for dir in $withval ; do
|
||||
if test -f "$dir/include/libmnl/libmnl.h" -o -f "$dir/include/libmnl/libmnl/libmnl.h"; then
|
||||
found_libmnl="yes"
|
||||
extralibmnl=""
|
||||
@@ -24269,10 +24443,14 @@ printf "%s\n" "found in $dir" >&6; }
|
||||
LIBS="$LIBS -lmnl"
|
||||
break;
|
||||
fi
|
||||
done
|
||||
if test x_$found_libmnl != x_yes; then
|
||||
as_fn_error $? "Could not find libmnl, libmnl.h" "$LINENO" 5
|
||||
fi
|
||||
done
|
||||
if test x_$found_libmnl != x_yes; then
|
||||
as_fn_error $? "Could not find libmnl, libmnl.h" "$LINENO" 5
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
done
|
||||
;;
|
||||
no|*)
|
||||
# nothing
|
||||
@@ -24467,7 +24645,7 @@ printf "%s\n" "#define MAXSYSLOGMSGLEN 10240" >>confdefs.h
|
||||
|
||||
|
||||
|
||||
version=1.20.1
|
||||
version=1.21.1
|
||||
|
||||
date=`date +'%b %e, %Y'`
|
||||
|
||||
@@ -24979,7 +25157,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
||||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by unbound $as_me 1.20.1, which was
|
||||
This file was extended by unbound $as_me 1.21.1, which was
|
||||
generated by GNU Autoconf 2.71. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@@ -25047,7 +25225,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\
|
||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_config='$ac_cs_config_escaped'
|
||||
ac_cs_version="\\
|
||||
unbound config.status 1.20.1
|
||||
unbound config.status 1.21.1
|
||||
configured by $0, generated by GNU Autoconf 2.71,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
||||
+81
-17
@@ -10,7 +10,7 @@ sinclude(dnscrypt/dnscrypt.m4)
|
||||
|
||||
# must be numbers. ac_defun because of later processing
|
||||
m4_define([VERSION_MAJOR],[1])
|
||||
m4_define([VERSION_MINOR],[20])
|
||||
m4_define([VERSION_MINOR],[21])
|
||||
m4_define([VERSION_MICRO],[1])
|
||||
AC_INIT([unbound],m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]),[unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues],[unbound])
|
||||
AC_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR])
|
||||
@@ -18,7 +18,7 @@ AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR])
|
||||
AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO])
|
||||
|
||||
LIBUNBOUND_CURRENT=9
|
||||
LIBUNBOUND_REVISION=28
|
||||
LIBUNBOUND_REVISION=29
|
||||
LIBUNBOUND_AGE=1
|
||||
# 1.0.0 had 0:12:0
|
||||
# 1.0.1 had 0:13:0
|
||||
@@ -113,7 +113,8 @@ LIBUNBOUND_AGE=1
|
||||
# 1.19.2 had 9:25:1
|
||||
# 1.19.3 had 9:26:1
|
||||
# 1.20.0 had 9:27:1
|
||||
# 1.20.1 had 9:28:1
|
||||
# 1.21.0 had 9:28:1
|
||||
# 1.21.1 had 9:29:1
|
||||
|
||||
# Current -- the number of the binary API that we're implementing
|
||||
# Revision -- which iteration of the implementation of the binary
|
||||
@@ -339,6 +340,8 @@ AC_MSG_RESULT($ac_cv_c_weak_attribute)
|
||||
if test $ac_cv_c_weak_attribute = yes; then
|
||||
AC_DEFINE(HAVE_ATTR_WEAK, 1, [Whether the C compiler accepts the "weak" attribute])
|
||||
AC_DEFINE(ATTR_WEAK, [__attribute__((weak))], [apply the weak attribute to a symbol])
|
||||
else
|
||||
AC_DEFINE(ATTR_WEAK,[], [apply the weak attribute to a symbol])
|
||||
fi
|
||||
])dnl End of CHECK_WEAK_ATTRIBUTE
|
||||
|
||||
@@ -360,11 +363,54 @@ AC_MSG_RESULT($ac_cv_c_noreturn_attribute)
|
||||
if test $ac_cv_c_noreturn_attribute = yes; then
|
||||
AC_DEFINE(HAVE_ATTR_NORETURN, 1, [Whether the C compiler accepts the "noreturn" attribute])
|
||||
AC_DEFINE(ATTR_NORETURN, [__attribute__((__noreturn__))], [apply the noreturn attribute to a function that exits the program])
|
||||
else
|
||||
AC_DEFINE(ATTR_NORETURN,[], [apply the noreturn attribute to a function that exits the program])
|
||||
fi
|
||||
])dnl End of CHECK_NORETURN_ATTRIBUTE
|
||||
|
||||
CHECK_NORETURN_ATTRIBUTE
|
||||
|
||||
AC_DEFUN([CHECK_FALLTHROUGH_ATTRIBUTE],
|
||||
[AC_REQUIRE([AC_PROG_CC])
|
||||
AC_MSG_CHECKING(whether the C compiler (${CC-cc}) accepts the "fallthrough" attribute)
|
||||
BAKCFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS -Werror"
|
||||
AC_CACHE_VAL(ac_cv_c_fallthrough_attribute,
|
||||
[ac_cv_c_fallthrough_attribute=no
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <stdio.h>
|
||||
void f(int x) {
|
||||
int y = 0;
|
||||
switch(x) {
|
||||
case 1:
|
||||
y = 1;
|
||||
__attribute__((fallthrough));
|
||||
/* fallthrough */
|
||||
case 2:
|
||||
y++;
|
||||
break;
|
||||
case 3:
|
||||
y = 3;
|
||||
break;
|
||||
}
|
||||
printf("%d", y);
|
||||
}
|
||||
]], [[
|
||||
f(1);
|
||||
]])],[ac_cv_c_fallthrough_attribute="yes"],[ac_cv_c_fallthrough_attribute="no"])
|
||||
])
|
||||
CFLAGS="$BAKCFLAGS"
|
||||
|
||||
AC_MSG_RESULT($ac_cv_c_fallthrough_attribute)
|
||||
if test $ac_cv_c_fallthrough_attribute = yes; then
|
||||
AC_DEFINE(HAVE_ATTR_FALLTHROUGH, 1, [Whether the C compiler accepts the "fallthrough" attribute])
|
||||
AC_DEFINE(ATTR_FALLTHROUGH, [__attribute__((fallthrough));], [apply the fallthrough attribute.])
|
||||
else
|
||||
AC_DEFINE(ATTR_FALLTHROUGH,[], [apply the fallthrough attribute.])
|
||||
fi
|
||||
])dnl End of CHECK_FALLTHROUGH_ATTRIBUTE
|
||||
|
||||
CHECK_FALLTHROUGH_ATTRIBUTE
|
||||
|
||||
if test "$srcdir" != "."; then
|
||||
CPPFLAGS="$CPPFLAGS -I$srcdir"
|
||||
fi
|
||||
@@ -944,7 +990,7 @@ else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
AC_CHECK_HEADERS([openssl/conf.h openssl/engine.h openssl/bn.h openssl/dh.h openssl/dsa.h openssl/rsa.h openssl/core_names.h openssl/param_build.h],,, [AC_INCLUDES_DEFAULT])
|
||||
AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_default_properties_is_fips_enabled EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ENGINE_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex CRYPTO_THREADID_set_callback EVP_MAC_CTX_set_params OSSL_PARAM_BLD_new BIO_set_callback_ex])
|
||||
AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_default_properties_is_fips_enabled EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ENGINE_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex CRYPTO_THREADID_set_callback EVP_MAC_CTX_set_params OSSL_PARAM_BLD_new BIO_set_callback_ex SSL_CTX_set_tmp_ecdh])
|
||||
|
||||
# these check_funcs need -lssl
|
||||
BAKLIBS="$LIBS"
|
||||
@@ -1181,8 +1227,17 @@ case "$enable_ecdsa" in
|
||||
;;
|
||||
*)
|
||||
if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
|
||||
AC_CHECK_FUNC(ECDSA_sign, [], [AC_MSG_ERROR([OpenSSL does not support ECDSA: please upgrade or rerun with --disable-ecdsa])])
|
||||
AC_CHECK_FUNC(SHA384_Init, [], [AC_MSG_ERROR([OpenSSL does not support SHA384: please upgrade or rerun with --disable-ecdsa])])
|
||||
AC_CHECK_FUNC(EVP_PKEY_fromdata, [
|
||||
# with EVP_PKEY_fromdata, check if EC is not disabled
|
||||
AC_CHECK_DECL([OPENSSL_NO_EC], [AC_MSG_ERROR([OpenSSL does not support ECDSA: please upgrade or rerun with --disable-ecdsa])
|
||||
], [], [AC_INCLUDES_DEFAULT
|
||||
#include <openssl/evp.h>
|
||||
])
|
||||
], [
|
||||
# without EVP_PKEY_fromdata, older openssl, check for support
|
||||
AC_CHECK_FUNC(ECDSA_sign, [], [AC_MSG_ERROR([OpenSSL does not support ECDSA: please upgrade or rerun with --disable-ecdsa])])
|
||||
AC_CHECK_FUNC(SHA384_Init, [], [AC_MSG_ERROR([OpenSSL does not support SHA384: please upgrade or rerun with --disable-ecdsa])])
|
||||
])
|
||||
AC_CHECK_DECLS([NID_X9_62_prime256v1, NID_secp384r1], [], [AC_MSG_ERROR([OpenSSL does not support the ECDSA curves: please upgrade or rerun with --disable-ecdsa])], [AC_INCLUDES_DEFAULT
|
||||
#include <openssl/evp.h>
|
||||
])
|
||||
@@ -1922,15 +1977,17 @@ case "$enable_ipset" in
|
||||
IPSET_OBJ="ipset.lo"
|
||||
AC_SUBST(IPSET_OBJ)
|
||||
|
||||
# mnl
|
||||
AC_ARG_WITH(libmnl, AS_HELP_STRING([--with-libmnl=path],[specify explicit path for libmnl.]),
|
||||
# BSD's pf
|
||||
AC_CHECK_HEADERS([net/pfvar.h], [], [
|
||||
# mnl
|
||||
AC_ARG_WITH(libmnl, AS_HELP_STRING([--with-libmnl=path],[specify explicit path for libmnl.]),
|
||||
[ ],[ withval="yes" ])
|
||||
found_libmnl="no"
|
||||
AC_MSG_CHECKING(for libmnl)
|
||||
if test x_$withval = x_ -o x_$withval = x_yes; then
|
||||
found_libmnl="no"
|
||||
AC_MSG_CHECKING(for libmnl)
|
||||
if test x_$withval = x_ -o x_$withval = x_yes; then
|
||||
withval="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr"
|
||||
fi
|
||||
for dir in $withval ; do
|
||||
fi
|
||||
for dir in $withval ; do
|
||||
if test -f "$dir/include/libmnl/libmnl.h" -o -f "$dir/include/libmnl/libmnl/libmnl.h"; then
|
||||
found_libmnl="yes"
|
||||
dnl assume /usr is in default path.
|
||||
@@ -1948,10 +2005,14 @@ case "$enable_ipset" in
|
||||
LIBS="$LIBS -lmnl"
|
||||
break;
|
||||
fi
|
||||
done
|
||||
if test x_$found_libmnl != x_yes; then
|
||||
AC_MSG_ERROR([Could not find libmnl, libmnl.h])
|
||||
fi
|
||||
done
|
||||
if test x_$found_libmnl != x_yes; then
|
||||
AC_MSG_ERROR([Could not find libmnl, libmnl.h])
|
||||
fi
|
||||
], [
|
||||
#include <netinet/in.h>
|
||||
#include <net/if.h>
|
||||
])
|
||||
;;
|
||||
no|*)
|
||||
# nothing
|
||||
@@ -2269,6 +2330,7 @@ struct sockaddr_storage;
|
||||
# define calloc(n,s) unbound_stat_calloc_log(n, s, __FILE__, __LINE__, __func__)
|
||||
# define free(p) unbound_stat_free_log(p, __FILE__, __LINE__, __func__)
|
||||
# define realloc(p,s) unbound_stat_realloc_log(p, s, __FILE__, __LINE__, __func__)
|
||||
# define strdup(s) unbound_stat_strdup_log(s, __FILE__, __LINE__, __func__)
|
||||
void *unbound_stat_malloc(size_t size);
|
||||
void *unbound_stat_calloc(size_t nmemb, size_t size);
|
||||
void unbound_stat_free(void *ptr);
|
||||
@@ -2281,6 +2343,8 @@ void unbound_stat_free_log(void *ptr, const char* file, int line,
|
||||
const char* func);
|
||||
void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
|
||||
int line, const char* func);
|
||||
char *unbound_stat_strdup_log(const char *s, const char* file, int line,
|
||||
const char* func);
|
||||
#elif defined(UNBOUND_ALLOC_LITE)
|
||||
# include "util/alloc.h"
|
||||
#endif /* UNBOUND_ALLOC_LITE and UNBOUND_ALLOC_STATS */
|
||||
|
||||
@@ -42,8 +42,8 @@
|
||||
[Unit]
|
||||
Description=Validating, recursive, and caching DNS resolver
|
||||
Documentation=man:unbound(8)
|
||||
After=network.target
|
||||
Before=network-online.target nss-lookup.target
|
||||
After=network-online.target
|
||||
Before=nss-lookup.target
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
[Unit]
|
||||
Description=Validating, recursive, and caching DNS resolver
|
||||
Documentation=man:unbound(8)
|
||||
After=network.target
|
||||
Before=network-online.target nss-lookup.target
|
||||
After=network-online.target
|
||||
Before=nss-lookup.target
|
||||
Wants=nss-lookup.target
|
||||
|
||||
[Install]
|
||||
|
||||
+39
-8
@@ -344,7 +344,7 @@ static int setup_acl_for_ports(struct acl_list* list,
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
daemon_open_shared_ports(struct daemon* daemon)
|
||||
{
|
||||
log_assert(daemon);
|
||||
@@ -444,6 +444,19 @@ daemon_open_shared_ports(struct daemon* daemon)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
daemon_privileged(struct daemon* daemon)
|
||||
{
|
||||
daemon->env->cfg = daemon->cfg;
|
||||
daemon->env->alloc = &daemon->superalloc;
|
||||
daemon->env->worker = NULL;
|
||||
if(!modstack_call_startup(&daemon->mods, daemon->cfg->module_conf,
|
||||
daemon->env)) {
|
||||
fatal_exit("failed to startup modules");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup modules. setup module stack.
|
||||
* @param daemon: the daemon
|
||||
@@ -453,11 +466,15 @@ static void daemon_setup_modules(struct daemon* daemon)
|
||||
daemon->env->cfg = daemon->cfg;
|
||||
daemon->env->alloc = &daemon->superalloc;
|
||||
daemon->env->worker = NULL;
|
||||
daemon->env->need_to_validate = 0; /* set by module init below */
|
||||
if(!modstack_setup(&daemon->mods, daemon->cfg->module_conf,
|
||||
daemon->env)) {
|
||||
fatal_exit("failed to setup modules");
|
||||
if(daemon->mods_inited) {
|
||||
modstack_call_deinit(&daemon->mods, daemon->env);
|
||||
}
|
||||
daemon->env->need_to_validate = 0; /* set by module init below */
|
||||
if(!modstack_call_init(&daemon->mods, daemon->cfg->module_conf,
|
||||
daemon->env)) {
|
||||
fatal_exit("failed to init modules");
|
||||
}
|
||||
daemon->mods_inited = 1;
|
||||
log_edns_known_options(VERB_ALGO, daemon->env);
|
||||
}
|
||||
|
||||
@@ -503,7 +520,10 @@ daemon_clear_allocs(struct daemon* daemon)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0; i<daemon->num; i++) {
|
||||
/* daemon->num may be different during reloads (after configuration
|
||||
* read). Use old_num which has the correct value used to setup the
|
||||
* worker_allocs */
|
||||
for(i=0; i<daemon->old_num; i++) {
|
||||
alloc_clear(daemon->worker_allocs[i]);
|
||||
free(daemon->worker_allocs[i]);
|
||||
}
|
||||
@@ -715,6 +735,14 @@ daemon_fork(struct daemon* daemon)
|
||||
"dnscrypt support");
|
||||
#endif
|
||||
}
|
||||
if(daemon->cfg->cookie_secret_file &&
|
||||
daemon->cfg->cookie_secret_file[0]) {
|
||||
if(!(daemon->cookie_secrets = cookie_secrets_create()))
|
||||
fatal_exit("Could not create cookie_secrets: out of memory");
|
||||
if(!cookie_secrets_apply_cfg(daemon->cookie_secrets,
|
||||
daemon->cfg->cookie_secret_file))
|
||||
fatal_exit("Could not setup cookie_secrets");
|
||||
}
|
||||
/* create global local_zones */
|
||||
if(!(daemon->local_zones = local_zones_create()))
|
||||
fatal_exit("Could not create local zones: out of memory");
|
||||
@@ -858,7 +886,7 @@ daemon_cleanup(struct daemon* daemon)
|
||||
daemon->views = NULL;
|
||||
if(daemon->env->auth_zones)
|
||||
auth_zones_cleanup(daemon->env->auth_zones);
|
||||
/* key cache is cleared by module desetup during next daemon_fork() */
|
||||
/* key cache is cleared by module deinit during next daemon_fork() */
|
||||
daemon_remote_clear(daemon->rc);
|
||||
for(i=0; i<daemon->num; i++)
|
||||
worker_delete(daemon->workers[i]);
|
||||
@@ -888,7 +916,9 @@ daemon_delete(struct daemon* daemon)
|
||||
size_t i;
|
||||
if(!daemon)
|
||||
return;
|
||||
modstack_desetup(&daemon->mods, daemon->env);
|
||||
modstack_call_deinit(&daemon->mods, daemon->env);
|
||||
modstack_call_destartup(&daemon->mods, daemon->env);
|
||||
modstack_free(&daemon->mods);
|
||||
daemon_remote_delete(daemon->rc);
|
||||
for(i = 0; i < daemon->num_ports; i++)
|
||||
listening_ports_free(daemon->ports[i]);
|
||||
@@ -907,6 +937,7 @@ daemon_delete(struct daemon* daemon)
|
||||
acl_list_delete(daemon->acl);
|
||||
acl_list_delete(daemon->acl_interface);
|
||||
tcl_list_delete(daemon->tcl);
|
||||
cookie_secrets_delete(daemon->cookie_secrets);
|
||||
listen_desetup_locks();
|
||||
free(daemon->chroot);
|
||||
free(daemon->pidfile);
|
||||
|
||||
@@ -58,6 +58,7 @@ struct ub_randstate;
|
||||
struct daemon_remote;
|
||||
struct respip_set;
|
||||
struct shm_main_info;
|
||||
struct cookie_secrets;
|
||||
|
||||
#include "dnstap/dnstap_config.h"
|
||||
#ifdef USE_DNSTAP
|
||||
@@ -115,6 +116,8 @@ struct daemon {
|
||||
struct module_env* env;
|
||||
/** stack of module callbacks */
|
||||
struct module_stack mods;
|
||||
/** The module stack has been inited */
|
||||
int mods_inited;
|
||||
/** access control, which client IPs are allowed to connect */
|
||||
struct acl_list* acl;
|
||||
/** access control, which interfaces are allowed to connect */
|
||||
@@ -146,6 +149,8 @@ struct daemon {
|
||||
#endif
|
||||
/** reuse existing cache on reload if other conditions allow it. */
|
||||
int reuse_cache;
|
||||
/** the EDNS cookie secrets from the cookie-secret-file */
|
||||
struct cookie_secrets* cookie_secrets;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -162,6 +167,15 @@ struct daemon* daemon_init(void);
|
||||
*/
|
||||
int daemon_open_shared_ports(struct daemon* daemon);
|
||||
|
||||
/**
|
||||
* Do daemon setup that needs privileges
|
||||
* like opening privileged ports or opening device files.
|
||||
* The cfg member pointer must have been set for the daemon.
|
||||
* @param daemon: the daemon.
|
||||
* @return: false on error.
|
||||
*/
|
||||
int daemon_privileged(struct daemon* daemon);
|
||||
|
||||
/**
|
||||
* Fork workers and start service.
|
||||
* When the routine exits, it is no longer forked.
|
||||
|
||||
+216
@@ -88,6 +88,7 @@
|
||||
#include "sldns/wire2str.h"
|
||||
#include "sldns/sbuffer.h"
|
||||
#include "util/timeval_func.h"
|
||||
#include "util/edns.h"
|
||||
#ifdef USE_CACHEDB
|
||||
#include "cachedb/cachedb.h"
|
||||
#endif
|
||||
@@ -1682,6 +1683,8 @@ do_cache_remove(struct worker* worker, uint8_t* nm, size_t nmlen,
|
||||
#ifdef USE_CACHEDB
|
||||
if(remcachedb && worker->env.cachedb_enabled)
|
||||
cachedb_msg_remove_qinfo(&worker->env, &k);
|
||||
#else
|
||||
(void)remcachedb;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -3193,6 +3196,210 @@ do_rpz_disable(RES* ssl, struct worker* worker, char* arg)
|
||||
do_rpz_enable_disable(ssl, worker, arg, 0);
|
||||
}
|
||||
|
||||
/** Write the cookie secrets to file, returns `0` on failure.
|
||||
* Caller has to hold the lock. */
|
||||
static int
|
||||
cookie_secret_file_dump(RES* ssl, struct worker* worker) {
|
||||
char const* secret_file = worker->env.cfg->cookie_secret_file;
|
||||
struct cookie_secrets* cookie_secrets = worker->daemon->cookie_secrets;
|
||||
char secret_hex[UNBOUND_COOKIE_SECRET_SIZE * 2 + 1];
|
||||
FILE* f;
|
||||
size_t i;
|
||||
if(secret_file == NULL || secret_file[0]==0) {
|
||||
(void)ssl_printf(ssl, "error: no cookie secret file configured\n");
|
||||
return 0;
|
||||
}
|
||||
log_assert( secret_file != NULL );
|
||||
|
||||
/* open write only and truncate */
|
||||
if((f = fopen(secret_file, "w")) == NULL ) {
|
||||
(void)ssl_printf(ssl, "unable to open cookie secret file %s: %s",
|
||||
secret_file, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
if(cookie_secrets == NULL) {
|
||||
/* nothing to write */
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
for(i = 0; i < cookie_secrets->cookie_count; i++) {
|
||||
struct cookie_secret const* cs = &cookie_secrets->
|
||||
cookie_secrets[i];
|
||||
ssize_t const len = hex_ntop(cs->cookie_secret,
|
||||
UNBOUND_COOKIE_SECRET_SIZE, secret_hex,
|
||||
sizeof(secret_hex));
|
||||
(void)len; /* silence unused variable warning with -DNDEBUG */
|
||||
log_assert( len == UNBOUND_COOKIE_SECRET_SIZE * 2 );
|
||||
secret_hex[UNBOUND_COOKIE_SECRET_SIZE * 2] = '\0';
|
||||
fprintf(f, "%s\n", secret_hex);
|
||||
}
|
||||
explicit_bzero(secret_hex, sizeof(secret_hex));
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** Activate cookie secret */
|
||||
static void
|
||||
do_activate_cookie_secret(RES* ssl, struct worker* worker) {
|
||||
char const* secret_file = worker->env.cfg->cookie_secret_file;
|
||||
struct cookie_secrets* cookie_secrets = worker->daemon->cookie_secrets;
|
||||
|
||||
if(secret_file == NULL || secret_file[0] == 0) {
|
||||
(void)ssl_printf(ssl, "error: no cookie secret file configured\n");
|
||||
return;
|
||||
}
|
||||
if(cookie_secrets == NULL) {
|
||||
(void)ssl_printf(ssl, "error: there are no cookie_secrets.");
|
||||
return;
|
||||
}
|
||||
lock_basic_lock(&cookie_secrets->lock);
|
||||
|
||||
if(cookie_secrets->cookie_count <= 1 ) {
|
||||
lock_basic_unlock(&cookie_secrets->lock);
|
||||
(void)ssl_printf(ssl, "error: no staging cookie secret to activate\n");
|
||||
return;
|
||||
}
|
||||
/* Only the worker 0 writes to file, the others update state. */
|
||||
if(worker->thread_num == 0 && !cookie_secret_file_dump(ssl, worker)) {
|
||||
lock_basic_unlock(&cookie_secrets->lock);
|
||||
(void)ssl_printf(ssl, "error: writing to cookie secret file: \"%s\"\n",
|
||||
secret_file);
|
||||
return;
|
||||
}
|
||||
activate_cookie_secret(cookie_secrets);
|
||||
if(worker->thread_num == 0)
|
||||
(void)cookie_secret_file_dump(ssl, worker);
|
||||
lock_basic_unlock(&cookie_secrets->lock);
|
||||
send_ok(ssl);
|
||||
}
|
||||
|
||||
/** Drop cookie secret */
|
||||
static void
|
||||
do_drop_cookie_secret(RES* ssl, struct worker* worker) {
|
||||
char const* secret_file = worker->env.cfg->cookie_secret_file;
|
||||
struct cookie_secrets* cookie_secrets = worker->daemon->cookie_secrets;
|
||||
|
||||
if(secret_file == NULL || secret_file[0] == 0) {
|
||||
(void)ssl_printf(ssl, "error: no cookie secret file configured\n");
|
||||
return;
|
||||
}
|
||||
if(cookie_secrets == NULL) {
|
||||
(void)ssl_printf(ssl, "error: there are no cookie_secrets.");
|
||||
return;
|
||||
}
|
||||
lock_basic_lock(&cookie_secrets->lock);
|
||||
|
||||
if(cookie_secrets->cookie_count <= 1 ) {
|
||||
lock_basic_unlock(&cookie_secrets->lock);
|
||||
(void)ssl_printf(ssl, "error: can not drop the currently active cookie secret\n");
|
||||
return;
|
||||
}
|
||||
/* Only the worker 0 writes to file, the others update state. */
|
||||
if(worker->thread_num == 0 && !cookie_secret_file_dump(ssl, worker)) {
|
||||
lock_basic_unlock(&cookie_secrets->lock);
|
||||
(void)ssl_printf(ssl, "error: writing to cookie secret file: \"%s\"\n",
|
||||
secret_file);
|
||||
return;
|
||||
}
|
||||
drop_cookie_secret(cookie_secrets);
|
||||
if(worker->thread_num == 0)
|
||||
(void)cookie_secret_file_dump(ssl, worker);
|
||||
lock_basic_unlock(&cookie_secrets->lock);
|
||||
send_ok(ssl);
|
||||
}
|
||||
|
||||
/** Add cookie secret */
|
||||
static void
|
||||
do_add_cookie_secret(RES* ssl, struct worker* worker, char* arg) {
|
||||
uint8_t secret[UNBOUND_COOKIE_SECRET_SIZE];
|
||||
char const* secret_file = worker->env.cfg->cookie_secret_file;
|
||||
struct cookie_secrets* cookie_secrets = worker->daemon->cookie_secrets;
|
||||
|
||||
if(secret_file == NULL || secret_file[0] == 0) {
|
||||
(void)ssl_printf(ssl, "error: no cookie secret file configured\n");
|
||||
return;
|
||||
}
|
||||
if(cookie_secrets == NULL) {
|
||||
worker->daemon->cookie_secrets = cookie_secrets_create();
|
||||
if(!worker->daemon->cookie_secrets) {
|
||||
(void)ssl_printf(ssl, "error: out of memory");
|
||||
return;
|
||||
}
|
||||
cookie_secrets = worker->daemon->cookie_secrets;
|
||||
}
|
||||
lock_basic_lock(&cookie_secrets->lock);
|
||||
|
||||
if(*arg == '\0') {
|
||||
lock_basic_unlock(&cookie_secrets->lock);
|
||||
(void)ssl_printf(ssl, "error: missing argument (cookie_secret)\n");
|
||||
return;
|
||||
}
|
||||
if(strlen(arg) != 32) {
|
||||
lock_basic_unlock(&cookie_secrets->lock);
|
||||
explicit_bzero(arg, strlen(arg));
|
||||
(void)ssl_printf(ssl, "invalid cookie secret: invalid argument length\n");
|
||||
(void)ssl_printf(ssl, "please provide a 128bit hex encoded secret\n");
|
||||
return;
|
||||
}
|
||||
if(hex_pton(arg, secret, UNBOUND_COOKIE_SECRET_SIZE) !=
|
||||
UNBOUND_COOKIE_SECRET_SIZE ) {
|
||||
lock_basic_unlock(&cookie_secrets->lock);
|
||||
explicit_bzero(secret, UNBOUND_COOKIE_SECRET_SIZE);
|
||||
explicit_bzero(arg, strlen(arg));
|
||||
(void)ssl_printf(ssl, "invalid cookie secret: parse error\n");
|
||||
(void)ssl_printf(ssl, "please provide a 128bit hex encoded secret\n");
|
||||
return;
|
||||
}
|
||||
/* Only the worker 0 writes to file, the others update state. */
|
||||
if(worker->thread_num == 0 && !cookie_secret_file_dump(ssl, worker)) {
|
||||
lock_basic_unlock(&cookie_secrets->lock);
|
||||
explicit_bzero(secret, UNBOUND_COOKIE_SECRET_SIZE);
|
||||
explicit_bzero(arg, strlen(arg));
|
||||
(void)ssl_printf(ssl, "error: writing to cookie secret file: \"%s\"\n",
|
||||
secret_file);
|
||||
return;
|
||||
}
|
||||
add_cookie_secret(cookie_secrets, secret, UNBOUND_COOKIE_SECRET_SIZE);
|
||||
explicit_bzero(secret, UNBOUND_COOKIE_SECRET_SIZE);
|
||||
if(worker->thread_num == 0)
|
||||
(void)cookie_secret_file_dump(ssl, worker);
|
||||
lock_basic_unlock(&cookie_secrets->lock);
|
||||
explicit_bzero(arg, strlen(arg));
|
||||
send_ok(ssl);
|
||||
}
|
||||
|
||||
/** Print cookie secrets */
|
||||
static void
|
||||
do_print_cookie_secrets(RES* ssl, struct worker* worker) {
|
||||
struct cookie_secrets* cookie_secrets = worker->daemon->cookie_secrets;
|
||||
char secret_hex[UNBOUND_COOKIE_SECRET_SIZE * 2 + 1];
|
||||
int i;
|
||||
|
||||
if(!cookie_secrets)
|
||||
return; /* Output is empty. */
|
||||
lock_basic_lock(&cookie_secrets->lock);
|
||||
for(i = 0; (size_t)i < cookie_secrets->cookie_count; i++) {
|
||||
struct cookie_secret const* cs = &cookie_secrets->
|
||||
cookie_secrets[i];
|
||||
ssize_t const len = hex_ntop(cs->cookie_secret,
|
||||
UNBOUND_COOKIE_SECRET_SIZE, secret_hex,
|
||||
sizeof(secret_hex));
|
||||
(void)len; /* silence unused variable warning with -DNDEBUG */
|
||||
log_assert( len == UNBOUND_COOKIE_SECRET_SIZE * 2 );
|
||||
secret_hex[UNBOUND_COOKIE_SECRET_SIZE * 2] = '\0';
|
||||
if (i == 0)
|
||||
(void)ssl_printf(ssl, "active : %s\n", secret_hex);
|
||||
else if (cookie_secrets->cookie_count == 2)
|
||||
(void)ssl_printf(ssl, "staging: %s\n", secret_hex);
|
||||
else
|
||||
(void)ssl_printf(ssl, "staging[%d]: %s\n", i,
|
||||
secret_hex);
|
||||
}
|
||||
lock_basic_unlock(&cookie_secrets->lock);
|
||||
explicit_bzero(secret_hex, sizeof(secret_hex));
|
||||
}
|
||||
|
||||
/** check for name with end-of-string, space or tab after it */
|
||||
static int
|
||||
cmdcmp(char* p, const char* cmd, size_t len)
|
||||
@@ -3325,6 +3532,9 @@ execute_cmd(struct daemon_remote* rc, RES* ssl, char* cmd,
|
||||
} else if(cmdcmp(p, "view_local_datas", 16)) {
|
||||
do_view_datas_add(rc, ssl, worker, skipwhite(p+16));
|
||||
return;
|
||||
} else if(cmdcmp(p, "print_cookie_secrets", 20)) {
|
||||
do_print_cookie_secrets(ssl, worker);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef THREADS_DISABLED
|
||||
@@ -3389,6 +3599,12 @@ execute_cmd(struct daemon_remote* rc, RES* ssl, char* cmd,
|
||||
do_rpz_enable(ssl, worker, skipwhite(p+10));
|
||||
} else if(cmdcmp(p, "rpz_disable", 11)) {
|
||||
do_rpz_disable(ssl, worker, skipwhite(p+11));
|
||||
} else if(cmdcmp(p, "add_cookie_secret", 17)) {
|
||||
do_add_cookie_secret(ssl, worker, skipwhite(p+17));
|
||||
} else if(cmdcmp(p, "drop_cookie_secret", 18)) {
|
||||
do_drop_cookie_secret(ssl, worker);
|
||||
} else if(cmdcmp(p, "activate_cookie_secret", 22)) {
|
||||
do_activate_cookie_secret(ssl, worker);
|
||||
} else {
|
||||
(void)ssl_printf(ssl, "error unknown command '%s'\n", p);
|
||||
}
|
||||
|
||||
+8
-1
@@ -391,6 +391,13 @@ void server_stats_obtain(struct worker* worker, struct worker* who,
|
||||
else worker_send_cmd(who, worker_cmd_stats_noreset);
|
||||
verbose(VERB_ALGO, "wait for stats reply");
|
||||
if(tube_wait_timeout(worker->cmd, STATS_THREAD_WAIT) == 0) {
|
||||
#if defined(HAVE_PTHREAD) && defined(SIZEOF_PTHREAD_T) && defined(SIZEOF_UNSIGNED_LONG)
|
||||
# if SIZEOF_PTHREAD_T == SIZEOF_UNSIGNED_LONG
|
||||
unsigned long pthid = 0;
|
||||
if(verbosity >= VERB_OPS)
|
||||
memcpy(&pthid, &who->thr_id, sizeof(unsigned long));
|
||||
# endif
|
||||
#endif
|
||||
verbose(VERB_OPS, "no response from thread %d"
|
||||
#ifdef HAVE_GETTID
|
||||
" LWP %u"
|
||||
@@ -407,7 +414,7 @@ void server_stats_obtain(struct worker* worker, struct worker* who,
|
||||
#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)
|
||||
, pthid
|
||||
# endif
|
||||
#endif
|
||||
);
|
||||
|
||||
@@ -473,7 +473,11 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
|
||||
#endif
|
||||
#ifdef HAVE_GETPWNAM
|
||||
struct passwd *pwd = NULL;
|
||||
#endif
|
||||
|
||||
if(!daemon_privileged(daemon))
|
||||
fatal_exit("could not do privileged setup");
|
||||
#ifdef HAVE_GETPWNAM
|
||||
if(cfg->username && cfg->username[0]) {
|
||||
if((pwd = getpwnam(cfg->username)) == NULL)
|
||||
fatal_exit("user '%s' does not exist.", cfg->username);
|
||||
|
||||
+7
-4
@@ -160,9 +160,11 @@ worker_mem_report(struct worker* ATTR_UNUSED(worker),
|
||||
+ sizeof(worker->rndstate)
|
||||
+ regional_get_mem(worker->scratchpad)
|
||||
+ sizeof(*worker->env.scratch_buffer)
|
||||
+ sldns_buffer_capacity(worker->env.scratch_buffer)
|
||||
+ forwards_get_mem(worker->env.fwds)
|
||||
+ hints_get_mem(worker->env.hints);
|
||||
+ sldns_buffer_capacity(worker->env.scratch_buffer);
|
||||
if(worker->daemon->env->fwds)
|
||||
log_info("forwards=%u", (unsigned)forwards_get_mem(worker->env.fwds));
|
||||
if(worker->daemon->env->hints)
|
||||
log_info("hints=%u", (unsigned)hints_get_mem(worker->env.hints));
|
||||
if(worker->thread_num == 0)
|
||||
me += acl_list_get_mem(worker->daemon->acl);
|
||||
if(cur_serv) {
|
||||
@@ -1571,7 +1573,8 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
|
||||
if((ret=parse_edns_from_query_pkt(
|
||||
c->buffer, &edns, worker->env.cfg, c, repinfo,
|
||||
(worker->env.now ? *worker->env.now : time(NULL)),
|
||||
worker->scratchpad)) != 0) {
|
||||
worker->scratchpad,
|
||||
worker->daemon->cookie_secrets)) != 0) {
|
||||
struct edns_data reply_edns;
|
||||
verbose(VERB_ALGO, "worker parse edns: formerror.");
|
||||
log_addr(VERB_CLIENT, "from", &repinfo->client_addr,
|
||||
|
||||
+3
-2
@@ -701,6 +701,7 @@ dns64_operate(struct module_qstate* qstate, enum module_ev event, int id,
|
||||
iq->state = DNS64_NEW_QUERY;
|
||||
iq->started_no_cache_store = qstate->no_cache_store;
|
||||
qstate->no_cache_store = 1;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case module_event_pass:
|
||||
qstate->ext_state[id] = handle_event_pass(qstate, id);
|
||||
@@ -1044,8 +1045,8 @@ dns64_get_mem(struct module_env* env, int id)
|
||||
*/
|
||||
static struct module_func_block dns64_block = {
|
||||
"dns64",
|
||||
&dns64_init, &dns64_deinit, &dns64_operate, &dns64_inform_super,
|
||||
&dns64_clear, &dns64_get_mem
|
||||
NULL, NULL, &dns64_init, &dns64_deinit, &dns64_operate,
|
||||
&dns64_inform_super, &dns64_clear, &dns64_get_mem
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -86,6 +86,31 @@ dt_pack(const Dnstap__Dnstap *d, void **buf, size_t *sz)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** See if the message is sent due to dnstap sample rate */
|
||||
static int
|
||||
dt_sample_rate_limited(struct dt_env* env)
|
||||
{
|
||||
lock_basic_lock(&env->sample_lock);
|
||||
/* Sampling is every [n] packets. Where n==1, every packet is sent */
|
||||
if(env->sample_rate > 1) {
|
||||
int submit = 0;
|
||||
/* if sampling is engaged... */
|
||||
if (env->sample_rate_count > env->sample_rate) {
|
||||
/* once the count passes the limit */
|
||||
/* submit the message */
|
||||
submit = 1;
|
||||
/* and reset the count */
|
||||
env->sample_rate_count = 0;
|
||||
}
|
||||
/* increment count regardless */
|
||||
env->sample_rate_count++;
|
||||
lock_basic_unlock(&env->sample_lock);
|
||||
return !submit;
|
||||
}
|
||||
lock_basic_unlock(&env->sample_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
dt_send(const struct dt_env *env, void *buf, size_t len_buf)
|
||||
{
|
||||
@@ -146,6 +171,7 @@ dt_create(struct config_file* cfg)
|
||||
env = (struct dt_env *) calloc(1, sizeof(struct dt_env));
|
||||
if (!env)
|
||||
return NULL;
|
||||
lock_basic_init(&env->sample_lock);
|
||||
|
||||
env->dtio = dt_io_thread_create();
|
||||
if(!env->dtio) {
|
||||
@@ -241,6 +267,12 @@ dt_apply_cfg(struct dt_env *env, struct config_file *cfg)
|
||||
{
|
||||
verbose(VERB_OPS, "dnstap Message/FORWARDER_RESPONSE enabled");
|
||||
}
|
||||
lock_basic_lock(&env->sample_lock);
|
||||
if((env->sample_rate = (unsigned int)cfg->dnstap_sample_rate))
|
||||
{
|
||||
verbose(VERB_OPS, "dnstap SAMPLE_RATE enabled and set to \"%d\"", (int)env->sample_rate);
|
||||
}
|
||||
lock_basic_unlock(&env->sample_lock);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -273,6 +305,7 @@ dt_delete(struct dt_env *env)
|
||||
if (!env)
|
||||
return;
|
||||
dt_io_thread_delete(env->dtio);
|
||||
lock_basic_destroy(&env->sample_lock);
|
||||
free(env->identity);
|
||||
free(env->version);
|
||||
free(env);
|
||||
@@ -409,6 +442,9 @@ dt_msg_send_client_query(struct dt_env *env,
|
||||
struct dt_msg dm;
|
||||
struct timeval qtime;
|
||||
|
||||
if(dt_sample_rate_limited(env))
|
||||
return;
|
||||
|
||||
if(tstamp)
|
||||
memcpy(&qtime, tstamp, sizeof(qtime));
|
||||
else gettimeofday(&qtime, NULL);
|
||||
@@ -447,6 +483,9 @@ dt_msg_send_client_response(struct dt_env *env,
|
||||
struct dt_msg dm;
|
||||
struct timeval rtime;
|
||||
|
||||
if(dt_sample_rate_limited(env))
|
||||
return;
|
||||
|
||||
gettimeofday(&rtime, NULL);
|
||||
|
||||
/* type */
|
||||
@@ -484,6 +523,9 @@ dt_msg_send_outside_query(struct dt_env *env,
|
||||
struct timeval qtime;
|
||||
uint16_t qflags;
|
||||
|
||||
if(dt_sample_rate_limited(env))
|
||||
return;
|
||||
|
||||
gettimeofday(&qtime, NULL);
|
||||
qflags = sldns_buffer_read_u16_at(qmsg, 2);
|
||||
|
||||
@@ -537,6 +579,9 @@ dt_msg_send_outside_response(struct dt_env *env,
|
||||
struct dt_msg dm;
|
||||
uint16_t qflags;
|
||||
|
||||
if(dt_sample_rate_limited(env))
|
||||
return;
|
||||
|
||||
(void)qbuf_len; log_assert(qbuf_len >= sizeof(qflags));
|
||||
memcpy(&qflags, qbuf, sizeof(qflags));
|
||||
qflags = ntohs(qflags);
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
|
||||
#ifdef USE_DNSTAP
|
||||
|
||||
#include "util/locks.h"
|
||||
struct config_file;
|
||||
struct sldns_buffer;
|
||||
struct dt_msg_queue;
|
||||
@@ -75,6 +76,13 @@ struct dt_env {
|
||||
unsigned log_forwarder_query_messages : 1;
|
||||
/** whether to log Message/FORWARDER_RESPONSE */
|
||||
unsigned log_forwarder_response_messages : 1;
|
||||
|
||||
/** lock on sample count */
|
||||
lock_basic_type sample_lock;
|
||||
/** rate limit value from config, samples 1/N messages */
|
||||
unsigned int sample_rate;
|
||||
/** rate limit counter */
|
||||
unsigned int sample_rate_count;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
+28
-31
@@ -34,41 +34,38 @@ AC_DEFUN([dt_DNSTAP],
|
||||
LDFLAGS="$LDFLAGS -L$withval/lib"
|
||||
],
|
||||
[
|
||||
ifdef([PKG_CHECK_MODULES],
|
||||
[
|
||||
PKG_CHECK_MODULES([PROTOBUFC], [libprotobuf-c],
|
||||
[
|
||||
CFLAGS="$CFLAGS $PROTOBUFC_CFLAGS"
|
||||
LIBS="$LIBS $PROTOBUFC_LIBS"
|
||||
],
|
||||
[
|
||||
# pkg-config failed; try falling back to known values
|
||||
# workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
|
||||
if test -f /usr/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I/usr/include/google"
|
||||
if test -n "$PKG_CONFIG"; then
|
||||
PKG_CHECK_MODULES([PROTOBUFC], [libprotobuf-c],
|
||||
[
|
||||
CFLAGS="$CFLAGS $PROTOBUFC_CFLAGS"
|
||||
LIBS="$LIBS $PROTOBUFC_LIBS"
|
||||
],
|
||||
[
|
||||
# pkg-config failed; try falling back to known values
|
||||
# workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
|
||||
if test -f /usr/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I/usr/include/google"
|
||||
else
|
||||
if test -f /usr/local/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I/usr/local/include/google"
|
||||
LDFLAGS="$LDFLAGS -L/usr/local/lib"
|
||||
else
|
||||
if test -f /usr/local/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I/usr/local/include/google"
|
||||
LDFLAGS="$LDFLAGS -L/usr/local/lib"
|
||||
else
|
||||
AC_MSG_ERROR([The protobuf-c package was not found with pkg-config. Please install protobuf-c!])
|
||||
fi
|
||||
AC_MSG_ERROR([The protobuf-c package was not found with pkg-config. Please install protobuf-c!])
|
||||
fi
|
||||
]
|
||||
)
|
||||
],
|
||||
[
|
||||
# workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
|
||||
if test -f /usr/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I/usr/include/google"
|
||||
else
|
||||
if test -f /usr/local/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I/usr/local/include/google"
|
||||
LDFLAGS="$LDFLAGS -L/usr/local/lib"
|
||||
fi
|
||||
]
|
||||
)
|
||||
else
|
||||
# workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
|
||||
if test -f /usr/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I/usr/include/google"
|
||||
else
|
||||
if test -f /usr/local/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I/usr/local/include/google"
|
||||
LDFLAGS="$LDFLAGS -L/usr/local/lib"
|
||||
fi
|
||||
]
|
||||
)
|
||||
fi
|
||||
fi
|
||||
]
|
||||
)
|
||||
AC_SEARCH_LIBS([protobuf_c_message_pack], [protobuf-c], [],
|
||||
|
||||
+45
-8
@@ -176,10 +176,7 @@ void
|
||||
mq_wakeup_cb(void* arg)
|
||||
{
|
||||
struct dt_msg_queue* mq = (struct dt_msg_queue*)arg;
|
||||
/* even if the dtio is already active, because perhaps much
|
||||
* traffic suddenly, we leave the timer running to save on
|
||||
* managing it, the once a second timer is less work then
|
||||
* starting and stopping the timer frequently */
|
||||
|
||||
lock_basic_lock(&mq->dtio->wakeup_timer_lock);
|
||||
mq->dtio->wakeup_timer_enabled = 0;
|
||||
lock_basic_unlock(&mq->dtio->wakeup_timer_lock);
|
||||
@@ -210,6 +207,8 @@ dt_msg_queue_start_timer(struct dt_msg_queue* mq, int wakeupnow)
|
||||
lock_basic_lock(&mq->dtio->wakeup_timer_lock);
|
||||
if(mq->dtio->wakeup_timer_enabled) {
|
||||
if(wakeupnow) {
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
comm_timer_set(mq->wakeup_timer, &tv);
|
||||
}
|
||||
lock_basic_unlock(&mq->dtio->wakeup_timer_lock);
|
||||
@@ -221,8 +220,14 @@ dt_msg_queue_start_timer(struct dt_msg_queue* mq, int wakeupnow)
|
||||
if(!wakeupnow) {
|
||||
tv.tv_sec = 1;
|
||||
tv.tv_usec = 0;
|
||||
/* If it is already set, keep it running. */
|
||||
if(!comm_timer_is_set(mq->wakeup_timer))
|
||||
comm_timer_set(mq->wakeup_timer, &tv);
|
||||
} else {
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
comm_timer_set(mq->wakeup_timer, &tv);
|
||||
}
|
||||
comm_timer_set(mq->wakeup_timer, &tv);
|
||||
lock_basic_unlock(&mq->dtio->wakeup_timer_lock);
|
||||
}
|
||||
|
||||
@@ -260,8 +265,9 @@ dt_msg_queue_submit(struct dt_msg_queue* mq, void* buf, size_t len)
|
||||
|
||||
/* acquire lock */
|
||||
lock_basic_lock(&mq->lock);
|
||||
/* if list was empty, start timer for (eventual) wakeup */
|
||||
if(mq->first == NULL)
|
||||
/* if list was empty, start timer for (eventual) wakeup,
|
||||
* or if dtio is not writing now an eventual wakeup is needed. */
|
||||
if(mq->first == NULL || !mq->dtio->event_added_is_write)
|
||||
wakeupstarttimer = 1;
|
||||
/* if list contains more than wakeupnum elements, wakeup now,
|
||||
* or if list is (going to be) almost full */
|
||||
@@ -1259,6 +1265,13 @@ static void dtio_sleep(struct dt_io_thread* dtio)
|
||||
/* unregister the event polling for write, because there is
|
||||
* nothing to be written */
|
||||
(void)dtio_add_output_event_read(dtio);
|
||||
|
||||
/* Set wakeuptimer enabled off; so that the next worker thread that
|
||||
* wants to log starts a timer if needed, since the writer thread
|
||||
* has gone to sleep. */
|
||||
lock_basic_lock(&dtio->wakeup_timer_lock);
|
||||
dtio->wakeup_timer_enabled = 0;
|
||||
lock_basic_unlock(&dtio->wakeup_timer_lock);
|
||||
}
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
@@ -1322,7 +1335,11 @@ static int dtio_ssl_check_peer(struct dt_io_thread* dtio)
|
||||
if((SSL_get_verify_mode(dtio->ssl)&SSL_VERIFY_PEER)) {
|
||||
/* verification */
|
||||
if(SSL_get_verify_result(dtio->ssl) == X509_V_OK) {
|
||||
#ifdef HAVE_SSL_GET1_PEER_CERTIFICATE
|
||||
X509* x = SSL_get1_peer_certificate(dtio->ssl);
|
||||
#else
|
||||
X509* x = SSL_get_peer_certificate(dtio->ssl);
|
||||
#endif
|
||||
if(!x) {
|
||||
verbose(VERB_ALGO, "dnstap io, %s, SSL "
|
||||
"connection failed no certificate",
|
||||
@@ -1347,7 +1364,11 @@ static int dtio_ssl_check_peer(struct dt_io_thread* dtio)
|
||||
#endif
|
||||
X509_free(x);
|
||||
} else {
|
||||
#ifdef HAVE_SSL_GET1_PEER_CERTIFICATE
|
||||
X509* x = SSL_get1_peer_certificate(dtio->ssl);
|
||||
#else
|
||||
X509* x = SSL_get_peer_certificate(dtio->ssl);
|
||||
#endif
|
||||
if(x) {
|
||||
log_cert(VERB_ALGO, "dnstap io, peer "
|
||||
"certificate", x);
|
||||
@@ -1489,8 +1510,10 @@ void dtio_output_cb(int ATTR_UNUSED(fd), short bits, void* arg)
|
||||
#endif
|
||||
|
||||
if((bits&UB_EV_READ || dtio->ssl_brief_write)) {
|
||||
#ifdef HAVE_SSL
|
||||
if(dtio->ssl_brief_write)
|
||||
(void)dtio_disable_brief_write(dtio);
|
||||
#endif
|
||||
if(dtio->ready_frame_sent && !dtio->accept_frame_received) {
|
||||
if(dtio_read_accept_frame(dtio) <= 0)
|
||||
return;
|
||||
@@ -1513,8 +1536,22 @@ void dtio_output_cb(int ATTR_UNUSED(fd), short bits, void* arg)
|
||||
/* no messages on the first iteration,
|
||||
* the queues are all empty */
|
||||
dtio_sleep(dtio);
|
||||
/* After putting to sleep, see if
|
||||
* a message is in a message queue,
|
||||
* if so, resume service. Stops a
|
||||
* race condition where a thread could
|
||||
* have one message but the dtio
|
||||
* also just went to sleep. With the
|
||||
* message queued between the
|
||||
* dtio_find_msg and dtio_sleep
|
||||
* calls. */
|
||||
if(dtio_find_msg(dtio)) {
|
||||
if(!dtio_add_output_event_write(dtio))
|
||||
return;
|
||||
}
|
||||
}
|
||||
return; /* nothing to do */
|
||||
if(!dtio->cur_msg)
|
||||
return; /* nothing to do */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+248
-37
@@ -75,17 +75,18 @@
|
||||
static void usage(char* argv[])
|
||||
{
|
||||
printf("usage: %s [options]\n", argv[0]);
|
||||
printf(" Listen to dnstap messages\n");
|
||||
printf(" Listen to dnstap messages\n");
|
||||
printf("stdout has dnstap log, stderr has verbose server log\n");
|
||||
printf("-u <socketpath> listen to unix socket with this file name\n");
|
||||
printf("-s <serverip[@port]> listen for TCP on the IP and port\n");
|
||||
printf("-t <serverip[@port]> listen for TLS on IP and port\n");
|
||||
printf("-x <server.key> server key file for TLS service\n");
|
||||
printf("-y <server.pem> server cert file for TLS service\n");
|
||||
printf("-z <verify.pem> cert file to verify client connections\n");
|
||||
printf("-l long format for DNS printout\n");
|
||||
printf("-v more verbose log output\n");
|
||||
printf("-h this help text\n");
|
||||
printf("-u <socketpath> listen to unix socket with this file name\n");
|
||||
printf("-s <serverip[@port]> listen for TCP on the IP and port\n");
|
||||
printf("-t <serverip[@port]> listen for TLS on IP and port\n");
|
||||
printf("-x <server.key> server key file for TLS service\n");
|
||||
printf("-y <server.pem> server cert file for TLS service\n");
|
||||
printf("-z <verify.pem> cert file to verify client connections\n");
|
||||
printf("-l long format for DNS printout\n");
|
||||
printf("-v more verbose log output\n");
|
||||
printf("-c internal unit test and exit\n");
|
||||
printf("-h this help text\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -102,6 +103,14 @@ struct main_tap_data {
|
||||
struct tap_socket_list* acceptlist;
|
||||
};
|
||||
|
||||
/* list of data */
|
||||
struct tap_data_list {
|
||||
/** next in list */
|
||||
struct tap_data_list* next;
|
||||
/** the data */
|
||||
struct tap_data* d;
|
||||
};
|
||||
|
||||
/** tap callback variables */
|
||||
struct tap_data {
|
||||
/** the fd */
|
||||
@@ -128,6 +137,10 @@ struct tap_data {
|
||||
uint8_t* frame;
|
||||
/** length of this frame */
|
||||
size_t len;
|
||||
/** back pointer to the tap_data_list entry;
|
||||
* used to NULL the forward pointer to this data
|
||||
* when this data is freed. */
|
||||
struct tap_data_list* data_list;
|
||||
};
|
||||
|
||||
/** list of sockets */
|
||||
@@ -156,8 +169,89 @@ struct tap_socket {
|
||||
char* ip;
|
||||
/** for a TLS socket, the tls context */
|
||||
SSL_CTX* sslctx;
|
||||
/** dumb way to deal with memory leaks:
|
||||
* tap_data was only freed on errors and not during exit leading to
|
||||
* false positives when testing for memory leaks. */
|
||||
struct tap_data_list* data_list;
|
||||
};
|
||||
|
||||
/** try to delete tail entries from the list if all of them have no data */
|
||||
static void tap_data_list_try_to_free_tail(struct tap_data_list* list)
|
||||
{
|
||||
struct tap_data_list* current = list;
|
||||
log_assert(!list->d);
|
||||
if(!list->next) /* we are the last, we can't remove ourselves */
|
||||
return;
|
||||
list = list->next;
|
||||
while(list) {
|
||||
if(list->d) /* a tail entry still has data; return */
|
||||
return;
|
||||
list = list->next;
|
||||
}
|
||||
/* keep the next */
|
||||
list = current->next;
|
||||
/* the tail will be removed; but not ourselves */
|
||||
current->next = NULL;
|
||||
while(list) {
|
||||
current = list;
|
||||
list = list->next;
|
||||
free(current);
|
||||
}
|
||||
}
|
||||
|
||||
/** delete the tap structure */
|
||||
static void tap_data_free(struct tap_data* data, int free_tail)
|
||||
{
|
||||
if(!data)
|
||||
return;
|
||||
if(data->ev) {
|
||||
ub_event_del(data->ev);
|
||||
ub_event_free(data->ev);
|
||||
}
|
||||
#ifdef HAVE_SSL
|
||||
SSL_free(data->ssl);
|
||||
#endif
|
||||
sock_close(data->fd);
|
||||
free(data->id);
|
||||
free(data->frame);
|
||||
if(data->data_list) {
|
||||
data->data_list->d = NULL;
|
||||
if(free_tail)
|
||||
tap_data_list_try_to_free_tail(data->data_list);
|
||||
}
|
||||
free(data);
|
||||
}
|
||||
|
||||
/** insert tap_data in the tap_data_list */
|
||||
static int tap_data_list_insert(struct tap_data_list** liststart,
|
||||
struct tap_data* d)
|
||||
{
|
||||
struct tap_data_list* entry = (struct tap_data_list*)
|
||||
malloc(sizeof(*entry));
|
||||
if(!entry)
|
||||
return 0;
|
||||
entry->next = *liststart;
|
||||
entry->d = d;
|
||||
d->data_list = entry;
|
||||
*liststart = entry;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** delete the tap_data_list and free any remaining tap_data */
|
||||
static void tap_data_list_delete(struct tap_data_list* list)
|
||||
{
|
||||
struct tap_data_list* e = list, *next;
|
||||
while(e) {
|
||||
next = e->next;
|
||||
if(e->d) {
|
||||
tap_data_free(e->d, 0);
|
||||
e->d = NULL;
|
||||
}
|
||||
free(e);
|
||||
e = next;
|
||||
}
|
||||
}
|
||||
|
||||
/** del the tap event */
|
||||
static void tap_socket_delev(struct tap_socket* s)
|
||||
{
|
||||
@@ -173,7 +267,7 @@ static void tap_socket_close(struct tap_socket* s)
|
||||
{
|
||||
if(!s) return;
|
||||
if(s->fd == -1) return;
|
||||
close(s->fd);
|
||||
sock_close(s->fd);
|
||||
s->fd = -1;
|
||||
}
|
||||
|
||||
@@ -184,6 +278,7 @@ static void tap_socket_delete(struct tap_socket* s)
|
||||
#ifdef HAVE_SSL
|
||||
SSL_CTX_free(s->sslctx);
|
||||
#endif
|
||||
tap_data_list_delete(s->data_list);
|
||||
ub_event_free(s->ev);
|
||||
free(s->socketpath);
|
||||
free(s->ip);
|
||||
@@ -728,27 +823,12 @@ static ssize_t tap_receive(struct tap_data* data, void* buf, size_t len)
|
||||
return receive_bytes(data, data->fd, buf, len);
|
||||
}
|
||||
|
||||
/** delete the tap structure */
|
||||
static void tap_data_free(struct tap_data* data)
|
||||
{
|
||||
ub_event_del(data->ev);
|
||||
ub_event_free(data->ev);
|
||||
#ifdef HAVE_SSL
|
||||
SSL_free(data->ssl);
|
||||
#endif
|
||||
close(data->fd);
|
||||
free(data->id);
|
||||
free(data->frame);
|
||||
free(data);
|
||||
}
|
||||
|
||||
/** reply with ACCEPT control frame to bidirectional client,
|
||||
* returns 0 on error */
|
||||
static int reply_with_accept(struct tap_data* data)
|
||||
{
|
||||
#ifdef USE_DNSTAP
|
||||
/* len includes the escape and framelength */
|
||||
int r;
|
||||
size_t len = 0;
|
||||
void* acceptframe = fstrm_create_control_frame_accept(
|
||||
DNSTAP_CONTENT_TYPE, &len);
|
||||
@@ -759,6 +839,8 @@ static int reply_with_accept(struct tap_data* data)
|
||||
|
||||
fd_set_block(data->fd);
|
||||
if(data->ssl) {
|
||||
#ifdef HAVE_SSL
|
||||
int r;
|
||||
if((r=SSL_write(data->ssl, acceptframe, len)) <= 0) {
|
||||
int r2;
|
||||
if((r2=SSL_get_error(data->ssl, r)) == SSL_ERROR_ZERO_RETURN)
|
||||
@@ -769,6 +851,7 @@ static int reply_with_accept(struct tap_data* data)
|
||||
free(acceptframe);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
if(send(data->fd, acceptframe, len, 0) == -1) {
|
||||
log_err("send failed: %s", sock_strerror(errno));
|
||||
@@ -804,6 +887,7 @@ static int reply_with_finish(struct tap_data* data)
|
||||
|
||||
fd_set_block(data->fd);
|
||||
if(data->ssl) {
|
||||
#ifdef HAVE_SSL
|
||||
int r;
|
||||
if((r=SSL_write(data->ssl, finishframe, len)) <= 0) {
|
||||
int r2;
|
||||
@@ -815,6 +899,7 @@ static int reply_with_finish(struct tap_data* data)
|
||||
free(finishframe);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
if(send(data->fd, finishframe, len, 0) == -1) {
|
||||
log_err("send failed: %s", sock_strerror(errno));
|
||||
@@ -842,7 +927,11 @@ static int tap_check_peer(struct tap_data* data)
|
||||
if((SSL_get_verify_mode(data->ssl)&SSL_VERIFY_PEER)) {
|
||||
/* verification */
|
||||
if(SSL_get_verify_result(data->ssl) == X509_V_OK) {
|
||||
#ifdef HAVE_SSL_GET1_PEER_CERTIFICATE
|
||||
X509* x = SSL_get1_peer_certificate(data->ssl);
|
||||
#else
|
||||
X509* x = SSL_get_peer_certificate(data->ssl);
|
||||
#endif
|
||||
if(!x) {
|
||||
if(verbosity) log_info("SSL connection %s"
|
||||
" failed no certificate", data->id);
|
||||
@@ -864,7 +953,11 @@ static int tap_check_peer(struct tap_data* data)
|
||||
#endif
|
||||
X509_free(x);
|
||||
} else {
|
||||
#ifdef HAVE_SSL_GET1_PEER_CERTIFICATE
|
||||
X509* x = SSL_get1_peer_certificate(data->ssl);
|
||||
#else
|
||||
X509* x = SSL_get_peer_certificate(data->ssl);
|
||||
#endif
|
||||
if(x) {
|
||||
if(verbosity)
|
||||
log_cert(VERB_ALGO, "peer certificate", x);
|
||||
@@ -906,7 +999,7 @@ static int tap_handshake(struct tap_data* data)
|
||||
return 0;
|
||||
} else if(r == 0) {
|
||||
/* closed */
|
||||
tap_data_free(data);
|
||||
tap_data_free(data, 1);
|
||||
return 0;
|
||||
} else if(want == SSL_ERROR_SYSCALL) {
|
||||
/* SYSCALL and errno==0 means closed uncleanly */
|
||||
@@ -924,7 +1017,7 @@ static int tap_handshake(struct tap_data* data)
|
||||
if(!silent)
|
||||
log_err("SSL_handshake syscall: %s",
|
||||
strerror(errno));
|
||||
tap_data_free(data);
|
||||
tap_data_free(data, 1);
|
||||
return 0;
|
||||
} else {
|
||||
unsigned long err = ERR_get_error();
|
||||
@@ -934,7 +1027,7 @@ static int tap_handshake(struct tap_data* data)
|
||||
verbose(VERB_OPS, "ssl handshake failed "
|
||||
"from %s", data->id);
|
||||
}
|
||||
tap_data_free(data);
|
||||
tap_data_free(data, 1);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -942,7 +1035,7 @@ static int tap_handshake(struct tap_data* data)
|
||||
data->ssl_handshake_done = 1;
|
||||
if(!tap_check_peer(data)) {
|
||||
/* closed */
|
||||
tap_data_free(data);
|
||||
tap_data_free(data, 1);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
@@ -968,7 +1061,7 @@ void dtio_tap_callback(int ATTR_UNUSED(fd), short ATTR_UNUSED(bits), void* arg)
|
||||
if(verbosity>=4) log_info("s recv %d", (int)ret);
|
||||
if(ret == 0) {
|
||||
/* closed or error */
|
||||
tap_data_free(data);
|
||||
tap_data_free(data, 1);
|
||||
return;
|
||||
} else if(ret == -1) {
|
||||
/* continue later */
|
||||
@@ -990,7 +1083,7 @@ void dtio_tap_callback(int ATTR_UNUSED(fd), short ATTR_UNUSED(bits), void* arg)
|
||||
data->frame = calloc(1, data->len);
|
||||
if(!data->frame) {
|
||||
log_err("out of memory");
|
||||
tap_data_free(data);
|
||||
tap_data_free(data, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1003,7 +1096,7 @@ void dtio_tap_callback(int ATTR_UNUSED(fd), short ATTR_UNUSED(bits), void* arg)
|
||||
if(verbosity>=4) log_info("f recv %d", (int)r);
|
||||
if(r == 0) {
|
||||
/* closed or error */
|
||||
tap_data_free(data);
|
||||
tap_data_free(data, 1);
|
||||
return;
|
||||
} else if(r == -1) {
|
||||
/* continue later */
|
||||
@@ -1028,13 +1121,13 @@ void dtio_tap_callback(int ATTR_UNUSED(fd), short ATTR_UNUSED(bits), void* arg)
|
||||
data->is_bidirectional = 1;
|
||||
if(verbosity) log_info("bidirectional stream");
|
||||
if(!reply_with_accept(data)) {
|
||||
tap_data_free(data);
|
||||
tap_data_free(data, 1);
|
||||
return;
|
||||
}
|
||||
} else if(data->len >= 4 && sldns_read_uint32(data->frame) ==
|
||||
FSTRM_CONTROL_FRAME_STOP && data->is_bidirectional) {
|
||||
if(!reply_with_finish(data)) {
|
||||
tap_data_free(data);
|
||||
tap_data_free(data, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1046,7 +1139,6 @@ void dtio_tap_callback(int ATTR_UNUSED(fd), short ATTR_UNUSED(bits), void* arg)
|
||||
data->len = 0;
|
||||
data->len_done = 0;
|
||||
data->data_done = 0;
|
||||
|
||||
}
|
||||
|
||||
/** callback for main listening file descriptor */
|
||||
@@ -1129,6 +1221,8 @@ void dtio_mainfdcallback(int fd, short ATTR_UNUSED(bits), void* arg)
|
||||
&dtio_tap_callback, data);
|
||||
if(!data->ev) fatal_exit("could not ub_event_new");
|
||||
if(ub_event_add(data->ev, NULL) != 0) fatal_exit("could not ub_event_add");
|
||||
if(!tap_data_list_insert(&tap_sock->data_list, data))
|
||||
fatal_exit("could not tap_data_list_insert");
|
||||
}
|
||||
|
||||
/** setup local accept sockets */
|
||||
@@ -1243,6 +1337,114 @@ setup_and_run(struct config_strlist_head* local_list,
|
||||
free(maindata);
|
||||
}
|
||||
|
||||
/* internal unit tests */
|
||||
static int internal_unittest()
|
||||
{
|
||||
/* unit test tap_data_list_try_to_free_tail() */
|
||||
#define unit_tap_datas_max 5
|
||||
struct tap_data* datas[unit_tap_datas_max];
|
||||
struct tap_data_list* list;
|
||||
struct tap_socket* socket = calloc(1, sizeof(*socket));
|
||||
size_t i = 0;
|
||||
log_assert(socket);
|
||||
log_assert(unit_tap_datas_max>2); /* needed for the test */
|
||||
for(i=0; i<unit_tap_datas_max; i++) {
|
||||
datas[i] = calloc(1, sizeof(struct tap_data));
|
||||
log_assert(datas[i]);
|
||||
log_assert(tap_data_list_insert(&socket->data_list, datas[i]));
|
||||
}
|
||||
/* sanity base check */
|
||||
list = socket->data_list;
|
||||
for(i=0; list; i++) list = list->next;
|
||||
log_assert(i==unit_tap_datas_max);
|
||||
|
||||
/* Free the last data, tail cannot be erased */
|
||||
list = socket->data_list;
|
||||
while(list->next) list = list->next;
|
||||
free(list->d);
|
||||
list->d = NULL;
|
||||
tap_data_list_try_to_free_tail(list);
|
||||
list = socket->data_list;
|
||||
for(i=0; list; i++) list = list->next;
|
||||
log_assert(i==unit_tap_datas_max);
|
||||
|
||||
/* Free the third to last data, tail cannot be erased */
|
||||
list = socket->data_list;
|
||||
for(i=0; i<unit_tap_datas_max-3; i++) list = list->next;
|
||||
free(list->d);
|
||||
list->d = NULL;
|
||||
tap_data_list_try_to_free_tail(list);
|
||||
list = socket->data_list;
|
||||
for(i=0; list; i++) list = list->next;
|
||||
log_assert(i==unit_tap_datas_max);
|
||||
|
||||
/* Free the second to last data, try to remove tail from the third
|
||||
* again, tail (last 2) should be removed */
|
||||
list = socket->data_list;
|
||||
for(i=0; i<unit_tap_datas_max-2; i++) list = list->next;
|
||||
free(list->d);
|
||||
list->d = NULL;
|
||||
list = socket->data_list;
|
||||
while(list->d) list = list->next;
|
||||
tap_data_list_try_to_free_tail(list);
|
||||
list = socket->data_list;
|
||||
for(i=0; list; i++) list = list->next;
|
||||
log_assert(i==unit_tap_datas_max-2);
|
||||
|
||||
/* Free all the remaining data, try to remove tail from the start,
|
||||
* only the start should remain */
|
||||
list = socket->data_list;
|
||||
while(list) {
|
||||
free(list->d);
|
||||
list->d = NULL;
|
||||
list = list->next;
|
||||
}
|
||||
tap_data_list_try_to_free_tail(socket->data_list);
|
||||
list = socket->data_list;
|
||||
for(i=0; list; i++) list = list->next;
|
||||
log_assert(i==1);
|
||||
|
||||
/* clean up */
|
||||
tap_data_list_delete(socket->data_list);
|
||||
free(socket);
|
||||
|
||||
/* Start again. Add two elements */
|
||||
socket = calloc(1, sizeof(*socket));
|
||||
log_assert(socket);
|
||||
for(i=0; i<2; i++) {
|
||||
datas[i] = calloc(1, sizeof(struct tap_data));
|
||||
log_assert(datas[i]);
|
||||
log_assert(tap_data_list_insert(&socket->data_list, datas[i]));
|
||||
}
|
||||
/* sanity base check */
|
||||
list = socket->data_list;
|
||||
for(i=0; list; i++) list = list->next;
|
||||
log_assert(i==2);
|
||||
|
||||
/* Free the last data, tail cannot be erased */
|
||||
list = socket->data_list;
|
||||
while(list->next) list = list->next;
|
||||
free(list->d);
|
||||
list->d = NULL;
|
||||
tap_data_list_try_to_free_tail(list);
|
||||
list = socket->data_list;
|
||||
for(i=0; list; i++) list = list->next;
|
||||
log_assert(i==2);
|
||||
|
||||
/* clean up */
|
||||
tap_data_list_delete(socket->data_list);
|
||||
free(socket);
|
||||
|
||||
if(log_get_lock()) {
|
||||
lock_basic_destroy((lock_basic_type*)log_get_lock());
|
||||
}
|
||||
checklock_stop();
|
||||
#ifdef USE_WINSOCK
|
||||
WSACleanup();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** getopt global, in case header files fail to declare it. */
|
||||
extern int optind;
|
||||
/** getopt global, in case header files fail to declare it. */
|
||||
@@ -1293,7 +1495,7 @@ int main(int argc, char** argv)
|
||||
#endif
|
||||
|
||||
/* command line options */
|
||||
while( (c=getopt(argc, argv, "hls:t:u:vx:y:z:")) != -1) {
|
||||
while( (c=getopt(argc, argv, "hcls:t:u:vx:y:z:")) != -1) {
|
||||
switch(c) {
|
||||
case 'u':
|
||||
if(!cfg_strlist_append(&local_list,
|
||||
@@ -1329,6 +1531,12 @@ int main(int argc, char** argv)
|
||||
case 'v':
|
||||
verbosity++;
|
||||
break;
|
||||
case 'c':
|
||||
#ifndef UNBOUND_DEBUG
|
||||
fatal_exit("-c option needs compilation with "
|
||||
"--enable-debug");
|
||||
#endif
|
||||
return internal_unittest();
|
||||
case 'h':
|
||||
case '?':
|
||||
default:
|
||||
@@ -1365,6 +1573,9 @@ int main(int argc, char** argv)
|
||||
config_delstrlist(tcp_list.first);
|
||||
config_delstrlist(tls_list.first);
|
||||
|
||||
if(log_get_lock()) {
|
||||
lock_basic_destroy((lock_basic_type*)log_get_lock());
|
||||
}
|
||||
checklock_stop();
|
||||
#ifdef USE_WINSOCK
|
||||
WSACleanup();
|
||||
|
||||
+185
@@ -1,3 +1,188 @@
|
||||
9 August 2024: Wouter
|
||||
- Fix spelling for the cache-min-negative-ttl entry in the
|
||||
example.conf.
|
||||
|
||||
8 August 2024: Wouter
|
||||
- Fix CAMP issues with global quota. Thanks to Huayi Duan, Marco
|
||||
Bearzi, Jodok Vieli, and Cagin Tanir from NetSec group, ETH Zurich.
|
||||
- Fix CacheFlush issues with limit on NS RRs. Thanks to Yehuda Afek,
|
||||
Anat Bremler-Barr, Shoham Danino and Yuval Shavitt (Tel-Aviv
|
||||
University and Reichman University).
|
||||
- Set version number to 1.21.0 for release.
|
||||
- Fix that for windows the module startup is called and sets up
|
||||
the module-config.
|
||||
|
||||
2 August 2024: Wouter
|
||||
- Fix that alloc stats has strdup checks, it stops debuggers from
|
||||
complaining about mismatch at free time.
|
||||
- Fix testbound for alloc stats strdup in util/alloc.c.
|
||||
- Merge #1090: Cookie secret file. Adds
|
||||
`cookie-secret-file: "unbound_cookiesecrets.txt"` option to store
|
||||
cookie secrets for EDNS COOKIE secret rollover. The remote control
|
||||
add_cookie_secret, activate_cookie_secret and drop_cookie_secret
|
||||
commands can be used for rollover, the command print_cookie_secrets
|
||||
shows the values in use.
|
||||
- Fix that alloc stats for forwards and hints are printed, and when
|
||||
alloc stats is enabled, the unit test for unbound control waits for
|
||||
reloads to complete.
|
||||
|
||||
1 August 2024: Wouter
|
||||
- Fix dnstap test program, cleans up to have clean memory on exit,
|
||||
for tap_data_free, does not delete NULL items. Also it does not try
|
||||
to free the tail, specifically in the free of the list since that
|
||||
picked up the next item in the list for its loop causing invalid
|
||||
free. Added internal unit test to unbound-dnstap-socket for that.
|
||||
- Fix that the worker mem report with alloc stats does not attempt
|
||||
to print memory use of forwards and hints if they have been
|
||||
deleted already.
|
||||
|
||||
31 July 2024: Wouter
|
||||
- Fix for #1114: Fix that cache fill for forward-host names is
|
||||
performed, so that with nonzero target-fetch-policy it fetches
|
||||
forwarder addresses and uses them from cache. Also updated that
|
||||
delegation point cache fill routines use CDflag for AAAA message
|
||||
lookups, so that its negative lookup stops a recursion since the
|
||||
cache uses the bit for disambiguation for dns64 but the recursion
|
||||
uses CDflag for the AAAA target lookups, so the check correctly
|
||||
stops a useless recursion by its cache lookup.
|
||||
|
||||
30 July 2024: Wouter
|
||||
- Fix to document parameters of auth_zone_verify_zonemd_with_key.
|
||||
|
||||
25 July 2024: Wouter
|
||||
- Add root key 38696 from 2024 for DNSSEC validation. It is added
|
||||
to the default root keys in unbound-anchor. The content can be
|
||||
inspected with `unbound-anchor -l`.
|
||||
|
||||
23 July 2024: Yorgos
|
||||
- Fix #1106: ratelimit-below-domain logs the wrong FROM address.
|
||||
- Cleanup ede.tdir test.
|
||||
- For #935 and #1104, clarify RPZ order and semantics.
|
||||
|
||||
23 July 2024: Wouter
|
||||
- Merge #1110: Make fallthrough explicit for libworker.c.
|
||||
- For #1110: Test for fallthrough attribute in configure and add
|
||||
fallthrough attribute annotations.
|
||||
- Fix compile when the compiler does not support the noreturn
|
||||
attribute.
|
||||
- Fix to have empty definition when not supported for weak attribute.
|
||||
- Fix uninitialized variable warning in create_tcp_accept_sock.
|
||||
- Fix link of dnstap without openssl.
|
||||
- Fix link of unbound-dnstap-socket without openssl.
|
||||
|
||||
19 July 2024: Wouter
|
||||
- Add dnstap-sample-rate that logs only 1/N messages, for high volume
|
||||
server environments. Thanks Dan Luther.
|
||||
- Fix dnstap wakeup, a running wakeup timer is left to expire and not
|
||||
increased, a timer is started when the dtio thread is sleeping,
|
||||
the timer set disabled when the dtio thread goes to sleep, and
|
||||
after sleep the thread checks to see if there are messages to log
|
||||
immediately.
|
||||
|
||||
16 July 2024: Wouter
|
||||
- For #1103: Fix to drop mesh state reference for the http2 stream
|
||||
associated with the reply, not the currently active stream. And
|
||||
it does not remove it twice on a mesh_send_reply call. The reply
|
||||
h2_stream is NULL when not in use, for more initialisation.
|
||||
|
||||
15 July 2024: Wouter
|
||||
- For #1103: fix to also drop mesh state reference when the discard
|
||||
limit is reached, when there is an error making a new recursion
|
||||
state and when the connection is dropped with is_drop.
|
||||
|
||||
12 July 2024: Yorgos
|
||||
- Add RPZ tag tests in acl_interface.tdir.
|
||||
- For #1102: clearer text for using interface-* options for the
|
||||
loopback interface.
|
||||
|
||||
12 July 2024: Wouter
|
||||
- Fix #1103: unbound 1.20.0 segmentation fault with nghttp2.
|
||||
- For #1103: fix to also drop mesh state reference when a h2 reply is
|
||||
dropped.
|
||||
|
||||
10 July 2024: Wouter
|
||||
- For #773: In contrib/unbound.service.in set unbound to start after
|
||||
network-online.target. Also for contrib/unbound_portable.service.in.
|
||||
|
||||
9 July 2024: Yorgos
|
||||
- Update list of known EDE codes.
|
||||
|
||||
8 July 2024: Wouter
|
||||
- Fix that validation reason failure that uses string print uses
|
||||
separate buffer that is passed, from the scratch validation buffer.
|
||||
- Fixup algo_needs_reason string buffer length.
|
||||
- Fix shadowed error string variable in validator dnskey handling.
|
||||
|
||||
5 July 2024: Yorgos
|
||||
- Don't check for message TTL changes if the RRsets remain the same.
|
||||
|
||||
5 July 2024: Wouter
|
||||
- Fix for neater printout for error for missing DS response.
|
||||
- Fix neater printout.
|
||||
- Fix #1099: Unbound core dump on SIGSEGV.
|
||||
- Fix for #1099: Fix to check for deleted RRset when the contents
|
||||
is updated and fetched after it is stored, and also check for a
|
||||
changed RRset.
|
||||
|
||||
4 July 2024: Wouter
|
||||
- Fix to print details about the failure to lookup a DNSKEY record
|
||||
when validation fails due to the missing DNSKEY. Also for key prime
|
||||
and DS lookups.
|
||||
|
||||
3 July 2024: Yorgos
|
||||
- Fix for repeated use of a DNAME record: first overallocate and then
|
||||
move the exact size of the init value to avoid false positive heap
|
||||
overflow reads from address sanitizers.
|
||||
|
||||
3 July 2024: Wouter
|
||||
- Fix #144: Port ipset to BSD pf tables.
|
||||
- Add unit test skip files and bison and flex output to gitignore.
|
||||
- Fix to use modstack_init in zonemd unit test.
|
||||
- Fix to remove unneeded linebreak in fptr_wlist.c.
|
||||
- Fix compile warnings in fptr_wlist.c.
|
||||
|
||||
2 July 2024: Wouter
|
||||
- Fix to remove unused include from the readzone test program.
|
||||
- Fix unused variable warning in do_cache_remove.
|
||||
- Fix compile warning in worker pthread id printout.
|
||||
|
||||
17 June 2024: Wouter
|
||||
- Fix ip-ratelimit-cookie setting, it was not applied.
|
||||
|
||||
26 June 2024: Yorgos
|
||||
- Explicitly set the RD bit for the mesh query flags when prefetching.
|
||||
These queries have no waiting client but they need to be treated as
|
||||
recursive.
|
||||
|
||||
21 June 2024: Yorgos
|
||||
- Fix pkg-config availability check in dnstap/dnstap.m4 and
|
||||
systemd.m4.
|
||||
|
||||
19 June 2024: Yorgos
|
||||
- Fix #1092: Ubuntu 22.04 Jammy fails to compile unbound 1.20.0; by
|
||||
adding helpful text for the Python interpreter version and allowing
|
||||
the default pkg-config unavailability error message to be shown.
|
||||
|
||||
17 June 2024: Wouter
|
||||
- Fix #1091: Build fails with OpenSSL >= 3.0 built with
|
||||
OPENSSL_NO_DEPRECATED.
|
||||
|
||||
7 June 2024: Wouter
|
||||
- Add unit test for validation of repeated use of a DNAME record.
|
||||
|
||||
6 June 2024: Wouter
|
||||
- Fix memory leak in setup of dsa sig.
|
||||
- Fix typos for 'the the' in text.
|
||||
- Fix validation for repeated use of a DNAME record.
|
||||
|
||||
4 June 2024: Yorgos
|
||||
- Merge #1080: AddressSanitizer detection in tdir tests and memory leak
|
||||
fixes.
|
||||
- Fix memory leak when reload_keep_cache is used and num-threads
|
||||
changes.
|
||||
- Fix memory leak on exit for unbound-dnstap-socket; creates false
|
||||
negatives during testing.
|
||||
|
||||
3 June 2024: Wouter
|
||||
- Fix to squelch connection reset by peer errors from log. And fix
|
||||
that the tcp read errors are labeled as initial for the first calls.
|
||||
|
||||
+10
-2
@@ -228,7 +228,7 @@ server:
|
||||
|
||||
# the time to live (TTL) value lower bound, in seconds. Default 0.
|
||||
# For negative responses in the cache. If disabled, default,
|
||||
# cache-min-tll applies if configured.
|
||||
# cache-min-ttl applies if configured.
|
||||
# cache-min-negative-ttl: 0
|
||||
|
||||
# the time to live (TTL) value for cached roundtrip times, lameness and
|
||||
@@ -1044,6 +1044,11 @@ server:
|
||||
# example value "000102030405060708090a0b0c0d0e0f".
|
||||
# cookie-secret: <128 bit random hex string>
|
||||
|
||||
# File with cookie secrets, the 'cookie-secret:' option is ignored
|
||||
# and the file can be managed to have staging and active secrets
|
||||
# with remote control commands. Disabled with "". Default is "".
|
||||
# cookie-secret-file: "/usr/local/etc/unbound_cookiesecrets.txt"
|
||||
|
||||
# Enable to attach Extended DNS Error codes (RFC8914) to responses.
|
||||
# ede: no
|
||||
|
||||
@@ -1329,6 +1334,8 @@ remote-control:
|
||||
# dnstap-identity: ""
|
||||
# # if "" it uses the package version.
|
||||
# dnstap-version: ""
|
||||
# # log only 1/N messages, if 0 it is disabled. default 0.
|
||||
# dnstap-sample-rate: 0
|
||||
# dnstap-log-resolver-query-messages: no
|
||||
# dnstap-log-resolver-response-messages: no
|
||||
# dnstap-log-client-query-messages: no
|
||||
@@ -1337,7 +1344,8 @@ remote-control:
|
||||
# dnstap-log-forwarder-response-messages: no
|
||||
|
||||
# Response Policy Zones
|
||||
# RPZ policies. Applied in order of configuration. QNAME, Response IP
|
||||
# RPZ policies. Applied in order of configuration. Any match from an earlier
|
||||
# RPZ zone will terminate the RPZ lookup. QNAME, Response IP
|
||||
# Address, nsdname, nsip and clientip triggers are supported. Supported
|
||||
# actions are: NXDOMAIN, NODATA, PASSTHRU, DROP, Local Data, tcp-only
|
||||
# and drop. Policies can be loaded from a file, or using zone
|
||||
|
||||
@@ -350,6 +350,41 @@ Remove a list of \fIlocal_data\fR for given view from stdin. Like local_datas_re
|
||||
.TP
|
||||
.B view_local_datas \fIview\fR
|
||||
Add a list of \fIlocal_data\fR for given view from stdin. Like local_datas.
|
||||
.TP
|
||||
.B add_cookie_secret <secret>
|
||||
Add or replace a cookie secret persistently. <secret> needs to be an 128 bit
|
||||
hex string.
|
||||
.IP
|
||||
Cookie secrets can be either \fIactive\fR or \fIstaging\fR. \fIActive\fR cookie
|
||||
secrets are used to create DNS Cookies, but verification of a DNS Cookie
|
||||
succeeds with any of the \fIactive\fR or \fIstaging\fR cookie secrets. The
|
||||
state of the current cookie secrets can be printed with the
|
||||
\fBprint_cookie_secrets\fR command.
|
||||
.IP
|
||||
When there are no cookie secrets configured yet, the <secret> is added as
|
||||
\fIactive\fR. If there is already an \fIactive\fR cookie secret, the <secret>
|
||||
is added as \fIstaging\fR or replacing an existing \fIstaging\fR secret.
|
||||
.IP
|
||||
To "roll" a cookie secret used in an anycast set. The new secret has to be
|
||||
added as staging secret to \fBall\fR nodes in the anycast set. When \fBall\fR
|
||||
nodes can verify DNS Cookies with the new secret, the new secret can be
|
||||
activated with the \fBactivate_cookie_secret\fR command. After \fBall\fR nodes
|
||||
have the new secret \fIactive\fR for at least one hour, the previous secret can
|
||||
be dropped with the \fBdrop_cookie_secret\fR command.
|
||||
.IP
|
||||
Persistence is accomplished by writing to a file which if configured with the
|
||||
\fBcookie\-secret\-file\fR option in the server section of the config file.
|
||||
This is disabled by default, "".
|
||||
.TP
|
||||
.B drop_cookie_secret
|
||||
Drop the \fIstaging\fR cookie secret.
|
||||
.TP
|
||||
.B activate_cookie_secret
|
||||
Make the current \fIstaging\fR cookie secret \fIactive\fR, and the current
|
||||
\fIactive\fR cookie secret \fIstaging\fR.
|
||||
.TP
|
||||
.B print_cookie_secrets
|
||||
Show the current configured cookie secrets with their status.
|
||||
.SH "EXIT CODE"
|
||||
The unbound\-control program exits with status code 1 on error, 0 on success.
|
||||
.SH "SET UP"
|
||||
|
||||
+42
-13
@@ -788,7 +788,8 @@ transports, regardless of the presence of an DNS Cookie and regardless of the
|
||||
UDP queries without a DNS Cookie receive REFUSED responses with the TC flag set,
|
||||
that may trigger fall back to TCP for those clients.
|
||||
.IP
|
||||
By default only localhost is \fIallow\fRed, the rest is \fIrefuse\fRd.
|
||||
By default only localhost (the 127.0.0.0/8 IP netblock, not the loopback
|
||||
interface) is implicitly \fIallow\fRed, the rest is \fIrefuse\fRd.
|
||||
The default is \fIrefuse\fRd, because that is protocol\-friendly. The DNS
|
||||
protocol is not designed to handle dropped packets due to policy, and
|
||||
dropping may result in (possibly excessive) retried queries.
|
||||
@@ -824,8 +825,12 @@ 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.
|
||||
By default only localhost (the 127.0.0.0/8 IP netblock, not the loopback
|
||||
interface) is implicitly \fIallow\fRed through the default
|
||||
\fBaccess\-control:\fR behavior.
|
||||
This also means that any attempt to use the \fBinterface-*:\fR options for the
|
||||
loopback interface will not work as they will be overridden by the implicit
|
||||
default "\fBaccess\-control:\fR 127.0.0.0/8 allow" option.
|
||||
.IP
|
||||
Note that the interface needs to be already specified with \fBinterface:\fR
|
||||
and that any \fBaccess-control*:\fR setting overrides all \fBinterface-*:\fR
|
||||
@@ -1978,6 +1983,20 @@ Useful to explicitly set for servers in an anycast deployment that need to
|
||||
share the secret in order to verify each other's Server Cookies.
|
||||
An example hex string would be "000102030405060708090a0b0c0d0e0f".
|
||||
Default is a 128 bits random secret generated at startup time.
|
||||
This option is ignored if a \fBcookie\-secret\-file\fR is
|
||||
present. In that case the secrets from that file are used in DNS Cookie
|
||||
calculations.
|
||||
.TP 5
|
||||
.B cookie\-secret\-file: \fI<filename>
|
||||
File from which the secrets are read used in DNS Cookie calculations. When this
|
||||
file exists, the secrets in this file are used and the secret specified by the
|
||||
\fBcookie-secret\fR option is ignored.
|
||||
Enable it by setting a filename, like "/usr/local/etc/unbound_cookiesecrets.txt".
|
||||
The content of this file must be manipulated with the \fBadd_cookie_secret\fR,
|
||||
\fBdrop_cookie_secret\fR and \fBactivate_cookie_secret\fR commands to the
|
||||
\fIunbound\-control\fR(8) tool. Please see that manpage on how to perform a
|
||||
safe cookie secret rollover.
|
||||
Default is "" (disabled).
|
||||
.TP 5
|
||||
.B edns\-client\-string: \fI<IP netblock> <string>
|
||||
Include an EDNS0 option containing configured ascii string in queries with
|
||||
@@ -2847,6 +2866,13 @@ Default is "".
|
||||
The version to send with messages, if "" the package version is used.
|
||||
Default is "".
|
||||
.TP
|
||||
.B dnstap-sample-rate: \fI<number>
|
||||
The sample rate for log of messages, it logs only 1/N messages. With 0 it
|
||||
is disabled. Default is 0. This is useful in a high volume environment,
|
||||
where log functionality would otherwise not be reliable. For example 10
|
||||
would spend only 1/10th time on logging, and 100 would only spend a
|
||||
hundredth of the time on logging.
|
||||
.TP
|
||||
.B dnstap-log-resolver-query-messages: \fI<yes or no>
|
||||
Enable to log resolver query messages. Default is no.
|
||||
These are messages from Unbound to upstream servers.
|
||||
@@ -2871,9 +2897,11 @@ Enable to log forwarder response messages. Default is no.
|
||||
.SS Response Policy Zone Options
|
||||
.LP
|
||||
Response Policy Zones are configured with \fBrpz:\fR, and each one must have a
|
||||
\fBname:\fR. There can be multiple ones, by listing multiple rpz clauses, each
|
||||
with a different name. RPZ clauses are applied in order of configuration. The
|
||||
\fBrespip\fR module needs to be added to the \fBmodule-config\fR, e.g.:
|
||||
\fBname:\fR. There can be multiple ones, by listing multiple RPZ clauses, each
|
||||
with a different name. RPZ clauses are applied in order of configuration and
|
||||
any match from an earlier RPZ zone will terminate the RPZ lookup. Note that a
|
||||
PASSTHRU action is still considered a match.
|
||||
The \fBrespip\fR module needs to be added to the \fBmodule-config\fR, e.g.:
|
||||
\fBmodule-config: "respip validator iterator"\fR.
|
||||
.P
|
||||
QNAME, Response IP Address, nsdname, nsip and clientip triggers are supported.
|
||||
@@ -2881,12 +2909,13 @@ Supported actions are: NXDOMAIN, NODATA, PASSTHRU, DROP, Local Data, tcp\-only
|
||||
and drop. RPZ QNAME triggers are applied after \fBlocal\-zones\fR and
|
||||
before \fBauth\-zones\fR.
|
||||
.P
|
||||
The rpz zone is formatted with a SOA start record as usual. The items in
|
||||
the zone are entries, that specify what to act on (the trigger) and what to
|
||||
do (the action). The trigger to act on is recorded in the name, the action
|
||||
to do is recorded as the resource record. The names all end in the zone
|
||||
name, so you could type the trigger names without a trailing dot in the
|
||||
zonefile.
|
||||
The RPZ zone is a regular DNS zone formatted with a SOA start record as usual.
|
||||
The items in the zone are entries, that specify what to act on (the trigger)
|
||||
and what to do (the action).
|
||||
The trigger to act on is recorded in the name, the action to do is recorded as
|
||||
the resource record.
|
||||
The names all end in the zone name, so you could type the trigger names without
|
||||
a trailing dot in the zonefile.
|
||||
.P
|
||||
An example RPZ record, that answers example.com with NXDOMAIN
|
||||
.nf
|
||||
@@ -2986,7 +3015,7 @@ externally blocked. Default is no.
|
||||
If enabled the zone is authoritatively answered for and queries for the RPZ
|
||||
zone information are answered to downstream clients. This is useful for
|
||||
monitoring scripts, that can then access the SOA information to check if
|
||||
the rpz information is up to date. Default is no.
|
||||
the RPZ information is up to date. Default is no.
|
||||
.TP
|
||||
.B tags: \fI<list of tags>
|
||||
Limit the policies from this RPZ clause to clients with a matching tag. Tags
|
||||
|
||||
@@ -297,8 +297,8 @@ inplace_cb_delete_wrapped(struct module_env* env, enum inplace_cb_list_type type
|
||||
*/
|
||||
static struct module_func_block dynlibmod_block = {
|
||||
"dynlib",
|
||||
&dynlibmod_init, &dynlibmod_deinit, &dynlibmod_operate, &dynlibmod_inform_super,
|
||||
&dynlibmod_clear, &dynlibmod_get_mem
|
||||
NULL, NULL, &dynlibmod_init, &dynlibmod_deinit, &dynlibmod_operate,
|
||||
&dynlibmod_inform_super, &dynlibmod_clear, &dynlibmod_get_mem
|
||||
};
|
||||
|
||||
struct module_func_block* dynlibmod_get_funcblock(void)
|
||||
|
||||
@@ -995,7 +995,8 @@ subnetmod_get_mem(struct module_env *env, int id)
|
||||
* The module function block
|
||||
*/
|
||||
static struct module_func_block subnetmod_block = {
|
||||
"subnetcache", &subnetmod_init, &subnetmod_deinit, &subnetmod_operate,
|
||||
"subnetcache",
|
||||
NULL, NULL, &subnetmod_init, &subnetmod_deinit, &subnetmod_operate,
|
||||
&subnetmod_inform_super, &subnetmod_clear, &subnetmod_get_mem
|
||||
};
|
||||
|
||||
|
||||
+1
-1
@@ -615,7 +615,7 @@ ipsecmod_get_mem(struct module_env* env, int id)
|
||||
*/
|
||||
static struct module_func_block ipsecmod_block = {
|
||||
"ipsecmod",
|
||||
&ipsecmod_init, &ipsecmod_deinit, &ipsecmod_operate,
|
||||
NULL, NULL, &ipsecmod_init, &ipsecmod_deinit, &ipsecmod_operate,
|
||||
&ipsecmod_inform_super, &ipsecmod_clear, &ipsecmod_get_mem
|
||||
};
|
||||
|
||||
|
||||
+162
-47
@@ -17,9 +17,19 @@
|
||||
#include "sldns/wire2str.h"
|
||||
#include "sldns/parseutil.h"
|
||||
|
||||
#ifdef HAVE_NET_PFVAR_H
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <net/if.h>
|
||||
#include <net/pfvar.h>
|
||||
typedef intptr_t filter_dev;
|
||||
#else
|
||||
#include <libmnl/libmnl.h>
|
||||
#include <linux/netfilter/nfnetlink.h>
|
||||
#include <linux/netfilter/ipset/ip_set.h>
|
||||
typedef struct mnl_socket * filter_dev;
|
||||
#endif
|
||||
|
||||
#define BUFF_LEN 256
|
||||
|
||||
@@ -41,24 +51,95 @@ static int error_response(struct module_qstate* qstate, int id, int rcode) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct mnl_socket * open_mnl_socket() {
|
||||
struct mnl_socket *mnl;
|
||||
#ifdef HAVE_NET_PFVAR_H
|
||||
static void * open_filter() {
|
||||
filter_dev dev;
|
||||
|
||||
mnl = mnl_socket_open(NETLINK_NETFILTER);
|
||||
if (!mnl) {
|
||||
dev = open("/dev/pf", O_RDWR);
|
||||
if (dev == -1) {
|
||||
log_err("open(\"/dev/pf\") failed: %s", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
return (void *)dev;
|
||||
}
|
||||
#else
|
||||
static void * open_filter() {
|
||||
filter_dev dev;
|
||||
|
||||
dev = mnl_socket_open(NETLINK_NETFILTER);
|
||||
if (!dev) {
|
||||
log_err("ipset: could not open netfilter.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (mnl_socket_bind(mnl, 0, MNL_SOCKET_AUTOPID) < 0) {
|
||||
mnl_socket_close(mnl);
|
||||
if (mnl_socket_bind(dev, 0, MNL_SOCKET_AUTOPID) < 0) {
|
||||
mnl_socket_close(dev);
|
||||
log_err("ipset: could not bind netfilter.");
|
||||
return NULL;
|
||||
}
|
||||
return mnl;
|
||||
return (void *)dev;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int add_to_ipset(struct mnl_socket *mnl, const char *setname, const void *ipaddr, int af) {
|
||||
#ifdef HAVE_NET_PFVAR_H
|
||||
static int add_to_ipset(filter_dev dev, const char *setname, const void *ipaddr, int af) {
|
||||
struct pfioc_table io;
|
||||
struct pfr_addr addr;
|
||||
const char *p;
|
||||
int i;
|
||||
|
||||
bzero(&io, sizeof(io));
|
||||
bzero(&addr, sizeof(addr));
|
||||
|
||||
p = strrchr(setname, '/');
|
||||
if (p) {
|
||||
i = p - setname;
|
||||
if (i >= PATH_MAX) {
|
||||
errno = ENAMETOOLONG;
|
||||
return -1;
|
||||
}
|
||||
memcpy(io.pfrio_table.pfrt_anchor, setname, i);
|
||||
if (i < PATH_MAX)
|
||||
io.pfrio_table.pfrt_anchor[i] = '\0';
|
||||
p++;
|
||||
}
|
||||
else
|
||||
p = setname;
|
||||
|
||||
if (strlen(p) >= PF_TABLE_NAME_SIZE) {
|
||||
errno = ENAMETOOLONG;
|
||||
return -1;
|
||||
}
|
||||
strlcpy(io.pfrio_table.pfrt_name, p, PF_TABLE_NAME_SIZE);
|
||||
|
||||
io.pfrio_buffer = &addr;
|
||||
io.pfrio_size = 1;
|
||||
io.pfrio_esize = sizeof(addr);
|
||||
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
addr.pfra_ip4addr = *(struct in_addr *)ipaddr;
|
||||
addr.pfra_net = 32;
|
||||
break;
|
||||
case AF_INET6:
|
||||
addr.pfra_ip6addr = *(struct in6_addr *)ipaddr;
|
||||
addr.pfra_net = 128;
|
||||
break;
|
||||
default:
|
||||
errno = EAFNOSUPPORT;
|
||||
return -1;
|
||||
}
|
||||
addr.pfra_af = af;
|
||||
|
||||
if (ioctl(dev, DIOCRADDADDRS, &io) == -1) {
|
||||
log_err("ioctl failed: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static int add_to_ipset(filter_dev dev, const char *setname, const void *ipaddr, int af) {
|
||||
struct nlmsghdr *nlh;
|
||||
struct nfgenmsg *nfg;
|
||||
struct nlattr *nested[2];
|
||||
@@ -91,14 +172,15 @@ static int add_to_ipset(struct mnl_socket *mnl, const char *setname, const void
|
||||
mnl_attr_nest_end(nlh, nested[1]);
|
||||
mnl_attr_nest_end(nlh, nested[0]);
|
||||
|
||||
if (mnl_socket_sendto(mnl, nlh, nlh->nlmsg_len) < 0) {
|
||||
if (mnl_socket_sendto(dev, nlh, nlh->nlmsg_len) < 0) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
ipset_add_rrset_data(struct ipset_env *ie, struct mnl_socket *mnl,
|
||||
ipset_add_rrset_data(struct ipset_env *ie,
|
||||
struct packed_rrset_data *d, const char* setname, int af,
|
||||
const char* dname)
|
||||
{
|
||||
@@ -123,12 +205,16 @@ ipset_add_rrset_data(struct ipset_env *ie, struct mnl_socket *mnl,
|
||||
snprintf(ip, sizeof(ip), "(inet_ntop_error)");
|
||||
verbose(VERB_QUERY, "ipset: add %s to %s for %s", ip, setname, dname);
|
||||
}
|
||||
ret = add_to_ipset(mnl, setname, rr_data + 2, af);
|
||||
ret = add_to_ipset((filter_dev)ie->dev, setname, rr_data + 2, af);
|
||||
if (ret < 0) {
|
||||
log_err("ipset: could not add %s into %s", dname, setname);
|
||||
|
||||
mnl_socket_close(mnl);
|
||||
ie->mnl = NULL;
|
||||
#if HAVE_NET_PFVAR_H
|
||||
/* don't close as we might not be able to open again due to dropped privs */
|
||||
#else
|
||||
mnl_socket_close((filter_dev)ie->dev);
|
||||
ie->dev = NULL;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -137,8 +223,8 @@ ipset_add_rrset_data(struct ipset_env *ie, struct mnl_socket *mnl,
|
||||
|
||||
static int
|
||||
ipset_check_zones_for_rrset(struct module_env *env, struct ipset_env *ie,
|
||||
struct mnl_socket *mnl, struct ub_packed_rrset_key *rrset,
|
||||
const char *qname, const int qlen, const char *setname, int af)
|
||||
struct ub_packed_rrset_key *rrset, const char *qname, int qlen,
|
||||
const char *setname, int af)
|
||||
{
|
||||
static char dname[BUFF_LEN];
|
||||
const char *ds, *qs;
|
||||
@@ -152,11 +238,20 @@ ipset_check_zones_for_rrset(struct module_env *env, struct ipset_env *ie,
|
||||
log_err("bad domain name");
|
||||
return -1;
|
||||
}
|
||||
if (dname[dlen - 1] == '.') {
|
||||
dlen--;
|
||||
}
|
||||
if (qname[qlen - 1] == '.') {
|
||||
qlen--;
|
||||
}
|
||||
|
||||
for (p = env->cfg->local_zones_ipset; p; p = p->next) {
|
||||
ds = NULL;
|
||||
qs = NULL;
|
||||
plen = strlen(p->str);
|
||||
if (p->str[plen - 1] == '.') {
|
||||
plen--;
|
||||
}
|
||||
|
||||
if (dlen == plen || (dlen > plen && dname[dlen - plen - 1] == '.' )) {
|
||||
ds = dname + (dlen - plen);
|
||||
@@ -167,8 +262,7 @@ ipset_check_zones_for_rrset(struct module_env *env, struct ipset_env *ie,
|
||||
if ((ds && strncasecmp(p->str, ds, plen) == 0)
|
||||
|| (qs && strncasecmp(p->str, qs, plen) == 0)) {
|
||||
d = (struct packed_rrset_data*)rrset->entry.data;
|
||||
ipset_add_rrset_data(ie, mnl, d, setname,
|
||||
af, dname);
|
||||
ipset_add_rrset_data(ie, d, setname, af, dname);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -178,7 +272,6 @@ ipset_check_zones_for_rrset(struct module_env *env, struct ipset_env *ie,
|
||||
static int ipset_update(struct module_env *env, struct dns_msg *return_msg,
|
||||
struct query_info qinfo, struct ipset_env *ie)
|
||||
{
|
||||
struct mnl_socket *mnl;
|
||||
size_t i;
|
||||
const char *setname;
|
||||
struct ub_packed_rrset_key *rrset;
|
||||
@@ -186,15 +279,17 @@ static int ipset_update(struct module_env *env, struct dns_msg *return_msg,
|
||||
static char qname[BUFF_LEN];
|
||||
int qlen;
|
||||
|
||||
mnl = (struct mnl_socket *)ie->mnl;
|
||||
if (!mnl) {
|
||||
#ifdef HAVE_NET_PFVAR_H
|
||||
#else
|
||||
if (!ie->dev) {
|
||||
/* retry to create mnl socket */
|
||||
mnl = open_mnl_socket();
|
||||
if (!mnl) {
|
||||
ie->dev = open_filter();
|
||||
if (!ie->dev) {
|
||||
log_warn("ipset open_filter failed");
|
||||
return -1;
|
||||
}
|
||||
ie->mnl = mnl;
|
||||
}
|
||||
#endif
|
||||
|
||||
qlen = sldns_wire2str_dname_buf(qinfo.qname, qinfo.qname_len,
|
||||
qname, BUFF_LEN);
|
||||
@@ -217,8 +312,8 @@ static int ipset_update(struct module_env *env, struct dns_msg *return_msg,
|
||||
}
|
||||
|
||||
if (setname) {
|
||||
if(ipset_check_zones_for_rrset(env, ie, mnl, rrset,
|
||||
qname, qlen, setname, af) == -1)
|
||||
if(ipset_check_zones_for_rrset(env, ie, rrset, qname,
|
||||
qlen, setname, af) == -1)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -226,7 +321,7 @@ static int ipset_update(struct module_env *env, struct dns_msg *return_msg,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ipset_init(struct module_env* env, int id) {
|
||||
int ipset_startup(struct module_env* env, int id) {
|
||||
struct ipset_env *ipset_env;
|
||||
|
||||
ipset_env = (struct ipset_env *)calloc(1, sizeof(struct ipset_env));
|
||||
@@ -237,7 +332,43 @@ int ipset_init(struct module_env* env, int id) {
|
||||
|
||||
env->modinfo[id] = (void *)ipset_env;
|
||||
|
||||
ipset_env->mnl = NULL;
|
||||
#ifdef HAVE_NET_PFVAR_H
|
||||
ipset_env->dev = open_filter();
|
||||
if (!ipset_env->dev) {
|
||||
log_err("ipset open_filter failed");
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
ipset_env->dev = NULL;
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ipset_destartup(struct module_env* env, int id) {
|
||||
filter_dev dev;
|
||||
struct ipset_env *ipset_env;
|
||||
|
||||
if (!env || !env->modinfo[id]) {
|
||||
return;
|
||||
}
|
||||
ipset_env = (struct ipset_env*)env->modinfo[id];
|
||||
|
||||
dev = (filter_dev)ipset_env->dev;
|
||||
if (dev) {
|
||||
#if HAVE_NET_PFVAR_H
|
||||
close(dev);
|
||||
#else
|
||||
mnl_socket_close(dev);
|
||||
#endif
|
||||
ipset_env->dev = NULL;
|
||||
}
|
||||
|
||||
free(ipset_env);
|
||||
env->modinfo[id] = NULL;
|
||||
}
|
||||
|
||||
int ipset_init(struct module_env* env, int id) {
|
||||
struct ipset_env *ipset_env = env->modinfo[id];
|
||||
|
||||
ipset_env->name_v4 = env->cfg->ipset_name_v4;
|
||||
ipset_env->name_v6 = env->cfg->ipset_name_v6;
|
||||
@@ -253,24 +384,8 @@ int ipset_init(struct module_env* env, int id) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ipset_deinit(struct module_env *env, int id) {
|
||||
struct mnl_socket *mnl;
|
||||
struct ipset_env *ipset_env;
|
||||
|
||||
if (!env || !env->modinfo[id]) {
|
||||
return;
|
||||
}
|
||||
|
||||
ipset_env = (struct ipset_env *)env->modinfo[id];
|
||||
|
||||
mnl = (struct mnl_socket *)ipset_env->mnl;
|
||||
if (mnl) {
|
||||
mnl_socket_close(mnl);
|
||||
ipset_env->mnl = NULL;
|
||||
}
|
||||
|
||||
free(ipset_env);
|
||||
env->modinfo[id] = NULL;
|
||||
void ipset_deinit(struct module_env *ATTR_UNUSED(env), int ATTR_UNUSED(id)) {
|
||||
/* nothing */
|
||||
}
|
||||
|
||||
static int ipset_new(struct module_qstate* qstate, int id) {
|
||||
@@ -376,8 +491,8 @@ size_t ipset_get_mem(struct module_env *env, int id) {
|
||||
*/
|
||||
static struct module_func_block ipset_block = {
|
||||
"ipset",
|
||||
&ipset_init, &ipset_deinit, &ipset_operate,
|
||||
&ipset_inform_super, &ipset_clear, &ipset_get_mem
|
||||
&ipset_startup, &ipset_destartup, &ipset_init, &ipset_deinit,
|
||||
&ipset_operate, &ipset_inform_super, &ipset_clear, &ipset_get_mem
|
||||
};
|
||||
|
||||
struct module_func_block * ipset_get_funcblock(void) {
|
||||
|
||||
+5
-1
@@ -37,7 +37,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
struct ipset_env {
|
||||
void* mnl;
|
||||
void* dev;
|
||||
|
||||
int v4_enabled;
|
||||
int v6_enabled;
|
||||
@@ -50,6 +50,10 @@ struct ipset_qstate {
|
||||
int dummy;
|
||||
};
|
||||
|
||||
/** Startup the ipset module */
|
||||
int ipset_startup(struct module_env* env, int id);
|
||||
/** Destartup the ipset module */
|
||||
void ipset_destartup(struct module_env* env, int id);
|
||||
/** Init the ipset module */
|
||||
int ipset_init(struct module_env* env, int id);
|
||||
/** Deinit the ipset module */
|
||||
|
||||
@@ -367,6 +367,47 @@ type_allowed_in_additional_section(uint16_t tp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Shorten RRset */
|
||||
static void
|
||||
shorten_rrset(sldns_buffer* pkt, struct rrset_parse* rrset, int count)
|
||||
{
|
||||
/* The too large NS RRset is shortened. This is so that too large
|
||||
* content does not overwhelm the cache. It may make the rrset
|
||||
* bogus if it was signed, and then the domain is not resolved any
|
||||
* more, that is okay, the NS RRset was too large. During a referral
|
||||
* it can be shortened and then the first part of the list could
|
||||
* be used to resolve. The scrub continues to disallow glue for the
|
||||
* removed nameserver RRs and removes that too. Because the glue
|
||||
* is not marked as okay, since the RRs have been removed here. */
|
||||
int i;
|
||||
struct rr_parse* rr = rrset->rr_first, *prev = NULL;
|
||||
if(!rr)
|
||||
return;
|
||||
for(i=0; i<count; i++) {
|
||||
prev = rr;
|
||||
rr = rr->next;
|
||||
if(!rr)
|
||||
return; /* The RRset is already short. */
|
||||
}
|
||||
if(verbosity >= VERB_QUERY
|
||||
&& rrset->dname_len <= LDNS_MAX_DOMAINLEN) {
|
||||
uint8_t buf[LDNS_MAX_DOMAINLEN+1];
|
||||
dname_pkt_copy(pkt, buf, rrset->dname);
|
||||
log_nametypeclass(VERB_QUERY, "normalize: shorten RRset:", buf,
|
||||
rrset->type, ntohs(rrset->rrset_class));
|
||||
}
|
||||
/* remove further rrs */
|
||||
rrset->rr_last = prev;
|
||||
rrset->rr_count = count;
|
||||
while(rr) {
|
||||
rrset->size -= rr->size;
|
||||
rr = rr->next;
|
||||
}
|
||||
if(rrset->rr_last)
|
||||
rrset->rr_last->next = NULL;
|
||||
else rrset->rr_first = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine normalizes a response. This includes removing "irrelevant"
|
||||
* records from the answer and additional sections and (re)synthesizing
|
||||
@@ -387,6 +428,7 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
|
||||
uint8_t* sname = qinfo->qname;
|
||||
size_t snamelen = qinfo->qname_len;
|
||||
struct rrset_parse* rrset, *prev, *nsset=NULL;
|
||||
int cname_length = 0; /* number of CNAMEs, or DNAMEs */
|
||||
|
||||
if(FLAGS_GET_RCODE(msg->flags) != LDNS_RCODE_NOERROR &&
|
||||
FLAGS_GET_RCODE(msg->flags) != LDNS_RCODE_NXDOMAIN)
|
||||
@@ -401,6 +443,16 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
|
||||
prev = NULL;
|
||||
rrset = msg->rrset_first;
|
||||
while(rrset && rrset->section == LDNS_SECTION_ANSWER) {
|
||||
if(cname_length > 11 /* env->cfg.iter_scrub_cname */) {
|
||||
/* Too many CNAMEs, or DNAMEs, from the authority
|
||||
* server, scrub down the length to something
|
||||
* shorter. This deletes everything after the limit
|
||||
* is reached. The iterator is going to look up
|
||||
* the content one by one anyway. */
|
||||
remove_rrset("normalize: removing because too many cnames:",
|
||||
pkt, msg, prev, &rrset);
|
||||
continue;
|
||||
}
|
||||
if(rrset->type == LDNS_RR_TYPE_DNAME &&
|
||||
pkt_strict_sub(pkt, sname, rrset->dname)) {
|
||||
/* check if next rrset is correct CNAME. else,
|
||||
@@ -420,6 +472,7 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
|
||||
"too long");
|
||||
return 0;
|
||||
}
|
||||
cname_length++;
|
||||
if(nx && nx->type == LDNS_RR_TYPE_CNAME &&
|
||||
dname_pkt_compare(pkt, sname, nx->dname) == 0) {
|
||||
/* check next cname */
|
||||
@@ -460,6 +513,7 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
|
||||
if(rrset->type == LDNS_RR_TYPE_CNAME) {
|
||||
struct rrset_parse* nx = rrset->rrset_all_next;
|
||||
uint8_t* oldsname = sname;
|
||||
cname_length++;
|
||||
/* see if the next one is a DNAME, if so, swap them */
|
||||
if(nx && nx->section == LDNS_SECTION_ANSWER &&
|
||||
nx->type == LDNS_RR_TYPE_DNAME &&
|
||||
@@ -507,6 +561,10 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
|
||||
LDNS_SECTION_ANSWER &&
|
||||
dname_pkt_compare(pkt, oldsname,
|
||||
rrset->dname) == 0) {
|
||||
if(rrset->type == LDNS_RR_TYPE_NS &&
|
||||
rrset->rr_count > 20 /* env->cfg->iter_scrub_ns */) {
|
||||
shorten_rrset(pkt, rrset, 20 /* env->cfg->iter_scrub_ns */);
|
||||
}
|
||||
prev = rrset;
|
||||
rrset = rrset->rrset_all_next;
|
||||
}
|
||||
@@ -522,6 +580,11 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
|
||||
continue;
|
||||
}
|
||||
|
||||
if(rrset->type == LDNS_RR_TYPE_NS &&
|
||||
rrset->rr_count > 20 /* env->cfg->iter_scrub_ns */) {
|
||||
shorten_rrset(pkt, rrset, 20 /* env->cfg->iter_scrub_ns */);
|
||||
}
|
||||
|
||||
/* Mark the additional names from relevant rrset as OK. */
|
||||
/* only for RRsets that match the query name, other ones
|
||||
* will be removed by sanitize, so no additional for them */
|
||||
@@ -578,6 +641,25 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
|
||||
"RRset:", pkt, msg, prev, &rrset);
|
||||
continue;
|
||||
}
|
||||
if(rrset->rr_count > 20 /* env->cfg->iter_scrub_ns */) {
|
||||
/* If this is not a referral, and the NS RRset
|
||||
* is signed, then remove it entirely, so
|
||||
* that when it becomes bogus it does not
|
||||
* make the message that is otherwise fine
|
||||
* into a bogus message. */
|
||||
if(!(msg->an_rrsets == 0 &&
|
||||
FLAGS_GET_RCODE(msg->flags) ==
|
||||
LDNS_RCODE_NOERROR &&
|
||||
!soa_in_auth(msg) &&
|
||||
!(msg->flags & BIT_AA)) &&
|
||||
rrset->rrsig_count != 0) {
|
||||
remove_rrset("normalize: removing too large NS "
|
||||
"RRset:", pkt, msg, prev, &rrset);
|
||||
continue;
|
||||
} else {
|
||||
shorten_rrset(pkt, rrset, 20 /* env->cfg->iter_scrub_ns */);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* if this is type DS and we query for type DS we just got
|
||||
* a referral answer for our type DS query, fix packet */
|
||||
|
||||
+26
-2
@@ -760,6 +760,14 @@ target_count_increase_nx(struct iter_qstate* iq, int num)
|
||||
iq->target_count[TARGET_COUNT_NX] += num;
|
||||
}
|
||||
|
||||
static void
|
||||
target_count_increase_global_quota(struct iter_qstate* iq, int num)
|
||||
{
|
||||
target_count_create(iq);
|
||||
if(iq->target_count)
|
||||
iq->target_count[TARGET_COUNT_GLOBAL_QUOTA] += num;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a subrequest.
|
||||
* Generate a local request event. Local events are tied to this module, and
|
||||
@@ -1560,6 +1568,11 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
errinf(qstate, "malloc failure for forward zone");
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
if(!cache_fill_missing(qstate->env, iq->qchase.qclass,
|
||||
qstate->region, iq->dp)) {
|
||||
errinf(qstate, "malloc failure, copy extra info into delegation point");
|
||||
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
if((qstate->query_flags&BIT_RD)==0) {
|
||||
/* If the server accepts RD=0 queries and forwards
|
||||
* with RD=1, then if the server is listed as an NS
|
||||
@@ -3008,6 +3021,17 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
|
||||
}
|
||||
}
|
||||
|
||||
target_count_increase_global_quota(iq, 1);
|
||||
if(iq->target_count && iq->target_count[TARGET_COUNT_GLOBAL_QUOTA]
|
||||
> MAX_GLOBAL_QUOTA) {
|
||||
char s[LDNS_MAX_DOMAINLEN+1];
|
||||
dname_str(qstate->qinfo.qname, s);
|
||||
verbose(VERB_QUERY, "request %s has exceeded the maximum "
|
||||
"global quota on number of upstream queries %d", s,
|
||||
iq->target_count[TARGET_COUNT_GLOBAL_QUOTA]);
|
||||
return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL);
|
||||
}
|
||||
|
||||
/* Do not check ratelimit for forwarding queries or if we already got a
|
||||
* pass. */
|
||||
sq_check_ratelimit = (!(iq->chase_flags & BIT_RD) && !iq->ratelimit_ok);
|
||||
@@ -4489,8 +4513,8 @@ iter_get_mem(struct module_env* env, int id)
|
||||
*/
|
||||
static struct module_func_block iter_block = {
|
||||
"iterator",
|
||||
&iter_init, &iter_deinit, &iter_operate, &iter_inform_super,
|
||||
&iter_clear, &iter_get_mem
|
||||
NULL, NULL, &iter_init, &iter_deinit, &iter_operate,
|
||||
&iter_inform_super, &iter_clear, &iter_get_mem
|
||||
};
|
||||
|
||||
struct module_func_block*
|
||||
|
||||
@@ -55,6 +55,9 @@ struct rbtree_type;
|
||||
|
||||
/** max number of targets spawned for a query and its subqueries */
|
||||
#define MAX_TARGET_COUNT 64
|
||||
/** max number of upstream queries for a query and its subqueries, it is
|
||||
* never reset. */
|
||||
#define MAX_GLOBAL_QUOTA 128
|
||||
/** max number of target lookups per qstate, per delegation point */
|
||||
#define MAX_DP_TARGET_COUNT 16
|
||||
/** max number of nxdomains allowed for target lookups for a query and
|
||||
@@ -248,6 +251,9 @@ enum target_count_variables {
|
||||
TARGET_COUNT_QUERIES,
|
||||
/** Number of nxdomain responses encountered. */
|
||||
TARGET_COUNT_NX,
|
||||
/** Global quota on number of queries to upstream servers per
|
||||
* client request, that is never reset. */
|
||||
TARGET_COUNT_GLOBAL_QUOTA,
|
||||
|
||||
/** This should stay last here, it is used for the allocation */
|
||||
TARGET_COUNT_MAX,
|
||||
|
||||
@@ -75,7 +75,9 @@ context_finalize(struct ub_ctx* ctx)
|
||||
ctx->pipe_pid = getpid();
|
||||
cfg_apply_local_port_policy(cfg, 65536);
|
||||
config_apply(cfg);
|
||||
if(!modstack_setup(&ctx->mods, cfg->module_conf, ctx->env))
|
||||
if(!modstack_call_startup(&ctx->mods, cfg->module_conf, ctx->env))
|
||||
return UB_INITFAIL;
|
||||
if(!modstack_call_init(&ctx->mods, cfg->module_conf, ctx->env))
|
||||
return UB_INITFAIL;
|
||||
listen_setup_locks();
|
||||
log_edns_known_options(VERB_ALGO, ctx->env);
|
||||
|
||||
@@ -188,7 +188,9 @@ ub_ctx_create(void)
|
||||
int e = errno;
|
||||
ub_randfree(ctx->seed_rnd);
|
||||
config_delete(ctx->env->cfg);
|
||||
modstack_desetup(&ctx->mods, ctx->env);
|
||||
modstack_call_deinit(&ctx->mods, ctx->env);
|
||||
modstack_call_destartup(&ctx->mods, ctx->env);
|
||||
modstack_free(&ctx->mods);
|
||||
listen_desetup_locks();
|
||||
edns_known_options_delete(ctx->env);
|
||||
edns_strings_delete(ctx->env->edns_strings);
|
||||
@@ -202,7 +204,9 @@ ub_ctx_create(void)
|
||||
tube_delete(ctx->qq_pipe);
|
||||
ub_randfree(ctx->seed_rnd);
|
||||
config_delete(ctx->env->cfg);
|
||||
modstack_desetup(&ctx->mods, ctx->env);
|
||||
modstack_call_deinit(&ctx->mods, ctx->env);
|
||||
modstack_call_destartup(&ctx->mods, ctx->env);
|
||||
modstack_free(&ctx->mods);
|
||||
listen_desetup_locks();
|
||||
edns_known_options_delete(ctx->env);
|
||||
edns_strings_delete(ctx->env->edns_strings);
|
||||
@@ -360,7 +364,9 @@ ub_ctx_delete(struct ub_ctx* ctx)
|
||||
}
|
||||
libworker_delete_event(ctx->event_worker);
|
||||
|
||||
modstack_desetup(&ctx->mods, ctx->env);
|
||||
modstack_call_deinit(&ctx->mods, ctx->env);
|
||||
modstack_call_destartup(&ctx->mods, ctx->env);
|
||||
modstack_free(&ctx->mods);
|
||||
a = ctx->alloc_list;
|
||||
while(a) {
|
||||
na = a->super;
|
||||
|
||||
@@ -292,6 +292,7 @@ libworker_do_cmd(struct libworker* w, uint8_t* msg, uint32_t len)
|
||||
log_err("unknown command for bg worker %d",
|
||||
(int)context_serial_getcmd(msg, len));
|
||||
/* and fall through to quit */
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case UB_LIBCMD_QUIT:
|
||||
free(msg);
|
||||
|
||||
+1
-1
@@ -53,7 +53,7 @@ Generate a distribution tar file for unbound.
|
||||
(which will then be unbound-<version>rc<number>)
|
||||
-u git_url Retrieve the source from the specified repository url.
|
||||
Detected from the working copy if not specified.
|
||||
-b git_branch Retrieve the the specified branch or tag.
|
||||
-b git_branch Retrieve the specified branch or tag.
|
||||
Detected from the working copy if not specified.
|
||||
-wssl openssl.xx.tar.gz Also build openssl from tarball for windows dist.
|
||||
-wxp expat.xx.tar.gz Also build expat from tarball for windows dist.
|
||||
|
||||
@@ -777,8 +777,8 @@ size_t pythonmod_get_mem(struct module_env* env, int id)
|
||||
*/
|
||||
static struct module_func_block pythonmod_block = {
|
||||
"python",
|
||||
&pythonmod_init, &pythonmod_deinit, &pythonmod_operate, &pythonmod_inform_super,
|
||||
&pythonmod_clear, &pythonmod_get_mem
|
||||
NULL, NULL, &pythonmod_init, &pythonmod_deinit, &pythonmod_operate,
|
||||
&pythonmod_inform_super, &pythonmod_clear, &pythonmod_get_mem
|
||||
};
|
||||
|
||||
struct module_func_block* pythonmod_get_funcblock(void)
|
||||
|
||||
+2
-2
@@ -1259,8 +1259,8 @@ respip_get_mem(struct module_env* env, int id)
|
||||
*/
|
||||
static struct module_func_block respip_block = {
|
||||
"respip",
|
||||
&respip_init, &respip_deinit, &respip_operate, &respip_inform_super,
|
||||
&respip_clear, &respip_get_mem
|
||||
NULL, NULL, &respip_init, &respip_deinit, &respip_operate,
|
||||
&respip_inform_super, &respip_clear, &respip_get_mem
|
||||
};
|
||||
|
||||
struct module_func_block*
|
||||
|
||||
+32
-16
@@ -7778,7 +7778,8 @@ static void auth_zone_log(uint8_t* name, enum verbosity_value level,
|
||||
static int zonemd_dnssec_verify_rrset(struct auth_zone* z,
|
||||
struct module_env* env, struct module_stack* mods,
|
||||
struct ub_packed_rrset_key* dnskey, struct auth_data* node,
|
||||
struct auth_rrset* rrset, char** why_bogus, uint8_t* sigalg)
|
||||
struct auth_rrset* rrset, char** why_bogus, uint8_t* sigalg,
|
||||
char* reasonbuf, size_t reasonlen)
|
||||
{
|
||||
struct ub_packed_rrset_key pk;
|
||||
enum sec_status sec;
|
||||
@@ -7808,7 +7809,7 @@ static int zonemd_dnssec_verify_rrset(struct auth_zone* z,
|
||||
"zonemd: verify %s RRset with DNSKEY", typestr);
|
||||
}
|
||||
sec = dnskeyset_verify_rrset(env, ve, &pk, dnskey, sigalg, why_bogus, NULL,
|
||||
LDNS_SECTION_ANSWER, NULL, &verified);
|
||||
LDNS_SECTION_ANSWER, NULL, &verified, reasonbuf, reasonlen);
|
||||
if(sec == sec_status_secure) {
|
||||
return 1;
|
||||
}
|
||||
@@ -7851,7 +7852,8 @@ static int nsec3_of_param_has_type(struct auth_rrset* nsec3, int algo,
|
||||
static int zonemd_check_dnssec_absence(struct auth_zone* z,
|
||||
struct module_env* env, struct module_stack* mods,
|
||||
struct ub_packed_rrset_key* dnskey, struct auth_data* apex,
|
||||
char** reason, char** why_bogus, uint8_t* sigalg)
|
||||
char** reason, char** why_bogus, uint8_t* sigalg, char* reasonbuf,
|
||||
size_t reasonlen)
|
||||
{
|
||||
struct auth_rrset* nsec = NULL;
|
||||
if(!apex) {
|
||||
@@ -7863,7 +7865,7 @@ static int zonemd_check_dnssec_absence(struct auth_zone* z,
|
||||
struct ub_packed_rrset_key pk;
|
||||
/* dnssec verify the NSEC */
|
||||
if(!zonemd_dnssec_verify_rrset(z, env, mods, dnskey, apex,
|
||||
nsec, why_bogus, sigalg)) {
|
||||
nsec, why_bogus, sigalg, reasonbuf, reasonlen)) {
|
||||
*reason = "DNSSEC verify failed for NSEC RRset";
|
||||
return 0;
|
||||
}
|
||||
@@ -7906,7 +7908,7 @@ static int zonemd_check_dnssec_absence(struct auth_zone* z,
|
||||
}
|
||||
/* dnssec verify the NSEC3 */
|
||||
if(!zonemd_dnssec_verify_rrset(z, env, mods, dnskey, match,
|
||||
nsec3, why_bogus, sigalg)) {
|
||||
nsec3, why_bogus, sigalg, reasonbuf, reasonlen)) {
|
||||
*reason = "DNSSEC verify failed for NSEC3 RRset";
|
||||
return 0;
|
||||
}
|
||||
@@ -7928,7 +7930,7 @@ static int zonemd_check_dnssec_soazonemd(struct auth_zone* z,
|
||||
struct module_env* env, struct module_stack* mods,
|
||||
struct ub_packed_rrset_key* dnskey, struct auth_data* apex,
|
||||
struct auth_rrset* zonemd_rrset, char** reason, char** why_bogus,
|
||||
uint8_t* sigalg)
|
||||
uint8_t* sigalg, char* reasonbuf, size_t reasonlen)
|
||||
{
|
||||
struct auth_rrset* soa;
|
||||
if(!apex) {
|
||||
@@ -7941,12 +7943,12 @@ static int zonemd_check_dnssec_soazonemd(struct auth_zone* z,
|
||||
return 0;
|
||||
}
|
||||
if(!zonemd_dnssec_verify_rrset(z, env, mods, dnskey, apex, soa,
|
||||
why_bogus, sigalg)) {
|
||||
why_bogus, sigalg, reasonbuf, reasonlen)) {
|
||||
*reason = "DNSSEC verify failed for SOA RRset";
|
||||
return 0;
|
||||
}
|
||||
if(!zonemd_dnssec_verify_rrset(z, env, mods, dnskey, apex,
|
||||
zonemd_rrset, why_bogus, sigalg)) {
|
||||
zonemd_rrset, why_bogus, sigalg, reasonbuf, reasonlen)) {
|
||||
*reason = "DNSSEC verify failed for ZONEMD RRset";
|
||||
return 0;
|
||||
}
|
||||
@@ -8014,6 +8016,7 @@ auth_zone_verify_zonemd_with_key(struct auth_zone* z, struct module_env* env,
|
||||
struct module_stack* mods, struct ub_packed_rrset_key* dnskey,
|
||||
int is_insecure, char** result, uint8_t* sigalg)
|
||||
{
|
||||
char reasonbuf[256];
|
||||
char* reason = NULL, *why_bogus = NULL;
|
||||
struct auth_data* apex = NULL;
|
||||
struct auth_rrset* zonemd_rrset = NULL;
|
||||
@@ -8042,7 +8045,8 @@ auth_zone_verify_zonemd_with_key(struct auth_zone* z, struct module_env* env,
|
||||
} else if(!zonemd_rrset && dnskey && !is_insecure) {
|
||||
/* fetch, DNSSEC verify, and check NSEC/NSEC3 */
|
||||
if(!zonemd_check_dnssec_absence(z, env, mods, dnskey, apex,
|
||||
&reason, &why_bogus, sigalg)) {
|
||||
&reason, &why_bogus, sigalg, reasonbuf,
|
||||
sizeof(reasonbuf))) {
|
||||
auth_zone_zonemd_fail(z, env, reason, why_bogus, result);
|
||||
return;
|
||||
}
|
||||
@@ -8050,7 +8054,8 @@ auth_zone_verify_zonemd_with_key(struct auth_zone* z, struct module_env* env,
|
||||
} else if(zonemd_rrset && dnskey && !is_insecure) {
|
||||
/* check DNSSEC verify of SOA and ZONEMD */
|
||||
if(!zonemd_check_dnssec_soazonemd(z, env, mods, dnskey, apex,
|
||||
zonemd_rrset, &reason, &why_bogus, sigalg)) {
|
||||
zonemd_rrset, &reason, &why_bogus, sigalg, reasonbuf,
|
||||
sizeof(reasonbuf))) {
|
||||
auth_zone_zonemd_fail(z, env, reason, why_bogus, result);
|
||||
return;
|
||||
}
|
||||
@@ -8107,6 +8112,8 @@ auth_zone_verify_zonemd_with_key(struct auth_zone* z, struct module_env* env,
|
||||
* @param why_bogus: if the routine fails, returns the failure reason.
|
||||
* @param keystorage: where to store the ub_packed_rrset_key that is created
|
||||
* on success. A pointer to it is returned on success.
|
||||
* @param reasonbuf: buffer to use for fail reason string print.
|
||||
* @param reasonlen: length of reasonbuf.
|
||||
* @return the dnskey RRset, reference to zone data and keystorage, or
|
||||
* NULL on failure.
|
||||
*/
|
||||
@@ -8114,7 +8121,8 @@ static struct ub_packed_rrset_key*
|
||||
zonemd_get_dnskey_from_anchor(struct auth_zone* z, struct module_env* env,
|
||||
struct module_stack* mods, struct trust_anchor* anchor,
|
||||
int* is_insecure, char** why_bogus,
|
||||
struct ub_packed_rrset_key* keystorage)
|
||||
struct ub_packed_rrset_key* keystorage, char* reasonbuf,
|
||||
size_t reasonlen)
|
||||
{
|
||||
struct auth_data* apex;
|
||||
struct auth_rrset* dnskey_rrset;
|
||||
@@ -8150,7 +8158,8 @@ zonemd_get_dnskey_from_anchor(struct auth_zone* z, struct module_env* env,
|
||||
auth_zone_log(z->name, VERB_QUERY,
|
||||
"zonemd: verify DNSKEY RRset with trust anchor");
|
||||
sec = val_verify_DNSKEY_with_TA(env, ve, keystorage, anchor->ds_rrset,
|
||||
anchor->dnskey_rrset, NULL, why_bogus, NULL, NULL);
|
||||
anchor->dnskey_rrset, NULL, why_bogus, NULL, NULL, reasonbuf,
|
||||
reasonlen);
|
||||
regional_free_all(env->scratch);
|
||||
if(sec == sec_status_secure) {
|
||||
/* success */
|
||||
@@ -8173,7 +8182,8 @@ static struct ub_packed_rrset_key*
|
||||
auth_zone_verify_zonemd_key_with_ds(struct auth_zone* z,
|
||||
struct module_env* env, struct module_stack* mods,
|
||||
struct ub_packed_rrset_key* ds, int* is_insecure, char** why_bogus,
|
||||
struct ub_packed_rrset_key* keystorage, uint8_t* sigalg)
|
||||
struct ub_packed_rrset_key* keystorage, uint8_t* sigalg,
|
||||
char* reasonbuf, size_t reasonlen)
|
||||
{
|
||||
struct auth_data* apex;
|
||||
struct auth_rrset* dnskey_rrset;
|
||||
@@ -8209,7 +8219,7 @@ auth_zone_verify_zonemd_key_with_ds(struct auth_zone* z,
|
||||
keystorage->rk.rrset_class = htons(z->dclass);
|
||||
auth_zone_log(z->name, VERB_QUERY, "zonemd: verify zone DNSKEY with DS");
|
||||
sec = val_verify_DNSKEY_with_DS(env, ve, keystorage, ds, sigalg,
|
||||
why_bogus, NULL, NULL);
|
||||
why_bogus, NULL, NULL, reasonbuf, reasonlen);
|
||||
regional_free_all(env->scratch);
|
||||
if(sec == sec_status_secure) {
|
||||
/* success */
|
||||
@@ -8235,6 +8245,7 @@ void auth_zonemd_dnskey_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
|
||||
{
|
||||
struct auth_zone* z = (struct auth_zone*)arg;
|
||||
struct module_env* env;
|
||||
char reasonbuf[256];
|
||||
char* reason = NULL, *ds_bogus = NULL, *typestr="DNSKEY";
|
||||
struct ub_packed_rrset_key* dnskey = NULL, *ds = NULL;
|
||||
int is_insecure = 0, downprot;
|
||||
@@ -8346,7 +8357,8 @@ void auth_zonemd_dnskey_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
|
||||
if(!reason && !is_insecure && !dnskey && ds) {
|
||||
dnskey = auth_zone_verify_zonemd_key_with_ds(z, env,
|
||||
&env->mesh->mods, ds, &is_insecure, &ds_bogus,
|
||||
&keystorage, downprot?sigalg:NULL);
|
||||
&keystorage, downprot?sigalg:NULL, reasonbuf,
|
||||
sizeof(reasonbuf));
|
||||
if(!dnskey && !is_insecure && !reason)
|
||||
reason = "DNSKEY verify with DS failed";
|
||||
}
|
||||
@@ -8354,6 +8366,7 @@ void auth_zonemd_dnskey_lookup_callback(void* arg, int rcode, sldns_buffer* buf,
|
||||
if(reason) {
|
||||
auth_zone_zonemd_fail(z, env, reason, ds_bogus, NULL);
|
||||
lock_rw_unlock(&z->lock);
|
||||
regional_free_all(env->scratch);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -8438,6 +8451,7 @@ zonemd_lookup_dnskey(struct auth_zone* z, struct module_env* env)
|
||||
void auth_zone_verify_zonemd(struct auth_zone* z, struct module_env* env,
|
||||
struct module_stack* mods, char** result, int offline, int only_online)
|
||||
{
|
||||
char reasonbuf[256];
|
||||
char* reason = NULL, *why_bogus = NULL;
|
||||
struct trust_anchor* anchor = NULL;
|
||||
struct ub_packed_rrset_key* dnskey = NULL;
|
||||
@@ -8472,7 +8486,8 @@ void auth_zone_verify_zonemd(struct auth_zone* z, struct module_env* env,
|
||||
}
|
||||
/* equal to trustanchor, no need for online lookups */
|
||||
dnskey = zonemd_get_dnskey_from_anchor(z, env, mods, anchor,
|
||||
&is_insecure, &why_bogus, &keystorage);
|
||||
&is_insecure, &why_bogus, &keystorage, reasonbuf,
|
||||
sizeof(reasonbuf));
|
||||
lock_basic_unlock(&anchor->lock);
|
||||
if(!dnskey && !reason && !is_insecure) {
|
||||
reason = "verify DNSKEY RRset with trust anchor failed";
|
||||
@@ -8498,6 +8513,7 @@ void auth_zone_verify_zonemd(struct auth_zone* z, struct module_env* env,
|
||||
|
||||
if(reason) {
|
||||
auth_zone_zonemd_fail(z, env, reason, why_bogus, result);
|
||||
regional_free_all(env->scratch);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Vendored
+28
-5
@@ -96,7 +96,8 @@ store_rrsets(struct module_env* env, struct reply_info* rep, time_t now,
|
||||
struct ub_packed_rrset_key* ck;
|
||||
lock_rw_rdlock(&rep->ref[i].key->entry.lock);
|
||||
/* if deleted rrset, do not copy it */
|
||||
if(rep->ref[i].key->id == 0)
|
||||
if(rep->ref[i].key->id == 0 ||
|
||||
rep->ref[i].id != rep->ref[i].key->id)
|
||||
ck = NULL;
|
||||
else ck = packed_rrset_copy_region(
|
||||
rep->ref[i].key, region, now);
|
||||
@@ -109,14 +110,22 @@ store_rrsets(struct module_env* env, struct reply_info* rep, time_t now,
|
||||
/* no break: also copy key item */
|
||||
/* the line below is matched by gcc regex and silences
|
||||
* the fallthrough warning */
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 1: /* ref updated, item inserted */
|
||||
rep->rrsets[i] = rep->ref[i].key;
|
||||
/* ref was updated; make sure the message ttl is
|
||||
* updated to the minimum of the current rrsets. */
|
||||
lock_rw_rdlock(&rep->ref[i].key->entry.lock);
|
||||
/* if deleted, skip ttl update. */
|
||||
if(rep->ref[i].key->id != 0 &&
|
||||
rep->ref[i].id == rep->ref[i].key->id) {
|
||||
ttl = ((struct packed_rrset_data*)
|
||||
rep->rrsets[i]->entry.data)->ttl;
|
||||
if(ttl < min_ttl) min_ttl = ttl;
|
||||
}
|
||||
lock_rw_unlock(&rep->ref[i].key->entry.lock);
|
||||
}
|
||||
/* if ref was updated make sure the message ttl is updated to
|
||||
* the minimum of the current rrsets. */
|
||||
ttl = ((struct packed_rrset_data*)rep->rrsets[i]->entry.data)->ttl;
|
||||
if(ttl < min_ttl) min_ttl = ttl;
|
||||
}
|
||||
if(min_ttl < rep->ttl) {
|
||||
rep->ttl = min_ttl;
|
||||
@@ -337,6 +346,13 @@ find_add_addrs(struct module_env* env, uint16_t qclass,
|
||||
* not use dns64 translation */
|
||||
neg = msg_cache_lookup(env, ns->name, ns->namelen,
|
||||
LDNS_RR_TYPE_AAAA, qclass, 0, now, 0);
|
||||
/* Because recursion for lookup uses BIT_CD, check
|
||||
* for that so it stops the recursion lookup, if a
|
||||
* negative answer is cached. Because the cache uses
|
||||
* the CD flag for type AAAA. */
|
||||
if(!neg)
|
||||
neg = msg_cache_lookup(env, ns->name, ns->namelen,
|
||||
LDNS_RR_TYPE_AAAA, qclass, BIT_CD, now, 0);
|
||||
if(neg) {
|
||||
delegpt_add_neg_msg(dp, neg);
|
||||
lock_rw_unlock(&neg->entry.lock);
|
||||
@@ -396,6 +412,13 @@ cache_fill_missing(struct module_env* env, uint16_t qclass,
|
||||
* not use dns64 translation */
|
||||
neg = msg_cache_lookup(env, ns->name, ns->namelen,
|
||||
LDNS_RR_TYPE_AAAA, qclass, 0, now, 0);
|
||||
/* Because recursion for lookup uses BIT_CD, check
|
||||
* for that so it stops the recursion lookup, if a
|
||||
* negative answer is cached. Because the cache uses
|
||||
* the CD flag for type AAAA. */
|
||||
if(!neg)
|
||||
neg = msg_cache_lookup(env, ns->name, ns->namelen,
|
||||
LDNS_RR_TYPE_AAAA, qclass, BIT_CD, now, 0);
|
||||
if(neg) {
|
||||
delegpt_add_neg_msg(dp, neg);
|
||||
lock_rw_unlock(&neg->entry.lock);
|
||||
|
||||
Vendored
+2
@@ -357,6 +357,7 @@ infra_create(struct config_file* cfg)
|
||||
return NULL;
|
||||
}
|
||||
infra_ip_ratelimit = cfg->ip_ratelimit;
|
||||
infra_ip_ratelimit_cookie = cfg->ip_ratelimit_cookie;
|
||||
infra->client_ip_rates = slabhash_create(cfg->ip_ratelimit_slabs,
|
||||
INFRA_HOST_STARTSIZE, cfg->ip_ratelimit_size, &ip_rate_sizefunc,
|
||||
&ip_rate_compfunc, &ip_rate_delkeyfunc, &ip_rate_deldatafunc, NULL);
|
||||
@@ -408,6 +409,7 @@ infra_adjust(struct infra_cache* infra, struct config_file* cfg)
|
||||
infra->infra_keep_probing = cfg->infra_keep_probing;
|
||||
infra_dp_ratelimit = cfg->ratelimit;
|
||||
infra_ip_ratelimit = cfg->ip_ratelimit;
|
||||
infra_ip_ratelimit_cookie = cfg->ip_ratelimit_cookie;
|
||||
maxmem = cfg->infra_cache_numhosts * (sizeof(struct infra_key)+
|
||||
sizeof(struct infra_data)+INFRA_BYTES_NAME);
|
||||
/* divide cachesize by slabs and multiply by slabs, because if the
|
||||
|
||||
Vendored
+1
-1
@@ -234,7 +234,7 @@ struct infra_cache* infra_adjust(struct infra_cache* infra,
|
||||
struct config_file* cfg);
|
||||
|
||||
/**
|
||||
* Plain find infra data function (used by the the other functions)
|
||||
* Plain find infra data function (used by the other functions)
|
||||
* @param infra: infrastructure cache.
|
||||
* @param addr: host address.
|
||||
* @param addrlen: length of addr.
|
||||
|
||||
@@ -675,7 +675,7 @@ create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto,
|
||||
int* reuseport, int transparent, int mss, int nodelay, int freebind,
|
||||
int use_systemd, int dscp)
|
||||
{
|
||||
int s;
|
||||
int s = -1;
|
||||
char* err;
|
||||
#if defined(SO_REUSEADDR) || defined(SO_REUSEPORT) || defined(IPV6_V6ONLY) || defined(IP_TRANSPARENT) || defined(IP_BINDANY) || defined(IP_FREEBIND) || defined(SO_BINDANY)
|
||||
int on = 1;
|
||||
|
||||
+32
-9
@@ -413,6 +413,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
int timeout = mesh->env->cfg->serve_expired?
|
||||
mesh->env->cfg->serve_expired_client_timeout:0;
|
||||
struct sldns_buffer* r_buffer = rep->c->buffer;
|
||||
uint16_t mesh_flags = qflags&(BIT_RD|BIT_CD);
|
||||
if(rep->c->tcp_req_info) {
|
||||
r_buffer = rep->c->tcp_req_info->spool_buffer;
|
||||
}
|
||||
@@ -425,7 +426,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
return;
|
||||
}
|
||||
if(!unique)
|
||||
s = mesh_area_find(mesh, cinfo, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0);
|
||||
s = mesh_area_find(mesh, cinfo, qinfo, mesh_flags, 0, 0);
|
||||
/* does this create a new reply state? */
|
||||
if(!s || s->list_select == mesh_no_list) {
|
||||
if(!mesh_make_new_space(mesh, rep->c->buffer)) {
|
||||
@@ -453,7 +454,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
struct rbnode_type* n;
|
||||
#endif
|
||||
s = mesh_state_create(mesh->env, qinfo, cinfo,
|
||||
qflags&(BIT_RD|BIT_CD), 0, 0);
|
||||
mesh_flags, 0, 0);
|
||||
if(!s) {
|
||||
log_err("mesh_state_create: out of memory; SERVFAIL");
|
||||
if(!inplace_cb_reply_servfail_call(mesh->env, qinfo, NULL, NULL,
|
||||
@@ -565,6 +566,8 @@ servfail_mem:
|
||||
edns->opt_list_inplace_cb_out = NULL;
|
||||
error_encode(r_buffer, LDNS_RCODE_SERVFAIL,
|
||||
qinfo, qid, qflags, edns);
|
||||
if(rep->c->use_h2)
|
||||
http2_stream_remove_mesh_state(rep->c->h2_stream);
|
||||
comm_point_send_reply(rep);
|
||||
if(added)
|
||||
mesh_state_delete(&s->s);
|
||||
@@ -583,8 +586,9 @@ mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
int was_detached = 0;
|
||||
int was_noreply = 0;
|
||||
int added = 0;
|
||||
uint16_t mesh_flags = qflags&(BIT_RD|BIT_CD);
|
||||
if(!unique)
|
||||
s = mesh_area_find(mesh, NULL, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0);
|
||||
s = mesh_area_find(mesh, NULL, qinfo, mesh_flags, 0, 0);
|
||||
|
||||
/* there are no limits on the number of callbacks */
|
||||
|
||||
@@ -594,7 +598,7 @@ mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
struct rbnode_type* n;
|
||||
#endif
|
||||
s = mesh_state_create(mesh->env, qinfo, NULL,
|
||||
qflags&(BIT_RD|BIT_CD), 0, 0);
|
||||
mesh_flags, 0, 0);
|
||||
if(!s) {
|
||||
return 0;
|
||||
}
|
||||
@@ -673,8 +677,12 @@ static void mesh_schedule_prefetch(struct mesh_area* mesh,
|
||||
struct query_info* qinfo, uint16_t qflags, time_t leeway, int run,
|
||||
int rpz_passthru)
|
||||
{
|
||||
/* Explicitly set the BIT_RD regardless of the client's flags. This is
|
||||
* for a prefetch query (no client attached) but it needs to be treated
|
||||
* as a recursion query. */
|
||||
uint16_t mesh_flags = BIT_RD|(qflags&BIT_CD);
|
||||
struct mesh_state* s = mesh_area_find(mesh, NULL, qinfo,
|
||||
qflags&(BIT_RD|BIT_CD), 0, 0);
|
||||
mesh_flags, 0, 0);
|
||||
#ifdef UNBOUND_DEBUG
|
||||
struct rbnode_type* n;
|
||||
#endif
|
||||
@@ -694,8 +702,7 @@ static void mesh_schedule_prefetch(struct mesh_area* mesh,
|
||||
return;
|
||||
}
|
||||
|
||||
s = mesh_state_create(mesh->env, qinfo, NULL,
|
||||
qflags&(BIT_RD|BIT_CD), 0, 0);
|
||||
s = mesh_state_create(mesh->env, qinfo, NULL, mesh_flags, 0, 0);
|
||||
if(!s) {
|
||||
log_err("prefetch mesh_state_create: out of memory");
|
||||
return;
|
||||
@@ -756,14 +763,17 @@ static void mesh_schedule_prefetch_subnet(struct mesh_area* mesh,
|
||||
#ifdef UNBOUND_DEBUG
|
||||
struct rbnode_type* n;
|
||||
#endif
|
||||
/* Explicitly set the BIT_RD regardless of the client's flags. This is
|
||||
* for a prefetch query (no client attached) but it needs to be treated
|
||||
* as a recursion query. */
|
||||
uint16_t mesh_flags = BIT_RD|(qflags&BIT_CD);
|
||||
if(!mesh_make_new_space(mesh, NULL)) {
|
||||
verbose(VERB_ALGO, "Too many queries. dropped prefetch.");
|
||||
mesh->stats_dropped ++;
|
||||
return;
|
||||
}
|
||||
|
||||
s = mesh_state_create(mesh->env, qinfo, NULL,
|
||||
qflags&(BIT_RD|BIT_CD), 0, 0);
|
||||
s = mesh_state_create(mesh->env, qinfo, NULL, mesh_flags, 0, 0);
|
||||
if(!s) {
|
||||
log_err("prefetch_subnet mesh_state_create: out of memory");
|
||||
return;
|
||||
@@ -966,6 +976,8 @@ mesh_state_cleanup(struct mesh_state* mstate)
|
||||
for(; rep; rep=rep->next) {
|
||||
infra_wait_limit_dec(mesh->env->infra_cache,
|
||||
&rep->query_reply, mesh->env->cfg);
|
||||
if(rep->query_reply.c->use_h2)
|
||||
http2_stream_remove_mesh_state(rep->h2_stream);
|
||||
comm_point_drop_reply(&rep->query_reply);
|
||||
log_assert(mesh->num_reply_addrs > 0);
|
||||
mesh->num_reply_addrs--;
|
||||
@@ -1522,6 +1534,8 @@ void mesh_query_done(struct mesh_state* mstate)
|
||||
infra_wait_limit_dec(mstate->s.env->infra_cache,
|
||||
&r->query_reply, mstate->s.env->cfg);
|
||||
mstate->reply_list = NULL;
|
||||
if(r->query_reply.c->use_h2)
|
||||
http2_stream_remove_mesh_state(r->h2_stream);
|
||||
comm_point_drop_reply(&r->query_reply);
|
||||
mstate->reply_list = reply_list;
|
||||
mstate->s.env->mesh->stats_dropped++;
|
||||
@@ -1554,6 +1568,9 @@ void mesh_query_done(struct mesh_state* mstate)
|
||||
infra_wait_limit_dec(mstate->s.env->infra_cache,
|
||||
&r->query_reply, mstate->s.env->cfg);
|
||||
mstate->reply_list = NULL;
|
||||
if(r->query_reply.c->use_h2) {
|
||||
http2_stream_remove_mesh_state(r->h2_stream);
|
||||
}
|
||||
comm_point_drop_reply(&r->query_reply);
|
||||
mstate->reply_list = reply_list;
|
||||
} else {
|
||||
@@ -1568,6 +1585,8 @@ void mesh_query_done(struct mesh_state* mstate)
|
||||
tcp_req_info_remove_mesh_state(r->query_reply.c->tcp_req_info, mstate);
|
||||
r_buffer = NULL;
|
||||
}
|
||||
/* mesh_send_reply removed mesh state from
|
||||
* http2_stream. */
|
||||
prev = r;
|
||||
prev_buffer = r_buffer;
|
||||
}
|
||||
@@ -1720,6 +1739,7 @@ int mesh_state_add_reply(struct mesh_state* s, struct edns_data* edns,
|
||||
return 0;
|
||||
if(rep->c->use_h2)
|
||||
r->h2_stream = rep->c->h2_stream;
|
||||
else r->h2_stream = NULL;
|
||||
|
||||
/* Data related to local alias stored in 'qinfo' (if any) is ephemeral
|
||||
* and can be different for different original queries (even if the
|
||||
@@ -2243,6 +2263,8 @@ mesh_serve_expired_callback(void* arg)
|
||||
infra_wait_limit_dec(mstate->s.env->infra_cache,
|
||||
&r->query_reply, mstate->s.env->cfg);
|
||||
mstate->reply_list = NULL;
|
||||
if(r->query_reply.c->use_h2)
|
||||
http2_stream_remove_mesh_state(r->h2_stream);
|
||||
comm_point_drop_reply(&r->query_reply);
|
||||
mstate->reply_list = reply_list;
|
||||
mstate->s.env->mesh->stats_dropped++;
|
||||
@@ -2276,6 +2298,7 @@ mesh_serve_expired_callback(void* arg)
|
||||
r, r_buffer, prev, prev_buffer);
|
||||
if(r->query_reply.c->tcp_req_info)
|
||||
tcp_req_info_remove_mesh_state(r->query_reply.c->tcp_req_info, mstate);
|
||||
/* mesh_send_reply removed mesh state from http2_stream. */
|
||||
infra_wait_limit_dec(mstate->s.env->infra_cache,
|
||||
&r->query_reply, mstate->s.env->cfg);
|
||||
prev = r;
|
||||
|
||||
+69
-9
@@ -95,6 +95,16 @@ modstack_init(struct module_stack* stack)
|
||||
stack->mod = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
modstack_free(struct module_stack* stack)
|
||||
{
|
||||
if(!stack)
|
||||
return;
|
||||
stack->num = 0;
|
||||
free(stack->mod);
|
||||
stack->mod = NULL;
|
||||
}
|
||||
|
||||
int
|
||||
modstack_config(struct module_stack* stack, const char* module_conf)
|
||||
{
|
||||
@@ -222,18 +232,59 @@ module_func_block* module_factory(const char** str)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
modstack_setup(struct module_stack* stack, const char* module_conf,
|
||||
int
|
||||
modstack_call_startup(struct module_stack* stack, const char* module_conf,
|
||||
struct module_env* env)
|
||||
{
|
||||
int i;
|
||||
if(stack->num != 0)
|
||||
modstack_desetup(stack, env);
|
||||
fatal_exit("unexpected already initialised modules");
|
||||
/* fixed setup of the modules */
|
||||
if(!modstack_config(stack, module_conf)) {
|
||||
return 0;
|
||||
}
|
||||
for(i=0; i<stack->num; i++) {
|
||||
if(stack->mod[i]->startup == NULL)
|
||||
continue;
|
||||
verbose(VERB_OPS, "startup module %d: %s",
|
||||
i, stack->mod[i]->name);
|
||||
fptr_ok(fptr_whitelist_mod_startup(stack->mod[i]->startup));
|
||||
if(!(*stack->mod[i]->startup)(env, i)) {
|
||||
log_err("module startup for module %s failed",
|
||||
stack->mod[i]->name);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
modstack_call_init(struct module_stack* stack, const char* module_conf,
|
||||
struct module_env* env)
|
||||
{
|
||||
int i, changed = 0;
|
||||
env->need_to_validate = 0; /* set by module init below */
|
||||
for(i=0; i<stack->num; i++) {
|
||||
while(*module_conf && isspace(*module_conf))
|
||||
module_conf++;
|
||||
if(strncmp(stack->mod[i]->name, module_conf,
|
||||
strlen(stack->mod[i]->name))) {
|
||||
if(stack->mod[i]->startup || stack->mod[i]->destartup) {
|
||||
log_err("changed module ordering during reload not supported, for module that needs startup");
|
||||
return 0;
|
||||
} else {
|
||||
changed = 1;
|
||||
}
|
||||
}
|
||||
module_conf += strlen(stack->mod[i]->name);
|
||||
}
|
||||
if(changed) {
|
||||
modstack_free(stack);
|
||||
if(!modstack_config(stack, module_conf)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
for(i=0; i<stack->num; i++) {
|
||||
verbose(VERB_OPS, "init module %d: %s",
|
||||
i, stack->mod[i]->name);
|
||||
@@ -247,20 +298,29 @@ modstack_setup(struct module_stack* stack, const char* module_conf,
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
modstack_desetup(struct module_stack* stack, struct module_env* env)
|
||||
void
|
||||
modstack_call_deinit(struct module_stack* stack, struct module_env* env)
|
||||
{
|
||||
int i;
|
||||
for(i=0; i<stack->num; i++) {
|
||||
fptr_ok(fptr_whitelist_mod_deinit(stack->mod[i]->deinit));
|
||||
(*stack->mod[i]->deinit)(env, i);
|
||||
}
|
||||
stack->num = 0;
|
||||
free(stack->mod);
|
||||
stack->mod = NULL;
|
||||
}
|
||||
|
||||
int
|
||||
void
|
||||
modstack_call_destartup(struct module_stack* stack, struct module_env* env)
|
||||
{
|
||||
int i;
|
||||
for(i=0; i<stack->num; i++) {
|
||||
if(stack->mod[i]->destartup == NULL)
|
||||
continue;
|
||||
fptr_ok(fptr_whitelist_mod_destartup(stack->mod[i]->destartup));
|
||||
(*stack->mod[i]->destartup)(env, i);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
modstack_find(struct module_stack* stack, const char* name)
|
||||
{
|
||||
int i;
|
||||
|
||||
+31
-7
@@ -60,6 +60,23 @@ struct module_stack {
|
||||
*/
|
||||
void modstack_init(struct module_stack* stack);
|
||||
|
||||
/**
|
||||
* Free the stack of modules
|
||||
* @param stack: stack that frees up memory.
|
||||
*/
|
||||
void modstack_free(struct module_stack* stack);
|
||||
|
||||
/**
|
||||
* Initialises modules and assignes ids. Calls module_startup().
|
||||
* @param stack: Expected empty, filled according to module_conf
|
||||
* @param module_conf: string what modules to initialize
|
||||
* @param env: module environment which is inited by the modules.
|
||||
* environment should have a superalloc, cfg,
|
||||
* @return on false a module init failed.
|
||||
*/
|
||||
int modstack_call_startup(struct module_stack* stack, const char* module_conf,
|
||||
struct module_env* env);
|
||||
|
||||
/**
|
||||
* Read config file module settings and set up the modfunc block
|
||||
* @param stack: the stack of modules (empty before call).
|
||||
@@ -83,24 +100,31 @@ struct module_func_block* module_factory(const char** str);
|
||||
const char** module_list_avail(void);
|
||||
|
||||
/**
|
||||
* Setup modules. Assigns ids and calls module_init.
|
||||
* @param stack: if not empty beforehand, it will be desetup()ed.
|
||||
* It is then modstack_configged().
|
||||
* @param module_conf: string what modules to insert.
|
||||
* Init modules. Calls module_init().
|
||||
* @param stack: It is modstack_setupped().
|
||||
* @param module_conf: module ordering to check against the ordering in stack.
|
||||
* fails on changed ordering.
|
||||
* @param env: module environment which is inited by the modules.
|
||||
* environment should have a superalloc, cfg,
|
||||
* env.need_to_validate is set by the modules.
|
||||
* @return on false a module init failed.
|
||||
*/
|
||||
int modstack_setup(struct module_stack* stack, const char* module_conf,
|
||||
int modstack_call_init(struct module_stack* stack, const char* module_conf,
|
||||
struct module_env* env);
|
||||
|
||||
/**
|
||||
* Desetup the modules, deinit, delete.
|
||||
* Deinit the modules.
|
||||
* @param stack: made empty.
|
||||
* @param env: module env for module deinit() calls.
|
||||
*/
|
||||
void modstack_desetup(struct module_stack* stack, struct module_env* env);
|
||||
void modstack_call_deinit(struct module_stack* stack, struct module_env* env);
|
||||
|
||||
/**
|
||||
* Destartup the modules, close, delete.
|
||||
* @param stack: made empty.
|
||||
* @param env: module env for module destartup() calls.
|
||||
*/
|
||||
void modstack_call_destartup(struct module_stack* stack, struct module_env* env);
|
||||
|
||||
/**
|
||||
* Find index of module by name.
|
||||
|
||||
@@ -3466,7 +3466,10 @@ outnet_serviced_query(struct outside_network* outnet,
|
||||
timenow = *env->now;
|
||||
if(!infra_ratelimit_inc(env->infra_cache, zone,
|
||||
zonelen, timenow, env->cfg->ratelimit_backoff,
|
||||
&qstate->qinfo, qstate->reply)) {
|
||||
&qstate->qinfo,
|
||||
qstate->mesh_info->reply_list
|
||||
?&qstate->mesh_info->reply_list->query_reply
|
||||
:NULL)) {
|
||||
/* Can we pass through with slip factor? */
|
||||
if(env->cfg->ratelimit_factor == 0 ||
|
||||
ub_random_max(env->rnd,
|
||||
|
||||
+18
-6
@@ -242,10 +242,14 @@ rpz_action_to_localzone_type(enum rpz_action a)
|
||||
case RPZ_NODATA_ACTION: return local_zone_always_nodata;
|
||||
case RPZ_DROP_ACTION: return local_zone_always_deny;
|
||||
case RPZ_PASSTHRU_ACTION: return local_zone_always_transparent;
|
||||
case RPZ_LOCAL_DATA_ACTION: /* fallthrough */
|
||||
case RPZ_LOCAL_DATA_ACTION:
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case RPZ_CNAME_OVERRIDE_ACTION: return local_zone_redirect;
|
||||
case RPZ_TCP_ONLY_ACTION: return local_zone_truncate;
|
||||
case RPZ_INVALID_ACTION: /* fallthrough */
|
||||
case RPZ_INVALID_ACTION:
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
default: return local_zone_invalid;
|
||||
}
|
||||
}
|
||||
@@ -258,10 +262,14 @@ rpz_action_to_respip_action(enum rpz_action a)
|
||||
case RPZ_NODATA_ACTION: return respip_always_nodata;
|
||||
case RPZ_DROP_ACTION: return respip_always_deny;
|
||||
case RPZ_PASSTHRU_ACTION: return respip_always_transparent;
|
||||
case RPZ_LOCAL_DATA_ACTION: /* fallthrough */
|
||||
case RPZ_LOCAL_DATA_ACTION:
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case RPZ_CNAME_OVERRIDE_ACTION: return respip_redirect;
|
||||
case RPZ_TCP_ONLY_ACTION: return respip_truncate;
|
||||
case RPZ_INVALID_ACTION: /* fallthrough */
|
||||
case RPZ_INVALID_ACTION:
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
default: return respip_invalid;
|
||||
}
|
||||
}
|
||||
@@ -276,7 +284,9 @@ localzone_type_to_rpz_action(enum localzone_type lzt)
|
||||
case local_zone_always_transparent: return RPZ_PASSTHRU_ACTION;
|
||||
case local_zone_redirect: return RPZ_LOCAL_DATA_ACTION;
|
||||
case local_zone_truncate: return RPZ_TCP_ONLY_ACTION;
|
||||
case local_zone_invalid: /* fallthrough */
|
||||
case local_zone_invalid:
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
default: return RPZ_INVALID_ACTION;
|
||||
}
|
||||
}
|
||||
@@ -291,7 +301,9 @@ respip_action_to_rpz_action(enum respip_action a)
|
||||
case respip_always_transparent: return RPZ_PASSTHRU_ACTION;
|
||||
case respip_redirect: return RPZ_LOCAL_DATA_ACTION;
|
||||
case respip_truncate: return RPZ_TCP_ONLY_ACTION;
|
||||
case respip_invalid: /* fallthrough */
|
||||
case respip_invalid:
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
default: return RPZ_INVALID_ACTION;
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -106,7 +106,7 @@ ssize_t sldns_bget_token(struct sldns_buffer *b, char *token, const char *delim,
|
||||
* \param[in] k_del keyword delimiter
|
||||
* \param[out] data the data found
|
||||
* \param[in] d_del the data delimiter
|
||||
* \param[in] data_limit maximum size the the data buffer
|
||||
* \param[in] data_limit maximum size the data buffer
|
||||
* \return the number of character read
|
||||
*/
|
||||
ssize_t sldns_fget_keyword_data(FILE *f, const char *keyword, const char *k_del, char *data, const char *d_del, size_t data_limit);
|
||||
@@ -119,7 +119,7 @@ ssize_t sldns_fget_keyword_data(FILE *f, const char *keyword, const char *k_del,
|
||||
* \param[in] k_del keyword delimiter
|
||||
* \param[out] data the data found
|
||||
* \param[in] d_del the data delimiter
|
||||
* \param[in] data_limit maximum size the the data buffer
|
||||
* \param[in] data_limit maximum size the data buffer
|
||||
* \param[in] line_nr pointer to an integer containing the current line number (for
|
||||
debugging purposes)
|
||||
* \return the number of character read
|
||||
@@ -134,7 +134,7 @@ ssize_t sldns_fget_keyword_data_l(FILE *f, const char *keyword, const char *k_de
|
||||
* \param[in] k_del keyword delimiter
|
||||
* \param[out] data the data found
|
||||
* \param[in] d_del the data delimiter
|
||||
* \param[in] data_limit maximum size the the data buffer
|
||||
* \param[in] data_limit maximum size the data buffer
|
||||
* \return the number of character read
|
||||
*/
|
||||
ssize_t sldns_bget_keyword_data(struct sldns_buffer *b, const char *keyword, const char *k_del, char *data, const char *d_del, size_t data_limit);
|
||||
|
||||
@@ -436,11 +436,13 @@ sldns_b32_ntop_base(const uint8_t* src, size_t src_sz, char* dst, size_t dst_sz,
|
||||
|
||||
/* ........ ........ ....4444 4....... ........ */
|
||||
c = src[3] >> 7 ;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 3: dst[4] = b32[(src[2] & 0x0f) << 1 | c];
|
||||
|
||||
/* ........ .......3 3333.... ........ ........ */
|
||||
c = src[2] >> 4 ;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 2: dst[3] = b32[(src[1] & 0x01) << 4 | c];
|
||||
|
||||
@@ -449,6 +451,7 @@ sldns_b32_ntop_base(const uint8_t* src, size_t src_sz, char* dst, size_t dst_sz,
|
||||
|
||||
/* .....111 11...... ........ ........ ........ */
|
||||
c = src[1] >> 6 ;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 1: dst[1] = b32[(src[0] & 0x07) << 2 | c];
|
||||
|
||||
@@ -460,11 +463,14 @@ sldns_b32_ntop_base(const uint8_t* src, size_t src_sz, char* dst, size_t dst_sz,
|
||||
switch (src_sz) {
|
||||
case 1: dst[2] = '=';
|
||||
dst[3] = '=';
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 2: dst[4] = '=';
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 3: dst[5] = '=';
|
||||
dst[6] = '=';
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case 4: dst[7] = '=';
|
||||
}
|
||||
@@ -577,17 +583,20 @@ sldns_b32_pton_base(const char* src, size_t src_sz, uint8_t* dst, size_t dst_sz,
|
||||
/* ........ ........ ........ .55555.. ........ */
|
||||
/* ........ ........ ....4444 4....... ........ */
|
||||
dst[3] = buf[4] << 7 | buf[5] << 2 | buf[6] >> 3;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
|
||||
case 5: /* ........ ........ ....4444 4....... ........ */
|
||||
/* ........ .......3 3333.... ........ ........ */
|
||||
dst[2] = buf[3] << 4 | buf[4] >> 1;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
|
||||
case 4: /* ........ .......3 3333.... ........ ........ */
|
||||
/* ........ ..22222. ........ ........ ........ */
|
||||
/* .....111 11...... ........ ........ ........ */
|
||||
dst[1] = buf[1] << 6 | buf[2] << 1 | buf[3] >> 4;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
|
||||
case 2: /* .....111 11...... ........ ........ ........ */
|
||||
|
||||
@@ -470,6 +470,11 @@ enum sldns_enum_ede_code
|
||||
LDNS_EDE_NO_REACHABLE_AUTHORITY = 22,
|
||||
LDNS_EDE_NETWORK_ERROR = 23,
|
||||
LDNS_EDE_INVALID_DATA = 24,
|
||||
LDNS_EDE_SIGNATURE_EXPIRED_BEFORE_VALID = 25,
|
||||
LDNS_EDE_TOO_EARLY = 26,
|
||||
LDNS_EDE_UNSUPPORTED_NSEC3_ITERATIONS = 27,
|
||||
LDNS_EDE_BADPROXYPOLICY = 28,
|
||||
LDNS_EDE_SYNTHESIZED = 29
|
||||
};
|
||||
typedef enum sldns_enum_ede_code sldns_ede_code;
|
||||
|
||||
|
||||
@@ -228,6 +228,11 @@ static sldns_lookup_table sldns_edns_ede_codes_data[] = {
|
||||
{ LDNS_EDE_NO_REACHABLE_AUTHORITY, "No Reachable Authority" },
|
||||
{ LDNS_EDE_NETWORK_ERROR, "Network Error" },
|
||||
{ LDNS_EDE_INVALID_DATA, "Invalid Data" },
|
||||
{ LDNS_EDE_SIGNATURE_EXPIRED_BEFORE_VALID, "Signature Expired Before Valid" },
|
||||
{ LDNS_EDE_TOO_EARLY, "Non-Replayable Transactions Received in 0-RTT Data" },
|
||||
{ LDNS_EDE_UNSUPPORTED_NSEC3_ITERATIONS, "Unsupported NSEC3 Iterations Value" },
|
||||
{ LDNS_EDE_BADPROXYPOLICY, "Unable to Conform to Policy" },
|
||||
{ LDNS_EDE_SYNTHESIZED, "Synthesized Answer" },
|
||||
{ 0, NULL}
|
||||
};
|
||||
sldns_lookup_table* sldns_edns_ede_codes = sldns_edns_ede_codes_data;
|
||||
@@ -1236,6 +1241,7 @@ int sldns_wire2str_svcparam_scan(uint8_t** d, size_t* dlen, char** s, size_t* sl
|
||||
r = sldns_wire2str_svcparam_ech2str(s, slen, data_len, *d);
|
||||
break;
|
||||
case SVCB_KEY_DOHPATH:
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
default:
|
||||
r = sldns_str_print(s, slen, "=\"");
|
||||
|
||||
@@ -151,7 +151,7 @@
|
||||
#define HTTPS_PORT 443
|
||||
|
||||
#ifdef USE_WINSOCK
|
||||
/* sneakily reuse the the wsa_strerror function, on windows */
|
||||
/* sneakily reuse the wsa_strerror function, on windows */
|
||||
char* wsa_strerror(int err);
|
||||
#endif
|
||||
|
||||
@@ -183,7 +183,9 @@ static const char DS_TRUST_ANCHOR[] =
|
||||
/* The anchors must start on a new line with ". IN DS and end with \n"[;]
|
||||
* because the makedist script greps on the source here */
|
||||
/* anchor 20326 is from 2017 */
|
||||
". IN DS 20326 8 2 E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D\n";
|
||||
". IN DS 20326 8 2 E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D\n"
|
||||
/* anchor 38696 is from 2024 */
|
||||
". IN DS 38696 8 2 683D2D0ACB8C9B712A1948B27F741219298D0A450D612C483AF444A4C0FB2B16\n";
|
||||
|
||||
/** verbosity for this application */
|
||||
static int verb = 0;
|
||||
@@ -805,7 +807,11 @@ TLS_initiate(SSL_CTX* sslctx, int fd, const char* urlname, int use_sni)
|
||||
}
|
||||
/* wants to be called again */
|
||||
}
|
||||
#ifdef HAVE_SSL_GET1_PEER_CERTIFICATE
|
||||
x = SSL_get1_peer_certificate(ssl);
|
||||
#else
|
||||
x = SSL_get_peer_certificate(ssl);
|
||||
#endif
|
||||
if(!x) {
|
||||
if(verb) printf("Server presented no peer certificate\n");
|
||||
SSL_free(ssl);
|
||||
|
||||
@@ -140,10 +140,13 @@ check_mod(struct config_file* cfg, struct module_func_block* fb)
|
||||
fatal_exit("out of memory");
|
||||
if(!edns_known_options_init(&env))
|
||||
fatal_exit("out of memory");
|
||||
if(!(*fb->init)(&env, 0)) {
|
||||
fatal_exit("bad config for %s module", fb->name);
|
||||
}
|
||||
if(fb->startup && !(*fb->startup)(&env, 0))
|
||||
fatal_exit("bad config during startup for %s module", fb->name);
|
||||
if(!(*fb->init)(&env, 0))
|
||||
fatal_exit("bad config during init for %s module", fb->name);
|
||||
(*fb->deinit)(&env, 0);
|
||||
if(fb->destartup)
|
||||
(*fb->destartup)(&env, 0);
|
||||
sldns_buffer_free(env.scratch_buffer);
|
||||
regional_destroy(env.scratch);
|
||||
edns_known_options_delete(&env);
|
||||
|
||||
@@ -186,6 +186,10 @@ usage(void)
|
||||
printf(" rpz_enable zone Enable the RPZ zone if it had previously\n");
|
||||
printf(" been disabled\n");
|
||||
printf(" rpz_disable zone Disable the RPZ zone\n");
|
||||
printf(" add_cookie_secret <secret> add (or replace) a new cookie secret <secret>\n");
|
||||
printf(" drop_cookie_secret drop a staging cookie secret\n");
|
||||
printf(" activate_cookie_secret make a staging cookie secret active\n");
|
||||
printf(" print_cookie_secrets show all cookie secrets with their status\n");
|
||||
printf("Version %s\n", PACKAGE_VERSION);
|
||||
printf("BSD licensed, see LICENSE in source package for details.\n");
|
||||
printf("Report bugs to %s\n", PACKAGE_BUGREPORT);
|
||||
@@ -759,7 +763,11 @@ setup_ssl(SSL_CTX* ctx, int fd)
|
||||
/* check authenticity of server */
|
||||
if(SSL_get_verify_result(ssl) != X509_V_OK)
|
||||
ssl_err("SSL verification failed");
|
||||
#ifdef HAVE_SSL_GET1_PEER_CERTIFICATE
|
||||
x = SSL_get1_peer_certificate(ssl);
|
||||
#else
|
||||
x = SSL_get_peer_certificate(ssl);
|
||||
#endif
|
||||
if(!x)
|
||||
ssl_err("Server presented no peer certificate");
|
||||
X509_free(x);
|
||||
|
||||
+8
-6
@@ -2,17 +2,19 @@
|
||||
# Copyright 2015, Sami Kerola, CloudFlare.
|
||||
# BSD licensed.
|
||||
AC_ARG_ENABLE([systemd],
|
||||
[AS_HELP_STRING([--enable-systemd], [compile with systemd support])],
|
||||
[AS_HELP_STRING([--enable-systemd], [compile with systemd support (requires libsystemd, pkg-config)])],
|
||||
[], [enable_systemd=no])
|
||||
have_systemd=no
|
||||
AS_IF([test "x$enable_systemd" != xno], [
|
||||
ifdef([PKG_CHECK_MODULES], [
|
||||
if test -n "$PKG_CONFIG"; then
|
||||
dnl systemd v209 or newer
|
||||
PKG_CHECK_MODULES([SYSTEMD], [libsystemd], [have_systemd=yes], [have_systemd=no])
|
||||
have_systemd=no
|
||||
PKG_CHECK_MODULES([SYSTEMD], [libsystemd], [have_systemd=yes], [])
|
||||
dnl old systemd library
|
||||
AS_IF([test "x$have_systemd" != "xyes"], [
|
||||
have_systemd_daemon=no
|
||||
PKG_CHECK_MODULES([SYSTEMD_DAEMON], [libsystemd-daemon],
|
||||
[have_systemd_daemon=yes], [have_systemd_daemon=no])
|
||||
[have_systemd_daemon=yes], [])
|
||||
AS_IF([test "x$have_systemd_daemon" = "xyes"],
|
||||
[have_systemd=yes])
|
||||
])
|
||||
@@ -24,8 +26,8 @@ AS_IF([test "x$enable_systemd" != xno], [
|
||||
LIBS="$LIBS $SYSTEMD_LIBS"
|
||||
]
|
||||
)
|
||||
], [
|
||||
else
|
||||
AC_MSG_ERROR([systemd enabled but need pkg-config to configure for it])
|
||||
])
|
||||
fi
|
||||
])
|
||||
AM_CONDITIONAL([USE_SYSTEMD], [test "x$have_systemd" = xyes])
|
||||
|
||||
@@ -1655,6 +1655,12 @@ void comm_timer_set(struct comm_timer* timer, struct timeval* tv)
|
||||
timeval_add(&t->tv, &t->runtime->now_tv);
|
||||
}
|
||||
|
||||
int comm_timer_is_set(struct comm_timer* timer)
|
||||
{
|
||||
struct fake_timer* t = (struct fake_timer*)timer;
|
||||
return t->enabled;
|
||||
}
|
||||
|
||||
void comm_timer_delete(struct comm_timer* timer)
|
||||
{
|
||||
struct fake_timer* t = (struct fake_timer*)timer;
|
||||
@@ -1978,4 +1984,8 @@ void http2_stream_add_meshstate(struct http2_stream* ATTR_UNUSED(h2_stream),
|
||||
{
|
||||
}
|
||||
|
||||
void http2_stream_remove_mesh_state(struct http2_stream* ATTR_UNUSED(h2_stream))
|
||||
{
|
||||
}
|
||||
|
||||
/*********** End of Dummy routines ***********/
|
||||
|
||||
@@ -127,6 +127,7 @@ dir=$name.$$
|
||||
result=result.$name
|
||||
done=.done-$name
|
||||
skip=.skip-$name
|
||||
asan_text="SUMMARY: AddressSanitizer"
|
||||
success="no"
|
||||
if test -x "`which bash`"; then
|
||||
shell="bash"
|
||||
@@ -200,6 +201,16 @@ if test -f $name.post -a ! -f ../$skip; then
|
||||
echo "Warning: $name.post did not exit successfully"
|
||||
fi
|
||||
fi
|
||||
# Check if there were any AddressSanitizer errors
|
||||
# if compiled with -fsanitize=address
|
||||
if grep "$asan_text" $result >/dev/null 2>&1; then
|
||||
if test -f ../$done; then
|
||||
rm ../$done
|
||||
fi
|
||||
echo "$name: FAILED (AddressSanitizer)" >> $result
|
||||
echo "$name: FAILED (AddressSanitizer)"
|
||||
success="no"
|
||||
fi
|
||||
echo "DateRunEnd: "`date "+%s" 2>/dev/null` >> $result
|
||||
|
||||
mv $result ..
|
||||
|
||||
+1
-1
@@ -256,7 +256,7 @@ setup_ctx(char* key, char* cert)
|
||||
#if HAVE_DECL_SSL_CTX_SET_ECDH_AUTO
|
||||
if (!SSL_CTX_set_ecdh_auto(ctx,1))
|
||||
if(verb>=1) printf("failed to set_ecdh_auto, not enabling ECDHE\n");
|
||||
#elif defined(USE_ECDSA)
|
||||
#elif defined(USE_ECDSA) && defined(HAVE_SSL_CTX_SET_TMP_ECDH)
|
||||
if(1) {
|
||||
EC_KEY *ecdh = EC_KEY_new_by_curve_name (NID_X9_62_prime256v1);
|
||||
if (!ecdh) {
|
||||
|
||||
@@ -45,7 +45,6 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include "sldns/str2wire.h"
|
||||
#include "sldns/wire2str.h"
|
||||
|
||||
|
||||
@@ -471,7 +471,11 @@ send_em(const char* svr, const char* pp2_client, int udp, int usessl,
|
||||
}
|
||||
}
|
||||
if(1) {
|
||||
#ifdef HAVE_SSL_GET1_PEER_CERTIFICATE
|
||||
X509* x = SSL_get1_peer_certificate(ssl);
|
||||
#else
|
||||
X509* x = SSL_get_peer_certificate(ssl);
|
||||
#endif
|
||||
if(!x) printf("SSL: no peer certificate\n");
|
||||
else {
|
||||
X509_print_fp(stdout, x);
|
||||
|
||||
@@ -72,23 +72,6 @@ int daemon_main(int argc, char* argv[]);
|
||||
/** config files (removed at exit) */
|
||||
static struct config_strlist* cfgfiles = NULL;
|
||||
|
||||
#ifdef UNBOUND_ALLOC_STATS
|
||||
# define strdup(s) unbound_stat_strdup_log(s, __FILE__, __LINE__, __func__)
|
||||
char* unbound_stat_strdup_log(char* s, const char* file, int line,
|
||||
const char* func);
|
||||
char* unbound_stat_strdup_log(char* s, const char* file, int line,
|
||||
const char* func) {
|
||||
char* result;
|
||||
size_t len;
|
||||
if(!s) return NULL;
|
||||
len = strlen(s);
|
||||
log_info("%s:%d %s strdup(%u)", file, line, func, (unsigned)len+1);
|
||||
result = unbound_stat_malloc(len+1);
|
||||
memmove(result, s, len+1);
|
||||
return result;
|
||||
}
|
||||
#endif /* UNBOUND_ALLOC_STATS */
|
||||
|
||||
/** give commandline usage for testbound. */
|
||||
static void
|
||||
testbound_usage(void)
|
||||
|
||||
+1
-1
@@ -1117,7 +1117,7 @@ static void edns_ede_encode_encodedecode(struct query_info* qinfo,
|
||||
sldns_buffer_skip(pkt, 2 + 2);
|
||||
/* decode */
|
||||
unit_assert(parse_edns_from_query_pkt(pkt, edns, NULL, NULL, NULL, 0,
|
||||
region) == 0);
|
||||
region, NULL) == 0);
|
||||
}
|
||||
|
||||
static void edns_ede_encode_check(struct edns_data* edns, int* found_ede,
|
||||
|
||||
@@ -178,6 +178,7 @@ verifytest_rrset(struct module_env* env, struct val_env* ve,
|
||||
struct query_info* qinfo)
|
||||
{
|
||||
enum sec_status sec;
|
||||
char reasonbuf[256];
|
||||
char* reason = NULL;
|
||||
uint8_t sigalg[ALGO_NEEDS_MAX+1];
|
||||
int verified = 0;
|
||||
@@ -188,8 +189,9 @@ verifytest_rrset(struct module_env* env, struct val_env* ve,
|
||||
}
|
||||
setup_sigalg(dnskey, sigalg); /* check all algorithms in the dnskey */
|
||||
/* ok to give null as qstate here, won't be used for answer section. */
|
||||
sec = dnskeyset_verify_rrset(env, ve, rrset, dnskey, sigalg, &reason, NULL,
|
||||
LDNS_SECTION_ANSWER, NULL, &verified);
|
||||
sec = dnskeyset_verify_rrset(env, ve, rrset, dnskey, sigalg, &reason,
|
||||
NULL, LDNS_SECTION_ANSWER, NULL, &verified, reasonbuf,
|
||||
sizeof(reasonbuf));
|
||||
if(vsig) {
|
||||
printf("verify outcome is: %s %s\n", sec_status_to_string(sec),
|
||||
reason?reason:"");
|
||||
|
||||
@@ -256,7 +256,6 @@ static void zonemd_verify_test(char* zname, char* zfile, char* tastr,
|
||||
struct auth_zone* z;
|
||||
|
||||
/* setup test harness */
|
||||
memset(&mods, 0, sizeof(mods));
|
||||
memset(&env, 0, sizeof(env));
|
||||
env.scratch = regional_create();
|
||||
if(!env.scratch)
|
||||
@@ -288,8 +287,10 @@ static void zonemd_verify_test(char* zname, char* zfile, char* tastr,
|
||||
if(!env.auth_zones)
|
||||
fatal_exit("out of memory");
|
||||
modstack_init(&mods);
|
||||
if(!modstack_setup(&mods, env.cfg->module_conf, &env))
|
||||
fatal_exit("could not modstack_setup");
|
||||
if(!modstack_call_startup(&mods, env.cfg->module_conf, &env))
|
||||
fatal_exit("could not modstack_startup");
|
||||
if(!modstack_call_init(&mods, env.cfg->module_conf, &env))
|
||||
fatal_exit("could not modstack_call_init");
|
||||
env.mesh = mesh_create(&mods, &env);
|
||||
if(!env.mesh)
|
||||
fatal_exit("out of memory");
|
||||
@@ -327,7 +328,9 @@ static void zonemd_verify_test(char* zname, char* zfile, char* tastr,
|
||||
|
||||
/* desetup test harness */
|
||||
mesh_delete(env.mesh);
|
||||
modstack_desetup(&mods, &env);
|
||||
modstack_call_deinit(&mods, &env);
|
||||
modstack_call_destartup(&mods, &env);
|
||||
modstack_free(&mods);
|
||||
auth_zones_delete(env.auth_zones);
|
||||
anchors_delete(env.anchors);
|
||||
config_delete(env.cfg);
|
||||
|
||||
+55
-43
@@ -7,57 +7,69 @@
|
||||
. ../common.sh
|
||||
PRE="../.."
|
||||
get_make
|
||||
(cd $PRE ; $MAKE unittest; $MAKE lock-verify)
|
||||
(cd $PRE ; $MAKE unittest; $MAKE lock-verify; $MAKE unbound-dnstap-socket)
|
||||
|
||||
if test -f $PRE/unbound_do_valgrind_in_test; then
|
||||
do_valgrind=yes
|
||||
DO_VALGRIND=yes
|
||||
else
|
||||
do_valgrind=no
|
||||
DO_VALGRIND=no
|
||||
fi
|
||||
VALGRIND_FLAGS="--leak-check=full --show-leak-kinds=all"
|
||||
|
||||
if test $do_valgrind = "yes"; then
|
||||
echo "valgrind yes"
|
||||
echo
|
||||
tmpout=/tmp/tmpout.$$
|
||||
if (cd $PRE; valgrind $VALGRIND_FLAGS ./unittest >$tmpout 2>&1); then
|
||||
echo "unit test worked."
|
||||
# Run a unit test; it exits on failure
|
||||
# $1: the command to start the unit test
|
||||
run_unittest () {
|
||||
unit_cmd=$1
|
||||
echo "> testing $unit_cmd"
|
||||
if test $DO_VALGRIND = "yes"; then
|
||||
echo "valgrind yes"
|
||||
echo
|
||||
tmpout=/tmp/tmpout.$$
|
||||
if (cd $PRE; valgrind $VALGRIND_FLAGS ./$unit_cmd >$tmpout 2>&1); then
|
||||
echo "unit test worked."
|
||||
else
|
||||
echo "unit test failed."
|
||||
exit 1
|
||||
fi
|
||||
if grep "All heap blocks were freed -- no leaks are possible" $tmpout; then
|
||||
: # clean
|
||||
else
|
||||
cat $tmpout
|
||||
echo "Memory leaked in unit test"
|
||||
grep "in use at exit" $tmpout
|
||||
exit 1
|
||||
fi
|
||||
if grep "ERROR SUMMARY: 0 errors from 0 contexts" $tmpout; then
|
||||
: # clean
|
||||
else
|
||||
cat $tmpout
|
||||
echo "Errors in unit test"
|
||||
grep "ERROR SUMMARY" $tmpout
|
||||
exit 1
|
||||
fi
|
||||
rm -f $tmpout
|
||||
else
|
||||
echo "unit test failed."
|
||||
exit 1
|
||||
# without valgrind
|
||||
if (cd $PRE; ./$unit_cmd); then
|
||||
echo "unit test worked."
|
||||
else
|
||||
echo "unit test failed."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
if grep "All heap blocks were freed -- no leaks are possible" $tmpout; then
|
||||
: # clean
|
||||
else
|
||||
cat $tmpout
|
||||
echo "Memory leaked in unittest"
|
||||
grep "in use at exit" $tmpout
|
||||
exit 1
|
||||
fi
|
||||
if grep "ERROR SUMMARY: 0 errors from 0 contexts" $tmpout; then
|
||||
: # clean
|
||||
else
|
||||
cat $tmpout
|
||||
echo "Errors in unittest"
|
||||
grep "ERROR SUMMARY" $tmpout
|
||||
exit 1
|
||||
fi
|
||||
rm -f $tmpout
|
||||
else
|
||||
# without valgrind
|
||||
if (cd $PRE; ./unittest); then
|
||||
echo "unit test worked."
|
||||
else
|
||||
echo "unit test failed."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
if test -f $PRE/ublocktrace.0; then
|
||||
if (cd $PRE; ./lock-verify ublocktrace.*); then
|
||||
echo "lock-verify test worked."
|
||||
else
|
||||
echo "lock-verify test failed."
|
||||
exit 1
|
||||
if test -f $PRE/ublocktrace.0; then
|
||||
if (cd $PRE; ./lock-verify ublocktrace.*); then
|
||||
echo "lock-verify test worked."
|
||||
else
|
||||
echo "lock-verify test failed."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
run_unittest "unittest"
|
||||
if grep "define UNBOUND_DEBUG" $PRE/config.h >/dev/null; then
|
||||
run_unittest "unbound-dnstap-socket -c"
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
+50
-16
@@ -73,12 +73,53 @@ control_command () {
|
||||
$PRE/unbound-control $@ > outfile
|
||||
}
|
||||
|
||||
# Reload the server and check the reload has finished processing
|
||||
# when a lot of debug is enabled, a lot of log needs to be printed.
|
||||
control_reload () {
|
||||
prelines=`wc -l unbound.log | awk '{print $1;}'`
|
||||
cmd="$1"
|
||||
if test -z "$cmd"; then cmd="reload"; fi
|
||||
control_command -c ub.conf $cmd
|
||||
expect_exit_value 0
|
||||
# see if the reload has completed.
|
||||
lines1=`wc -l unbound.log | awk '{print $1;}'`
|
||||
count=0
|
||||
lines2=`wc -l unbound.log | awk '{print $1;}'`
|
||||
# See if the log finishes up without sleeping too long.
|
||||
while test "$lines1" -ne "$lines2"; do
|
||||
lines1=`wc -l unbound.log | awk '{print $1;}'`
|
||||
# There is no sleep here. The add and compare are a
|
||||
# brief wait.
|
||||
count=`expr "$count" + 1`
|
||||
if test "$count" -gt 30; then
|
||||
break;
|
||||
fi
|
||||
lines2=`wc -l unbound.log | awk '{print $1;}'`
|
||||
done
|
||||
if test "$lines1" -ne "$lines2"; then
|
||||
count=0
|
||||
while test "$lines1" -ne "$lines2"; do
|
||||
tail -1 unbound.log
|
||||
lines1=`wc -l unbound.log | awk '{print $1;}'`
|
||||
sleep 1
|
||||
count=`expr "$count" + 1`
|
||||
if test "$count" -gt 30; then
|
||||
echo "reload is taking too long"
|
||||
exit 1
|
||||
fi
|
||||
lines2=`wc -l unbound.log | awk '{print $1;}'`
|
||||
done
|
||||
if test "$count" -ne "0"; then
|
||||
echo "reload done with $count sec"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Reload the server for a clean state
|
||||
clean_reload () {
|
||||
echo "> Reloading the server for a clean state"
|
||||
cp main.conf ub.conf
|
||||
control_command -c ub.conf reload
|
||||
expect_exit_value 0
|
||||
control_reload
|
||||
}
|
||||
|
||||
# Reload the server for a clean state and populate the cache
|
||||
@@ -175,8 +216,7 @@ expect_exit_value 1
|
||||
# local-data element in the server.
|
||||
teststep "reload the server"
|
||||
echo "server: local-data: 'afterreload. IN A 5.6.7.8'" >> ub.conf
|
||||
control_command -c ub.conf reload
|
||||
expect_exit_value 0
|
||||
control_reload
|
||||
query afterreload.
|
||||
expect_answer "5.6.7.8"
|
||||
|
||||
@@ -336,16 +376,14 @@ fi
|
||||
clean_reload_and_fill_cache
|
||||
|
||||
teststep "reload and check cache - should be empty"
|
||||
control_command -c ub.conf reload
|
||||
expect_exit_value 0
|
||||
control_reload
|
||||
query www.example.com +nordflag
|
||||
fail_answer "10.20.30.40"
|
||||
|
||||
clean_reload_and_fill_cache
|
||||
|
||||
teststep "reload_keep_cache and check cache - should not be empty"
|
||||
control_command -c ub.conf reload_keep_cache
|
||||
expect_exit_value 0
|
||||
control_reload reload_keep_cache
|
||||
query www.example.com +nordflag
|
||||
expect_answer "10.20.30.40"
|
||||
|
||||
@@ -353,8 +391,7 @@ clean_reload_and_fill_cache
|
||||
|
||||
teststep "change msg-cache-size and reload_keep_cache - should be empty"
|
||||
echo "server: msg-cache-size: 2m" >> ub.conf
|
||||
control_command -c ub.conf reload_keep_cache
|
||||
expect_exit_value 0
|
||||
control_reload reload_keep_cache
|
||||
query www.example.com +nordflag
|
||||
fail_answer "10.20.30.40"
|
||||
|
||||
@@ -362,8 +399,7 @@ clean_reload_and_fill_cache
|
||||
|
||||
teststep "change rrset-cache-size and reload_keep_cache - should be empty"
|
||||
echo "server: rrset-cache-size: 2m" >> ub.conf
|
||||
control_command -c ub.conf reload_keep_cache
|
||||
expect_exit_value 0
|
||||
control_reload reload_keep_cache
|
||||
query www.example.com +nordflag
|
||||
fail_answer "10.20.30.40"
|
||||
|
||||
@@ -375,8 +411,7 @@ clean_reload_and_fill_cache
|
||||
|
||||
teststep "change num-threads and reload_keep_cache - should be empty"
|
||||
echo "server: num-threads: 2" >> ub.conf
|
||||
control_command -c ub.conf reload_keep_cache
|
||||
expect_exit_value 0
|
||||
control_reload reload_keep_cache
|
||||
query www.example.com +nordflag
|
||||
fail_answer "10.20.30.40"
|
||||
|
||||
@@ -384,8 +419,7 @@ clean_reload_and_fill_cache
|
||||
|
||||
teststep "change minimal-responses and reload_keep_cache - should not be empty"
|
||||
echo "server: minimal-responses: no" >> ub.conf
|
||||
control_command -c ub.conf reload_keep_cache
|
||||
expect_exit_value 0
|
||||
control_reload reload_keep_cache
|
||||
query www.example.com +nordflag
|
||||
expect_answer "10.20.30.40"
|
||||
|
||||
|
||||
+45
-1
@@ -5,9 +5,10 @@ server:
|
||||
pidfile: "unbound.pid"
|
||||
chroot: ""
|
||||
username: ""
|
||||
module-config: "respip validator iterator" # respip for the RPZ part
|
||||
do-not-query-localhost: no
|
||||
use-caps-for-id: no
|
||||
define-tag: "one two refuse"
|
||||
define-tag: "one two refuse rpz-one rpz-two rpz-nx"
|
||||
|
||||
# Interface configuration for IPv4
|
||||
interface: @IPV4_ADDR@@@PORT_ALLOW@
|
||||
@@ -16,6 +17,9 @@ server:
|
||||
interface: @IPV4_ADDR@@@PORT_TAG_1@
|
||||
interface: @IPV4_ADDR@@@PORT_TAG_2@
|
||||
interface: @IPV4_ADDR@@@PORT_TAG_3@
|
||||
interface: @IPV4_ADDR@@@PORT_RPZ_1@
|
||||
interface: @IPV4_ADDR@@@PORT_RPZ_2@
|
||||
interface: @IPV4_ADDR@@@PORT_RPZ_NX@
|
||||
interface: @IPV4_ADDR@@@PORT_VIEW_INT@
|
||||
interface: @IPV4_ADDR@@@PORT_VIEW_EXT@
|
||||
interface: @IPV4_ADDR@@@PORT_VIEW_INTEXT@
|
||||
@@ -26,6 +30,9 @@ server:
|
||||
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_RPZ_1@ allow
|
||||
interface-action: @IPV4_ADDR@@@PORT_RPZ_2@ allow
|
||||
interface-action: @IPV4_ADDR@@@PORT_RPZ_NX@ 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
|
||||
@@ -33,6 +40,9 @@ server:
|
||||
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: @IPV4_ADDR@@@PORT_RPZ_1@ "rpz-one"
|
||||
interface-tag: @IPV4_ADDR@@@PORT_RPZ_2@ "rpz-two"
|
||||
interface-tag: @IPV4_ADDR@@@PORT_RPZ_NX@ "rpz-nx"
|
||||
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
|
||||
@@ -50,6 +60,9 @@ server:
|
||||
interface: @IPV6_ADDR@@@PORT_TAG_1@
|
||||
interface: @IPV6_ADDR@@@PORT_TAG_2@
|
||||
interface: @IPV6_ADDR@@@PORT_TAG_3@
|
||||
interface: @IPV6_ADDR@@@PORT_RPZ_1@
|
||||
interface: @IPV6_ADDR@@@PORT_RPZ_2@
|
||||
interface: @IPV6_ADDR@@@PORT_RPZ_NX@
|
||||
interface: @IPV6_ADDR@@@PORT_VIEW_INT@
|
||||
interface: @IPV6_ADDR@@@PORT_VIEW_EXT@
|
||||
interface: @IPV6_ADDR@@@PORT_VIEW_INTEXT@
|
||||
@@ -60,6 +73,9 @@ server:
|
||||
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_RPZ_1@ allow
|
||||
interface-action: @IPV6_ADDR@@@PORT_RPZ_2@ allow
|
||||
interface-action: @IPV6_ADDR@@@PORT_RPZ_NX@ 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
|
||||
@@ -67,6 +83,9 @@ server:
|
||||
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: @IPV6_ADDR@@@PORT_RPZ_1@ "rpz-one"
|
||||
interface-tag: @IPV6_ADDR@@@PORT_RPZ_2@ "rpz-two"
|
||||
interface-tag: @IPV6_ADDR@@@PORT_RPZ_NX@ "rpz-nx"
|
||||
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
|
||||
@@ -84,6 +103,9 @@ server:
|
||||
interface: @INTERFACE@@@PORT_TAG_1@
|
||||
interface: @INTERFACE@@@PORT_TAG_2@
|
||||
interface: @INTERFACE@@@PORT_TAG_3@
|
||||
interface: @INTERFACE@@@PORT_RPZ_1@
|
||||
interface: @INTERFACE@@@PORT_RPZ_2@
|
||||
interface: @INTERFACE@@@PORT_RPZ_NX@
|
||||
interface: @INTERFACE@@@PORT_VIEW_INT@
|
||||
interface: @INTERFACE@@@PORT_VIEW_EXT@
|
||||
interface: @INTERFACE@@@PORT_VIEW_INTEXT@
|
||||
@@ -94,6 +116,9 @@ server:
|
||||
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_RPZ_1@ allow
|
||||
interface-action: @INTERFACE@@@PORT_RPZ_2@ allow
|
||||
interface-action: @INTERFACE@@@PORT_RPZ_NX@ allow
|
||||
interface-action: @INTERFACE@@@PORT_VIEW_INT@ allow
|
||||
interface-action: @INTERFACE@@@PORT_VIEW_EXT@ allow
|
||||
interface-action: @INTERFACE@@@PORT_VIEW_INTEXT@ allow
|
||||
@@ -101,6 +126,9 @@ server:
|
||||
interface-tag: @INTERFACE@@@PORT_TAG_1@ "one"
|
||||
interface-tag: @INTERFACE@@@PORT_TAG_2@ "two"
|
||||
interface-tag: @INTERFACE@@@PORT_TAG_3@ "refuse"
|
||||
interface-tag: @INTERFACE@@@PORT_RPZ_1@ "rpz-one"
|
||||
interface-tag: @INTERFACE@@@PORT_RPZ_2@ "rpz-two"
|
||||
interface-tag: @INTERFACE@@@PORT_RPZ_NX@ "rpz-nx"
|
||||
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
|
||||
@@ -130,6 +158,22 @@ view:
|
||||
name: "intext"
|
||||
view-first: yes
|
||||
|
||||
# RPZ configuration
|
||||
rpz:
|
||||
name: "rpz-one"
|
||||
zonefile: "rpz-one.zone"
|
||||
tags: "rpz-one"
|
||||
|
||||
rpz:
|
||||
name: "rpz-two"
|
||||
zonefile: "rpz-two.zone"
|
||||
tags: "rpz-two"
|
||||
|
||||
rpz:
|
||||
name: "rpz-nx"
|
||||
zonefile: "rpz-nx.zone"
|
||||
tags: "rpz-nx"
|
||||
|
||||
# Stubs configuration
|
||||
forward-zone:
|
||||
name: "."
|
||||
|
||||
+12
-3
@@ -7,7 +7,7 @@ if test ! -x "`which unshare 2>&1`"; then
|
||||
skip_test "no unshare (from util-linux package) available, skip test"
|
||||
fi
|
||||
|
||||
get_random_port 11
|
||||
get_random_port 14
|
||||
|
||||
PORT_ALLOW=$RND_PORT
|
||||
PORT_DENY=$(($RND_PORT + 1))
|
||||
@@ -18,8 +18,11 @@ 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))
|
||||
PORT_RPZ_1=$(($RND_PORT + 9))
|
||||
PORT_RPZ_2=$(($RND_PORT + 10))
|
||||
PORT_RPZ_NX=$(($RND_PORT + 11))
|
||||
FORWARD_PORT=$(($RND_PORT + 12))
|
||||
STUB_PORT=$(($RND_PORT + 13))
|
||||
|
||||
IPV4_ADDR=192.168.1.1
|
||||
IPV6_ADDR=2001:db8::1
|
||||
@@ -41,6 +44,9 @@ sed \
|
||||
-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/@PORT_RPZ_1\@/'$PORT_RPZ_1'/' \
|
||||
-e 's/@PORT_RPZ_2\@/'$PORT_RPZ_2'/' \
|
||||
-e 's/@PORT_RPZ_NX\@/'$PORT_RPZ_NX'/' \
|
||||
-e 's/@FORWARD_PORT\@/'$FORWARD_PORT'/' \
|
||||
-e 's/@STUB_PORT\@/'$STUB_PORT'/' \
|
||||
-e 's/@IPV4_ADDR\@/'$IPV4_ADDR'/' \
|
||||
@@ -63,6 +69,9 @@ 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 "PORT_RPZ_1=$PORT_RPZ_1" >> .tpkg.var.test
|
||||
echo "PORT_RPZ_2=$PORT_RPZ_2" >> .tpkg.var.test
|
||||
echo "PORT_RPZ_NX=$PORT_RPZ_NX" >> .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
|
||||
|
||||
@@ -78,6 +78,16 @@ expect_refused () {
|
||||
fi
|
||||
}
|
||||
|
||||
expect_nx_answer () {
|
||||
echo "> check answer for NXDOMAIN"
|
||||
if grep "NXDOMAIN" 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
|
||||
@@ -118,6 +128,26 @@ expect_tag_two_answer () {
|
||||
fi
|
||||
}
|
||||
|
||||
expect_rpz_one_answer () {
|
||||
echo "> check tag 'one' answer"
|
||||
if grep "11.11.11.11" outfile; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "Not OK"
|
||||
end 1
|
||||
fi
|
||||
}
|
||||
|
||||
expect_rpz_two_answer () {
|
||||
echo "> check tag 'two' answer"
|
||||
if grep "22.22.22.22" outfile; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "Not OK"
|
||||
end 1
|
||||
fi
|
||||
}
|
||||
|
||||
# do the test
|
||||
|
||||
for i in 4 6; do
|
||||
@@ -142,6 +172,15 @@ for i in 4 6; do
|
||||
query $i $PORT_TAG_3 "local"
|
||||
expect_refused
|
||||
|
||||
query $i $PORT_RPZ_1 "local"
|
||||
expect_rpz_one_answer
|
||||
|
||||
query $i $PORT_RPZ_2 "local"
|
||||
expect_rpz_two_answer
|
||||
|
||||
query $i $PORT_RPZ_NX "local"
|
||||
expect_nx_answer
|
||||
|
||||
query $i $PORT_VIEW_INT "www.internal"
|
||||
expect_internal_answer
|
||||
|
||||
@@ -183,6 +222,15 @@ for addr in $INTERFACE_ADDR_1 $INTERFACE_ADDR_2 $INTERFACE_ADDR_3 $INTERFACE_ADD
|
||||
query_addr $addr $PORT_TAG_3 "local"
|
||||
expect_refused
|
||||
|
||||
query_addr $addr $PORT_RPZ_1 "local"
|
||||
expect_rpz_one_answer
|
||||
|
||||
query_addr $addr $PORT_RPZ_2 "local"
|
||||
expect_rpz_two_answer
|
||||
|
||||
query_addr $addr $PORT_RPZ_NX "local"
|
||||
expect_nx_answer
|
||||
|
||||
query_addr $addr $PORT_VIEW_INT "www.internal"
|
||||
expect_internal_answer
|
||||
|
||||
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
$ORIGIN rpz-nx.
|
||||
@ IN SOA no.no no.no 1 2 3 4 5
|
||||
local IN CNAME .
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
$ORIGIN rpz-one.
|
||||
@ IN SOA no.no no.no 1 2 3 4 5
|
||||
local IN A 11.11.11.11
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
$ORIGIN rpz-two.
|
||||
@ IN SOA no.no no.no 1 2 3 4 5
|
||||
local IN A 22.22.22.22
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
server:
|
||||
verbosity: 7
|
||||
use-syslog: no
|
||||
directory: ""
|
||||
pidfile: "unbound.pid"
|
||||
chroot: ""
|
||||
username: ""
|
||||
do-not-query-localhost: no
|
||||
use-caps-for-id: no
|
||||
port: @SERVER_PORT@
|
||||
interface: 127.0.0.1
|
||||
cookie-secret-file: "cookie_secrets.txt"
|
||||
answer-cookie: yes
|
||||
access-control: 127.0.0.0/8 allow_cookie # BADCOOKIE for incomplete/invalid cookies
|
||||
|
||||
remote-control:
|
||||
control-enable: yes
|
||||
control-port: @CONTROL_PORT@
|
||||
control-use-cert: no
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
BaseName: cookie_file
|
||||
Version: 1.0
|
||||
Description: Check the cookie rollover
|
||||
CreationDate: Fri 14 Jun 11:00:00 CEST 2024
|
||||
Maintainer:
|
||||
Category:
|
||||
Component:
|
||||
CmdDepends:
|
||||
Depends:
|
||||
Help:
|
||||
Pre: cookie_file.pre
|
||||
Post: cookie_file.post
|
||||
Test: cookie_file.test
|
||||
AuxFiles:
|
||||
Passed:
|
||||
Failure:
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
# #-- cookie_file.post --#
|
||||
# source the master var file when it's there
|
||||
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
|
||||
# source the test var file when it's there
|
||||
[ -f .tpkg.var.test ] && source .tpkg.var.test
|
||||
#
|
||||
# do your teardown here
|
||||
. ../common.sh
|
||||
kill_from_pidfile "unbound.pid"
|
||||
cat unbound.log
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
# #-- cookie_file.pre--#
|
||||
PRE="../.."
|
||||
. ../common.sh
|
||||
|
||||
get_random_port 2
|
||||
SERVER_PORT=$RND_PORT
|
||||
CONTROL_PORT=$(($RND_PORT + 1))
|
||||
echo "SERVER_PORT=$SERVER_PORT" >> .tpkg.var.test
|
||||
echo "CONTROL_PORT=$CONTROL_PORT" >> .tpkg.var.test
|
||||
|
||||
# make config file
|
||||
sed \
|
||||
-e 's/@SERVER_PORT\@/'$SERVER_PORT'/' \
|
||||
-e 's/@CONTROL_PORT\@/'$CONTROL_PORT'/' \
|
||||
< cookie_file.conf > ub.conf
|
||||
|
||||
# empty cookie file
|
||||
touch cookie_secrets.txt
|
||||
|
||||
# start unbound in the background
|
||||
$PRE/unbound -d -c ub.conf > unbound.log 2>&1 &
|
||||
|
||||
cat .tpkg.var.test
|
||||
wait_unbound_up unbound.log
|
||||
+248
@@ -0,0 +1,248 @@
|
||||
# #-- cookie_file.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
|
||||
|
||||
first_secret=dd3bdf9344b678b185a6f5cb60fca715
|
||||
second_secret=445536bcd2513298075a5d379663c962
|
||||
|
||||
|
||||
teststep "Add first secret"
|
||||
echo ">> add_cookie_secret $first_secret"
|
||||
$PRE/unbound-control -c ub.conf add_cookie_secret $first_secret
|
||||
# check secret is persisted
|
||||
outfile=cookie_secrets.1
|
||||
$PRE/unbound-control -c ub.conf print_cookie_secrets > $outfile
|
||||
if ! grep -q "$first_secret" $outfile
|
||||
then
|
||||
sleep 1
|
||||
$PRE/unbound-control -c ub.conf print_cookie_secrets > $outfile
|
||||
fi
|
||||
if ! grep -q "$first_secret" $outfile
|
||||
then
|
||||
sleep 1
|
||||
$PRE/unbound-control -c ub.conf print_cookie_secrets > $outfile
|
||||
fi
|
||||
if ! grep -q "$first_secret" $outfile
|
||||
then
|
||||
sleep 1
|
||||
$PRE/unbound-control -c ub.conf print_cookie_secrets > $outfile
|
||||
fi
|
||||
if ! grep -q "^active.*$first_secret" $outfile
|
||||
then
|
||||
cat $outfile
|
||||
echo "First secret was not provisioned"
|
||||
exit 1
|
||||
fi
|
||||
echo ">> print_cookie_secrets"
|
||||
cat $outfile
|
||||
|
||||
|
||||
teststep "Get a valid cookie for this secret"
|
||||
outfile=dig.output.1
|
||||
dig version.server ch txt @127.0.0.1 -p $SERVER_PORT +cookie=3132333435363738 > $outfile
|
||||
if ! grep -q "BADCOOKIE" $outfile
|
||||
then
|
||||
cat $outfile
|
||||
echo "Did not get a BADCOOKIE response for a client-only cookie"
|
||||
exit 1
|
||||
fi
|
||||
if ! grep -q "COOKIE: 3132333435363738" $outfile
|
||||
then
|
||||
cat $outfile
|
||||
echo "Did not get a cookie in the response"
|
||||
exit 1
|
||||
fi
|
||||
first_cookie=$(grep "; COOKIE:" $outfile | cut -d ' ' -f 3)
|
||||
cat $outfile
|
||||
echo "first cookie: $first_cookie"
|
||||
|
||||
|
||||
teststep "Verify the first cookie can be reused"
|
||||
outfile=dig.output.2
|
||||
dig version.server ch txt @127.0.0.1 -p $SERVER_PORT +cookie=$first_cookie > $outfile
|
||||
if grep -q "BADCOOKIE" $outfile
|
||||
then
|
||||
cat $outfile
|
||||
echo "Got BADCOOKIE response for a valid cookie"
|
||||
exit 1
|
||||
fi
|
||||
if ! grep -q "COOKIE: $first_cookie" $outfile
|
||||
then
|
||||
cat $outfile
|
||||
echo "Did not get the same first cookie in the response"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
teststep "Add second secret"
|
||||
outfile=cookie_secrets.2
|
||||
echo ">> add_cookie_secret $second_secret"
|
||||
$PRE/unbound-control -c ub.conf add_cookie_secret $second_secret
|
||||
$PRE/unbound-control -c ub.conf print_cookie_secrets > $outfile
|
||||
if ! grep -q "$second_secret" $outfile
|
||||
then
|
||||
sleep 1
|
||||
$PRE/unbound-control -c ub.conf print_cookie_secrets > $outfile
|
||||
fi
|
||||
if ! grep -q "$second_secret" $outfile
|
||||
then
|
||||
sleep 1
|
||||
$PRE/unbound-control -c ub.conf print_cookie_secrets > $outfile
|
||||
fi
|
||||
if ! grep -q "$second_secret" $outfile
|
||||
then
|
||||
sleep 1
|
||||
$PRE/unbound-control -c ub.conf print_cookie_secrets > $outfile
|
||||
fi
|
||||
if ! grep -q "^staging.*$second_secret" $outfile \
|
||||
|| ! grep -q "^active.*$first_secret" $outfile
|
||||
then
|
||||
cat $outfile
|
||||
echo "Secrets were not provisioned"
|
||||
exit 1
|
||||
fi
|
||||
echo ">> print_cookie_secrets"
|
||||
cat $outfile
|
||||
echo ">> cookie_secrets.txt"
|
||||
cat cookie_secrets.txt
|
||||
|
||||
|
||||
teststep "Verify the first cookie can be reused"
|
||||
outfile=dig.output.3
|
||||
dig version.server ch txt @127.0.0.1 -p $SERVER_PORT +cookie=$first_cookie > $outfile
|
||||
if grep -q "BADCOOKIE" $outfile
|
||||
then
|
||||
cat $outfile
|
||||
echo "Got BADCOOKIE response for a valid cookie"
|
||||
exit 1
|
||||
fi
|
||||
if ! grep -q "COOKIE: $first_cookie" $outfile
|
||||
then
|
||||
cat $outfile
|
||||
echo "Did not get the same first cookie in the response"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
teststep "Secret rollover"
|
||||
outfile=cookie_secrets.3
|
||||
$PRE/unbound-control -c ub.conf activate_cookie_secret
|
||||
$PRE/unbound-control -c ub.conf print_cookie_secrets > $outfile
|
||||
if ! grep -q "^active.*$second_secret" $outfile
|
||||
then
|
||||
sleep 1
|
||||
$PRE/unbound-control -c ub.conf print_cookie_secrets > $outfile
|
||||
fi
|
||||
if ! grep -q "^active.*$second_secret" $outfile
|
||||
then
|
||||
sleep 1
|
||||
$PRE/unbound-control -c ub.conf print_cookie_secrets > $outfile
|
||||
fi
|
||||
if ! grep -q "^active.*$second_secret" $outfile
|
||||
then
|
||||
sleep 1
|
||||
$PRE/unbound-control -c ub.conf print_cookie_secrets > $outfile
|
||||
fi
|
||||
if ! grep -q "^active.*$second_secret" $outfile \
|
||||
|| ! grep -q "^staging.*$first_secret" $outfile
|
||||
then
|
||||
cat $outfile
|
||||
echo "Second secret was not activated"
|
||||
exit 1
|
||||
fi
|
||||
echo ">> activate cookie secret, printout"
|
||||
cat $outfile
|
||||
echo ">> cookie_secrets.txt"
|
||||
cat cookie_secrets.txt
|
||||
|
||||
|
||||
teststep "Verify the first cookie can be reused but a new cookie is returned from the second secret"
|
||||
outfile=dig.output.4
|
||||
dig version.server ch txt @127.0.0.1 -p $SERVER_PORT +cookie=$first_cookie > $outfile
|
||||
if grep -q "BADCOOKIE" $outfile
|
||||
then
|
||||
cat $outfile
|
||||
echo "Got BADCOOKIE response for a valid cookie"
|
||||
exit 1
|
||||
fi
|
||||
if ! grep -q "COOKIE: 3132333435363738" $outfile
|
||||
then
|
||||
cat $outfile
|
||||
echo "Did not get a cookie in the response"
|
||||
exit 1
|
||||
fi
|
||||
if grep -q "COOKIE: $first_cookie" $outfile
|
||||
then
|
||||
cat $outfile
|
||||
echo "Got the same first cookie in the response while the second secret is active"
|
||||
exit 1
|
||||
fi
|
||||
second_cookie=$(grep "; COOKIE:" $outfile | cut -d ' ' -f 3)
|
||||
cat $outfile
|
||||
echo "second cookie: $second_cookie"
|
||||
|
||||
|
||||
teststep "Drop cookie secret"
|
||||
outfile=cookie_secrets.4
|
||||
$PRE/unbound-control -c ub.conf drop_cookie_secret
|
||||
$PRE/unbound-control -c ub.conf print_cookie_secrets > $outfile
|
||||
if grep -q "^staging.*$first_secret" $outfile
|
||||
then
|
||||
sleep 1
|
||||
$PRE/unbound-control -c ub.conf print_cookie_secrets > $outfile
|
||||
fi
|
||||
if grep -q "^staging.*$first_secret" $outfile
|
||||
then
|
||||
sleep 1
|
||||
$PRE/unbound-control -c ub.conf print_cookie_secrets > $outfile
|
||||
fi
|
||||
if grep -q "^staging.*$first_secret" $outfile
|
||||
then
|
||||
sleep 1
|
||||
$PRE/unbound-control -c ub.conf print_cookie_secrets > $outfile
|
||||
fi
|
||||
if grep -q "^staging.*$first_secret" $outfile
|
||||
then
|
||||
cat $outfile
|
||||
echo "First secret was not dropped"
|
||||
exit 1
|
||||
fi
|
||||
echo ">> drop cookie secret, printout"
|
||||
cat $outfile
|
||||
echo ">> cookie_secrets.txt"
|
||||
cat cookie_secrets.txt
|
||||
|
||||
|
||||
teststep "Verify the first cookie can not be reused and the second cookie is returned instead"
|
||||
outfile=dig.output.4
|
||||
dig version.server ch txt @127.0.0.1 -p $SERVER_PORT +cookie=$first_cookie > $outfile
|
||||
if ! grep -q "BADCOOKIE" $outfile
|
||||
then
|
||||
cat $outfile
|
||||
echo "Did not get BADCOOKIE response for an invalid cookie"
|
||||
exit 1
|
||||
fi
|
||||
if ! grep -q "COOKIE: 3132333435363738" $outfile
|
||||
then
|
||||
cat $outfile
|
||||
echo "Did not get a cookie in the response"
|
||||
exit 1
|
||||
fi
|
||||
if grep -q "COOKIE: $first_cookie" $outfile
|
||||
then
|
||||
cat $outfile
|
||||
echo "Got the same first cookie in the response while the second secret is active"
|
||||
exit 1
|
||||
fi
|
||||
if ! grep -q "COOKIE: $second_cookie" $outfile
|
||||
then
|
||||
cat $outfile
|
||||
echo "Did not get the same second cookie in the response"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
Vendored
+2
@@ -12,4 +12,6 @@ kill_pid $FWD_PID
|
||||
kill $UNBOUND_PID
|
||||
kill $UNBOUND_PID >/dev/null 2>&1
|
||||
cat unbound.log
|
||||
cat tap.log
|
||||
cat tap.errlog
|
||||
exit 0
|
||||
|
||||
Vendored
-2
@@ -122,8 +122,6 @@ if test $num_responses -gt 2; then
|
||||
fi
|
||||
|
||||
echo "> cat logfiles"
|
||||
cat tap.log
|
||||
cat tap.errlog
|
||||
cat fwd.log
|
||||
echo "> OK"
|
||||
exit 0
|
||||
|
||||
Vendored
-1
@@ -24,4 +24,3 @@ auth-zone:
|
||||
auth-zone:
|
||||
name: "rrsig-failures.test"
|
||||
zonefile: "bogus/rrsig-failures.test.signed"
|
||||
|
||||
|
||||
Vendored
+8
-8
@@ -33,18 +33,18 @@ server:
|
||||
local-zone: test nodefault
|
||||
do-not-query-localhost: no
|
||||
|
||||
forward-zone:
|
||||
stub-zone:
|
||||
name: "dnssec-failures.test"
|
||||
forward-addr: 127.0.0.1@@PORT2@
|
||||
stub-addr: 127.0.0.1@@PORT2@
|
||||
|
||||
forward-zone:
|
||||
stub-zone:
|
||||
name: "dnskey-failures.test"
|
||||
forward-addr: 127.0.0.1@@PORT2@
|
||||
stub-addr: 127.0.0.1@@PORT2@
|
||||
|
||||
forward-zone:
|
||||
stub-zone:
|
||||
name: "nsec-failures.test"
|
||||
forward-addr: 127.0.0.1@@PORT2@
|
||||
stub-addr: 127.0.0.1@@PORT2@
|
||||
|
||||
forward-zone:
|
||||
stub-zone:
|
||||
name: "rrsig-failures.test"
|
||||
forward-addr: 127.0.0.1@@PORT2@
|
||||
stub-addr: 127.0.0.1@@PORT2@
|
||||
|
||||
Vendored
-3
@@ -5,9 +5,6 @@
|
||||
[ -f .tpkg.var.test ] && source .tpkg.var.test
|
||||
|
||||
|
||||
# DNSSEC failure: Signature Expired or DNSKEY Missing (depending on the servfail configuration)
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT servfail.nl > servfail.txt
|
||||
|
||||
# DNSSEC failure: key not incepted
|
||||
dig @127.0.0.1 -p $UNBOUND_PORT notyetincepted.dnssec-failures.test. TXT +dnssec > sig_notyetincepted.txt
|
||||
|
||||
|
||||
Vendored
+152
@@ -0,0 +1,152 @@
|
||||
; config options
|
||||
server:
|
||||
# must have target-fetch-policy to fetch forward-host name.
|
||||
target-fetch-policy: "3 2 1 0 0"
|
||||
qname-minimisation: no
|
||||
minimal-responses: no
|
||||
|
||||
forward-zone:
|
||||
name: "."
|
||||
forward-addr: 1.2.3.4
|
||||
forward-host: ns.example.com
|
||||
CONFIG_END
|
||||
|
||||
SCENARIO_BEGIN Test forward with forward-host lookup for more addresses
|
||||
|
||||
; Forward server
|
||||
RANGE_BEGIN 0 15
|
||||
ADDRESS 1.2.3.4
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
ns.example.com. IN A
|
||||
SECTION ANSWER
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ns.example.com. IN A 1.2.3.5
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
ns.example.com. IN AAAA
|
||||
SECTION ANSWER
|
||||
SECTION AUTHORITY
|
||||
example.com. IN SOA ns.example.com. host.example.com. 3 3600 300 86400 3600
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. IN A 1.2.3.6
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; The forward server gives no answers.
|
||||
RANGE_BEGIN 20 55
|
||||
ADDRESS 1.2.3.4
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR SERVFAIL
|
||||
SECTION QUESTION
|
||||
www2.example.com. IN A
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR SERVFAIL
|
||||
SECTION QUESTION
|
||||
www3.example.com. IN A
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; The other forward server.
|
||||
RANGE_BEGIN 20 55
|
||||
ADDRESS 1.2.3.5
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
www2.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www2.example.com. IN A 1.2.3.7
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
www3.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www3.example.com. IN A 1.2.3.8
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
STEP 1 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. IN A 1.2.3.6
|
||||
ENTRY_END
|
||||
|
||||
; The address 1.2.3.4 is not responding so it has to fail over to the
|
||||
; address from the name lookup.
|
||||
STEP 20 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
www2.example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 30 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
www2.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www2.example.com. IN A 1.2.3.7
|
||||
ENTRY_END
|
||||
|
||||
STEP 40 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD
|
||||
SECTION QUESTION
|
||||
www3.example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 50 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all
|
||||
REPLY QR RD RA NOERROR
|
||||
SECTION QUESTION
|
||||
www3.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www3.example.com. IN A 1.2.3.8
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
Vendored
+5
@@ -8,6 +8,11 @@
|
||||
|
||||
PRE="../.."
|
||||
if grep "define USE_IPSET 1" $PRE/config.h; then echo test enabled; else skip_test "test skipped"; fi
|
||||
if grep "define HAVE_NET_PFVAR_H 1" $PRE/config.h; then
|
||||
if test ! -f /dev/pf; then
|
||||
skip_test "no /dev/pf"
|
||||
fi
|
||||
fi
|
||||
|
||||
get_random_port 2
|
||||
UNBOUND_PORT=$RND_PORT
|
||||
|
||||
Vendored
+226
@@ -0,0 +1,226 @@
|
||||
; config options
|
||||
; The island of trust is at example.com
|
||||
server:
|
||||
trust-anchor: "example.com. 3600 IN DS 2854 3 1 46e4ffc6e9a4793b488954bd3f0cc6af0dfb201b"
|
||||
val-override-date: "20070916134226"
|
||||
target-fetch-policy: "0 0 0 0 0"
|
||||
qname-minimisation: "no"
|
||||
fake-sha1: yes
|
||||
trust-anchor-signaling: no
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
|
||||
CONFIG_END
|
||||
|
||||
SCENARIO_BEGIN Test validator with a dname used twice
|
||||
|
||||
; K.ROOT-SERVERS.NET.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 193.0.14.129
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
. IN NS
|
||||
SECTION ANSWER
|
||||
. IN NS K.ROOT-SERVERS.NET.
|
||||
SECTION ADDITIONAL
|
||||
K.ROOT-SERVERS.NET. IN A 193.0.14.129
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode subdomain
|
||||
ADJUST copy_id copy_query
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
com. IN NS
|
||||
SECTION AUTHORITY
|
||||
com. IN NS a.gtld-servers.net.
|
||||
SECTION ADDITIONAL
|
||||
a.gtld-servers.net. IN A 192.5.6.30
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; a.gtld-servers.net.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 192.5.6.30
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
com. IN NS
|
||||
SECTION ANSWER
|
||||
com. IN NS a.gtld-servers.net.
|
||||
SECTION ADDITIONAL
|
||||
a.gtld-servers.net. IN A 192.5.6.30
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode subdomain
|
||||
ADJUST copy_id copy_query
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN NS
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; ns.example.com.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 1.2.3.4
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN NS
|
||||
SECTION ANSWER
|
||||
example.com. IN NS ns.example.com.
|
||||
example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
|
||||
ENTRY_END
|
||||
|
||||
; response to DNSKEY priming query
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN DNSKEY
|
||||
SECTION ANSWER
|
||||
example.com. 3600 IN DNSKEY 256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
|
||||
example.com. 3600 IN RRSIG DNSKEY DSA 2 3600 20070926134150 20070829134150 2854 example.com. MCwCFBQRtlR4BEv9ohi+PGFjp+AHsJuHAhRCvz0shggvnvI88DFnBDCczHUcVA== ;{id = 2854}
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
|
||||
ENTRY_END
|
||||
|
||||
; response to query of interest
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
a.a.test-dname-2.example.com. IN A
|
||||
SECTION ANSWER
|
||||
test-dname-2.example.com. 3600 IN DNAME test-2.example.com.
|
||||
test-dname-2.example.com. 3600 IN RRSIG DNAME 3 3 3600 20070926134150 20070829134150 2854 example.com. AB9F05uhCzJ0hFbu/033nWLEMDoDrIY1PL69PsD9kMUuyzT4irnUlGY=
|
||||
; unsigned CNAME
|
||||
a.a.test-dname-2.example.com. IN CNAME a.a.test-2.example.com.
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
a.a.test-2.example.com. IN A
|
||||
SECTION ANSWER
|
||||
a.a.test-2.example.com. 3600 IN CNAME a.test-dname-2.example.com.
|
||||
a.a.test-2.example.com. 3600 IN RRSIG CNAME 3 5 3600 20070926134150 20070829134150 2854 example.com. AECBiHVJ8qaSV3sC7LcOlSF2W4b9JD+g44fQ2EvkKqGJVUJfa6840i8=
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
a.test-dname-2.example.com. IN A
|
||||
SECTION ANSWER
|
||||
test-dname-2.example.com. 3600 IN DNAME test-2.example.com.
|
||||
test-dname-2.example.com. 3600 IN RRSIG DNAME 3 3 3600 20070926134150 20070829134150 2854 example.com. AB9F05uhCzJ0hFbu/033nWLEMDoDrIY1PL69PsD9kMUuyzT4irnUlGY=
|
||||
; unsigned CNAME
|
||||
a.test-dname-2.example.com. IN CNAME a.test-2.example.com.
|
||||
SECTION AUTHORITY
|
||||
snow.example.com. 3600 IN NSEC a.a.test-2.example.com. A AAAA RRSIG NSEC
|
||||
snow.example.com. 3600 IN RRSIG NSEC 3 3 3600 20070926134150 20070829134150 2854 example.com. AHy/eDMTc5D7Q7Svh/B/r/twvHn8GTzYgSwO1jFasFrb2Gmtk8waXaM=
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
a.test-2.example.com. IN A
|
||||
SECTION ANSWER
|
||||
SECTION AUTHORITY
|
||||
example.com. 3600 IN SOA ns.example.com. root.example.com. 1 3600 300 7200 3600
|
||||
example.com. 3600 IN RRSIG SOA 3 2 3600 20070926134150 20070829134150 2854 example.com. AEO4JOt/lNSVk3InhQz4MvUXll2vOOuZklfB7HpnW45kvEqHsqfWuNw=
|
||||
snow.example.com. 3600 IN NSEC a.a.test-2.example.com. A AAAA RRSIG NSEC
|
||||
snow.example.com. 3600 IN RRSIG NSEC 3 3 3600 20070926134150 20070829134150 2854 example.com. AHy/eDMTc5D7Q7Svh/B/r/twvHn8GTzYgSwO1jFasFrb2Gmtk8waXaM=
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
STEP 1 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
a.a.test-dname-2.example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA AD DO NOERROR
|
||||
SECTION QUESTION
|
||||
a.a.test-dname-2.example.com. IN A
|
||||
SECTION ANSWER
|
||||
test-dname-2.example.com. 3600 IN DNAME test-2.example.com.
|
||||
test-dname-2.example.com. 3600 IN RRSIG DNAME 3 3 3600 20070926134150 20070829134150 2854 example.com. AB9F05uhCzJ0hFbu/033nWLEMDoDrIY1PL69PsD9kMUuyzT4irnUlGY= ;{id = 2854}
|
||||
a.a.test-dname-2.example.com. 3600 IN CNAME a.a.test-2.example.com.
|
||||
a.a.test-2.example.com. 3600 IN CNAME a.test-dname-2.example.com.
|
||||
a.a.test-2.example.com. 3600 IN RRSIG CNAME 3 5 3600 20070926134150 20070829134150 2854 example.com. AECBiHVJ8qaSV3sC7LcOlSF2W4b9JD+g44fQ2EvkKqGJVUJfa6840i8= ;{id = 2854}
|
||||
a.test-dname-2.example.com. 3600 IN CNAME a.test-2.example.com.
|
||||
|
||||
SECTION AUTHORITY
|
||||
example.com. 3600 IN SOA ns.example.com. root.example.com. 1 3600 300 7200 3600
|
||||
example.com. 3600 IN RRSIG SOA 3 2 3600 20070926134150 20070829134150 2854 example.com. AEO4JOt/lNSVk3InhQz4MvUXll2vOOuZklfB7HpnW45kvEqHsqfWuNw= ;{id = 2854}
|
||||
snow.example.com. 3600 IN NSEC a.a.test-2.example.com. A AAAA RRSIG NSEC
|
||||
snow.example.com. 3600 IN RRSIG NSEC 3 3 3600 20070926134150 20070829134150 2854 example.com. AHy/eDMTc5D7Q7Svh/B/r/twvHn8GTzYgSwO1jFasFrb2Gmtk8waXaM= ;{id = 2854}
|
||||
ENTRY_END
|
||||
|
||||
; Check cache response for DNAME
|
||||
; so 100+ the authority will not respond any more : must be from cache.
|
||||
STEP 110 TIME_PASSES ELAPSE 10
|
||||
|
||||
STEP 120 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
a.a.test-dname-2.example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 130 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA AD DO NOERROR
|
||||
SECTION QUESTION
|
||||
a.a.test-dname-2.example.com. IN A
|
||||
SECTION ANSWER
|
||||
test-dname-2.example.com. 3590 IN DNAME test-2.example.com.
|
||||
test-dname-2.example.com. 3590 IN RRSIG DNAME 3 3 3600 20070926134150 20070829134150 2854 example.com. AB9F05uhCzJ0hFbu/033nWLEMDoDrIY1PL69PsD9kMUuyzT4irnUlGY= ;{id = 2854}
|
||||
a.a.test-dname-2.example.com. 3590 IN CNAME a.a.test-2.example.com.
|
||||
a.a.test-2.example.com. 3590 IN CNAME a.test-dname-2.example.com.
|
||||
a.a.test-2.example.com. 3590 IN RRSIG CNAME 3 5 3600 20070926134150 20070829134150 2854 example.com. AECBiHVJ8qaSV3sC7LcOlSF2W4b9JD+g44fQ2EvkKqGJVUJfa6840i8= ;{id = 2854}
|
||||
a.test-dname-2.example.com. 3590 IN CNAME a.test-2.example.com.
|
||||
|
||||
SECTION AUTHORITY
|
||||
example.com. 3590 IN SOA ns.example.com. root.example.com. 1 3600 300 7200 3600
|
||||
example.com. 3590 IN RRSIG SOA 3 2 3600 20070926134150 20070829134150 2854 example.com. AEO4JOt/lNSVk3InhQz4MvUXll2vOOuZklfB7HpnW45kvEqHsqfWuNw= ;{id = 2854}
|
||||
snow.example.com. 3590 IN NSEC a.a.test-2.example.com. A AAAA RRSIG NSEC
|
||||
snow.example.com. 3590 IN RRSIG NSEC 3 3 3600 20070926134150 20070829134150 2854 example.com. AHy/eDMTc5D7Q7Svh/B/r/twvHn8GTzYgSwO1jFasFrb2Gmtk8waXaM= ;{id = 2854}
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
Vendored
+348
@@ -0,0 +1,348 @@
|
||||
; config options
|
||||
; The island of trust is at example.com
|
||||
server:
|
||||
trust-anchor: "example.com. 3600 IN DS 2854 3 1 46e4ffc6e9a4793b488954bd3f0cc6af0dfb201b"
|
||||
trust-anchor: "example.net. 3600 IN DS 1444 8 2 69887be92d4848c0bc10acc95682a01e7e3b57ab0750a2ee6f72cac7191a64f1"
|
||||
val-override-date: "20070916134226"
|
||||
target-fetch-policy: "0 0 0 0 0"
|
||||
qname-minimisation: "no"
|
||||
fake-sha1: yes
|
||||
trust-anchor-signaling: no
|
||||
minimal-responses: no
|
||||
log-servfail: yes
|
||||
val-log-level: 2
|
||||
ede: yes
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
|
||||
CONFIG_END
|
||||
|
||||
SCENARIO_BEGIN Test validator with failure for chaing of trust lookup.
|
||||
; The error message that is created, also for EDE is more extensive.
|
||||
|
||||
; K.ROOT-SERVERS.NET.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 193.0.14.129
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
. IN NS
|
||||
SECTION ANSWER
|
||||
. IN NS K.ROOT-SERVERS.NET.
|
||||
SECTION ADDITIONAL
|
||||
K.ROOT-SERVERS.NET. IN A 193.0.14.129
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode subdomain
|
||||
ADJUST copy_id copy_query
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
com. IN NS
|
||||
SECTION AUTHORITY
|
||||
com. IN NS a.gtld-servers.net.
|
||||
SECTION ADDITIONAL
|
||||
a.gtld-servers.net. IN A 192.5.6.30
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode subdomain
|
||||
ADJUST copy_id copy_query
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
net. IN NS
|
||||
SECTION AUTHORITY
|
||||
net. IN NS a.gtld-servers.net.
|
||||
SECTION ADDITIONAL
|
||||
a.gtld-servers.net. IN A 192.5.6.30
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; a.gtld-servers.net.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 192.5.6.30
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
com. IN NS
|
||||
SECTION ANSWER
|
||||
com. IN NS a.gtld-servers.net.
|
||||
SECTION ADDITIONAL
|
||||
a.gtld-servers.net. IN A 192.5.6.30
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode subdomain
|
||||
ADJUST copy_id copy_query
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN NS
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode subdomain
|
||||
ADJUST copy_id copy_query
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.net. IN NS
|
||||
SECTION AUTHORITY
|
||||
example.net. IN NS ns.example.net.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.net. IN A 1.2.3.5
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; ns.example.com.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 1.2.3.4
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN NS
|
||||
SECTION ANSWER
|
||||
example.com. IN NS ns.example.com.
|
||||
example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
ns.example.com. IN A
|
||||
SECTION ANSWER
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
ns.example.com. IN AAAA
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
|
||||
ENTRY_END
|
||||
|
||||
; response to DNSKEY priming query
|
||||
;ENTRY_BEGIN
|
||||
;MATCH opcode qtype qname
|
||||
;ADJUST copy_id
|
||||
;REPLY QR NOERROR
|
||||
;SECTION QUESTION
|
||||
;example.com. IN DNSKEY
|
||||
;SECTION ANSWER
|
||||
;example.com. 3600 IN DNSKEY 256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
|
||||
;example.com. 3600 IN RRSIG DNSKEY 3 2 3600 20070926134802 20070829134802 2854 example.com. MCwCFG1yhRNtTEa3Eno2zhVVuy2EJX3wAhQeLyUp6+UXcpC5qGNu9tkrTEgPUg== ;{id = 2854}
|
||||
;SECTION AUTHORITY
|
||||
;example.com. IN NS ns.example.com.
|
||||
;example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
|
||||
;SECTION ADDITIONAL
|
||||
;ns.example.com. IN A 1.2.3.4
|
||||
;ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
|
||||
;ENTRY_END
|
||||
; servfail for DNSKEY priming query
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA SERVFAIL
|
||||
SECTION QUESTION
|
||||
example.com. IN DNSKEY
|
||||
ENTRY_END
|
||||
|
||||
; response to query of interest
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. IN A 10.20.30.40
|
||||
ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; ns.example.com.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 1.2.3.5
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
example.net. IN NS
|
||||
SECTION ANSWER
|
||||
example.net. 3600 IN NS ns.example.net.
|
||||
example.net. 3600 IN RRSIG NS 8 2 3600 20070926134150 20070829134150 1444 example.net. nHpOqZb00nIGytQ1YmVoXEHURL/75dWhlKSEtRTorjVdPGPZNN7ziCWJW303v7u07TkZ+i6oFVEWG/SDR4ejn5o31UKJy1373PEH/cvPf9/44jw9gAFaHF1eO6ZQGaRQaeEpU06+xUcnc2QXFt6rNu60EsTvMRDN83bD+r7FA7Y=
|
||||
SECTION ADDITIONAL
|
||||
ns.example.net. 3600 IN A 1.2.3.5
|
||||
ns.example.net. 3600 IN RRSIG A 8 3 3600 20070926134150 20070829134150 1444 example.net. TgQ4nfGtLHuZXlC4JJlVQ6mejf1WJbstTxsh/kgMAc2tryOxF/gvGBHaMtz6oceFZrIgk6g3RYI1Gk5gjSFNADh+EIwI422M8XPAAxRLfFahiO4lr1aCo4c94TYeZNpnDKy81rINTz2hQE1pGWr8Z03ySABqSBnTE1FQt4N/JCo=
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
ns.example.net. IN A
|
||||
SECTION ANSWER
|
||||
ns.example.net. 3600 IN A 1.2.3.5
|
||||
ns.example.net. 3600 IN RRSIG A 8 3 3600 20070926134150 20070829134150 1444 example.net. TgQ4nfGtLHuZXlC4JJlVQ6mejf1WJbstTxsh/kgMAc2tryOxF/gvGBHaMtz6oceFZrIgk6g3RYI1Gk5gjSFNADh+EIwI422M8XPAAxRLfFahiO4lr1aCo4c94TYeZNpnDKy81rINTz2hQE1pGWr8Z03ySABqSBnTE1FQt4N/JCo=
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
ns.example.net. IN AAAA
|
||||
SECTION AUTHORITY
|
||||
example.net. 3600 IN SOA ns.example.net. host.example.net. 1 3600 300 7200 3600
|
||||
example.net. 3600 IN RRSIG SOA 8 2 3600 20070926134150 20070829134150 1444 example.net. P5FRQ4A/0n5owaBhZqlYBFD2PNAWJc5oxiDwvwh0hdjxETx8ta3EAvDKtNj5XZ5EKDAhP/tivd+Bq50I0xfRBmrouxgxjgnV3ye8zU+M1fXbuKpsWme9R3S4cs9WYfggTn7X00Af8m0tE62SLH/ZtOOQi2CvOPu7PXtHYT6KW4Q=
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
example.net. IN DNSKEY
|
||||
SECTION ANSWER
|
||||
example.net. 3600 IN DNSKEY 257 3 8 AwEAAbd9WqjzE2Pynz21OG5doSf9hFzMr5dhzz2waZ3vTa+0o5r7AjTAqmA1yH/B3+aAMihUm5ucZSfVqo7+kOaRE8yFj9aivOmA1n1+JLevJq/oyvQyjxQN2Qb89LyaNUT5oKZIiL+uyyhNW3KDR3SSbQ/GBwQNDHVcZi+JDR3RC0r7 ;{id = 1444 (ksk), size = 1024b}
|
||||
example.net. 3600 IN RRSIG DNSKEY 8 2 3600 20070926134150 20070829134150 1444 example.net. hAAlJt/YwAgWBzseK0N42+ysSMaWgntcuftF8a43chLh+fbe3vPWrgwqr/Cic52tu4ZqMox592tqWDxAG7F1eDGfO0SfzS2C9Tc/Wnz5nFjFh75G4Mtt8DTv5vTyGUVX5zAFzV8SNijVC0o1F7MHaVPt3rFtjjg2zW/UOz2m9+U=
|
||||
ENTRY_END
|
||||
|
||||
; For sub1.example.net. zone; it is co-hosted with example.net, so that
|
||||
; there can be failures for the DS lookup. But the data lookup succeeds.
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
www.sub1.example.net. IN A
|
||||
SECTION ANSWER
|
||||
www.sub1.example.net. IN A 10.20.30.41
|
||||
www.sub1.example.net. 3600 IN RRSIG A 8 4 3600 20070926134150 20070829134150 29332 sub1.example.net. NcFP77Hixawt8hb+STIbbeqdF9tWTuHsbGEB4agKXlwHqS0BnyA+It6+UdE57IF0Kbnc7gSuaslX9At8ctd4HuC/9F/osbo96o23JEfnXPky/r5SsLaeN5KmUmUVjG9oxyAEc6PVlaaQ5a/RhaxmDRaDiku2gB7KjdjPxwxe+Rc54GV2eM3GtcfT+oDakLdSSACqeVjUFIOtYMpG8jAHrBe4uSnjKI7O0fWDFN5OES6sN9iUS9/ceorIoF/gSIqM7xWEuPLxE2c5TtYJyPtMCeGJ9wBP4wrTXfJ58+Lg5SFKgEuKTvAqEv9KEwg/kJb1GQ+ho5XKFO6EII2iyeUK/w==
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR SERVFAIL
|
||||
SECTION QUESTION
|
||||
sub1.example.net. IN DS
|
||||
SECTION ANSWER
|
||||
; no DS for sub1.example.net id=29332 algo=8
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
www.sub2.example.net. IN A
|
||||
SECTION ANSWER
|
||||
www.sub2.example.net. IN A 10.20.30.42
|
||||
www.sub2.example.net. 3600 IN RRSIG A 8 4 3600 20070926134150 20070829134150 29332 sub2.example.net. FOY6YxNoFyrSkBtWV7HcECmORTMedRWHdGk7Rm04icT8Bw0dWfzVaIpAkBY6FXx8UvqN7McN4IJI5dAVXptfekO+Yvy2PwkjehRUXvQK64XH5UM5pVbX5g8E4pnOrLa/jzPB7srzMpyWVCpt81lPoFpdfXUMm7434ifkTYhpAll7y5NAocFiT3F+XGe06qMIr51WxoFfegIGohMFhkTDUdLWrdV10128W+NzPdwoYtiigtCObKxTtyj3gK+mxqXvX4X4F2YIGQ+mx62ovdUilnLYZm/WC/ZQkdxeOZjeCTxvSpGGG+wtu1QufgIJ+BpAZAOxREOYZkhR29AG0np4EA==
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR SERVFAIL
|
||||
SECTION QUESTION
|
||||
sub2.example.net. IN DNSKEY
|
||||
SECTION ANSWER
|
||||
; sub2.example.net. IN DNSKEY 257 3 8 AwEAAb4WMOTBLTFvmBra5m6SK4VfViOzmvyUAU0qv861ZQXeEFvwlndqNU9rwRsMxrSWAYs5nHErKDn49usC/HyxxW1477iGFHhfgL4mjNreJm9zft2QFB1VLbRbEPYdDMLCn4co0qnG7/KG8W2i8Pym1L7f+aREwbLo+/716AS2PbaKMhfWLKLiq5wnBcUClQMNzCiwhqxDJp1oePqfkVdeUgXOtgi0dYRIKyQFhJ5VWJ22npoi/Gif0XLCADAlAwRLKc8o/yJkCxskzgpHpw5Cki1lclg0aq4ssOuPRQ+ne6IHYCz9D2mwzulblhLFamKdq7aHzNt4NlyxhpANVFiKLD8= ;{id = 29332 (ksk), size = 2048b}
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
sub2.example.net. IN DS
|
||||
SECTION ANSWER
|
||||
sub2.example.net. 3600 IN DS 29332 8 2 d53e615d9d736b0f2a0097f1d5fa51c84320610f94ecbd7197e7de5f44f02d72
|
||||
sub2.example.net. 3600 IN RRSIG DS 8 3 3600 20070926134150 20070829134150 1444 example.net. dYLYs1uMxJm5+MB6L1+uStE5S1YtyYR0JF+1pPoTptc/H1hYqMxK7pVQPtIGvq8j8wNyC7jOzALfEXgwRKiSdR1l1GQ5HIxWkhUmkpLcecwJOjemee4nXaifOFa5bdbdYpuDwTiIzx+PvanlaVjEPy0i1IukanDi6jojfyWcgLA=
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
STEP 1 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
; The DNSKEY lookup for the key prime is a failure.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ede=9
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
|
||||
STEP 20 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
www.sub1.example.net. IN A
|
||||
ENTRY_END
|
||||
|
||||
; The DS lookup is a failure.
|
||||
STEP 30 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ede=23
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.sub1.example.net. IN A
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
|
||||
STEP 40 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
www.sub2.example.net. IN A
|
||||
ENTRY_END
|
||||
|
||||
; The DNSKEY lookup is a failure.
|
||||
STEP 50 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ede=9
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.sub2.example.net. IN A
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
@@ -466,6 +466,18 @@ void *unbound_stat_realloc(void *ptr, size_t size)
|
||||
memcpy(res+8, &mem_special, sizeof(mem_special));
|
||||
return res+16;
|
||||
}
|
||||
/** strdup with stats */
|
||||
char *unbound_stat_strdup(const char* s)
|
||||
{
|
||||
size_t len;
|
||||
char* res;
|
||||
if(!s) return NULL;
|
||||
len = strlen(s);
|
||||
res = unbound_stat_malloc(len+1);
|
||||
if(!res) return NULL;
|
||||
memmove(res, s, len+1);
|
||||
return res;
|
||||
}
|
||||
|
||||
/** log to file where alloc was done */
|
||||
void *unbound_stat_malloc_log(size_t size, const char* file, int line,
|
||||
@@ -507,6 +519,15 @@ void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
|
||||
return unbound_stat_realloc(ptr, size);
|
||||
}
|
||||
|
||||
/** log to file where strdup was done */
|
||||
char *unbound_stat_strdup_log(const char *s, const char* file, int line,
|
||||
const char* func)
|
||||
{
|
||||
log_info("%s:%d %s strdup size %u", file, line, func,
|
||||
(s?(unsigned)strlen(s)+1:0));
|
||||
return unbound_stat_strdup(s);
|
||||
}
|
||||
|
||||
#endif /* UNBOUND_ALLOC_STATS */
|
||||
#ifdef UNBOUND_ALLOC_LITE
|
||||
#undef malloc
|
||||
|
||||
@@ -387,6 +387,7 @@ config_create(void)
|
||||
memset(cfg->cookie_secret, 0, sizeof(cfg->cookie_secret));
|
||||
cfg->cookie_secret_len = 16;
|
||||
init_cookie_secret(cfg->cookie_secret, cfg->cookie_secret_len);
|
||||
cfg->cookie_secret_file = NULL;
|
||||
#ifdef USE_CACHEDB
|
||||
if(!(cfg->cachedb_backend = strdup("testframe"))) goto error_exit;
|
||||
if(!(cfg->cachedb_secret = strdup("default"))) goto error_exit;
|
||||
@@ -770,6 +771,7 @@ int config_set_option(struct config_file* cfg, const char* opt,
|
||||
else S_YNO("dnstap-send-version:", dnstap_send_version)
|
||||
else S_STR("dnstap-identity:", dnstap_identity)
|
||||
else S_STR("dnstap-version:", dnstap_version)
|
||||
else S_NUMBER_OR_ZERO("dnstap-sample-rate:", dnstap_sample_rate)
|
||||
else S_YNO("dnstap-log-resolver-query-messages:",
|
||||
dnstap_log_resolver_query_messages)
|
||||
else S_YNO("dnstap-log-resolver-response-messages:",
|
||||
@@ -838,6 +840,8 @@ int config_set_option(struct config_file* cfg, const char* opt,
|
||||
{ IS_NUMBER_OR_ZERO; cfg->ipsecmod_max_ttl = atoi(val); }
|
||||
else S_YNO("ipsecmod-strict:", ipsecmod_strict)
|
||||
#endif
|
||||
else S_YNO("answer-cookie:", do_answer_cookie)
|
||||
else S_STR("cookie-secret-file:", cookie_secret_file)
|
||||
#ifdef USE_CACHEDB
|
||||
else S_YNO("cachedb-no-store:", cachedb_no_store)
|
||||
else S_YNO("cachedb-check-when-serve-expired:", cachedb_check_when_serve_expired)
|
||||
@@ -1249,6 +1253,7 @@ config_get_option(struct config_file* cfg, const char* opt,
|
||||
else O_YNO(opt, "dnstap-send-version", dnstap_send_version)
|
||||
else O_STR(opt, "dnstap-identity", dnstap_identity)
|
||||
else O_STR(opt, "dnstap-version", dnstap_version)
|
||||
else O_UNS(opt, "dnstap-sample-rate", dnstap_sample_rate)
|
||||
else O_YNO(opt, "dnstap-log-resolver-query-messages",
|
||||
dnstap_log_resolver_query_messages)
|
||||
else O_YNO(opt, "dnstap-log-resolver-response-messages",
|
||||
@@ -1334,6 +1339,8 @@ config_get_option(struct config_file* cfg, const char* opt,
|
||||
else O_LST(opt, "ipsecmod-whitelist", ipsecmod_whitelist)
|
||||
else O_YNO(opt, "ipsecmod-strict", ipsecmod_strict)
|
||||
#endif
|
||||
else O_YNO(opt, "answer-cookie", do_answer_cookie)
|
||||
else O_STR(opt, "cookie-secret-file", cookie_secret_file)
|
||||
#ifdef USE_CACHEDB
|
||||
else O_STR(opt, "backend", cachedb_backend)
|
||||
else O_STR(opt, "secret-seed", cachedb_secret)
|
||||
@@ -1719,6 +1726,7 @@ config_delete(struct config_file* cfg)
|
||||
free(cfg->ipsecmod_hook);
|
||||
config_delstrlist(cfg->ipsecmod_whitelist);
|
||||
#endif
|
||||
free(cfg->cookie_secret_file);
|
||||
#ifdef USE_CACHEDB
|
||||
free(cfg->cachedb_backend);
|
||||
free(cfg->cachedb_secret);
|
||||
|
||||
@@ -592,6 +592,8 @@ struct config_file {
|
||||
char* dnstap_identity;
|
||||
/** dnstap "version", package version is used if "". */
|
||||
char* dnstap_version;
|
||||
/** dnstap sample rate */
|
||||
int dnstap_sample_rate;
|
||||
|
||||
/** true to log dnstap RESOLVER_QUERY message events */
|
||||
int dnstap_log_resolver_query_messages;
|
||||
@@ -748,6 +750,8 @@ struct config_file {
|
||||
uint8_t cookie_secret[40];
|
||||
/** cookie secret length */
|
||||
size_t cookie_secret_len;
|
||||
/** path to cookie secret store */
|
||||
char* cookie_secret_file;
|
||||
|
||||
/* ipset module */
|
||||
#ifdef USE_IPSET
|
||||
|
||||
@@ -513,6 +513,7 @@ dnstap-log-forwarder-query-messages{COLON} {
|
||||
YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES) }
|
||||
dnstap-log-forwarder-response-messages{COLON} {
|
||||
YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES) }
|
||||
dnstap-sample-rate { YDVAR(1, VAR_DNSTAP_SAMPLE_RATE) }
|
||||
disable-dnssec-lame-check{COLON} { YDVAR(1, VAR_DISABLE_DNSSEC_LAME_CHECK) }
|
||||
ip-ratelimit{COLON} { YDVAR(1, VAR_IP_RATELIMIT) }
|
||||
ip-ratelimit-cookie{COLON} { YDVAR(1, VAR_IP_RATELIMIT_COOKIE) }
|
||||
@@ -581,6 +582,7 @@ udp-upstream-without-downstream{COLON} { YDVAR(1, VAR_UDP_UPSTREAM_WITHOUT_DOWNS
|
||||
tcp-connection-limit{COLON} { YDVAR(2, VAR_TCP_CONNECTION_LIMIT) }
|
||||
answer-cookie{COLON} { YDVAR(1, VAR_ANSWER_COOKIE ) }
|
||||
cookie-secret{COLON} { YDVAR(1, VAR_COOKIE_SECRET) }
|
||||
cookie-secret-file{COLON} { YDVAR(1, VAR_COOKIE_SECRET_FILE) }
|
||||
edns-client-string{COLON} { YDVAR(2, VAR_EDNS_CLIENT_STRING) }
|
||||
edns-client-string-opcode{COLON} { YDVAR(1, VAR_EDNS_CLIENT_STRING_OPCODE) }
|
||||
nsid{COLON} { YDVAR(1, VAR_NSID ) }
|
||||
|
||||
+61
-40
@@ -137,6 +137,7 @@ extern struct config_parser_state* cfg_parser;
|
||||
%token VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES
|
||||
%token VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES
|
||||
%token VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES
|
||||
%token VAR_DNSTAP_SAMPLE_RATE
|
||||
%token VAR_RESPONSE_IP_TAG VAR_RESPONSE_IP VAR_RESPONSE_IP_DATA
|
||||
%token VAR_HARDEN_ALGO_DOWNGRADE VAR_IP_TRANSPARENT
|
||||
%token VAR_IP_DSCP
|
||||
@@ -204,6 +205,7 @@ extern struct config_parser_state* cfg_parser;
|
||||
%token VAR_PROXY_PROTOCOL_PORT VAR_STATISTICS_INHIBIT_ZERO
|
||||
%token VAR_HARDEN_UNKNOWN_ADDITIONAL VAR_DISABLE_EDNS_DO VAR_CACHEDB_NO_STORE
|
||||
%token VAR_LOG_DESTADDR VAR_CACHEDB_CHECK_WHEN_SERVE_EXPIRED
|
||||
%token VAR_COOKIE_SECRET_FILE
|
||||
|
||||
%%
|
||||
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
|
||||
@@ -341,7 +343,7 @@ content_server: server_num_threads | server_verbosity | server_port |
|
||||
server_interface_automatic_ports | server_ede |
|
||||
server_proxy_protocol_port | server_statistics_inhibit_zero |
|
||||
server_harden_unknown_additional | server_disable_edns_do |
|
||||
server_log_destaddr
|
||||
server_log_destaddr | server_cookie_secret_file
|
||||
;
|
||||
stubstart: VAR_STUB_ZONE
|
||||
{
|
||||
@@ -3453,7 +3455,8 @@ content_dt: dt_dnstap_enable | dt_dnstap_socket_path | dt_dnstap_bidirectional |
|
||||
dt_dnstap_log_client_query_messages |
|
||||
dt_dnstap_log_client_response_messages |
|
||||
dt_dnstap_log_forwarder_query_messages |
|
||||
dt_dnstap_log_forwarder_response_messages
|
||||
dt_dnstap_log_forwarder_response_messages |
|
||||
dt_dnstap_sample_rate
|
||||
;
|
||||
dt_dnstap_enable: VAR_DNSTAP_ENABLE STRING_ARG
|
||||
{
|
||||
@@ -3617,6 +3620,17 @@ dt_dnstap_log_forwarder_response_messages: VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MES
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
dt_dnstap_sample_rate: VAR_DNSTAP_SAMPLE_RATE STRING_ARG
|
||||
{
|
||||
OUTYY(("P(dt_dnstap_sample_rate:%s)\n", $2));
|
||||
if(atoi($2) == 0 && strcmp($2, "0") != 0)
|
||||
yyerror("number expected");
|
||||
else if(atoi($2) < 0)
|
||||
yyerror("dnstap sample rate too small");
|
||||
else cfg_parser->cfg->dnstap_sample_rate = atoi($2);
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
pythonstart: VAR_PYTHON
|
||||
{
|
||||
OUTYY(("\nP(python:)\n"));
|
||||
@@ -3985,45 +3999,52 @@ server_cookie_secret: VAR_COOKIE_SECRET STRING_ARG
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
ipsetstart: VAR_IPSET
|
||||
{
|
||||
OUTYY(("\nP(ipset:)\n"));
|
||||
cfg_parser->started_toplevel = 1;
|
||||
}
|
||||
;
|
||||
contents_ipset: contents_ipset content_ipset
|
||||
| ;
|
||||
content_ipset: ipset_name_v4 | ipset_name_v6
|
||||
;
|
||||
ipset_name_v4: VAR_IPSET_NAME_V4 STRING_ARG
|
||||
{
|
||||
#ifdef USE_IPSET
|
||||
OUTYY(("P(name-v4:%s)\n", $2));
|
||||
if(cfg_parser->cfg->ipset_name_v4)
|
||||
yyerror("ipset name v4 override, there must be one "
|
||||
"name for ip v4");
|
||||
free(cfg_parser->cfg->ipset_name_v4);
|
||||
cfg_parser->cfg->ipset_name_v4 = $2;
|
||||
#else
|
||||
OUTYY(("P(Compiled without ipset, ignoring)\n"));
|
||||
free($2);
|
||||
#endif
|
||||
}
|
||||
;
|
||||
ipset_name_v6: VAR_IPSET_NAME_V6 STRING_ARG
|
||||
server_cookie_secret_file: VAR_COOKIE_SECRET_FILE STRING_ARG
|
||||
{
|
||||
#ifdef USE_IPSET
|
||||
OUTYY(("P(name-v6:%s)\n", $2));
|
||||
if(cfg_parser->cfg->ipset_name_v6)
|
||||
yyerror("ipset name v6 override, there must be one "
|
||||
"name for ip v6");
|
||||
free(cfg_parser->cfg->ipset_name_v6);
|
||||
cfg_parser->cfg->ipset_name_v6 = $2;
|
||||
#else
|
||||
OUTYY(("P(Compiled without ipset, ignoring)\n"));
|
||||
free($2);
|
||||
#endif
|
||||
}
|
||||
OUTYY(("P(cookie_secret_file:%s)\n", $2));
|
||||
free(cfg_parser->cfg->cookie_secret_file);
|
||||
cfg_parser->cfg->cookie_secret_file = $2;
|
||||
}
|
||||
;
|
||||
ipsetstart: VAR_IPSET
|
||||
{
|
||||
OUTYY(("\nP(ipset:)\n"));
|
||||
cfg_parser->started_toplevel = 1;
|
||||
}
|
||||
;
|
||||
contents_ipset: contents_ipset content_ipset
|
||||
| ;
|
||||
content_ipset: ipset_name_v4 | ipset_name_v6
|
||||
;
|
||||
ipset_name_v4: VAR_IPSET_NAME_V4 STRING_ARG
|
||||
{
|
||||
#ifdef USE_IPSET
|
||||
OUTYY(("P(name-v4:%s)\n", $2));
|
||||
if(cfg_parser->cfg->ipset_name_v4)
|
||||
yyerror("ipset name v4 override, there must be one "
|
||||
"name for ip v4");
|
||||
free(cfg_parser->cfg->ipset_name_v4);
|
||||
cfg_parser->cfg->ipset_name_v4 = $2;
|
||||
#else
|
||||
OUTYY(("P(Compiled without ipset, ignoring)\n"));
|
||||
free($2);
|
||||
#endif
|
||||
}
|
||||
;
|
||||
ipset_name_v6: VAR_IPSET_NAME_V6 STRING_ARG
|
||||
{
|
||||
#ifdef USE_IPSET
|
||||
OUTYY(("P(name-v6:%s)\n", $2));
|
||||
if(cfg_parser->cfg->ipset_name_v6)
|
||||
yyerror("ipset name v6 override, there must be one "
|
||||
"name for ip v6");
|
||||
free(cfg_parser->cfg->ipset_name_v6);
|
||||
cfg_parser->cfg->ipset_name_v6 = $2;
|
||||
#else
|
||||
OUTYY(("P(Compiled without ipset, ignoring)\n"));
|
||||
free($2);
|
||||
#endif
|
||||
}
|
||||
;
|
||||
%%
|
||||
|
||||
|
||||
+46
-31
@@ -62,6 +62,10 @@
|
||||
#define RETVAL_TRUNC -4
|
||||
/** return code that means all is peachy keen. Equal to DNS rcode NOERROR */
|
||||
#define RETVAL_OK 0
|
||||
/** Max compressions we are willing to perform; more than that will result
|
||||
* in semi-compressed messages, or truncated even on TCP for huge messages, to
|
||||
* avoid locking the CPU for long */
|
||||
#define MAX_COMPRESSION_PER_MESSAGE 120
|
||||
|
||||
/**
|
||||
* Data structure to help domain name compression in outgoing messages.
|
||||
@@ -284,15 +288,17 @@ write_compressed_dname(sldns_buffer* pkt, uint8_t* dname, int labs,
|
||||
|
||||
/** compress owner name of RR, return RETVAL_OUTMEM RETVAL_TRUNC */
|
||||
static int
|
||||
compress_owner(struct ub_packed_rrset_key* key, sldns_buffer* pkt,
|
||||
struct regional* region, struct compress_tree_node** tree,
|
||||
size_t owner_pos, uint16_t* owner_ptr, int owner_labs)
|
||||
compress_owner(struct ub_packed_rrset_key* key, sldns_buffer* pkt,
|
||||
struct regional* region, struct compress_tree_node** tree,
|
||||
size_t owner_pos, uint16_t* owner_ptr, int owner_labs,
|
||||
size_t* compress_count)
|
||||
{
|
||||
struct compress_tree_node* p;
|
||||
struct compress_tree_node** insertpt = NULL;
|
||||
if(!*owner_ptr) {
|
||||
/* compress first time dname */
|
||||
if((p = compress_tree_lookup(tree, key->rk.dname,
|
||||
if(*compress_count < MAX_COMPRESSION_PER_MESSAGE &&
|
||||
(p = compress_tree_lookup(tree, key->rk.dname,
|
||||
owner_labs, &insertpt))) {
|
||||
if(p->labs == owner_labs)
|
||||
/* avoid ptr chains, since some software is
|
||||
@@ -301,6 +307,7 @@ compress_owner(struct ub_packed_rrset_key* key, sldns_buffer* pkt,
|
||||
if(!write_compressed_dname(pkt, key->rk.dname,
|
||||
owner_labs, p))
|
||||
return RETVAL_TRUNC;
|
||||
(*compress_count)++;
|
||||
/* check if typeclass+4 ttl + rdatalen is available */
|
||||
if(sldns_buffer_remaining(pkt) < 4+4+2)
|
||||
return RETVAL_TRUNC;
|
||||
@@ -313,7 +320,8 @@ compress_owner(struct ub_packed_rrset_key* key, sldns_buffer* pkt,
|
||||
if(owner_pos <= PTR_MAX_OFFSET)
|
||||
*owner_ptr = htons(PTR_CREATE(owner_pos));
|
||||
}
|
||||
if(!compress_tree_store(key->rk.dname, owner_labs,
|
||||
if(*compress_count < MAX_COMPRESSION_PER_MESSAGE &&
|
||||
!compress_tree_store(key->rk.dname, owner_labs,
|
||||
owner_pos, region, p, insertpt))
|
||||
return RETVAL_OUTMEM;
|
||||
} else {
|
||||
@@ -333,20 +341,24 @@ compress_owner(struct ub_packed_rrset_key* key, sldns_buffer* pkt,
|
||||
|
||||
/** compress any domain name to the packet, return RETVAL_* */
|
||||
static int
|
||||
compress_any_dname(uint8_t* dname, sldns_buffer* pkt, int labs,
|
||||
struct regional* region, struct compress_tree_node** tree)
|
||||
compress_any_dname(uint8_t* dname, sldns_buffer* pkt, int labs,
|
||||
struct regional* region, struct compress_tree_node** tree,
|
||||
size_t* compress_count)
|
||||
{
|
||||
struct compress_tree_node* p;
|
||||
struct compress_tree_node** insertpt = NULL;
|
||||
size_t pos = sldns_buffer_position(pkt);
|
||||
if((p = compress_tree_lookup(tree, dname, labs, &insertpt))) {
|
||||
if(*compress_count < MAX_COMPRESSION_PER_MESSAGE &&
|
||||
(p = compress_tree_lookup(tree, dname, labs, &insertpt))) {
|
||||
if(!write_compressed_dname(pkt, dname, labs, p))
|
||||
return RETVAL_TRUNC;
|
||||
(*compress_count)++;
|
||||
} else {
|
||||
if(!dname_buffer_write(pkt, dname))
|
||||
return RETVAL_TRUNC;
|
||||
}
|
||||
if(!compress_tree_store(dname, labs, pos, region, p, insertpt))
|
||||
if(*compress_count < MAX_COMPRESSION_PER_MESSAGE &&
|
||||
!compress_tree_store(dname, labs, pos, region, p, insertpt))
|
||||
return RETVAL_OUTMEM;
|
||||
return RETVAL_OK;
|
||||
}
|
||||
@@ -364,9 +376,9 @@ type_rdata_compressable(struct ub_packed_rrset_key* key)
|
||||
|
||||
/** compress domain names in rdata, return RETVAL_* */
|
||||
static int
|
||||
compress_rdata(sldns_buffer* pkt, uint8_t* rdata, size_t todolen,
|
||||
struct regional* region, struct compress_tree_node** tree,
|
||||
const sldns_rr_descriptor* desc)
|
||||
compress_rdata(sldns_buffer* pkt, uint8_t* rdata, size_t todolen,
|
||||
struct regional* region, struct compress_tree_node** tree,
|
||||
const sldns_rr_descriptor* desc, size_t* compress_count)
|
||||
{
|
||||
int labs, r, rdf = 0;
|
||||
size_t dname_len, len, pos = sldns_buffer_position(pkt);
|
||||
@@ -380,8 +392,8 @@ compress_rdata(sldns_buffer* pkt, uint8_t* rdata, size_t todolen,
|
||||
switch(desc->_wireformat[rdf]) {
|
||||
case LDNS_RDF_TYPE_DNAME:
|
||||
labs = dname_count_size_labels(rdata, &dname_len);
|
||||
if((r=compress_any_dname(rdata, pkt, labs, region,
|
||||
tree)) != RETVAL_OK)
|
||||
if((r=compress_any_dname(rdata, pkt, labs, region,
|
||||
tree, compress_count)) != RETVAL_OK)
|
||||
return r;
|
||||
rdata += dname_len;
|
||||
todolen -= dname_len;
|
||||
@@ -449,7 +461,8 @@ static int
|
||||
packed_rrset_encode(struct ub_packed_rrset_key* key, sldns_buffer* pkt,
|
||||
uint16_t* num_rrs, time_t timenow, struct regional* region,
|
||||
int do_data, int do_sig, struct compress_tree_node** tree,
|
||||
sldns_pkt_section s, uint16_t qtype, int dnssec, size_t rr_offset)
|
||||
sldns_pkt_section s, uint16_t qtype, int dnssec, size_t rr_offset,
|
||||
size_t* compress_count)
|
||||
{
|
||||
size_t i, j, owner_pos;
|
||||
int r, owner_labs;
|
||||
@@ -477,9 +490,9 @@ packed_rrset_encode(struct ub_packed_rrset_key* key, sldns_buffer* pkt,
|
||||
for(i=0; i<data->count; i++) {
|
||||
/* rrset roundrobin */
|
||||
j = (i + rr_offset) % data->count;
|
||||
if((r=compress_owner(key, pkt, region, tree,
|
||||
owner_pos, &owner_ptr, owner_labs))
|
||||
!= RETVAL_OK)
|
||||
if((r=compress_owner(key, pkt, region, tree,
|
||||
owner_pos, &owner_ptr, owner_labs,
|
||||
compress_count)) != RETVAL_OK)
|
||||
return r;
|
||||
sldns_buffer_write(pkt, &key->rk.type, 2);
|
||||
sldns_buffer_write(pkt, &key->rk.rrset_class, 2);
|
||||
@@ -489,8 +502,8 @@ packed_rrset_encode(struct ub_packed_rrset_key* key, sldns_buffer* pkt,
|
||||
else sldns_buffer_write_u32(pkt, data->rr_ttl[j]-adjust);
|
||||
if(c) {
|
||||
if((r=compress_rdata(pkt, data->rr_data[j],
|
||||
data->rr_len[j], region, tree, c))
|
||||
!= RETVAL_OK)
|
||||
data->rr_len[j], region, tree, c,
|
||||
compress_count)) != RETVAL_OK)
|
||||
return r;
|
||||
} else {
|
||||
if(sldns_buffer_remaining(pkt) < data->rr_len[j])
|
||||
@@ -510,9 +523,9 @@ packed_rrset_encode(struct ub_packed_rrset_key* key, sldns_buffer* pkt,
|
||||
return RETVAL_TRUNC;
|
||||
sldns_buffer_write(pkt, &owner_ptr, 2);
|
||||
} else {
|
||||
if((r=compress_any_dname(key->rk.dname,
|
||||
pkt, owner_labs, region, tree))
|
||||
!= RETVAL_OK)
|
||||
if((r=compress_any_dname(key->rk.dname,
|
||||
pkt, owner_labs, region, tree,
|
||||
compress_count)) != RETVAL_OK)
|
||||
return r;
|
||||
if(sldns_buffer_remaining(pkt) <
|
||||
4+4+data->rr_len[i])
|
||||
@@ -544,7 +557,8 @@ static int
|
||||
insert_section(struct reply_info* rep, size_t num_rrsets, uint16_t* num_rrs,
|
||||
sldns_buffer* pkt, size_t rrsets_before, time_t timenow,
|
||||
struct regional* region, struct compress_tree_node** tree,
|
||||
sldns_pkt_section s, uint16_t qtype, int dnssec, size_t rr_offset)
|
||||
sldns_pkt_section s, uint16_t qtype, int dnssec, size_t rr_offset,
|
||||
size_t* compress_count)
|
||||
{
|
||||
int r;
|
||||
size_t i, setstart;
|
||||
@@ -560,7 +574,7 @@ insert_section(struct reply_info* rep, size_t num_rrsets, uint16_t* num_rrs,
|
||||
setstart = sldns_buffer_position(pkt);
|
||||
if((r=packed_rrset_encode(rep->rrsets[rrsets_before+i],
|
||||
pkt, num_rrs, timenow, region, 1, 1, tree,
|
||||
s, qtype, dnssec, rr_offset))
|
||||
s, qtype, dnssec, rr_offset, compress_count))
|
||||
!= RETVAL_OK) {
|
||||
/* Bad, but if due to size must set TC bit */
|
||||
/* trim off the rrset neatly. */
|
||||
@@ -573,7 +587,7 @@ insert_section(struct reply_info* rep, size_t num_rrsets, uint16_t* num_rrs,
|
||||
setstart = sldns_buffer_position(pkt);
|
||||
if((r=packed_rrset_encode(rep->rrsets[rrsets_before+i],
|
||||
pkt, num_rrs, timenow, region, 1, 0, tree,
|
||||
s, qtype, dnssec, rr_offset))
|
||||
s, qtype, dnssec, rr_offset, compress_count))
|
||||
!= RETVAL_OK) {
|
||||
sldns_buffer_set_position(pkt, setstart);
|
||||
return r;
|
||||
@@ -584,7 +598,7 @@ insert_section(struct reply_info* rep, size_t num_rrsets, uint16_t* num_rrs,
|
||||
setstart = sldns_buffer_position(pkt);
|
||||
if((r=packed_rrset_encode(rep->rrsets[rrsets_before+i],
|
||||
pkt, num_rrs, timenow, region, 0, 1, tree,
|
||||
s, qtype, dnssec, rr_offset))
|
||||
s, qtype, dnssec, rr_offset, compress_count))
|
||||
!= RETVAL_OK) {
|
||||
sldns_buffer_set_position(pkt, setstart);
|
||||
return r;
|
||||
@@ -677,6 +691,7 @@ reply_info_encode(struct query_info* qinfo, struct reply_info* rep,
|
||||
struct compress_tree_node* tree = 0;
|
||||
int r;
|
||||
size_t rr_offset;
|
||||
size_t compress_count=0;
|
||||
|
||||
sldns_buffer_clear(buffer);
|
||||
if(udpsize < sldns_buffer_limit(buffer))
|
||||
@@ -723,7 +738,7 @@ reply_info_encode(struct query_info* qinfo, struct reply_info* rep,
|
||||
arep.rrsets = &qinfo->local_alias->rrset;
|
||||
if((r=insert_section(&arep, 1, &ancount, buffer, 0,
|
||||
timezero, region, &tree, LDNS_SECTION_ANSWER,
|
||||
qinfo->qtype, dnssec, rr_offset)) != RETVAL_OK) {
|
||||
qinfo->qtype, dnssec, rr_offset, &compress_count)) != RETVAL_OK) {
|
||||
if(r == RETVAL_TRUNC) {
|
||||
/* create truncated message */
|
||||
sldns_buffer_write_u16_at(buffer, 6, ancount);
|
||||
@@ -738,7 +753,7 @@ reply_info_encode(struct query_info* qinfo, struct reply_info* rep,
|
||||
/* insert answer section */
|
||||
if((r=insert_section(rep, rep->an_numrrsets, &ancount, buffer,
|
||||
0, timenow, region, &tree, LDNS_SECTION_ANSWER, qinfo->qtype,
|
||||
dnssec, rr_offset)) != RETVAL_OK) {
|
||||
dnssec, rr_offset, &compress_count)) != RETVAL_OK) {
|
||||
if(r == RETVAL_TRUNC) {
|
||||
/* create truncated message */
|
||||
sldns_buffer_write_u16_at(buffer, 6, ancount);
|
||||
@@ -756,7 +771,7 @@ reply_info_encode(struct query_info* qinfo, struct reply_info* rep,
|
||||
if((r=insert_section(rep, rep->ns_numrrsets, &nscount, buffer,
|
||||
rep->an_numrrsets, timenow, region, &tree,
|
||||
LDNS_SECTION_AUTHORITY, qinfo->qtype,
|
||||
dnssec, rr_offset)) != RETVAL_OK) {
|
||||
dnssec, rr_offset, &compress_count)) != RETVAL_OK) {
|
||||
if(r == RETVAL_TRUNC) {
|
||||
/* create truncated message */
|
||||
sldns_buffer_write_u16_at(buffer, 8, nscount);
|
||||
@@ -773,7 +788,7 @@ reply_info_encode(struct query_info* qinfo, struct reply_info* rep,
|
||||
if((r=insert_section(rep, rep->ar_numrrsets, &arcount, buffer,
|
||||
rep->an_numrrsets + rep->ns_numrrsets, timenow, region,
|
||||
&tree, LDNS_SECTION_ADDITIONAL, qinfo->qtype,
|
||||
dnssec, rr_offset)) != RETVAL_OK) {
|
||||
dnssec, rr_offset, &compress_count)) != RETVAL_OK) {
|
||||
if(r == RETVAL_TRUNC) {
|
||||
/* no need to set TC bit, this is the additional */
|
||||
sldns_buffer_write_u16_at(buffer, 10, arcount);
|
||||
|
||||
+40
-10
@@ -947,7 +947,8 @@ parse_packet(sldns_buffer* pkt, struct msg_parse* msg, struct regional* region)
|
||||
static int
|
||||
parse_edns_options_from_query(uint8_t* rdata_ptr, size_t rdata_len,
|
||||
struct edns_data* edns, struct config_file* cfg, struct comm_point* c,
|
||||
struct comm_reply* repinfo, uint32_t now, struct regional* region)
|
||||
struct comm_reply* repinfo, uint32_t now, struct regional* region,
|
||||
struct cookie_secrets* cookie_secrets)
|
||||
{
|
||||
/* To respond with a Keepalive option, the client connection must have
|
||||
* received one message with a TCP Keepalive EDNS option, and that
|
||||
@@ -1070,13 +1071,24 @@ parse_edns_options_from_query(uint8_t* rdata_ptr, size_t rdata_len,
|
||||
&((struct sockaddr_in6*)&repinfo->remote_addr)->sin6_addr, 16);
|
||||
}
|
||||
|
||||
cookie_val_status = edns_cookie_server_validate(
|
||||
rdata_ptr, opt_len, cfg->cookie_secret,
|
||||
cfg->cookie_secret_len, cookie_is_v4,
|
||||
server_cookie, now);
|
||||
if(cfg->cookie_secret_file &&
|
||||
cfg->cookie_secret_file[0]) {
|
||||
/* Loop over the active and staging cookies. */
|
||||
cookie_val_status =
|
||||
cookie_secrets_server_validate(
|
||||
rdata_ptr, opt_len, cookie_secrets,
|
||||
cookie_is_v4, server_cookie, now);
|
||||
} else {
|
||||
/* Use the cookie option value to validate. */
|
||||
cookie_val_status = edns_cookie_server_validate(
|
||||
rdata_ptr, opt_len, cfg->cookie_secret,
|
||||
cfg->cookie_secret_len, cookie_is_v4,
|
||||
server_cookie, now);
|
||||
}
|
||||
if(cookie_val_status == COOKIE_STATUS_VALID_RENEW)
|
||||
edns->cookie_valid = 1;
|
||||
switch(cookie_val_status) {
|
||||
case COOKIE_STATUS_VALID:
|
||||
case COOKIE_STATUS_VALID_RENEW:
|
||||
edns->cookie_valid = 1;
|
||||
/* Reuse cookie */
|
||||
if(!edns_opt_list_append(
|
||||
@@ -1091,13 +1103,30 @@ parse_edns_options_from_query(uint8_t* rdata_ptr, size_t rdata_len,
|
||||
break;
|
||||
case COOKIE_STATUS_CLIENT_ONLY:
|
||||
edns->cookie_client = 1;
|
||||
ATTR_FALLTHROUGH
|
||||
/* fallthrough */
|
||||
case COOKIE_STATUS_VALID_RENEW:
|
||||
case COOKIE_STATUS_FUTURE:
|
||||
case COOKIE_STATUS_EXPIRED:
|
||||
case COOKIE_STATUS_INVALID:
|
||||
default:
|
||||
edns_cookie_server_write(server_cookie,
|
||||
cfg->cookie_secret, cookie_is_v4, now);
|
||||
if(cfg->cookie_secret_file &&
|
||||
cfg->cookie_secret_file[0]) {
|
||||
if(!cookie_secrets)
|
||||
break;
|
||||
lock_basic_lock(&cookie_secrets->lock);
|
||||
if(cookie_secrets->cookie_count < 1) {
|
||||
lock_basic_unlock(&cookie_secrets->lock);
|
||||
break;
|
||||
}
|
||||
edns_cookie_server_write(server_cookie,
|
||||
cookie_secrets->cookie_secrets[0].cookie_secret,
|
||||
cookie_is_v4, now);
|
||||
lock_basic_unlock(&cookie_secrets->lock);
|
||||
} else {
|
||||
edns_cookie_server_write(server_cookie,
|
||||
cfg->cookie_secret, cookie_is_v4, now);
|
||||
}
|
||||
if(!edns_opt_list_append(&edns->opt_list_out,
|
||||
LDNS_EDNS_COOKIE, 24, server_cookie,
|
||||
region)) {
|
||||
@@ -1239,7 +1268,8 @@ skip_pkt_rrs(sldns_buffer* pkt, int num)
|
||||
int
|
||||
parse_edns_from_query_pkt(sldns_buffer* pkt, struct edns_data* edns,
|
||||
struct config_file* cfg, struct comm_point* c,
|
||||
struct comm_reply* repinfo, time_t now, struct regional* region)
|
||||
struct comm_reply* repinfo, time_t now, struct regional* region,
|
||||
struct cookie_secrets* cookie_secrets)
|
||||
{
|
||||
size_t rdata_len;
|
||||
uint8_t* rdata_ptr;
|
||||
@@ -1285,7 +1315,7 @@ parse_edns_from_query_pkt(sldns_buffer* pkt, struct edns_data* edns,
|
||||
rdata_ptr = sldns_buffer_current(pkt);
|
||||
/* ignore rrsigs */
|
||||
return parse_edns_options_from_query(rdata_ptr, rdata_len, edns, cfg,
|
||||
c, repinfo, now, region);
|
||||
c, repinfo, now, region, cookie_secrets);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -73,6 +73,7 @@ struct edns_option;
|
||||
struct config_file;
|
||||
struct comm_point;
|
||||
struct comm_reply;
|
||||
struct cookie_secrets;
|
||||
|
||||
/** number of buckets in parse rrset hash table. Must be power of 2. */
|
||||
#define PARSE_TABLE_SIZE 32
|
||||
@@ -322,12 +323,14 @@ int skip_pkt_rrs(struct sldns_buffer* pkt, int num);
|
||||
* @param repinfo: commreply to determine the client address
|
||||
* @param now: current time
|
||||
* @param region: region to alloc results in (edns option contents)
|
||||
* @param cookie_secrets: the cookie secrets for EDNS COOKIE validation.
|
||||
* @return: 0 on success, or an RCODE on error.
|
||||
* RCODE formerr if OPT is badly formatted and so on.
|
||||
*/
|
||||
int parse_edns_from_query_pkt(struct sldns_buffer* pkt, struct edns_data* edns,
|
||||
struct config_file* cfg, struct comm_point* c,
|
||||
struct comm_reply* repinfo, time_t now, struct regional* region);
|
||||
struct comm_reply* repinfo, time_t now, struct regional* region,
|
||||
struct cookie_secrets* cookie_secrets);
|
||||
|
||||
/**
|
||||
* Calculate hash value for rrset in packet.
|
||||
|
||||
+186
@@ -187,3 +187,189 @@ edns_cookie_server_validate(const uint8_t* cookie, size_t cookie_len,
|
||||
return COOKIE_STATUS_VALID_RENEW;
|
||||
return COOKIE_STATUS_VALID;
|
||||
}
|
||||
|
||||
struct cookie_secrets*
|
||||
cookie_secrets_create(void)
|
||||
{
|
||||
struct cookie_secrets* cookie_secrets = calloc(1,
|
||||
sizeof(*cookie_secrets));
|
||||
if(!cookie_secrets)
|
||||
return NULL;
|
||||
lock_basic_init(&cookie_secrets->lock);
|
||||
lock_protect(&cookie_secrets->lock, &cookie_secrets->cookie_count,
|
||||
sizeof(cookie_secrets->cookie_count));
|
||||
lock_protect(&cookie_secrets->lock, cookie_secrets->cookie_secrets,
|
||||
sizeof(cookie_secret_type)*UNBOUND_COOKIE_HISTORY_SIZE);
|
||||
return cookie_secrets;
|
||||
}
|
||||
|
||||
void
|
||||
cookie_secrets_delete(struct cookie_secrets* cookie_secrets)
|
||||
{
|
||||
if(!cookie_secrets)
|
||||
return;
|
||||
lock_basic_destroy(&cookie_secrets->lock);
|
||||
explicit_bzero(cookie_secrets->cookie_secrets,
|
||||
sizeof(cookie_secret_type)*UNBOUND_COOKIE_HISTORY_SIZE);
|
||||
free(cookie_secrets);
|
||||
}
|
||||
|
||||
/** Read the cookie secret file */
|
||||
static int
|
||||
cookie_secret_file_read(struct cookie_secrets* cookie_secrets,
|
||||
char* cookie_secret_file)
|
||||
{
|
||||
char secret[UNBOUND_COOKIE_SECRET_SIZE * 2 + 2/*'\n' and '\0'*/];
|
||||
FILE* f;
|
||||
int corrupt = 0;
|
||||
size_t count;
|
||||
|
||||
log_assert(cookie_secret_file != NULL);
|
||||
cookie_secrets->cookie_count = 0;
|
||||
f = fopen(cookie_secret_file, "r");
|
||||
/* a non-existing cookie file is not an error */
|
||||
if( f == NULL ) {
|
||||
if(errno != EPERM) {
|
||||
log_err("Could not read cookie-secret-file '%s': %s",
|
||||
cookie_secret_file, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/* cookie secret file exists and is readable */
|
||||
for( count = 0; count < UNBOUND_COOKIE_HISTORY_SIZE; count++ ) {
|
||||
size_t secret_len = 0;
|
||||
ssize_t decoded_len = 0;
|
||||
if( fgets(secret, sizeof(secret), f) == NULL ) { break; }
|
||||
secret_len = strlen(secret);
|
||||
if( secret_len == 0 ) { break; }
|
||||
log_assert( secret_len <= sizeof(secret) );
|
||||
secret_len = secret[secret_len - 1] == '\n' ? secret_len - 1 : secret_len;
|
||||
if( secret_len != UNBOUND_COOKIE_SECRET_SIZE * 2 ) { corrupt++; break; }
|
||||
/* needed for `hex_pton`; stripping potential `\n` */
|
||||
secret[secret_len] = '\0';
|
||||
decoded_len = hex_pton(secret, cookie_secrets->cookie_secrets[count].cookie_secret,
|
||||
UNBOUND_COOKIE_SECRET_SIZE);
|
||||
if( decoded_len != UNBOUND_COOKIE_SECRET_SIZE ) { corrupt++; break; }
|
||||
cookie_secrets->cookie_count++;
|
||||
}
|
||||
fclose(f);
|
||||
return corrupt == 0;
|
||||
}
|
||||
|
||||
int
|
||||
cookie_secrets_apply_cfg(struct cookie_secrets* cookie_secrets,
|
||||
char* cookie_secret_file)
|
||||
{
|
||||
if(!cookie_secrets) {
|
||||
if(!cookie_secret_file || !cookie_secret_file[0])
|
||||
return 1; /* There is nothing to read anyway */
|
||||
log_err("Could not read cookie secrets, no structure alloced");
|
||||
return 0;
|
||||
}
|
||||
if(!cookie_secret_file_read(cookie_secrets, cookie_secret_file))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
enum edns_cookie_val_status
|
||||
cookie_secrets_server_validate(const uint8_t* cookie, size_t cookie_len,
|
||||
struct cookie_secrets* cookie_secrets, int v4,
|
||||
const uint8_t* hash_input, uint32_t now)
|
||||
{
|
||||
size_t i;
|
||||
enum edns_cookie_val_status cookie_val_status,
|
||||
last = COOKIE_STATUS_INVALID;
|
||||
if(!cookie_secrets)
|
||||
return COOKIE_STATUS_INVALID; /* There are no cookie secrets.*/
|
||||
lock_basic_lock(&cookie_secrets->lock);
|
||||
if(cookie_secrets->cookie_count == 0) {
|
||||
lock_basic_unlock(&cookie_secrets->lock);
|
||||
return COOKIE_STATUS_INVALID; /* There are no cookie secrets.*/
|
||||
}
|
||||
for(i=0; i<cookie_secrets->cookie_count; i++) {
|
||||
cookie_val_status = edns_cookie_server_validate(cookie,
|
||||
cookie_len,
|
||||
cookie_secrets->cookie_secrets[i].cookie_secret,
|
||||
UNBOUND_COOKIE_SECRET_SIZE, v4, hash_input, now);
|
||||
if(cookie_val_status == COOKIE_STATUS_VALID ||
|
||||
cookie_val_status == COOKIE_STATUS_VALID_RENEW) {
|
||||
lock_basic_unlock(&cookie_secrets->lock);
|
||||
/* For staging cookies, write a fresh cookie. */
|
||||
if(i != 0)
|
||||
return COOKIE_STATUS_VALID_RENEW;
|
||||
return cookie_val_status;
|
||||
}
|
||||
if(last == COOKIE_STATUS_INVALID)
|
||||
last = cookie_val_status; /* Store more interesting
|
||||
failure to return. */
|
||||
}
|
||||
lock_basic_unlock(&cookie_secrets->lock);
|
||||
return last;
|
||||
}
|
||||
|
||||
void add_cookie_secret(struct cookie_secrets* cookie_secrets,
|
||||
uint8_t* secret, size_t secret_len)
|
||||
{
|
||||
log_assert(secret_len == UNBOUND_COOKIE_SECRET_SIZE);
|
||||
(void)secret_len;
|
||||
if(!cookie_secrets)
|
||||
return;
|
||||
|
||||
/* New cookie secret becomes the staging secret (position 1)
|
||||
* unless there is no active cookie yet, then it becomes the active
|
||||
* secret. If the UNBOUND_COOKIE_HISTORY_SIZE > 2 then all staging cookies
|
||||
* are moved one position down.
|
||||
*/
|
||||
if(cookie_secrets->cookie_count == 0) {
|
||||
memcpy( cookie_secrets->cookie_secrets->cookie_secret
|
||||
, secret, UNBOUND_COOKIE_SECRET_SIZE);
|
||||
cookie_secrets->cookie_count = 1;
|
||||
explicit_bzero(secret, UNBOUND_COOKIE_SECRET_SIZE);
|
||||
return;
|
||||
}
|
||||
#if UNBOUND_COOKIE_HISTORY_SIZE > 2
|
||||
memmove( &cookie_secrets->cookie_secrets[2], &cookie_secrets->cookie_secrets[1]
|
||||
, sizeof(struct cookie_secret) * (UNBOUND_COOKIE_HISTORY_SIZE - 2));
|
||||
#endif
|
||||
memcpy( cookie_secrets->cookie_secrets[1].cookie_secret
|
||||
, secret, UNBOUND_COOKIE_SECRET_SIZE);
|
||||
cookie_secrets->cookie_count = cookie_secrets->cookie_count < UNBOUND_COOKIE_HISTORY_SIZE
|
||||
? cookie_secrets->cookie_count + 1 : UNBOUND_COOKIE_HISTORY_SIZE;
|
||||
explicit_bzero(secret, UNBOUND_COOKIE_SECRET_SIZE);
|
||||
}
|
||||
|
||||
void activate_cookie_secret(struct cookie_secrets* cookie_secrets)
|
||||
{
|
||||
uint8_t active_secret[UNBOUND_COOKIE_SECRET_SIZE];
|
||||
if(!cookie_secrets)
|
||||
return;
|
||||
/* The staging secret becomes the active secret.
|
||||
* The active secret becomes a staging secret.
|
||||
* If the UNBOUND_COOKIE_HISTORY_SIZE > 2 then all staging secrets are moved
|
||||
* one position up and the previously active secret becomes the last
|
||||
* staging secret.
|
||||
*/
|
||||
if(cookie_secrets->cookie_count < 2)
|
||||
return;
|
||||
memcpy( active_secret, cookie_secrets->cookie_secrets[0].cookie_secret
|
||||
, UNBOUND_COOKIE_SECRET_SIZE);
|
||||
memmove( &cookie_secrets->cookie_secrets[0], &cookie_secrets->cookie_secrets[1]
|
||||
, sizeof(struct cookie_secret) * (UNBOUND_COOKIE_HISTORY_SIZE - 1));
|
||||
memcpy( cookie_secrets->cookie_secrets[cookie_secrets->cookie_count - 1].cookie_secret
|
||||
, active_secret, UNBOUND_COOKIE_SECRET_SIZE);
|
||||
explicit_bzero(active_secret, UNBOUND_COOKIE_SECRET_SIZE);
|
||||
}
|
||||
|
||||
void drop_cookie_secret(struct cookie_secrets* cookie_secrets)
|
||||
{
|
||||
if(!cookie_secrets)
|
||||
return;
|
||||
/* Drops a staging cookie secret. If there are more than one, it will
|
||||
* drop the last staging secret. */
|
||||
if(cookie_secrets->cookie_count < 2)
|
||||
return;
|
||||
explicit_bzero( cookie_secrets->cookie_secrets[cookie_secrets->cookie_count - 1].cookie_secret
|
||||
, UNBOUND_COOKIE_SECRET_SIZE);
|
||||
cookie_secrets->cookie_count -= 1;
|
||||
}
|
||||
|
||||
+85
@@ -43,6 +43,7 @@
|
||||
#define UTIL_EDNS_H
|
||||
|
||||
#include "util/storage/dnstree.h"
|
||||
#include "util/locks.h"
|
||||
|
||||
struct edns_data;
|
||||
struct config_file;
|
||||
@@ -75,6 +76,31 @@ struct edns_string_addr {
|
||||
size_t string_len;
|
||||
};
|
||||
|
||||
#define UNBOUND_COOKIE_HISTORY_SIZE 2
|
||||
#define UNBOUND_COOKIE_SECRET_SIZE 16
|
||||
|
||||
typedef struct cookie_secret cookie_secret_type;
|
||||
struct cookie_secret {
|
||||
/** cookie secret */
|
||||
uint8_t cookie_secret[UNBOUND_COOKIE_SECRET_SIZE];
|
||||
};
|
||||
|
||||
/**
|
||||
* The cookie secrets from the cookie-secret-file.
|
||||
*/
|
||||
struct cookie_secrets {
|
||||
/** lock on the structure, in case there are modifications
|
||||
* from remote control, this avoids race conditions. */
|
||||
lock_basic_type lock;
|
||||
|
||||
/** how many cookies are there in the cookies array */
|
||||
size_t cookie_count;
|
||||
|
||||
/* keep track of the last `UNBOUND_COOKIE_HISTORY_SIZE`
|
||||
* cookies as per rfc requirement .*/
|
||||
cookie_secret_type cookie_secrets[UNBOUND_COOKIE_HISTORY_SIZE];
|
||||
};
|
||||
|
||||
enum edns_cookie_val_status {
|
||||
COOKIE_STATUS_CLIENT_ONLY = -3,
|
||||
COOKIE_STATUS_FUTURE = -2,
|
||||
@@ -165,4 +191,63 @@ enum edns_cookie_val_status edns_cookie_server_validate(const uint8_t* cookie,
|
||||
size_t cookie_len, const uint8_t* secret, size_t secret_len, int v4,
|
||||
const uint8_t* hash_input, uint32_t now);
|
||||
|
||||
/**
|
||||
* Create the cookie secrets structure.
|
||||
* @return the structure or NULL on failure.
|
||||
*/
|
||||
struct cookie_secrets* cookie_secrets_create(void);
|
||||
|
||||
/**
|
||||
* Delete the cookie secrets.
|
||||
* @param cookie_secrets: the cookie secrets.
|
||||
*/
|
||||
void cookie_secrets_delete(struct cookie_secrets* cookie_secrets);
|
||||
|
||||
/**
|
||||
* Apply configuration to cookie secrets, read them from file.
|
||||
* @param cookie_secrets: the cookie secrets structure.
|
||||
* @param cookie_secret_file: the file name, it is read.
|
||||
* @return false on failure.
|
||||
*/
|
||||
int cookie_secrets_apply_cfg(struct cookie_secrets* cookie_secrets,
|
||||
char* cookie_secret_file);
|
||||
|
||||
/**
|
||||
* Validate the cookie secrets, try all of them.
|
||||
* @param cookie: pointer to the cookie data.
|
||||
* @param cookie_len: the length of the cookie data.
|
||||
* @param cookie_secrets: struct of cookie secrets.
|
||||
* @param v4: if the client IP is v4 or v6.
|
||||
* @param hash_input: pointer to the hash input for validation. It needs to be:
|
||||
* Client Cookie | Version | Reserved | Timestamp | Client-IP
|
||||
* @param now: the current time.
|
||||
* return edns_cookie_val_status with the cookie validation status i.e.,
|
||||
* <=0 for invalid, else valid.
|
||||
*/
|
||||
enum edns_cookie_val_status cookie_secrets_server_validate(
|
||||
const uint8_t* cookie, size_t cookie_len,
|
||||
struct cookie_secrets* cookie_secrets, int v4,
|
||||
const uint8_t* hash_input, uint32_t now);
|
||||
|
||||
/**
|
||||
* Add a cookie secret. If there are no secrets yet, the secret will become
|
||||
* the active secret. Otherwise it will become the staging secret.
|
||||
* Active secrets are used to both verify and create new DNS Cookies.
|
||||
* Staging secrets are only used to verify DNS Cookies. Caller has to lock.
|
||||
*/
|
||||
void add_cookie_secret(struct cookie_secrets* cookie_secrets, uint8_t* secret,
|
||||
size_t secret_len);
|
||||
|
||||
/**
|
||||
* Makes the staging cookie secret active and the active secret staging.
|
||||
* Caller has to lock.
|
||||
*/
|
||||
void activate_cookie_secret(struct cookie_secrets* cookie_secrets);
|
||||
|
||||
/**
|
||||
* Drop a cookie secret. Drops the staging secret. An active secret will not
|
||||
* be dropped. Caller has to lock.
|
||||
*/
|
||||
void drop_cookie_secret(struct cookie_secrets* cookie_secrets);
|
||||
|
||||
#endif
|
||||
|
||||
+24
-2
@@ -392,7 +392,7 @@ fptr_whitelist_modenv_detect_cycle(int (*fptr)(
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
fptr_whitelist_mod_init(int (*fptr)(struct module_env* env, int id))
|
||||
{
|
||||
if(fptr == &iter_init) return 1;
|
||||
@@ -420,7 +420,7 @@ fptr_whitelist_mod_init(int (*fptr)(struct module_env* env, int id))
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
fptr_whitelist_mod_deinit(void (*fptr)(struct module_env* env, int id))
|
||||
{
|
||||
if(fptr == &iter_deinit) return 1;
|
||||
@@ -448,6 +448,28 @@ fptr_whitelist_mod_deinit(void (*fptr)(struct module_env* env, int id))
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
fptr_whitelist_mod_startup(int (*fptr)(struct module_env* env, int id))
|
||||
{
|
||||
#ifdef USE_IPSET
|
||||
if(fptr == &ipset_startup) return 1;
|
||||
#else
|
||||
(void)fptr;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
fptr_whitelist_mod_destartup(void (*fptr)(struct module_env* env, int id))
|
||||
{
|
||||
#ifdef USE_IPSET
|
||||
if(fptr == &ipset_destartup) return 1;
|
||||
#else
|
||||
(void)fptr;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
fptr_whitelist_mod_operate(void (*fptr)(struct module_qstate* qstate,
|
||||
enum module_ev event, int id, struct outbound_entry* outbound))
|
||||
|
||||
@@ -278,6 +278,22 @@ int fptr_whitelist_mod_init(int (*fptr)(struct module_env* env, int id));
|
||||
*/
|
||||
int fptr_whitelist_mod_deinit(void (*fptr)(struct module_env* env, int id));
|
||||
|
||||
/**
|
||||
* Check function pointer whitelist for module startup call values.
|
||||
*
|
||||
* @param fptr: function pointer to check.
|
||||
* @return false if not in whitelist.
|
||||
*/
|
||||
int fptr_whitelist_mod_startup(int (*fptr)(struct module_env* env, int id));
|
||||
|
||||
/**
|
||||
* Check function pointer whitelist for module destartup call values.
|
||||
*
|
||||
* @param fptr: function pointer to check.
|
||||
* @return false if not in whitelist.
|
||||
*/
|
||||
int fptr_whitelist_mod_destartup(void (*fptr)(struct module_env* env, int id));
|
||||
|
||||
/**
|
||||
* Check function pointer whitelist for module operate call values.
|
||||
*
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user