Compare commits

..
Author SHA1 Message Date
Willem Toorop 2ffc17e826 Shumon's invalid query type EDE return 2024-07-25 19:29:09 -07:00
W.C.A. Wijngaards 3af4e44646 - 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.
2024-07-19 16:16:02 +02:00
W.C.A. Wijngaards c3dd6a2dbd - Add dnstap-sample-rate that logs only 1/N messages, for high volume
server environments. Thanks Dan Luther.
2024-07-19 10:04:40 +02:00
W.C.A. Wijngaards 8fca3e7c5b - 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.
2024-07-16 14:23:10 +02:00
W.C.A. Wijngaards 8947c2c764 - 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.
2024-07-15 14:51:20 +02:00
W.C.A. Wijngaards b1e3319a11 Merge branch 'master' of github.com:NLnetLabs/unbound 2024-07-12 16:41:58 +02:00
W.C.A. Wijngaards d52f501d90 - For #1103: fix to also drop mesh state reference when a h2 reply is
dropped.
2024-07-12 16:41:46 +02:00
Yorgos Thessalonikefs 7083d58c6b - For #1102: clearer text for using interface-* options for the
loopback interface.
2024-07-12 16:29:44 +02:00
W.C.A. Wijngaards 3adb9c8f92 - Fix #1103: unbound 1.20.0 segmentation fault with nghttp2. 2024-07-12 16:11:29 +02:00
Yorgos Thessalonikefs 51425b2388 - Add RPZ tag tests in acl_interface.tdir. 2024-07-12 15:38:12 +02:00
W.C.A. Wijngaards d43760a8cd - For #773: In contrib/unbound.service.in set unbound to start after
network-online.target. Also for contrib/unbound_portable.service.in.
2024-07-10 14:05:43 +02:00
Yorgos Thessalonikefs ea3e327006 - Update list of known EDE codes. 2024-07-09 15:58:30 +02:00
W.C.A. Wijngaards be09350eca - Fix shadowed error string variable in validator dnskey handling. 2024-07-08 16:50:16 +02:00
W.C.A. Wijngaards 169acfc546 - Fixup algo_needs_reason string buffer length. 2024-07-08 15:38:27 +02:00
W.C.A. Wijngaards bed7cc2a90 - Fix that validation reason failure that uses string print uses
separate buffer that is passed, from the scratch validation buffer.
2024-07-08 15:29:20 +02:00
Yorgos Thessalonikefs 02f4446833 - Don't check for message TTL changes if the RRsets remain the same. 2024-07-05 19:58:19 +02:00
W.C.A. Wijngaards c8a2289542 - 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.
2024-07-05 17:54:46 +02:00
W.C.A. Wijngaards b53d90053e - Fix #1099: Unbound core dump on SIGSEGV. 2024-07-05 17:18:01 +02:00
W.C.A. Wijngaards 978b0696d3 - Fix neater printout. 2024-07-05 14:11:26 +02:00
W.C.A. Wijngaards ec5f86b4eb - Fix for neater printout for error for missing DS response. 2024-07-05 08:49:52 +02:00
W.C.A. Wijngaards ec2f45c6fd - 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.
2024-07-04 14:51:18 +02:00
W.C.A. Wijngaards 6b319c97ee - Fix compile warnings in fptr_wlist.c. 2024-07-03 16:42:52 +02:00
W.C.A. Wijngaards 6eb3992c9e - Fix to remove unneeded linebreak in fptr_wlist.c. 2024-07-03 15:51:22 +02:00
W.C.A. Wijngaards 94a94fd8c8 - Fix to use modstack_init in zonemd unit test. 2024-07-03 15:49:13 +02:00
W.C.A. Wijngaards 36f9d1a2a9 - Add unit test skip files and bison and flex output to gitignore. 2024-07-03 14:59:39 +02:00
W.C.A. Wijngaards d3a2264272 Changelog entry for #144 and #1098
- Fix #144: Port ipset to BSD pf tables.
2024-07-03 14:53:42 +02:00
Wouter WijngaardsandGitHub 92b6c2a7b9 Merge pull request #1098 from NLnetLabs/ipset-pf-support
Ipset pf support
2024-07-03 14:49:16 +02:00
W.C.A. Wijngaards a335e601e4 ipset-pf-support, move startup and destartup to the front of the module
func block functions, modstack call deinit function names, and detect
module change when no startup functions are needed.
2024-07-03 13:53:44 +02:00
a19009df1d Apply suggestions from code review
Co-authored-by: Yorgos Thessalonikefs <yorgos@nlnetlabs.nl>
2024-07-03 13:08:51 +02:00
Yorgos Thessalonikefs 96f8a94c19 - 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.
2024-07-03 10:08:44 +02:00
W.C.A. Wijngaards 2fe4e2ec3e - Fix compile warning in worker pthread id printout. 2024-07-02 09:44:58 +02:00
W.C.A. Wijngaards e54928a628 - Fix unused variable warning in do_cache_remove. 2024-07-02 09:33:22 +02:00
W.C.A. Wijngaards 538434186e - Fix to remove unused include from the readzone test program. 2024-07-02 09:31:34 +02:00
W.C.A. Wijngaards 65e7253d19 ipset-pf-support, simplification of code. 2024-07-02 09:08:27 +02:00
W.C.A. Wijngaards 03ac902296 - ipset-pf-support, fix to skip unit test if no pf dev. 2024-07-01 17:11:20 +02:00
W.C.A. Wijngaards 97ad1df343 ipset-pf-support, fix to log error on failure to open pf. 2024-07-01 17:06:11 +02:00
W.C.A. Wijngaards 2279cde8f7 ipset-pf-support, fix to remove unused include, free at end, adjust
qname for comparison.
2024-07-01 17:02:49 +02:00
W.C.A. Wijngaards ff653a7ef8 Call module init init again, and new function startup and destartup.
NULL can be used if the function is not used. Open shared ports during
reload. Deinit is called during reload.
2024-07-01 16:10:07 +02:00
W.C.A. Wijngaards fd11cd9182 ipset-pf-support, fix compilation, close of pf socket. 2024-07-01 14:54:45 +02:00
W.C.A. Wijngaards 3953f827fb Merge branch 'master' of https://github.com/madroach/unbound into ipset-pf-support 2024-07-01 14:36:33 +02:00
W.C.A. Wijngaards 7fbc061846 - Fix ip-ratelimit-cookie setting, it was not applied. 2024-06-27 14:51:58 +02:00
Yorgos Thessalonikefs 70f73a33b3 - 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.
2024-06-26 15:51:58 +02:00
Yorgos Thessalonikefs b67fbb69e7 - Fix pkg-config availability check in dnstap/dnstap.m4 and
systemd.m4.
- autoconf.
2024-06-21 14:34:12 +02:00
Yorgos Thessalonikefs 902c79608c - 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.
- autoconf.
2024-06-19 15:27:50 +02:00
W.C.A. Wijngaards 08050dc939 - Fix #1091: Build fails with OpenSSL >= 3.0 built with
OPENSSL_NO_DEPRECATED.
2024-06-17 12:28:45 +02:00
W.C.A. Wijngaards 9603924bb4 - Add unit test for validation of repeated use of a DNAME record. 2024-06-07 11:56:19 +02:00
W.C.A. Wijngaards 4c2da2b979 - Fix validation for repeated use of a DNAME record. 2024-06-06 15:28:21 +02:00
W.C.A. Wijngaards 1974732d19 - Fix typos for 'the the' in text. 2024-06-06 09:35:57 +02:00
W.C.A. Wijngaards 3cad5818a1 - Fix memory leak in setup of dsa sig. 2024-06-06 09:30:09 +02:00
Yorgos Thessalonikefs ad12109191 - Merge #1080: AddressSanitizer detection in tdir tests and memory leak
fixes.
2024-06-04 17:34:58 +02:00
Yorgos Thessalonikefs f611220eb8 - Skip unbound-dnstap-socket unit test when not compiled with
--enable-debug.
2024-06-04 16:59:58 +02:00
Yorgos Thessalonikefs ac609fcbfc - Fix memory leak on exit for unbound-dnstap-socket; creates false negatives
during testing.
2024-05-31 12:11:17 +02:00
Yorgos Thessalonikefs 486985fbdf - Fix memory leak when reload_keep_cache is used and num-threads changes. 2024-05-31 12:09:35 +02:00
Yorgos Thessalonikefs caab100207 - Enable AddressSanitizer error detection in tdir tests. 2024-05-31 12:08:43 +02:00
Christopher Zimmermann 1d23e0c920 Merge remote-tracking branch 'upstream/master' 2021-02-03 13:19:19 +01:00
Christopher Zimmermann ad51795314 Don't try to run daemon_privileged on reload. 2020-05-10 22:30:25 +02:00
Christopher Zimmermann 7d76e84953 Port ipset to BSD pf tables 2020-05-10 22:30:25 +02:00
Christopher Zimmermann c96e4ca121 allow privileged initialisation of modules 2020-05-10 22:30:25 +02:00
90 changed files with 2376 additions and 886 deletions
+4
View File
@@ -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
+2 -1
View File
@@ -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
+1 -1
View File
@@ -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
View File
@@ -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
};
+6
View File
@@ -406,6 +406,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 +569,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
Vendored
+144 -44
View File
@@ -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
@@ -17624,7 +17625,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 +17686,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 +17721,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 +17781,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 +17832,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 +19230,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 +20701,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 +21241,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 +21267,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 +23805,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 +23866,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 +23904,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 +24317,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 +24341,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 +24365,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
+29 -14
View File
@@ -944,7 +944,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 +1181,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 +1931,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 +1959,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
+2 -2
View File
@@ -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
+2 -2
View File
@@ -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]
+30 -8
View File
@@ -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]);
}
@@ -858,7 +878,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 +908,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]);
+11
View File
@@ -115,6 +115,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 */
@@ -162,6 +164,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.
+2
View File
@@ -1682,6 +1682,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
}
+8 -1
View File
@@ -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
);
+4
View File
@@ -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);
+175 -169
View File
@@ -1111,6 +1111,172 @@ answer_notify(struct worker* w, struct query_info* qinfo,
LDNS_OPCODE_SET(sldns_buffer_begin(pkt), LDNS_PACKET_NOTIFY);
}
static int
make_ede_error(struct comm_point* c, struct worker* worker,
struct comm_reply* repinfo, int rcode, int16_t ede_code,
int ede, struct check_request_result* check_result)
{
size_t opt_rr_mark;
if(worker->stats.extended)
worker->stats.unwanted_queries++;
worker_check_request(c->buffer, worker, check_result);
if(check_result->value != 0) {
if(check_result->value != -1) {
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
check_result->value);
return 1;
}
comm_point_drop_reply(repinfo);
return 0;
}
/* worker_check_request() above guarantees that the buffer contains at
* least a header and that qdcount == 1
*/
log_assert(sldns_buffer_limit(c->buffer) >= LDNS_HEADER_SIZE
&& LDNS_QDCOUNT(sldns_buffer_begin(c->buffer)) == 1);
sldns_buffer_set_position(c->buffer, LDNS_HEADER_SIZE); /* skip header */
/* check additional section is present and that we respond with EDEs */
if(LDNS_ARCOUNT(sldns_buffer_begin(c->buffer)) != 1
|| !ede) {
LDNS_QDCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer), rcode);
sldns_buffer_set_position(c->buffer, LDNS_HEADER_SIZE);
sldns_buffer_flip(c->buffer);
return 1;
}
if (!query_dname_len(c->buffer)) {
LDNS_QDCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
LDNS_RCODE_FORMERR);
sldns_buffer_set_position(c->buffer, LDNS_HEADER_SIZE);
sldns_buffer_flip(c->buffer);
return 1;
}
/* space available for query type and class? */
if (sldns_buffer_remaining(c->buffer) < 2 * sizeof(uint16_t)) {
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
LDNS_RCODE_FORMERR);
LDNS_QDCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
sldns_buffer_set_position(c->buffer, LDNS_HEADER_SIZE);
sldns_buffer_flip(c->buffer);
return 1;
}
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer), rcode);
sldns_buffer_skip(c->buffer, (ssize_t)sizeof(uint16_t)); /* skip qtype */
sldns_buffer_skip(c->buffer, (ssize_t)sizeof(uint16_t)); /* skip qclass */
/* The OPT RR to be returned should come directly after
* the query, so mark this spot.
*/
opt_rr_mark = sldns_buffer_position(c->buffer);
/* Skip through the RR records */
if(LDNS_ANCOUNT(sldns_buffer_begin(c->buffer)) != 0 ||
LDNS_NSCOUNT(sldns_buffer_begin(c->buffer)) != 0) {
if(!skip_pkt_rrs(c->buffer,
((int)LDNS_ANCOUNT(sldns_buffer_begin(c->buffer)))+
((int)LDNS_NSCOUNT(sldns_buffer_begin(c->buffer))))) {
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
LDNS_RCODE_FORMERR);
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
sldns_buffer_set_position(c->buffer, opt_rr_mark);
sldns_buffer_flip(c->buffer);
return 1;
}
}
/* Do we have a valid OPT RR here? If not return rcode (could be a valid TSIG or something so no FORMERR) */
/* domain name must be the root of length 1. */
if(sldns_buffer_remaining(c->buffer) < 1 || *sldns_buffer_current(c->buffer) != 0) {
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
sldns_buffer_set_position(c->buffer, opt_rr_mark);
sldns_buffer_flip(c->buffer);
return 1;
} else {
sldns_buffer_skip(c->buffer, 1); /* skip root label */
}
if(sldns_buffer_remaining(c->buffer) < 2 ||
sldns_buffer_read_u16(c->buffer) != LDNS_RR_TYPE_OPT) {
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
sldns_buffer_set_position(c->buffer, opt_rr_mark);
sldns_buffer_flip(c->buffer);
return 1;
}
/* Write OPT RR directly after the query,
* so without the (possibly skipped) Answer and NS RRs
*/
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
sldns_buffer_clear(c->buffer); /* reset write limit */
sldns_buffer_set_position(c->buffer, opt_rr_mark);
/* Check if OPT record can be written
* 17 == root label (1) + RR type (2) + UDP Size (2)
* + Fields (4) + rdata len (2) + EDE Option code (2)
* + EDE Option length (2) + EDE info-code (2)
*/
if (sldns_buffer_available(c->buffer, 17) == 0) {
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
sldns_buffer_flip(c->buffer);
return 1;
}
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 1);
/* root label */
sldns_buffer_write_u8(c->buffer, 0);
sldns_buffer_write_u16(c->buffer, LDNS_RR_TYPE_OPT);
sldns_buffer_write_u16(c->buffer, EDNS_ADVERTISED_SIZE);
/* write OPT Record TTL Field */
sldns_buffer_write_u32(c->buffer, 0);
/* write rdata len: EDE option + length + info-code */
sldns_buffer_write_u16(c->buffer, 6);
/* write OPTIONS; add EDE option code */
sldns_buffer_write_u16(c->buffer, LDNS_EDNS_EDE);
/* write single EDE option length (for just 1 info-code) */
sldns_buffer_write_u16(c->buffer, 2);
/* write single EDE info-code */
sldns_buffer_write_u16(c->buffer, ede_code);
sldns_buffer_flip(c->buffer);
verbose(VERB_ALGO, "attached EDE code: %d", ede_code);
return 1;
}
static int
deny_refuse(struct comm_point* c, enum acl_access acl,
enum acl_access deny, enum acl_access refuse,
@@ -1129,174 +1295,14 @@ deny_refuse(struct comm_point* c, enum acl_access acl,
worker->stats.unwanted_queries++;
return 0;
} else if(acl == refuse) {
size_t opt_rr_mark;
if(verbosity >= VERB_ALGO) {
log_acl_action("refused", &repinfo->client_addr,
repinfo->client_addrlen, acl, acladdr);
log_buf(VERB_ALGO, "refuse", c->buffer);
}
if(worker->stats.extended)
worker->stats.unwanted_queries++;
worker_check_request(c->buffer, worker, check_result);
if(check_result->value != 0) {
if(check_result->value != -1) {
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
check_result->value);
return 1;
}
comm_point_drop_reply(repinfo);
return 0;
}
/* worker_check_request() above guarantees that the buffer contains at
* least a header and that qdcount == 1
*/
log_assert(sldns_buffer_limit(c->buffer) >= LDNS_HEADER_SIZE
&& LDNS_QDCOUNT(sldns_buffer_begin(c->buffer)) == 1);
sldns_buffer_set_position(c->buffer, LDNS_HEADER_SIZE); /* skip header */
/* check additional section is present and that we respond with EDEs */
if(LDNS_ARCOUNT(sldns_buffer_begin(c->buffer)) != 1
|| !ede) {
LDNS_QDCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
LDNS_RCODE_REFUSED);
sldns_buffer_set_position(c->buffer, LDNS_HEADER_SIZE);
sldns_buffer_flip(c->buffer);
return 1;
}
if (!query_dname_len(c->buffer)) {
LDNS_QDCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
LDNS_RCODE_FORMERR);
sldns_buffer_set_position(c->buffer, LDNS_HEADER_SIZE);
sldns_buffer_flip(c->buffer);
return 1;
}
/* space available for query type and class? */
if (sldns_buffer_remaining(c->buffer) < 2 * sizeof(uint16_t)) {
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
LDNS_RCODE_FORMERR);
LDNS_QDCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
sldns_buffer_set_position(c->buffer, LDNS_HEADER_SIZE);
sldns_buffer_flip(c->buffer);
return 1;
}
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
LDNS_RCODE_REFUSED);
sldns_buffer_skip(c->buffer, (ssize_t)sizeof(uint16_t)); /* skip qtype */
sldns_buffer_skip(c->buffer, (ssize_t)sizeof(uint16_t)); /* skip qclass */
/* The OPT RR to be returned should come directly after
* the query, so mark this spot.
*/
opt_rr_mark = sldns_buffer_position(c->buffer);
/* Skip through the RR records */
if(LDNS_ANCOUNT(sldns_buffer_begin(c->buffer)) != 0 ||
LDNS_NSCOUNT(sldns_buffer_begin(c->buffer)) != 0) {
if(!skip_pkt_rrs(c->buffer,
((int)LDNS_ANCOUNT(sldns_buffer_begin(c->buffer)))+
((int)LDNS_NSCOUNT(sldns_buffer_begin(c->buffer))))) {
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
LDNS_RCODE_FORMERR);
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
sldns_buffer_set_position(c->buffer, opt_rr_mark);
sldns_buffer_flip(c->buffer);
return 1;
}
}
/* Do we have a valid OPT RR here? If not return REFUSED (could be a valid TSIG or something so no FORMERR) */
/* domain name must be the root of length 1. */
if(sldns_buffer_remaining(c->buffer) < 1 || *sldns_buffer_current(c->buffer) != 0) {
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
sldns_buffer_set_position(c->buffer, opt_rr_mark);
sldns_buffer_flip(c->buffer);
return 1;
} else {
sldns_buffer_skip(c->buffer, 1); /* skip root label */
}
if(sldns_buffer_remaining(c->buffer) < 2 ||
sldns_buffer_read_u16(c->buffer) != LDNS_RR_TYPE_OPT) {
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
sldns_buffer_set_position(c->buffer, opt_rr_mark);
sldns_buffer_flip(c->buffer);
return 1;
}
/* Write OPT RR directly after the query,
* so without the (possibly skipped) Answer and NS RRs
*/
LDNS_ANCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
LDNS_NSCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
sldns_buffer_clear(c->buffer); /* reset write limit */
sldns_buffer_set_position(c->buffer, opt_rr_mark);
/* Check if OPT record can be written
* 17 == root label (1) + RR type (2) + UDP Size (2)
* + Fields (4) + rdata len (2) + EDE Option code (2)
* + EDE Option length (2) + EDE info-code (2)
*/
if (sldns_buffer_available(c->buffer, 17) == 0) {
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 0);
sldns_buffer_flip(c->buffer);
return 1;
}
LDNS_ARCOUNT_SET(sldns_buffer_begin(c->buffer), 1);
/* root label */
sldns_buffer_write_u8(c->buffer, 0);
sldns_buffer_write_u16(c->buffer, LDNS_RR_TYPE_OPT);
sldns_buffer_write_u16(c->buffer, EDNS_ADVERTISED_SIZE);
/* write OPT Record TTL Field */
sldns_buffer_write_u32(c->buffer, 0);
/* write rdata len: EDE option + length + info-code */
sldns_buffer_write_u16(c->buffer, 6);
/* write OPTIONS; add EDE option code */
sldns_buffer_write_u16(c->buffer, LDNS_EDNS_EDE);
/* write single EDE option length (for just 1 info-code) */
sldns_buffer_write_u16(c->buffer, 2);
/* write single EDE info-code */
sldns_buffer_write_u16(c->buffer, LDNS_EDE_PROHIBITED);
sldns_buffer_flip(c->buffer);
verbose(VERB_ALGO, "attached EDE code: %d", LDNS_EDE_PROHIBITED);
return 1;
return make_ede_error(c, worker, repinfo, LDNS_RCODE_REFUSED,
LDNS_EDE_PROHIBITED, ede, check_result);
}
return -1;
}
@@ -1552,6 +1558,8 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
qinfo.qtype == LDNS_RR_TYPE_MAILA ||
qinfo.qtype == LDNS_RR_TYPE_MAILB ||
(qinfo.qtype >= 128 && qinfo.qtype <= 248)) {
size_t opt_rr_mark;
verbose(VERB_ALGO, "worker request: formerror for meta-type.");
log_addr(VERB_CLIENT, "from", &repinfo->client_addr,
repinfo->client_addrlen);
@@ -1559,14 +1567,12 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
comm_point_drop_reply(repinfo);
return 0;
}
sldns_buffer_rewind(c->buffer);
LDNS_QR_SET(sldns_buffer_begin(c->buffer));
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer),
LDNS_RCODE_FORMERR);
if(worker->stats.extended) {
worker->stats.qtype[qinfo.qtype]++;
if (make_ede_error(c, worker, repinfo, LDNS_RCODE_FORMERR,
LDNS_EDE_INVALID_QUERY_TYPE,
worker->env.cfg->ede, &check_result)) {
goto send_reply;
}
goto send_reply;
return 0;
}
if((ret=parse_edns_from_query_pkt(
c->buffer, &edns, worker->env.cfg, c, repinfo,
+2 -2
View File
@@ -1044,8 +1044,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
};
/**
+45
View File
@@ -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);
+8
View File
@@ -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
View File
@@ -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], [],
+43 -8
View File
@@ -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);
@@ -1513,8 +1534,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 */
}
}
+188 -26
View File
@@ -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,82 @@ 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)
{
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);
data->data_list->d = NULL;
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);
e->d = NULL;
}
free(e);
e = next;
}
}
/** del the tap event */
static void tap_socket_delev(struct tap_socket* s)
{
@@ -184,6 +271,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,20 +816,6 @@ 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)
@@ -842,7 +916,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 +942,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);
@@ -1046,7 +1128,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 +1210,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 +1326,79 @@ 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);
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 +1449,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 +1485,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:
+113
View File
@@ -1,3 +1,116 @@
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.
+2
View File
@@ -1329,6 +1329,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
+15 -3
View File
@@ -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
@@ -2847,6 +2852,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.
+2 -2
View File
@@ -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)
+2 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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 */
-28
View File
@@ -408,34 +408,6 @@ find_NS(struct reply_info* rep, size_t from, size_t to)
return NULL;
}
struct delegpt* delegpt_from_deleg(struct dns_msg*, struct regional* region, uint8_t* ipv4, uint8_t* ipv6, uint8_t* ns_name, size_t ns_name_len) {
struct delegpt* dp;
dp = delegpt_create(region);
delegpt_set_name(dp, region, ns_name);
delegpt_add_ns(dp, region, ns_name, 0, NULL, 53);
// delegpt_rrset_add_ns(dp, region, ns_rrset, 0);
if (ipv4 != NULL) {
struct sockaddr_in sa4;
socklen_t lenv4 = (socklen_t)sizeof(sa4);
memset(&sa4, 0, lenv4);
sa4.sin_family = AF_INET;
memmove(&sa4.sin_addr, ipv4, INET_SIZE);
delegpt_add_target(dp, region, ns_name, ns_name_len, (struct sockaddr_storage*)&sa4, lenv4, 0, 0, NULL);
}
if (ipv6 != NULL) {
struct sockaddr_in6 sa6;
socklen_t lenv6 = (socklen_t)sizeof(sa6);
memset(&sa6, 0, lenv6);
sa6.sin6_family = AF_INET6;
memmove(&sa6.sin6_addr, ipv6, INET6_SIZE);
delegpt_add_target(dp, region, ns_name, ns_name_len, (struct sockaddr_storage*)&sa6, lenv6, 0, 0, NULL);
}
return dp;
// delegpt_add_addr(struct delegpt* dp, struct regional* region,
// struct sockaddr_storage* addr, socklen_t addrlen, uint8_t bogus,
// uint8_t lame, char* tls_auth_name, int port, int* additions)
}
struct delegpt*
delegpt_from_message(struct dns_msg* msg, struct regional* region)
{
-1
View File
@@ -361,7 +361,6 @@ size_t delegpt_count_targets(struct delegpt* dp);
struct delegpt* delegpt_from_message(struct dns_msg* msg,
struct regional* regional);
struct delegpt* delegpt_from_deleg(struct dns_msg*, struct regional* region, uint8_t* ipv4, uint8_t* pv6, uint8_t* ns_name, size_t ns_name_len);
/**
* Mark negative return in delegation point for specific nameserver.
* sets the got4 or got6 to negative, updates the ns->resolved.
+11 -261
View File
@@ -32,33 +32,7 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// @JESSE: Iterator (this file) is the module that does all the needed DNS
// iterations and walking the DNS tree to try and find an answer.
// It includes but not limited to:
// 1. Finding the closest known delegation point
// (root at startup, or configured zones)
// 2. Sends a query (the original query if no qname-minimisation)
// to that and gets either an answer or a referral answer.
// 3. In case of referral answer goes back to 1.
//
// A lot more is happening here, like fallbacks and retries. Don't try
// to understand everything at once, it's better to go with the flow
// and see what is relevant for you.
// @JESSE: We do not use '//' comments in the Unbound code base. I explicitly
// use them to identify non-relevant parts or WIP comments.
// @JESSE: Some tips:
// - For printf kind of debug logging it's easier to use log_err();
// these are printed on all verbosity levels.
// - For domain name manipulation methods you can have a look at
// dname.c/h.
// - If you need to do allocations; for your case everything should
// have the lifetime of the query state (qstate); you can use
// qstate->region as your arena allocator and pass that region to
// functions that require one. You can then alloc items there and
// forget about them. The whole region is freed when the qstate is
// no more.
/**
* \file
*
@@ -96,7 +70,6 @@
#include "sldns/parseutil.h"
#include "sldns/sbuffer.h"
/* in msec */
int UNKNOWN_SERVER_NICENESS = 376;
/* in msec */
@@ -163,8 +136,6 @@ iter_deinit(struct module_env* env, int id)
static int
iter_new(struct module_qstate* qstate, int id)
{
// @JESSE: each module can have its own query state. The iter_qstate
// struct below is the state for the iterator.
struct iter_qstate* iq = (struct iter_qstate*)regional_alloc(
qstate->region, sizeof(struct iter_qstate));
qstate->minfo[id] = iq;
@@ -193,13 +164,7 @@ iter_new(struct module_qstate* qstate, int id)
iq->dnssec_lame_query = 0;
iq->chase_flags = qstate->query_flags;
/* Start with the (current) qname. */
// @JESSE: iq->qchase will be the qinfo iterator will be working on and
// updating through the iteration process. It is set here to
// the initial query (qstate->qinfo) that started all this.
iq->qchase = qstate->qinfo;
iq->deleg_state = 2;
iq->deleg_original_qname_len = 0;
iq->deleg_original_qname = NULL;
outbound_list_init(&iq->outlist);
iq->minimise_count = 0;
iq->timeout_count = 0;
@@ -207,7 +172,7 @@ iter_new(struct module_qstate* qstate, int id)
iq->minimisation_state = INIT_MINIMISE_STATE;
else
iq->minimisation_state = DONOT_MINIMISE_STATE;
// @JESSE: iq->qinfo_out is the qinfo that will be sent out.
memset(&iq->qinfo_out, 0, sizeof(struct query_info));
return 1;
}
@@ -1631,10 +1596,8 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
delname = iq->dp->name;
delnamelen = iq->dp->namelen;
} else {
// @JESSE: Here we set the delegation name to be the original
// one ...
delname = iq->qchase.qname;
delnamelen = iq->qchase.qname_len;
delname = iq->qchase.qname;
delnamelen = iq->qchase.qname_len;
}
if(iq->qchase.qtype == LDNS_RR_TYPE_DS || iq->refetch_glue ||
(iq->qchase.qtype == LDNS_RR_TYPE_NS && qstate->prefetch_leeway
@@ -1655,10 +1618,8 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
/* Lookup the delegation in the cache. If null, then the
* cache needs to be primed for the qclass. */
// @JESSE: ... and here we'll try to get the closest delegation
// from cache.
if(delname)
iq->dp = dns_cache_find_delegation(qstate->env, delname,
iq->dp = dns_cache_find_delegation(qstate->env, delname,
delnamelen, iq->qchase.qtype, iq->qchase.qclass,
qstate->region, &iq->deleg_msg,
*qstate->env->now+qstate->prefetch_leeway, 1,
@@ -2423,7 +2384,6 @@ check_waiting_queries(struct iter_qstate* iq, struct module_qstate* qstate,
}
}
// @JESSE: This is where most of the iteration time will be spent.
/**
* This is the request event state where the request will be sent to one of
* its current query targets. This state also handles issuing target lookup
@@ -2577,77 +2537,6 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
if(!ie->supports_ipv4 && !ie->use_nat64)
delegpt_no_ipv4(iq->dp);
delegpt_log(VERB_ALGO, iq->dp);
log_err("Tes Test jesse jess", iq->deleg_original_qname);
uint8_t root_len = iq->qchase.qname[0];
//todo have to remove this from iq when query has been resolved
if (iq->deleg_original_qname == NULL) {
iq->deleg_original_qname = (uint8_t *)regional_alloc(qstate->region, iq->qchase.qname_len + 1);
memcpy(iq->deleg_original_qname, qstate->qinfo.qname, iq->qchase.qname_len);
iq->deleg_original_qname_len = iq->qchase.qname_len;
iq->original_query = iq->qchase.qtype;
} else {
//restore qname to original to put _deleg in correct point
memcpy(qstate->qinfo.qname, iq->deleg_original_qname, iq->deleg_original_qname_len);
memcpy(iq->qchase.qname, iq->deleg_original_qname, iq->deleg_original_qname_len);
iq->qchase.qname_len = iq->deleg_original_qname_len;
iq->qchase.qtype = iq->original_query;
iq->qinfo_out.qtype = iq->original_query;
}
if (iq->deleg_state == 0 && root_len > 0) {
iq->deleg_original_qname_len = iq->qchase.qname_len;
iq->deleg_state = 1;
int qchase_label_len = dname_count_labels(iq->qchase.qname);
size_t labdiff = qchase_label_len - iq->dp->namelabs - 1;
dname_remove_labels(&iq->qchase.qname, &iq->qchase.qname_len, labdiff);
//we have to add _deleg after the first label
//for ex. jesse.nlnetlabs.nl becomes jesse._deleg.nlnetlabs.nl
uint8_t deleg_wireformat[] = {6, 95, 100, 101, 108, 101, 103}; //{06}_deleg
size_t delnamelen = iq->qchase.qname_len + sizeof(deleg_wireformat);
uint8_t *delname = (uint8_t *)regional_alloc(qstate->region, delnamelen);
//put first label of original qname
uint8_t first_label_len = iq->qchase.qname[0];
uint8_t *qname_minus_first_label = iq->qchase.qname + first_label_len + 1;
uint8_t leftover_len = iq->qchase.qname_len - first_label_len - 1;
memcpy(delname, iq->qchase.qname, first_label_len + 1); //memcpy 1st label into delname
memcpy(delname + first_label_len + 1, deleg_wireformat, sizeof(deleg_wireformat)); //memcpy _deleg label in delname
memcpy(delname + first_label_len + sizeof(deleg_wireformat) + 1, qname_minus_first_label, leftover_len); //memcpy other labels in delname
iq->dp->namelen = delnamelen;
iq->qchase.qtype = LDNS_RR_TYPE_IDELEG;
iq->qchase.qname = delname;
iq->qchase.qname_len = delnamelen;
iq->qinfo_out.qtype = LDNS_RR_TYPE_IDELEG;
iq->qinfo_out.qname = delname;
iq->qinfo_out.qname_len = delnamelen;
} else if (root_len > 0 && iq->deleg_state == 2) { //in this state create deleg prime query
int qchase_label_len = dname_count_labels(iq->qchase.qname);
size_t labdiff = qchase_label_len - iq->dp->namelabs;
dname_remove_labels(&iq->qchase.qname, &iq->qchase.qname_len, labdiff);
uint8_t deleg_wireformat[] = {6, 95, 100, 101, 108, 101, 103}; //{06}_deleg
size_t deleg_len = sizeof(deleg_wireformat);
size_t delnamelen = iq->qchase.qname_len + deleg_len;
uint8_t *delname = (uint8_t *)regional_alloc(qstate->region, delnamelen);
memcpy(delname, deleg_wireformat, deleg_len);
memcpy(delname+deleg_len, iq->qchase.qname, iq->qchase.qname_len);
iq->qchase.qtype = LDNS_RR_TYPE_IDELEG;
iq->qchase.qname = delname;
iq->qchase.qname_len = delnamelen;
iq->qinfo_out.qtype = LDNS_RR_TYPE_IDELEG;
iq->qinfo_out.qname = delname;
iq->qinfo_out.qname_len = delnamelen;
}
if(iq->num_current_queries>0) {
/* already busy answering a query, this restart is because
@@ -2658,13 +2547,6 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
return 0;
}
//DELEG first check if _deleg in delegation point
//if no _deleg let unbound handle it
// @JESSE: The following ifs is where most qname-minimisation happens.
// We need something similar (adding a label at a time) but
// without the best-effort nature of qname-minimisation and its
// fallback. You can take inspiration from here on how to
// correctly set iq->qinfo_out.
if(iq->minimisation_state == INIT_MINIMISE_STATE
&& !(iq->chase_flags & BIT_RD)) {
/* (Re)set qinfo_out to (new) delegation point, except when
@@ -3149,7 +3031,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
log_name_addr(VERB_QUERY, "applied NAT64:",
iq->dp->name, &real_addr, real_addrlen);
}
// @JESSE: This is where a query is finally going out, hopefully.
fptr_ok(fptr_whitelist_modenv_send_query(qstate->env->send_query));
outq = (*qstate->env->send_query)(&iq->qinfo_out,
iq->chase_flags | (iq->chase_to_rd?BIT_RD:0),
@@ -3203,7 +3085,7 @@ find_NS(struct reply_info* rep, size_t from, size_t to)
return NULL;
}
// @JESSE: This is where responses are read.
/**
* Process the query response. All queries end up at this state first. This
* process generally consists of analyzing the response and routing the
@@ -3298,114 +3180,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
dnsseclame = 1;
}
} else iq->dnssec_lame_query = 0;
// @JESSE: Answers to _deleg queries would end up here. You need to
// make sure you identify those answers correclty and treat
// them the same way as referrals below.
/* handle each of the type cases */
// uint16_t SVCB_QTYPE = LDNS_RR_TYPE_IDELEG;
//check wether it was a deleg query
uint8_t deleg_wireformat[] = {6, 95, 100, 101, 108, 101, 103}; //{06}_deleg
uint8_t first_label_len = iq->qchase.qname[0];
int is_deleg_query = memcmp(iq->qchase.qname + first_label_len + 1, deleg_wireformat, 7);
int is_deleg_prime_query = memcmp(iq->qchase.qname, deleg_wireformat, 7);
if (iq->deleg_state == 1 && type == RESPONSE_TYPE_ANSWER && iq->qchase.qtype == 64 && is_deleg_query == 0) {
//result of a deleg refferal
if (FLAGS_GET_RCODE(iq->response->rep->flags) == LDNS_RCODE_NXDOMAIN) {
//whem _deleg return NXDOMAIN
//turns all values back to normal when no _deleg (NXDOMAIN)
iq->qchase.qname = iq->deleg_original_qname;
iq->qchase.qtype = iq->original_query;
iq->qchase.qname_len = iq->deleg_original_qname_len;
iq->qinfo_out.qtype = iq->original_query;
iq->qinfo_out.qname = iq->deleg_original_qname;
iq->qinfo_out.qname_len = iq->deleg_original_qname_len;
return next_state(iq, QUERYTARGETS_STATE);
}
//In this scenario _deleg exists
iq->deleg_state = 2;
struct ub_packed_rrset_key* rrset_key;
rrset_key = reply_find_answer_rrset(&iq->qchase, iq->response->rep);
if(rrset_key) {
struct packed_rrset_data* rrset_data = (struct packed_rrset_data*) rrset_key->entry.data;
size_t data_len = rrset_data->rr_len[0];
uint8_t* svcb_data = rrset_data->rr_data[0];
size_t index = 4; //index of 4 to start at first label (skip message length(2 octet) and priority(2 octet))
while(svcb_data[index] != 0) { //loop through dns labels, label length 0 means root so stop looping though labels
index = index + svcb_data[index] + 1;
}
index = index + 1;//add 1 for the root label
//Reference https://datatracker.ietf.org/doc/rfc9460/ section 2.2
uint8_t *ipv4 = NULL;
uint8_t *ipv6 = NULL;
while(index < data_len && (ipv4 == NULL || ipv6 == NULL)) {
uint16_t svcParamkey = (svcb_data[index] << 8) | svcb_data[index+1];
uint16_t svcParamValLen = (svcb_data[index+2] << 8) | svcb_data[index+3];
index = index + 4;
if (svcParamkey == 4) { //parse IPv4
ipv4 = (uint8_t *)regional_alloc(qstate->region, 4 * sizeof(uint8_t));
memcpy(ipv4, svcb_data + index, 4);
} else if (svcParamkey == 6) { //parse ipv6
ipv6 = (uint8_t *)regional_alloc(qstate->region, 16 * sizeof(uint8_t));
memcpy(ipv6, svcb_data + index, 16);
}
index = index + svcParamValLen;
}
//to get the new delegation name, we have to remove the second label, which is the _deleg label
//count labels with dname_count_labels()
size_t new_delegation_label_count = dname_count_labels(rrset_key->rk.dname);
size_t old_label_count = dname_count_labels(iq->deleg_original_qname);
size_t diff_label_len = old_label_count - new_delegation_label_count + 1;
uint8_t *new_delegation_name = (uint8_t *)regional_alloc(qstate->region, iq->deleg_original_qname_len);
size_t new_delegation_name_len = iq->deleg_original_qname_len;
memcpy(new_delegation_name, iq->deleg_original_qname, iq->deleg_original_qname_len);
dname_remove_labels(&new_delegation_name, &new_delegation_name_len, diff_label_len);
iq->dp = delegpt_from_deleg(iq->response, qstate->region, ipv4, ipv6, new_delegation_name, new_delegation_name_len);
iq->referral_count++;
iq->sent_count = 0;
iq->dp_target_count = 0;
if(qstate->env->cfg->harden_referral_path)
generate_ns_check(qstate, iq, id);
/* stop current outstanding queries.
* FIXME: should the outstanding queries be waited for and
* handled? Say by a subquery that inherits the outbound_entry.
*/
outbound_list_clear(&iq->outlist);
iq->num_current_queries = 0;
fptr_ok(fptr_whitelist_modenv_detach_subs(
qstate->env->detach_subs));
(*qstate->env->detach_subs)(qstate);
iq->num_target_queries = 0;
iq->response = NULL;
iq->fail_addr_type = 0;
verbose(VERB_ALGO, "cleared outbound list for next round");
return next_state(iq, QUERYTARGETS_STATE);
}
} else if (is_deleg_prime_query == 0) {
if (FLAGS_GET_RCODE(iq->response->rep->flags) == LDNS_RCODE_NXDOMAIN) {
//NX DOMAIN mean deleg not supported (no error and answer count = 0)
iq->deleg_state = 1;
return next_state(iq, QUERYTARGETS_STATE);
} else if (FLAGS_GET_RCODE(iq->response->rep->flags) == LDNS_RCODE_NOERROR && iq->response->rep->an_numrrsets == 0) {
//no data means _deleg supported
iq->deleg_state = 0;
return next_state(iq, QUERYTARGETS_STATE);
}
}
/* see if referral brings us close to the target */
if(type == RESPONSE_TYPE_REFERRAL){
//deleg: go to state 2 when normal refferal found, to try deleg again for child
iq->deleg_state = 2;
if(type == RESPONSE_TYPE_REFERRAL) {
struct ub_packed_rrset_key* ns = find_NS(
iq->response->rep, iq->response->rep->an_numrrsets,
iq->response->rep->an_numrrsets
@@ -3448,14 +3224,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
type = RESPONSE_TYPE_ANSWER;
}
if(type == RESPONSE_TYPE_ANSWER ){
//set original qname to NULL after query has been resolved, to handle new queries
if (iq->deleg_original_qname != NULL) {
iq->deleg_original_qname = NULL;
iq->deleg_original_qname_len = 0;
iq->original_query = 0;
log_err("en hier ook nog wel??");
}
/* handle each of the type cases */
if(type == RESPONSE_TYPE_ANSWER) {
/* ANSWER type responses terminate the query algorithm,
* so they sent on their */
if(verbosity >= VERB_DETAIL) {
@@ -3465,7 +3235,6 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
(iq->response->rep->an_numrrsets?"ANSWER":
"nodata ANSWER"));
}
/* if qtype is DS, check we have the right level of answer,
* like grandchild answer but we need the middle, reject it */
if(iq->qchase.qtype == LDNS_RR_TYPE_DS && !iq->dsns_point
@@ -3554,13 +3323,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
return next_state(iq, QUERYTARGETS_STATE);
}
return final_state(iq);
// @JESSE: I guess for the test environemnt we mostly don't care about
// referrals; these are traditional DNS referral responses.
} else if(type == RESPONSE_TYPE_REFERRAL) {
//added code
// iq->deleg_state = 0;
struct delegpt* old_dp = NULL;
/* REFERRAL type responses get a reset of the
* delegation point, and back to the QUERYTARGETS_STATE. */
verbose(VERB_DETAIL, "query response was REFERRAL");
@@ -3829,14 +3593,6 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
* In this case, the event is just sent directly back to
* the QUERYTARGETS_STATE without resetting anything,
* because, clearly, the next target must be tried. */
iq->qchase.qname = iq->deleg_original_qname;
iq->qchase.qtype = iq->original_query;
iq->qchase.qname_len = iq->deleg_original_qname_len;
iq->qinfo_out.qtype = iq->original_query;
iq->qinfo_out.qname = iq->deleg_original_qname;
iq->qinfo_out.qname_len = iq->deleg_original_qname_len;
verbose(VERB_DETAIL, "query response was THROWAWAY");
} else {
log_warn("A query response came back with an unknown type: %d",
@@ -4384,12 +4140,6 @@ iter_inform_super(struct module_qstate* qstate, int id,
else processTargetResponse(qstate, id, super);
}
// @JESSE: These are all the available states the iterator could be for a given
// query. You should not worry about the following cases:
// - COLLECT_CLASS_STATE (it has to do with ANY queries)
// - DSNS_FIND_STATE (it tries to find the correct parent for a DS
// query; I think it is not relevant since the
// _deleg stuff always live at the parent)
/**
* Handle iterator state.
* Handle events. This is the real processing loop for events, responsible
@@ -4739,8 +4489,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*
-6
View File
@@ -431,12 +431,6 @@ struct iter_qstate {
/** State for capsfail: QNAME minimisation state for comparisons. */
enum minimisation_state caps_minimisation_state;
//DELEG added code
int deleg_state;
uint8_t* deleg_original_qname;
size_t deleg_original_qname_len;
uint16_t original_query;
/**
* The query info that is sent upstream. Will be a subset of qchase
* when qname minimisation is enabled.
+3 -1
View File
@@ -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);
+9 -3
View File
@@ -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;
+1 -1
View File
@@ -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.
+2 -2
View File
@@ -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
View File
@@ -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*
+30 -16
View File
@@ -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;
}
@@ -8114,7 +8119,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 +8156,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 +8180,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 +8217,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 +8243,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 +8355,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 +8364,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 +8449,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 +8484,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 +8511,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;
}
+13 -5
View File
@@ -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);
@@ -112,11 +113,18 @@ store_rrsets(struct module_env* env, struct reply_info* rep, time_t now,
/* 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;
+2
View File
@@ -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
+1 -1
View File
@@ -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.
+32 -9
View File
@@ -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
View File
@@ -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
View File
@@ -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.
+3 -3
View File
@@ -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);
+6 -3
View File
@@ -234,9 +234,6 @@ enum sldns_enum_rr_type
/* RFC 4431, 5074, DNSSEC Lookaside Validation */
LDNS_RR_TYPE_DLV = 32769,
/* draft-homburg-deleg-inctremental-deleg */
LDNS_RR_TYPE_IDELEG = 65280,
/* type codes from nsec3 experimental phase
LDNS_RR_TYPE_NSEC3 = 65324,
LDNS_RR_TYPE_NSEC3PARAMS = 65325, */
@@ -473,6 +470,12 @@ 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,
LDNS_EDE_INVALID_QUERY_TYPE = 30
};
typedef enum sldns_enum_ede_code sldns_ede_code;
+5
View File
@@ -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;
+5 -1
View File
@@ -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
@@ -805,7 +805,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);
+6 -3
View File
@@ -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);
+4
View File
@@ -759,7 +759,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
View File
@@ -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])
+10
View File
@@ -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 ***********/
+11
View File
@@ -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
View File
@@ -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) {
-1
View File
@@ -45,7 +45,6 @@
#include <string.h>
#include <unistd.h>
#include <stdint.h>
#include "sldns/str2wire.h"
#include "sldns/wire2str.h"
+4
View File
@@ -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);
+4 -2
View File
@@ -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:"");
+7 -4
View File
@@ -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
View File
@@ -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
+45 -1
View File
@@ -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
View File
@@ -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
+48
View File
@@ -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
View File
@@ -0,0 +1,3 @@
$ORIGIN rpz-nx.
@ IN SOA no.no no.no 1 2 3 4 5
local IN CNAME .
+3
View File
@@ -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
View File
@@ -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
+5
View File
@@ -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
+226
View File
@@ -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
+348
View File
@@ -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
+2
View File
@@ -770,6 +770,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:",
@@ -1249,6 +1250,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",
+2
View File
@@ -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;
+1
View File
@@ -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) }
+14 -1
View File
@@ -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
@@ -3453,7 +3454,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 +3619,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"));
+24 -2
View File
@@ -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))
+16
View File
@@ -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.
*
+26 -4
View File
@@ -143,7 +143,7 @@
* also contain an rcode that is nonzero, but in this case additional
* information (query, additional) can be passed along.
*
* The rcode and dns_msg are used to pass the result from the the rightmost
* The rcode and dns_msg are used to pass the result from the rightmost
* module towards the leftmost modules and then towards the user.
*
* If you want to avoid recursion-cycles where queries need other queries
@@ -712,8 +712,29 @@ struct module_func_block {
/** text string name of module */
const char* name;
/**
* init the module. Called once for the global state.
/**
* Set up the module for start. This is called only once at startup.
* Privileged operations like opening device files may be done here.
* The function ptr can be NULL, if it is not used.
* @param env: module environment.
* @param id: module id number.
* return: 0 on error
*/
int (*startup)(struct module_env* env, int id);
/**
* Close down the module for stop. This is called only once before
* shutdown to free resources allocated during startup().
* Closing privileged ports or files must be done here.
* The function ptr can be NULL, if it is not used.
* @param env: module environment.
* @param id: module id number.
*/
void (*destartup)(struct module_env* env, int id);
/**
* Initialise the module. Called when restarting or reloading the
* daemon.
* This is the place to apply settings from the config file.
* @param env: module environment.
* @param id: module id number.
@@ -722,7 +743,8 @@ struct module_func_block {
int (*init)(struct module_env* env, int id);
/**
* de-init, delete, the module. Called once for the global state.
* Deinitialise the module, undo stuff done during init().
* Called before reloading the daemon.
* @param env: module environment.
* @param id: module id number.
*/
+1 -1
View File
@@ -1220,7 +1220,7 @@ listen_sslctx_setup_2(void* ctxt)
if(!SSL_CTX_set_ecdh_auto(ctx,1)) {
log_crypto_err("Error in SSL_CTX_ecdh_auto, not enabling ECDHE");
}
#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) {
+7
View File
@@ -3307,6 +3307,13 @@ void http2_stream_add_meshstate(struct http2_stream* h2_stream,
h2_stream->mesh_state = m;
}
void http2_stream_remove_mesh_state(struct http2_stream* h2_stream)
{
if(!h2_stream)
return;
h2_stream->mesh_state = NULL;
}
/** delete http2 session server. After closing connection. */
static void http2_session_server_delete(struct http2_session* h2_session)
{
+3
View File
@@ -955,6 +955,9 @@ void http2_session_add_stream(struct http2_session* h2_session,
void http2_stream_add_meshstate(struct http2_stream* h2_stream,
struct mesh_area* mesh, struct mesh_state* m);
/** Remove mesh state from stream. When the mesh state has been removed. */
void http2_stream_remove_mesh_state(struct http2_stream* h2_stream);
/**
* This routine is published for checks and tests, and is only used internally.
* handle libevent callback for timer comm.
+2 -1
View File
@@ -1262,12 +1262,13 @@ verify_dnskey(struct module_env* env, struct val_env* ve,
struct trust_anchor* tp, struct ub_packed_rrset_key* rrset,
struct module_qstate* qstate)
{
char reasonbuf[256];
char* reason = NULL;
uint8_t sigalg[ALGO_NEEDS_MAX+1];
int downprot = env->cfg->harden_algo_downgrade;
enum sec_status sec = val_verify_DNSKEY_with_TA(env, ve, rrset,
tp->ds_rrset, tp->dnskey_rrset, downprot?sigalg:NULL, &reason,
NULL, qstate);
NULL, qstate, reasonbuf, sizeof(reasonbuf));
/* sigalg is ignored, it returns algorithms signalled to exist, but
* in 5011 there are no other rrsets to check. if downprot is
* enabled, then it checks that the DNSKEY is signed with all
+7 -5
View File
@@ -177,7 +177,7 @@ static int
nsec_verify_rrset(struct module_env* env, struct val_env* ve,
struct ub_packed_rrset_key* nsec, struct key_entry_key* kkey,
char** reason, sldns_ede_code* reason_bogus,
struct module_qstate* qstate)
struct module_qstate* qstate, char* reasonbuf, size_t reasonlen)
{
struct packed_rrset_data* d = (struct packed_rrset_data*)
nsec->entry.data;
@@ -189,7 +189,8 @@ nsec_verify_rrset(struct module_env* env, struct val_env* ve,
if(d->security == sec_status_secure)
return 1;
d->security = val_verify_rrset_entry(env, ve, nsec, kkey, reason,
reason_bogus, LDNS_SECTION_AUTHORITY, qstate, &verified);
reason_bogus, LDNS_SECTION_AUTHORITY, qstate, &verified,
reasonbuf, reasonlen);
if(d->security == sec_status_secure) {
rrset_update_sec_status(env->rrset_cache, nsec, *env->now);
return 1;
@@ -201,7 +202,8 @@ enum sec_status
val_nsec_prove_nodata_dsreply(struct module_env* env, struct val_env* ve,
struct query_info* qinfo, struct reply_info* rep,
struct key_entry_key* kkey, time_t* proof_ttl, char** reason,
sldns_ede_code* reason_bogus, struct module_qstate* qstate)
sldns_ede_code* reason_bogus, struct module_qstate* qstate,
char* reasonbuf, size_t reasonlen)
{
struct ub_packed_rrset_key* nsec = reply_find_rrset_section_ns(
rep, qinfo->qname, qinfo->qname_len, LDNS_RR_TYPE_NSEC,
@@ -219,7 +221,7 @@ val_nsec_prove_nodata_dsreply(struct module_env* env, struct val_env* ve,
* 2) this is not a delegation point */
if(nsec) {
if(!nsec_verify_rrset(env, ve, nsec, kkey, reason,
reason_bogus, qstate)) {
reason_bogus, qstate, reasonbuf, reasonlen)) {
verbose(VERB_ALGO, "NSEC RRset for the "
"referral did not verify.");
return sec_status_bogus;
@@ -250,7 +252,7 @@ val_nsec_prove_nodata_dsreply(struct module_env* env, struct val_env* ve,
if(rep->rrsets[i]->rk.type != htons(LDNS_RR_TYPE_NSEC))
continue;
if(!nsec_verify_rrset(env, ve, rep->rrsets[i], kkey, reason,
reason_bogus, qstate)) {
reason_bogus, qstate, reasonbuf, reasonlen)) {
verbose(VERB_ALGO, "NSEC for empty non-terminal "
"did not verify.");
*reason = "NSEC for empty non-terminal "
+3 -1
View File
@@ -68,6 +68,8 @@ struct key_entry_key;
* @param reason: string explaining why bogus.
* @param reason_bogus: relevant EDE code for validation failure.
* @param qstate: qstate with region.
* @param reasonbuf: buffer to use for fail reason string print.
* @param reasonlen: length of reasonbuf.
* @return security status.
* SECURE: proved absence of DS.
* INSECURE: proved that this was not a delegation point.
@@ -78,7 +80,7 @@ enum sec_status val_nsec_prove_nodata_dsreply(struct module_env* env,
struct val_env* ve, struct query_info* qinfo,
struct reply_info* rep, struct key_entry_key* kkey,
time_t* proof_ttl, char** reason, sldns_ede_code* reason_bogus,
struct module_qstate* qstate);
struct module_qstate* qstate, char* reasonbuf, size_t reasonlen);
/**
* nsec typemap check, takes an NSEC-type bitmap as argument, checks for type.
+5 -4
View File
@@ -1445,7 +1445,7 @@ static int
list_is_secure(struct module_env* env, struct val_env* ve,
struct ub_packed_rrset_key** list, size_t num,
struct key_entry_key* kkey, char** reason, sldns_ede_code *reason_bogus,
struct module_qstate* qstate)
struct module_qstate* qstate, char* reasonbuf, size_t reasonlen)
{
struct packed_rrset_data* d;
size_t i;
@@ -1461,7 +1461,7 @@ list_is_secure(struct module_env* env, struct val_env* ve,
continue;
d->security = val_verify_rrset_entry(env, ve, list[i], kkey,
reason, reason_bogus, LDNS_SECTION_AUTHORITY, qstate,
&verified);
&verified, reasonbuf, reasonlen);
if(d->security != sec_status_secure) {
verbose(VERB_ALGO, "NSEC3 did not verify");
return 0;
@@ -1476,7 +1476,7 @@ nsec3_prove_nods(struct module_env* env, struct val_env* ve,
struct ub_packed_rrset_key** list, size_t num,
struct query_info* qinfo, struct key_entry_key* kkey, char** reason,
sldns_ede_code* reason_bogus, struct module_qstate* qstate,
struct nsec3_cache_table* ct)
struct nsec3_cache_table* ct, char* reasonbuf, size_t reasonlen)
{
struct nsec3_filter flt;
struct ce_response ce;
@@ -1491,7 +1491,8 @@ nsec3_prove_nods(struct module_env* env, struct val_env* ve,
*reason = "no valid NSEC3s";
return sec_status_bogus; /* no valid NSEC3s, bogus */
}
if(!list_is_secure(env, ve, list, num, kkey, reason, reason_bogus, qstate)) {
if(!list_is_secure(env, ve, list, num, kkey, reason, reason_bogus,
qstate, reasonbuf, reasonlen)) {
*reason = "not all NSEC3 records secure";
return sec_status_bogus; /* not all NSEC3 records secure */
}
+3 -1
View File
@@ -210,6 +210,8 @@ nsec3_prove_wildcard(struct module_env* env, struct val_env* ve,
* @param reason_bogus: EDE (RFC8914) code paired with the reason of failure.
* @param qstate: qstate with region.
* @param ct: cached hashes table.
* @param reasonbuf: buffer to use for fail reason string print.
* @param reasonlen: length of reasonbuf.
* @return:
* sec_status SECURE of the proposition is proven by the NSEC3 RRs,
* BOGUS if not, INSECURE if all of the NSEC3s could be validly ignored.
@@ -222,7 +224,7 @@ nsec3_prove_nods(struct module_env* env, struct val_env* ve,
struct ub_packed_rrset_key** list, size_t num,
struct query_info* qinfo, struct key_entry_key* kkey, char** reason,
sldns_ede_code* reason_bogus, struct module_qstate* qstate,
struct nsec3_cache_table* ct);
struct nsec3_cache_table* ct, char* reasonbuf, size_t reasonlen);
/**
* Prove NXDOMAIN or NODATA.
+4 -1
View File
@@ -423,7 +423,10 @@ setup_dsa_sig(unsigned char** sig, unsigned int* len)
if(!dsasig) return 0;
#ifdef HAVE_DSA_SIG_SET0
if(!DSA_SIG_set0(dsasig, R, S)) return 0;
if(!DSA_SIG_set0(dsasig, R, S)) {
DSA_SIG_free(dsasig);
return 0;
}
#else
# ifndef S_SPLINT_S
dsasig->r = R;
+10 -9
View File
@@ -623,7 +623,8 @@ enum sec_status
dnskeyset_verify_rrset(struct module_env* env, struct val_env* ve,
struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey,
uint8_t* sigalg, char** reason, sldns_ede_code *reason_bogus,
sldns_pkt_section section, struct module_qstate* qstate, int* verified)
sldns_pkt_section section, struct module_qstate* qstate, int* verified,
char* reasonbuf, size_t reasonlen)
{
enum sec_status sec;
size_t i, num;
@@ -680,7 +681,8 @@ dnskeyset_verify_rrset(struct module_env* env, struct val_env* ve,
verbose(VERB_ALGO, "rrset failed to verify: "
"no valid signatures for %d algorithms",
(int)algo_needs_num_missing(&needs));
algo_needs_reason(env, alg, reason, "no signatures");
algo_needs_reason(alg, reason, "no signatures", reasonbuf,
reasonlen);
} else {
verbose(VERB_ALGO, "rrset failed to verify: "
"no valid signatures");
@@ -688,17 +690,16 @@ dnskeyset_verify_rrset(struct module_env* env, struct val_env* ve,
return sec_status_bogus;
}
void algo_needs_reason(struct module_env* env, int alg, char** reason, char* s)
void algo_needs_reason(int alg, char** reason, char* s, char* reasonbuf,
size_t reasonlen)
{
char buf[256];
sldns_lookup_table *t = sldns_lookup_by_id(sldns_algorithms, alg);
if(t&&t->name)
snprintf(buf, sizeof(buf), "%s with algorithm %s", s, t->name);
else snprintf(buf, sizeof(buf), "%s with algorithm ALG%u", s,
snprintf(reasonbuf, reasonlen, "%s with algorithm %s", s,
t->name);
else snprintf(reasonbuf, reasonlen, "%s with algorithm ALG%u", s,
(unsigned)alg);
*reason = regional_strdup(env->scratch, buf);
if(!*reason)
*reason = s;
*reason = reasonbuf;
}
enum sec_status
+8 -4
View File
@@ -134,12 +134,14 @@ int algo_needs_missing(struct algo_needs* n);
/**
* Format error reason for algorithm missing.
* @param env: module env with scratch for temp storage of string.
* @param alg: DNSKEY-algorithm missing.
* @param reason: destination.
* @param s: string, appended with 'with algorithm ..'.
* @param reasonbuf: buffer to use for fail reason string print.
* @param reasonlen: length of reasonbuf.
*/
void algo_needs_reason(struct module_env* env, int alg, char** reason, char* s);
void algo_needs_reason(int alg, char** reason, char* s, char* reasonbuf,
size_t reasonlen);
/**
* Check if dnskey matches a DS digest
@@ -261,6 +263,8 @@ uint16_t dnskey_get_flags(struct ub_packed_rrset_key* k, size_t idx);
* @param section: section of packet where this rrset comes from.
* @param qstate: qstate with region.
* @param verified: if not NULL the number of RRSIG validations is returned.
* @param reasonbuf: buffer to use for fail reason string print.
* @param reasonlen: length of reasonbuf.
* @return SECURE if one key in the set verifies one rrsig.
* UNCHECKED on allocation errors, unsupported algorithms, malformed data,
* and BOGUS on verification failures (no keys match any signatures).
@@ -269,8 +273,8 @@ enum sec_status dnskeyset_verify_rrset(struct module_env* env,
struct val_env* ve, struct ub_packed_rrset_key* rrset,
struct ub_packed_rrset_key* dnskey, uint8_t* sigalg,
char** reason, sldns_ede_code *reason_bogus,
sldns_pkt_section section, struct module_qstate* qstate, int* verified);
sldns_pkt_section section, struct module_qstate* qstate, int* verified,
char* reasonbuf, size_t reasonlen);
/**
* verify rrset against one specific dnskey (from rrset)
+61 -21
View File
@@ -240,6 +240,26 @@ val_find_best_signer(struct ub_packed_rrset_key* rrset,
}
}
/** Detect if the, unsigned, CNAME is under a previous DNAME RR in the
* message, and thus it was generated from that previous DNAME.
*/
static int
cname_under_previous_dname(struct reply_info* rep, size_t cname_idx,
size_t* ret)
{
size_t i;
for(i=0; i<cname_idx; i++) {
if(ntohs(rep->rrsets[i]->rk.type) == LDNS_RR_TYPE_DNAME &&
dname_strict_subdomain_c(rep->rrsets[cname_idx]->
rk.dname, rep->rrsets[i]->rk.dname)) {
*ret = i;
return 1;
}
}
*ret = 0;
return 0;
}
void
val_find_signer(enum val_classification subtype, struct query_info* qinf,
struct reply_info* rep, size_t skip, uint8_t** signer_name,
@@ -275,12 +295,19 @@ val_find_signer(enum val_classification subtype, struct query_info* qinf,
*signer_name = NULL;
*signer_len = 0;
} else if(subtype == VAL_CLASS_CNAME) {
size_t j;
/* check for the first signed cname/dname rrset */
for(i=skip; i<rep->an_numrrsets; i++) {
val_find_rrset_signer(rep->rrsets[i],
signer_name, signer_len);
if(*signer_name)
return;
if(ntohs(rep->rrsets[i]->rk.type) == LDNS_RR_TYPE_CNAME
&& cname_under_previous_dname(rep, i, &j)) {
val_find_rrset_signer(rep->rrsets[j],
signer_name, signer_len);
return;
}
if(ntohs(rep->rrsets[i]->rk.type) != LDNS_RR_TYPE_DNAME)
break; /* only check CNAME after a DNAME */
}
@@ -379,7 +406,7 @@ val_verify_rrset(struct module_env* env, struct val_env* ve,
struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* keys,
uint8_t* sigalg, char** reason, sldns_ede_code *reason_bogus,
sldns_pkt_section section, struct module_qstate* qstate,
int *verified)
int *verified, char* reasonbuf, size_t reasonlen)
{
enum sec_status sec;
struct packed_rrset_data* d = (struct packed_rrset_data*)rrset->
@@ -404,7 +431,7 @@ val_verify_rrset(struct module_env* env, struct val_env* ve,
log_nametypeclass(VERB_ALGO, "verify rrset", rrset->rk.dname,
ntohs(rrset->rk.type), ntohs(rrset->rk.rrset_class));
sec = dnskeyset_verify_rrset(env, ve, rrset, keys, sigalg, reason,
reason_bogus, section, qstate, verified);
reason_bogus, section, qstate, verified, reasonbuf, reasonlen);
verbose(VERB_ALGO, "verify result: %s", sec_status_to_string(sec));
regional_free_all(env->scratch);
@@ -439,7 +466,7 @@ val_verify_rrset_entry(struct module_env* env, struct val_env* ve,
struct ub_packed_rrset_key* rrset, struct key_entry_key* kkey,
char** reason, sldns_ede_code *reason_bogus,
sldns_pkt_section section, struct module_qstate* qstate,
int* verified)
int* verified, char* reasonbuf, size_t reasonlen)
{
/* temporary dnskey rrset-key */
struct ub_packed_rrset_key dnskey;
@@ -453,7 +480,7 @@ val_verify_rrset_entry(struct module_env* env, struct val_env* ve,
dnskey.entry.key = &dnskey;
dnskey.entry.data = kd->rrset_data;
sec = val_verify_rrset(env, ve, rrset, &dnskey, kd->algo, reason,
reason_bogus, section, qstate, verified);
reason_bogus, section, qstate, verified, reasonbuf, reasonlen);
return sec;
}
@@ -463,7 +490,7 @@ verify_dnskeys_with_ds_rr(struct module_env* env, struct val_env* ve,
struct ub_packed_rrset_key* dnskey_rrset,
struct ub_packed_rrset_key* ds_rrset, size_t ds_idx, char** reason,
sldns_ede_code *reason_bogus, struct module_qstate* qstate,
int *nonechecked)
int *nonechecked, char* reasonbuf, size_t reasonlen)
{
enum sec_status sec = sec_status_bogus;
size_t i, num, numchecked = 0, numhashok = 0, numsizesupp = 0;
@@ -517,8 +544,8 @@ verify_dnskeys_with_ds_rr(struct module_env* env, struct val_env* ve,
return sec_status_insecure;
}
if(numchecked == 0) {
algo_needs_reason(env, ds_get_key_algo(ds_rrset, ds_idx),
reason, "no keys have a DS");
algo_needs_reason(ds_get_key_algo(ds_rrset, ds_idx),
reason, "no keys have a DS", reasonbuf, reasonlen);
*nonechecked = 1;
} else if(numhashok == 0) {
*reason = "DS hash mismatches key";
@@ -549,7 +576,8 @@ enum sec_status
val_verify_DNSKEY_with_DS(struct module_env* env, struct val_env* ve,
struct ub_packed_rrset_key* dnskey_rrset,
struct ub_packed_rrset_key* ds_rrset, uint8_t* sigalg, char** reason,
sldns_ede_code *reason_bogus, struct module_qstate* qstate)
sldns_ede_code *reason_bogus, struct module_qstate* qstate,
char* reasonbuf, size_t reasonlen)
{
/* as long as this is false, we can consider this DS rrset to be
* equivalent to no DS rrset. */
@@ -588,7 +616,7 @@ val_verify_DNSKEY_with_DS(struct module_env* env, struct val_env* ve,
sec = verify_dnskeys_with_ds_rr(env, ve, dnskey_rrset,
ds_rrset, i, reason, reason_bogus, qstate,
&nonechecked);
&nonechecked, reasonbuf, reasonlen);
if(sec == sec_status_insecure) {
/* DNSKEY too large unsupported or algo refused by
* crypto lib. */
@@ -639,8 +667,8 @@ val_verify_DNSKEY_with_DS(struct module_env* env, struct val_env* ve,
/* If any were understandable, then it is bad. */
verbose(VERB_QUERY, "Failed to match any usable DS to a DNSKEY.");
if(sigalg && (alg=algo_needs_missing(&needs)) != 0) {
algo_needs_reason(env, alg, reason, "missing verification of "
"DNSKEY signature");
algo_needs_reason(alg, reason, "missing verification of "
"DNSKEY signature", reasonbuf, reasonlen);
}
return sec_status_bogus;
}
@@ -649,12 +677,13 @@ struct key_entry_key*
val_verify_new_DNSKEYs(struct regional* region, struct module_env* env,
struct val_env* ve, struct ub_packed_rrset_key* dnskey_rrset,
struct ub_packed_rrset_key* ds_rrset, int downprot, char** reason,
sldns_ede_code *reason_bogus, struct module_qstate* qstate)
sldns_ede_code *reason_bogus, struct module_qstate* qstate,
char* reasonbuf, size_t reasonlen)
{
uint8_t sigalg[ALGO_NEEDS_MAX+1];
enum sec_status sec = val_verify_DNSKEY_with_DS(env, ve,
dnskey_rrset, ds_rrset, downprot?sigalg:NULL, reason,
reason_bogus, qstate);
reason_bogus, qstate, reasonbuf, reasonlen);
if(sec == sec_status_secure) {
return key_entry_create_rrset(region,
@@ -679,7 +708,8 @@ val_verify_DNSKEY_with_TA(struct module_env* env, struct val_env* ve,
struct ub_packed_rrset_key* dnskey_rrset,
struct ub_packed_rrset_key* ta_ds,
struct ub_packed_rrset_key* ta_dnskey, uint8_t* sigalg, char** reason,
sldns_ede_code *reason_bogus, struct module_qstate* qstate)
sldns_ede_code *reason_bogus, struct module_qstate* qstate,
char* reasonbuf, size_t reasonlen)
{
/* as long as this is false, we can consider this anchor to be
* equivalent to no anchor. */
@@ -730,7 +760,8 @@ val_verify_DNSKEY_with_TA(struct module_env* env, struct val_env* ve,
continue;
sec = verify_dnskeys_with_ds_rr(env, ve, dnskey_rrset,
ta_ds, i, reason, reason_bogus, qstate, &nonechecked);
ta_ds, i, reason, reason_bogus, qstate, &nonechecked,
reasonbuf, reasonlen);
if(sec == sec_status_insecure) {
has_algo_refusal = 1;
continue;
@@ -810,8 +841,8 @@ val_verify_DNSKEY_with_TA(struct module_env* env, struct val_env* ve,
/* If any were understandable, then it is bad. */
verbose(VERB_QUERY, "Failed to match any usable anchor to a DNSKEY.");
if(sigalg && (alg=algo_needs_missing(&needs)) != 0) {
algo_needs_reason(env, alg, reason, "missing verification of "
"DNSKEY signature");
algo_needs_reason(alg, reason, "missing verification of "
"DNSKEY signature", reasonbuf, reasonlen);
}
return sec_status_bogus;
}
@@ -821,12 +852,14 @@ val_verify_new_DNSKEYs_with_ta(struct regional* region, struct module_env* env,
struct val_env* ve, struct ub_packed_rrset_key* dnskey_rrset,
struct ub_packed_rrset_key* ta_ds_rrset,
struct ub_packed_rrset_key* ta_dnskey_rrset, int downprot,
char** reason, sldns_ede_code *reason_bogus, struct module_qstate* qstate)
char** reason, sldns_ede_code *reason_bogus,
struct module_qstate* qstate, char* reasonbuf, size_t reasonlen)
{
uint8_t sigalg[ALGO_NEEDS_MAX+1];
enum sec_status sec = val_verify_DNSKEY_with_TA(env, ve,
dnskey_rrset, ta_ds_rrset, ta_dnskey_rrset,
downprot?sigalg:NULL, reason, reason_bogus, qstate);
downprot?sigalg:NULL, reason, reason_bogus, qstate,
reasonbuf, reasonlen);
if(sec == sec_status_secure) {
return key_entry_create_rrset(region,
@@ -979,7 +1012,7 @@ void
val_fill_reply(struct reply_info* chase, struct reply_info* orig,
size_t skip, uint8_t* name, size_t len, uint8_t* signer)
{
size_t i;
size_t i, j;
int seen_dname = 0;
chase->rrset_count = 0;
chase->an_numrrsets = 0;
@@ -1002,8 +1035,15 @@ val_fill_reply(struct reply_info* chase, struct reply_info* orig,
LDNS_RR_TYPE_DNAME) {
seen_dname = 1;
}
} else if(ntohs(orig->rrsets[i]->rk.type) == LDNS_RR_TYPE_CNAME
&& ((struct packed_rrset_data*)orig->rrsets[i]->
entry.data)->rrsig_count == 0 &&
cname_under_previous_dname(orig, i, &j) &&
rrset_has_signer(orig->rrsets[j], name, len)) {
chase->rrsets[chase->an_numrrsets++] = orig->rrsets[j];
chase->rrsets[chase->an_numrrsets++] = orig->rrsets[i];
}
}
}
/* AUTHORITY section */
for(i = (skip > orig->an_numrrsets)?skip:orig->an_numrrsets;
i<orig->an_numrrsets+orig->ns_numrrsets;
+20 -6
View File
@@ -125,13 +125,15 @@ void val_find_signer(enum val_classification subtype,
* @param section: section of packet where this rrset comes from.
* @param qstate: qstate with region.
* @param verified: if not NULL, the number of RRSIG validations is returned.
* @param reasonbuf: buffer to use for fail reason string print.
* @param reasonlen: length of reasonbuf.
* @return security status of verification.
*/
enum sec_status val_verify_rrset_entry(struct module_env* env,
struct val_env* ve, struct ub_packed_rrset_key* rrset,
struct key_entry_key* kkey, char** reason, sldns_ede_code *reason_bogus,
sldns_pkt_section section, struct module_qstate* qstate,
int* verified);
int* verified, char* reasonbuf, size_t reasonlen);
/**
* Verify DNSKEYs with DS rrset. Like val_verify_new_DNSKEYs but
@@ -146,6 +148,8 @@ enum sec_status val_verify_rrset_entry(struct module_env* env,
* @param reason: reason of failure. Fixed string or alloced in scratch.
* @param reason_bogus: EDE (RFC8914) code paired with the reason of failure.
* @param qstate: qstate with region.
* @param reasonbuf: buffer to use for fail reason string print.
* @param reasonlen: length of reasonbuf.
* @return: sec_status_secure if a DS matches.
* sec_status_insecure if end of trust (i.e., unknown algorithms).
* sec_status_bogus if it fails.
@@ -153,7 +157,8 @@ enum sec_status val_verify_rrset_entry(struct module_env* env,
enum sec_status val_verify_DNSKEY_with_DS(struct module_env* env,
struct val_env* ve, struct ub_packed_rrset_key* dnskey_rrset,
struct ub_packed_rrset_key* ds_rrset, uint8_t* sigalg, char** reason,
sldns_ede_code *reason_bogus, struct module_qstate* qstate);
sldns_ede_code *reason_bogus, struct module_qstate* qstate,
char* reasonbuf, size_t reasonlen);
/**
* Verify DNSKEYs with DS and DNSKEY rrset. Like val_verify_DNSKEY_with_DS
@@ -167,8 +172,10 @@ enum sec_status val_verify_DNSKEY_with_DS(struct module_env* env,
* algorithm is enough. The list of signalled algorithms is returned,
* must have enough space for ALGO_NEEDS_MAX+1.
* @param reason: reason of failure. Fixed string or alloced in scratch.
* @param reason_bogus: EDE (RFC8914) code paired with the reason of failure.
* @param reason_bogus: EDE (RFC8914) code paired with the reason of failure.
* @param qstate: qstate with region.
* @param reasonbuf: buffer to use for fail reason string print.
* @param reasonlen: length of reasonbuf.
* @return: sec_status_secure if a DS matches.
* sec_status_insecure if end of trust (i.e., unknown algorithms).
* sec_status_bogus if it fails.
@@ -177,7 +184,8 @@ enum sec_status val_verify_DNSKEY_with_TA(struct module_env* env,
struct val_env* ve, struct ub_packed_rrset_key* dnskey_rrset,
struct ub_packed_rrset_key* ta_ds,
struct ub_packed_rrset_key* ta_dnskey, uint8_t* sigalg, char** reason,
sldns_ede_code *reason_bogus, struct module_qstate* qstate);
sldns_ede_code *reason_bogus, struct module_qstate* qstate,
char* reasonbuf, size_t reasonlen);
/**
* Verify new DNSKEYs with DS rrset. The DS contains hash values that should
@@ -194,6 +202,8 @@ enum sec_status val_verify_DNSKEY_with_TA(struct module_env* env,
* @param reason: reason of failure. Fixed string or alloced in scratch.
* @param reason_bogus: EDE (RFC8914) code paired with the reason of failure.
* @param qstate: qstate with region.
* @param reasonbuf: buffer to use for fail reason string print.
* @param reasonlen: length of reasonbuf.
* @return a KeyEntry. This will either contain the now trusted
* dnskey_rrset, a "null" key entry indicating that this DS
* rrset/DNSKEY pair indicate an secure end to the island of trust
@@ -208,7 +218,8 @@ struct key_entry_key* val_verify_new_DNSKEYs(struct regional* region,
struct module_env* env, struct val_env* ve,
struct ub_packed_rrset_key* dnskey_rrset,
struct ub_packed_rrset_key* ds_rrset, int downprot, char** reason,
sldns_ede_code *reason_bogus, struct module_qstate* qstate);
sldns_ede_code *reason_bogus, struct module_qstate* qstate,
char* reasonbuf, size_t reasonlen);
/**
* Verify rrset with trust anchor: DS and DNSKEY rrset.
@@ -224,6 +235,8 @@ struct key_entry_key* val_verify_new_DNSKEYs(struct regional* region,
* @param reason: reason of failure. Fixed string or alloced in scratch.
* @param reason_bogus: EDE (RFC8914) code paired with the reason of failure.
* @param qstate: qstate with region.
* @param reasonbuf: buffer to use for fail reason string print.
* @param reasonlen: length of reasonbuf.
* @return a KeyEntry. This will either contain the now trusted
* dnskey_rrset, a "null" key entry indicating that this DS
* rrset/DNSKEY pair indicate an secure end to the island of trust
@@ -239,7 +252,8 @@ struct key_entry_key* val_verify_new_DNSKEYs_with_ta(struct regional* region,
struct ub_packed_rrset_key* dnskey_rrset,
struct ub_packed_rrset_key* ta_ds_rrset,
struct ub_packed_rrset_key* ta_dnskey_rrset, int downprot,
char** reason, sldns_ede_code *reason_bogus, struct module_qstate* qstate);
char** reason, sldns_ede_code *reason_bogus, struct module_qstate* qstate,
char* reasonbuf, size_t reasonlen);
/**
* Determine if DS rrset is usable for validator or not.
+92 -37
View File
@@ -72,7 +72,8 @@
/* forward decl for cache response and normal super inform calls of a DS */
static void process_ds_response(struct module_qstate* qstate,
struct val_qstate* vq, int id, int rcode, struct dns_msg* msg,
struct query_info* qinfo, struct sock_list* origin, int* suspend);
struct query_info* qinfo, struct sock_list* origin, int* suspend,
struct module_qstate* sub_qstate);
/* Updates the suplied EDE (RFC8914) code selectively so we don't lose
@@ -273,11 +274,17 @@ val_new_getmsg(struct module_qstate* qstate, struct val_qstate* vq)
return NULL;
if(vq->orig_msg->rep->rrset_count > RR_COUNT_MAX)
return NULL; /* protect against integer overflow */
vq->chase_reply->rrsets = regional_alloc_init(qstate->region,
vq->orig_msg->rep->rrsets, sizeof(struct ub_packed_rrset_key*)
* vq->orig_msg->rep->rrset_count);
/* Over allocate (+an_numrrsets) in case we need to put extra DNAME
* records for unsigned CNAME repetitions */
vq->chase_reply->rrsets = regional_alloc(qstate->region,
sizeof(struct ub_packed_rrset_key*) *
(vq->orig_msg->rep->rrset_count
+ vq->orig_msg->rep->an_numrrsets));
if(!vq->chase_reply->rrsets)
return NULL;
memmove(vq->chase_reply->rrsets, vq->orig_msg->rep->rrsets,
sizeof(struct ub_packed_rrset_key*) *
vq->orig_msg->rep->rrset_count);
vq->rrset_skip = 0;
return vq;
}
@@ -640,6 +647,7 @@ validate_msg_signatures(struct module_qstate* qstate, struct val_qstate* vq,
struct ub_packed_rrset_key* s;
enum sec_status sec;
int num_verifies = 0, verified, have_state = 0;
char reasonbuf[256];
char* reason = NULL;
sldns_ede_code reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
*suspend = 0;
@@ -675,7 +683,8 @@ validate_msg_signatures(struct module_qstate* qstate, struct val_qstate* vq,
/* Verify the answer rrset */
sec = val_verify_rrset_entry(env, ve, s, key_entry, &reason,
&reason_bogus, LDNS_SECTION_ANSWER, qstate, &verified);
&reason_bogus, LDNS_SECTION_ANSWER, qstate, &verified,
reasonbuf, sizeof(reasonbuf));
/* If the (answer) rrset failed to validate, then this
* message is BAD. */
if(sec != sec_status_secure) {
@@ -720,7 +729,7 @@ validate_msg_signatures(struct module_qstate* qstate, struct val_qstate* vq,
s = chase_reply->rrsets[i];
sec = val_verify_rrset_entry(env, ve, s, key_entry, &reason,
&reason_bogus, LDNS_SECTION_AUTHORITY, qstate,
&verified);
&verified, reasonbuf, sizeof(reasonbuf));
/* If anything in the authority section fails to be secure,
* we have a bad message. */
if(sec != sec_status_secure) {
@@ -766,7 +775,7 @@ validate_msg_signatures(struct module_qstate* qstate, struct val_qstate* vq,
if(sname && query_dname_compare(sname, key_entry->name)==0)
(void)val_verify_rrset_entry(env, ve, s, key_entry,
&reason, NULL, LDNS_SECTION_ADDITIONAL, qstate,
&verified);
&verified, reasonbuf, sizeof(reasonbuf));
/* the additional section can fail to be secure,
* it is optional, check signature in case we need
* to clean the additional section later. */
@@ -2060,7 +2069,7 @@ processFindKey(struct module_qstate* qstate, struct val_qstate* vq, int id)
verbose(VERB_ALGO, "Process suspended sub DS response");
msg = vq->sub_ds_msg;
process_ds_response(qstate, vq, id, LDNS_RCODE_NOERROR,
msg, &msg->qinfo, NULL, &suspend);
msg, &msg->qinfo, NULL, &suspend, NULL);
if(suspend) {
/* we'll come back here later to continue */
if(!validate_suspend_setup_timer(qstate, vq,
@@ -2076,7 +2085,7 @@ processFindKey(struct module_qstate* qstate, struct val_qstate* vq, int id)
vq->key_entry->name)) ) {
verbose(VERB_ALGO, "Process cached DS response");
process_ds_response(qstate, vq, id, LDNS_RCODE_NOERROR,
msg, &msg->qinfo, NULL, &suspend);
msg, &msg->qinfo, NULL, &suspend, NULL);
if(suspend) {
/* we'll come back here later to continue */
if(!validate_suspend_setup_timer(qstate, vq,
@@ -2658,6 +2667,8 @@ val_operate(struct module_qstate* qstate, enum module_ev event, int id,
* @param ta: trust anchor.
* @param qstate: qstate that needs key.
* @param id: module id.
* @param sub_qstate: the sub query state, that is the lookup that fetched
* the trust anchor data, it contains error information for the answer.
* @return new key entry or NULL on allocation failure.
* The key entry will either contain a validated DNSKEY rrset, or
* represent a Null key (query failed, but validation did not), or a
@@ -2665,31 +2676,38 @@ val_operate(struct module_qstate* qstate, enum module_ev event, int id,
*/
static struct key_entry_key*
primeResponseToKE(struct ub_packed_rrset_key* dnskey_rrset,
struct trust_anchor* ta, struct module_qstate* qstate, int id)
struct trust_anchor* ta, struct module_qstate* qstate, int id,
struct module_qstate* sub_qstate)
{
struct val_env* ve = (struct val_env*)qstate->env->modinfo[id];
struct key_entry_key* kkey = NULL;
enum sec_status sec = sec_status_unchecked;
char reasonbuf[256];
char* reason = NULL;
sldns_ede_code reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
int downprot = qstate->env->cfg->harden_algo_downgrade;
if(!dnskey_rrset) {
char* err = errinf_to_str_misc(sub_qstate);
char rstr[1024];
log_nametypeclass(VERB_OPS, "failed to prime trust anchor -- "
"could not fetch DNSKEY rrset",
ta->name, LDNS_RR_TYPE_DNSKEY, ta->dclass);
reason_bogus = LDNS_EDE_DNSKEY_MISSING;
reason = "no DNSKEY rrset";
if(!err) {
snprintf(rstr, sizeof(rstr), "no DNSKEY rrset");
} else {
snprintf(rstr, sizeof(rstr), "no DNSKEY rrset "
"[%s]", err);
}
if(qstate->env->cfg->harden_dnssec_stripped) {
errinf_ede(qstate, reason, reason_bogus);
errinf_ede(qstate, rstr, reason_bogus);
kkey = key_entry_create_bad(qstate->region, ta->name,
ta->namelen, ta->dclass, BOGUS_KEY_TTL,
reason_bogus, reason,
*qstate->env->now);
reason_bogus, rstr, *qstate->env->now);
} else kkey = key_entry_create_null(qstate->region, ta->name,
ta->namelen, ta->dclass, NULL_KEY_TTL,
reason_bogus, reason,
*qstate->env->now);
reason_bogus, rstr, *qstate->env->now);
if(!kkey) {
log_err("out of memory: allocate fail prime key");
return NULL;
@@ -2699,7 +2717,7 @@ primeResponseToKE(struct ub_packed_rrset_key* dnskey_rrset,
/* attempt to verify with trust anchor DS and DNSKEY */
kkey = val_verify_new_DNSKEYs_with_ta(qstate->region, qstate->env, ve,
dnskey_rrset, ta->ds_rrset, ta->dnskey_rrset, downprot,
&reason, &reason_bogus, qstate);
&reason, &reason_bogus, qstate, reasonbuf, sizeof(reasonbuf));
if(!kkey) {
log_err("out of memory: verifying prime TA");
return NULL;
@@ -2754,6 +2772,9 @@ primeResponseToKE(struct ub_packed_rrset_key* dnskey_rrset,
* DS response indicated an end to secure space, is_good if the DS
* validated. It returns ke=NULL if the DS response indicated that the
* request wasn't a delegation point.
* @param sub_qstate: the sub query state, that is the lookup that fetched
* the trust anchor data, it contains error information for the answer.
* Can be NULL.
* @return
* 0 on success,
* 1 on servfail error (malloc failure),
@@ -2762,9 +2783,10 @@ primeResponseToKE(struct ub_packed_rrset_key* dnskey_rrset,
static int
ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
int id, int rcode, struct dns_msg* msg, struct query_info* qinfo,
struct key_entry_key** ke)
struct key_entry_key** ke, struct module_qstate* sub_qstate)
{
struct val_env* ve = (struct val_env*)qstate->env->modinfo[id];
char reasonbuf[256];
char* reason = NULL;
sldns_ede_code reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
enum val_classification subtype;
@@ -2777,6 +2799,14 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
verbose(VERB_DETAIL, "DS response was error, thus bogus");
errinf(qstate, rc);
reason = "no DS";
if(sub_qstate) {
char* err = errinf_to_str_misc(sub_qstate);
if(err) {
char buf[1024];
snprintf(buf, sizeof(buf), "[%s]", err);
errinf(qstate, buf);
}
}
reason_bogus = LDNS_EDE_NETWORK_ERROR;
errinf_ede(qstate, reason, reason_bogus);
goto return_bogus;
@@ -2799,7 +2829,9 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
/* Verify only returns BOGUS or SECURE. If the rrset is
* bogus, then we are done. */
sec = val_verify_rrset_entry(qstate->env, ve, ds,
vq->key_entry, &reason, &reason_bogus, LDNS_SECTION_ANSWER, qstate, &verified);
vq->key_entry, &reason, &reason_bogus,
LDNS_SECTION_ANSWER, qstate, &verified, reasonbuf,
sizeof(reasonbuf));
if(sec != sec_status_secure) {
verbose(VERB_DETAIL, "DS rrset in DS response did "
"not verify");
@@ -2849,7 +2881,8 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
/* Try to prove absence of the DS with NSEC */
sec = val_nsec_prove_nodata_dsreply(
qstate->env, ve, qinfo, msg->rep, vq->key_entry,
&proof_ttl, &reason, &reason_bogus, qstate);
&proof_ttl, &reason, &reason_bogus, qstate,
reasonbuf, sizeof(reasonbuf));
switch(sec) {
case sec_status_secure:
verbose(VERB_DETAIL, "NSEC RRset for the "
@@ -2886,7 +2919,8 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
sec = nsec3_prove_nods(qstate->env, ve,
msg->rep->rrsets + msg->rep->an_numrrsets,
msg->rep->ns_numrrsets, qinfo, vq->key_entry, &reason,
&reason_bogus, qstate, &vq->nsec3_cache_table);
&reason_bogus, qstate, &vq->nsec3_cache_table,
reasonbuf, sizeof(reasonbuf));
switch(sec) {
case sec_status_insecure:
/* case insecure also continues to unsigned
@@ -2953,7 +2987,8 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
}
sec = val_verify_rrset_entry(qstate->env, ve, cname,
vq->key_entry, &reason, &reason_bogus,
LDNS_SECTION_ANSWER, qstate, &verified);
LDNS_SECTION_ANSWER, qstate, &verified, reasonbuf,
sizeof(reasonbuf));
if(sec == sec_status_secure) {
verbose(VERB_ALGO, "CNAME validated, "
"proof that DS does not exist");
@@ -3002,11 +3037,15 @@ return_bogus:
* @param origin: the origin of msg.
* @param suspend: returned true if the task takes too long and needs to
* suspend to continue the effort later.
* @param sub_qstate: the sub query state, that is the lookup that fetched
* the trust anchor data, it contains error information for the answer.
* Can be NULL.
*/
static void
process_ds_response(struct module_qstate* qstate, struct val_qstate* vq,
int id, int rcode, struct dns_msg* msg, struct query_info* qinfo,
struct sock_list* origin, int* suspend)
struct sock_list* origin, int* suspend,
struct module_qstate* sub_qstate)
{
struct val_env* ve = (struct val_env*)qstate->env->modinfo[id];
struct key_entry_key* dske = NULL;
@@ -3014,7 +3053,8 @@ process_ds_response(struct module_qstate* qstate, struct val_qstate* vq,
int ret;
*suspend = 0;
vq->empty_DS_name = NULL;
ret = ds_response_to_ke(qstate, vq, id, rcode, msg, qinfo, &dske);
ret = ds_response_to_ke(qstate, vq, id, rcode, msg, qinfo, &dske,
sub_qstate);
if(ret != 0) {
switch(ret) {
case 1:
@@ -3090,16 +3130,19 @@ process_ds_response(struct module_qstate* qstate, struct val_qstate* vq,
* @param msg: result message (if rcode is OK).
* @param qinfo: from the sub query state, query info.
* @param origin: the origin of msg.
* @param sub_qstate: the sub query state, that is the lookup that fetched
* the trust anchor data, it contains error information for the answer.
*/
static void
process_dnskey_response(struct module_qstate* qstate, struct val_qstate* vq,
int id, int rcode, struct dns_msg* msg, struct query_info* qinfo,
struct sock_list* origin)
struct sock_list* origin, struct module_qstate* sub_qstate)
{
struct val_env* ve = (struct val_env*)qstate->env->modinfo[id];
struct key_entry_key* old = vq->key_entry;
struct ub_packed_rrset_key* dnskey = NULL;
int downprot;
char reasonbuf[256];
char* reason = NULL;
sldns_ede_code reason_bogus = LDNS_EDE_DNSSEC_BOGUS;
@@ -3107,6 +3150,8 @@ process_dnskey_response(struct module_qstate* qstate, struct val_qstate* vq,
dnskey = reply_find_answer_rrset(qinfo, msg->rep);
if(dnskey == NULL) {
char* err;
char rstr[1024];
/* bad response */
verbose(VERB_DETAIL, "Missing DNSKEY RRset in response to "
"DNSKEY query.");
@@ -3118,17 +3163,22 @@ process_dnskey_response(struct module_qstate* qstate, struct val_qstate* vq,
vq->restart_count++;
return;
}
reason = "No DNSKEY record";
err = errinf_to_str_misc(sub_qstate);
if(!err) {
snprintf(rstr, sizeof(rstr), "No DNSKEY record");
} else {
snprintf(rstr, sizeof(rstr), "No DNSKEY record "
"[%s]", err);
}
reason_bogus = LDNS_EDE_DNSKEY_MISSING;
vq->key_entry = key_entry_create_bad(qstate->region,
qinfo->qname, qinfo->qname_len, qinfo->qclass,
BOGUS_KEY_TTL, reason_bogus, reason,
*qstate->env->now);
BOGUS_KEY_TTL, reason_bogus, rstr, *qstate->env->now);
if(!vq->key_entry) {
log_err("alloc failure in missing dnskey response");
/* key_entry is NULL for failure in Validate */
}
errinf_ede(qstate, reason, reason_bogus);
errinf_ede(qstate, rstr, reason_bogus);
errinf_origin(qstate, origin);
errinf_dname(qstate, "for key", qinfo->qname);
vq->state = VAL_VALIDATE_STATE;
@@ -3142,7 +3192,8 @@ process_dnskey_response(struct module_qstate* qstate, struct val_qstate* vq,
}
downprot = qstate->env->cfg->harden_algo_downgrade;
vq->key_entry = val_verify_new_DNSKEYs(qstate->region, qstate->env,
ve, dnskey, vq->ds_rrset, downprot, &reason, &reason_bogus, qstate);
ve, dnskey, vq->ds_rrset, downprot, &reason, &reason_bogus,
qstate, reasonbuf, sizeof(reasonbuf));
if(!vq->key_entry) {
log_err("out of memory in verify new DNSKEYs");
@@ -3192,10 +3243,13 @@ process_dnskey_response(struct module_qstate* qstate, struct val_qstate* vq,
* @param rcode: rcode result value.
* @param msg: result message (if rcode is OK).
* @param origin: the origin of msg.
* @param sub_qstate: the sub query state, that is the lookup that fetched
* the trust anchor data, it contains error information for the answer.
*/
static void
process_prime_response(struct module_qstate* qstate, struct val_qstate* vq,
int id, int rcode, struct dns_msg* msg, struct sock_list* origin)
int id, int rcode, struct dns_msg* msg, struct sock_list* origin,
struct module_qstate* sub_qstate)
{
struct val_env* ve = (struct val_env*)qstate->env->modinfo[id];
struct ub_packed_rrset_key* dnskey_rrset = NULL;
@@ -3227,7 +3281,8 @@ process_prime_response(struct module_qstate* qstate, struct val_qstate* vq,
return;
}
}
vq->key_entry = primeResponseToKE(dnskey_rrset, ta, qstate, id);
vq->key_entry = primeResponseToKE(dnskey_rrset, ta, qstate, id,
sub_qstate);
lock_basic_unlock(&ta->lock);
if(vq->key_entry) {
if(key_entry_isbad(vq->key_entry)
@@ -3278,14 +3333,14 @@ val_inform_super(struct module_qstate* qstate, int id,
if(vq->wait_prime_ta) {
vq->wait_prime_ta = 0;
process_prime_response(super, vq, id, qstate->return_rcode,
qstate->return_msg, qstate->reply_origin);
qstate->return_msg, qstate->reply_origin, qstate);
return;
}
if(qstate->qinfo.qtype == LDNS_RR_TYPE_DS) {
int suspend;
process_ds_response(super, vq, id, qstate->return_rcode,
qstate->return_msg, &qstate->qinfo,
qstate->reply_origin, &suspend);
qstate->reply_origin, &suspend, qstate);
/* If NSEC3 was needed during validation, NULL the NSEC3 cache;
* it will be re-initiated if needed later on.
* Validation (and the cache table) are happening/allocated in
@@ -3306,7 +3361,7 @@ val_inform_super(struct module_qstate* qstate, int id,
} else if(qstate->qinfo.qtype == LDNS_RR_TYPE_DNSKEY) {
process_dnskey_response(super, vq, id, qstate->return_rcode,
qstate->return_msg, &qstate->qinfo,
qstate->reply_origin);
qstate->reply_origin, qstate);
return;
}
log_err("internal error in validator: no inform_supers possible");
@@ -3344,8 +3399,8 @@ val_get_mem(struct module_env* env, int id)
*/
static struct module_func_block val_block = {
"validator",
&val_init, &val_deinit, &val_operate, &val_inform_super, &val_clear,
&val_get_mem
NULL, NULL, &val_init, &val_deinit, &val_operate, &val_inform_super,
&val_clear, &val_get_mem
};
struct module_func_block*