mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-08-17 21:25:50 +02:00
Compare commits
58
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2ffc17e826 | ||
|
|
3af4e44646 | ||
|
|
c3dd6a2dbd | ||
|
|
8fca3e7c5b | ||
|
|
8947c2c764 | ||
|
|
b1e3319a11 | ||
|
|
d52f501d90 | ||
|
|
7083d58c6b | ||
|
|
3adb9c8f92 | ||
|
|
51425b2388 | ||
|
|
d43760a8cd | ||
|
|
ea3e327006 | ||
|
|
be09350eca | ||
|
|
169acfc546 | ||
|
|
bed7cc2a90 | ||
|
|
02f4446833 | ||
|
|
c8a2289542 | ||
|
|
b53d90053e | ||
|
|
978b0696d3 | ||
|
|
ec5f86b4eb | ||
|
|
ec2f45c6fd | ||
|
|
6b319c97ee | ||
|
|
6eb3992c9e | ||
|
|
94a94fd8c8 | ||
|
|
36f9d1a2a9 | ||
|
|
d3a2264272 | ||
|
|
92b6c2a7b9 | ||
|
|
a335e601e4 | ||
|
|
a19009df1d | ||
|
|
96f8a94c19 | ||
|
|
2fe4e2ec3e | ||
|
|
e54928a628 | ||
|
|
538434186e | ||
|
|
65e7253d19 | ||
|
|
03ac902296 | ||
|
|
97ad1df343 | ||
|
|
2279cde8f7 | ||
|
|
ff653a7ef8 | ||
|
|
fd11cd9182 | ||
|
|
3953f827fb | ||
|
|
7fbc061846 | ||
|
|
70f73a33b3 | ||
|
|
b67fbb69e7 | ||
|
|
902c79608c | ||
|
|
08050dc939 | ||
|
|
9603924bb4 | ||
|
|
4c2da2b979 | ||
|
|
1974732d19 | ||
|
|
3cad5818a1 | ||
|
|
ad12109191 | ||
|
|
f611220eb8 | ||
|
|
ac609fcbfc | ||
|
|
486985fbdf | ||
|
|
caab100207 | ||
|
|
1d23e0c920 | ||
|
|
ad51795314 | ||
|
|
7d76e84953 | ||
|
|
c96e4ca121 |
@@ -10,6 +10,9 @@
|
||||
/config.status
|
||||
/dnstap/dnstap_config.h
|
||||
/dnscrypt/dnscrypt_config.h
|
||||
/util/configlexer.c
|
||||
/util/configparser.c
|
||||
/util/configparser.h
|
||||
/clubsyms.def
|
||||
/doc/example.conf
|
||||
/doc/libunbound.3
|
||||
@@ -55,6 +58,7 @@
|
||||
/pythonmod/unboundmodule.py
|
||||
/testdata/result.*
|
||||
/testdata/.done-*
|
||||
/testdata/.skip-*
|
||||
/testdata/.perfstats.txt
|
||||
/doc/html
|
||||
/doc/xml
|
||||
|
||||
+2
-1
@@ -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
@@ -9,7 +9,7 @@ AC_DEFUN([AC_PYTHON_DEVEL],[
|
||||
|
||||
AC_PATH_PROG([PYTHON],[python[$PYTHON_VERSION]])
|
||||
if test -z "$PYTHON"; then
|
||||
AC_MSG_ERROR([Cannot find python$PYTHON_VERSION in your system path])
|
||||
AC_MSG_ERROR([Cannot find 'python$PYTHON_VERSION' in your system path. You can use the environment variable 'PYTHON_VERSION=version_number' for an explicit version.])
|
||||
PYTHON_VERSION=""
|
||||
fi
|
||||
|
||||
|
||||
+1
-1
@@ -983,7 +983,7 @@ cachedb_get_mem(struct module_env* env, int id)
|
||||
*/
|
||||
static struct module_func_block cachedb_block = {
|
||||
"cachedb",
|
||||
&cachedb_init, &cachedb_deinit, &cachedb_operate,
|
||||
NULL, NULL, &cachedb_init, &cachedb_deinit, &cachedb_operate,
|
||||
&cachedb_inform_super, &cachedb_clear, &cachedb_get_mem
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -42,8 +42,8 @@
|
||||
[Unit]
|
||||
Description=Validating, recursive, and caching DNS resolver
|
||||
Documentation=man:unbound(8)
|
||||
After=network.target
|
||||
Before=network-online.target nss-lookup.target
|
||||
After=network-online.target
|
||||
Before=nss-lookup.target
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
[Unit]
|
||||
Description=Validating, recursive, and caching DNS resolver
|
||||
Documentation=man:unbound(8)
|
||||
After=network.target
|
||||
Before=network-online.target nss-lookup.target
|
||||
After=network-online.target
|
||||
Before=nss-lookup.target
|
||||
Wants=nss-lookup.target
|
||||
|
||||
[Install]
|
||||
|
||||
+30
-8
@@ -344,7 +344,7 @@ static int setup_acl_for_ports(struct acl_list* list,
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
daemon_open_shared_ports(struct daemon* daemon)
|
||||
{
|
||||
log_assert(daemon);
|
||||
@@ -444,6 +444,19 @@ daemon_open_shared_ports(struct daemon* daemon)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
daemon_privileged(struct daemon* daemon)
|
||||
{
|
||||
daemon->env->cfg = daemon->cfg;
|
||||
daemon->env->alloc = &daemon->superalloc;
|
||||
daemon->env->worker = NULL;
|
||||
if(!modstack_call_startup(&daemon->mods, daemon->cfg->module_conf,
|
||||
daemon->env)) {
|
||||
fatal_exit("failed to startup modules");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup modules. setup module stack.
|
||||
* @param daemon: the daemon
|
||||
@@ -453,11 +466,15 @@ static void daemon_setup_modules(struct daemon* daemon)
|
||||
daemon->env->cfg = daemon->cfg;
|
||||
daemon->env->alloc = &daemon->superalloc;
|
||||
daemon->env->worker = NULL;
|
||||
daemon->env->need_to_validate = 0; /* set by module init below */
|
||||
if(!modstack_setup(&daemon->mods, daemon->cfg->module_conf,
|
||||
daemon->env)) {
|
||||
fatal_exit("failed to setup modules");
|
||||
if(daemon->mods_inited) {
|
||||
modstack_call_deinit(&daemon->mods, daemon->env);
|
||||
}
|
||||
daemon->env->need_to_validate = 0; /* set by module init below */
|
||||
if(!modstack_call_init(&daemon->mods, daemon->cfg->module_conf,
|
||||
daemon->env)) {
|
||||
fatal_exit("failed to init modules");
|
||||
}
|
||||
daemon->mods_inited = 1;
|
||||
log_edns_known_options(VERB_ALGO, daemon->env);
|
||||
}
|
||||
|
||||
@@ -503,7 +520,10 @@ daemon_clear_allocs(struct daemon* daemon)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0; i<daemon->num; i++) {
|
||||
/* daemon->num may be different during reloads (after configuration
|
||||
* read). Use old_num which has the correct value used to setup the
|
||||
* worker_allocs */
|
||||
for(i=0; i<daemon->old_num; i++) {
|
||||
alloc_clear(daemon->worker_allocs[i]);
|
||||
free(daemon->worker_allocs[i]);
|
||||
}
|
||||
@@ -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]);
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
@@ -391,6 +391,13 @@ void server_stats_obtain(struct worker* worker, struct worker* who,
|
||||
else worker_send_cmd(who, worker_cmd_stats_noreset);
|
||||
verbose(VERB_ALGO, "wait for stats reply");
|
||||
if(tube_wait_timeout(worker->cmd, STATS_THREAD_WAIT) == 0) {
|
||||
#if defined(HAVE_PTHREAD) && defined(SIZEOF_PTHREAD_T) && defined(SIZEOF_UNSIGNED_LONG)
|
||||
# if SIZEOF_PTHREAD_T == SIZEOF_UNSIGNED_LONG
|
||||
unsigned long pthid = 0;
|
||||
if(verbosity >= VERB_OPS)
|
||||
memcpy(&pthid, &who->thr_id, sizeof(unsigned long));
|
||||
# endif
|
||||
#endif
|
||||
verbose(VERB_OPS, "no response from thread %d"
|
||||
#ifdef HAVE_GETTID
|
||||
" LWP %u"
|
||||
@@ -407,7 +414,7 @@ void server_stats_obtain(struct worker* worker, struct worker* who,
|
||||
#endif
|
||||
#if defined(HAVE_PTHREAD) && defined(SIZEOF_PTHREAD_T) && defined(SIZEOF_UNSIGNED_LONG)
|
||||
# if SIZEOF_PTHREAD_T == SIZEOF_UNSIGNED_LONG
|
||||
, (unsigned long)*((unsigned long*)&who->thr_id)
|
||||
, pthid
|
||||
# endif
|
||||
#endif
|
||||
);
|
||||
|
||||
@@ -473,7 +473,11 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
|
||||
#endif
|
||||
#ifdef HAVE_GETPWNAM
|
||||
struct passwd *pwd = NULL;
|
||||
#endif
|
||||
|
||||
if(!daemon_privileged(daemon))
|
||||
fatal_exit("could not do privileged setup");
|
||||
#ifdef HAVE_GETPWNAM
|
||||
if(cfg->username && cfg->username[0]) {
|
||||
if((pwd = getpwnam(cfg->username)) == NULL)
|
||||
fatal_exit("user '%s' does not exist.", cfg->username);
|
||||
|
||||
+175
-169
@@ -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
@@ -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
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -86,6 +86,31 @@ dt_pack(const Dnstap__Dnstap *d, void **buf, size_t *sz)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** See if the message is sent due to dnstap sample rate */
|
||||
static int
|
||||
dt_sample_rate_limited(struct dt_env* env)
|
||||
{
|
||||
lock_basic_lock(&env->sample_lock);
|
||||
/* Sampling is every [n] packets. Where n==1, every packet is sent */
|
||||
if(env->sample_rate > 1) {
|
||||
int submit = 0;
|
||||
/* if sampling is engaged... */
|
||||
if (env->sample_rate_count > env->sample_rate) {
|
||||
/* once the count passes the limit */
|
||||
/* submit the message */
|
||||
submit = 1;
|
||||
/* and reset the count */
|
||||
env->sample_rate_count = 0;
|
||||
}
|
||||
/* increment count regardless */
|
||||
env->sample_rate_count++;
|
||||
lock_basic_unlock(&env->sample_lock);
|
||||
return !submit;
|
||||
}
|
||||
lock_basic_unlock(&env->sample_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
dt_send(const struct dt_env *env, void *buf, size_t len_buf)
|
||||
{
|
||||
@@ -146,6 +171,7 @@ dt_create(struct config_file* cfg)
|
||||
env = (struct dt_env *) calloc(1, sizeof(struct dt_env));
|
||||
if (!env)
|
||||
return NULL;
|
||||
lock_basic_init(&env->sample_lock);
|
||||
|
||||
env->dtio = dt_io_thread_create();
|
||||
if(!env->dtio) {
|
||||
@@ -241,6 +267,12 @@ dt_apply_cfg(struct dt_env *env, struct config_file *cfg)
|
||||
{
|
||||
verbose(VERB_OPS, "dnstap Message/FORWARDER_RESPONSE enabled");
|
||||
}
|
||||
lock_basic_lock(&env->sample_lock);
|
||||
if((env->sample_rate = (unsigned int)cfg->dnstap_sample_rate))
|
||||
{
|
||||
verbose(VERB_OPS, "dnstap SAMPLE_RATE enabled and set to \"%d\"", (int)env->sample_rate);
|
||||
}
|
||||
lock_basic_unlock(&env->sample_lock);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -273,6 +305,7 @@ dt_delete(struct dt_env *env)
|
||||
if (!env)
|
||||
return;
|
||||
dt_io_thread_delete(env->dtio);
|
||||
lock_basic_destroy(&env->sample_lock);
|
||||
free(env->identity);
|
||||
free(env->version);
|
||||
free(env);
|
||||
@@ -409,6 +442,9 @@ dt_msg_send_client_query(struct dt_env *env,
|
||||
struct dt_msg dm;
|
||||
struct timeval qtime;
|
||||
|
||||
if(dt_sample_rate_limited(env))
|
||||
return;
|
||||
|
||||
if(tstamp)
|
||||
memcpy(&qtime, tstamp, sizeof(qtime));
|
||||
else gettimeofday(&qtime, NULL);
|
||||
@@ -447,6 +483,9 @@ dt_msg_send_client_response(struct dt_env *env,
|
||||
struct dt_msg dm;
|
||||
struct timeval rtime;
|
||||
|
||||
if(dt_sample_rate_limited(env))
|
||||
return;
|
||||
|
||||
gettimeofday(&rtime, NULL);
|
||||
|
||||
/* type */
|
||||
@@ -484,6 +523,9 @@ dt_msg_send_outside_query(struct dt_env *env,
|
||||
struct timeval qtime;
|
||||
uint16_t qflags;
|
||||
|
||||
if(dt_sample_rate_limited(env))
|
||||
return;
|
||||
|
||||
gettimeofday(&qtime, NULL);
|
||||
qflags = sldns_buffer_read_u16_at(qmsg, 2);
|
||||
|
||||
@@ -537,6 +579,9 @@ dt_msg_send_outside_response(struct dt_env *env,
|
||||
struct dt_msg dm;
|
||||
uint16_t qflags;
|
||||
|
||||
if(dt_sample_rate_limited(env))
|
||||
return;
|
||||
|
||||
(void)qbuf_len; log_assert(qbuf_len >= sizeof(qflags));
|
||||
memcpy(&qflags, qbuf, sizeof(qflags));
|
||||
qflags = ntohs(qflags);
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
|
||||
#ifdef USE_DNSTAP
|
||||
|
||||
#include "util/locks.h"
|
||||
struct config_file;
|
||||
struct sldns_buffer;
|
||||
struct dt_msg_queue;
|
||||
@@ -75,6 +76,13 @@ struct dt_env {
|
||||
unsigned log_forwarder_query_messages : 1;
|
||||
/** whether to log Message/FORWARDER_RESPONSE */
|
||||
unsigned log_forwarder_response_messages : 1;
|
||||
|
||||
/** lock on sample count */
|
||||
lock_basic_type sample_lock;
|
||||
/** rate limit value from config, samples 1/N messages */
|
||||
unsigned int sample_rate;
|
||||
/** rate limit counter */
|
||||
unsigned int sample_rate_count;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
+28
-31
@@ -34,41 +34,38 @@ AC_DEFUN([dt_DNSTAP],
|
||||
LDFLAGS="$LDFLAGS -L$withval/lib"
|
||||
],
|
||||
[
|
||||
ifdef([PKG_CHECK_MODULES],
|
||||
[
|
||||
PKG_CHECK_MODULES([PROTOBUFC], [libprotobuf-c],
|
||||
[
|
||||
CFLAGS="$CFLAGS $PROTOBUFC_CFLAGS"
|
||||
LIBS="$LIBS $PROTOBUFC_LIBS"
|
||||
],
|
||||
[
|
||||
# pkg-config failed; try falling back to known values
|
||||
# workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
|
||||
if test -f /usr/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I/usr/include/google"
|
||||
if test -n "$PKG_CONFIG"; then
|
||||
PKG_CHECK_MODULES([PROTOBUFC], [libprotobuf-c],
|
||||
[
|
||||
CFLAGS="$CFLAGS $PROTOBUFC_CFLAGS"
|
||||
LIBS="$LIBS $PROTOBUFC_LIBS"
|
||||
],
|
||||
[
|
||||
# pkg-config failed; try falling back to known values
|
||||
# workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
|
||||
if test -f /usr/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I/usr/include/google"
|
||||
else
|
||||
if test -f /usr/local/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I/usr/local/include/google"
|
||||
LDFLAGS="$LDFLAGS -L/usr/local/lib"
|
||||
else
|
||||
if test -f /usr/local/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I/usr/local/include/google"
|
||||
LDFLAGS="$LDFLAGS -L/usr/local/lib"
|
||||
else
|
||||
AC_MSG_ERROR([The protobuf-c package was not found with pkg-config. Please install protobuf-c!])
|
||||
fi
|
||||
AC_MSG_ERROR([The protobuf-c package was not found with pkg-config. Please install protobuf-c!])
|
||||
fi
|
||||
]
|
||||
)
|
||||
],
|
||||
[
|
||||
# workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
|
||||
if test -f /usr/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I/usr/include/google"
|
||||
else
|
||||
if test -f /usr/local/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I/usr/local/include/google"
|
||||
LDFLAGS="$LDFLAGS -L/usr/local/lib"
|
||||
fi
|
||||
]
|
||||
)
|
||||
else
|
||||
# workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
|
||||
if test -f /usr/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I/usr/include/google"
|
||||
else
|
||||
if test -f /usr/local/include/google/protobuf-c/protobuf-c.h; then
|
||||
CFLAGS="$CFLAGS -I/usr/local/include/google"
|
||||
LDFLAGS="$LDFLAGS -L/usr/local/lib"
|
||||
fi
|
||||
]
|
||||
)
|
||||
fi
|
||||
fi
|
||||
]
|
||||
)
|
||||
AC_SEARCH_LIBS([protobuf_c_message_pack], [protobuf-c], [],
|
||||
|
||||
+43
-8
@@ -176,10 +176,7 @@ void
|
||||
mq_wakeup_cb(void* arg)
|
||||
{
|
||||
struct dt_msg_queue* mq = (struct dt_msg_queue*)arg;
|
||||
/* even if the dtio is already active, because perhaps much
|
||||
* traffic suddenly, we leave the timer running to save on
|
||||
* managing it, the once a second timer is less work then
|
||||
* starting and stopping the timer frequently */
|
||||
|
||||
lock_basic_lock(&mq->dtio->wakeup_timer_lock);
|
||||
mq->dtio->wakeup_timer_enabled = 0;
|
||||
lock_basic_unlock(&mq->dtio->wakeup_timer_lock);
|
||||
@@ -210,6 +207,8 @@ dt_msg_queue_start_timer(struct dt_msg_queue* mq, int wakeupnow)
|
||||
lock_basic_lock(&mq->dtio->wakeup_timer_lock);
|
||||
if(mq->dtio->wakeup_timer_enabled) {
|
||||
if(wakeupnow) {
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
comm_timer_set(mq->wakeup_timer, &tv);
|
||||
}
|
||||
lock_basic_unlock(&mq->dtio->wakeup_timer_lock);
|
||||
@@ -221,8 +220,14 @@ dt_msg_queue_start_timer(struct dt_msg_queue* mq, int wakeupnow)
|
||||
if(!wakeupnow) {
|
||||
tv.tv_sec = 1;
|
||||
tv.tv_usec = 0;
|
||||
/* If it is already set, keep it running. */
|
||||
if(!comm_timer_is_set(mq->wakeup_timer))
|
||||
comm_timer_set(mq->wakeup_timer, &tv);
|
||||
} else {
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
comm_timer_set(mq->wakeup_timer, &tv);
|
||||
}
|
||||
comm_timer_set(mq->wakeup_timer, &tv);
|
||||
lock_basic_unlock(&mq->dtio->wakeup_timer_lock);
|
||||
}
|
||||
|
||||
@@ -260,8 +265,9 @@ dt_msg_queue_submit(struct dt_msg_queue* mq, void* buf, size_t len)
|
||||
|
||||
/* acquire lock */
|
||||
lock_basic_lock(&mq->lock);
|
||||
/* if list was empty, start timer for (eventual) wakeup */
|
||||
if(mq->first == NULL)
|
||||
/* if list was empty, start timer for (eventual) wakeup,
|
||||
* or if dtio is not writing now an eventual wakeup is needed. */
|
||||
if(mq->first == NULL || !mq->dtio->event_added_is_write)
|
||||
wakeupstarttimer = 1;
|
||||
/* if list contains more than wakeupnum elements, wakeup now,
|
||||
* or if list is (going to be) almost full */
|
||||
@@ -1259,6 +1265,13 @@ static void dtio_sleep(struct dt_io_thread* dtio)
|
||||
/* unregister the event polling for write, because there is
|
||||
* nothing to be written */
|
||||
(void)dtio_add_output_event_read(dtio);
|
||||
|
||||
/* Set wakeuptimer enabled off; so that the next worker thread that
|
||||
* wants to log starts a timer if needed, since the writer thread
|
||||
* has gone to sleep. */
|
||||
lock_basic_lock(&dtio->wakeup_timer_lock);
|
||||
dtio->wakeup_timer_enabled = 0;
|
||||
lock_basic_unlock(&dtio->wakeup_timer_lock);
|
||||
}
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
@@ -1322,7 +1335,11 @@ static int dtio_ssl_check_peer(struct dt_io_thread* dtio)
|
||||
if((SSL_get_verify_mode(dtio->ssl)&SSL_VERIFY_PEER)) {
|
||||
/* verification */
|
||||
if(SSL_get_verify_result(dtio->ssl) == X509_V_OK) {
|
||||
#ifdef HAVE_SSL_GET1_PEER_CERTIFICATE
|
||||
X509* x = SSL_get1_peer_certificate(dtio->ssl);
|
||||
#else
|
||||
X509* x = SSL_get_peer_certificate(dtio->ssl);
|
||||
#endif
|
||||
if(!x) {
|
||||
verbose(VERB_ALGO, "dnstap io, %s, SSL "
|
||||
"connection failed no certificate",
|
||||
@@ -1347,7 +1364,11 @@ static int dtio_ssl_check_peer(struct dt_io_thread* dtio)
|
||||
#endif
|
||||
X509_free(x);
|
||||
} else {
|
||||
#ifdef HAVE_SSL_GET1_PEER_CERTIFICATE
|
||||
X509* x = SSL_get1_peer_certificate(dtio->ssl);
|
||||
#else
|
||||
X509* x = SSL_get_peer_certificate(dtio->ssl);
|
||||
#endif
|
||||
if(x) {
|
||||
log_cert(VERB_ALGO, "dnstap io, peer "
|
||||
"certificate", x);
|
||||
@@ -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
@@ -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
@@ -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.
|
||||
|
||||
@@ -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
@@ -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.
|
||||
|
||||
@@ -297,8 +297,8 @@ inplace_cb_delete_wrapped(struct module_env* env, enum inplace_cb_list_type type
|
||||
*/
|
||||
static struct module_func_block dynlibmod_block = {
|
||||
"dynlib",
|
||||
&dynlibmod_init, &dynlibmod_deinit, &dynlibmod_operate, &dynlibmod_inform_super,
|
||||
&dynlibmod_clear, &dynlibmod_get_mem
|
||||
NULL, NULL, &dynlibmod_init, &dynlibmod_deinit, &dynlibmod_operate,
|
||||
&dynlibmod_inform_super, &dynlibmod_clear, &dynlibmod_get_mem
|
||||
};
|
||||
|
||||
struct module_func_block* dynlibmod_get_funcblock(void)
|
||||
|
||||
@@ -995,7 +995,8 @@ subnetmod_get_mem(struct module_env *env, int id)
|
||||
* The module function block
|
||||
*/
|
||||
static struct module_func_block subnetmod_block = {
|
||||
"subnetcache", &subnetmod_init, &subnetmod_deinit, &subnetmod_operate,
|
||||
"subnetcache",
|
||||
NULL, NULL, &subnetmod_init, &subnetmod_deinit, &subnetmod_operate,
|
||||
&subnetmod_inform_super, &subnetmod_clear, &subnetmod_get_mem
|
||||
};
|
||||
|
||||
|
||||
+1
-1
@@ -615,7 +615,7 @@ ipsecmod_get_mem(struct module_env* env, int id)
|
||||
*/
|
||||
static struct module_func_block ipsecmod_block = {
|
||||
"ipsecmod",
|
||||
&ipsecmod_init, &ipsecmod_deinit, &ipsecmod_operate,
|
||||
NULL, NULL, &ipsecmod_init, &ipsecmod_deinit, &ipsecmod_operate,
|
||||
&ipsecmod_inform_super, &ipsecmod_clear, &ipsecmod_get_mem
|
||||
};
|
||||
|
||||
|
||||
+162
-47
@@ -17,9 +17,19 @@
|
||||
#include "sldns/wire2str.h"
|
||||
#include "sldns/parseutil.h"
|
||||
|
||||
#ifdef HAVE_NET_PFVAR_H
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <net/if.h>
|
||||
#include <net/pfvar.h>
|
||||
typedef intptr_t filter_dev;
|
||||
#else
|
||||
#include <libmnl/libmnl.h>
|
||||
#include <linux/netfilter/nfnetlink.h>
|
||||
#include <linux/netfilter/ipset/ip_set.h>
|
||||
typedef struct mnl_socket * filter_dev;
|
||||
#endif
|
||||
|
||||
#define BUFF_LEN 256
|
||||
|
||||
@@ -41,24 +51,95 @@ static int error_response(struct module_qstate* qstate, int id, int rcode) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct mnl_socket * open_mnl_socket() {
|
||||
struct mnl_socket *mnl;
|
||||
#ifdef HAVE_NET_PFVAR_H
|
||||
static void * open_filter() {
|
||||
filter_dev dev;
|
||||
|
||||
mnl = mnl_socket_open(NETLINK_NETFILTER);
|
||||
if (!mnl) {
|
||||
dev = open("/dev/pf", O_RDWR);
|
||||
if (dev == -1) {
|
||||
log_err("open(\"/dev/pf\") failed: %s", strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
return (void *)dev;
|
||||
}
|
||||
#else
|
||||
static void * open_filter() {
|
||||
filter_dev dev;
|
||||
|
||||
dev = mnl_socket_open(NETLINK_NETFILTER);
|
||||
if (!dev) {
|
||||
log_err("ipset: could not open netfilter.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (mnl_socket_bind(mnl, 0, MNL_SOCKET_AUTOPID) < 0) {
|
||||
mnl_socket_close(mnl);
|
||||
if (mnl_socket_bind(dev, 0, MNL_SOCKET_AUTOPID) < 0) {
|
||||
mnl_socket_close(dev);
|
||||
log_err("ipset: could not bind netfilter.");
|
||||
return NULL;
|
||||
}
|
||||
return mnl;
|
||||
return (void *)dev;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int add_to_ipset(struct mnl_socket *mnl, const char *setname, const void *ipaddr, int af) {
|
||||
#ifdef HAVE_NET_PFVAR_H
|
||||
static int add_to_ipset(filter_dev dev, const char *setname, const void *ipaddr, int af) {
|
||||
struct pfioc_table io;
|
||||
struct pfr_addr addr;
|
||||
const char *p;
|
||||
int i;
|
||||
|
||||
bzero(&io, sizeof(io));
|
||||
bzero(&addr, sizeof(addr));
|
||||
|
||||
p = strrchr(setname, '/');
|
||||
if (p) {
|
||||
i = p - setname;
|
||||
if (i >= PATH_MAX) {
|
||||
errno = ENAMETOOLONG;
|
||||
return -1;
|
||||
}
|
||||
memcpy(io.pfrio_table.pfrt_anchor, setname, i);
|
||||
if (i < PATH_MAX)
|
||||
io.pfrio_table.pfrt_anchor[i] = '\0';
|
||||
p++;
|
||||
}
|
||||
else
|
||||
p = setname;
|
||||
|
||||
if (strlen(p) >= PF_TABLE_NAME_SIZE) {
|
||||
errno = ENAMETOOLONG;
|
||||
return -1;
|
||||
}
|
||||
strlcpy(io.pfrio_table.pfrt_name, p, PF_TABLE_NAME_SIZE);
|
||||
|
||||
io.pfrio_buffer = &addr;
|
||||
io.pfrio_size = 1;
|
||||
io.pfrio_esize = sizeof(addr);
|
||||
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
addr.pfra_ip4addr = *(struct in_addr *)ipaddr;
|
||||
addr.pfra_net = 32;
|
||||
break;
|
||||
case AF_INET6:
|
||||
addr.pfra_ip6addr = *(struct in6_addr *)ipaddr;
|
||||
addr.pfra_net = 128;
|
||||
break;
|
||||
default:
|
||||
errno = EAFNOSUPPORT;
|
||||
return -1;
|
||||
}
|
||||
addr.pfra_af = af;
|
||||
|
||||
if (ioctl(dev, DIOCRADDADDRS, &io) == -1) {
|
||||
log_err("ioctl failed: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static int add_to_ipset(filter_dev dev, const char *setname, const void *ipaddr, int af) {
|
||||
struct nlmsghdr *nlh;
|
||||
struct nfgenmsg *nfg;
|
||||
struct nlattr *nested[2];
|
||||
@@ -91,14 +172,15 @@ static int add_to_ipset(struct mnl_socket *mnl, const char *setname, const void
|
||||
mnl_attr_nest_end(nlh, nested[1]);
|
||||
mnl_attr_nest_end(nlh, nested[0]);
|
||||
|
||||
if (mnl_socket_sendto(mnl, nlh, nlh->nlmsg_len) < 0) {
|
||||
if (mnl_socket_sendto(dev, nlh, nlh->nlmsg_len) < 0) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
ipset_add_rrset_data(struct ipset_env *ie, struct mnl_socket *mnl,
|
||||
ipset_add_rrset_data(struct ipset_env *ie,
|
||||
struct packed_rrset_data *d, const char* setname, int af,
|
||||
const char* dname)
|
||||
{
|
||||
@@ -123,12 +205,16 @@ ipset_add_rrset_data(struct ipset_env *ie, struct mnl_socket *mnl,
|
||||
snprintf(ip, sizeof(ip), "(inet_ntop_error)");
|
||||
verbose(VERB_QUERY, "ipset: add %s to %s for %s", ip, setname, dname);
|
||||
}
|
||||
ret = add_to_ipset(mnl, setname, rr_data + 2, af);
|
||||
ret = add_to_ipset((filter_dev)ie->dev, setname, rr_data + 2, af);
|
||||
if (ret < 0) {
|
||||
log_err("ipset: could not add %s into %s", dname, setname);
|
||||
|
||||
mnl_socket_close(mnl);
|
||||
ie->mnl = NULL;
|
||||
#if HAVE_NET_PFVAR_H
|
||||
/* don't close as we might not be able to open again due to dropped privs */
|
||||
#else
|
||||
mnl_socket_close((filter_dev)ie->dev);
|
||||
ie->dev = NULL;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -137,8 +223,8 @@ ipset_add_rrset_data(struct ipset_env *ie, struct mnl_socket *mnl,
|
||||
|
||||
static int
|
||||
ipset_check_zones_for_rrset(struct module_env *env, struct ipset_env *ie,
|
||||
struct mnl_socket *mnl, struct ub_packed_rrset_key *rrset,
|
||||
const char *qname, const int qlen, const char *setname, int af)
|
||||
struct ub_packed_rrset_key *rrset, const char *qname, int qlen,
|
||||
const char *setname, int af)
|
||||
{
|
||||
static char dname[BUFF_LEN];
|
||||
const char *ds, *qs;
|
||||
@@ -152,11 +238,20 @@ ipset_check_zones_for_rrset(struct module_env *env, struct ipset_env *ie,
|
||||
log_err("bad domain name");
|
||||
return -1;
|
||||
}
|
||||
if (dname[dlen - 1] == '.') {
|
||||
dlen--;
|
||||
}
|
||||
if (qname[qlen - 1] == '.') {
|
||||
qlen--;
|
||||
}
|
||||
|
||||
for (p = env->cfg->local_zones_ipset; p; p = p->next) {
|
||||
ds = NULL;
|
||||
qs = NULL;
|
||||
plen = strlen(p->str);
|
||||
if (p->str[plen - 1] == '.') {
|
||||
plen--;
|
||||
}
|
||||
|
||||
if (dlen == plen || (dlen > plen && dname[dlen - plen - 1] == '.' )) {
|
||||
ds = dname + (dlen - plen);
|
||||
@@ -167,8 +262,7 @@ ipset_check_zones_for_rrset(struct module_env *env, struct ipset_env *ie,
|
||||
if ((ds && strncasecmp(p->str, ds, plen) == 0)
|
||||
|| (qs && strncasecmp(p->str, qs, plen) == 0)) {
|
||||
d = (struct packed_rrset_data*)rrset->entry.data;
|
||||
ipset_add_rrset_data(ie, mnl, d, setname,
|
||||
af, dname);
|
||||
ipset_add_rrset_data(ie, d, setname, af, dname);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -178,7 +272,6 @@ ipset_check_zones_for_rrset(struct module_env *env, struct ipset_env *ie,
|
||||
static int ipset_update(struct module_env *env, struct dns_msg *return_msg,
|
||||
struct query_info qinfo, struct ipset_env *ie)
|
||||
{
|
||||
struct mnl_socket *mnl;
|
||||
size_t i;
|
||||
const char *setname;
|
||||
struct ub_packed_rrset_key *rrset;
|
||||
@@ -186,15 +279,17 @@ static int ipset_update(struct module_env *env, struct dns_msg *return_msg,
|
||||
static char qname[BUFF_LEN];
|
||||
int qlen;
|
||||
|
||||
mnl = (struct mnl_socket *)ie->mnl;
|
||||
if (!mnl) {
|
||||
#ifdef HAVE_NET_PFVAR_H
|
||||
#else
|
||||
if (!ie->dev) {
|
||||
/* retry to create mnl socket */
|
||||
mnl = open_mnl_socket();
|
||||
if (!mnl) {
|
||||
ie->dev = open_filter();
|
||||
if (!ie->dev) {
|
||||
log_warn("ipset open_filter failed");
|
||||
return -1;
|
||||
}
|
||||
ie->mnl = mnl;
|
||||
}
|
||||
#endif
|
||||
|
||||
qlen = sldns_wire2str_dname_buf(qinfo.qname, qinfo.qname_len,
|
||||
qname, BUFF_LEN);
|
||||
@@ -217,8 +312,8 @@ static int ipset_update(struct module_env *env, struct dns_msg *return_msg,
|
||||
}
|
||||
|
||||
if (setname) {
|
||||
if(ipset_check_zones_for_rrset(env, ie, mnl, rrset,
|
||||
qname, qlen, setname, af) == -1)
|
||||
if(ipset_check_zones_for_rrset(env, ie, rrset, qname,
|
||||
qlen, setname, af) == -1)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -226,7 +321,7 @@ static int ipset_update(struct module_env *env, struct dns_msg *return_msg,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ipset_init(struct module_env* env, int id) {
|
||||
int ipset_startup(struct module_env* env, int id) {
|
||||
struct ipset_env *ipset_env;
|
||||
|
||||
ipset_env = (struct ipset_env *)calloc(1, sizeof(struct ipset_env));
|
||||
@@ -237,7 +332,43 @@ int ipset_init(struct module_env* env, int id) {
|
||||
|
||||
env->modinfo[id] = (void *)ipset_env;
|
||||
|
||||
ipset_env->mnl = NULL;
|
||||
#ifdef HAVE_NET_PFVAR_H
|
||||
ipset_env->dev = open_filter();
|
||||
if (!ipset_env->dev) {
|
||||
log_err("ipset open_filter failed");
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
ipset_env->dev = NULL;
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ipset_destartup(struct module_env* env, int id) {
|
||||
filter_dev dev;
|
||||
struct ipset_env *ipset_env;
|
||||
|
||||
if (!env || !env->modinfo[id]) {
|
||||
return;
|
||||
}
|
||||
ipset_env = (struct ipset_env*)env->modinfo[id];
|
||||
|
||||
dev = (filter_dev)ipset_env->dev;
|
||||
if (dev) {
|
||||
#if HAVE_NET_PFVAR_H
|
||||
close(dev);
|
||||
#else
|
||||
mnl_socket_close(dev);
|
||||
#endif
|
||||
ipset_env->dev = NULL;
|
||||
}
|
||||
|
||||
free(ipset_env);
|
||||
env->modinfo[id] = NULL;
|
||||
}
|
||||
|
||||
int ipset_init(struct module_env* env, int id) {
|
||||
struct ipset_env *ipset_env = env->modinfo[id];
|
||||
|
||||
ipset_env->name_v4 = env->cfg->ipset_name_v4;
|
||||
ipset_env->name_v6 = env->cfg->ipset_name_v6;
|
||||
@@ -253,24 +384,8 @@ int ipset_init(struct module_env* env, int id) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ipset_deinit(struct module_env *env, int id) {
|
||||
struct mnl_socket *mnl;
|
||||
struct ipset_env *ipset_env;
|
||||
|
||||
if (!env || !env->modinfo[id]) {
|
||||
return;
|
||||
}
|
||||
|
||||
ipset_env = (struct ipset_env *)env->modinfo[id];
|
||||
|
||||
mnl = (struct mnl_socket *)ipset_env->mnl;
|
||||
if (mnl) {
|
||||
mnl_socket_close(mnl);
|
||||
ipset_env->mnl = NULL;
|
||||
}
|
||||
|
||||
free(ipset_env);
|
||||
env->modinfo[id] = NULL;
|
||||
void ipset_deinit(struct module_env *ATTR_UNUSED(env), int ATTR_UNUSED(id)) {
|
||||
/* nothing */
|
||||
}
|
||||
|
||||
static int ipset_new(struct module_qstate* qstate, int id) {
|
||||
@@ -376,8 +491,8 @@ size_t ipset_get_mem(struct module_env *env, int id) {
|
||||
*/
|
||||
static struct module_func_block ipset_block = {
|
||||
"ipset",
|
||||
&ipset_init, &ipset_deinit, &ipset_operate,
|
||||
&ipset_inform_super, &ipset_clear, &ipset_get_mem
|
||||
&ipset_startup, &ipset_destartup, &ipset_init, &ipset_deinit,
|
||||
&ipset_operate, &ipset_inform_super, &ipset_clear, &ipset_get_mem
|
||||
};
|
||||
|
||||
struct module_func_block * ipset_get_funcblock(void) {
|
||||
|
||||
+5
-1
@@ -37,7 +37,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
struct ipset_env {
|
||||
void* mnl;
|
||||
void* dev;
|
||||
|
||||
int v4_enabled;
|
||||
int v6_enabled;
|
||||
@@ -50,6 +50,10 @@ struct ipset_qstate {
|
||||
int dummy;
|
||||
};
|
||||
|
||||
/** Startup the ipset module */
|
||||
int ipset_startup(struct module_env* env, int id);
|
||||
/** Destartup the ipset module */
|
||||
void ipset_destartup(struct module_env* env, int id);
|
||||
/** Init the ipset module */
|
||||
int ipset_init(struct module_env* env, int id);
|
||||
/** Deinit the ipset module */
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
@@ -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*
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -75,7 +75,9 @@ context_finalize(struct ub_ctx* ctx)
|
||||
ctx->pipe_pid = getpid();
|
||||
cfg_apply_local_port_policy(cfg, 65536);
|
||||
config_apply(cfg);
|
||||
if(!modstack_setup(&ctx->mods, cfg->module_conf, ctx->env))
|
||||
if(!modstack_call_startup(&ctx->mods, cfg->module_conf, ctx->env))
|
||||
return UB_INITFAIL;
|
||||
if(!modstack_call_init(&ctx->mods, cfg->module_conf, ctx->env))
|
||||
return UB_INITFAIL;
|
||||
listen_setup_locks();
|
||||
log_edns_known_options(VERB_ALGO, ctx->env);
|
||||
|
||||
@@ -188,7 +188,9 @@ ub_ctx_create(void)
|
||||
int e = errno;
|
||||
ub_randfree(ctx->seed_rnd);
|
||||
config_delete(ctx->env->cfg);
|
||||
modstack_desetup(&ctx->mods, ctx->env);
|
||||
modstack_call_deinit(&ctx->mods, ctx->env);
|
||||
modstack_call_destartup(&ctx->mods, ctx->env);
|
||||
modstack_free(&ctx->mods);
|
||||
listen_desetup_locks();
|
||||
edns_known_options_delete(ctx->env);
|
||||
edns_strings_delete(ctx->env->edns_strings);
|
||||
@@ -202,7 +204,9 @@ ub_ctx_create(void)
|
||||
tube_delete(ctx->qq_pipe);
|
||||
ub_randfree(ctx->seed_rnd);
|
||||
config_delete(ctx->env->cfg);
|
||||
modstack_desetup(&ctx->mods, ctx->env);
|
||||
modstack_call_deinit(&ctx->mods, ctx->env);
|
||||
modstack_call_destartup(&ctx->mods, ctx->env);
|
||||
modstack_free(&ctx->mods);
|
||||
listen_desetup_locks();
|
||||
edns_known_options_delete(ctx->env);
|
||||
edns_strings_delete(ctx->env->edns_strings);
|
||||
@@ -360,7 +364,9 @@ ub_ctx_delete(struct ub_ctx* ctx)
|
||||
}
|
||||
libworker_delete_event(ctx->event_worker);
|
||||
|
||||
modstack_desetup(&ctx->mods, ctx->env);
|
||||
modstack_call_deinit(&ctx->mods, ctx->env);
|
||||
modstack_call_destartup(&ctx->mods, ctx->env);
|
||||
modstack_free(&ctx->mods);
|
||||
a = ctx->alloc_list;
|
||||
while(a) {
|
||||
na = a->super;
|
||||
|
||||
+1
-1
@@ -53,7 +53,7 @@ Generate a distribution tar file for unbound.
|
||||
(which will then be unbound-<version>rc<number>)
|
||||
-u git_url Retrieve the source from the specified repository url.
|
||||
Detected from the working copy if not specified.
|
||||
-b git_branch Retrieve the the specified branch or tag.
|
||||
-b git_branch Retrieve the specified branch or tag.
|
||||
Detected from the working copy if not specified.
|
||||
-wssl openssl.xx.tar.gz Also build openssl from tarball for windows dist.
|
||||
-wxp expat.xx.tar.gz Also build expat from tarball for windows dist.
|
||||
|
||||
@@ -777,8 +777,8 @@ size_t pythonmod_get_mem(struct module_env* env, int id)
|
||||
*/
|
||||
static struct module_func_block pythonmod_block = {
|
||||
"python",
|
||||
&pythonmod_init, &pythonmod_deinit, &pythonmod_operate, &pythonmod_inform_super,
|
||||
&pythonmod_clear, &pythonmod_get_mem
|
||||
NULL, NULL, &pythonmod_init, &pythonmod_deinit, &pythonmod_operate,
|
||||
&pythonmod_inform_super, &pythonmod_clear, &pythonmod_get_mem
|
||||
};
|
||||
|
||||
struct module_func_block* pythonmod_get_funcblock(void)
|
||||
|
||||
+2
-2
@@ -1259,8 +1259,8 @@ respip_get_mem(struct module_env* env, int id)
|
||||
*/
|
||||
static struct module_func_block respip_block = {
|
||||
"respip",
|
||||
&respip_init, &respip_deinit, &respip_operate, &respip_inform_super,
|
||||
&respip_clear, &respip_get_mem
|
||||
NULL, NULL, &respip_init, &respip_deinit, &respip_operate,
|
||||
&respip_inform_super, &respip_clear, &respip_get_mem
|
||||
};
|
||||
|
||||
struct module_func_block*
|
||||
|
||||
+30
-16
@@ -7778,7 +7778,8 @@ static void auth_zone_log(uint8_t* name, enum verbosity_value level,
|
||||
static int zonemd_dnssec_verify_rrset(struct auth_zone* z,
|
||||
struct module_env* env, struct module_stack* mods,
|
||||
struct ub_packed_rrset_key* dnskey, struct auth_data* node,
|
||||
struct auth_rrset* rrset, char** why_bogus, uint8_t* sigalg)
|
||||
struct auth_rrset* rrset, char** why_bogus, uint8_t* sigalg,
|
||||
char* reasonbuf, size_t reasonlen)
|
||||
{
|
||||
struct ub_packed_rrset_key pk;
|
||||
enum sec_status sec;
|
||||
@@ -7808,7 +7809,7 @@ static int zonemd_dnssec_verify_rrset(struct auth_zone* z,
|
||||
"zonemd: verify %s RRset with DNSKEY", typestr);
|
||||
}
|
||||
sec = dnskeyset_verify_rrset(env, ve, &pk, dnskey, sigalg, why_bogus, NULL,
|
||||
LDNS_SECTION_ANSWER, NULL, &verified);
|
||||
LDNS_SECTION_ANSWER, NULL, &verified, reasonbuf, reasonlen);
|
||||
if(sec == sec_status_secure) {
|
||||
return 1;
|
||||
}
|
||||
@@ -7851,7 +7852,8 @@ static int nsec3_of_param_has_type(struct auth_rrset* nsec3, int algo,
|
||||
static int zonemd_check_dnssec_absence(struct auth_zone* z,
|
||||
struct module_env* env, struct module_stack* mods,
|
||||
struct ub_packed_rrset_key* dnskey, struct auth_data* apex,
|
||||
char** reason, char** why_bogus, uint8_t* sigalg)
|
||||
char** reason, char** why_bogus, uint8_t* sigalg, char* reasonbuf,
|
||||
size_t reasonlen)
|
||||
{
|
||||
struct auth_rrset* nsec = NULL;
|
||||
if(!apex) {
|
||||
@@ -7863,7 +7865,7 @@ static int zonemd_check_dnssec_absence(struct auth_zone* z,
|
||||
struct ub_packed_rrset_key pk;
|
||||
/* dnssec verify the NSEC */
|
||||
if(!zonemd_dnssec_verify_rrset(z, env, mods, dnskey, apex,
|
||||
nsec, why_bogus, sigalg)) {
|
||||
nsec, why_bogus, sigalg, reasonbuf, reasonlen)) {
|
||||
*reason = "DNSSEC verify failed for NSEC RRset";
|
||||
return 0;
|
||||
}
|
||||
@@ -7906,7 +7908,7 @@ static int zonemd_check_dnssec_absence(struct auth_zone* z,
|
||||
}
|
||||
/* dnssec verify the NSEC3 */
|
||||
if(!zonemd_dnssec_verify_rrset(z, env, mods, dnskey, match,
|
||||
nsec3, why_bogus, sigalg)) {
|
||||
nsec3, why_bogus, sigalg, reasonbuf, reasonlen)) {
|
||||
*reason = "DNSSEC verify failed for NSEC3 RRset";
|
||||
return 0;
|
||||
}
|
||||
@@ -7928,7 +7930,7 @@ static int zonemd_check_dnssec_soazonemd(struct auth_zone* z,
|
||||
struct module_env* env, struct module_stack* mods,
|
||||
struct ub_packed_rrset_key* dnskey, struct auth_data* apex,
|
||||
struct auth_rrset* zonemd_rrset, char** reason, char** why_bogus,
|
||||
uint8_t* sigalg)
|
||||
uint8_t* sigalg, char* reasonbuf, size_t reasonlen)
|
||||
{
|
||||
struct auth_rrset* soa;
|
||||
if(!apex) {
|
||||
@@ -7941,12 +7943,12 @@ static int zonemd_check_dnssec_soazonemd(struct auth_zone* z,
|
||||
return 0;
|
||||
}
|
||||
if(!zonemd_dnssec_verify_rrset(z, env, mods, dnskey, apex, soa,
|
||||
why_bogus, sigalg)) {
|
||||
why_bogus, sigalg, reasonbuf, reasonlen)) {
|
||||
*reason = "DNSSEC verify failed for SOA RRset";
|
||||
return 0;
|
||||
}
|
||||
if(!zonemd_dnssec_verify_rrset(z, env, mods, dnskey, apex,
|
||||
zonemd_rrset, why_bogus, sigalg)) {
|
||||
zonemd_rrset, why_bogus, sigalg, reasonbuf, reasonlen)) {
|
||||
*reason = "DNSSEC verify failed for ZONEMD RRset";
|
||||
return 0;
|
||||
}
|
||||
@@ -8014,6 +8016,7 @@ auth_zone_verify_zonemd_with_key(struct auth_zone* z, struct module_env* env,
|
||||
struct module_stack* mods, struct ub_packed_rrset_key* dnskey,
|
||||
int is_insecure, char** result, uint8_t* sigalg)
|
||||
{
|
||||
char reasonbuf[256];
|
||||
char* reason = NULL, *why_bogus = NULL;
|
||||
struct auth_data* apex = NULL;
|
||||
struct auth_rrset* zonemd_rrset = NULL;
|
||||
@@ -8042,7 +8045,8 @@ auth_zone_verify_zonemd_with_key(struct auth_zone* z, struct module_env* env,
|
||||
} else if(!zonemd_rrset && dnskey && !is_insecure) {
|
||||
/* fetch, DNSSEC verify, and check NSEC/NSEC3 */
|
||||
if(!zonemd_check_dnssec_absence(z, env, mods, dnskey, apex,
|
||||
&reason, &why_bogus, sigalg)) {
|
||||
&reason, &why_bogus, sigalg, reasonbuf,
|
||||
sizeof(reasonbuf))) {
|
||||
auth_zone_zonemd_fail(z, env, reason, why_bogus, result);
|
||||
return;
|
||||
}
|
||||
@@ -8050,7 +8054,8 @@ auth_zone_verify_zonemd_with_key(struct auth_zone* z, struct module_env* env,
|
||||
} else if(zonemd_rrset && dnskey && !is_insecure) {
|
||||
/* check DNSSEC verify of SOA and ZONEMD */
|
||||
if(!zonemd_check_dnssec_soazonemd(z, env, mods, dnskey, apex,
|
||||
zonemd_rrset, &reason, &why_bogus, sigalg)) {
|
||||
zonemd_rrset, &reason, &why_bogus, sigalg, reasonbuf,
|
||||
sizeof(reasonbuf))) {
|
||||
auth_zone_zonemd_fail(z, env, reason, why_bogus, result);
|
||||
return;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Vendored
+13
-5
@@ -96,7 +96,8 @@ store_rrsets(struct module_env* env, struct reply_info* rep, time_t now,
|
||||
struct ub_packed_rrset_key* ck;
|
||||
lock_rw_rdlock(&rep->ref[i].key->entry.lock);
|
||||
/* if deleted rrset, do not copy it */
|
||||
if(rep->ref[i].key->id == 0)
|
||||
if(rep->ref[i].key->id == 0 ||
|
||||
rep->ref[i].id != rep->ref[i].key->id)
|
||||
ck = NULL;
|
||||
else ck = packed_rrset_copy_region(
|
||||
rep->ref[i].key, region, now);
|
||||
@@ -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;
|
||||
|
||||
Vendored
+2
@@ -357,6 +357,7 @@ infra_create(struct config_file* cfg)
|
||||
return NULL;
|
||||
}
|
||||
infra_ip_ratelimit = cfg->ip_ratelimit;
|
||||
infra_ip_ratelimit_cookie = cfg->ip_ratelimit_cookie;
|
||||
infra->client_ip_rates = slabhash_create(cfg->ip_ratelimit_slabs,
|
||||
INFRA_HOST_STARTSIZE, cfg->ip_ratelimit_size, &ip_rate_sizefunc,
|
||||
&ip_rate_compfunc, &ip_rate_delkeyfunc, &ip_rate_deldatafunc, NULL);
|
||||
@@ -408,6 +409,7 @@ infra_adjust(struct infra_cache* infra, struct config_file* cfg)
|
||||
infra->infra_keep_probing = cfg->infra_keep_probing;
|
||||
infra_dp_ratelimit = cfg->ratelimit;
|
||||
infra_ip_ratelimit = cfg->ip_ratelimit;
|
||||
infra_ip_ratelimit_cookie = cfg->ip_ratelimit_cookie;
|
||||
maxmem = cfg->infra_cache_numhosts * (sizeof(struct infra_key)+
|
||||
sizeof(struct infra_data)+INFRA_BYTES_NAME);
|
||||
/* divide cachesize by slabs and multiply by slabs, because if the
|
||||
|
||||
Vendored
+1
-1
@@ -234,7 +234,7 @@ struct infra_cache* infra_adjust(struct infra_cache* infra,
|
||||
struct config_file* cfg);
|
||||
|
||||
/**
|
||||
* Plain find infra data function (used by the the other functions)
|
||||
* Plain find infra data function (used by the other functions)
|
||||
* @param infra: infrastructure cache.
|
||||
* @param addr: host address.
|
||||
* @param addrlen: length of addr.
|
||||
|
||||
+32
-9
@@ -413,6 +413,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
int timeout = mesh->env->cfg->serve_expired?
|
||||
mesh->env->cfg->serve_expired_client_timeout:0;
|
||||
struct sldns_buffer* r_buffer = rep->c->buffer;
|
||||
uint16_t mesh_flags = qflags&(BIT_RD|BIT_CD);
|
||||
if(rep->c->tcp_req_info) {
|
||||
r_buffer = rep->c->tcp_req_info->spool_buffer;
|
||||
}
|
||||
@@ -425,7 +426,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
return;
|
||||
}
|
||||
if(!unique)
|
||||
s = mesh_area_find(mesh, cinfo, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0);
|
||||
s = mesh_area_find(mesh, cinfo, qinfo, mesh_flags, 0, 0);
|
||||
/* does this create a new reply state? */
|
||||
if(!s || s->list_select == mesh_no_list) {
|
||||
if(!mesh_make_new_space(mesh, rep->c->buffer)) {
|
||||
@@ -453,7 +454,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
struct rbnode_type* n;
|
||||
#endif
|
||||
s = mesh_state_create(mesh->env, qinfo, cinfo,
|
||||
qflags&(BIT_RD|BIT_CD), 0, 0);
|
||||
mesh_flags, 0, 0);
|
||||
if(!s) {
|
||||
log_err("mesh_state_create: out of memory; SERVFAIL");
|
||||
if(!inplace_cb_reply_servfail_call(mesh->env, qinfo, NULL, NULL,
|
||||
@@ -565,6 +566,8 @@ servfail_mem:
|
||||
edns->opt_list_inplace_cb_out = NULL;
|
||||
error_encode(r_buffer, LDNS_RCODE_SERVFAIL,
|
||||
qinfo, qid, qflags, edns);
|
||||
if(rep->c->use_h2)
|
||||
http2_stream_remove_mesh_state(rep->c->h2_stream);
|
||||
comm_point_send_reply(rep);
|
||||
if(added)
|
||||
mesh_state_delete(&s->s);
|
||||
@@ -583,8 +586,9 @@ mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
int was_detached = 0;
|
||||
int was_noreply = 0;
|
||||
int added = 0;
|
||||
uint16_t mesh_flags = qflags&(BIT_RD|BIT_CD);
|
||||
if(!unique)
|
||||
s = mesh_area_find(mesh, NULL, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0);
|
||||
s = mesh_area_find(mesh, NULL, qinfo, mesh_flags, 0, 0);
|
||||
|
||||
/* there are no limits on the number of callbacks */
|
||||
|
||||
@@ -594,7 +598,7 @@ mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo,
|
||||
struct rbnode_type* n;
|
||||
#endif
|
||||
s = mesh_state_create(mesh->env, qinfo, NULL,
|
||||
qflags&(BIT_RD|BIT_CD), 0, 0);
|
||||
mesh_flags, 0, 0);
|
||||
if(!s) {
|
||||
return 0;
|
||||
}
|
||||
@@ -673,8 +677,12 @@ static void mesh_schedule_prefetch(struct mesh_area* mesh,
|
||||
struct query_info* qinfo, uint16_t qflags, time_t leeway, int run,
|
||||
int rpz_passthru)
|
||||
{
|
||||
/* Explicitly set the BIT_RD regardless of the client's flags. This is
|
||||
* for a prefetch query (no client attached) but it needs to be treated
|
||||
* as a recursion query. */
|
||||
uint16_t mesh_flags = BIT_RD|(qflags&BIT_CD);
|
||||
struct mesh_state* s = mesh_area_find(mesh, NULL, qinfo,
|
||||
qflags&(BIT_RD|BIT_CD), 0, 0);
|
||||
mesh_flags, 0, 0);
|
||||
#ifdef UNBOUND_DEBUG
|
||||
struct rbnode_type* n;
|
||||
#endif
|
||||
@@ -694,8 +702,7 @@ static void mesh_schedule_prefetch(struct mesh_area* mesh,
|
||||
return;
|
||||
}
|
||||
|
||||
s = mesh_state_create(mesh->env, qinfo, NULL,
|
||||
qflags&(BIT_RD|BIT_CD), 0, 0);
|
||||
s = mesh_state_create(mesh->env, qinfo, NULL, mesh_flags, 0, 0);
|
||||
if(!s) {
|
||||
log_err("prefetch mesh_state_create: out of memory");
|
||||
return;
|
||||
@@ -756,14 +763,17 @@ static void mesh_schedule_prefetch_subnet(struct mesh_area* mesh,
|
||||
#ifdef UNBOUND_DEBUG
|
||||
struct rbnode_type* n;
|
||||
#endif
|
||||
/* Explicitly set the BIT_RD regardless of the client's flags. This is
|
||||
* for a prefetch query (no client attached) but it needs to be treated
|
||||
* as a recursion query. */
|
||||
uint16_t mesh_flags = BIT_RD|(qflags&BIT_CD);
|
||||
if(!mesh_make_new_space(mesh, NULL)) {
|
||||
verbose(VERB_ALGO, "Too many queries. dropped prefetch.");
|
||||
mesh->stats_dropped ++;
|
||||
return;
|
||||
}
|
||||
|
||||
s = mesh_state_create(mesh->env, qinfo, NULL,
|
||||
qflags&(BIT_RD|BIT_CD), 0, 0);
|
||||
s = mesh_state_create(mesh->env, qinfo, NULL, mesh_flags, 0, 0);
|
||||
if(!s) {
|
||||
log_err("prefetch_subnet mesh_state_create: out of memory");
|
||||
return;
|
||||
@@ -966,6 +976,8 @@ mesh_state_cleanup(struct mesh_state* mstate)
|
||||
for(; rep; rep=rep->next) {
|
||||
infra_wait_limit_dec(mesh->env->infra_cache,
|
||||
&rep->query_reply, mesh->env->cfg);
|
||||
if(rep->query_reply.c->use_h2)
|
||||
http2_stream_remove_mesh_state(rep->h2_stream);
|
||||
comm_point_drop_reply(&rep->query_reply);
|
||||
log_assert(mesh->num_reply_addrs > 0);
|
||||
mesh->num_reply_addrs--;
|
||||
@@ -1522,6 +1534,8 @@ void mesh_query_done(struct mesh_state* mstate)
|
||||
infra_wait_limit_dec(mstate->s.env->infra_cache,
|
||||
&r->query_reply, mstate->s.env->cfg);
|
||||
mstate->reply_list = NULL;
|
||||
if(r->query_reply.c->use_h2)
|
||||
http2_stream_remove_mesh_state(r->h2_stream);
|
||||
comm_point_drop_reply(&r->query_reply);
|
||||
mstate->reply_list = reply_list;
|
||||
mstate->s.env->mesh->stats_dropped++;
|
||||
@@ -1554,6 +1568,9 @@ void mesh_query_done(struct mesh_state* mstate)
|
||||
infra_wait_limit_dec(mstate->s.env->infra_cache,
|
||||
&r->query_reply, mstate->s.env->cfg);
|
||||
mstate->reply_list = NULL;
|
||||
if(r->query_reply.c->use_h2) {
|
||||
http2_stream_remove_mesh_state(r->h2_stream);
|
||||
}
|
||||
comm_point_drop_reply(&r->query_reply);
|
||||
mstate->reply_list = reply_list;
|
||||
} else {
|
||||
@@ -1568,6 +1585,8 @@ void mesh_query_done(struct mesh_state* mstate)
|
||||
tcp_req_info_remove_mesh_state(r->query_reply.c->tcp_req_info, mstate);
|
||||
r_buffer = NULL;
|
||||
}
|
||||
/* mesh_send_reply removed mesh state from
|
||||
* http2_stream. */
|
||||
prev = r;
|
||||
prev_buffer = r_buffer;
|
||||
}
|
||||
@@ -1720,6 +1739,7 @@ int mesh_state_add_reply(struct mesh_state* s, struct edns_data* edns,
|
||||
return 0;
|
||||
if(rep->c->use_h2)
|
||||
r->h2_stream = rep->c->h2_stream;
|
||||
else r->h2_stream = NULL;
|
||||
|
||||
/* Data related to local alias stored in 'qinfo' (if any) is ephemeral
|
||||
* and can be different for different original queries (even if the
|
||||
@@ -2243,6 +2263,8 @@ mesh_serve_expired_callback(void* arg)
|
||||
infra_wait_limit_dec(mstate->s.env->infra_cache,
|
||||
&r->query_reply, mstate->s.env->cfg);
|
||||
mstate->reply_list = NULL;
|
||||
if(r->query_reply.c->use_h2)
|
||||
http2_stream_remove_mesh_state(r->h2_stream);
|
||||
comm_point_drop_reply(&r->query_reply);
|
||||
mstate->reply_list = reply_list;
|
||||
mstate->s.env->mesh->stats_dropped++;
|
||||
@@ -2276,6 +2298,7 @@ mesh_serve_expired_callback(void* arg)
|
||||
r, r_buffer, prev, prev_buffer);
|
||||
if(r->query_reply.c->tcp_req_info)
|
||||
tcp_req_info_remove_mesh_state(r->query_reply.c->tcp_req_info, mstate);
|
||||
/* mesh_send_reply removed mesh state from http2_stream. */
|
||||
infra_wait_limit_dec(mstate->s.env->infra_cache,
|
||||
&r->query_reply, mstate->s.env->cfg);
|
||||
prev = r;
|
||||
|
||||
+69
-9
@@ -95,6 +95,16 @@ modstack_init(struct module_stack* stack)
|
||||
stack->mod = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
modstack_free(struct module_stack* stack)
|
||||
{
|
||||
if(!stack)
|
||||
return;
|
||||
stack->num = 0;
|
||||
free(stack->mod);
|
||||
stack->mod = NULL;
|
||||
}
|
||||
|
||||
int
|
||||
modstack_config(struct module_stack* stack, const char* module_conf)
|
||||
{
|
||||
@@ -222,18 +232,59 @@ module_func_block* module_factory(const char** str)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
modstack_setup(struct module_stack* stack, const char* module_conf,
|
||||
int
|
||||
modstack_call_startup(struct module_stack* stack, const char* module_conf,
|
||||
struct module_env* env)
|
||||
{
|
||||
int i;
|
||||
if(stack->num != 0)
|
||||
modstack_desetup(stack, env);
|
||||
fatal_exit("unexpected already initialised modules");
|
||||
/* fixed setup of the modules */
|
||||
if(!modstack_config(stack, module_conf)) {
|
||||
return 0;
|
||||
}
|
||||
for(i=0; i<stack->num; i++) {
|
||||
if(stack->mod[i]->startup == NULL)
|
||||
continue;
|
||||
verbose(VERB_OPS, "startup module %d: %s",
|
||||
i, stack->mod[i]->name);
|
||||
fptr_ok(fptr_whitelist_mod_startup(stack->mod[i]->startup));
|
||||
if(!(*stack->mod[i]->startup)(env, i)) {
|
||||
log_err("module startup for module %s failed",
|
||||
stack->mod[i]->name);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
modstack_call_init(struct module_stack* stack, const char* module_conf,
|
||||
struct module_env* env)
|
||||
{
|
||||
int i, changed = 0;
|
||||
env->need_to_validate = 0; /* set by module init below */
|
||||
for(i=0; i<stack->num; i++) {
|
||||
while(*module_conf && isspace(*module_conf))
|
||||
module_conf++;
|
||||
if(strncmp(stack->mod[i]->name, module_conf,
|
||||
strlen(stack->mod[i]->name))) {
|
||||
if(stack->mod[i]->startup || stack->mod[i]->destartup) {
|
||||
log_err("changed module ordering during reload not supported, for module that needs startup");
|
||||
return 0;
|
||||
} else {
|
||||
changed = 1;
|
||||
}
|
||||
}
|
||||
module_conf += strlen(stack->mod[i]->name);
|
||||
}
|
||||
if(changed) {
|
||||
modstack_free(stack);
|
||||
if(!modstack_config(stack, module_conf)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
for(i=0; i<stack->num; i++) {
|
||||
verbose(VERB_OPS, "init module %d: %s",
|
||||
i, stack->mod[i]->name);
|
||||
@@ -247,20 +298,29 @@ modstack_setup(struct module_stack* stack, const char* module_conf,
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
modstack_desetup(struct module_stack* stack, struct module_env* env)
|
||||
void
|
||||
modstack_call_deinit(struct module_stack* stack, struct module_env* env)
|
||||
{
|
||||
int i;
|
||||
for(i=0; i<stack->num; i++) {
|
||||
fptr_ok(fptr_whitelist_mod_deinit(stack->mod[i]->deinit));
|
||||
(*stack->mod[i]->deinit)(env, i);
|
||||
}
|
||||
stack->num = 0;
|
||||
free(stack->mod);
|
||||
stack->mod = NULL;
|
||||
}
|
||||
|
||||
int
|
||||
void
|
||||
modstack_call_destartup(struct module_stack* stack, struct module_env* env)
|
||||
{
|
||||
int i;
|
||||
for(i=0; i<stack->num; i++) {
|
||||
if(stack->mod[i]->destartup == NULL)
|
||||
continue;
|
||||
fptr_ok(fptr_whitelist_mod_destartup(stack->mod[i]->destartup));
|
||||
(*stack->mod[i]->destartup)(env, i);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
modstack_find(struct module_stack* stack, const char* name)
|
||||
{
|
||||
int i;
|
||||
|
||||
+31
-7
@@ -60,6 +60,23 @@ struct module_stack {
|
||||
*/
|
||||
void modstack_init(struct module_stack* stack);
|
||||
|
||||
/**
|
||||
* Free the stack of modules
|
||||
* @param stack: stack that frees up memory.
|
||||
*/
|
||||
void modstack_free(struct module_stack* stack);
|
||||
|
||||
/**
|
||||
* Initialises modules and assignes ids. Calls module_startup().
|
||||
* @param stack: Expected empty, filled according to module_conf
|
||||
* @param module_conf: string what modules to initialize
|
||||
* @param env: module environment which is inited by the modules.
|
||||
* environment should have a superalloc, cfg,
|
||||
* @return on false a module init failed.
|
||||
*/
|
||||
int modstack_call_startup(struct module_stack* stack, const char* module_conf,
|
||||
struct module_env* env);
|
||||
|
||||
/**
|
||||
* Read config file module settings and set up the modfunc block
|
||||
* @param stack: the stack of modules (empty before call).
|
||||
@@ -83,24 +100,31 @@ struct module_func_block* module_factory(const char** str);
|
||||
const char** module_list_avail(void);
|
||||
|
||||
/**
|
||||
* Setup modules. Assigns ids and calls module_init.
|
||||
* @param stack: if not empty beforehand, it will be desetup()ed.
|
||||
* It is then modstack_configged().
|
||||
* @param module_conf: string what modules to insert.
|
||||
* Init modules. Calls module_init().
|
||||
* @param stack: It is modstack_setupped().
|
||||
* @param module_conf: module ordering to check against the ordering in stack.
|
||||
* fails on changed ordering.
|
||||
* @param env: module environment which is inited by the modules.
|
||||
* environment should have a superalloc, cfg,
|
||||
* env.need_to_validate is set by the modules.
|
||||
* @return on false a module init failed.
|
||||
*/
|
||||
int modstack_setup(struct module_stack* stack, const char* module_conf,
|
||||
int modstack_call_init(struct module_stack* stack, const char* module_conf,
|
||||
struct module_env* env);
|
||||
|
||||
/**
|
||||
* Desetup the modules, deinit, delete.
|
||||
* Deinit the modules.
|
||||
* @param stack: made empty.
|
||||
* @param env: module env for module deinit() calls.
|
||||
*/
|
||||
void modstack_desetup(struct module_stack* stack, struct module_env* env);
|
||||
void modstack_call_deinit(struct module_stack* stack, struct module_env* env);
|
||||
|
||||
/**
|
||||
* Destartup the modules, close, delete.
|
||||
* @param stack: made empty.
|
||||
* @param env: module env for module destartup() calls.
|
||||
*/
|
||||
void modstack_call_destartup(struct module_stack* stack, struct module_env* env);
|
||||
|
||||
/**
|
||||
* Find index of module by name.
|
||||
|
||||
+3
-3
@@ -106,7 +106,7 @@ ssize_t sldns_bget_token(struct sldns_buffer *b, char *token, const char *delim,
|
||||
* \param[in] k_del keyword delimiter
|
||||
* \param[out] data the data found
|
||||
* \param[in] d_del the data delimiter
|
||||
* \param[in] data_limit maximum size the the data buffer
|
||||
* \param[in] data_limit maximum size the data buffer
|
||||
* \return the number of character read
|
||||
*/
|
||||
ssize_t sldns_fget_keyword_data(FILE *f, const char *keyword, const char *k_del, char *data, const char *d_del, size_t data_limit);
|
||||
@@ -119,7 +119,7 @@ ssize_t sldns_fget_keyword_data(FILE *f, const char *keyword, const char *k_del,
|
||||
* \param[in] k_del keyword delimiter
|
||||
* \param[out] data the data found
|
||||
* \param[in] d_del the data delimiter
|
||||
* \param[in] data_limit maximum size the the data buffer
|
||||
* \param[in] data_limit maximum size the data buffer
|
||||
* \param[in] line_nr pointer to an integer containing the current line number (for
|
||||
debugging purposes)
|
||||
* \return the number of character read
|
||||
@@ -134,7 +134,7 @@ ssize_t sldns_fget_keyword_data_l(FILE *f, const char *keyword, const char *k_de
|
||||
* \param[in] k_del keyword delimiter
|
||||
* \param[out] data the data found
|
||||
* \param[in] d_del the data delimiter
|
||||
* \param[in] data_limit maximum size the the data buffer
|
||||
* \param[in] data_limit maximum size the data buffer
|
||||
* \return the number of character read
|
||||
*/
|
||||
ssize_t sldns_bget_keyword_data(struct sldns_buffer *b, const char *keyword, const char *k_del, char *data, const char *d_del, size_t data_limit);
|
||||
|
||||
+6
-3
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
@@ -2,17 +2,19 @@
|
||||
# Copyright 2015, Sami Kerola, CloudFlare.
|
||||
# BSD licensed.
|
||||
AC_ARG_ENABLE([systemd],
|
||||
[AS_HELP_STRING([--enable-systemd], [compile with systemd support])],
|
||||
[AS_HELP_STRING([--enable-systemd], [compile with systemd support (requires libsystemd, pkg-config)])],
|
||||
[], [enable_systemd=no])
|
||||
have_systemd=no
|
||||
AS_IF([test "x$enable_systemd" != xno], [
|
||||
ifdef([PKG_CHECK_MODULES], [
|
||||
if test -n "$PKG_CONFIG"; then
|
||||
dnl systemd v209 or newer
|
||||
PKG_CHECK_MODULES([SYSTEMD], [libsystemd], [have_systemd=yes], [have_systemd=no])
|
||||
have_systemd=no
|
||||
PKG_CHECK_MODULES([SYSTEMD], [libsystemd], [have_systemd=yes], [])
|
||||
dnl old systemd library
|
||||
AS_IF([test "x$have_systemd" != "xyes"], [
|
||||
have_systemd_daemon=no
|
||||
PKG_CHECK_MODULES([SYSTEMD_DAEMON], [libsystemd-daemon],
|
||||
[have_systemd_daemon=yes], [have_systemd_daemon=no])
|
||||
[have_systemd_daemon=yes], [])
|
||||
AS_IF([test "x$have_systemd_daemon" = "xyes"],
|
||||
[have_systemd=yes])
|
||||
])
|
||||
@@ -24,8 +26,8 @@ AS_IF([test "x$enable_systemd" != xno], [
|
||||
LIBS="$LIBS $SYSTEMD_LIBS"
|
||||
]
|
||||
)
|
||||
], [
|
||||
else
|
||||
AC_MSG_ERROR([systemd enabled but need pkg-config to configure for it])
|
||||
])
|
||||
fi
|
||||
])
|
||||
AM_CONDITIONAL([USE_SYSTEMD], [test "x$have_systemd" = xyes])
|
||||
|
||||
@@ -1655,6 +1655,12 @@ void comm_timer_set(struct comm_timer* timer, struct timeval* tv)
|
||||
timeval_add(&t->tv, &t->runtime->now_tv);
|
||||
}
|
||||
|
||||
int comm_timer_is_set(struct comm_timer* timer)
|
||||
{
|
||||
struct fake_timer* t = (struct fake_timer*)timer;
|
||||
return t->enabled;
|
||||
}
|
||||
|
||||
void comm_timer_delete(struct comm_timer* timer)
|
||||
{
|
||||
struct fake_timer* t = (struct fake_timer*)timer;
|
||||
@@ -1978,4 +1984,8 @@ void http2_stream_add_meshstate(struct http2_stream* ATTR_UNUSED(h2_stream),
|
||||
{
|
||||
}
|
||||
|
||||
void http2_stream_remove_mesh_state(struct http2_stream* ATTR_UNUSED(h2_stream))
|
||||
{
|
||||
}
|
||||
|
||||
/*********** End of Dummy routines ***********/
|
||||
|
||||
@@ -127,6 +127,7 @@ dir=$name.$$
|
||||
result=result.$name
|
||||
done=.done-$name
|
||||
skip=.skip-$name
|
||||
asan_text="SUMMARY: AddressSanitizer"
|
||||
success="no"
|
||||
if test -x "`which bash`"; then
|
||||
shell="bash"
|
||||
@@ -200,6 +201,16 @@ if test -f $name.post -a ! -f ../$skip; then
|
||||
echo "Warning: $name.post did not exit successfully"
|
||||
fi
|
||||
fi
|
||||
# Check if there were any AddressSanitizer errors
|
||||
# if compiled with -fsanitize=address
|
||||
if grep "$asan_text" $result >/dev/null 2>&1; then
|
||||
if test -f ../$done; then
|
||||
rm ../$done
|
||||
fi
|
||||
echo "$name: FAILED (AddressSanitizer)" >> $result
|
||||
echo "$name: FAILED (AddressSanitizer)"
|
||||
success="no"
|
||||
fi
|
||||
echo "DateRunEnd: "`date "+%s" 2>/dev/null` >> $result
|
||||
|
||||
mv $result ..
|
||||
|
||||
+1
-1
@@ -256,7 +256,7 @@ setup_ctx(char* key, char* cert)
|
||||
#if HAVE_DECL_SSL_CTX_SET_ECDH_AUTO
|
||||
if (!SSL_CTX_set_ecdh_auto(ctx,1))
|
||||
if(verb>=1) printf("failed to set_ecdh_auto, not enabling ECDHE\n");
|
||||
#elif defined(USE_ECDSA)
|
||||
#elif defined(USE_ECDSA) && defined(HAVE_SSL_CTX_SET_TMP_ECDH)
|
||||
if(1) {
|
||||
EC_KEY *ecdh = EC_KEY_new_by_curve_name (NID_X9_62_prime256v1);
|
||||
if (!ecdh) {
|
||||
|
||||
@@ -45,7 +45,6 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include "sldns/str2wire.h"
|
||||
#include "sldns/wire2str.h"
|
||||
|
||||
|
||||
@@ -471,7 +471,11 @@ send_em(const char* svr, const char* pp2_client, int udp, int usessl,
|
||||
}
|
||||
}
|
||||
if(1) {
|
||||
#ifdef HAVE_SSL_GET1_PEER_CERTIFICATE
|
||||
X509* x = SSL_get1_peer_certificate(ssl);
|
||||
#else
|
||||
X509* x = SSL_get_peer_certificate(ssl);
|
||||
#endif
|
||||
if(!x) printf("SSL: no peer certificate\n");
|
||||
else {
|
||||
X509_print_fp(stdout, x);
|
||||
|
||||
@@ -178,6 +178,7 @@ verifytest_rrset(struct module_env* env, struct val_env* ve,
|
||||
struct query_info* qinfo)
|
||||
{
|
||||
enum sec_status sec;
|
||||
char reasonbuf[256];
|
||||
char* reason = NULL;
|
||||
uint8_t sigalg[ALGO_NEEDS_MAX+1];
|
||||
int verified = 0;
|
||||
@@ -188,8 +189,9 @@ verifytest_rrset(struct module_env* env, struct val_env* ve,
|
||||
}
|
||||
setup_sigalg(dnskey, sigalg); /* check all algorithms in the dnskey */
|
||||
/* ok to give null as qstate here, won't be used for answer section. */
|
||||
sec = dnskeyset_verify_rrset(env, ve, rrset, dnskey, sigalg, &reason, NULL,
|
||||
LDNS_SECTION_ANSWER, NULL, &verified);
|
||||
sec = dnskeyset_verify_rrset(env, ve, rrset, dnskey, sigalg, &reason,
|
||||
NULL, LDNS_SECTION_ANSWER, NULL, &verified, reasonbuf,
|
||||
sizeof(reasonbuf));
|
||||
if(vsig) {
|
||||
printf("verify outcome is: %s %s\n", sec_status_to_string(sec),
|
||||
reason?reason:"");
|
||||
|
||||
@@ -256,7 +256,6 @@ static void zonemd_verify_test(char* zname, char* zfile, char* tastr,
|
||||
struct auth_zone* z;
|
||||
|
||||
/* setup test harness */
|
||||
memset(&mods, 0, sizeof(mods));
|
||||
memset(&env, 0, sizeof(env));
|
||||
env.scratch = regional_create();
|
||||
if(!env.scratch)
|
||||
@@ -288,8 +287,10 @@ static void zonemd_verify_test(char* zname, char* zfile, char* tastr,
|
||||
if(!env.auth_zones)
|
||||
fatal_exit("out of memory");
|
||||
modstack_init(&mods);
|
||||
if(!modstack_setup(&mods, env.cfg->module_conf, &env))
|
||||
fatal_exit("could not modstack_setup");
|
||||
if(!modstack_call_startup(&mods, env.cfg->module_conf, &env))
|
||||
fatal_exit("could not modstack_startup");
|
||||
if(!modstack_call_init(&mods, env.cfg->module_conf, &env))
|
||||
fatal_exit("could not modstack_call_init");
|
||||
env.mesh = mesh_create(&mods, &env);
|
||||
if(!env.mesh)
|
||||
fatal_exit("out of memory");
|
||||
@@ -327,7 +328,9 @@ static void zonemd_verify_test(char* zname, char* zfile, char* tastr,
|
||||
|
||||
/* desetup test harness */
|
||||
mesh_delete(env.mesh);
|
||||
modstack_desetup(&mods, &env);
|
||||
modstack_call_deinit(&mods, &env);
|
||||
modstack_call_destartup(&mods, &env);
|
||||
modstack_free(&mods);
|
||||
auth_zones_delete(env.auth_zones);
|
||||
anchors_delete(env.anchors);
|
||||
config_delete(env.cfg);
|
||||
|
||||
+55
-43
@@ -7,57 +7,69 @@
|
||||
. ../common.sh
|
||||
PRE="../.."
|
||||
get_make
|
||||
(cd $PRE ; $MAKE unittest; $MAKE lock-verify)
|
||||
(cd $PRE ; $MAKE unittest; $MAKE lock-verify; $MAKE unbound-dnstap-socket)
|
||||
|
||||
if test -f $PRE/unbound_do_valgrind_in_test; then
|
||||
do_valgrind=yes
|
||||
DO_VALGRIND=yes
|
||||
else
|
||||
do_valgrind=no
|
||||
DO_VALGRIND=no
|
||||
fi
|
||||
VALGRIND_FLAGS="--leak-check=full --show-leak-kinds=all"
|
||||
|
||||
if test $do_valgrind = "yes"; then
|
||||
echo "valgrind yes"
|
||||
echo
|
||||
tmpout=/tmp/tmpout.$$
|
||||
if (cd $PRE; valgrind $VALGRIND_FLAGS ./unittest >$tmpout 2>&1); then
|
||||
echo "unit test worked."
|
||||
# Run a unit test; it exits on failure
|
||||
# $1: the command to start the unit test
|
||||
run_unittest () {
|
||||
unit_cmd=$1
|
||||
echo "> testing $unit_cmd"
|
||||
if test $DO_VALGRIND = "yes"; then
|
||||
echo "valgrind yes"
|
||||
echo
|
||||
tmpout=/tmp/tmpout.$$
|
||||
if (cd $PRE; valgrind $VALGRIND_FLAGS ./$unit_cmd >$tmpout 2>&1); then
|
||||
echo "unit test worked."
|
||||
else
|
||||
echo "unit test failed."
|
||||
exit 1
|
||||
fi
|
||||
if grep "All heap blocks were freed -- no leaks are possible" $tmpout; then
|
||||
: # clean
|
||||
else
|
||||
cat $tmpout
|
||||
echo "Memory leaked in unit test"
|
||||
grep "in use at exit" $tmpout
|
||||
exit 1
|
||||
fi
|
||||
if grep "ERROR SUMMARY: 0 errors from 0 contexts" $tmpout; then
|
||||
: # clean
|
||||
else
|
||||
cat $tmpout
|
||||
echo "Errors in unit test"
|
||||
grep "ERROR SUMMARY" $tmpout
|
||||
exit 1
|
||||
fi
|
||||
rm -f $tmpout
|
||||
else
|
||||
echo "unit test failed."
|
||||
exit 1
|
||||
# without valgrind
|
||||
if (cd $PRE; ./$unit_cmd); then
|
||||
echo "unit test worked."
|
||||
else
|
||||
echo "unit test failed."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
if grep "All heap blocks were freed -- no leaks are possible" $tmpout; then
|
||||
: # clean
|
||||
else
|
||||
cat $tmpout
|
||||
echo "Memory leaked in unittest"
|
||||
grep "in use at exit" $tmpout
|
||||
exit 1
|
||||
fi
|
||||
if grep "ERROR SUMMARY: 0 errors from 0 contexts" $tmpout; then
|
||||
: # clean
|
||||
else
|
||||
cat $tmpout
|
||||
echo "Errors in unittest"
|
||||
grep "ERROR SUMMARY" $tmpout
|
||||
exit 1
|
||||
fi
|
||||
rm -f $tmpout
|
||||
else
|
||||
# without valgrind
|
||||
if (cd $PRE; ./unittest); then
|
||||
echo "unit test worked."
|
||||
else
|
||||
echo "unit test failed."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
if test -f $PRE/ublocktrace.0; then
|
||||
if (cd $PRE; ./lock-verify ublocktrace.*); then
|
||||
echo "lock-verify test worked."
|
||||
else
|
||||
echo "lock-verify test failed."
|
||||
exit 1
|
||||
if test -f $PRE/ublocktrace.0; then
|
||||
if (cd $PRE; ./lock-verify ublocktrace.*); then
|
||||
echo "lock-verify test worked."
|
||||
else
|
||||
echo "lock-verify test failed."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
run_unittest "unittest"
|
||||
if grep "define UNBOUND_DEBUG" $PRE/config.h >/dev/null; then
|
||||
run_unittest "unbound-dnstap-socket -c"
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
+45
-1
@@ -5,9 +5,10 @@ server:
|
||||
pidfile: "unbound.pid"
|
||||
chroot: ""
|
||||
username: ""
|
||||
module-config: "respip validator iterator" # respip for the RPZ part
|
||||
do-not-query-localhost: no
|
||||
use-caps-for-id: no
|
||||
define-tag: "one two refuse"
|
||||
define-tag: "one two refuse rpz-one rpz-two rpz-nx"
|
||||
|
||||
# Interface configuration for IPv4
|
||||
interface: @IPV4_ADDR@@@PORT_ALLOW@
|
||||
@@ -16,6 +17,9 @@ server:
|
||||
interface: @IPV4_ADDR@@@PORT_TAG_1@
|
||||
interface: @IPV4_ADDR@@@PORT_TAG_2@
|
||||
interface: @IPV4_ADDR@@@PORT_TAG_3@
|
||||
interface: @IPV4_ADDR@@@PORT_RPZ_1@
|
||||
interface: @IPV4_ADDR@@@PORT_RPZ_2@
|
||||
interface: @IPV4_ADDR@@@PORT_RPZ_NX@
|
||||
interface: @IPV4_ADDR@@@PORT_VIEW_INT@
|
||||
interface: @IPV4_ADDR@@@PORT_VIEW_EXT@
|
||||
interface: @IPV4_ADDR@@@PORT_VIEW_INTEXT@
|
||||
@@ -26,6 +30,9 @@ server:
|
||||
interface-action: @IPV4_ADDR@@@PORT_TAG_1@ allow
|
||||
interface-action: @IPV4_ADDR@@@PORT_TAG_2@ allow
|
||||
interface-action: @IPV4_ADDR@@@PORT_TAG_3@ allow
|
||||
interface-action: @IPV4_ADDR@@@PORT_RPZ_1@ allow
|
||||
interface-action: @IPV4_ADDR@@@PORT_RPZ_2@ allow
|
||||
interface-action: @IPV4_ADDR@@@PORT_RPZ_NX@ allow
|
||||
interface-action: @IPV4_ADDR@@@PORT_VIEW_INT@ allow
|
||||
interface-action: @IPV4_ADDR@@@PORT_VIEW_EXT@ allow
|
||||
interface-action: @IPV4_ADDR@@@PORT_VIEW_INTEXT@ allow
|
||||
@@ -33,6 +40,9 @@ server:
|
||||
interface-tag: @IPV4_ADDR@@@PORT_TAG_1@ "one"
|
||||
interface-tag: @IPV4_ADDR@@@PORT_TAG_2@ "two"
|
||||
interface-tag: @IPV4_ADDR@@@PORT_TAG_3@ "refuse"
|
||||
interface-tag: @IPV4_ADDR@@@PORT_RPZ_1@ "rpz-one"
|
||||
interface-tag: @IPV4_ADDR@@@PORT_RPZ_2@ "rpz-two"
|
||||
interface-tag: @IPV4_ADDR@@@PORT_RPZ_NX@ "rpz-nx"
|
||||
interface-tag-action: @IPV4_ADDR@@@PORT_TAG_1@ one redirect
|
||||
interface-tag-data: @IPV4_ADDR@@@PORT_TAG_1@ one "A 1.1.1.1"
|
||||
interface-tag-action: @IPV4_ADDR@@@PORT_TAG_2@ two redirect
|
||||
@@ -50,6 +60,9 @@ server:
|
||||
interface: @IPV6_ADDR@@@PORT_TAG_1@
|
||||
interface: @IPV6_ADDR@@@PORT_TAG_2@
|
||||
interface: @IPV6_ADDR@@@PORT_TAG_3@
|
||||
interface: @IPV6_ADDR@@@PORT_RPZ_1@
|
||||
interface: @IPV6_ADDR@@@PORT_RPZ_2@
|
||||
interface: @IPV6_ADDR@@@PORT_RPZ_NX@
|
||||
interface: @IPV6_ADDR@@@PORT_VIEW_INT@
|
||||
interface: @IPV6_ADDR@@@PORT_VIEW_EXT@
|
||||
interface: @IPV6_ADDR@@@PORT_VIEW_INTEXT@
|
||||
@@ -60,6 +73,9 @@ server:
|
||||
interface-action: @IPV6_ADDR@@@PORT_TAG_1@ allow
|
||||
interface-action: @IPV6_ADDR@@@PORT_TAG_2@ allow
|
||||
interface-action: @IPV6_ADDR@@@PORT_TAG_3@ allow
|
||||
interface-action: @IPV6_ADDR@@@PORT_RPZ_1@ allow
|
||||
interface-action: @IPV6_ADDR@@@PORT_RPZ_2@ allow
|
||||
interface-action: @IPV6_ADDR@@@PORT_RPZ_NX@ allow
|
||||
interface-action: @IPV6_ADDR@@@PORT_VIEW_INT@ allow
|
||||
interface-action: @IPV6_ADDR@@@PORT_VIEW_EXT@ allow
|
||||
interface-action: @IPV6_ADDR@@@PORT_VIEW_INTEXT@ allow
|
||||
@@ -67,6 +83,9 @@ server:
|
||||
interface-tag: @IPV6_ADDR@@@PORT_TAG_1@ "one"
|
||||
interface-tag: @IPV6_ADDR@@@PORT_TAG_2@ "two"
|
||||
interface-tag: @IPV6_ADDR@@@PORT_TAG_3@ "refuse"
|
||||
interface-tag: @IPV6_ADDR@@@PORT_RPZ_1@ "rpz-one"
|
||||
interface-tag: @IPV6_ADDR@@@PORT_RPZ_2@ "rpz-two"
|
||||
interface-tag: @IPV6_ADDR@@@PORT_RPZ_NX@ "rpz-nx"
|
||||
interface-tag-action: @IPV6_ADDR@@@PORT_TAG_1@ one redirect
|
||||
interface-tag-data: @IPV6_ADDR@@@PORT_TAG_1@ one "A 1.1.1.1"
|
||||
interface-tag-action: @IPV6_ADDR@@@PORT_TAG_2@ two redirect
|
||||
@@ -84,6 +103,9 @@ server:
|
||||
interface: @INTERFACE@@@PORT_TAG_1@
|
||||
interface: @INTERFACE@@@PORT_TAG_2@
|
||||
interface: @INTERFACE@@@PORT_TAG_3@
|
||||
interface: @INTERFACE@@@PORT_RPZ_1@
|
||||
interface: @INTERFACE@@@PORT_RPZ_2@
|
||||
interface: @INTERFACE@@@PORT_RPZ_NX@
|
||||
interface: @INTERFACE@@@PORT_VIEW_INT@
|
||||
interface: @INTERFACE@@@PORT_VIEW_EXT@
|
||||
interface: @INTERFACE@@@PORT_VIEW_INTEXT@
|
||||
@@ -94,6 +116,9 @@ server:
|
||||
interface-action: @INTERFACE@@@PORT_TAG_1@ allow
|
||||
interface-action: @INTERFACE@@@PORT_TAG_2@ allow
|
||||
interface-action: @INTERFACE@@@PORT_TAG_3@ allow
|
||||
interface-action: @INTERFACE@@@PORT_RPZ_1@ allow
|
||||
interface-action: @INTERFACE@@@PORT_RPZ_2@ allow
|
||||
interface-action: @INTERFACE@@@PORT_RPZ_NX@ allow
|
||||
interface-action: @INTERFACE@@@PORT_VIEW_INT@ allow
|
||||
interface-action: @INTERFACE@@@PORT_VIEW_EXT@ allow
|
||||
interface-action: @INTERFACE@@@PORT_VIEW_INTEXT@ allow
|
||||
@@ -101,6 +126,9 @@ server:
|
||||
interface-tag: @INTERFACE@@@PORT_TAG_1@ "one"
|
||||
interface-tag: @INTERFACE@@@PORT_TAG_2@ "two"
|
||||
interface-tag: @INTERFACE@@@PORT_TAG_3@ "refuse"
|
||||
interface-tag: @INTERFACE@@@PORT_RPZ_1@ "rpz-one"
|
||||
interface-tag: @INTERFACE@@@PORT_RPZ_2@ "rpz-two"
|
||||
interface-tag: @INTERFACE@@@PORT_RPZ_NX@ "rpz-nx"
|
||||
interface-tag-action: @INTERFACE@@@PORT_TAG_1@ one redirect
|
||||
interface-tag-data: @INTERFACE@@@PORT_TAG_1@ one "A 1.1.1.1"
|
||||
interface-tag-action: @INTERFACE@@@PORT_TAG_2@ two redirect
|
||||
@@ -130,6 +158,22 @@ view:
|
||||
name: "intext"
|
||||
view-first: yes
|
||||
|
||||
# RPZ configuration
|
||||
rpz:
|
||||
name: "rpz-one"
|
||||
zonefile: "rpz-one.zone"
|
||||
tags: "rpz-one"
|
||||
|
||||
rpz:
|
||||
name: "rpz-two"
|
||||
zonefile: "rpz-two.zone"
|
||||
tags: "rpz-two"
|
||||
|
||||
rpz:
|
||||
name: "rpz-nx"
|
||||
zonefile: "rpz-nx.zone"
|
||||
tags: "rpz-nx"
|
||||
|
||||
# Stubs configuration
|
||||
forward-zone:
|
||||
name: "."
|
||||
|
||||
+12
-3
@@ -7,7 +7,7 @@ if test ! -x "`which unshare 2>&1`"; then
|
||||
skip_test "no unshare (from util-linux package) available, skip test"
|
||||
fi
|
||||
|
||||
get_random_port 11
|
||||
get_random_port 14
|
||||
|
||||
PORT_ALLOW=$RND_PORT
|
||||
PORT_DENY=$(($RND_PORT + 1))
|
||||
@@ -18,8 +18,11 @@ PORT_TAG_3=$(($RND_PORT + 5))
|
||||
PORT_VIEW_INT=$(($RND_PORT + 6))
|
||||
PORT_VIEW_EXT=$(($RND_PORT + 7))
|
||||
PORT_VIEW_INTEXT=$(($RND_PORT + 8))
|
||||
FORWARD_PORT=$(($RND_PORT + 9))
|
||||
STUB_PORT=$(($RND_PORT + 10))
|
||||
PORT_RPZ_1=$(($RND_PORT + 9))
|
||||
PORT_RPZ_2=$(($RND_PORT + 10))
|
||||
PORT_RPZ_NX=$(($RND_PORT + 11))
|
||||
FORWARD_PORT=$(($RND_PORT + 12))
|
||||
STUB_PORT=$(($RND_PORT + 13))
|
||||
|
||||
IPV4_ADDR=192.168.1.1
|
||||
IPV6_ADDR=2001:db8::1
|
||||
@@ -41,6 +44,9 @@ sed \
|
||||
-e 's/@PORT_VIEW_INT\@/'$PORT_VIEW_INT'/' \
|
||||
-e 's/@PORT_VIEW_EXT\@/'$PORT_VIEW_EXT'/' \
|
||||
-e 's/@PORT_VIEW_INTEXT\@/'$PORT_VIEW_INTEXT'/' \
|
||||
-e 's/@PORT_RPZ_1\@/'$PORT_RPZ_1'/' \
|
||||
-e 's/@PORT_RPZ_2\@/'$PORT_RPZ_2'/' \
|
||||
-e 's/@PORT_RPZ_NX\@/'$PORT_RPZ_NX'/' \
|
||||
-e 's/@FORWARD_PORT\@/'$FORWARD_PORT'/' \
|
||||
-e 's/@STUB_PORT\@/'$STUB_PORT'/' \
|
||||
-e 's/@IPV4_ADDR\@/'$IPV4_ADDR'/' \
|
||||
@@ -63,6 +69,9 @@ echo "PORT_TAG_3=$PORT_TAG_3" >> .tpkg.var.test
|
||||
echo "PORT_VIEW_INT=$PORT_VIEW_INT" >> .tpkg.var.test
|
||||
echo "PORT_VIEW_EXT=$PORT_VIEW_EXT" >> .tpkg.var.test
|
||||
echo "PORT_VIEW_INTEXT=$PORT_VIEW_INTEXT" >> .tpkg.var.test
|
||||
echo "PORT_RPZ_1=$PORT_RPZ_1" >> .tpkg.var.test
|
||||
echo "PORT_RPZ_2=$PORT_RPZ_2" >> .tpkg.var.test
|
||||
echo "PORT_RPZ_NX=$PORT_RPZ_NX" >> .tpkg.var.test
|
||||
echo "FORWARD_PORT=$FORWARD_PORT" >> .tpkg.var.test
|
||||
echo "STUB_PORT=$STUB_PORT" >> .tpkg.var.test
|
||||
echo "IPV4_ADDR=$IPV4_ADDR" >> .tpkg.var.test
|
||||
|
||||
@@ -78,6 +78,16 @@ expect_refused () {
|
||||
fi
|
||||
}
|
||||
|
||||
expect_nx_answer () {
|
||||
echo "> check answer for NXDOMAIN"
|
||||
if grep "NXDOMAIN" outfile; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "Not OK"
|
||||
end 1
|
||||
fi
|
||||
}
|
||||
|
||||
expect_external_answer () {
|
||||
echo "> check external answer"
|
||||
if grep "1.2.3.4" outfile; then
|
||||
@@ -118,6 +128,26 @@ expect_tag_two_answer () {
|
||||
fi
|
||||
}
|
||||
|
||||
expect_rpz_one_answer () {
|
||||
echo "> check tag 'one' answer"
|
||||
if grep "11.11.11.11" outfile; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "Not OK"
|
||||
end 1
|
||||
fi
|
||||
}
|
||||
|
||||
expect_rpz_two_answer () {
|
||||
echo "> check tag 'two' answer"
|
||||
if grep "22.22.22.22" outfile; then
|
||||
echo "OK"
|
||||
else
|
||||
echo "Not OK"
|
||||
end 1
|
||||
fi
|
||||
}
|
||||
|
||||
# do the test
|
||||
|
||||
for i in 4 6; do
|
||||
@@ -142,6 +172,15 @@ for i in 4 6; do
|
||||
query $i $PORT_TAG_3 "local"
|
||||
expect_refused
|
||||
|
||||
query $i $PORT_RPZ_1 "local"
|
||||
expect_rpz_one_answer
|
||||
|
||||
query $i $PORT_RPZ_2 "local"
|
||||
expect_rpz_two_answer
|
||||
|
||||
query $i $PORT_RPZ_NX "local"
|
||||
expect_nx_answer
|
||||
|
||||
query $i $PORT_VIEW_INT "www.internal"
|
||||
expect_internal_answer
|
||||
|
||||
@@ -183,6 +222,15 @@ for addr in $INTERFACE_ADDR_1 $INTERFACE_ADDR_2 $INTERFACE_ADDR_3 $INTERFACE_ADD
|
||||
query_addr $addr $PORT_TAG_3 "local"
|
||||
expect_refused
|
||||
|
||||
query_addr $addr $PORT_RPZ_1 "local"
|
||||
expect_rpz_one_answer
|
||||
|
||||
query_addr $addr $PORT_RPZ_2 "local"
|
||||
expect_rpz_two_answer
|
||||
|
||||
query_addr $addr $PORT_RPZ_NX "local"
|
||||
expect_nx_answer
|
||||
|
||||
query_addr $addr $PORT_VIEW_INT "www.internal"
|
||||
expect_internal_answer
|
||||
|
||||
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
$ORIGIN rpz-nx.
|
||||
@ IN SOA no.no no.no 1 2 3 4 5
|
||||
local IN CNAME .
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
$ORIGIN rpz-one.
|
||||
@ IN SOA no.no no.no 1 2 3 4 5
|
||||
local IN A 11.11.11.11
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
$ORIGIN rpz-two.
|
||||
@ IN SOA no.no no.no 1 2 3 4 5
|
||||
local IN A 22.22.22.22
|
||||
Vendored
+5
@@ -8,6 +8,11 @@
|
||||
|
||||
PRE="../.."
|
||||
if grep "define USE_IPSET 1" $PRE/config.h; then echo test enabled; else skip_test "test skipped"; fi
|
||||
if grep "define HAVE_NET_PFVAR_H 1" $PRE/config.h; then
|
||||
if test ! -f /dev/pf; then
|
||||
skip_test "no /dev/pf"
|
||||
fi
|
||||
fi
|
||||
|
||||
get_random_port 2
|
||||
UNBOUND_PORT=$RND_PORT
|
||||
|
||||
Vendored
+226
@@ -0,0 +1,226 @@
|
||||
; config options
|
||||
; The island of trust is at example.com
|
||||
server:
|
||||
trust-anchor: "example.com. 3600 IN DS 2854 3 1 46e4ffc6e9a4793b488954bd3f0cc6af0dfb201b"
|
||||
val-override-date: "20070916134226"
|
||||
target-fetch-policy: "0 0 0 0 0"
|
||||
qname-minimisation: "no"
|
||||
fake-sha1: yes
|
||||
trust-anchor-signaling: no
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
|
||||
CONFIG_END
|
||||
|
||||
SCENARIO_BEGIN Test validator with a dname used twice
|
||||
|
||||
; K.ROOT-SERVERS.NET.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 193.0.14.129
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
. IN NS
|
||||
SECTION ANSWER
|
||||
. IN NS K.ROOT-SERVERS.NET.
|
||||
SECTION ADDITIONAL
|
||||
K.ROOT-SERVERS.NET. IN A 193.0.14.129
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode subdomain
|
||||
ADJUST copy_id copy_query
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
com. IN NS
|
||||
SECTION AUTHORITY
|
||||
com. IN NS a.gtld-servers.net.
|
||||
SECTION ADDITIONAL
|
||||
a.gtld-servers.net. IN A 192.5.6.30
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; a.gtld-servers.net.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 192.5.6.30
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
com. IN NS
|
||||
SECTION ANSWER
|
||||
com. IN NS a.gtld-servers.net.
|
||||
SECTION ADDITIONAL
|
||||
a.gtld-servers.net. IN A 192.5.6.30
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode subdomain
|
||||
ADJUST copy_id copy_query
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN NS
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; ns.example.com.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 1.2.3.4
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN NS
|
||||
SECTION ANSWER
|
||||
example.com. IN NS ns.example.com.
|
||||
example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
|
||||
ENTRY_END
|
||||
|
||||
; response to DNSKEY priming query
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN DNSKEY
|
||||
SECTION ANSWER
|
||||
example.com. 3600 IN DNSKEY 256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
|
||||
example.com. 3600 IN RRSIG DNSKEY DSA 2 3600 20070926134150 20070829134150 2854 example.com. MCwCFBQRtlR4BEv9ohi+PGFjp+AHsJuHAhRCvz0shggvnvI88DFnBDCczHUcVA== ;{id = 2854}
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
|
||||
ENTRY_END
|
||||
|
||||
; response to query of interest
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
a.a.test-dname-2.example.com. IN A
|
||||
SECTION ANSWER
|
||||
test-dname-2.example.com. 3600 IN DNAME test-2.example.com.
|
||||
test-dname-2.example.com. 3600 IN RRSIG DNAME 3 3 3600 20070926134150 20070829134150 2854 example.com. AB9F05uhCzJ0hFbu/033nWLEMDoDrIY1PL69PsD9kMUuyzT4irnUlGY=
|
||||
; unsigned CNAME
|
||||
a.a.test-dname-2.example.com. IN CNAME a.a.test-2.example.com.
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
a.a.test-2.example.com. IN A
|
||||
SECTION ANSWER
|
||||
a.a.test-2.example.com. 3600 IN CNAME a.test-dname-2.example.com.
|
||||
a.a.test-2.example.com. 3600 IN RRSIG CNAME 3 5 3600 20070926134150 20070829134150 2854 example.com. AECBiHVJ8qaSV3sC7LcOlSF2W4b9JD+g44fQ2EvkKqGJVUJfa6840i8=
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
a.test-dname-2.example.com. IN A
|
||||
SECTION ANSWER
|
||||
test-dname-2.example.com. 3600 IN DNAME test-2.example.com.
|
||||
test-dname-2.example.com. 3600 IN RRSIG DNAME 3 3 3600 20070926134150 20070829134150 2854 example.com. AB9F05uhCzJ0hFbu/033nWLEMDoDrIY1PL69PsD9kMUuyzT4irnUlGY=
|
||||
; unsigned CNAME
|
||||
a.test-dname-2.example.com. IN CNAME a.test-2.example.com.
|
||||
SECTION AUTHORITY
|
||||
snow.example.com. 3600 IN NSEC a.a.test-2.example.com. A AAAA RRSIG NSEC
|
||||
snow.example.com. 3600 IN RRSIG NSEC 3 3 3600 20070926134150 20070829134150 2854 example.com. AHy/eDMTc5D7Q7Svh/B/r/twvHn8GTzYgSwO1jFasFrb2Gmtk8waXaM=
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
a.test-2.example.com. IN A
|
||||
SECTION ANSWER
|
||||
SECTION AUTHORITY
|
||||
example.com. 3600 IN SOA ns.example.com. root.example.com. 1 3600 300 7200 3600
|
||||
example.com. 3600 IN RRSIG SOA 3 2 3600 20070926134150 20070829134150 2854 example.com. AEO4JOt/lNSVk3InhQz4MvUXll2vOOuZklfB7HpnW45kvEqHsqfWuNw=
|
||||
snow.example.com. 3600 IN NSEC a.a.test-2.example.com. A AAAA RRSIG NSEC
|
||||
snow.example.com. 3600 IN RRSIG NSEC 3 3 3600 20070926134150 20070829134150 2854 example.com. AHy/eDMTc5D7Q7Svh/B/r/twvHn8GTzYgSwO1jFasFrb2Gmtk8waXaM=
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
STEP 1 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
a.a.test-dname-2.example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
; recursion happens here.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA AD DO NOERROR
|
||||
SECTION QUESTION
|
||||
a.a.test-dname-2.example.com. IN A
|
||||
SECTION ANSWER
|
||||
test-dname-2.example.com. 3600 IN DNAME test-2.example.com.
|
||||
test-dname-2.example.com. 3600 IN RRSIG DNAME 3 3 3600 20070926134150 20070829134150 2854 example.com. AB9F05uhCzJ0hFbu/033nWLEMDoDrIY1PL69PsD9kMUuyzT4irnUlGY= ;{id = 2854}
|
||||
a.a.test-dname-2.example.com. 3600 IN CNAME a.a.test-2.example.com.
|
||||
a.a.test-2.example.com. 3600 IN CNAME a.test-dname-2.example.com.
|
||||
a.a.test-2.example.com. 3600 IN RRSIG CNAME 3 5 3600 20070926134150 20070829134150 2854 example.com. AECBiHVJ8qaSV3sC7LcOlSF2W4b9JD+g44fQ2EvkKqGJVUJfa6840i8= ;{id = 2854}
|
||||
a.test-dname-2.example.com. 3600 IN CNAME a.test-2.example.com.
|
||||
|
||||
SECTION AUTHORITY
|
||||
example.com. 3600 IN SOA ns.example.com. root.example.com. 1 3600 300 7200 3600
|
||||
example.com. 3600 IN RRSIG SOA 3 2 3600 20070926134150 20070829134150 2854 example.com. AEO4JOt/lNSVk3InhQz4MvUXll2vOOuZklfB7HpnW45kvEqHsqfWuNw= ;{id = 2854}
|
||||
snow.example.com. 3600 IN NSEC a.a.test-2.example.com. A AAAA RRSIG NSEC
|
||||
snow.example.com. 3600 IN RRSIG NSEC 3 3 3600 20070926134150 20070829134150 2854 example.com. AHy/eDMTc5D7Q7Svh/B/r/twvHn8GTzYgSwO1jFasFrb2Gmtk8waXaM= ;{id = 2854}
|
||||
ENTRY_END
|
||||
|
||||
; Check cache response for DNAME
|
||||
; so 100+ the authority will not respond any more : must be from cache.
|
||||
STEP 110 TIME_PASSES ELAPSE 10
|
||||
|
||||
STEP 120 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
a.a.test-dname-2.example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
STEP 130 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ttl
|
||||
REPLY QR RD RA AD DO NOERROR
|
||||
SECTION QUESTION
|
||||
a.a.test-dname-2.example.com. IN A
|
||||
SECTION ANSWER
|
||||
test-dname-2.example.com. 3590 IN DNAME test-2.example.com.
|
||||
test-dname-2.example.com. 3590 IN RRSIG DNAME 3 3 3600 20070926134150 20070829134150 2854 example.com. AB9F05uhCzJ0hFbu/033nWLEMDoDrIY1PL69PsD9kMUuyzT4irnUlGY= ;{id = 2854}
|
||||
a.a.test-dname-2.example.com. 3590 IN CNAME a.a.test-2.example.com.
|
||||
a.a.test-2.example.com. 3590 IN CNAME a.test-dname-2.example.com.
|
||||
a.a.test-2.example.com. 3590 IN RRSIG CNAME 3 5 3600 20070926134150 20070829134150 2854 example.com. AECBiHVJ8qaSV3sC7LcOlSF2W4b9JD+g44fQ2EvkKqGJVUJfa6840i8= ;{id = 2854}
|
||||
a.test-dname-2.example.com. 3590 IN CNAME a.test-2.example.com.
|
||||
|
||||
SECTION AUTHORITY
|
||||
example.com. 3590 IN SOA ns.example.com. root.example.com. 1 3600 300 7200 3600
|
||||
example.com. 3590 IN RRSIG SOA 3 2 3600 20070926134150 20070829134150 2854 example.com. AEO4JOt/lNSVk3InhQz4MvUXll2vOOuZklfB7HpnW45kvEqHsqfWuNw= ;{id = 2854}
|
||||
snow.example.com. 3590 IN NSEC a.a.test-2.example.com. A AAAA RRSIG NSEC
|
||||
snow.example.com. 3590 IN RRSIG NSEC 3 3 3600 20070926134150 20070829134150 2854 example.com. AHy/eDMTc5D7Q7Svh/B/r/twvHn8GTzYgSwO1jFasFrb2Gmtk8waXaM= ;{id = 2854}
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
Vendored
+348
@@ -0,0 +1,348 @@
|
||||
; config options
|
||||
; The island of trust is at example.com
|
||||
server:
|
||||
trust-anchor: "example.com. 3600 IN DS 2854 3 1 46e4ffc6e9a4793b488954bd3f0cc6af0dfb201b"
|
||||
trust-anchor: "example.net. 3600 IN DS 1444 8 2 69887be92d4848c0bc10acc95682a01e7e3b57ab0750a2ee6f72cac7191a64f1"
|
||||
val-override-date: "20070916134226"
|
||||
target-fetch-policy: "0 0 0 0 0"
|
||||
qname-minimisation: "no"
|
||||
fake-sha1: yes
|
||||
trust-anchor-signaling: no
|
||||
minimal-responses: no
|
||||
log-servfail: yes
|
||||
val-log-level: 2
|
||||
ede: yes
|
||||
|
||||
stub-zone:
|
||||
name: "."
|
||||
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
|
||||
CONFIG_END
|
||||
|
||||
SCENARIO_BEGIN Test validator with failure for chaing of trust lookup.
|
||||
; The error message that is created, also for EDE is more extensive.
|
||||
|
||||
; K.ROOT-SERVERS.NET.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 193.0.14.129
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
. IN NS
|
||||
SECTION ANSWER
|
||||
. IN NS K.ROOT-SERVERS.NET.
|
||||
SECTION ADDITIONAL
|
||||
K.ROOT-SERVERS.NET. IN A 193.0.14.129
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode subdomain
|
||||
ADJUST copy_id copy_query
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
com. IN NS
|
||||
SECTION AUTHORITY
|
||||
com. IN NS a.gtld-servers.net.
|
||||
SECTION ADDITIONAL
|
||||
a.gtld-servers.net. IN A 192.5.6.30
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode subdomain
|
||||
ADJUST copy_id copy_query
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
net. IN NS
|
||||
SECTION AUTHORITY
|
||||
net. IN NS a.gtld-servers.net.
|
||||
SECTION ADDITIONAL
|
||||
a.gtld-servers.net. IN A 192.5.6.30
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; a.gtld-servers.net.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 192.5.6.30
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
com. IN NS
|
||||
SECTION ANSWER
|
||||
com. IN NS a.gtld-servers.net.
|
||||
SECTION ADDITIONAL
|
||||
a.gtld-servers.net. IN A 192.5.6.30
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode subdomain
|
||||
ADJUST copy_id copy_query
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN NS
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode subdomain
|
||||
ADJUST copy_id copy_query
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.net. IN NS
|
||||
SECTION AUTHORITY
|
||||
example.net. IN NS ns.example.net.
|
||||
SECTION ADDITIONAL
|
||||
ns.example.net. IN A 1.2.3.5
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; ns.example.com.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 1.2.3.4
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
example.com. IN NS
|
||||
SECTION ANSWER
|
||||
example.com. IN NS ns.example.com.
|
||||
example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
ns.example.com. IN A
|
||||
SECTION ANSWER
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
ns.example.com. IN AAAA
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
|
||||
ENTRY_END
|
||||
|
||||
; response to DNSKEY priming query
|
||||
;ENTRY_BEGIN
|
||||
;MATCH opcode qtype qname
|
||||
;ADJUST copy_id
|
||||
;REPLY QR NOERROR
|
||||
;SECTION QUESTION
|
||||
;example.com. IN DNSKEY
|
||||
;SECTION ANSWER
|
||||
;example.com. 3600 IN DNSKEY 256 3 3 ALXLUsWqUrY3JYER3T4TBJII s70j+sDS/UT2QRp61SE7S3E EXopNXoFE73JLRmvpi/UrOO/Vz4Se 6wXv/CYCKjGw06U4WRgR YXcpEhJROyNapmdIKSx hOzfLVE1gqA0PweZR8d tY3aNQSRn3sPpwJr6Mi /PqQKAMMrZ9ckJpf1+b QMOOvxgzz2U1GS18b3y ZKcgTMEaJzd/GZYzi/B N2DzQ0MsrSwYXfsNLFO Bbs8PJMW4LYIxeeOe6rUgkWOF 7CC9Dh/dduQ1QrsJhmZAEFfd6ByYV+ ;{id = 2854 (zsk), size = 1688b}
|
||||
;example.com. 3600 IN RRSIG DNSKEY 3 2 3600 20070926134802 20070829134802 2854 example.com. MCwCFG1yhRNtTEa3Eno2zhVVuy2EJX3wAhQeLyUp6+UXcpC5qGNu9tkrTEgPUg== ;{id = 2854}
|
||||
;SECTION AUTHORITY
|
||||
;example.com. IN NS ns.example.com.
|
||||
;example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
|
||||
;SECTION ADDITIONAL
|
||||
;ns.example.com. IN A 1.2.3.4
|
||||
;ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCMSWxVehgOQLoYclB9PIAbNP229AIUeH0vNNGJhjnZiqgIOKvs1EhzqAo= ;{id = 2854}
|
||||
;ENTRY_END
|
||||
; servfail for DNSKEY priming query
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA SERVFAIL
|
||||
SECTION QUESTION
|
||||
example.com. IN DNSKEY
|
||||
ENTRY_END
|
||||
|
||||
; response to query of interest
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR NOERROR
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
www.example.com. IN A 10.20.30.40
|
||||
ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854}
|
||||
SECTION AUTHORITY
|
||||
example.com. IN NS ns.example.com.
|
||||
example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854}
|
||||
SECTION ADDITIONAL
|
||||
ns.example.com. IN A 1.2.3.4
|
||||
www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854}
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
; ns.example.com.
|
||||
RANGE_BEGIN 0 100
|
||||
ADDRESS 1.2.3.5
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
example.net. IN NS
|
||||
SECTION ANSWER
|
||||
example.net. 3600 IN NS ns.example.net.
|
||||
example.net. 3600 IN RRSIG NS 8 2 3600 20070926134150 20070829134150 1444 example.net. nHpOqZb00nIGytQ1YmVoXEHURL/75dWhlKSEtRTorjVdPGPZNN7ziCWJW303v7u07TkZ+i6oFVEWG/SDR4ejn5o31UKJy1373PEH/cvPf9/44jw9gAFaHF1eO6ZQGaRQaeEpU06+xUcnc2QXFt6rNu60EsTvMRDN83bD+r7FA7Y=
|
||||
SECTION ADDITIONAL
|
||||
ns.example.net. 3600 IN A 1.2.3.5
|
||||
ns.example.net. 3600 IN RRSIG A 8 3 3600 20070926134150 20070829134150 1444 example.net. TgQ4nfGtLHuZXlC4JJlVQ6mejf1WJbstTxsh/kgMAc2tryOxF/gvGBHaMtz6oceFZrIgk6g3RYI1Gk5gjSFNADh+EIwI422M8XPAAxRLfFahiO4lr1aCo4c94TYeZNpnDKy81rINTz2hQE1pGWr8Z03ySABqSBnTE1FQt4N/JCo=
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
ns.example.net. IN A
|
||||
SECTION ANSWER
|
||||
ns.example.net. 3600 IN A 1.2.3.5
|
||||
ns.example.net. 3600 IN RRSIG A 8 3 3600 20070926134150 20070829134150 1444 example.net. TgQ4nfGtLHuZXlC4JJlVQ6mejf1WJbstTxsh/kgMAc2tryOxF/gvGBHaMtz6oceFZrIgk6g3RYI1Gk5gjSFNADh+EIwI422M8XPAAxRLfFahiO4lr1aCo4c94TYeZNpnDKy81rINTz2hQE1pGWr8Z03ySABqSBnTE1FQt4N/JCo=
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
ns.example.net. IN AAAA
|
||||
SECTION AUTHORITY
|
||||
example.net. 3600 IN SOA ns.example.net. host.example.net. 1 3600 300 7200 3600
|
||||
example.net. 3600 IN RRSIG SOA 8 2 3600 20070926134150 20070829134150 1444 example.net. P5FRQ4A/0n5owaBhZqlYBFD2PNAWJc5oxiDwvwh0hdjxETx8ta3EAvDKtNj5XZ5EKDAhP/tivd+Bq50I0xfRBmrouxgxjgnV3ye8zU+M1fXbuKpsWme9R3S4cs9WYfggTn7X00Af8m0tE62SLH/ZtOOQi2CvOPu7PXtHYT6KW4Q=
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
example.net. IN DNSKEY
|
||||
SECTION ANSWER
|
||||
example.net. 3600 IN DNSKEY 257 3 8 AwEAAbd9WqjzE2Pynz21OG5doSf9hFzMr5dhzz2waZ3vTa+0o5r7AjTAqmA1yH/B3+aAMihUm5ucZSfVqo7+kOaRE8yFj9aivOmA1n1+JLevJq/oyvQyjxQN2Qb89LyaNUT5oKZIiL+uyyhNW3KDR3SSbQ/GBwQNDHVcZi+JDR3RC0r7 ;{id = 1444 (ksk), size = 1024b}
|
||||
example.net. 3600 IN RRSIG DNSKEY 8 2 3600 20070926134150 20070829134150 1444 example.net. hAAlJt/YwAgWBzseK0N42+ysSMaWgntcuftF8a43chLh+fbe3vPWrgwqr/Cic52tu4ZqMox592tqWDxAG7F1eDGfO0SfzS2C9Tc/Wnz5nFjFh75G4Mtt8DTv5vTyGUVX5zAFzV8SNijVC0o1F7MHaVPt3rFtjjg2zW/UOz2m9+U=
|
||||
ENTRY_END
|
||||
|
||||
; For sub1.example.net. zone; it is co-hosted with example.net, so that
|
||||
; there can be failures for the DS lookup. But the data lookup succeeds.
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
www.sub1.example.net. IN A
|
||||
SECTION ANSWER
|
||||
www.sub1.example.net. IN A 10.20.30.41
|
||||
www.sub1.example.net. 3600 IN RRSIG A 8 4 3600 20070926134150 20070829134150 29332 sub1.example.net. NcFP77Hixawt8hb+STIbbeqdF9tWTuHsbGEB4agKXlwHqS0BnyA+It6+UdE57IF0Kbnc7gSuaslX9At8ctd4HuC/9F/osbo96o23JEfnXPky/r5SsLaeN5KmUmUVjG9oxyAEc6PVlaaQ5a/RhaxmDRaDiku2gB7KjdjPxwxe+Rc54GV2eM3GtcfT+oDakLdSSACqeVjUFIOtYMpG8jAHrBe4uSnjKI7O0fWDFN5OES6sN9iUS9/ceorIoF/gSIqM7xWEuPLxE2c5TtYJyPtMCeGJ9wBP4wrTXfJ58+Lg5SFKgEuKTvAqEv9KEwg/kJb1GQ+ho5XKFO6EII2iyeUK/w==
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR SERVFAIL
|
||||
SECTION QUESTION
|
||||
sub1.example.net. IN DS
|
||||
SECTION ANSWER
|
||||
; no DS for sub1.example.net id=29332 algo=8
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
www.sub2.example.net. IN A
|
||||
SECTION ANSWER
|
||||
www.sub2.example.net. IN A 10.20.30.42
|
||||
www.sub2.example.net. 3600 IN RRSIG A 8 4 3600 20070926134150 20070829134150 29332 sub2.example.net. FOY6YxNoFyrSkBtWV7HcECmORTMedRWHdGk7Rm04icT8Bw0dWfzVaIpAkBY6FXx8UvqN7McN4IJI5dAVXptfekO+Yvy2PwkjehRUXvQK64XH5UM5pVbX5g8E4pnOrLa/jzPB7srzMpyWVCpt81lPoFpdfXUMm7434ifkTYhpAll7y5NAocFiT3F+XGe06qMIr51WxoFfegIGohMFhkTDUdLWrdV10128W+NzPdwoYtiigtCObKxTtyj3gK+mxqXvX4X4F2YIGQ+mx62ovdUilnLYZm/WC/ZQkdxeOZjeCTxvSpGGG+wtu1QufgIJ+BpAZAOxREOYZkhR29AG0np4EA==
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR SERVFAIL
|
||||
SECTION QUESTION
|
||||
sub2.example.net. IN DNSKEY
|
||||
SECTION ANSWER
|
||||
; sub2.example.net. IN DNSKEY 257 3 8 AwEAAb4WMOTBLTFvmBra5m6SK4VfViOzmvyUAU0qv861ZQXeEFvwlndqNU9rwRsMxrSWAYs5nHErKDn49usC/HyxxW1477iGFHhfgL4mjNreJm9zft2QFB1VLbRbEPYdDMLCn4co0qnG7/KG8W2i8Pym1L7f+aREwbLo+/716AS2PbaKMhfWLKLiq5wnBcUClQMNzCiwhqxDJp1oePqfkVdeUgXOtgi0dYRIKyQFhJ5VWJ22npoi/Gif0XLCADAlAwRLKc8o/yJkCxskzgpHpw5Cki1lclg0aq4ssOuPRQ+ne6IHYCz9D2mwzulblhLFamKdq7aHzNt4NlyxhpANVFiKLD8= ;{id = 29332 (ksk), size = 2048b}
|
||||
ENTRY_END
|
||||
|
||||
ENTRY_BEGIN
|
||||
MATCH opcode qtype qname
|
||||
ADJUST copy_id
|
||||
REPLY QR AA NOERROR
|
||||
SECTION QUESTION
|
||||
sub2.example.net. IN DS
|
||||
SECTION ANSWER
|
||||
sub2.example.net. 3600 IN DS 29332 8 2 d53e615d9d736b0f2a0097f1d5fa51c84320610f94ecbd7197e7de5f44f02d72
|
||||
sub2.example.net. 3600 IN RRSIG DS 8 3 3600 20070926134150 20070829134150 1444 example.net. dYLYs1uMxJm5+MB6L1+uStE5S1YtyYR0JF+1pPoTptc/H1hYqMxK7pVQPtIGvq8j8wNyC7jOzALfEXgwRKiSdR1l1GQ5HIxWkhUmkpLcecwJOjemee4nXaifOFa5bdbdYpuDwTiIzx+PvanlaVjEPy0i1IukanDi6jojfyWcgLA=
|
||||
ENTRY_END
|
||||
RANGE_END
|
||||
|
||||
STEP 1 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
ENTRY_END
|
||||
|
||||
; The DNSKEY lookup for the key prime is a failure.
|
||||
STEP 10 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ede=9
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.example.com. IN A
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
|
||||
STEP 20 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
www.sub1.example.net. IN A
|
||||
ENTRY_END
|
||||
|
||||
; The DS lookup is a failure.
|
||||
STEP 30 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ede=23
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.sub1.example.net. IN A
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
|
||||
STEP 40 QUERY
|
||||
ENTRY_BEGIN
|
||||
REPLY RD DO
|
||||
SECTION QUESTION
|
||||
www.sub2.example.net. IN A
|
||||
ENTRY_END
|
||||
|
||||
; The DNSKEY lookup is a failure.
|
||||
STEP 50 CHECK_ANSWER
|
||||
ENTRY_BEGIN
|
||||
MATCH all ede=9
|
||||
REPLY QR RD RA DO SERVFAIL
|
||||
SECTION QUESTION
|
||||
www.sub2.example.net. IN A
|
||||
SECTION ANSWER
|
||||
ENTRY_END
|
||||
|
||||
SCENARIO_END
|
||||
@@ -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",
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
@@ -392,7 +392,7 @@ fptr_whitelist_modenv_detect_cycle(int (*fptr)(
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
fptr_whitelist_mod_init(int (*fptr)(struct module_env* env, int id))
|
||||
{
|
||||
if(fptr == &iter_init) return 1;
|
||||
@@ -420,7 +420,7 @@ fptr_whitelist_mod_init(int (*fptr)(struct module_env* env, int id))
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
int
|
||||
fptr_whitelist_mod_deinit(void (*fptr)(struct module_env* env, int id))
|
||||
{
|
||||
if(fptr == &iter_deinit) return 1;
|
||||
@@ -448,6 +448,28 @@ fptr_whitelist_mod_deinit(void (*fptr)(struct module_env* env, int id))
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
fptr_whitelist_mod_startup(int (*fptr)(struct module_env* env, int id))
|
||||
{
|
||||
#ifdef USE_IPSET
|
||||
if(fptr == &ipset_startup) return 1;
|
||||
#else
|
||||
(void)fptr;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
fptr_whitelist_mod_destartup(void (*fptr)(struct module_env* env, int id))
|
||||
{
|
||||
#ifdef USE_IPSET
|
||||
if(fptr == &ipset_destartup) return 1;
|
||||
#else
|
||||
(void)fptr;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
fptr_whitelist_mod_operate(void (*fptr)(struct module_qstate* qstate,
|
||||
enum module_ev event, int id, struct outbound_entry* outbound))
|
||||
|
||||
@@ -278,6 +278,22 @@ int fptr_whitelist_mod_init(int (*fptr)(struct module_env* env, int id));
|
||||
*/
|
||||
int fptr_whitelist_mod_deinit(void (*fptr)(struct module_env* env, int id));
|
||||
|
||||
/**
|
||||
* Check function pointer whitelist for module startup call values.
|
||||
*
|
||||
* @param fptr: function pointer to check.
|
||||
* @return false if not in whitelist.
|
||||
*/
|
||||
int fptr_whitelist_mod_startup(int (*fptr)(struct module_env* env, int id));
|
||||
|
||||
/**
|
||||
* Check function pointer whitelist for module destartup call values.
|
||||
*
|
||||
* @param fptr: function pointer to check.
|
||||
* @return false if not in whitelist.
|
||||
*/
|
||||
int fptr_whitelist_mod_destartup(void (*fptr)(struct module_env* env, int id));
|
||||
|
||||
/**
|
||||
* Check function pointer whitelist for module operate call values.
|
||||
*
|
||||
|
||||
+26
-4
@@ -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
@@ -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) {
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 "
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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 */
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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*
|
||||
|
||||
Reference in New Issue
Block a user