# Copyright 2009, Wouter Wijngaards, NLnet Labs.
# BSD licensed.
#
-# Version 46
+# Version 48
+# 2024-01-16 fix to add -l:libssp.a to -lcrypto link check.
+# and check for getaddrinfo with only header.
+# 2024-01-15 fix to add crypt32 to -lcrypto link check when checking for gdi32.
# 2023-05-04 fix to remove unused whitespace.
# 2023-01-26 fix -Wstrict-prototypes.
# 2022-09-01 fix checking if nonblocking sockets work on OpenBSD.
LIBSSL_LDFLAGS="$LIBSSL_LDFLAGS -L$ssldir_lib"
ACX_RUNTIME_PATH_ADD([$ssldir_lib])
fi
-
+
AC_MSG_CHECKING([for EVP_sha256 in -lcrypto])
LIBS="$LIBS -lcrypto"
LIBSSL_LIBS="$LIBSSL_LIBS -lcrypto"
]])],[
AC_DEFINE([HAVE_EVP_SHA256], 1,
[If you have EVP_sha256])
- AC_MSG_RESULT(yes)
+ AC_MSG_RESULT(yes)
],[
AC_MSG_RESULT(no)
LIBS="$BAKLIBS"
LIBSSL_LIBS="$BAKSSLLIBS"
- LIBS="$LIBS -ldl"
- LIBSSL_LIBS="$LIBSSL_LIBS -ldl"
- AC_MSG_CHECKING([if -lcrypto needs -ldl])
- AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[
- int EVP_sha256(void);
- (void)EVP_sha256();
- ]])],[
- AC_DEFINE([HAVE_EVP_SHA256], 1,
- [If you have EVP_sha256])
- AC_MSG_RESULT(yes)
- ],[
- AC_MSG_RESULT(no)
- LIBS="$BAKLIBS"
- LIBSSL_LIBS="$BAKSSLLIBS"
- LIBS="$LIBS -ldl -pthread"
- LIBSSL_LIBS="$LIBSSL_LIBS -ldl -pthread"
- AC_MSG_CHECKING([if -lcrypto needs -ldl -pthread])
- AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[
- int EVP_sha256(void);
- (void)EVP_sha256();
- ]])],[
- AC_DEFINE([HAVE_EVP_SHA256], 1,
- [If you have EVP_sha256])
- AC_MSG_RESULT(yes)
- ],[
- AC_MSG_RESULT(no)
- AC_MSG_ERROR([OpenSSL found in $ssldir, but version 0.9.7 or higher is required])
+
+ LIBS="$LIBS -lgdi32 -lws2_32 -lcrypt32"
+ LIBSSL_LIBS="$LIBSSL_LIBS -lgdi32 -lws2_32 -lcrypt32"
+ AC_MSG_CHECKING([if -lcrypto needs -lgdi32 -lws2_32 -lcrypt32])
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[
+ int EVP_sha256(void);
+ (void)EVP_sha256();
+ ]])],[
+ AC_DEFINE([HAVE_EVP_SHA256], 1,
+ [If you have EVP_sha256])
+ AC_MSG_RESULT(yes)
+ ],[
+ AC_MSG_RESULT(no)
+ LIBS="$BAKLIBS"
+ LIBSSL_LIBS="$BAKSSLLIBS"
+
+ LIBS="$LIBS -lgdi32 -lws2_32 -lcrypt32 -l:libssp.a"
+ LIBSSL_LIBS="$LIBSSL_LIBS -lgdi32 -lws2_32 -lcrypt32 -l:libssp.a"
+ AC_MSG_CHECKING([if -lcrypto needs -lgdi32 -lws2_32 -lcrypt32 -l:libssp.a])
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[
+ int EVP_sha256(void);
+ (void)EVP_sha256();
+ ]])],[
+ AC_DEFINE([HAVE_EVP_SHA256], 1,
+ [If you have EVP_sha256])
+ AC_MSG_RESULT(yes)
+ ],[
+ AC_MSG_RESULT(no)
+ LIBS="$BAKLIBS"
+ LIBSSL_LIBS="$BAKSSLLIBS"
+
+ LIBS="$LIBS -ldl"
+ LIBSSL_LIBS="$LIBSSL_LIBS -ldl"
+ AC_MSG_CHECKING([if -lcrypto needs -ldl])
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[
+ int EVP_sha256(void);
+ (void)EVP_sha256();
+ ]])],[
+ AC_DEFINE([HAVE_EVP_SHA256], 1,
+ [If you have EVP_sha256])
+ AC_MSG_RESULT(yes)
+ ],[
+ AC_MSG_RESULT(no)
+ LIBS="$BAKLIBS"
+ LIBSSL_LIBS="$BAKSSLLIBS"
+ LIBS="$LIBS -ldl -pthread"
+ LIBSSL_LIBS="$LIBSSL_LIBS -ldl -pthread"
+ AC_MSG_CHECKING([if -lcrypto needs -ldl -pthread])
+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[
+ int EVP_sha256(void);
+ (void)EVP_sha256();
+ ]])],[
+ AC_DEFINE([HAVE_EVP_SHA256], 1,
+ [If you have EVP_sha256])
+ AC_MSG_RESULT(yes)
+ ],[
+ AC_MSG_RESULT(no)
+ AC_MSG_ERROR([OpenSSL found in $ssldir, but version 0.9.7 or higher is required])
+ ])
+ ])
])
- ])
+ ])
])
])
fi
dnl Check for SSL, where SSL is mandatory
dnl Adds --with-ssl option, searches for openssl and defines HAVE_SSL if found
-dnl Setup of CPPFLAGS, CFLAGS. Adds -lcrypto to LIBS.
+dnl Setup of CPPFLAGS, CFLAGS. Adds -lcrypto to LIBS.
dnl Checks main header files of SSL.
dnl
AC_DEFUN([ACX_WITH_SSL],
if test "$ac_cv_header_windows_h" = "yes"; then
AC_DEFINE(USE_WINSOCK, 1, [Whether the windows socket API is used])
USE_WINSOCK="1"
- if echo $LIBS | grep 'lws2_32' >/dev/null; then
+ if echo "$LIBS" | grep 'lws2_32' >/dev/null; then
:
else
LIBS="$LIBS -lws2_32"
fi
],
dnl no quick getaddrinfo, try mingw32 and winsock2 library.
+dnl perhaps getaddrinfo needs only the include
+AC_LINK_IFELSE(
+[AC_LANG_PROGRAM(
+[
+#ifdef HAVE_WS2TCPIP_H
+#include <ws2tcpip.h>
+#endif
+],
+[
+ (void)getaddrinfo(NULL, NULL, NULL, NULL);
+]
+)],
+[
+ac_cv_func_getaddrinfo="yes"
+AC_DEFINE(USE_WINSOCK, 1, [Whether the windows socket API is used])
+USE_WINSOCK="1"
+],
+
ORIGLIBS="$LIBS"
LIBS="$LIBS -lws2_32"
AC_LINK_IFELSE(
LIBS="$ORIGLIBS"
])
)
+)
AC_MSG_RESULT($ac_cv_func_getaddrinfo)
if test $ac_cv_func_getaddrinfo = yes; then
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for unbound 1.19.2.
+# Generated by GNU Autoconf 2.69 for unbound 1.19.3.
#
# Report bugs to <unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues>.
#
# Identity of this package.
PACKAGE_NAME='unbound'
PACKAGE_TARNAME='unbound'
-PACKAGE_VERSION='1.19.2'
-PACKAGE_STRING='unbound 1.19.2'
+PACKAGE_VERSION='1.19.3'
+PACKAGE_STRING='unbound 1.19.3'
PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues'
PACKAGE_URL=''
DNSTAP_SOCKET_PATH
opt_dnstap_socket_path
ENABLE_DNSTAP
+PROTOBUFC_LIBS
+PROTOBUFC_CFLAGS
PROTOC_C
UBSYMS
EXTRALINK
SYSTEMD_LIBS
SYSTEMD_DAEMON_CFLAGS
SYSTEMD_DAEMON_LIBS
-PYTHON_VERSION'
+PYTHON_VERSION
+PROTOBUFC_CFLAGS
+PROTOBUFC_LIBS'
# Initialize some variables set by options.
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures unbound 1.19.2 to adapt to many kinds of systems.
+\`configure' configures unbound 1.19.3 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of unbound 1.19.2:";;
+ short | recursive ) echo "Configuration of unbound 1.19.3:";;
esac
cat <<\_ACEOF
The installed Python version to use, for example '2.3'. This
string will be appended to the Python interpreter canonical
name.
+ PROTOBUFC_CFLAGS
+ C compiler flags for PROTOBUFC, overriding pkg-config
+ PROTOBUFC_LIBS
+ linker flags for PROTOBUFC, overriding pkg-config
Use these variables to override the choices made by `configure' or to help
it to find libraries and programs with nonstandard names/locations.
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-unbound configure 1.19.2
+unbound configure 1.19.3
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by unbound $as_me 1.19.2, which was
+It was created by unbound $as_me 1.19.3, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
UNBOUND_VERSION_MINOR=19
-UNBOUND_VERSION_MICRO=2
+UNBOUND_VERSION_MICRO=3
LIBUNBOUND_CURRENT=9
-LIBUNBOUND_REVISION=25
+LIBUNBOUND_REVISION=26
LIBUNBOUND_AGE=1
# 1.0.0 had 0:12:0
# 1.0.1 had 0:13:0
# 1.19.0 had 9:23:1
# 1.19.1 had 9:24:1
# 1.19.2 had 9:25:1
+# 1.19.3 had 9:26:1
# Current -- the number of the binary API that we're implementing
# Revision -- which iteration of the implementation of the binary
# pkg-config is only needed for these options, do not require it otherwise
-if test "$enable_systemd" = "yes" -o "$with_pyunbound" = "yes" -o "$with_pythonmod" = "yes"; then
+if test "$enable_systemd" = "yes" -o "$enable_dnstap" = "yes" -o "$with_pyunbound" = "yes" -o "$with_pythonmod" = "yes"; then
$as_echo "no" >&6; }
LIBS="$BAKLIBS"
LIBSSL_LIBS="$BAKSSLLIBS"
- LIBS="$LIBS -ldl"
- LIBSSL_LIBS="$LIBSSL_LIBS -ldl"
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if -lcrypto needs -ldl" >&5
+
+ LIBS="$LIBS -lgdi32 -lws2_32 -lcrypt32"
+ LIBSSL_LIBS="$LIBSSL_LIBS -lgdi32 -lws2_32 -lcrypt32"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if -lcrypto needs -lgdi32 -lws2_32 -lcrypt32" >&5
+$as_echo_n "checking if -lcrypto needs -lgdi32 -lws2_32 -lcrypt32... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ int EVP_sha256(void);
+ (void)EVP_sha256();
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+
+$as_echo "#define HAVE_EVP_SHA256 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ LIBS="$BAKLIBS"
+ LIBSSL_LIBS="$BAKSSLLIBS"
+
+ LIBS="$LIBS -lgdi32 -lws2_32 -lcrypt32 -l:libssp.a"
+ LIBSSL_LIBS="$LIBSSL_LIBS -lgdi32 -lws2_32 -lcrypt32 -l:libssp.a"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if -lcrypto needs -lgdi32 -lws2_32 -lcrypt32 -l:libssp.a" >&5
+$as_echo_n "checking if -lcrypto needs -lgdi32 -lws2_32 -lcrypt32 -l:libssp.a... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ int EVP_sha256(void);
+ (void)EVP_sha256();
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+
+$as_echo "#define HAVE_EVP_SHA256 1" >>confdefs.h
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ LIBS="$BAKLIBS"
+ LIBSSL_LIBS="$BAKSSLLIBS"
+
+ LIBS="$LIBS -ldl"
+ LIBSSL_LIBS="$LIBSSL_LIBS -ldl"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if -lcrypto needs -ldl" >&5
$as_echo_n "checking if -lcrypto needs -ldl... " >&6; }
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
main ()
{
- int EVP_sha256(void);
- (void)EVP_sha256();
+ int EVP_sha256(void);
+ (void)EVP_sha256();
;
return 0;
$as_echo "#define HAVE_EVP_SHA256 1" >>confdefs.h
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
- LIBS="$BAKLIBS"
- LIBSSL_LIBS="$BAKSSLLIBS"
- LIBS="$LIBS -ldl -pthread"
- LIBSSL_LIBS="$LIBSSL_LIBS -ldl -pthread"
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking if -lcrypto needs -ldl -pthread" >&5
+ LIBS="$BAKLIBS"
+ LIBSSL_LIBS="$BAKSSLLIBS"
+ LIBS="$LIBS -ldl -pthread"
+ LIBSSL_LIBS="$LIBSSL_LIBS -ldl -pthread"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if -lcrypto needs -ldl -pthread" >&5
$as_echo_n "checking if -lcrypto needs -ldl -pthread... " >&6; }
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
main ()
{
- int EVP_sha256(void);
- (void)EVP_sha256();
+ int EVP_sha256(void);
+ (void)EVP_sha256();
;
return 0;
$as_echo "#define HAVE_EVP_SHA256 1" >>confdefs.h
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
else
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
- as_fn_error $? "OpenSSL found in $ssldir, but version 0.9.7 or higher is required" "$LINENO" 5
+ as_fn_error $? "OpenSSL found in $ssldir, but version 0.9.7 or higher is required" "$LINENO" 5
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
fi
rm -f core conftest.err conftest.$ac_objext \
if test "$on_mingw" = yes; then
staticexe="-all-static"
# for static compile, include gdi32 and zlib here.
- if echo $LIBS | grep 'lgdi32' >/dev/null; then
+ if echo "$LIBS" | grep 'lgdi32' >/dev/null; then
:
else
LIBS="$LIBS -lgdi32"
LIBS="$LIBS -lz"
fi
- LIBS="$LIBS -l:libssp.a"
+ if echo "$LIBS" | grep -e "libssp.a" -e "lssp" >/dev/null; then
+ :
+ else
+ LIBS="$LIBS -l:libssp.a"
+ fi
fi
fi
LIBS="$LIBS -lz"
fi
- LIBS="$LIBS -l:libssp.a"
+ if echo "$LIBS" | grep -e "libssp.a" -e "lssp" >/dev/null; then
+ :
+ else
+ LIBS="$LIBS -l:libssp.a"
+ fi
fi
fi
$as_echo "#define USE_WINSOCK 1" >>confdefs.h
USE_WINSOCK="1"
- if echo $LIBS | grep 'lws2_32' >/dev/null; then
+ if echo "$LIBS" | grep 'lws2_32' >/dev/null; then
:
else
LIBS="$LIBS -lws2_32"
fi
fi
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+#ifdef HAVE_WS2TCPIP_H
+#include <ws2tcpip.h>
+#endif
+
+int
+main ()
+{
+
+ (void)getaddrinfo(NULL, NULL, NULL, NULL);
+
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+ac_cv_func_getaddrinfo="yes"
+
+$as_echo "#define USE_WINSOCK 1" >>confdefs.h
+
+USE_WINSOCK="1"
+
else
ORIGLIBS="$LIBS"
LIBS="$LIBS -lws2_32"
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_getaddrinfo" >&5
$as_echo "$ac_cv_func_getaddrinfo" >&6; }
if test $ac_cv_func_getaddrinfo = yes; then
WINDRES="$ac_cv_prog_WINDRES"
fi
- LIBS="$LIBS -liphlpapi -lcrypt32"
+ if echo "$LIBS" | grep crypt32 >/dev/null; then
+ LIBS="$LIBS -liphlpapi"
+ else
+ LIBS="$LIBS -liphlpapi -lcrypt32"
+ fi
WINAPPS="unbound-service-install.exe unbound-service-remove.exe anchor-update.exe"
WIN_DAEMON_SRC="winrc/win_svc.c winrc/w_inst.c"
# check for dnstap if requested
- # Check whether --enable-dnstap was given.
+ # Check whether --enable-dnstap was given.
if test "${enable_dnstap+set}" = set; then :
enableval=$enable_dnstap; opt_dnstap=$enableval
else
fi
- if test "x$opt_dnstap" != "xno"; then
- # Extract the first word of "protoc-c", so it can be a program name with args.
+ if test "x$opt_dnstap" != "xno"; then
+ # Extract the first word of "protoc-c", so it can be a program name with args.
set dummy protoc-c; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
fi
- if test -z "$PROTOC_C"; then
- as_fn_error $? "The protoc-c program was not found. Please install protobuf-c!" "$LINENO" 5
- fi
+ if test -z "$PROTOC_C"; then
+ as_fn_error $? "The protoc-c program was not found. Please install protobuf-c!" "$LINENO" 5
+ fi
# Check whether --with-protobuf-c was given.
if test "${with_protobuf_c+set}" = set; then :
withval=$with_protobuf_c;
- # workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
- if test -f $withval/include/google/protobuf-c/protobuf-c.h; then
- CFLAGS="$CFLAGS -I$withval/include/google"
- else
- CFLAGS="$CFLAGS -I$withval/include"
- fi
- LDFLAGS="$LDFLAGS -L$withval/lib"
+ # workaround for protobuf-c includes at old dir before protobuf-c-1.0.0
+ if test -f $withval/include/google/protobuf-c/protobuf-c.h; then
+ CFLAGS="$CFLAGS -I$withval/include/google"
+ else
+ CFLAGS="$CFLAGS -I$withval/include"
+ fi
+ LDFLAGS="$LDFLAGS -L$withval/lib"
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
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for PROTOBUFC" >&5
+$as_echo_n "checking for PROTOBUFC... " >&6; }
+
+if test -n "$PROTOBUFC_CFLAGS"; then
+ pkg_cv_PROTOBUFC_CFLAGS="$PROTOBUFC_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libprotobuf-c\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libprotobuf-c") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_PROTOBUFC_CFLAGS=`$PKG_CONFIG --cflags "libprotobuf-c" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+if test -n "$PROTOBUFC_LIBS"; then
+ pkg_cv_PROTOBUFC_LIBS="$PROTOBUFC_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libprotobuf-c\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "libprotobuf-c") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_PROTOBUFC_LIBS=`$PKG_CONFIG --libs "libprotobuf-c" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
fi
+ if test $_pkg_short_errors_supported = yes; then
+ PROTOBUFC_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libprotobuf-c" 2>&1`
+ else
+ PROTOBUFC_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libprotobuf-c" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ 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"
+ 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
+ fi
+
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing protobuf_c_message_pack" >&5
+elif test $pkg_failed = untried; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "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"
+ 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
+ fi
+
+
+else
+ PROTOBUFC_CFLAGS=$pkg_cv_PROTOBUFC_CFLAGS
+ PROTOBUFC_LIBS=$pkg_cv_PROTOBUFC_LIBS
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+ CFLAGS="$CFLAGS $PROTOBUFC_CFLAGS"
+ LIBS="$LIBS $PROTOBUFC_LIBS"
+
+fi
+
+
+
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing protobuf_c_message_pack" >&5
$as_echo_n "checking for library containing protobuf_c_message_pack... " >&6; }
if ${ac_cv_search_protobuf_c_message_pack+:} false; then :
$as_echo_n "(cached) " >&6
DNSTAP_OBJ="dnstap.lo dnstap.pb-c.lo dnstap_fstrm.lo dtstream.lo"
- else
+ else
ENABLE_DNSTAP=0
- fi
+ fi
# check for dnscrypt if requested
-version=1.19.2
+version=1.19.3
date=`date +'%b %e, %Y'`
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by unbound $as_me 1.19.2, which was
+This file was extended by unbound $as_me 1.19.3, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-unbound config.status 1.19.2
+unbound config.status 1.19.3
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
# must be numbers. ac_defun because of later processing
m4_define([VERSION_MAJOR],[1])
m4_define([VERSION_MINOR],[19])
-m4_define([VERSION_MICRO],[2])
+m4_define([VERSION_MICRO],[3])
AC_INIT([unbound],m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]),[unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues],[unbound])
AC_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR])
AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR])
AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO])
LIBUNBOUND_CURRENT=9
-LIBUNBOUND_REVISION=25
+LIBUNBOUND_REVISION=26
LIBUNBOUND_AGE=1
# 1.0.0 had 0:12:0
# 1.0.1 had 0:13:0
# 1.19.0 had 9:23:1
# 1.19.1 had 9:24:1
# 1.19.2 had 9:25:1
+# 1.19.3 had 9:26:1
# Current -- the number of the binary API that we're implementing
# Revision -- which iteration of the implementation of the binary
ACX_LIBTOOL_C_ONLY
# pkg-config is only needed for these options, do not require it otherwise
-if test "$enable_systemd" = "yes" -o "$with_pyunbound" = "yes" -o "$with_pythonmod" = "yes"; then
+if test "$enable_systemd" = "yes" -o "$enable_dnstap" = "yes" -o "$with_pyunbound" = "yes" -o "$with_pythonmod" = "yes"; then
PKG_PROG_PKG_CONFIG
fi
if test "$on_mingw" = yes; then
staticexe="-all-static"
# for static compile, include gdi32 and zlib here.
- if echo $LIBS | grep 'lgdi32' >/dev/null; then
+ if echo "$LIBS" | grep 'lgdi32' >/dev/null; then
:
else
LIBS="$LIBS -lgdi32"
fi
AC_CHECK_LIB([z], [compress], [ LIBS="$LIBS -lz" ])
- LIBS="$LIBS -l:libssp.a"
+ if echo "$LIBS" | grep -e "libssp.a" -e "lssp" >/dev/null; then
+ :
+ else
+ LIBS="$LIBS -l:libssp.a"
+ fi
fi
fi
LIBS="$LIBS -lgdi32"
fi
AC_CHECK_LIB([z], [compress], [ LIBS="$LIBS -lz" ])
- LIBS="$LIBS -l:libssp.a"
+ if echo "$LIBS" | grep -e "libssp.a" -e "lssp" >/dev/null; then
+ :
+ else
+ LIBS="$LIBS -l:libssp.a"
+ fi
fi
fi
#include <windows.h>
])
AC_CHECK_TOOL(WINDRES, windres)
- LIBS="$LIBS -liphlpapi -lcrypt32"
+ if echo "$LIBS" | grep crypt32 >/dev/null; then
+ LIBS="$LIBS -liphlpapi"
+ else
+ LIBS="$LIBS -liphlpapi -lcrypt32"
+ fi
WINAPPS="unbound-service-install.exe unbound-service-remove.exe anchor-update.exe"
AC_SUBST(WINAPPS)
WIN_DAEMON_SRC="winrc/win_svc.c winrc/w_inst.c"
static int
ssl_print_vmsg(RES* ssl, const char* format, va_list args)
{
- char msg[1024];
+ char msg[65535];
vsnprintf(msg, sizeof(msg), format, args);
return ssl_print_text(ssl, msg);
}
do_flush_bogus(ssl, worker);
} else if(cmdcmp(p, "flush_negative", 14)) {
do_flush_negative(ssl, worker);
- } else if(cmdcmp(p, "rpz_enable", 10)) {
- do_rpz_enable(ssl, worker, skipwhite(p+10));
- } else if(cmdcmp(p, "rpz_disable", 11)) {
- do_rpz_disable(ssl, worker, skipwhite(p+11));
+ } else if(cmdcmp(p, "rpz_enable", 10)) {
+ do_rpz_enable(ssl, worker, skipwhite(p+10));
+ } else if(cmdcmp(p, "rpz_disable", 11)) {
+ do_rpz_disable(ssl, worker, skipwhite(p+11));
} else {
(void)ssl_printf(ssl, "error unknown command '%s'\n", p);
}
log_assert(sldns_buffer_limit(c->buffer) >= LDNS_HEADER_SIZE
&& LDNS_QDCOUNT(sldns_buffer_begin(c->buffer)) == 1);
- sldns_buffer_skip(c->buffer, LDNS_HEADER_SIZE); /* skip header */
+ 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
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;
}
worker, repinfo, acladdr, ede, check_result);
}
-/* Returns 1 if the ip rate limit check can happen before EDNS parsing,
- * else 0 */
-static int
-pre_edns_ip_ratelimit_check(enum acl_access acl)
-{
- if(acl == acl_allow_cookie) return 0;
- return 1;
-}
-
/* Check if the query is blocked by source IP rate limiting.
* Returns 1 if it passes the check, 0 otherwise. */
static int
if(worker->dtenv.log_client_query_messages) {
log_addr(VERB_ALGO, "request from client", &repinfo->client_addr, repinfo->client_addrlen);
log_addr(VERB_ALGO, "to local addr", (void*)repinfo->c->socket->addr->ai_addr, repinfo->c->socket->addr->ai_addrlen);
- dt_msg_send_client_query(&worker->dtenv, &repinfo->client_addr, (void*)repinfo->c->socket->addr->ai_addr, c->type, c->buffer,
+ dt_msg_send_client_query(&worker->dtenv, &repinfo->client_addr, (void*)repinfo->c->socket->addr->ai_addr, c->type, c->ssl, c->buffer,
((worker->env.cfg->sock_queue_timeout && timeval_isset(&c->recv_tv))?&c->recv_tv:NULL));
}
#endif
}
worker->stats.num_queries++;
- pre_edns_ip_ratelimit = pre_edns_ip_ratelimit_check(acl);
+ pre_edns_ip_ratelimit = !worker->env.cfg->do_answer_cookie
+ || sldns_buffer_limit(c->buffer) < LDNS_HEADER_SIZE
+ || LDNS_ARCOUNT(sldns_buffer_begin(c->buffer)) == 0;
/* If the IP rate limiting check needs extra EDNS information (e.g.,
* DNS Cookies) postpone the check until after EDNS is parsed. */
if(worker->dtenv.log_client_response_messages) {
log_addr(VERB_ALGO, "from local addr", (void*)repinfo->c->socket->addr->ai_addr, repinfo->c->socket->addr->ai_addrlen);
log_addr(VERB_ALGO, "response to client", &repinfo->client_addr, repinfo->client_addrlen);
- dt_msg_send_client_response(&worker->dtenv, &repinfo->client_addr, (void*)repinfo->c->socket->addr->ai_addr, c->type, c->buffer);
+ dt_msg_send_client_response(&worker->dtenv, &repinfo->client_addr, (void*)repinfo->c->socket->addr->ai_addr, c->type, c->ssl, c->buffer);
}
#endif
if(worker->env.cfg->log_replies)
qinfo.qname = qinfo.local_alias->rrset->rk.dname;
log_reply_info(NO_VERBOSE, &qinfo,
&repinfo->client_addr, repinfo->client_addrlen,
- tv, 1, c->buffer);
+ tv, 1, c->buffer,
+ (worker->env.cfg->log_destaddr?(void*)repinfo->c->socket->addr->ai_addr:NULL),
+ c->type);
} else {
log_reply_info(NO_VERBOSE, &qinfo,
&repinfo->client_addr, repinfo->client_addrlen,
- tv, 1, c->buffer);
+ tv, 1, c->buffer,
+ (worker->env.cfg->log_destaddr?(void*)repinfo->c->socket->addr->ai_addr:NULL),
+ c->type);
}
}
#ifdef USE_DNSCRYPT
struct sockaddr_storage *qs,
struct sockaddr_storage *rs,
enum comm_point_type cptype,
+ void *cpssl,
ProtobufCBinaryData *qaddr, protobuf_c_boolean *has_qaddr,
uint32_t *qport, protobuf_c_boolean *has_qport,
ProtobufCBinaryData *raddr, protobuf_c_boolean *has_raddr,
*has_rport = 1;
}
- log_assert(cptype == comm_udp || cptype == comm_tcp);
if (cptype == comm_udp) {
/* socket_protocol */
dm->m.socket_protocol = DNSTAP__SOCKET_PROTOCOL__UDP;
dm->m.has_socket_protocol = 1;
} else if (cptype == comm_tcp) {
+ if (cpssl == NULL) {
+ /* socket_protocol */
+ dm->m.socket_protocol = DNSTAP__SOCKET_PROTOCOL__TCP;
+ dm->m.has_socket_protocol = 1;
+ } else {
+ /* socket_protocol */
+ dm->m.socket_protocol = DNSTAP__SOCKET_PROTOCOL__DOT;
+ dm->m.has_socket_protocol = 1;
+ }
+ } else if (cptype == comm_http) {
/* socket_protocol */
+ dm->m.socket_protocol = DNSTAP__SOCKET_PROTOCOL__DOH;
+ dm->m.has_socket_protocol = 1;
+ } else {
+ /* other socket protocol */
dm->m.socket_protocol = DNSTAP__SOCKET_PROTOCOL__TCP;
dm->m.has_socket_protocol = 1;
}
struct sockaddr_storage *qsock,
struct sockaddr_storage *rsock,
enum comm_point_type cptype,
+ void *cpssl,
sldns_buffer *qmsg,
struct timeval* tstamp)
{
dt_fill_buffer(qmsg, &dm.m.query_message, &dm.m.has_query_message);
/* socket_family, socket_protocol, query_address, query_port, response_address, response_port */
- log_assert(cptype == comm_udp || cptype == comm_tcp);
- dt_msg_fill_net(&dm, qsock, rsock, cptype,
+ dt_msg_fill_net(&dm, qsock, rsock, cptype, cpssl,
&dm.m.query_address, &dm.m.has_query_address,
&dm.m.query_port, &dm.m.has_query_port,
&dm.m.response_address, &dm.m.has_response_address,
struct sockaddr_storage *qsock,
struct sockaddr_storage *rsock,
enum comm_point_type cptype,
+ void *cpssl,
sldns_buffer *rmsg)
{
struct dt_msg dm;
dt_fill_buffer(rmsg, &dm.m.response_message, &dm.m.has_response_message);
/* socket_family, socket_protocol, query_address, query_port, response_address, response_port */
- log_assert(cptype == comm_udp || cptype == comm_tcp);
- dt_msg_fill_net(&dm, qsock, rsock, cptype,
+ dt_msg_fill_net(&dm, qsock, rsock, cptype, cpssl,
&dm.m.query_address, &dm.m.has_query_address,
&dm.m.query_port, &dm.m.has_query_port,
&dm.m.response_address, &dm.m.has_response_address,
struct sockaddr_storage *rsock,
struct sockaddr_storage *qsock,
enum comm_point_type cptype,
+ void *cpssl,
uint8_t *zone, size_t zone_len,
sldns_buffer *qmsg)
{
dt_fill_buffer(qmsg, &dm.m.query_message, &dm.m.has_query_message);
/* socket_family, socket_protocol, response_address, response_port, query_address, query_port */
- log_assert(cptype == comm_udp || cptype == comm_tcp);
- dt_msg_fill_net(&dm, rsock, qsock, cptype,
+ dt_msg_fill_net(&dm, rsock, qsock, cptype, cpssl,
&dm.m.response_address, &dm.m.has_response_address,
&dm.m.response_port, &dm.m.has_response_port,
&dm.m.query_address, &dm.m.has_query_address,
struct sockaddr_storage *rsock,
struct sockaddr_storage *qsock,
enum comm_point_type cptype,
+ void *cpssl,
uint8_t *zone, size_t zone_len,
uint8_t *qbuf, size_t qbuf_len,
const struct timeval *qtime,
dt_fill_buffer(rmsg, &dm.m.response_message, &dm.m.has_response_message);
/* socket_family, socket_protocol, response_address, response_port, query_address, query_port */
- log_assert(cptype == comm_udp || cptype == comm_tcp);
- dt_msg_fill_net(&dm, rsock, qsock, cptype,
+ dt_msg_fill_net(&dm, rsock, qsock, cptype, cpssl,
&dm.m.response_address, &dm.m.has_response_address,
&dm.m.response_port, &dm.m.has_response_port,
&dm.m.query_address, &dm.m.has_query_address,
// with this file. If not, see:
//
// <http://creativecommons.org/publicdomain/zero/1.0/>.
-syntax = "proto2";
+syntax = "proto2";
package dnstap;
// "Dnstap": this is the top-level dnstap type, which is a "union" type that
INET6 = 2; // IPv6 (RFC 2460)
}
-// SocketProtocol: the transport protocol of a socket. This specifies how to
-// interpret "transport port" fields.
+// SocketProtocol: the protocol used to transport a DNS message.
enum SocketProtocol {
- UDP = 1; // User Datagram Protocol (RFC 768)
- TCP = 2; // Transmission Control Protocol (RFC 793)
+ UDP = 1; // DNS over UDP transport (RFC 1035 section 4.2.1)
+ TCP = 2; // DNS over TCP transport (RFC 1035 section 4.2.2)
+ DOT = 3; // DNS over TLS (RFC 7858)
+ DOH = 4; // DNS over HTTPS (RFC 8484)
+ DNSCryptUDP = 5; // DNSCrypt over UDP (https://dnscrypt.info/protocol)
+ DNSCryptTCP = 6; // DNSCrypt over TCP (https://dnscrypt.info/protocol)
+ DOQ = 7; // DNS over QUIC (RFC 9250)
+}
+
+// Policy: information about any name server operator policy
+// applied to the processing of a DNS message.
+message Policy {
+
+ // Match: what aspect of the message or message exchange
+ // triggered the application of the Policy.
+ enum Match {
+ QNAME = 1; // Name in question section of query
+ CLIENT_IP = 2; // Client IP address
+ RESPONSE_IP = 3; // Address in A/AAAA RRSet
+ NS_NAME = 4; // Authoritative name server, by name
+ NS_IP = 5; // Authoritative name server, by IP address
+ }
+
+ // The Action taken to implement the Policy.
+ enum Action {
+ NXDOMAIN = 1; // Respond with NXDOMAIN
+ NODATA = 2; // Respond with empty answer section
+ PASS = 3; // Do not alter the response (passthrough)
+ DROP = 4; // Do not respond.
+ TRUNCATE = 5; // Truncate UDP response, forcing TCP retry
+ LOCAL_DATA = 6; // Respond with local data from policy
+ }
+
+ // type: the type of policy applied, e.g. "RPZ" for a
+ // policy from a Response Policy Zone.
+ optional string type = 1;
+
+ // rule: the rule matched by the message.
+ //
+ // In a RPZ context, this is the owner name of the rule in
+ // the Reponse Policy Zone in wire format.
+ optional bytes rule = 2;
+
+ // action: the policy action taken in response to the
+ // rule match.
+ optional Action action = 3;
+
+ // match: the feature of the message exchange which matched the rule.
+ optional Match match = 4;
+
+ // The matched value. Format depends on the matched feature .
+ optional bytes value = 5;
}
// Message: a wire-format (RFC 1035 section 4) DNS message and associated
// STUB_RESPONSE is a DNS response message sent from a DNS server to a
// stub resolver, from the perspective of the stub resolver.
STUB_RESPONSE = 10;
+
+ // TOOL_QUERY is a DNS query message sent from a DNS software tool to a
+ // DNS server, from the perspective of the tool.
+ TOOL_QUERY = 11;
+
+ // TOOL_RESPONSE is a DNS response message received by a DNS software
+ // tool from a DNS server, from the perspective of the tool.
+ TOOL_RESPONSE = 12;
+
+ // UPDATE_QUERY is a Dynamic DNS Update request (RFC 2136) received
+ // by an authoritative name server, from the perspective of the
+ // authoritative name server.
+ UPDATE_QUERY = 13;
+
+ // UPDATE_RESPONSE is a Dynamic DNS Update response (RFC 2136) sent
+ // from an authoritative name server, from the perspective of the
+ // authoritative name server.
+ UPDATE_RESPONSE = 14;
}
// One of the Type values described above.
// The responder's original wire-format DNS response message, verbatim.
optional bytes response_message = 14;
+
+ // Operator policy applied to the processing of this message, if any.
+ optional Policy policy = 15;
}
// All fields except for 'type' in the Message schema are optional.
// RESOLVER_QUERY:
// socket_family, socket_protocol
-// query_name, query_type, query_class
// query_message
// query_time_sec, query_time_nsec
// query_zone
// RESOLVER_RESPONSE:
// socket_family, socket_protocol
-// query_name, query_type, query_class
// query_time_sec, query_time_nsec
// query_zone
// response_address, response_port
+8 March 2024: Wouter
+ - Fix unbound-control-setup.cmd to use 3072 bits so that certificates
+ are long enough for newer OpenSSL versions.
+ - Fix TTL of synthesized CNAME when a DNAME is used from cache.
+ - Fix unbound-control-setup.cmd to have CA v3 basicConstraints,
+ like unbound-control-setup.sh has.
+
+7 March 2024: Wouter
+ - Version set to 1.19.3 for release. After 1.19.2 point release with
+ security fix for CVE-2024-1931, Denial of service when trimming
+ EDE text on positive replies. The code repo includes the fix and
+ is for version 1.19.3.
+
+5 March 2024: Wouter
+ - Fix for #1022: Fix ede prohibited in access control refused answers.
+
+4 March 2024: Wouter
+ - Fix edns subnet replies for scope zero answers to not get stored
+ in the global cache, and in cachedb, when the upstream replies
+ without an EDNS record.
+
+28 February 2024: Wouter
+ - Move github workflows to use checkoutv4.
+
+23 February 2024: Yorgos
+ - Document the suspend argument for process_ds_response().
+
+22 February 2024: Wouter
+ - Fix trim of EDE text from large udp responses from spinning cpu.
+
+20 February 2024: Yorgos
+ - Merge #1010: Mention REFUSED has the TC bit set with unmatched
+ allow_cookie acl in the manpage. It also fixes the code to match the
+ documentation about clients with a valid cookie that bypass the
+ ratelimit regardless of the allow_cookie acl.
+
+13 February 2024: Wouter
+ - Fix CVE-2023-50387, DNSSEC verification complexity can be exploited
+ to exhaust CPU resources and stall DNS resolvers.
+ - Fix CVE-2023-50868, NSEC3 closest encloser proof can exhaust CPU.
+ - These fixes are part of the 1.19.1 release, that is a security
+ point release on 1.19.0, the code repository continues with these
+ fixes, with version number 1.19.2.
+
+8 February 2024: Wouter
+ - Fix documentation for access-control in the unbound.conf man page.
+
+7 February 2024: Yorgos
+ - Fix #1006: Can't find protobuf-c package since #999.
+
+30 January 2024: Wouter
+ - Merge #999: Search for protobuf-c with pkg-config.
+
+23 January 2024: Yorgos
+ - Update message TTL when using cached RRSETs. It could result in
+ non-expired messages with expired RRSETs (non-usable messages by
+ Unbound).
+
+22 January 2024: Yorgos
+ - Update error printout for duplicate trust anchors to include the
+ trust anchor name (relates to #920).
+
+22 January 2024: Wouter
+ - Fix for #997: Print details for SSL certificate failure.
+
+17 January 2024: Wouter
+ - Update workflow for ports to use newer openssl on windows compile.
+ - Fix warning for windres on resource files due to redefinition.
+
+16 January 2024: Wouter
+ - Fix to link with libssp for libcrypto and getaddrinfo check for
+ only header. Also update crosscompile to remove ssp for 32bit.
+ - Merge #993: Update b.root-servers.net also in example config file.
+
+15 January 2024: Wouter
+ - Fix to link with -lcrypt32 for OpenSSL 3.2.0 on Windows.
+
+9 January 2024: Wouter
+ - Merge #988: Fix NLnetLabs#981: dump_cache truncates large records.
+
+5 January 2024: Wouter
+ - Merge #987: skip edns frag retry if advertised udp payload size is
+ not smaller.
+ - Fix unit test for #987 change in udp1xxx retry packet send.
+
+4 January 2024: Wouter
+ - Remove unneeded newlines and improve indentation in remote control
+ code.
+
+3 January 2024: Wouter
+ - Merge #980: DoH: reject non-h2 early. To fix #979: Improve errors
+ for non-HTTP/2 DoH clients.
+ - Merge #985: Add DoH and DoT to dnstap message.
+ - Fix #983: Sha1 runtime insecure change was incomplete.
+
+22 December 2023: Yorgos
+ - Update example.conf with cookie options.
+
+8 December 2023: Yorgos
+ - Merge PR #973: Use the origin (DNAME) TTL for synthesized CNAMEs as
+ per RFC 6672.
+
+8 December 2023: Wouter
+ - Fix root_zonemd unit test, it checks that the root ZONEMD verifies,
+ now that the root has a valid ZONEMD.
+
+7 December 2023: Wouter
+ - Fix #974: doc: default number of outgoing ports without libevent.
+ - Merge #975: Fixed some syntax errors in rpl files.
+
+6 December 2023: Wouter
+ - Fix to sync the tests script file common.sh.
+ - iana portlist update.
+ - Updated IPv4 and IPv6 address for b.root-servers.net in root hints.
+ - Update test script file common.sh.
+ - Fix tests to use new common.sh functions, wait_logfile and
+ kill_from_pidfile.
+
+5 December 2023: Wouter
+ - Merge #971: fix 'WARNING: Message has 41 extra bytes at end'.
+ - Fix #969: [FR] distinguish Do53, DoT and DoH in the logs.
+ - Fix dnstap that assertion failed on logging other than UDP and TCP
+ traffic. It lists it as TCP traffic.
+
+27 November 2023: Yorgos
+ - Merge #968: Replace the obsolescent fgrep with grep -F in tests.
+
+27 November 2023: Wouter
+ - Fix #964: config.h.in~ backup file in release tar balls.
+
+24 November 2023: Yorgos
+ - Use 127.0.0.1 explicitly in tests to avoid delays and errors on
+ newer systems.
+
+9 November 2023: Wouter
+ - Fix unit test parse of origin syntax.
+
2 November 2023: Wouter
- Set version number to 1.19.0.
- - Tag for 1.19.0rc1 release.
+ - Tag for 1.19.0rc1 release. It became 1.19.0 release on 8 nov 2023.
+ The repository continues with 1.19.1.
1 November 2023: George
- Mention flex and bison in README.md when building from repository
-README for Unbound 1.19.2
+README for Unbound 1.19.3
Copyright 2007 NLnet Labs
http://unbound.net
* Make and install: ./configure; make; make install
* --with-libevent=/path/to/libevent
Can be set to either the system install or the build directory.
- --with-libevent=no (default) gives a builtin alternative
- implementation. libevent is useful when having many (thousands)
- of outgoing ports. This improves randomization and spoof
- resistance. For the default of 16 ports the builtin alternative
- works well and is a little faster.
+ --with-libevent=no gives a builtin alternative implementation.
+ Libevent is enabled by default, it is useful when having many
+ (thousands) of outgoing ports. This improves randomization and spoof
+ resistance. It also allows a higher number of outgoing queries.
* --with-libexpat=/path/to/libexpat
Can be set to the install directory of libexpat.
* --without-pthreads
#
# Example configuration file.
#
-# See unbound.conf(5) man page, version 1.19.2.
+# See unbound.conf(5) man page, version 1.19.3.
#
# this is a comment.
# Choose deny (drop message), refuse (polite error reply),
# allow (recursive ok), allow_setrd (recursive ok, rd bit is forced on),
# allow_snoop (recursive and nonrecursive ok)
+ # allow_cookie (allow UDP with valid cookie or stateful transport)
# deny_non_local (drop queries unless can be answered from local-data)
# refuse_non_local (like deny_non_local but polite error reply).
# access-control: 127.0.0.0/8 allow
# filtering log-queries and log-replies from the log.
# log-tag-queryreply: no
+ # log with destination address, port and type for log-replies.
+ # log-destaddr: no
+
# log the local-zone actions, like local-zone type inform is enabled
# also for the other local zone types.
# log-local-actions: no
# if 0(default) it is disabled, otherwise states qps allowed per ip address
# ip-ratelimit: 0
+ # global query ratelimit for all ip addresses with a valid DNS Cookie.
+ # feature is experimental.
+ # if 0(default) it is disabled, otherwise states qps allowed per ip address
+ # useful in combination with 'allow_cookie'.
+ # If used, suggested to be higher than ip-ratelimit, tenfold.
+ # ip-ratelimit-cookie: 0
+
# ip ratelimits are tracked in a cache, size in bytes of cache (or k,m).
# ip-ratelimit-size: 4m
# ip ratelimit cache slabs, reduces lock contention if equal to cpucount.
# the number of servers that will be used in the fast server selection.
# fast-server-num: 3
+ # reply to requests containing DNS Cookies as specified in RFC 7873 and RFC 9018.
+ # answer-cookie: no
+
+ # secret for DNS Cookie generation.
+ # useful for anycast deployments.
+ # example value "000102030405060708090a0b0c0d0e0f".
+ # cookie-secret: <128 bit random hex string>
+
# Enable to attach Extended DNS Error codes (RFC8914) to responses.
# ede: no
# sources of notifies.
# auth-zone:
# name: "."
-# primary: 199.9.14.201 # b.root-servers.net
+# primary: 170.247.170.2 # b.root-servers.net
# primary: 192.33.4.12 # c.root-servers.net
# primary: 199.7.91.13 # d.root-servers.net
# primary: 192.5.5.241 # f.root-servers.net
# primary: 193.0.14.129 # k.root-servers.net
# primary: 192.0.47.132 # xfr.cjr.dns.icann.org
# primary: 192.0.32.132 # xfr.lax.dns.icann.org
-# primary: 2001:500:200::b # b.root-servers.net
+# primary: 2801:1b8:10::b # b.root-servers.net
# primary: 2001:500:2::c # c.root-servers.net
# primary: 2001:500:2d::d # d.root-servers.net
# primary: 2001:500:2f::f # f.root-servers.net
-.TH "libunbound" "3" "Mar 7, 2024" "NLnet Labs" "unbound 1.19.2"
+.TH "libunbound" "3" "Mar 14, 2024" "NLnet Labs" "unbound 1.19.3"
.\"
.\" libunbound.3 -- unbound library functions manual
.\"
.B ub_ctx_zone_remove,
.B ub_ctx_data_add,
.B ub_ctx_data_remove
-\- Unbound DNS validating resolver 1.19.2 functions.
+\- Unbound DNS validating resolver 1.19.3 functions.
.SH "SYNOPSIS"
.B #include <unbound.h>
.LP
-.TH "unbound-anchor" "8" "Mar 7, 2024" "NLnet Labs" "unbound 1.19.2"
+.TH "unbound-anchor" "8" "Mar 14, 2024" "NLnet Labs" "unbound 1.19.3"
.\"
.\" unbound-anchor.8 -- unbound anchor maintenance utility manual
.\"
-.TH "unbound-checkconf" "8" "Mar 7, 2024" "NLnet Labs" "unbound 1.19.2"
+.TH "unbound-checkconf" "8" "Mar 14, 2024" "NLnet Labs" "unbound 1.19.3"
.\"
.\" unbound-checkconf.8 -- unbound configuration checker manual
.\"
-.TH "unbound-control" "8" "Mar 7, 2024" "NLnet Labs" "unbound 1.19.2"
+.TH "unbound-control" "8" "Mar 14, 2024" "NLnet Labs" "unbound 1.19.3"
.\"
.\" unbound-control.8 -- unbound remote control manual
.\"
-.TH "unbound\-host" "1" "Mar 7, 2024" "NLnet Labs" "unbound 1.19.2"
+.TH "unbound\-host" "1" "Mar 14, 2024" "NLnet Labs" "unbound 1.19.3"
.\"
.\" unbound-host.1 -- unbound DNS lookup utility
.\"
-.TH "unbound" "8" "Mar 7, 2024" "NLnet Labs" "unbound 1.19.2"
+.TH "unbound" "8" "Mar 14, 2024" "NLnet Labs" "unbound 1.19.3"
.\"
.\" unbound.8 -- unbound manual
.\"
.\"
.SH "NAME"
.B unbound
-\- Unbound DNS validating resolver 1.19.2.
+\- Unbound DNS validating resolver 1.19.3.
.SH "SYNOPSIS"
.B unbound
.RB [ \-h ]
-.TH "unbound.conf" "5" "Mar 7, 2024" "NLnet Labs" "unbound 1.19.2"
+.TH "unbound.conf" "5" "Mar 14, 2024" "NLnet Labs" "unbound 1.19.3"
.\"
.\" unbound.conf.5 -- unbound.conf manual
.\"
This option is experimental at this time.
.TP
.B access\-control: \fI<IP netblock> <action>
+Specify treatment of incoming queries from their originating IP address.
+Queries can be allowed to have access to this server that gives DNS
+answers, or refused, with other actions possible. The IP address range
+can be specified as a netblock, it is possible to give the statement
+several times in order to specify the treatment of different netblocks.
+.IP
The netblock is given as an IP4 or IP6 address with /size appended for a
classless network block. The action can be \fIdeny\fR, \fIrefuse\fR,
\fIallow\fR, \fIallow_setrd\fR, \fIallow_snoop\fR, \fIallow_cookie\fR,
also be a valuable debugging tool (when you want to examine the cache
contents). In that case use \fIallow_snoop\fR for your administration host.
.IP
-The \fIallow_cookie\fR action allows access to UDP queries that contain a
+The \fIallow_cookie\fR action allows access only to UDP queries that contain a
valid DNS Cookie as specified in RFC 7873 and RFC 9018, when the
\fBanswer\-cookie\fR option is enabled.
UDP queries containing only a DNS Client Cookie and no Server Cookie, or an
The \fIallow_cookie\fR action will also accept requests over stateful
transports, regardless of the presence of an DNS Cookie and regardless of the
\fBanswer\-cookie\fR setting.
-If \fBip\-ratelimit\fR is used, clients with a valid DNS Cookie will bypass the
-ratelimit.
-If a ratelimit for such clients is still needed, \fBip\-ratelimit\-cookie\fR
-can be used instead.
+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.
The default is \fIrefuse\fRd, because that is protocol\-friendly. The DNS
This makes filtering logs easier. The default is off (for backwards
compatibility).
.TP
+.B log\-destaddr: \fI<yes or no>
+Prints the destination address, port and type in the log\-replies output.
+This disambiguates what type of traffic, eg. udp or tcp, and to what local
+port the traffic was sent to.
+.TP
.B log\-local\-actions: \fI<yes or no>
Print log lines to inform about local zone actions. These lines are like the
local\-zone type inform prints out, but they are also printed for the other
completely dropped and will not receive a reply, SERVFAIL or otherwise.
IP ratelimiting happens before looking in the cache. This may be useful for
mitigating amplification attacks.
+Clients with a valid DNS Cookie will bypass the ratelimit.
+If a ratelimit for such clients is still needed, \fBip\-ratelimit\-cookie\fR
+can be used instead.
Default is 0 (disabled).
.TP 5
.B ip\-ratelimit\-cookie: \fI<number or 0>
fwd_zone_free(z);
fwd_init_parents(fwd);
}
-
dp->has_parent_side_NS = 1;
if(do_ip4) {
if(!ah(dp, "A.ROOT-SERVERS.NET.", "198.41.0.4")) goto failed;
- if(!ah(dp, "B.ROOT-SERVERS.NET.", "199.9.14.201")) goto failed;
+ if(!ah(dp, "B.ROOT-SERVERS.NET.", "170.247.170.2")) goto failed;
if(!ah(dp, "C.ROOT-SERVERS.NET.", "192.33.4.12")) goto failed;
if(!ah(dp, "D.ROOT-SERVERS.NET.", "199.7.91.13")) goto failed;
if(!ah(dp, "E.ROOT-SERVERS.NET.", "192.203.230.10")) goto failed;
}
if(do_ip6) {
if(!ah(dp, "A.ROOT-SERVERS.NET.", "2001:503:ba3e::2:30")) goto failed;
- if(!ah(dp, "B.ROOT-SERVERS.NET.", "2001:500:200::b")) goto failed;
+ if(!ah(dp, "B.ROOT-SERVERS.NET.", "2801:1b8:10::b")) goto failed;
if(!ah(dp, "C.ROOT-SERVERS.NET.", "2001:500:2::c")) goto failed;
if(!ah(dp, "D.ROOT-SERVERS.NET.", "2001:500:2d::d")) goto failed;
if(!ah(dp, "E.ROOT-SERVERS.NET.", "2001:500:a8::e")) goto failed;
hints_stub_free(z);
name_tree_init_parents(&hints->tree);
}
-
sizeof(uint32_t)+sizeof(uint16_t)+aliaslen);
if(!cn->rr_first->ttl_data)
return NULL;
- sldns_write_uint32(cn->rr_first->ttl_data, 0); /* TTL = 0 */
+ memmove(cn->rr_first->ttl_data, rrset->rr_first->ttl_data,
+ sizeof(uint32_t)); /* RFC6672: synth CNAME TTL == DNAME TTL */
sldns_write_uint16(cn->rr_first->ttl_data+4, aliaslen);
memmove(cn->rr_first->ttl_data+6, alias, aliaslen);
cn->rr_first->size = sizeof(uint16_t)+aliaslen;
/* like packet got dropped */
goto handle_it;
}
- if(!inplace_cb_edns_back_parsed_call(qstate->env, qstate)) {
- log_err("unable to call edns_back_parsed callback");
- goto handle_it;
- }
+ }
+ if(!inplace_cb_edns_back_parsed_call(qstate->env, qstate)) {
+ log_err("unable to call edns_back_parsed callback");
+ goto handle_it;
}
/* remove CD-bit, we asked for in case we handle validation ourself */
if(!d)
return 0; /* out of memory */
(*cname)->entry.data = d;
- d->ttl = 0; /* 0 for synthesized CNAME TTL */
+ d->ttl = dname->data->ttl; /* RFC6672: synth CNAME TTL == DNAME TTL */
d->count = 1;
d->rrsig_count = 0;
d->trust = rrset_trust_ans_noAA;
struct regional* region, time_t qstarttime)
{
size_t i;
+ time_t ttl, min_ttl = rep->ttl;
/* see if rrset already exists in cache, if not insert it. */
for(i=0; i<rep->rrset_count; i++) {
rep->ref[i].key = rep->rrsets[i];
case 1: /* ref updated, item inserted */
rep->rrsets[i] = rep->ref[i].key;
}
+ /* 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;
+ rep->prefetch_ttl = PREFETCH_TTL_CALC(rep->ttl);
+ rep->serve_expired_ttl = rep->ttl + SERVE_EXPIRED_TTL;
}
}
if(!newd)
return NULL;
ck->entry.data = newd;
- newd->ttl = 0; /* 0 for synthesized CNAME TTL */
+ newd->ttl = d->ttl - now; /* RFC6672: synth CNAME TTL == DNAME TTL */
newd->count = 1;
newd->rrsig_count = 0;
newd->trust = rrset_trust_ans_noAA;
return 0; /* invalid cname */
if(dname_is_wild(ctarget)) {
/* synthesize cname target */
- struct packed_rrset_data* d;
+ struct packed_rrset_data* d, *lr_d;
/* -3 for wildcard label and root label from qname */
size_t newtargetlen = qinfo->qname_len + ctargetlen - 3;
+ newtargetlen);
if(!d)
return 0; /* out of memory */
+ lr_d = (struct packed_rrset_data*)lr->rrset->entry.data;
qinfo->local_alias->rrset->entry.data = d;
- d->ttl = 0; /* 0 for synthesized CNAME TTL */
+ d->ttl = lr_d->rr_ttl[0]; /* RFC6672-like behavior:
+ synth CNAME TTL uses original TTL*/
d->count = 1;
d->rrsig_count = 0;
d->trust = rrset_trust_ans_noAA;
#include "edns-subnet/subnetmod.h"
#include "edns-subnet/edns-subnet.h"
#endif
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
/**
* Compare two response-ip client info entries for the purpose of mesh state
if(m->s.env->cfg->log_replies) {
log_reply_info(NO_VERBOSE, &m->s.qinfo,
&r->query_reply.client_addr,
- r->query_reply.client_addrlen, duration, 0, r_buffer);
+ r->query_reply.client_addrlen, duration, 0, r_buffer,
+ (m->s.env->cfg->log_destaddr?(void*)r->query_reply.c->socket->addr->ai_addr:NULL),
+ r->query_reply.c->type);
}
}
sldns_buffer tmp;
sldns_buffer_init_frm_data(&tmp, w->pkt, w->pkt_len);
dt_msg_send_outside_query(outnet->dtenv, &w->sq->addr,
- &pend_tcp->pi->addr, comm_tcp, w->sq->zone,
+ &pend_tcp->pi->addr, comm_tcp, NULL, w->sq->zone,
w->sq->zonelen, &tmp);
}
#endif
outnet->dtenv->log_forwarder_query_messages)) {
log_addr(VERB_ALGO, "from local addr", &pend->pc->pif->addr, pend->pc->pif->addrlen);
log_addr(VERB_ALGO, "request to upstream", &pend->addr, pend->addrlen);
- dt_msg_send_outside_query(outnet->dtenv, &pend->addr, &pend->pc->pif->addr, comm_udp,
+ dt_msg_send_outside_query(outnet->dtenv, &pend->addr, &pend->pc->pif->addr, comm_udp, NULL,
pend->sq->zone, pend->sq->zonelen, packet);
}
#endif
sldns_buffer tmp;
sldns_buffer_init_frm_data(&tmp, w->pkt, w->pkt_len);
dt_msg_send_outside_query(sq->outnet->dtenv, &sq->addr,
- &pend->pi->addr, comm_tcp, sq->zone,
+ &pend->pi->addr, comm_tcp, NULL, sq->zone,
sq->zonelen, &tmp);
}
#endif
}
}
+static uint16_t
+serviced_query_udp_size(struct serviced_query* sq, enum serviced_query_status status) {
+ uint16_t udp_size;
+ if(status == serviced_query_UDP_EDNS_FRAG) {
+ if(addr_is_ip6(&sq->addr, sq->addrlen)) {
+ if(EDNS_FRAG_SIZE_IP6 < EDNS_ADVERTISED_SIZE)
+ udp_size = EDNS_FRAG_SIZE_IP6;
+ else udp_size = EDNS_ADVERTISED_SIZE;
+ } else {
+ if(EDNS_FRAG_SIZE_IP4 < EDNS_ADVERTISED_SIZE)
+ udp_size = EDNS_FRAG_SIZE_IP4;
+ else udp_size = EDNS_ADVERTISED_SIZE;
+ }
+ } else {
+ udp_size = EDNS_ADVERTISED_SIZE;
+ }
+ return udp_size;
+}
+
/** put serviced query into a buffer */
static void
serviced_encode(struct serviced_query* sq, sldns_buffer* buff, int with_edns)
edns.opt_list_in = NULL;
edns.opt_list_out = sq->opt_list;
edns.opt_list_inplace_cb_out = NULL;
- if(sq->status == serviced_query_UDP_EDNS_FRAG) {
- if(addr_is_ip6(&sq->addr, sq->addrlen)) {
- if(EDNS_FRAG_SIZE_IP6 < EDNS_ADVERTISED_SIZE)
- edns.udp_size = EDNS_FRAG_SIZE_IP6;
- else edns.udp_size = EDNS_ADVERTISED_SIZE;
- } else {
- if(EDNS_FRAG_SIZE_IP4 < EDNS_ADVERTISED_SIZE)
- edns.udp_size = EDNS_FRAG_SIZE_IP4;
- else edns.udp_size = EDNS_ADVERTISED_SIZE;
- }
- } else {
- edns.udp_size = EDNS_ADVERTISED_SIZE;
- }
+ edns.udp_size = serviced_query_udp_size(sq, sq->status);
edns.bits = 0;
if(sq->dnssec & EDNS_DO)
edns.bits = EDNS_DO;
log_addr(VERB_ALGO, "response from upstream", &sq->addr, sq->addrlen);
log_addr(VERB_ALGO, "to local addr", &pi->addr, pi->addrlen);
dt_msg_send_outside_response(sq->outnet->dtenv, &sq->addr,
- &pi->addr, c->type, sq->zone, sq->zonelen, sq->qbuf,
+ &pi->addr, c->type, c->ssl, sq->zone, sq->zonelen, sq->qbuf,
sq->qbuflen, &sq->last_sent_time, sq->outnet->now_tv,
c->buffer);
}
sq->pending = NULL; /* removed after callback */
if(error == NETEVENT_TIMEOUT) {
- if(sq->status == serviced_query_UDP_EDNS && sq->last_rtt < 5000) {
+ if(sq->status == serviced_query_UDP_EDNS && sq->last_rtt < 5000 &&
+ (serviced_query_udp_size(sq, serviced_query_UDP_EDNS_FRAG) < serviced_query_udp_size(sq, serviced_query_UDP_EDNS))) {
/* fallback to 1480/1280 */
sq->status = serviced_query_UDP_EDNS_FRAG;
log_name_addr(VERB_ALGO, "try edns1xx0", sq->qbuf+10,
log_addr(VERB_ALGO, "to local addr", &p->pc->pif->addr,
p->pc->pif->addrlen);
dt_msg_send_outside_response(outnet->dtenv, &sq->addr,
- &p->pc->pif->addr, c->type, sq->zone, sq->zonelen,
+ &p->pc->pif->addr, c->type, c->ssl, sq->zone, sq->zonelen,
sq->qbuf, sq->qbuflen, &sq->last_sent_time,
sq->outnet->now_tv, c->buffer);
}
cfg->log_tag_queryreply = 0;
cfg->log_local_actions = 0;
cfg->log_servfail = 0;
+ cfg->log_destaddr = 0;
#ifndef USE_WINSOCK
# ifdef USE_MINI_EVENT
/* select max 1024 sockets */
else S_YNO("log-tag-queryreply:", log_tag_queryreply)
else S_YNO("log-local-actions:", log_local_actions)
else S_YNO("log-servfail:", log_servfail)
+ else S_YNO("log-destaddr:", log_destaddr)
else S_YNO("val-permissive-mode:", val_permissive_mode)
else S_YNO("aggressive-nsec:", aggressive_nsec)
else S_YNO("ignore-cd-flag:", ignore_cd)
else O_YNO(opt, "log-tag-queryreply", log_tag_queryreply)
else O_YNO(opt, "log-local-actions", log_local_actions)
else O_YNO(opt, "log-servfail", log_servfail)
+ else O_YNO(opt, "log-destaddr", log_destaddr)
else O_STR(opt, "pidfile", pidfile)
else O_YNO(opt, "hide-identity", hide_identity)
else O_YNO(opt, "hide-version", hide_version)
int log_servfail;
/** log identity to report */
char* log_identity;
+ /** log dest addr for log_replies */
+ int log_destaddr;
/** do not report identity (id.server, hostname.bind) */
int hide_identity;
log-tag-queryreply{COLON} { YDVAR(1, VAR_LOG_TAG_QUERYREPLY) }
log-local-actions{COLON} { YDVAR(1, VAR_LOG_LOCAL_ACTIONS) }
log-servfail{COLON} { YDVAR(1, VAR_LOG_SERVFAIL) }
+log-destaddr{COLON} { YDVAR(1, VAR_LOG_DESTADDR) }
local-zone{COLON} { YDVAR(2, VAR_LOCAL_ZONE) }
local-data{COLON} { YDVAR(1, VAR_LOCAL_DATA) }
local-data-ptr{COLON} { YDVAR(1, VAR_LOCAL_DATA_PTR) }
%token VAR_INTERFACE_TAG_ACTION VAR_INTERFACE_TAG_DATA
%token VAR_PROXY_PROTOCOL_PORT VAR_STATISTICS_INHIBIT_ZERO
%token VAR_HARDEN_UNKNOWN_ADDITIONAL VAR_DISABLE_EDNS_DO VAR_CACHEDB_NO_STORE
+%token VAR_LOG_DESTADDR
%%
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
server_tcp_reuse_timeout | server_tcp_auth_query_timeout |
server_interface_automatic_ports | server_ede |
server_proxy_protocol_port | server_statistics_inhibit_zero |
- server_harden_unknown_additional | server_disable_edns_do
+ server_harden_unknown_additional | server_disable_edns_do |
+ server_log_destaddr
;
stubstart: VAR_STUB_ZONE
{
free($2);
}
;
+server_log_destaddr: VAR_LOG_DESTADDR STRING_ARG
+ {
+ OUTYY(("P(server_log_destaddr:%s)\n", $2));
+ if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
+ yyerror("expected yes or no.");
+ else cfg_parser->cfg->log_destaddr = (strcmp($2, "yes")==0);
+ free($2);
+ }
+ ;
server_log_local_actions: VAR_LOG_LOCAL_ACTIONS STRING_ARG
{
OUTYY(("P(server_log_local_actions:%s)\n", $2));
void
log_reply_info(enum verbosity_value v, struct query_info *qinf,
struct sockaddr_storage *addr, socklen_t addrlen, struct timeval dur,
- int cached, struct sldns_buffer *rmsg)
+ int cached, struct sldns_buffer *rmsg, struct sockaddr_storage* daddr,
+ enum comm_point_type tp)
{
char qname_buf[LDNS_MAX_DOMAINLEN+1];
char clientip_buf[128];
char rcode_buf[16];
char type_buf[16];
char class_buf[16];
+ char dest_buf[160];
size_t pktlen;
uint16_t rcode = FLAGS_GET_RCODE(sldns_buffer_read_u16_at(rmsg, 2));
sldns_wire2str_rcode_buf((int)rcode, rcode_buf, sizeof(rcode_buf));
addr_to_str(addr, addrlen, clientip_buf, sizeof(clientip_buf));
+ if(daddr) {
+ char da[128];
+ int port = 0;
+ char* comm;
+ if(daddr->ss_family == AF_INET6) {
+ struct sockaddr_in6 *d = (struct sockaddr_in6 *)daddr;
+ if(inet_ntop(d->sin6_family, &d->sin6_addr, da,
+ sizeof(*d)) == 0)
+ snprintf(dest_buf, sizeof(dest_buf),
+ "(inet_ntop_error)");
+ port = ntohs(d->sin6_port);
+ } else if(daddr->ss_family == AF_INET) {
+ struct sockaddr_in *d = (struct sockaddr_in *)daddr;
+ if(inet_ntop(d->sin_family, &d->sin_addr, da,
+ sizeof(*d)) == 0)
+ snprintf(dest_buf, sizeof(dest_buf),
+ "(inet_ntop_error)");
+ port = ntohs(d->sin_port);
+ } else {
+ snprintf(da, sizeof(da), "socket%d",
+ (int)daddr->ss_family);
+ }
+ comm = "udp";
+ if(tp == comm_tcp) comm = "tcp";
+ else if(tp == comm_tcp_accept) comm = "tcp";
+ else if(tp == comm_http) comm = "dot";
+ else if(tp == comm_local) comm = "unix";
+ else if(tp == comm_raw) comm = "raw";
+ snprintf(dest_buf, sizeof(dest_buf), " on %s %s %d",
+ comm, da, port);
+ } else {
+ dest_buf[0]=0;
+ }
if(rcode == LDNS_RCODE_FORMERR)
{
if(LOG_TAG_QUERYREPLY)
- log_reply("%s - - - %s - - - ", clientip_buf, rcode_buf);
- else log_info("%s - - - %s - - - ", clientip_buf, rcode_buf);
+ log_reply("%s - - - %s - - -%s", clientip_buf,
+ rcode_buf, dest_buf);
+ else log_info("%s - - - %s - - -%s", clientip_buf,
+ rcode_buf, dest_buf);
} else {
if(qinf->qname)
dname_str(qinf->qname, qname_buf);
sldns_wire2str_type_buf(qinf->qtype, type_buf, sizeof(type_buf));
sldns_wire2str_class_buf(qinf->qclass, class_buf, sizeof(class_buf));
if(LOG_TAG_QUERYREPLY)
- log_reply("%s %s %s %s %s " ARG_LL "d.%6.6d %d %d",
+ log_reply("%s %s %s %s %s " ARG_LL "d.%6.6d %d %d%s",
clientip_buf, qname_buf, type_buf, class_buf,
- rcode_buf, (long long)dur.tv_sec, (int)dur.tv_usec, cached, (int)pktlen);
- else log_info("%s %s %s %s %s " ARG_LL "d.%6.6d %d %d",
+ rcode_buf, (long long)dur.tv_sec, (int)dur.tv_usec,
+ cached, (int)pktlen, dest_buf);
+ else log_info("%s %s %s %s %s " ARG_LL "d.%6.6d %d %d%s",
clientip_buf, qname_buf, type_buf, class_buf,
- rcode_buf, (long long)dur.tv_sec, (int)dur.tv_usec, cached, (int)pktlen);
+ rcode_buf, (long long)dur.tv_sec, (int)dur.tv_usec,
+ cached, (int)pktlen, dest_buf);
}
}
struct rrset_parse;
struct local_rrset;
struct dns_msg;
+enum comm_point_type;
/** calculate the prefetch TTL as 90% of original. Calculation
* without numerical overflow (uin32_t) */
* @param cached: whether or not the reply is coming from
* the cache, or an outside network.
* @param rmsg: sldns buffer packet.
+ * @param daddr: if not NULL, the destination address and port are logged.
+ * @param tp: type of the comm point for logging destination connection type.
*/
void log_reply_info(enum verbosity_value v, struct query_info *qinf,
struct sockaddr_storage *addr, socklen_t addrlen, struct timeval dur,
- int cached, struct sldns_buffer *rmsg);
+ int cached, struct sldns_buffer *rmsg, struct sockaddr_storage* daddr,
+ enum comm_point_type tp);
/**
* Print string with neat domain name, type, class from query info.
struct packed_rrset_data* d = (struct packed_rrset_data*)rrset->
entry.data;
uint8_t rr[65535];
+ size_t wlen;
size_t rlen = rrset->rk.dname_len + 2 + 2 + 4 + d->rr_len[i];
time_t adjust = 0;
log_assert(dest_len > 0 && dest);
sldns_write_uint32(rr+rrset->rk.dname_len+4,
(uint32_t)(d->rr_ttl[i]-adjust));
memmove(rr+rrset->rk.dname_len+8, d->rr_data[i], d->rr_len[i]);
- if(sldns_wire2str_rr_buf(rr, rlen, dest, dest_len) == -1) {
+ wlen = (size_t)sldns_wire2str_rr_buf(rr, rlen, dest, dest_len);
+ if(wlen >= dest_len) {
+ /* the output string was truncated */
log_info("rrbuf failure %d %s", (int)d->rr_len[i], dest);
dest[0] = 0;
return 0;
356,
357,
358,
-359,
360,
361,
362,
} else {
unsigned long err = ERR_get_error();
if(!squelch_err_ssl_handshake(err)) {
+ long vr;
log_crypto_err_io_code("ssl handshake failed",
want, err);
+ if((vr=SSL_get_verify_result(c->ssl)) != 0)
+ log_err("ssl handshake cert error: %s",
+ X509_verify_cert_error_string(
+ vr));
log_addr(VERB_OPS, "ssl handshake failed",
&c->repinfo.remote_addr,
c->repinfo.remote_addrlen);
/* connection upgraded to HTTP2 */
c->tcp_do_toggle_rw = 0;
c->use_h2 = 1;
+ } else {
+ verbose(VERB_ALGO, "client doesn't support HTTP/2");
+ return 0;
}
}
#endif
if(repinfo->c->dtenv != NULL && repinfo->c->dtenv->log_client_response_messages) {
log_addr(VERB_ALGO, "from local addr", (void*)repinfo->c->socket->addr->ai_addr, repinfo->c->socket->addr->ai_addrlen);
log_addr(VERB_ALGO, "response to client", &repinfo->client_addr, repinfo->client_addrlen);
- dt_msg_send_client_response(repinfo->c->dtenv, &repinfo->client_addr, (void*)repinfo->c->socket->addr->ai_addr, repinfo->c->type, repinfo->c->buffer);
+ dt_msg_send_client_response(repinfo->c->dtenv, &repinfo->client_addr, (void*)repinfo->c->socket->addr->ai_addr, repinfo->c->type, repinfo->c->ssl, repinfo->c->buffer);
}
#endif
} else {
if(repinfo->c->tcp_parent->dtenv != NULL && repinfo->c->tcp_parent->dtenv->log_client_response_messages) {
log_addr(VERB_ALGO, "from local addr", (void*)repinfo->c->socket->addr->ai_addr, repinfo->c->socket->addr->ai_addrlen);
log_addr(VERB_ALGO, "response to client", &repinfo->client_addr, repinfo->client_addrlen);
- dt_msg_send_client_response(repinfo->c->tcp_parent->dtenv, &repinfo->client_addr, (void*)repinfo->c->socket->addr->ai_addr, repinfo->c->type,
+ dt_msg_send_client_response(repinfo->c->tcp_parent->dtenv, &repinfo->client_addr, (void*)repinfo->c->socket->addr->ai_addr, repinfo->c->type, repinfo->c->ssl,
( repinfo->c->tcp_req_info? repinfo->c->tcp_req_info->spool_buffer: repinfo->c->buffer ));
}
#endif
lock_basic_lock(&anchors->lock);
if(!rbtree_insert(anchors->tree, &tp->node)) {
+ char buf[LDNS_MAX_DOMAINLEN+1];
lock_basic_unlock(&anchors->lock);
- log_err("trust anchor presented twice");
+ dname_str(tp->name, buf);
+ log_err("trust anchor for '%s' presented twice", buf);
free(tp->name);
free(tp->autr);
free(tp);
return NULL;
}
if(!rbtree_insert(&anchors->autr->probe, &tp->autr->pnode)) {
+ char buf[LDNS_MAX_DOMAINLEN+1];
(void)rbtree_delete(anchors->tree, tp);
lock_basic_unlock(&anchors->lock);
- log_err("trust anchor in probetree twice");
+ dname_str(tp->name, buf);
+ log_err("trust anchor for '%s' in probetree twice", buf);
free(tp->name);
free(tp->autr);
free(tp);
return sec_status_bogus;
}
}
- verbose(VERB_ALGO, "rrset failed to verify: all signatures are bogus");
if(!numchecked) {
*reason = "signature for expected key and algorithm missing";
if(reason_bogus)
*reason = "algorithm refused by cryptolib";
return sec_status_indeterminate;
}
+ verbose(VERB_ALGO, "rrset failed to verify: all signatures are bogus");
return sec_status_bogus;
}
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)
+ sldns_ede_code *reason_bogus, struct module_qstate* qstate,
+ int *nonechecked)
{
enum sec_status sec = sec_status_bogus;
size_t i, num, numchecked = 0, numhashok = 0, numsizesupp = 0;
num = rrset_get_count(dnskey_rrset);
+ *nonechecked = 0;
for(i=0; i<num; i++) {
/* Skip DNSKEYs that don't match the basic criteria. */
if(ds_get_key_algo(ds_rrset, ds_idx)
/* there is a working DS, but that DNSKEY is not supported */
return sec_status_insecure;
}
- if(numchecked == 0)
+ if(numchecked == 0) {
algo_needs_reason(env, ds_get_key_algo(ds_rrset, ds_idx),
reason, "no keys have a DS");
- else if(numhashok == 0)
+ *nonechecked = 1;
+ } else if(numhashok == 0) {
*reason = "DS hash mismatches key";
- else if(!*reason)
+ } else if(!*reason) {
*reason = "keyset not secured by DNSKEY that matches DS";
+ }
return sec_status_bogus;
}
{
/* as long as this is false, we can consider this DS rrset to be
* equivalent to no DS rrset. */
- int has_useful_ds = 0, digest_algo, alg;
+ int has_useful_ds = 0, digest_algo, alg, has_algo_refusal = 0,
+ nonechecked, has_checked_ds = 0;
struct algo_needs needs;
size_t i, num;
enum sec_status sec;
}
sec = verify_dnskeys_with_ds_rr(env, ve, dnskey_rrset,
- ds_rrset, i, reason, reason_bogus, qstate);
- if(sec == sec_status_insecure)
+ ds_rrset, i, reason, reason_bogus, qstate,
+ &nonechecked);
+ if(sec == sec_status_insecure) {
+ /* DNSKEY too large unsupported or algo refused by
+ * crypto lib. */
+ has_algo_refusal = 1;
continue;
+ }
+ if(!nonechecked)
+ has_checked_ds = 1;
/* Once we see a single DS with a known digestID and
* algorithm, we cannot return INSECURE (with a
/* None of the DS's worked out. */
+ /* If none of the DSes have been checked, eg. that means no matches
+ * for keytags, and the other dses are all algo_refusal, it is an
+ * insecure delegation point, since the only matched DS records
+ * have an algo refusal, or are unsupported. */
+ if(has_algo_refusal && !has_checked_ds) {
+ verbose(VERB_ALGO, "No supported DS records were found -- "
+ "treating as insecure.");
+ return sec_status_insecure;
+ }
/* If no DSs were understandable, then this is OK. */
if(!has_useful_ds) {
verbose(VERB_ALGO, "No usable DS records were found -- "
{
/* as long as this is false, we can consider this anchor to be
* equivalent to no anchor. */
- int has_useful_ta = 0, digest_algo = 0, alg;
+ int has_useful_ta = 0, digest_algo = 0, alg, has_algo_refusal = 0,
+ nonechecked, has_checked_ds = 0;
struct algo_needs needs;
size_t i, num;
enum sec_status sec;
continue;
sec = verify_dnskeys_with_ds_rr(env, ve, dnskey_rrset,
- ta_ds, i, reason, reason_bogus, qstate);
- if(sec == sec_status_insecure)
+ ta_ds, i, reason, reason_bogus, qstate, &nonechecked);
+ if(sec == sec_status_insecure) {
+ has_algo_refusal = 1;
continue;
+ }
+ if(!nonechecked)
+ has_checked_ds = 1;
/* Once we see a single DS with a known digestID and
* algorithm, we cannot return INSECURE (with a
}
}
+ /* If none of the DSes have been checked, eg. that means no matches
+ * for keytags, and the other dses are all algo_refusal, it is an
+ * insecure delegation point, since the only matched DS records
+ * have an algo refusal, or are unsupported. */
+ if(has_algo_refusal && !has_checked_ds) {
+ verbose(VERB_ALGO, "No supported trust anchors were found -- "
+ "treating as insecure.");
+ return sec_status_insecure;
+ }
/* If no DSs were understandable, then this is OK. */
if(!has_useful_ta) {
verbose(VERB_ALGO, "No usable trust anchors were found -- "
* @param msg: result message (if rcode is OK).
* @param qinfo: from the sub query state, query info.
* @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.
*/
static void
process_ds_response(struct module_qstate* qstate, struct val_qstate* vq,