pbtag
pcall
PCDNSSEC
-PCKS
PCmissing
pcomp
pcount
Meerwald
Mekking
memlock
-MEMLOCK
Memusage
menuselection
metadatabase
taskqueue
tbhandler
tcely
+TCounters
tcp
tcpconnecttimeouts
tcpdump
tsigkey
tsigname
tsigsecret
+Tsinghua
tstamp
TSU
ttls
Xek
Xeon
XForwarded
+Xiang
xorbooter
xpf
XRecord
XXXXXX
yahttp
Yehuda
+yeswehack
Yiu
Ylitalo
yml
- ubuntu-kinetic
- ubuntu-lunar
- debian-bookworm
+ - amazon-2023
fail-fast: false
steps:
- uses: actions/checkout@v3
Yes We Hack
-----------
Security issues can also be reported on [our YesWeHack page](https://yeswehack.com/programs/powerdns) and might fetch a bounty.
-Do note that only the PowerDNS software (PowerDNS Authoritative Server, the PowerDNS Recursor and dnsdist) is in scope for the HackerOne program, not our websites or other infrastructure.
+Do note that only the PowerDNS software (PowerDNS Authoritative Server, the PowerDNS Recursor and dnsdist) is in scope for the YesWeHack program, not our websites or other infrastructure.
Disclosure Policy
-----------------
# Modules
import argparse
+import re
import subprocess
import sys
# Globals
-g_version = '0.0.1'
+g_version = '1.0.2'
g_verbose = False
parser.add_argument('release', metavar='RELEASE',
choices=[# Authoritative Server
'auth-44', 'auth-45', 'auth-46', 'auth-47',
- 'auth-master',
+ 'auth-48', 'auth-master',
# Recursor
- 'rec-45', 'rec-46', 'rec-47', 'rec-48',
+ 'rec-46', 'rec-47', 'rec-48', 'rec-49',
'rec-master',
# DNSDist
'dnsdist-15', 'dnsdist-16', 'dnsdist-17',
if g_verbose:
print("Writing release files...")
- if release in ['auth-44', 'auth-45', 'auth-46', 'auth-47',
+ if release in ['auth-44', 'auth-45', 'auth-46', 'auth-47', 'auth-48',
'auth-master',
- 'rec-45', 'rec-46', 'rec-47', 'rec-48',
+ 'rec-46', 'rec-47', 'rec-48', 'rec-49',
'rec-master',
'dnsdist-15', 'dnsdist-16', 'dnsdist-17', 'dnsdist-18',
'dnsdist-master']:
write_dockerfile('el', '8', release)
write_dockerfile('debian', 'buster', release)
write_list_file('debian', 'buster', release)
- write_dockerfile('ubuntu', 'bionic', release)
- write_list_file('ubuntu', 'bionic', release)
write_dockerfile('ubuntu', 'focal', release)
write_list_file('ubuntu', 'focal', release)
write_dockerfile('raspbian', 'buster', release)
write_list_file('raspbian', 'buster', release)
- if release in ['auth-46', 'auth-47', 'auth-master',
- 'rec-45', 'rec-46', 'rec-47', 'rec-48', 'rec-master',
+ if release in ['auth-46', 'auth-47', 'auth-48', 'auth-master',
+ 'rec-46', 'rec-47', 'rec-48', 'rec-49', 'rec-master',
'dnsdist-16', 'dnsdist-17', 'dnsdist-18', 'dnsdist-master']:
write_dockerfile('debian', 'bullseye', release)
write_list_file('debian', 'bullseye', release)
if release in ['auth-46', 'auth-47', 'auth-master',
- 'rec-46', 'rec-47', 'rec-48', 'rec-master',
+ 'rec-46', 'rec-47', 'rec-48', 'rec-49', 'rec-master',
+ 'dnsdist-15', 'dnsdist-16', 'dnsdist-17', 'dnsdist-master']:
+ write_dockerfile('ubuntu', 'bionic', release)
+ write_list_file('ubuntu', 'bionic', release)
+
+ if release in ['auth-46', 'auth-47', 'auth-48', 'auth-master',
+ 'rec-46', 'rec-47', 'rec-48', 'rec-49', 'rec-master',
'dnsdist-17', 'dnsdist-18', 'dnsdist-master']:
write_dockerfile('ubuntu', 'jammy', release)
write_list_file('ubuntu', 'jammy', release)
- if release in ['auth-47', 'auth-master',
- 'rec-47', 'rec-48', 'rec-master',
+ if release in ['auth-47', 'auth-48', 'auth-master',
+ 'rec-47', 'rec-48', 'rec-49', 'rec-master',
'dnsdist-17', 'dnsdist-18', 'dnsdist-master']:
write_dockerfile('el', '9', release)
capture_run_output = not(g_verbose)
print('Running Docker container tagged {}...'.format(tag))
cp = subprocess.run(['docker', 'run', tag],
- capture_output=capture_run_output)
+ stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ version = re.search('(PowerDNS Authoritative Server|PowerDNS Recursor|' +
+ 'dnsdist) (\d+\.\d+\.\d+(-\w+)?)',
+ cp.stdout.decode())
+ if g_verbose:
+ print(cp.stdout.decode())
# for some reason 99 is returned on `cmd --version` :shrug:
if cp.returncode != 0 and cp.returncode != 99:
# FIXME write failed output to log
print('Error running {}: {}'.format(tag, repr(cp.returncode)))
return cp.returncode
- return cp.returncode
+ if version and version.group(2):
+ return cp.returncode, version.group(2)
+ else:
+ return cp.returncode, None
def collect_dockerfiles (release):
dockerfiles = sorted(collect_dockerfiles(release))
failed_builds = []
failed_runs = []
+ returned_versions = []
print('=== testing {} ==='.format(release))
for df in dockerfiles:
if g_verbose:
print('Skipping running {} due to undetermined tag.'.format(df))
failed_builds.append((str(df), returncode))
else:
- returncode = run(tag)
- # for some reason 99 is returned on `cmd --version` :shrug:
+ (returncode, return_version) = run(tag)
+ # for some reason 99 is returned on `cmd --version` :shrug:
+ # (not sure if this is true since using `stdout=PIPE...`)
if returncode != 0 and returncode != 99:
failed_runs.append((tag, returncode))
+ if return_version:
+ returned_versions.append((tag, return_version))
print('Test done.')
if len(failed_builds) > 0:
print('- failed builds:')
print('- failed runs:')
for fr in failed_runs:
print(' - {}'.format(fr))
+ if len(returned_versions) > 0:
+ print('- returned versions:')
+ for rv in returned_versions:
+ print(' - {}: {}'.format(rv[0], rv[1]))
+ else:
+ print('- ERROR: no returned versions (unsupported product?)')
# Main Program
numdomains="$1"
fi
+if false; then
set +x
for prefix in 'www' 'wildcard'; do
+ rm -f ${prefix}.csv
for num in $(seq 0 1000000); do
echo "${num},${prefix}.powerdnssec.org" >> ${prefix}.csv
done
done
set -x
+fi
EXIT=0
+++ /dev/null
-See /usr/share/doc/quilt/README.source
--- /dev/null
+#!/bin/bash
+
+if [ "$1" = "--cflags" ]; then
+ FLAGS=$(/usr/bin/net-snmp-config --cflags)
+ MYFLAGS=""
+ for flag in $FLAGS; do
+ if [[ "$flag" =~ -DNETSNMP* ]]; then
+ MYFLAGS="$MYFLAGS $flag"
+ fi
+ done
+ echo "$MYFLAGS"
+ exit 0
+
+elif [ "$1" = "--netsnmp-agent-libs" ]; then
+ /usr/bin/net-snmp-config "$@"
+ exit $?
+
+else
+ echo "E: debian/configure-helpers/net-snmp-config: unknown flag $1" >&2
+ exit 1
+fi
Source: pdns-recursor
Section: net
-Priority: extra
-Standards-Version: 4.1.2
-Maintainer: PowerDNS.COM BV <powerdns.support@powerdns.com>
+Maintainer: PowerDNS Autobuilder <powerdns.support@powerdns.com>
+Priority: optional
+Standards-Version: 4.5.1
+Build-Conflicts: libboost-context-dev [mips mipsel]
Build-Depends: debhelper (>= 10),
dh-autoreconf,
- libboost-all-dev,
+ libboost-context-dev [amd64 arm64 armel armhf i386 ppc64el],
+ libboost-dev,
+ libboost-filesystem-dev,
+ libboost-program-options-dev,
+ libboost-system-dev,
+ libboost-test-dev,
+ libboost-thread-dev,
libcap-dev,
libcurl4-openssl-dev,
- libluajit-5.1-dev [!arm64 !s390x],
- liblua5.3-dev [arm64 s390x],
libfstrm-dev,
+ libluajit-5.1-dev (>= 2.1.0~beta3+dfsg-5.3) [amd64 arm64] | libluajit-5.1-dev [amd64] | liblua5.3-dev,
+ libprotobuf-dev,
libsnmp-dev,
libsodium-dev,
libssl-dev,
- libsystemd-dev [linux-any],
+ libsystemd-dev,
pkg-config,
+ protobuf-compiler,
ragel,
- systemd [linux-any]
-Vcs-Git: https://anonscm.debian.org/git/pkg-dns/pdns-recursor.git
-Vcs-Browser: https://anonscm.debian.org/cgit/pkg-dns/pdns-recursor.git
+ systemd
Homepage: https://www.powerdns.com/
+Rules-Requires-Root: no
Package: pdns-recursor
Architecture: any
+Pre-Depends: ${misc:Pre-Depends}
Depends: adduser,
dns-root-data,
${misc:Depends},
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: PowerDNS
Source: https://www.powerdns.com/downloads.html
+Upstream-Contact: https://mailman.powerdns.com/mailman/listinfo/pdns-users
Files: *
Copyright: 2002 - 2022 PowerDNS.COM BV and contributors
Copyright: 2002 - 2004 Wichert Akkermann <wichert@wiggy.net>
2004 - 2013 Matthijs Möhlmann <matthijs@cacholong.nl>
2012 - 2013 Marc Haber <mh+debian-packages@zugschlus.de>
- 2014 - 2016 Chris Hofstaedtler <zeha@debian.org>
- 2016 PowerDNS.COM BV and contributors
+ 2014 - 2018 Chris Hofstaedtler <zeha@debian.org>
+ 2016 - 2018 PowerDNS.COM BV and contributors
License: GPL-2
Files: ext/yahttp/*
+++ /dev/null
-# Variables for PowerDNS recursor init script.
-# Not honored when systemd is the running init.
-#
-# Set START to yes to start the pdns-recursor
-START=yes
-# Run resolvconf? (Deprecated feature.)
-RESOLVCONF=no
+++ /dev/null
-#!/bin/sh
-### BEGIN INIT INFO
-# Provides: pdns-recursor
-# Required-Start: $network $remote_fs $syslog
-# Required-Stop: $network $remote_fs $syslog
-# Default-Start: 2 3 4 5
-# Default-Stop: 0 1 6
-# Short-Description: PowerDNS Recursor - Recursive DNS Server
-# Description: PowerDNS Recursor - Recursive DNS Server
-### END INIT INFO
-
-#
-# Authors: Matthijs Möhlmann <matthijs@cacholong.nl>
-# Christoph Haas <haas@debian.org>
-#
-# Thanks to:
-# Thomas Hood <jdthood@aglu.demon.nl>
-#
-# initscript for PowerDNS recursor
-
-# Load lsb stuff for systemd redirection (if available).
-if [ -e /lib/lsb/init-functions ]; then
- . /lib/lsb/init-functions
-fi
-
-PATH=/sbin:/bin:/usr/sbin:/usr/bin
-DESC="PowerDNS Recursor"
-NAME=pdns_recursor
-DAEMON=/usr/sbin/$NAME
-# Derive the socket-dir setting from /etc/powerdns/recursor.conf
-# or fall back to the default /var/run if not specified there.
-PIDDIR=$(awk -F= '/^socket-dir=/ {print $2}' /etc/powerdns/recursor.conf)
-if [ -z "$PIDDIR" ]; then PIDDIR=/var/run/pdns-recursor; mkdir -p $PIDDIR; fi
-PIDFILE=$PIDDIR/$NAME.pid
-
-# Gracefully exit if the package has been removed.
-test -x $DAEMON || exit 0
-
-# Read config file if it is present.
-if [ -r /etc/default/pdns-recursor ]; then
- . /etc/default/pdns-recursor
-fi
-
-start() {
-# Return
-# 0 if daemon has been started / was already running
-# >0 if daemon could not be started
- start-stop-daemon --start --oknodo --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null || return 0
- start-stop-daemon --start --oknodo --quiet --pidfile $PIDFILE --exec $DAEMON -- --daemon=yes || return 2
-}
-
-start_resolvconf() {
- if [ "X$RESOLVCONF" = "Xyes" ] && [ -x /sbin/resolvconf ]; then
- echo "nameserver 127.0.0.1" | /sbin/resolvconf -a lo.pdns-recursor
- fi
- return 0
-}
-
-stop() {
-# Return
-# 0 if daemon has been stopped
-# 1 if daemon was already stopped
-# 2 if daemon could not be stopped
-# other if a failure occurred
- start-stop-daemon --stop --quiet --pidfile $PIDFILE --name $NAME
- RETVAL="$?"
- [ "$RETVAL" = 2 ] && return 2
- rm -f $PIDFILE
- return "$RETVAL"
-}
-
-stop_resolvconf() {
- if [ "X$RESOLVCONF" = "Xyes" ] && [ -x /sbin/resolvconf ]; then
- /sbin/resolvconf -d lo.pdns-recursor
- fi
- return 0
-}
-
-isrunning()
-{
- /usr/bin/rec_control ping > /dev/null
- return $?
-}
-
-case "$1" in
- start)
- if [ "$START" != "yes" ]; then
- echo "Not starting $DESC -- disabled."
- exit 0
- fi
- echo -n "Starting $DESC: $NAME ..."
- start
- case "$?" in
- 0)
- start_resolvconf
- echo done
- break
- ;;
- 1)
- echo "already running"
- break
- ;;
- *)
- echo "failed"
- exit 1
- ;;
- esac
- ;;
- stop)
- stop_resolvconf
- echo -n "Stopping $DESC: $NAME ..."
- stop
- case "$?" in
- 0)
- echo done
- break
- ;;
- 1)
- echo "not running"
- break
- ;;
- *)
- echo "failed"
- exit 1
- ;;
- esac
- ;;
- restart|force-reload)
- if [ "$START" != "yes" ]; then
- $0 stop
- exit 0
- fi
- echo -n "Restarting $DESC ..."
- stop
- case "$?" in
- 0|1)
- start
- case "$?" in
- 0)
- echo done
- exit 0
- ;;
- 1)
- echo "failed -- old process still running"
- exit 1
- ;;
- *)
- echo "failed to start"
- exit 1
- ;;
- esac
- ;;
- *)
- echo "failed to stop"
- exit 1
- ;;
- esac
- ;;
- status)
- if isrunning; then
- echo "$NAME is running"
- exit 0
- else
- echo "$NAME is not running or not responding"
- exit 3
- fi
- ;;
- *)
- echo "Usage: $0 {start|stop|restart|force-reload|status}" >&2
- exit 3
- ;;
-esac
-
-exit 0
-
# Source carries OpenSSL Exception
pdns-recursor: possible-gpl-code-linked-with-openssl
-# We load lsb-functions conditionally.
-pdns-recursor: init.d-script-needs-depends-on-lsb-base
case "$1" in
configure)
- if [ -z "`getent group pdns`" ]; then
- addgroup --system pdns
- fi
- if [ -z "`getent passwd pdns`" ]; then
- adduser --system --home /var/spool/powerdns --shell /bin/false --ingroup pdns --disabled-password --disabled-login --gecos "PowerDNS" pdns
- fi
- if [ "`stat -c '%U:%G' /etc/powerdns/recursor.conf`" = "root:root" ]; then
- chown root:pdns /etc/powerdns/recursor.conf
- # Make sure that pdns can read it; the default used to be 0600
- chmod g+r /etc/powerdns/recursor.conf
- fi
+ addgroup --system pdns
+ adduser --system --home /var/spool/powerdns --shell /bin/false --ingroup pdns --disabled-password --disabled-login --gecos "PowerDNS" pdns
;;
*)
;;
esac
-# Startup errors should never cause dpkg to fail.
-initscript_error() {
- return 0
-}
-
#DEBHELPER#
exit 0
--- /dev/null
+#!/bin/sh
+set -e
+
+delete_unchanged() {
+ if [ -e "$1" ] && echo "$2 $1" | md5sum --check --status; then
+ echo "Removing unchanged configuration file $1"
+ rm -f "$1"
+ fi
+}
+
+backup_conffile() {
+ if [ -e "$1" ]; then
+ echo "Moving configuration file $1 to $1.dpkg-bak"
+ mv -f "$1" "$1".dpkg-bak
+ fi
+}
+
+case "$1" in
+ install|upgrade)
+ # clean up files we no longer ship
+ delete_unchanged "/etc/default/pdns-recursor" a09916ceb17db9a49ac8cfa84790bf3b
+ delete_unchanged "/etc/default/pdns-recursor" 076b21b9b76d7ffecc918af47d2963c6
+ backup_conffile "/etc/default/pdns-recursor"
+ delete_unchanged "/etc/init.d/pdns-recursor" e2ea0586c3d99fdbafb76483a769b964
+ delete_unchanged "/etc/init.d/pdns-recursor" fb608ec5edc3d068213bac3480782355
+ backup_conffile "/etc/init.d/pdns-recursor"
+ ;;
+esac
+
+#DEBHELPER#
+++ /dev/null
-#!/bin/sh
-set -e
-
-# Startup errors should never cause dpkg to fail.
-initscript_error() {
- return 0
-}
-
-#DEBHELPER#
-
-exit 0
#!/usr/bin/make -f
-include /usr/share/dpkg/architecture.mk
-include /usr/share/dpkg/pkg-info.mk
-# Enable hardening features for daemons
+# Turn on all hardening flags, as we're a networked daemon.
# Note: blhc (build log hardening check) will find these false positives: CPPFLAGS 2 missing, LDFLAGS 1 missing
-export DEB_BUILD_MAINT_OPTIONS=hardening=+bindnow,+pie
+export DEB_BUILD_MAINT_OPTIONS = hardening=+all
+# see EXAMPLES in dpkg-buildflags(1) and read /usr/share/dpkg/*
DPKG_EXPORT_BUILDFLAGS = 1
-# Include buildflags.mk so we can append to the vars it sets.
-include /usr/share/dpkg/buildflags.mk
+include /usr/share/dpkg/default.mk
-# Only enable systemd integration on Linux operating systems
-ifeq ($(DEB_HOST_ARCH_OS),linux)
-CONFIGURE_ARGS += --enable-systemd --with-systemd=/lib/systemd/system
-DH_ARGS += --with systemd
-else
-CONFIGURE_ARGS += --disable-systemd
-endif
-
-# Only disable luajit on arm64
-ifneq ($(DEB_HOST_ARCH),arm64)
-CONFIGURE_ARGS += --with-lua=luajit
-else
-CONFIGURE_ARGS += --with-lua=lua5.3
-endif
-# Use new build system
%:
- dh $@ \
- --with autoreconf \
- $(DH_ARGS)
+ dh $@
+
+override_dh_auto_clean:
+ dh_auto_clean
+ rm -f dnslabeltext.cc
+ chmod +x mkpubsuffixcc || true
override_dh_auto_configure:
- dh_auto_configure -- \
+ PATH=debian/configure-helpers/:$$PATH dh_auto_configure -- \
--sysconfdir=/etc/powerdns \
+ --enable-systemd --with-systemd=/lib/systemd/system \
--enable-unit-tests \
+ --disable-silent-rules \
+ --with-service-user=pdns \
+ --with-service-group=pdns \
--with-libcap \
--with-libsodium \
+ --with-lua \
+ --with-net-snmp \
--enable-dns-over-tls \
--enable-dnstap \
- --with-net-snmp \
- --disable-silent-rules \
- --with-service-user=pdns \
- --with-service-group=pdns \
- $(CONFIGURE_ARGS)
+ --enable-nod
override_dh_auto_install:
dh_auto_install
install -d debian/pdns-recursor/usr/share/pdns-recursor/lua-config
install -m 644 -t debian/pdns-recursor/usr/share/pdns-recursor/lua-config debian/lua-config/rootkeys.lua
install -m 644 -t debian/pdns-recursor/etc/powerdns debian/recursor.lua
+ install -d debian/pdns-recursor/usr/share/pdns-recursor/snmp
+ install -m 644 -t debian/pdns-recursor/usr/share/pdns-recursor/snmp RECURSOR-MIB.txt
rm -f debian/pdns-recursor/etc/powerdns/recursor.conf-dist
- ./pdns_recursor --config=default | sed \
- -e 's!# config-dir=.*!config-dir=/etc/powerdns!' \
- -e 's!# include-dir=.*!&\ninclude-dir=/etc/powerdns/recursor.d!' \
- -e 's!# local-address=.*!local-address=127.0.0.1!' \
- -e 's!# lua-config-file=.*!lua-config-file=/etc/powerdns/recursor.lua!' \
- -e 's!# quiet=.*!quiet=yes!' \
- -e 's!# setgid=.*!setgid=pdns!' \
- -e 's!# setuid=.*!setuid=pdns!' \
- -e 's!# hint-file=.*!&\nhint-file=/usr/share/dns/root.hints!' \
+ ./pdns_recursor --no-config --config=default | sed \
+ -e 's!^# config-dir=.*!config-dir=/etc/powerdns!' \
+ -e 's!^# hint-file=.*!&\nhint-file=/usr/share/dns/root.hints!' \
+ -e 's!^# include-dir=.*!&\ninclude-dir=/etc/powerdns/recursor.d!' \
+ -e 's!^# local-address=.*!local-address=127.0.0.1!' \
+ -e 's!^# lua-config-file=.*!lua-config-file=/etc/powerdns/recursor.lua!' \
+ -e 's!^# quiet=.*!quiet=yes!' \
-e '/^# version-string=.*/d' \
> debian/pdns-recursor/etc/powerdns/recursor.conf
-override_dh_strip:
- dh_strip --ddeb-migration='pdns-recursor-dbg'
-
-override_dh_installinit:
- dh_installinit --error-handler=initscript_error
+override_dh_auto_test:
+ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS)))
+ dh_auto_test
+ -cat testrunner.log
+endif
override_dh_gencontrol:
dh_gencontrol -- $(SUBSTVARS)
-override_dh_fixperms:
- dh_fixperms
-# these files often contain passwords. 640 as it is chowned to root:pdns
- chmod 0640 debian/pdns-recursor/etc/powerdns/recursor.conf
-
+# Explicitly set a compression method, as Debian and Ubuntu defaults vary widely,
+# and xz support is not available in all tools yet. Removing this override can
+# make reprepro fail.
override_dh_builddeb:
dh_builddeb -- -Zgzip
+++ /dev/null
-# Source is in html/js/d3.js
-pdns-recursor source: source-is-missing html/js/d3.v3.js line length is 32005 characters (>512)
Tests: smoke
-Depends: @, dnsutils
+Depends: dnsutils,
+ @
Restrictions: needs-root
exec 2>&1
set -ex
+restart_failed() {
+ echo E: service restart failed
+ journalctl -n200 --no-pager
+ exit 1
+}
+
cat <<EOF >>/etc/powerdns/recursor.conf
auth-zones=example.org=/etc/powerdns/example.org.zone
EOF
smoke.example.org. 172800 IN A 127.0.0.123
EOF
-service pdns-recursor restart
+service pdns-recursor restart || restart_failed
TMPFILE=$(mktemp)
cleanup() {
- rm -f "$TMPFILE"
+ rm -f "$TMPFILE"
}
trap cleanup EXIT
--- /dev/null
+# First do the source builds
+@INCLUDE Dockerfile.target.sdist
+
+# This defines the distribution base layer
+# Put only the bare minimum of common commands here, without dev tools
+FROM amazonlinux:2023 as dist-base
+ARG BUILDER_CACHE_BUSTER=
+
+# Do the actual rpm build
+@INCLUDE Dockerfile.rpmbuild
+
+# Do a test install and verify
+# Can be skipped with skiptests=1 in the environment
+# @EXEC [ "$skiptests" = "" ] && include Dockerfile.rpmtest
BuildRequires: systemd-devel
%endif
-%if 0%{?rhel} < 8
+%if 0%{?rhel} < 8 && 0%{?amzn} != 2023
BuildRequires: boost169-devel
%else
BuildRequires: boost-devel
%endif
-%if 0%{?rhel} >= 7
+%if 0%{?rhel} >= 7 || 0%{?amzn} == 2023
BuildRequires: gnutls-devel
BuildRequires: libcap-devel
BuildRequires: libnghttp2-devel
BuildRequires: lmdb-devel
-BuildRequires: libsodium-devel
%ifarch aarch64
BuildRequires: lua-devel
%define lua_implementation lua
BuildRequires: luajit-devel
%define lua_implementation luajit
%endif
-BuildRequires: net-snmp-devel
BuildRequires: re2-devel
BuildRequires: systemd
BuildRequires: systemd-devel
BuildRequires: systemd-units
BuildRequires: tinycdb-devel
+%if 0%{?amzn} != 2023
+BuildRequires: libsodium-devel
+BuildRequires: net-snmp-devel
+%endif
%endif
%if 0%{?suse_version}
Requires(pre): shadow
%systemd_requires
%endif
-%if 0%{?rhel} >= 7
+%if 0%{?rhel} >= 7 || 0%{?amzn} == 2023
Requires(pre): shadow-utils
BuildRequires: fstrm-devel
%systemd_requires
--disable-dnscrypt \
--without-libsodium \
--without-re2 \
- --enable-systemd --with-systemd=/lib/systemd/system \
+ --enable-systemd --with-systemd=%{_unitdir} \
--without-net-snmp
%endif
%if 0%{?rhel} >= 7
--with-libsodium \
--enable-dnscrypt \
--enable-dns-over-https \
- --enable-systemd --with-systemd=/lib/systemd/system \
+ --enable-systemd --with-systemd=%{_unitdir} \
--with-re2 \
--with-net-snmp \
PKG_CONFIG_PATH=/opt/lib64/pkgconfig
install -d %{buildroot}/%{_sysconfdir}/dnsdist
%{__mv} %{buildroot}%{_sysconfdir}/dnsdist/dnsdist.conf-dist %{buildroot}%{_sysconfdir}/dnsdist/dnsdist.conf
chmod 0640 %{buildroot}/%{_sysconfdir}/dnsdist/dnsdist.conf
-sed -i "s,/^\(ExecStart.*\)dnsdist\(.*\)\$,\1dnsdist -u dnsdist -g dnsdist\2," %{buildroot}/lib/systemd/system/dnsdist.service
-sed -i "s,/^\(ExecStart.*\)dnsdist\(.*\)\$,\1dnsdist -u dnsdist -g dnsdist\2," %{buildroot}/lib/systemd/system/dnsdist@.service
+sed -i "s,/^\(ExecStart.*\)dnsdist\(.*\)\$,\1dnsdist -u dnsdist -g dnsdist\2," %{buildroot}/%{_unitdir}/dnsdist.service
+sed -i "s,/^\(ExecStart.*\)dnsdist\(.*\)\$,\1dnsdist -u dnsdist -g dnsdist\2," %{buildroot}/%{_unitdir}/dnsdist@.service
%pre
getent group dnsdist >/dev/null || groupadd -r dnsdist
%{_mandir}/man1/*
%dir %{_sysconfdir}/dnsdist
%config(noreplace) %{_sysconfdir}/%{name}/dnsdist.conf
-/lib/systemd/system/dnsdist*
+%{_unitdir}/dnsdist*
Provides: powerdns-recursor = %{version}-%{release}
-%if 0%{?rhel} < 8
+%if 0%{?rhel} < 8 && 0%{?amzn} != 2023
BuildRequires: boost169-devel
%else
BuildRequires: boost-devel
BuildRequires: systemd
BuildRequires: systemd-devel
BuildRequires: openssl-devel
-BuildRequires: net-snmp-devel
-BuildRequires: libsodium-devel
BuildRequires: fstrm-devel
BuildRequires: libcurl-devel
+%if 0%{?amzn} != 2023
+BuildRequires: net-snmp-devel
+BuildRequires: libsodium-devel
+%endif
+
%ifarch aarch64
BuildRequires: lua-devel
%define lua_implementation lua
%configure \
--enable-option-checking=fatal \
--sysconfdir=%{_sysconfdir}/%{name} \
- --with-libsodium \
- --with-net-snmp \
--disable-silent-rules \
--disable-static \
--enable-unit-tests \
--enable-dnstap \
--with-libcap \
--with-lua=%{lua_implementation} \
- --enable-systemd --with-systemd=%{_unitdir}
+%if 0%{?amzn} != 2023
+ --with-libsodium \
+ --with-net-snmp \
+%endif
+ --enable-systemd --with-systemd=%{_unitdir} \
+ --enable-nod
make %{?_smp_mflags}
BuildRequires: krb5-devel
BuildRequires: p11-kit-devel
BuildRequires: libcurl-devel
-%if 0%{?rhel} < 8
+%if 0%{?rhel} < 8 && 0%{?amzn} != 2023
BuildRequires: boost169-devel
%else
BuildRequires: boost-devel
%endif
-BuildRequires: libsodium-devel
BuildRequires: bison
BuildRequires: openssl-devel
+%if 0%{?amzn} != 2023
+BuildRequires: libsodium-devel
+%endif
+
Requires(pre): shadow-utils
%ifarch aarch64
Summary: MySQL backend for %{name}
Group: System Environment/Daemons
Requires: %{name}%{?_isa} = %{version}-%{release}
-%if 0%{?rhel} < 8
+%if 0%{?rhel} < 8 && 0%{?amzn} != 2023
BuildRequires: mysql-devel
%else
BuildRequires: mariadb-connector-c-devel
Group: System Environment/Daemons
Requires: %{name}%{?_isa} = %{version}-%{release}
BuildRequires: yaml-cpp-devel
-%if 0%{?rhel} < 9
+%if 0%{?rhel} < 9 && 0%{?amzn} != 2023
BuildRequires: geoip-devel
%endif
BuildRequires: libmaxminddb-devel
--with-lua=%{lua_implementation} \
--with-dynmodules='%{backends}' \
--enable-tools \
+%if 0%{?amzn} != 2023
--with-libsodium \
+%endif
%if 0%{?amzn} != 2
--enable-ixfrdist \
%endif
BIND backend can only read this file, not write it.
-
.. _setting-bind-supermaster-config:
``bind-supermaster-config``
Your ``bind-config`` file should have an ``include`` statement to make sure this file is read on startup.
+.. _setting-bind-supermaster-destdir:
+
+``bind-supermaster-destdir``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Each new zone configured via the autosecondary mechanism gets a zone file in this directory.
+This directory must be writable.
+
.. _bind-operation:
Operation
Defaults to 100 on 32 bit systems, and 16000 on 64 bit systems.
.. _settings-lmdb-flag-deleted:
+
``lmdb-flag-deleted``
^^^^^^^^^^^^^^^^^^^^^
.. versionadded:: 4.8.0
+- Boolean
+- Default: no
+
Instead of deleting items from the database, flag them as deleted in the item's `Lightning Stream <https://doc.powerdns.com/lightningstream>`_ header.
Only enable this if you are using Lightning Stream.
+``lmdb-lightning-stream``
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+ .. versionadded:: 4.8.0
+
+- Boolean
+- Default: no
+
+Run in Lightning Stream compatible mode. This:
+
+* forces ``flag-deleted`` on
+* forces ``random-ids`` on
+* handles duplicate entries in databases that can result from domains being added on two Lightning Stream nodes at the same time
+
LMDB Structure
--------------
Changelogs for 4.7.x
====================
+.. changelog::
+ :version: 4.7.4
+ :released: 17th of April 2023
+
+ This is release 4.7.4 of the Authoritative Server.
+ It contains various bug fixes, some performance improvements, and one new feature (``pdnsutil list-member-zones``).
+
+ .. change::
+ :tags: Bug Fixes
+ :pullreq: 12742
+
+ Properly encode json string containing binary data
+
+ .. change::
+ :tags: Bug Fixes
+ :pullreq: 12741
+
+ Prevent a race during the processing of SVC auto-hints
+
+ .. change::
+ :tags: New Features
+ :pullreq: 12676
+
+ pdnsutil, implement list-member-zones (Kees Monshouwer)
+
+ .. change::
+ :tags: Bug Fixes
+ :pullreq: 12675
+
+ lmdb delete fixes and tests (Kees Monshouwer)
+
+ .. change::
+ :tags: Bug Fixes
+ :pullreq: 12429
+
+ minicurl: stop leaking hostlist memory
+
+ .. change::
+ :tags: Bug Fixes
+ :pullreq: 12521
+
+ ixfrdist fixes and improvements
+
+ .. change::
+ :tags: Improvements
+ :pullreq: 12458
+
+ lock.hh: include <stdexcept>
+
+ .. change::
+ :tags: Bug Fixes
+ :pullreq: 12746
+
+ Pick the right signer name when a NSEC name is also a delegation point
+
+ .. change::
+ :tags: Improvements
+ :pullreq: 12745
+
+ calm down the communicator loop
+
+ .. change::
+ :tags: Bug Fixes
+ :pullreq: 12744
+
+ Fix multiple-version IXFR request handling in ixfrdist
+
+ .. change::
+ :tags: Improvements
+ :pullreq: 12743
+
+ timeout handling for IXFRs as a client
+
.. changelog::
:version: 4.7.3
:released: 9th of December 2022
If you believe you have found a security vulnerability that applies to DNS implementations generally, and you want to report this responsibly to a number of implementers, you might consider also using the `Open Source DNS Vulnerability mailing list <https://www.dns-oarc.net/oarc/oss-dns-vulns/>`_, managed by `DNS-OARC <https://www.dns-oarc.net/>`_.
-HackerOne
+YesWeHack
^^^^^^^^^
-Security issues can also be reported on `our HackerOne page <https://hackerone.com/powerdns>`_ and might fetch a bounty.
-Do note that only the PowerDNS software is in scope for the HackerOne program, not our websites or other infrastructure.
+Security issues can also be reported on `our YesWeHack page <https://yeswehack.com/programs/powerdns>`_ and might fetch a bounty.
+Do note that only the PowerDNS software is in scope for the YesWeHack program, not our websites or other infrastructure.
Disclosure Policy
^^^^^^^^^^^^^^^^^
If either IP address stops listening, only the other address will be
returned. If all IP addresses are down, all candidates are returned.
+You can also provide multiple sets of IP addresses to prioritize a set over the
+rest. If an IP address from the first set is available, it will be returned. If
+no addresses work in the first set, the second set is tried.
+
+For example::
+
+ www IN LUA A "ifportup(443, {{'192.0.2.1', '192.0.2.2'}, {'192.0.3.1'}})"
+
Because DNS queries require rapid answers, server availability is not checked
synchronously. In the background, a process periodically determines if IP
addresses mentioned in availability rules are, in fact, available.
domains:
- domain: example.com
master: 192.0.2.18:5301
+ max-soa-refresh: 1800
- domain: example.net
master: 2001:DB8:ABCD::2
Mandatory.
:master: IP address of the server to transfer this domain from.
Mandatory.
+ :max-soa-refresh: Cap the refresh time to the given maximum (in seconds).
+ Optional.
:webserver-address:
IP address to listen on for the built-in webserver.
-@ 86400 IN SOA pdns-public-ns1.powerdns.com. peter\.van\.dijk.powerdns.com. 2023032101 10800 3600 604800 10800
+@ 86400 IN SOA pdns-public-ns1.powerdns.com. peter\.van\.dijk.powerdns.com. 2023041700 10800 3600 604800 10800
@ 3600 IN NS pdns-public-ns1.powerdns.com.
@ 3600 IN NS pdns-public-ns2.powerdns.com.
auth-4.7.1.security-status 60 IN TXT "1 OK"
auth-4.7.2.security-status 60 IN TXT "1 OK"
auth-4.7.3.security-status 60 IN TXT "1 OK"
+auth-4.7.4.security-status 60 IN TXT "1 OK"
auth-4.8.0-alpha1.security-status 60 IN TXT "1 Unsupported pre-release"
; Auth Debian
recursor-4.6.0.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/recursor/security-advisories/powerdns-advisory-2022-01.html"
recursor-4.6.1.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/recursor/security-advisories/powerdns-advisory-2022-02.html"
recursor-4.6.2.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/recursor/security-advisories/powerdns-advisory-2022-02.html"
-recursor-4.6.3.security-status 60 IN TXT "1 OK"
-recursor-4.6.4.security-status 60 IN TXT "1 OK"
-recursor-4.6.5.security-status 60 IN TXT "1 OK"
+recursor-4.6.3.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/recursor/security-advisories/powerdns-advisory-2023-02.html"
+recursor-4.6.4.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/recursor/security-advisories/powerdns-advisory-2023-02.html"
+recursor-4.6.5.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/recursor/security-advisories/powerdns-advisory-2023-02.html"
+recursor-4.6.6.security-status 60 IN TXT "1 OK"
recursor-4.7.0-alpha1.security-status 60 IN TXT "3 Unsupported pre-release (known vulnerabilities)"
recursor-4.7.0-beta1.security-status 60 IN TXT "3 Unsupported pre-release (known vulnerabilities)"
recursor-4.7.0-rc1.security-status 60 IN TXT "3 Unsupported pre-release (known vulnerabilities)"
recursor-4.7.0.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/recursor/security-advisories/powerdns-advisory-2022-02.html"
recursor-4.7.1.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/recursor/security-advisories/powerdns-advisory-2022-02.html"
-recursor-4.7.2.security-status 60 IN TXT "1 OK"
-recursor-4.7.3.security-status 60 IN TXT "1 OK"
-recursor-4.7.4.security-status 60 IN TXT "1 OK"
+recursor-4.7.2.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/recursor/security-advisories/powerdns-advisory-2023-02.html"
+recursor-4.7.3.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/recursor/security-advisories/powerdns-advisory-2023-02.html"
+recursor-4.7.4.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/recursor/security-advisories/powerdns-advisory-2023-02.html"
+recursor-4.7.5.security-status 60 IN TXT "1 OK"
recursor-4.8.0-alpha1.security-status 60 IN TXT "3 Unsupported pre-release (known vulnerabilities)"
recursor-4.8.0-beta1.security-status 60 IN TXT "3 Unsupported pre-release (known vulnerabilities)"
recursor-4.8.0-beta2.security-status 60 IN TXT "3 Unsupported pre-release (known vulnerabilities)"
recursor-4.8.0-rc1.security-status 60 IN TXT "3 Unsupported pre-release (known vulnerabilities)"
recursor-4.8.0.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/recursor/security-advisories/powerdns-advisory-2023-01.html"
-recursor-4.8.1.security-status 60 IN TXT "1 OK"
-recursor-4.8.2.security-status 60 IN TXT "1 OK"
-recursor-4.8.3.security-status 60 IN TXT "1 OK"
+recursor-4.8.1.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/recursor/security-advisories/powerdns-advisory-2023-02.html"
+recursor-4.8.2.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/recursor/security-advisories/powerdns-advisory-2023-02.html"
+recursor-4.8.3.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/recursor/security-advisories/powerdns-advisory-2023-02.html"
+recursor-4.8.4.security-status 60 IN TXT "1 OK"
+recursor-4.9.0-alpha1.security-status 60 IN TXT "1 Unsupported pre-release"
; Recursor Debian
recursor-3.6.2-2.debian.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/3/security/powerdns-advisory-2015-01/ and https://doc.powerdns.com/3/security/powerdns-advisory-2016-02/"
dnsdist-1.7.1.security-status 60 IN TXT "1 OK"
dnsdist-1.7.2.security-status 60 IN TXT "1 OK"
dnsdist-1.7.3.security-status 60 IN TXT "1 OK"
+dnsdist-1.7.4.security-status 60 IN TXT "1 OK"
dnsdist-1.8.0-rc1.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities)"
dnsdist-1.8.0-rc2.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities)"
-dnsdist-1.8.0-rc3.security-status 60 IN TXT "1 Unsupported pre-release"
+dnsdist-1.8.0-rc3.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities)"
+dnsdist-1.8.0.security-status 60 IN TXT "1 OK"
return (lsh->d_flags & LS_FLAG_DELETED) != 0;
}
+ uint64_t LSgetTimestamp(std::string_view val) {
+ const LSheader* lsh = LSassertFixedHeaderSize(val);
+
+ return lsh->getTimestamp();
+ }
bool s_flag_deleted{false};
}
return std::string((char*)this, sizeof(*this)) + std::string(ntohs(d_numextra)*8, '\0');
}
-
+ uint64_t getTimestamp() const {
+ return _LMDB_SAFE_BSWAP64MAYBE(d_timestamp);
+ }
};
static_assert(sizeof(LSheader)==24, "LSheader size is wrong");
size_t LScheckHeaderAndGetSize(std::string_view val, size_t datasize=0);
size_t LScheckHeaderAndGetSize(const MDBOutVal *val, size_t datasize=0);
bool LSisDeleted(std::string_view val);
+ uint64_t LSgetTimestamp(std::string_view val);
extern bool s_flag_deleted;
}
auto scombined = makeCombinedKey(keyConv(d_parent->getMember(t)), id);
MDBInVal combined(scombined);
- txn->put(d_idx, combined, empty, flags);
+ MDBOutVal currentvalue;
+
+ // check if the entry already exists, so we don't uselessly bump the timestamp
+ if (txn->get(d_idx, combined, currentvalue) == MDB_NOTFOUND) {
+ txn->put(d_idx, combined, empty, flags);
+ }
}
void del(MDBRWTransaction& txn, const Class& t, uint32_t id)
// auto range = prefix_range<N>(key);
LMDBIDvec ids;
- get_multi<N>(key, ids);
+ // because we know we only want one item, pass onlyOldest=true to consistently get the same one out of a set of duplicates
+ get_multi<N>(key, ids, true);
if (ids.size() == 0) {
return 0;
};
template<int N>
- void get_multi(const typename std::tuple_element<N, tuple_t>::type::type& key, LMDBIDvec& ids)
+ void get_multi(const typename std::tuple_element<N, tuple_t>::type::type& key, LMDBIDvec& ids, bool onlyOldest=false)
{
// std::cerr<<"in get_multi"<<std::endl;
typename Parent::cursor_t cursor = (*d_parent.d_txn)->getCursor(std::get<N>(d_parent.d_parent->d_tuple).d_idx);
int rc = cursor.get(out, id, MDB_SET_RANGE);
- int scanned = 0;
+ uint64_t oldestts = UINT64_MAX;
+ uint32_t oldestid = 0;
+
while (rc == 0) {
- scanned++;
auto sout = out.getNoStripHeader<std::string>(); // FIXME: this (and many others) could probably be string_view
auto thiskey = getKeyFromCombinedKey(out);
auto sthiskey = thiskey.getNoStripHeader<std::string>();
if (sthiskey == keyString) {
auto _id = getIDFromCombinedKey(out);
- ids.push_back(_id.getNoStripHeader<uint32_t>());
+ uint64_t ts = LMDBLS::LSgetTimestamp(id.getNoStripHeader<string_view>());
+ uint32_t __id = _id.getNoStripHeader<uint32_t>();
+
+ if (onlyOldest) {
+ if (ts < oldestts) {
+ oldestts = ts;
+ oldestid = __id;
+
+ ids.clear();
+ ids.push_back(oldestid);
+ }
+ } else {
+ ids.push_back(__id);
+ }
}
rc = cursor.get(out, id, MDB_NEXT);
}
- // std::cerr<<"get_multi scanned="<<scanned<<std::endl;
if (rc != 0 && rc != MDB_NOTFOUND) {
throw std::runtime_error("error during get_multi");
}
}
if (d_dolog)
- g_log << Logger::Warning << "Query " << ((long)(void*)this) << ": " << d_dtime.udiffNoReset() << " usec to execute" << endl;
+ g_log << Logger::Warning << "Query " << ((long)(void*)this) << ": " << d_dtime.udiffNoReset() << " us to execute" << endl;
return this;
}
bool hasNextRow()
{
if (d_dolog && d_residx == d_resnum) {
- g_log << Logger::Warning << "Query " << ((long)(void*)this) << ": " << d_dtime.udiffNoReset() << " total usec to last row" << endl;
+ g_log << Logger::Warning << "Query " << ((long)(void*)this) << ": " << d_dtime.udiffNoReset() << " us total to last row" << endl;
}
return d_residx < d_resnum;
}
d_cur_set = 0;
if (d_dolog) {
auto diff = d_dtime.udiffNoReset();
- g_log << Logger::Warning << "Query " << ((long)(void*)this) << ": " << diff << " usec to execute" << endl;
+ g_log << Logger::Warning << "Query " << ((long)(void*)this) << ": " << diff << " us to execute" << endl;
}
nextResult();
bool hasNextRow()
{
if (d_dolog && d_residx == d_resnum) {
- g_log << Logger::Warning << "Query " << ((long)(void*)this) << ": " << d_dtime.udiff() << " total usec to last row" << endl;
+ g_log << Logger::Warning << "Query " << ((long)(void*)this) << ": " << d_dtime.udiff() << " us total to last row" << endl;
}
return d_residx < d_resnum;
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+#include "ext/lmdb-safe/lmdb-safe.hh"
#include <lmdb.h>
+#include <stdexcept>
#include <utility>
#ifdef HAVE_CONFIG_H
#include "config.h"
}
LMDBLS::s_flag_deleted = mustDo("flag-deleted");
+ d_handle_dups = false;
+
+ if (mustDo("lightning-stream")) {
+ d_random_ids = true;
+ d_handle_dups = true;
+ LMDBLS::s_flag_deleted = true;
+ }
bool opened = false;
return true;
}
+bool LMDBBackend::replaceComments(const uint32_t domain_id, const DNSName& qname, const QType& qt, const vector<Comment>& comments)
+{
+ // if the vector is empty, good, that's what we do here (LMDB does not store comments)
+ // if it's not, report failure
+ return comments.empty();
+}
+
// tempting to templatize these two functions but the pain is not worth it
std::shared_ptr<LMDBBackend::RecordsRWTransaction> LMDBBackend::getRecordsRWTransaction(uint32_t id)
{
if (d_getcursor->lower_bound(d_matchkey, key, val) || key.getNoStripHeader<StringView>().rfind(d_matchkey, 0) != 0) {
d_getcursor.reset();
if (d_dolog) {
- g_log << Logger::Warning << "Query " << ((long)(void*)this) << ": " << d_dtime.udiffNoReset() << " usec to execute (found nothing)" << endl;
+ g_log << Logger::Warning << "Query " << ((long)(void*)this) << ": " << d_dtime.udiffNoReset() << " us to execute (found nothing)" << endl;
}
return;
}
if (d_dolog) {
- g_log << Logger::Warning << "Query " << ((long)(void*)this) << ": " << d_dtime.udiffNoReset() << " usec to execute" << endl;
+ g_log << Logger::Warning << "Query " << ((long)(void*)this) << ": " << d_dtime.udiffNoReset() << " us to execute" << endl;
}
d_lookupdomain = hunt;
return true;
}
+void LMDBBackend::getAllDomainsFiltered(vector<DomainInfo>* domains, const std::function<bool(DomainInfo&)>& allow)
+{
+ auto txn = d_tdomains->getROTransaction();
+ if (d_handle_dups) {
+ map<DNSName, DomainInfo> zonemap;
+ set<DNSName> dups;
+
+ for (auto iter = txn.begin(); iter != txn.end(); ++iter) {
+ DomainInfo di = *iter;
+ di.id = iter.getID();
+ di.backend = this;
+
+ if (!zonemap.insert(std::make_pair(di.zone, di)).second) {
+ dups.insert(di.zone);
+ }
+ }
+
+ for (const auto& zone : dups) {
+ DomainInfo di;
+
+ // this get grabs the oldest item if there are duplicates
+ di.id = txn.get<0>(zone, di);
+
+ if (di.id == 0) {
+ // .get actually found nothing for us
+ continue;
+ }
+
+ di.backend = this;
+ zonemap[di.zone] = di;
+ }
+
+ for (auto [k, v] : zonemap) {
+ if (allow(v)) {
+ domains->push_back(v);
+ }
+ }
+ }
+ else {
+ for (auto iter = txn.begin(); iter != txn.end(); ++iter) {
+ DomainInfo di = *iter;
+ di.id = iter.getID();
+ di.backend = this;
+
+ if (allow(di)) {
+ domains->push_back(di);
+ }
+ }
+ }
+}
+
void LMDBBackend::getAllDomains(vector<DomainInfo>* domains, bool /* doSerial */, bool include_disabled)
{
domains->clear();
- auto txn = d_tdomains->getROTransaction();
- for (auto iter = txn.begin(); iter != txn.end(); ++iter) {
- // cerr<<"iter"<<endl;
- DomainInfo di = *iter;
- di.id = iter.getID();
+ getAllDomainsFiltered(domains, [this, include_disabled](DomainInfo& di) {
if (!getSerial(di) && !include_disabled) {
- continue;
+ return false;
}
- di.backend = this;
- domains->push_back(di);
- }
+ return true;
+ });
}
void LMDBBackend::getUnfreshSlaveInfos(vector<DomainInfo>* domains)
LMDBResourceRecord lrr;
soatimes st;
- auto txn = d_tdomains->getROTransaction();
- for (auto iter = txn.begin(); iter != txn.end(); ++iter) {
- if (!iter->isSecondaryType()) {
- continue;
+ getAllDomainsFiltered(domains, [this, &lrr, &st, &now, &serial](DomainInfo& di) {
+ if (!di.isSecondaryType()) {
+ return false;
}
- auto txn2 = getRecordsROTransaction(iter.getID());
+ auto txn2 = getRecordsROTransaction(di.id);
compoundOrdername co;
MDBOutVal val;
- if (!txn2->txn->get(txn2->db->dbi, co(iter.getID(), g_rootdnsname, QType::SOA), val)) {
+ if (!txn2->txn->get(txn2->db->dbi, co(di.id, g_rootdnsname, QType::SOA), val)) {
serFromString(val.get<string_view>(), lrr);
memcpy(&st, &lrr.content[lrr.content.size() - sizeof(soatimes)], sizeof(soatimes));
- if ((time_t)(iter->last_check + ntohl(st.refresh)) > now) { // still fresh
- continue;
+ if ((time_t)(di.last_check + ntohl(st.refresh)) > now) { // still fresh
+ return false;
}
serial = ntohl(st.serial);
}
serial = 0;
}
- DomainInfo di(*iter);
- di.id = iter.getID();
- di.serial = serial;
- di.backend = this;
-
- domains->emplace_back(di);
- }
+ return true;
+ });
}
void LMDBBackend::setStale(uint32_t domain_id)
void LMDBBackend::getUpdatedMasters(vector<DomainInfo>& updatedDomains, std::unordered_set<DNSName>& catalogs, CatalogHashMap& catalogHashes)
{
- DomainInfo di;
CatalogInfo ci;
- auto txn = d_tdomains->getROTransaction();
- for (auto iter = txn.begin(); iter != txn.end(); ++iter) {
-
- if (!iter->isPrimaryType()) {
- continue;
+ getAllDomainsFiltered(&(updatedDomains), [this, &catalogs, &catalogHashes, &ci](DomainInfo& di) {
+ if (!di.isPrimaryType()) {
+ return false;
}
- if (iter->kind == DomainInfo::Producer) {
- catalogs.insert(iter->zone);
- catalogHashes[iter->zone].process("\0");
- continue; // Producer fresness check is performed elsewhere
+ if (di.kind == DomainInfo::Producer) {
+ catalogs.insert(di.zone);
+ catalogHashes[di.zone].process("\0");
+ return false; // Producer fresness check is performed elsewhere
}
- di = *iter;
- di.id = iter.getID();
-
- if (!iter->catalog.empty()) {
- ci.fromJson(iter->options, CatalogInfo::CatalogType::Producer);
+ if (!di.catalog.empty()) {
+ ci.fromJson(di.options, CatalogInfo::CatalogType::Producer);
ci.updateHash(catalogHashes, di);
}
if (getSerial(di) && di.serial != di.notified_serial) {
di.backend = this;
- updatedDomains.emplace_back(di);
+ return true;
}
- }
+
+ return false;
+ });
}
void LMDBBackend::setNotified(uint32_t domain_id, uint32_t serial)
});
}
+class getCatalogMembersReturnFalseException : std::runtime_error
+{
+public:
+ getCatalogMembersReturnFalseException() :
+ std::runtime_error("getCatalogMembers should return false") {}
+};
+
bool LMDBBackend::getCatalogMembers(const DNSName& catalog, vector<CatalogInfo>& members, CatalogInfo::CatalogType type)
{
- auto txn = d_tdomains->getROTransaction();
- for (auto iter = txn.begin(); iter != txn.end(); ++iter) {
- if ((type == CatalogInfo::CatalogType::Producer && iter->kind != DomainInfo::Master) || (type == CatalogInfo::CatalogType::Consumer && iter->kind != DomainInfo::Slave) || iter->catalog != catalog) {
- continue;
- }
+ vector<DomainInfo> scratch;
+
+ try {
+ getAllDomainsFiltered(&scratch, [&catalog, &members, &type](DomainInfo& di) {
+ if ((type == CatalogInfo::CatalogType::Producer && di.kind != DomainInfo::Master) || (type == CatalogInfo::CatalogType::Consumer && di.kind != DomainInfo::Slave) || di.catalog != catalog) {
+ return false;
+ }
+
+ CatalogInfo ci;
+ ci.d_id = di.id;
+ ci.d_zone = di.zone;
+ ci.d_primaries = di.masters;
+ try {
+ ci.fromJson(di.options, type);
+ }
+ catch (const std::runtime_error& e) {
+ g_log << Logger::Warning << __PRETTY_FUNCTION__ << " options '" << di.options << "' for zone '" << di.zone << "' is no valid JSON: " << e.what() << endl;
+ members.clear();
+ throw getCatalogMembersReturnFalseException();
+ }
+ members.emplace_back(ci);
- CatalogInfo ci;
- ci.d_id = iter->id;
- ci.d_zone = iter->zone;
- ci.d_primaries = iter->masters;
- try {
- ci.fromJson(iter->options, type);
- }
- catch (const std::runtime_error& e) {
- g_log << Logger::Warning << __PRETTY_FUNCTION__ << " options '" << iter->options << "' for zone '" << iter->zone << "' is no valid JSON: " << e.what() << endl;
- members.clear();
return false;
- }
- members.emplace_back(ci);
+ });
+ }
+ catch (const getCatalogMembersReturnFalseException& e) {
+ return false;
}
return true;
}
declare(suffix, "random-ids", "Numeric IDs inside the database are generated randomly instead of sequentially", "no");
declare(suffix, "map-size", "LMDB map size in megabytes", (sizeof(void*) == 4) ? "100" : "16000");
declare(suffix, "flag-deleted", "Flag entries on deletion instead of deleting them", "no");
+ declare(suffix, "lightning-stream", "Run in Lightning Stream compatible mode", "no");
}
DNSBackend* make(const string& suffix = "") override
{
bool feedEnts(int domain_id, map<DNSName, bool>& nonterm) override;
bool feedEnts3(int domain_id, const DNSName& domain, map<DNSName, bool>& nonterm, const NSEC3PARAMRecordContent& ns3prc, bool narrow) override;
bool replaceRRSet(uint32_t domain_id, const DNSName& qname, const QType& qt, const vector<DNSResourceRecord>& rrset) override;
+ bool replaceComments(uint32_t domain_id, const DNSName& qname, const QType& qt, const vector<Comment>& comments) override;
void getAllDomains(vector<DomainInfo>* domains, bool doSerial, bool include_disabled) override;
void lookup(const QType& type, const DNSName& qdomain, int zoneId, DNSPacket* p = nullptr) override;
int genChangeDomain(uint32_t id, std::function<void(DomainInfo&)> func);
void deleteDomainRecords(RecordsRWTransaction& txn, uint32_t domain_id, uint16_t qtype = QType::ANY);
+ void getAllDomainsFiltered(vector<DomainInfo>* domains, const std::function<bool(DomainInfo&)>& allow);
+
bool getSerial(DomainInfo& di);
bool upgradeToSchemav3();
uint32_t d_transactiondomainid;
bool d_dolog;
bool d_random_ids;
+ bool d_handle_dups;
DTime d_dtime; // used only for logging
};
+ns2.secure-delegated.dnssec-parent.com:5.6.7.8:3600
+something1.auth-ent.dnssec-parent.com:1.1.2.3:3600
:secure-delegated.dnssec-parent.com:43:\324\057\010\002\240\271\303\214\323\044\030\052\360\357f\203\015\012\016\205\241\325\211y\311\203N\030\310qw\236\004\010W\267:3600
+C\052.dnssec-parent.com:secure-delegated.dnssec-parent.com.:3600
Cwww.dnssec-parent.com:www.insecure.dnssec-parent.com.:3600
Zdnssec-parent.com:ns1.dnssec-parent.com.:ahu.example.com.:2005092501:28800:7200:604800:86400:3600
#2000081501 auto axfr-get
::arg().set("only-notify", "Only send AXFR NOTIFY to these IP addresses or netmasks") = "0.0.0.0/0,::/0";
::arg().set("also-notify", "When notifying a zone, also notify these nameservers") = "";
::arg().set("allow-notify-from", "Allow AXFR NOTIFY from these IP ranges. If empty, drop all incoming notifies.") = "0.0.0.0/0,::/0";
- ::arg().set("slave-cycle-interval", "Schedule slave freshness checks once every .. seconds") = "60";
+ ::arg().set("slave-cycle-interval", "Schedule slave freshness checks once every .. seconds") = "";
::arg().set("xfr-cycle-interval", "Schedule primary/secondary SOA freshness checks once every .. seconds") = "60";
::arg().set("secondary-check-signature-freshness", "Check signatures in SOA freshness check. Sets DO flag on SOA queries. Outside some very problematic scenarios, say yes here.") = "yes";
::arg().set("allow-unsigned-autoprimary") = "yes";
if (!::arg().isEmpty("domain-metadata-cache-ttl"))
::arg().set("zone-metadata-cache-ttl") = ::arg()["domain-metadata-cache-ttl"];
+ if (!::arg().isEmpty("slave-cycle-interval"))
+ ::arg().set("xfr-cycle-interval") = ::arg()["slave-cycle-interval"];
// this mirroring back is on purpose, so that config dumps reflect the actual setting on both names
if (::arg().mustDo("primary"))
if (::arg().mustDo("allow-unsigned-autoprimary"))
::arg().set("allow-unsigned-supermaster") = "yes";
::arg().set("domain-metadata-cache-ttl") = ::arg()["zone-metadata-cache-ttl"];
+ ::arg().set("slave-cycle-interval") = ::arg()["xfr-cycle-interval"];
g_log.setLoglevel((Logger::Urgency)(::arg().asNum("loglevel")));
g_log.disableSyslog(::arg().mustDo("disable-syslog"));
}
}
-void GSQLBackend::feedComment(const Comment& comment)
+bool GSQLBackend::feedComment(const Comment& comment)
{
try {
reconnectIfNeeded();
catch (SSqlException &e) {
throw PDNSException("GSQLBackend unable to feed comment for RRSet '" + comment.qname.toLogString() + "|" + comment.qtype.toString() + "': "+e.txtReason());
}
+
+ return true;
}
bool GSQLBackend::replaceComments(const uint32_t domain_id, const DNSName& qname, const QType& qt, const vector<Comment>& comments)
bool listComments(const uint32_t domain_id) override;
bool getComment(Comment& comment) override;
- void feedComment(const Comment& comment) override;
+ bool feedComment(const Comment& comment) override;
bool replaceComments(const uint32_t domain_id, const DNSName& qname, const QType& qt, const vector<Comment>& comments) override;
string directBackendCmd(const string &query) override;
bool searchRecords(const string &pattern, int maxResults, vector<DNSResourceRecord>& result) override;
#include "capabilities.hh"
#include "misc.hh"
-bool dropCapabilities(std::set<std::string> capabilitiesToKeep)
+bool dropCapabilities([[maybe_unused]] std::set<std::string> capabilitiesToKeep)
{
#ifdef HAVE_LIBCAP
cap_t caps = cap_get_proc();
try {
setThreadName("pdns/comm-main");
signal(SIGPIPE,SIG_IGN);
- g_log<<Logger::Error<<"Primary/secondary communicator launching"<<endl;
- PacketHandler P;
- d_tickinterval=min(::arg().asNum("slave-cycle-interval"), ::arg().asNum("xfr-cycle-interval"));
- makeNotifySockets();
+ g_log << Logger::Warning << "Primary/secondary communicator launching" << endl;
+
+ d_tickinterval = ::arg().asNum("xfr-cycle-interval");
int rc;
- time_t next, tick;
+ time_t next;
+ PacketHandler P;
+
+ makeNotifySockets();
for(;;) {
slaveRefresh(&P);
masterUpdateCheck(&P);
- tick=doNotifications(&P); // this processes any notification acknowledgements and actually send out our own notifications
-
- tick = min (tick, d_tickinterval);
-
- next=time(nullptr)+tick;
+ doNotifications(&P); // this processes any notification acknowledgements and actually send out our own notifications
+
+ next = time(nullptr) + d_tickinterval;
while(time(nullptr) < next) {
rc=d_any_sem.tryWait();
}
break; // something happened
}
- // this gets executed at least once every second
+ // this gets executed about once per second
doNotifications(&P);
}
}
_exit(1);
}
}
-
};
std::string RCode::to_s(uint8_t rcode) {
- if (rcode > 0xF)
+ if (rcode > 0xF) {
return std::string("ErrOutOfRange");
+ }
return ERCode::to_s(rcode);
}
return rcodes_short_s.at(rcode);
}
-std::string ERCode::to_s(uint8_t rcode) {
- if (rcode > RCode::rcodes_s.size()-1)
+std::string ERCode::to_s(uint16_t rcode) {
+ if (rcode >= RCode::rcodes_s.size()) {
return std::string("Err#")+std::to_string(rcode);
+ }
return RCode::rcodes_s.at(rcode);
}
class RCode
{
public:
- enum rcodes_ { NoError=0, FormErr=1, ServFail=2, NXDomain=3, NotImp=4, Refused=5, YXDomain=6, YXRRSet=7, NXRRSet=8, NotAuth=9, NotZone=10};
+ enum rcodes_ : uint8_t { NoError=0, FormErr=1, ServFail=2, NXDomain=3, NotImp=4, Refused=5, YXDomain=6, YXRRSet=7, NXRRSet=8, NotAuth=9, NotZone=10};
static std::string to_s(uint8_t rcode);
static std::string to_short_s(uint8_t rcode);
const static std::array<std::string, 24> rcodes_s;
class ERCode
{
public:
- enum rcodes_ { BADVERS=16, BADSIG=16, BADKEY=17, BADTIME=18, BADMODE=19, BADNAME=20, BADALG=21, BADTRUNC=22, BADCOOKIE=23 };
- static std::string to_s(uint8_t rcode);
+ enum rcodes_ : uint16_t { BADVERS=16, BADSIG=16, BADKEY=17, BADTIME=18, BADMODE=19, BADNAME=20, BADALG=21, BADTRUNC=22, BADCOOKIE=23 };
+ static std::string to_s(uint16_t rcode);
};
class Opcode
return false;
}
- virtual void feedComment(const Comment& /* comment */)
+ virtual bool feedComment(const Comment& /* comment */)
{
+ return false;
}
virtual bool replaceComments(const uint32_t /* domain_id */, const DNSName& /* qname */, const QType& /* qt */, const vector<Comment>& /* comments */)
{
(*d_acc)(usec/1000.0);
// if(usec > 1000000)
- // cerr<<"Slow: "<<domain<<" ("<<usec/1000.0<<" msec)\n";
+ // cerr<<"Slow: "<<domain<<" ("<<usec/1000.0<<" ms)\n";
if(!g_quiet) {
- cout<<domain.name<<"|"<<DNSRecordContent::NumberToType(domain.type)<<": ("<<usec/1000.0<<"msec) rcode: "<<dr.rcode;
+ cout<<domain.name<<"|"<<DNSRecordContent::NumberToType(domain.type)<<": ("<<usec/1000.0<<" ms) rcode: "<<dr.rcode;
for(const ComboAddress& ca : dr.ips) {
cout<<", "<<ca.toString();
}
cerr<< datafmt % "Total " % (sr.d_oks + sr.d_errors + sr.d_nodatas + sr.d_nxdomains + sr.d_unknowns + inflighter.getTimeouts()) % "" % "";
cerr<<"\n";
- cerr<< "Mean response time: "<<mean(*sr.d_acc) << " msec"<<", median: "<<median(*sr.d_acc)<< " msec\n";
+ cerr<< "Mean response time: "<<mean(*sr.d_acc) << " ms"<<", median: "<<median(*sr.d_acc)<< " ms\n";
- boost::format statfmt("Time < %6.03f msec %|30t|%6.03f%% cumulative\n");
+ boost::format statfmt("Time < %6.03f ms %|30t|%6.03f%% cumulative\n");
for (unsigned int i = 0; i < sr.d_probs.size(); ++i) {
cerr << statfmt % extended_p_square(*sr.d_acc)[i] % (100*sr.d_probs[i]);
usleep(toSleepUSec);
}
else {
- vinfolog("Carbon export for %s took longer (%s usec) than the configured interval (%d usec)", endpoint.server.toStringWithPort(), elapsedUSec, intervalUSec);
+ vinfolog("Carbon export for %s took longer (%s us) than the configured interval (%d us)", endpoint.server.toStringWithPort(), elapsedUSec, intervalUSec);
}
consecutiveFailures = 0;
}
{ "getTLSFrontend", true, "n", "returns the TLS frontend with index n" },
{ "getTLSFrontendCount", true, "", "returns the number of DoT listeners" },
{ "getVerbose", true, "", "get whether log messages at the verbose level will be logged" },
- { "grepq", true, "Netmask|DNS Name|100ms|{\"::1\", \"powerdns.com\", \"100ms\"} [, n]", "shows the last n queries and responses matching the specified client address or range (Netmask), or the specified DNS Name, or slower than 100ms" },
+ { "grepq", true, "Netmask|DNS Name|100ms|{\"::1\", \"powerdns.com\", \"100ms\"} [, n] [,options]", "shows the last n queries and responses matching the specified client address or range (Netmask), or the specified DNS Name, or slower than 100ms" },
{ "hashPassword", true, "password [, workFactor]", "Returns a hashed and salted version of the supplied password, usable with 'setWebserverConfig()'"},
{ "HTTPHeaderRule", true, "name, regex", "matches DoH queries with a HTTP header 'name' whose content matches the regular expression 'regex'"},
{ "HTTPPathRegexRule", true, "regex", "matches DoH queries whose HTTP path matches 'regex'"},
}
std::string toString() const override
{
- return "delay by "+std::to_string(d_msec)+ " msec";
+ return "delay by "+std::to_string(d_msec)+ " ms";
}
private:
int d_msec;
}
std::string toString() const override
{
- return "delay by "+std::to_string(d_msec)+ " msec";
+ return "delay by "+std::to_string(d_msec)+ " ms";
}
private:
int d_msec;
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+#include <fcntl.h>
+
#include "dnsdist.hh"
#include "dnsdist-lua.hh"
#include "dnsdist-dynblocks.hh"
}
});
- luaCtx.writeFunction("grepq", [](LuaTypeOrArrayOf<std::string> inp, boost::optional<unsigned int> limit) {
+ luaCtx.writeFunction("grepq", [](LuaTypeOrArrayOf<std::string> inp, boost::optional<unsigned int> limit, boost::optional<LuaAssociativeTable<std::string>> options) {
setLuaNoSideEffect();
boost::optional<Netmask> nm;
boost::optional<DNSName> dn;
- int msec=-1;
+ int msec = -1;
+ std::unique_ptr<FILE, decltype(&fclose)> outputFile{nullptr, fclose};
+
+ if (options) {
+ std::string outputFileName;
+ if (getOptionalValue<std::string>(options, "outputFile", outputFileName) > 0) {
+ int fd = open(outputFileName.c_str(), O_CREAT | O_EXCL | O_WRONLY, 0600);
+ if (fd < 0) {
+ g_outputBuffer = "Error opening dump file for writing: " + stringerror() + "\n";
+ return;
+ }
+ outputFile = std::unique_ptr<FILE, decltype(&fclose)>(fdopen(fd, "w"), fclose);
+ if (outputFile == nullptr) {
+ g_outputBuffer = "Error opening dump file for writing: " + stringerror() + "\n";
+ close(fd);
+ return;
+ }
+ }
+ checkAllParametersConsumed("grepq", options);
+ }
vector<string> vec;
- auto str=boost::get<string>(&inp);
- if(str)
+ auto str = boost::get<string>(&inp);
+ if (str) {
vec.push_back(*str);
+ }
else {
auto v = boost::get<LuaArray<std::string>>(inp);
- for(const auto& a: v)
+ for (const auto& a: v) {
vec.push_back(a.second);
+ }
}
- for(const auto& s : vec) {
- try
- {
+ for (const auto& s : vec) {
+ try {
nm = Netmask(s);
- }
- catch(...) {
- if(boost::ends_with(s,"ms") && sscanf(s.c_str(), "%ums", &msec)) {
+ }
+ catch (...) {
+ if (boost::ends_with(s,"ms") && sscanf(s.c_str(), "%ums", &msec)) {
;
}
else {
- try { dn=DNSName(s); }
- catch(...)
- {
- g_outputBuffer = "Could not parse '"+s+"' as domain name or netmask";
- return;
- }
+ try {
+ dn = DNSName(s);
+ }
+ catch (...) {
+ g_outputBuffer = "Could not parse '"+s+"' as domain name or netmask";
+ return;
+ }
}
}
}
std::multimap<struct timespec, string> out;
- boost::format fmt("%-7.1f %-47s %-12s %-12s %-5d %-25s %-5s %-6.1f %-2s %-2s %-2s %-s\n");
- g_outputBuffer+= (fmt % "Time" % "Client" % "Protocol" % "Server" % "ID" % "Name" % "Type" % "Lat." % "TC" % "RD" % "AA" % "Rcode").str();
+ boost::format fmt("%-7.1f %-47s %-12s %-12s %-5d %-25s %-5s %-6.1f %-2s %-2s %-2s %-s\n");
+ const auto headLine = (fmt % "Time" % "Client" % "Protocol" % "Server" % "ID" % "Name" % "Type" % "Lat." % "TC" % "RD" % "AA" % "Rcode").str();
+ if (!outputFile) {
+ g_outputBuffer += headLine;
+ }
+ else {
+ fprintf(outputFile.get(), "%s", headLine.c_str());
+ }
- if(msec==-1) {
- for(const auto& c : qr) {
- bool nmmatch=true, dnmatch=true;
+ if (msec == -1) {
+ for (const auto& c : qr) {
+ bool nmmatch = true;
+ bool dnmatch = true;
if (nm) {
nmmatch = nm->match(c.requestor);
}
}
out.emplace(c.when, (fmt % DiffTime(now, c.when) % c.requestor.toStringWithPort() % dnsdist::Protocol(c.protocol).toString() % "" % htons(c.dh.id) % c.name.toString() % qt.toString() % "" % (c.dh.tc ? "TC" : "") % (c.dh.rd ? "RD" : "") % (c.dh.aa ? "AA" : "") % ("Question" + extra)).str());
- if(limit && *limit==++num)
+ if (limit && *limit == ++num) {
break;
+ }
}
}
}
- num=0;
-
+ num = 0;
string extra;
- for(const auto& c : rr) {
- bool nmmatch=true, dnmatch=true, msecmatch=true;
+ for (const auto& c : rr) {
+ bool nmmatch = true;
+ bool dnmatch = true;
+ bool msecmatch = true;
if (nm) {
nmmatch = nm->match(c.requestor);
}
}
}
if (msec != -1) {
- msecmatch=(c.usec/1000 > (unsigned int)msec);
+ msecmatch = (c.usec/1000 > (unsigned int)msec);
}
if (nmmatch && dnmatch && msecmatch) {
QType qt(c.qtype);
if (!c.dh.rcode) {
- extra=". " +std::to_string(htons(c.dh.ancount))+ " answers";
+ extra = ". " +std::to_string(htons(c.dh.ancount)) + " answers";
}
else {
extra.clear();
}
}
- for(const auto& p : out) {
- g_outputBuffer+=p.second;
+ for (const auto& p : out) {
+ if (!outputFile) {
+ g_outputBuffer += p.second;
+ }
+ else {
+ fprintf(outputFile.get(), "%s", p.second.c_str());
+ }
}
});
return;
}
- g_outputBuffer = (boost::format("Average response latency: %.02f msec\n") % (0.001*totlat/size)).str();
+ g_outputBuffer = (boost::format("Average response latency: %.02f ms\n") % (0.001*totlat/size)).str();
double highest=0;
for(auto iter = histo.cbegin(); iter != histo.cend(); ++iter) {
highest=std::max(highest, iter->second*1.0);
}
boost::format fmt("%7.2f\t%s\n");
- g_outputBuffer += (fmt % "msec" % "").str();
+ g_outputBuffer += (fmt % "ms" % "").str();
for(auto iter = histo.cbegin(); iter != histo.cend(); ++iter) {
int stars = (70.0 * iter->second/highest);
return getUniqueID(id);
}
-void parseRuleParams(boost::optional<luaruleparams_t> params, boost::uuids::uuid& uuid, std::string& name, uint64_t& creationOrder)
+void parseRuleParams(boost::optional<luaruleparams_t>& params, boost::uuids::uuid& uuid, std::string& name, uint64_t& creationOrder)
{
static uint64_t s_creationOrder = 0;
}
}
double udiff = sw.udiff();
- g_outputBuffer=(boost::format("Had %d matches out of %d, %.1f qps, in %.1f usec\n") % matches % times % (1000000*(1.0*times/udiff)) % udiff).str();
+ g_outputBuffer=(boost::format("Had %d matches out of %d, %.1f qps, in %.1f us\n") % matches % times % (1000000*(1.0*times/udiff)) % udiff).str();
});
getOptionalValue<bool>(vars, "useClientSubnet", config.useECS);
getOptionalValue<bool>(vars, "useProxyProtocol", config.useProxyProtocol);
- getOptionalValue<bool>(vars, "disableZeroScoping", config.disableZeroScope);
+ getOptionalValue<bool>(vars, "disableZeroScope", config.disableZeroScope);
getOptionalValue<bool>(vars, "ipBindAddrNoPort", config.ipBindAddrNoPort);
getOptionalIntegerValue("newServer", vars, "addXPF", config.xpfRRCode);
using nmts_t = NetmaskTree<DynBlock, AddressAndPortRange>;
std::shared_ptr<DNSRule> makeRule(const luadnsrule_t& var);
-void parseRuleParams(boost::optional<luaruleparams_t> params, boost::uuids::uuid& uuid, std::string& name, uint64_t& creationOrder);
+void parseRuleParams(boost::optional<luaruleparams_t>& params, boost::uuids::uuid& uuid, std::string& name, uint64_t& creationOrder);
void checkParameterBound(const std::string& parameter, uint64_t value, size_t max = std::numeric_limits<uint16_t>::max());
vector<std::function<void(void)>> setupLua(LuaContext& luaCtx, bool client, bool configCheck, const std::string& config);
if (currentResponse.d_idstate.selfGenerated == false && ds) {
const auto& ids = currentResponse.d_idstate;
double udiff = ids.queryRealTime.udiff();
- vinfolog("Got answer from %s, relayed to %s (%s, %d bytes), took %f usec", ds->d_config.remote.toStringWithPort(), ids.origRemote.toStringWithPort(), (state->d_handler.isTLS() ? "DoT" : "TCP"), currentResponse.d_buffer.size(), udiff);
+ vinfolog("Got answer from %s, relayed to %s (%s, %d bytes), took %f us", ds->d_config.remote.toStringWithPort(), ids.origRemote.toStringWithPort(), (state->d_handler.isTLS() ? "DoT" : "TCP"), currentResponse.d_buffer.size(), udiff);
auto backendProtocol = ds->getProtocol();
if (backendProtocol == dnsdist::Protocol::DoUDP) {
if (!selfGenerated) {
double udiff = ids.queryRealTime.udiff();
if (!muted) {
- vinfolog("Got answer from %s, relayed to %s (UDP), took %f usec", ds->d_config.remote.toStringWithPort(), ids.origRemote.toStringWithPort(), udiff);
+ vinfolog("Got answer from %s, relayed to %s (UDP), took %f us", ds->d_config.remote.toStringWithPort(), ids.origRemote.toStringWithPort(), udiff);
}
else {
- vinfolog("Got answer from %s, NOT relayed to %s (UDP) since that frontend is muted, took %f usec", ds->d_config.remote.toStringWithPort(), ids.origRemote.toStringWithPort(), udiff);
+ vinfolog("Got answer from %s, NOT relayed to %s (UDP) since that frontend is muted, took %f us", ds->d_config.remote.toStringWithPort(), ids.origRemote.toStringWithPort(), udiff);
}
handleResponseSent(ids, udiff, dr.ids.origRemote, ds->d_config.remote, response.size(), cleartextDH, ds->getProtocol(), true);
Changelog
=========
+.. changelog::
+ :version: 1.7.4
+ :released: 14th of April 2023
+
+ .. change::
+ :tags: Bug Fixes
+ :pullreq: 12183
+ :tickets: 12177
+
+ Fix building with boost < 1.56
+
+ .. change::
+ :tags: Bug Fixes
+ :pullreq: 12460
+ :tickets: 12453
+
+ lock.hh: include <stdexcept>
+
+ .. change::
+ :tags: Bug Fixes
+ :pullreq: 12569
+
+ dnsdist-protocols.hh: include <cstdint> (Sander Hoentjen)
+
+ .. change::
+ :tags: New Features
+ :pullreq: 12621
+ :tickets: 12074
+
+ Add getPoolNames() function, returning a list of pool names (Christof Chen)
+
+ .. change::
+ :tags: Bug Fixes
+ :pullreq: 12535
+
+ Fix the formatting of 'showServers'
+
+ .. change::
+ :tags: Bug Fixes
+ :pullreq: 12529
+ :tickets: 11905
+
+ Properly record the incoming flags on a timeout
+
+ .. change::
+ :tags: Bug Fixes, Metrics
+ :pullreq: 12484
+ :tickets: 11498
+
+ Properly update rcode-related metrics on RCodeAction hits
+
+ .. change::
+ :tags: Bug Fixes, DNS over TLS, DNS over HTTPS
+ :pullreq: 12421
+ :tickets: 12341
+
+ Skip invalid OCSP files after issuing a warning
+
+ .. change::
+ :tags: Bug Fixes
+ :pullreq: 12365
+ :tickets: 12357
+
+ Prevent an underflow of the TCP d_queued counter
+
+ .. change::
+ :tags: Bug Fixes, DNS over HTTPS
+ :pullreq: 12327
+
+ Fix the health-check timeout computation for DoH backend
+
+ .. change::
+ :tags: Bug Fixes, Webserver
+ :pullreq: 12260
+ :tickets: 9349
+
+ Properly encode json strings containing binary data
+
+ .. change::
+ :tags: Bug Fixes, DNS over TLS
+ :pullreq: 12237
+ :tickets: 12236
+
+ Ignore unclean TLS session shutdown
+
+ .. change::
+ :tags: Bug Fixes
+ :pullreq: 12100
+ :tickets: 12099
+
+ Properly handle single-SOA XFR responses
+
+ .. change::
+ :tags: Bug Fixes
+ :pullreq: 11830
+ :tickets: 4155
+
+ Also reconnect on ENETUNREACH. (Asgeir Storesund Nilsen)
+
+ .. change::
+ :tags: Bug Fixes
+ :pullreq: 11729
+ :tickets: 11728
+
+ Fix a bug in SetEDNSOptionAction
+
+ .. change::
+ :tags: Bug Fixes
+ :pullreq: 11718
+
+ Fix the number of concurrent queries on a backend TCP conn
+
+.. changelog::
+ :version: 1.8.0
+ :released: 30th of March 2023
+
+ .. change::
+ :tags: Bug Fixes
+ :pullreq: 12687
+
+ Fix 'Unknown key' issue for actions and rules parameters
+
+ .. change::
+ :tags: Bug Fixes
+ :pullreq: 12672
+
+ Fix a dnsheader unaligned case
+
+ .. change::
+ :tags: Bug Fixes
+ :pullreq: 12654
+
+ secpoll: explicitly include necessary ctime header for time_t
+
.. changelog::
:version: 1.8.0-rc3
:released: 16th of March 2023
:tags: New Features, DNS over HTTPS, DNS over TLS
:pullreq: 11027
- Add support for password protected PCKS12 files for TLS configuration
+ Add support for password protected PKCS12 files for TLS configuration
.. change::
:tags: New Features
- Release date
- Security-Only updates
- End of Life
+ * - 1.8
+ - March 30 2023
+ -
+ -
* - 1.7
- January 17 2022
- -
+ - March 30 2023
-
* - 1.6
- May 11 2021
- -
+ - March 30 2023
-
* - 1.5
- July 30 2020
- January 17 2022
- -
+ - EOL (March 30 2023)
* - 1.4
- November 20 2019
- May 2021
:param int top: How many rules to return. Default is 10.
-.. function:: grepq(selector[, num])
- grepq(selectors[, num])
+.. function:: grepq(selector[, num [, options]])
+ grepq(selectors[, num [, options]])
+
+ .. versionchanged:: 1.9.0
+ ``options`` optional parameter table added.
Prints the last ``num`` queries and responses matching ``selector`` or ``selectors``.
Queries and responses are accounted in separate ring buffers, and answers from the packet cache are not stored in the response ring buffer.
:param str selector: Select queries based on this property.
:param {str} selectors: A lua table of selectors. Only queries matching all selectors are shown
- :param int num: Show a maximum of ``num`` recent queries+responses, default is 10.
+ :param int num: Show a maximum of ``num`` recent queries+responses.
+ :param table options: A table with key: value pairs with options described below.
+
+ Options:
+
+ * ``outputFile=path``: string - Write the output of the command to the supplied file, instead of the standard output.
.. function:: setVerbose(verbose)
PKCS12 files are only supported by the ``openssl`` provider, password-protected or not.
- :param string pathToCert: Path to a file containing the certificate or a PCKS12 file containing both a certificate and a key.
+ :param string pathToCert: Path to a file containing the certificate or a PKCS12 file containing both a certificate and a key.
:param table options: A table with key: value pairs with additional options.
Options:
* ``key="path/to/key"``: string - Path to a file containing the key corresponding to the certificate.
- * ``password="pass"``: string - Password protecting the PCKS12 file if appropriate.
+ * ``password="pass"``: string - Password protecting the PKCS12 file if appropriate.
.. code-block:: lua
newTLSCertificate("path/to/pub.crt", {key="path/to/private.pem"})
- newTLSCertificate("path/to/domain.p12", {password="passphrase"}) -- use a password protected PCKS12 file
+ newTLSCertificate("path/to/domain.p12", {password="passphrase"}) -- use a password protected PKCS12 file
DOHFrontend
~~~~~~~~~~~
:param table options: A table with key: value pairs with options.
Options:
+
* ``ipv4MaxItems``: int - The maximum number of entries in the IPv4 map. Default is 0 which will not allow any entry at all.
* ``ipv4PinnedPath``: str - The filesystem path this map should be pinned to.
* ``ipv6MaxItems``: int - The maximum number of entries in the IPv6 map. Default is 0 which will not allow any entry at all.
* ``cidr6PinnedPath``: str - The filesystem path this map should be pinned to.
* ``qnamesMaxItems``: int - The maximum number of entries in the qname map. Default is 0 which will not allow any entry at all.
* ``qnamesPinnedPath``: str - The filesystem path this map should be pinned to.
- * ``external``: bool - If set to true, DNSDist can to load the internal eBPF program.
+ * ``external``: bool - If set to true, DNSDist does not load the internal eBPF program.
.. function:: newDynBPFFilter(bpf) -> DynBPFFilter
if (!du->ids.selfGenerated) {
double udiff = du->ids.queryRealTime.udiff();
- vinfolog("Got answer from %s, relayed to %s (https), took %f usec", du->downstream->d_config.remote.toStringWithPort(), du->ids.origRemote.toStringWithPort(), udiff);
+ vinfolog("Got answer from %s, relayed to %s (https), took %f us", du->downstream->d_config.remote.toStringWithPort(), du->ids.origRemote.toStringWithPort(), udiff);
auto backendProtocol = du->downstream->getProtocol();
if (backendProtocol == dnsdist::Protocol::DoUDP && du->tcp) {
du = std::move(dr.ids.du);
double udiff = du->ids.queryRealTime.udiff();
- vinfolog("Got answer from %s, relayed to %s (https), took %f usec", du->downstream->d_config.remote.toStringWithPort(), du->ids.origRemote.toStringWithPort(), udiff);
+ vinfolog("Got answer from %s, relayed to %s (https), took %f us", du->downstream->d_config.remote.toStringWithPort(), du->ids.origRemote.toStringWithPort(), udiff);
handleResponseSent(du->ids, udiff, dr.ids.origRemote, du->downstream->d_config.remote, du->response.size(), cleartextDH, du->downstream->getProtocol(), true);
DNSName DNSName::getCommonLabels(const DNSName& other) const
{
- DNSName result;
+ if (empty() || other.empty()) {
+ return DNSName();
+ }
+
+ DNSName result(g_rootdnsname);
const std::vector<std::string> ours = getRawLabels();
const std::vector<std::string> others = other.getRawLabels();
cout.precision(2);
for(unsigned int i =0 ; i < sizeof(limits)/sizeof(limits[0]); ++i) {
if(limits[i]!=flightTimes.size())
- cout<<"Within "<<limits[i]<<" msec: ";
+ cout<<"Within "<<limits[i]<<" ms: ";
else
- cout<<"Beyond "<<limits[i]-2<<" msec: ";
+ cout<<"Beyond "<<limits[i]-2<<" ms: ";
uint64_t here = countLessThan(limits[i]);
cout<<100.0*here/totals<<"% ("<<100.0*(here-sofar)/totals<<"%)"<<endl;
sofar=here;
perc=sum*100.0/totpairs;
if(j->first < 1024)
- cout<< perc <<"% of questions answered within " << j->first << " usec (";
+ cout<< perc <<"% of questions answered within " << j->first << " us (";
else
- cout<< perc <<"% of questions answered within " << j->first/1000.0 << " msec (";
+ cout<< perc <<"% of questions answered within " << j->first/1000.0 << " ms (";
cout<<perc-lastperc<<"%)\n";
lastperc=sum*100.0/totpairs;
if(!j->second) {
perc=sum*100.0/totpairs;
if(j->first < 1024)
- cout<< perc <<"% of questions answered within " << j->first << " usec (";
+ cout<< perc <<"% of questions answered within " << j->first << " us (";
else
- cout<< perc <<"% of questions answered within " << j->first/1000.0 << " msec (";
+ cout<< perc <<"% of questions answered within " << j->first/1000.0 << " ms (";
cout<<perc-lastperc<<"%)\n";
lastperc=sum*100.0/totpairs;
cout<< (totpairs-lastsum)<<" responses ("<<((totpairs-lastsum)*100.0/answers) <<"%) older than "<< (done.rbegin()->first/1000000.0) <<" seconds"<<endl;
if(totpairs)
- cout<<"Average non-late response time: "<<tottime/totpairs<<" usec"<<endl;
+ cout<<"Average non-late response time: "<<tottime/totpairs<<" us"<<endl;
if(!g_vm["load-stats"].as<string>().empty()) {
ofstream load(g_vm["load-stats"].as<string>().c_str());
if(verified) {
udiffVerify = dt.udiff() / 100;
- cout<<"Signature & verify ok, create "<<udiffCreate<<"usec, signature "<<udiffSign<<"usec, verify "<<udiffVerify<<"usec"<<endl;
+ cout<<"Signature & verify ok, create "<<udiffCreate<<"us, signature "<<udiffSign<<"us, verify "<<udiffVerify<<"us"<<endl;
}
else {
throw runtime_error("Verification of creator "+dckeCreate->getName()+" with signer "+dckeSign->getName()+" and verifier "+dckeVerify->getName()+" failed");
{
stable_sort(rrs.begin(), rrs.end(), rrsigncomp);
- DNSName signQName, wildcardQName;
+ DNSName authQName, signQName, wildcardQName;
uint16_t signQType=0;
uint32_t signTTL=0;
uint32_t origTTL=0;
DNSName signer;
for(auto pos = rrs.cbegin(); pos != rrs.cend(); ++pos) {
if(pos != rrs.cbegin() && (signQType != pos->dr.d_type || signQName != pos->dr.d_name)) {
- if(getBestAuthFromSet(authSet, signQName, signer))
+ if (getBestAuthFromSet(authSet, authQName, signer))
addSignature(dk, db, signer, signQName, wildcardQName, signQType, signTTL, signPlace, toSign, signedRecords, origTTL);
}
signedRecords.push_back(*pos);
- signQName= pos->dr.d_name.makeLowerCase();
+ signQName = pos->dr.d_name.makeLowerCase();
+ if (pos->dr.d_type == QType::NSEC) {
+ authQName = signQName.getCommonLabels(getRR<NSECRecordContent>(pos->dr)->d_next);
+ }
+ else {
+ authQName = signQName;
+ }
if(!pos->wildcardname.empty())
wildcardQName = pos->wildcardname.makeLowerCase();
else
toSign.insert(pos->dr.getContent()); // so ponder.. should this be a deep copy perhaps?
}
}
- if(getBestAuthFromSet(authSet, signQName, signer))
+ if (getBestAuthFromSet(authSet, authQName, signer))
addSignature(dk, db, signer, signQName, wildcardQName, signQType, signTTL, signPlace, toSign, signedRecords, origTTL);
rrs.swap(signedRecords);
}
if(g_verbose) {
cout<<"Sending queries to: "<<g_dest.toStringWithPort()<<endl;
cout<<"Attempting UDP first: " << (g_onlyTCP ? "no" : "yes") <<endl;
- cout<<"Timeout: "<< g_timeoutMsec<<"msec"<<endl;
+ cout<<"Timeout: "<< g_timeoutMsec<<" ms"<<endl;
cout << "Using TCP_NODELAY: "<<g_tcpNoDelay<<endl;
}
}
cout<<"Average qps: "<<mean(qps)<<", median qps: "<<median(qps)<<endl;
- cout<<"Average UDP latency: "<<mean(udpspeeds)<<"usec, median: "<<median(udpspeeds)<<"usec"<<endl;
- cout<<"Average TCP latency: "<<mean(tcpspeeds)<<"usec, median: "<<median(tcpspeeds)<<"usec"<<endl;
+ cout<<"Average UDP latency: "<<mean(udpspeeds)<<" us, median: "<<median(udpspeeds)<<" us"<<endl;
+ cout<<"Average TCP latency: "<<mean(tcpspeeds)<<" us, median: "<<median(tcpspeeds)<<" us"<<endl;
cout<<"OK: "<<g_OK<<", network errors: "<<g_networkErrors<<", other errors: "<<g_otherErrors<<endl;
cout<<"Timeouts: "<<g_timeOuts<<endl;
bool GssContext::supported() { return false; }
GssContext::GssContext() :
d_error(GSS_CONTEXT_UNSUPPORTED), d_type(GSS_CONTEXT_NONE) {}
-GssContext::GssContext(const DNSName& label) :
+GssContext::GssContext(const DNSName& /* label */) :
d_error(GSS_CONTEXT_UNSUPPORTED), d_type(GSS_CONTEXT_NONE) {}
-void GssContext::setLocalPrincipal(const std::string& name) {}
-bool GssContext::getLocalPrincipal(std::string& name) { return false; }
-void GssContext::setPeerPrincipal(const std::string& name) {}
-bool GssContext::getPeerPrincipal(std::string& name) { return false; }
-void GssContext::generateLabel(const std::string& suffix) {}
-void GssContext::setLabel(const DNSName& label) {}
-bool GssContext::init(const std::string& input, std::string& output) { return false; }
-bool GssContext::accept(const std::string& input, std::string& output) { return false; }
+void GssContext::setLocalPrincipal(const std::string& /* name */) {}
+bool GssContext::getLocalPrincipal(std::string& /* name */) { return false; }
+void GssContext::setPeerPrincipal(const std::string& /* name */) {}
+bool GssContext::getPeerPrincipal(std::string& /* name */) { return false; }
+void GssContext::generateLabel(const std::string& /* suffix */) {}
+void GssContext::setLabel(const DNSName& /* label */) {}
+bool GssContext::init(const std::string& /* input */, std::string& /* output */) { return false; }
+bool GssContext::accept(const std::string& /* input */, std::string& /* output */) { return false; }
bool GssContext::destroy() { return false; }
bool GssContext::expired() { return false; }
bool GssContext::valid() { return false; }
-bool GssContext::sign(const std::string& input, std::string& output) { return false; }
-bool GssContext::verify(const std::string& input, const std::string& signature) { return false; }
+bool GssContext::sign(const std::string& /* input */, std::string& /* output */) { return false; }
+bool GssContext::verify(const std::string& /* input */, const std::string& /* signature */) { return false; }
GssContextError GssContext::getError() { return GSS_CONTEXT_UNSUPPORTED; }
#else
setName(name);
};
+#ifdef ENABLE_GSS_TSIG
//! Parse name into native representation
bool setName(const std::string& name)
{
-#ifdef ENABLE_GSS_TSIG
gss_buffer_desc buffer;
d_name = GSS_C_NO_NAME;
}
return true;
-#endif
+ }
+#else
+ bool setName(const std::string& /* name */)
+ {
return false;
- };
+ }
+#endif
~GssName()
{
#endif
};
+#ifdef ENABLE_GSS_TSIG
//! Compare two Gss Names, if no gss support is compiled in, returns false always
//! This is not necessarily same as string comparison between two non-parsed names
bool operator==(const GssName& rhs)
{
-#ifdef ENABLE_GSS_TSIG
OM_uint32 maj, min;
int result;
maj = gss_compare_name(&min, d_name, rhs.d_name, &result);
return (maj == GSS_S_COMPLETE && result != 0);
-#endif
+ }
+#else
+ bool operator==(const GssName& /* rhs */)
+ {
return false;
}
+#endif
+#ifdef ENABLE_GSS_TSIG
//! Compare two Gss Names, if no gss support is compiled in, returns false always
//! This is not necessarily same as string comparison between two non-parsed names
bool match(const std::string& name)
{
-#ifdef ENABLE_GSS_TSIG
OM_uint32 maj, min;
int result;
gss_name_t comp;
maj = gss_compare_name(&min, d_name, comp, &result);
gss_release_name(&min, &comp);
return (maj == GSS_S_COMPLETE && result != 0);
+ }
#else
+ bool match(const std::string& /* name */)
+ {
return false;
+ }
#endif
- };
//! Check if GSS name was parsed successfully.
bool valid()
return ret;
}
-void setSocketIgnorePMTU(int sockfd, int family)
+void setSocketIgnorePMTU([[maybe_unused]] int sockfd, [[maybe_unused]] int family)
{
if (family == AF_INET) {
#if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
// Why a struct? This way we can add more options to a domain in the future
struct ixfrdistdomain_t {
set<ComboAddress> masters; // A set so we can do multiple master addresses in the future
+ uint32_t maxSOARefresh{0}; // Cap SOA refresh value to the given value in seconds
};
// This contains the configuration for each domain
}
auto& zoneLastCheck = lastCheck[domain];
- if ((current_soa != nullptr && now - zoneLastCheck < current_soa->d_st.refresh) || // Only check if we have waited `refresh` seconds
- (current_soa == nullptr && now - zoneLastCheck < soaRetry)) { // Or if we could not get an update at all still, every 30 seconds
+ uint32_t refresh = soaRetry; // default if we don't get an update at all
+ if (current_soa != nullptr) {
+ // Check every `refresh` seconds as advertised in the SOA record
+ refresh = current_soa->d_st.refresh;
+ if (domainConfig.second.maxSOARefresh > 0) {
+ // Cap refresh value to the configured one if any
+ refresh = std::min(refresh, domainConfig.second.maxSOARefresh);
+ }
+ }
+ if (now - zoneLastCheck < refresh) {
continue;
}
g_log<<Logger::Error<<"Unable to read domain '"<<domain["domain"].as<string>()<<"' master address: "<<e.what()<<endl;
retval = false;
}
+ if (domain["max-soa-refresh"]) {
+ try {
+ config["max-soa-refresh"].as<uint32_t>();
+ } catch (const runtime_error &e) {
+ g_log<<Logger::Error<<"Unable to read 'max-soa-refresh' value for domain '"<<domain["domain"].as<string>()<<"': "<<e.what()<<endl;
+ }
+ }
}
} else {
g_log<<Logger::Error<<"No domains configured"<<endl;
set<ComboAddress> s;
s.insert(domain["master"].as<ComboAddress>());
g_domainConfigs[domain["domain"].as<DNSName>()].masters = s;
+ if (domain["max-soa-refresh"]) {
+ g_domainConfigs[domain["domain"].as<DNSName>()].maxSOARefresh = domain["max-soa-refresh"].as<uint32_t>();
+ }
g_stats.registerDomain(domain["domain"].as<DNSName>());
}
# When no port is specified, 53 is used. When specifying ports for IPv6, use the
# "bracket" notation:
#
+# You can optionally cap the refresh time of the SOA using 'max-soa-refresh' (seconds)
+# Otherwise, or if set to 0, the retreived SOA refresh time will be used
+#
# domains:
# - domain: example.com
# master: 192.0.2.15
+# max-soa-refresh: 180
# - domain: rpz.example
# master: [2001:DB8:a34:543::53]:5353
#
}
#if OPENSSL_VERSION_MAJOR >= 3
-int libssl_ticket_key_callback(SSL* s, OpenSSLTLSTicketKeysRing& keyring, unsigned char keyName[TLS_TICKETS_KEY_NAME_SIZE], unsigned char* iv, EVP_CIPHER_CTX* ectx, EVP_MAC_CTX* hctx, int enc)
+int libssl_ticket_key_callback(SSL* /* s */, OpenSSLTLSTicketKeysRing& keyring, unsigned char keyName[TLS_TICKETS_KEY_NAME_SIZE], unsigned char* iv, EVP_CIPHER_CTX* ectx, EVP_MAC_CTX* hctx, int enc)
#else
-int libssl_ticket_key_callback(SSL* s, OpenSSLTLSTicketKeysRing& keyring, unsigned char keyName[TLS_TICKETS_KEY_NAME_SIZE], unsigned char* iv, EVP_CIPHER_CTX* ectx, HMAC_CTX* hctx, int enc)
+int libssl_ticket_key_callback(SSL* /* s */, OpenSSLTLSTicketKeysRing& keyring, unsigned char keyName[TLS_TICKETS_KEY_NAME_SIZE], unsigned char* iv, EVP_CIPHER_CTX* ectx, HMAC_CTX* hctx, int enc)
#endif
{
if (enc != 0) {
return SSL_TLSEXT_ERR_NOACK;
}
-static void libssl_info_callback(const SSL *ssl, int where, int ret)
+static void libssl_info_callback(const SSL *ssl, int where, int /* ret */)
{
SSL_CTX* sslCtx = SSL_get_SSL_CTX(ssl);
if (sslCtx == nullptr) {
file.close();
}
-void OpenSSLTLSTicketKeysRing::rotateTicketsKey(time_t now)
+void OpenSSLTLSTicketKeysRing::rotateTicketsKey(time_t /* now */)
{
auto newKey = std::make_shared<OpenSSLTLSTicketKey>();
addKey(newKey);
}
}
-
static std::string getGeo(const std::string& ip, GeoIPInterface::GeoIPQueryAttribute qa)
{
static bool initialized;
return result;
}
-static vector<ComboAddress> convComboAddressList(const iplist_t& items)
+static vector<ComboAddress> convComboAddressList(const iplist_t& items, uint16_t port=0)
{
vector<ComboAddress> result;
result.reserve(items.size());
for(const auto& item : items) {
- result.emplace_back(ComboAddress(item.second));
+ result.emplace_back(ComboAddress(item.second, port));
}
return result;
}
+/**
+ * Reads and unify single or multiple sets of ips :
+ * - {'192.0.2.1', '192.0.2.2'}
+ * - {{'192.0.2.1', '192.0.2.2'}, {'198.51.100.1'}}
+ */
+
+static vector<vector<ComboAddress>> convMultiComboAddressList(const boost::variant<iplist_t, ipunitlist_t>& items, uint16_t port = 0)
+{
+ vector<vector<ComboAddress>> candidates;
+
+ if(auto simple = boost::get<iplist_t>(&items)) {
+ vector<ComboAddress> unit = convComboAddressList(*simple, port);
+ candidates.push_back(unit);
+ } else {
+ auto units = boost::get<ipunitlist_t>(items);
+ for(const auto& u : units) {
+ vector<ComboAddress> unit = convComboAddressList(u.second, port);
+ candidates.push_back(unit);
+ }
+ }
+ return candidates;
+}
+
static vector<string> convStringList(const iplist_t& items)
{
vector<string> result;
static thread_local unique_ptr<lua_record_ctx_t> s_lua_record_ctx;
+static vector<string> genericIfUp(const boost::variant<iplist_t, ipunitlist_t>& ips, boost::optional<opts_t> options, std::function<bool(const ComboAddress&, const opts_t&)> upcheckf, uint16_t port = 0) {
+ vector<vector<ComboAddress> > candidates;
+ opts_t opts;
+ if(options)
+ opts = *options;
+
+ candidates = convMultiComboAddressList(ips, port);
+
+ for(const auto& unit : candidates) {
+ vector<ComboAddress> available;
+ for(const auto& c : unit) {
+ if (upcheckf(c, opts)) {
+ available.push_back(c);
+ }
+ }
+ if(!available.empty()) {
+ vector<ComboAddress> res = useSelector(getOptionValue(options, "selector", "random"), s_lua_record_ctx->bestwho, available);
+ return convComboAddressListToString(res);
+ }
+ }
+
+ // All units down, apply backupSelector on all candidates
+ vector<ComboAddress> ret{};
+ for(const auto& unit : candidates) {
+ ret.insert(ret.end(), unit.begin(), unit.end());
+ }
+
+ vector<ComboAddress> res = useSelector(getOptionValue(options, "backupSelector", "random"), s_lua_record_ctx->bestwho, ret);
+ return convComboAddressListToString(res);
+}
+
static void setupLuaRecords(LuaContext& lua)
{
lua.writeFunction("latlon", []() {
*
* @example ifportup(443, { '1.2.3.4', '5.4.3.2' })"
*/
- lua.writeFunction("ifportup", [](int port, const vector<pair<int, string> >& ips, const boost::optional<std::unordered_map<string,string>> options) {
- vector<ComboAddress> candidates, unavailables;
- opts_t opts;
- vector<ComboAddress > conv;
- std::string selector;
-
- if(options)
- opts = *options;
- for(const auto& i : ips) {
- ComboAddress rem(i.second, port);
- if(g_up.isUp(rem, opts)) {
- candidates.push_back(rem);
- }
- else {
- unavailables.push_back(rem);
- }
+ lua.writeFunction("ifportup", [](int port, const boost::variant<iplist_t, ipunitlist_t>& ips, const boost::optional<std::unordered_map<string,string>> options) {
+ if (port < 0) {
+ port = 0;
}
- if(!candidates.empty()) {
- // use regular selector
- selector = getOptionValue(options, "selector", "random");
- } else {
- // All units are down, apply backupSelector on all candidates
- candidates = std::move(unavailables);
- selector = getOptionValue(options, "backupSelector", "random");
+ if (port > std::numeric_limits<uint16_t>::max()) {
+ port = std::numeric_limits<uint16_t>::max();
}
- vector<ComboAddress> res = useSelector(selector, s_lua_record_ctx->bestwho, candidates);
- return convComboAddressListToString(res);
+ auto checker = [](const ComboAddress& addr, const opts_t& opts) {
+ return g_up.isUp(addr, opts);
+ };
+ return genericIfUp(ips, options, checker, port);
});
lua.writeFunction("ifurlextup", [](const vector<pair<int, opts_t> >& ipurls, boost::optional<opts_t> options) {
lua.writeFunction("ifurlup", [](const std::string& url,
const boost::variant<iplist_t, ipunitlist_t>& ips,
boost::optional<opts_t> options) {
- vector<vector<ComboAddress> > candidates;
- opts_t opts;
- if(options)
- opts = *options;
- if(auto simple = boost::get<iplist_t>(&ips)) {
- vector<ComboAddress> unit = convComboAddressList(*simple);
- candidates.push_back(unit);
- } else {
- auto units = boost::get<ipunitlist_t>(ips);
- for(const auto& u : units) {
- vector<ComboAddress> unit = convComboAddressList(u.second);
- candidates.push_back(unit);
- }
- }
- for(const auto& unit : candidates) {
- vector<ComboAddress> available;
- for(const auto& c : unit) {
- if(g_up.isUp(c, url, opts)) {
- available.push_back(c);
- }
- }
- if(!available.empty()) {
- vector<ComboAddress> res = useSelector(getOptionValue(options, "selector", "random"), s_lua_record_ctx->bestwho, available);
- return convComboAddressListToString(res);
- }
- }
-
- // All units down, apply backupSelector on all candidates
- vector<ComboAddress> ret{};
- for(const auto& unit : candidates) {
- ret.insert(ret.end(), unit.begin(), unit.end());
- }
-
- vector<ComboAddress> res = useSelector(getOptionValue(options, "backupSelector", "random"), s_lua_record_ctx->bestwho, ret);
- return convComboAddressListToString(res);
+ auto checker = [&url](const ComboAddress& addr, const opts_t& opts) {
+ return g_up.isUp(addr, url, opts);
+ };
+ return genericIfUp(ips, options, checker);
});
/*
* Returns a random IP address from the supplied list
void CommunicatorClass::notify(const DNSName &domain, const string &ip)
{
d_nq.add(domain, ip);
- d_any_sem.post();
}
return url.substr(pos, endpos-pos);
}
-void MiniCurl::setupURL(const std::string& str, const ComboAddress* rem, const ComboAddress* src, int timeout, size_t byteslimit, bool fastopen, bool verify)
+void MiniCurl::setupURL(const std::string& str, const ComboAddress* rem, const ComboAddress* src, int timeout, size_t byteslimit, [[maybe_unused]] bool fastopen, bool verify)
{
if (!d_fresh) {
curl_easy_reset(getCURLPtr(d_curl));
d_data.clear();
}
-std::string MiniCurl::getURL(const std::string& str, const ComboAddress* rem, const ComboAddress* src, int timeout, bool fastopen, bool verify, size_t byteslimit)
+std::string MiniCurl::getURL(const std::string& str, const ComboAddress* rem, const ComboAddress* src, int timeout, [[maybe_unused]] bool fastopen, bool verify, size_t byteslimit)
{
setupURL(str, rem, src, timeout, byteslimit, fastopen, verify);
auto res = curl_easy_perform(getCURLPtr(d_curl));
return flags & O_NONBLOCK;
}
-bool setReceiveSocketErrors(int sock, int af)
+bool setReceiveSocketErrors([[maybe_unused]] int sock, [[maybe_unused]] int af)
{
#ifdef __linux__
int tmp = 1, ret;
return foundMAC ? 0 : ENOENT;
}
#else
-int getMACAddress(const ComboAddress& ca, char* dest, size_t len)
+int getMACAddress(const ComboAddress& /* ca */, char* /* dest */, size_t /* len */)
{
return ENOENT;
}
return ret;
}
-uint64_t udpErrorStats(const std::string& str)
+uint64_t udpErrorStats([[maybe_unused]] const std::string& str)
{
#ifdef __linux__
ifstream ifs("/proc/net/snmp");
return 0;
}
-uint64_t udp6ErrorStats(const std::string& str)
+uint64_t udp6ErrorStats([[maybe_unused]] const std::string& str)
{
#ifdef __linux__
const std::map<std::string, std::string> keys = {
#endif
}
-int mapThreadToCPUList(pthread_t tid, const std::set<int>& cpus)
+int mapThreadToCPUList([[maybe_unused]] pthread_t tid, [[maybe_unused]] const std::set<int>& cpus)
{
#ifdef HAVE_PTHREAD_SETAFFINITY_NP
# ifdef __NetBSD__
return results;
}
-size_t getPipeBufferSize(int fd)
+size_t getPipeBufferSize([[maybe_unused]] int fd)
{
#ifdef F_GETPIPE_SZ
int res = fcntl(fd, F_GETPIPE_SZ);
#endif /* F_GETPIPE_SZ */
}
-bool setPipeBufferSize(int fd, size_t size)
+bool setPipeBufferSize([[maybe_unused]] int fd, [[maybe_unused]] size_t size)
{
#ifdef F_SETPIPE_SZ
if (size > static_cast<size_t>(std::numeric_limits<int>::max())) {
return (int)d_len << 3;
}
-bool OpenSSLEDDSADNSCryptoKeyEngine::checkKey(std::optional<std::reference_wrapper<std::vector<std::string>>> errorMessages) const
+bool OpenSSLEDDSADNSCryptoKeyEngine::checkKey([[maybe_unused]] std::optional<std::reference_wrapper<std::vector<std::string>>> errorMessages) const
{
#if OPENSSL_VERSION_MAJOR >= 3
auto ctx = KeyContext{EVP_PKEY_CTX_new_from_pkey(nullptr, d_edkey.get(), nullptr), EVP_PKEY_CTX_free};
}
else if (cmds.at(0) == "clear-zone") {
if(cmds.size() != 2) {
- cerr<<"Syntax: pdnsutil edit-zone ZONE"<<endl;
+ cerr<<"Syntax: pdnsutil clear-zone ZONE"<<endl;
return 0;
}
if (cmds.at(1) == ".")
Comment c;
while(src->getComment(c)) {
c.domain_id = di_new.id;
- tgt->feedComment(c);
+ if (!tgt->feedComment(c)) {
+ throw PDNSException("Target backend does not support comments - remove them first");
+ }
nc++;
}
}
attr.push_back(P11KitAttribute(CKA_LABEL, d_label));
FindObjects2(*slot, attr, key, 1);
if (key.size() == 0) {
- g_log<<Logger::Warning<<"Cannot load PCKS#11 private key "<<d_label<<std::endl;;
+ g_log<<Logger::Warning<<"Cannot load PKCS#11 private key "<<d_label<<std::endl;;
return;
}
d_private_key = key[0];
attr.push_back(P11KitAttribute(CKA_LABEL, d_pub_label));
FindObjects2(*slot, attr, key, 1);
if (key.size() == 0) {
- g_log<<Logger::Warning<<"Cannot load PCKS#11 public key "<<d_pub_label<<std::endl;
+ g_log<<Logger::Warning<<"Cannot load PKCS#11 public key "<<d_pub_label<<std::endl;
return;
}
d_public_key = key[0];
d_exponent = attr[1].str();
d_bits = attr[2].ulong();
} else {
- throw PDNSException("Cannot load attributes for PCKS#11 public key " + d_pub_label);
+ throw PDNSException("Cannot load attributes for PKCS#11 public key " + d_pub_label);
}
} else if (d_key_type == CKK_EC || d_key_type == CKK_ECDSA) {
attr.clear();
if (attr[1].str().length() != (d_bits*2/8 + 3)) throw PDNSException("EC Point data invalid");
d_ec_point = attr[1].str().substr(3);
} else {
- throw PDNSException("Cannot load attributes for PCKS#11 public key " + d_pub_label);
+ throw PDNSException("Cannot load attributes for PKCS#11 public key " + d_pub_label);
}
} else {
- throw PDNSException("Cannot determine type for PCKS#11 public key " + d_pub_label);
+ throw PDNSException("Cannot determine type for PKCS#11 public key " + d_pub_label);
}
} else {
- throw PDNSException("Cannot load attributes for PCKS#11 public key " + d_pub_label);
+ throw PDNSException("Cannot load attributes for PKCS#11 public key " + d_pub_label);
}
d_loaded = true;
REVISION "202209120000Z"
DESCRIPTION "Added metrics for answers from auths by rcode"
+ REVISION "202302240000Z"
+ DESCRIPTION "Added metrics for sharded packet cache contention"
+
::= { powerdns 2 }
powerdns OBJECT IDENTIFIER ::= { enterprises 43315 }
"Number of rcode 15 answers received"
::= { stats 144 }
+packetCacheContended OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Number of contended packet cache lock acquisitions"
+ ::= { stats 145 }
+
+packetCacheAcquired OBJECT-TYPE
+ SYNTAX Counter64
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Number of packet cache lock acquisitions"
+ ::= { stats 146 }
+
---
--- Traps / Notifications
authrcode12Count,
authrcode13Count,
authrcode14Count,
- authrcode15Count
+ authrcode15Count,
+ packetCacheContended,
+ packetCacheAcquired
}
STATUS current
DESCRIPTION "Objects conformance group for PowerDNS Recursor"
}
/* the TTL is already a TTD by now */
- if (!nsec3 && isWildcardExpanded(owner.countLabels(), signatures.at(0))) {
+ if (!nsec3 && isWildcardExpanded(owner.countLabels(), *signatures.at(0))) {
DNSName realOwner = getNSECOwnerName(owner, signatures);
auto pair = zoneEntry->d_entries.insert({record.getContent(), signatures, std::move(realOwner), std::move(next), record.d_ttl});
if (pair.second) {
}
}
-static void addRecordToRRSet(time_t now, const DNSName& owner, const QType& type, uint32_t ttl, std::shared_ptr<const DNSRecordContent>& content, std::vector<std::shared_ptr<const RRSIGRecordContent>> signatures, bool doDNSSEC, std::vector<DNSRecord>& ret)
+static void addRecordToRRSet(const DNSName& owner, const QType& type, uint32_t ttl, std::shared_ptr<const DNSRecordContent>& content, std::vector<std::shared_ptr<const RRSIGRecordContent>> signatures, bool doDNSSEC, std::vector<DNSRecord>& ret)
{
DNSRecord nsecRec;
nsecRec.d_type = type.getCode();
addToRRSet(now, wcSet, wcSignatures, name, doDNSSEC, ret, DNSResourceRecord::ANSWER);
/* no need for closest encloser proof, the wildcard is there */
- addRecordToRRSet(now, nextCloser.d_owner, QType::NSEC3, nextCloser.d_ttd - now, nextCloser.d_record, nextCloser.d_signatures, doDNSSEC, ret);
+ addRecordToRRSet(nextCloser.d_owner, QType::NSEC3, nextCloser.d_ttd - now, nextCloser.d_record, nextCloser.d_signatures, doDNSSEC, ret);
/* and of course we won't deny the wildcard either */
VLOG(log, name << ": Synthesized valid answer from NSEC3s and wildcard!" << endl);
++d_nsec3WildcardHits;
+ res = RCode::NoError;
return true;
}
}
addToRRSet(now, wcSet, wcSignatures, name, doDNSSEC, ret, DNSResourceRecord::ANSWER);
- addRecordToRRSet(now, nsec.d_owner, QType::NSEC, nsec.d_ttd - now, nsec.d_record, nsec.d_signatures, doDNSSEC, ret);
+ addRecordToRRSet(nsec.d_owner, QType::NSEC, nsec.d_ttd - now, nsec.d_record, nsec.d_signatures, doDNSSEC, ret);
VLOG(log, name << ": Synthesized valid answer from NSECs and wildcard!" << endl);
++d_nsecWildcardHits;
+ res = RCode::NoError;
return true;
}
return false;
}
- if (!isTypeDenied(nsec3, type)) {
+ if (!isTypeDenied(*nsec3, type)) {
VLOG_NO_PREFIX(log, " but the requested type (" << type.toString() << ") does exist" << endl);
return false;
}
const DNSName signer = getSigner(exactNSEC3.d_signatures);
/* here we need to allow an ancestor NSEC3 proving that a DS does not exist as it is an
exact match for the name */
- if (type != QType::DS && isNSEC3AncestorDelegation(signer, exactNSEC3.d_owner, nsec3)) {
+ if (type != QType::DS && isNSEC3AncestorDelegation(signer, exactNSEC3.d_owner, *nsec3)) {
/* RFC 6840 section 4.1 "Clarifications on Nonexistence Proofs":
Ancestor delegation NSEC or NSEC3 RRs MUST NOT be used to assume
nonexistence of any RRs below that zone cut, which include all RRs at
++d_nsec3Hits;
res = RCode::NoError;
addToRRSet(now, soaSet, soaSignatures, zone, doDNSSEC, ret);
- addRecordToRRSet(now, exactNSEC3.d_owner, QType::NSEC3, exactNSEC3.d_ttd - now, exactNSEC3.d_record, exactNSEC3.d_signatures, doDNSSEC, ret);
+ addRecordToRRSet(exactNSEC3.d_owner, QType::NSEC3, exactNSEC3.d_ttd - now, exactNSEC3.d_record, exactNSEC3.d_signatures, doDNSSEC, ret);
return true;
}
const DNSName signer = getSigner(closestNSEC3.d_signatures);
/* This time we do not allow any ancestor NSEC3, as if the closest encloser is a delegation
NS we know nothing about the names in the child zone. */
- if (isNSEC3AncestorDelegation(signer, closestNSEC3.d_owner, nsec3)) {
+ if (isNSEC3AncestorDelegation(signer, closestNSEC3.d_owner, *nsec3)) {
/* RFC 6840 section 4.1 "Clarifications on Nonexistence Proofs":
Ancestor delegation NSEC or NSEC3 RRs MUST NOT be used to assume
nonexistence of any RRs below that zone cut, which include all RRs at
const DNSName wcSigner = getSigner(wcEntry.d_signatures);
/* It's an exact match for the wildcard, so it does exist. If we are looking for a DS
an ancestor NSEC3 is fine, otherwise it does not prove anything. */
- if (type != QType::DS && isNSEC3AncestorDelegation(wcSigner, wcEntry.d_owner, nsec3)) {
+ if (type != QType::DS && isNSEC3AncestorDelegation(wcSigner, wcEntry.d_owner, *nsec3)) {
/* RFC 6840 section 4.1 "Clarifications on Nonexistence Proofs":
Ancestor delegation NSEC or NSEC3 RRs MUST NOT be used to assume
nonexistence of any RRs below that zone cut, which include all RRs at
return false;
}
- if (!isTypeDenied(nsec3, type)) {
+ if (!isTypeDenied(*nsec3, type)) {
VLOG_NO_PREFIX(log, " but the requested type (" << type.toString() << ") does exist" << endl);
return synthesizeFromNSEC3Wildcard(now, name, type, ret, res, doDNSSEC, nextCloserEntry, wildcard, log);
}
}
addToRRSet(now, soaSet, soaSignatures, zone, doDNSSEC, ret);
- addRecordToRRSet(now, closestNSEC3.d_owner, QType::NSEC3, closestNSEC3.d_ttd - now, closestNSEC3.d_record, closestNSEC3.d_signatures, doDNSSEC, ret);
+ addRecordToRRSet(closestNSEC3.d_owner, QType::NSEC3, closestNSEC3.d_ttd - now, closestNSEC3.d_record, closestNSEC3.d_signatures, doDNSSEC, ret);
/* no need to include the same NSEC3 twice */
if (nextCloserEntry.d_owner != closestNSEC3.d_owner) {
- addRecordToRRSet(now, nextCloserEntry.d_owner, QType::NSEC3, nextCloserEntry.d_ttd - now, nextCloserEntry.d_record, nextCloserEntry.d_signatures, doDNSSEC, ret);
+ addRecordToRRSet(nextCloserEntry.d_owner, QType::NSEC3, nextCloserEntry.d_ttd - now, nextCloserEntry.d_record, nextCloserEntry.d_signatures, doDNSSEC, ret);
}
if (wcEntry.d_owner != closestNSEC3.d_owner && wcEntry.d_owner != nextCloserEntry.d_owner) {
- addRecordToRRSet(now, wcEntry.d_owner, QType::NSEC3, wcEntry.d_ttd - now, wcEntry.d_record, wcEntry.d_signatures, doDNSSEC, ret);
+ addRecordToRRSet(wcEntry.d_owner, QType::NSEC3, wcEntry.d_ttd - now, wcEntry.d_record, wcEntry.d_signatures, doDNSSEC, ret);
}
VLOG(log, name << ": Found valid NSEC3s covering the requested name and type!" << endl);
VLOG_NO_PREFIX(log, ": found a possible NSEC at " << entry.d_owner << " ");
// note that matchesNSEC() takes care of ruling out ancestor NSECs for us
- auto denial = matchesNSEC(name, type.getCode(), entry.d_owner, content, entry.d_signatures, log);
+ auto denial = matchesNSEC(name, type.getCode(), entry.d_owner, *content, entry.d_signatures, log);
if (denial == dState::NODENIAL || denial == dState::INCONCLUSIVE) {
VLOG_NO_PREFIX(log, " but it does not cover us" << endl);
return false;
auto nsecContent = std::dynamic_pointer_cast<const NSECRecordContent>(wcEntry.d_record);
- denial = matchesNSEC(wc, type.getCode(), wcEntry.d_owner, nsecContent, wcEntry.d_signatures, log);
+ denial = matchesNSEC(wc, type.getCode(), wcEntry.d_owner, *nsecContent, wcEntry.d_signatures, log);
if (denial == dState::NODENIAL || denial == dState::INCONCLUSIVE) {
if (wcEntry.d_owner == wc) {
ret.reserve(ret.size() + soaSet.size() + soaSignatures.size() + /* NSEC */ 1 + entry.d_signatures.size() + (needWildcard ? (/* NSEC */ 1 + wcEntry.d_signatures.size()) : 0));
addToRRSet(now, soaSet, soaSignatures, zone, doDNSSEC, ret);
- addRecordToRRSet(now, entry.d_owner, QType::NSEC, entry.d_ttd - now, entry.d_record, entry.d_signatures, doDNSSEC, ret);
+ addRecordToRRSet(entry.d_owner, QType::NSEC, entry.d_ttd - now, entry.d_record, entry.d_signatures, doDNSSEC, ret);
if (needWildcard) {
- addRecordToRRSet(now, wcEntry.d_owner, QType::NSEC, wcEntry.d_ttd - now, wcEntry.d_record, wcEntry.d_signatures, doDNSSEC, ret);
+ addRecordToRRSet(wcEntry.d_owner, QType::NSEC, wcEntry.d_ttd - now, wcEntry.d_record, wcEntry.d_signatures, doDNSSEC, ret);
}
VLOG(log, name << ": Found valid NSECs covering the requested name and type!" << endl);
AC_CANONICAL_HOST
# Add some default CFLAGS and CXXFLAGS, can be appended to using the environment variables
-CFLAGS="-Wall -Wextra -Wshadow -Wno-unused-parameter -Wmissing-declarations -Wredundant-decls -fvisibility=hidden -g -O2 $CFLAGS"
-CXXFLAGS="-Wall -Wextra -Wshadow -Wno-unused-parameter -Wmissing-declarations -Wredundant-decls -fvisibility=hidden -g -O2 $CXXFLAGS"
+CFLAGS="-Wall -Wextra -Wshadow -Wmissing-declarations -Wredundant-decls -fvisibility=hidden -g -O2 $CFLAGS"
+CXXFLAGS="-Wall -Wextra -Wshadow -Wmissing-declarations -Wredundant-decls -fvisibility=hidden -g -O2 $CXXFLAGS"
AC_SUBST([pdns_configure_args],["$ac_configure_args"])
AC_DEFINE_UNQUOTED([PDNS_CONFIG_ARGS],
Changelogs for 4.6.X
====================
+.. changelog::
+ :version: 4.6.6
+ :released: 29th of March 2023
+
+ .. change::
+ :tags: Bug Fixes
+ :pullreq: 12702
+
+ PowerDNS Security Advisory 2023-02: Deterred spoofing attempts can lead to authoritative servers being marked unavailable.
+
.. changelog::
:version: 4.6.5
:released: 25th of November 2022
Changelogs for 4.7.X
====================
+.. changelog::
+ :version: 4.7.5
+ :released: 29th of March 2023
+
+ .. change::
+ :tags: Bug Fixes
+ :pullreq: 12701
+
+ PowerDNS Security Advisory 2023-02: Deterred spoofing attempts can lead to authoritative servers being marked unavailable.
+
.. changelog::
:version: 4.7.4
:released: 25th of November 2022
Changelogs for 4.8.X
====================
+.. changelog::
+ :version: 4.8.4
+ :released: 29th of March 2023
+
+ .. change::
+ :tags: Bug Fixes
+ :pullreq: 12700
+
+ PowerDNS Security Advisory 2023-02: Deterred spoofing attempts can lead to authoritative servers being marked unavailable.
+
.. changelog::
:version: 4.8.3
:released: 7th of March 2023
--- /dev/null
+Changelogs for 4.9.X
+====================
+
+.. changelog::
+ :version: 4.9.0-alpha1
+ :released: 14th of April 2023
+
+ .. change::
+ :tags: Improvements
+ :pullreq: 12710
+
+ Cleanup rcode enums: base one is 8 bit unsigned, extended one 16 bit unsigned
+
+ .. change::
+ :tags: Improvements
+ :pullreq: 12594
+
+ Sharded and shared packet cache.
+
+ .. change::
+ :tags: Improvements
+ :pullreq: 12709
+
+ More fine grained capping of packet cache TTL.
+
+ .. change::
+ :tags: Bug Fixes
+ :pullreq: 12655
+ :tickets: 12486
+
+ Rework root priming code to allow multiple addresses per NS.
+
+ .. change::
+ :tags: Improvements
+ :pullreq: 10072,12716
+
+ Update Debian packaging for Recursor (Chris Hofstaedtler).
+
+ .. change::
+ :tags: Improvements
+ :pullreq: 12497
+
+ Unify shorthands for seconds in log messages (Josh Soref).
+
+ .. change::
+ :tags: Improvements
+ :pullreq: 12674
+
+ Validate: Stop passing shared pointers all the way down.
+
+ .. change::
+ :tags: Improvements
+ :pullreq: 12688
+
+ Re-establish "recursion depth is always increasing" invariant.
+
+ .. change::
+ :tags: Bug Fixes
+ :pullreq: 12672
+
+ Fix a dnsheader unaligned case.
+
+ .. change::
+ :tags: Improvements
+ :pullreq: 12550,12540,12524,12516,12515,12513,12502,12501,12462,12412,12401
+
+ OpenSSL 3.0 compatibility.
+
+ .. change::
+ :tags: Bug Fixes
+ :pullreq: 12554
+
+ Serve-stale-extensions works on 30s so an hour should be 120. (Andreas Jakum)
+
+ .. change::
+ :tags: Bug Fixes
+ :pullreq: 12539
+
+ Fix doc typo (Matt Nordhoff).
+
+ .. change::
+ :tags: Improvements
+ :pullreq: 12493
+
+ Only store NSEC3 records in aggressive cache if we expect them to be effective.
+
+ .. change::
+ :tags: Improvements
+ :pullreq: 11777
+
+ rec_control trace-regex: trace to a file or stdout instead of the general log.
+
+ .. change::
+ :tags: Bug Fixes
+ :pullreq: 12495
+
+ Logging tweaks (Josh Soref).
+
+ .. change::
+ :tags: Improvements
+ :pullreq: 12434
+
+ Unify trace logging code in syncres and validator.
+
+ .. change::
+ :tags: Improvements
+ :pullreq: 12446,12695
+
+ Stack protector for mthread stacks.
+
+ .. change::
+ :tags: Improvements
+ :pullreq: 12425
+
+ Change the way RD=0 forwarded queries are handled.
+
+ .. change::
+ :tags: Improvements
+ :pullreq: 12381
+
+ Enable FORTIFY_SOURCE=3 when supported by the compiler.
+
+ .. change::
+ :tags: Bug Fixes
+ :pullreq: 12419
+ :tickets: 12374
+
+ Negcache dump code: close fd on fdopen fail.
+
+ .. change::
+ :tags: Improvements
+ :pullreq: 12396
+
+ Introduce a thread-safe version of stringerror().
+
+ .. change::
+ :tags: Improvements
+ :pullreq: 12399
+ :tickets: 11138
+
+ Name recursor threads consistently with a "rec/" prefix.
+
+ .. change::
+ :tags: Bug Fixes
+ :pullreq: 12392
+
+ Be more careful saving errno in makeClientSocket() and closesocket()
+
+ .. change::
+ :tags: Improvements
+ :pullreq: 12373
+
+ Rec: Warn on high (90%) mthread stack usage.
+
+ .. change::
+ :tags: Improvements
+ :pullreq: 12334,12691,12698
+
+ Rec: Generate EDE in more cases, specifically on unreachable auths or synthesized results.
+
+ .. change::
+ :tags: Bug Fixes
+ :pullreq: 12368
+
+ Add the 'parse packet from auth' error message to structured logging.
+
+ .. change::
+ :tags: Improvements
+ :pullreq: 12292
+
+ Wrap the CURL raw pointers in smart pointers.
+
+ .. change::
+ :tags: Improvements
+ :pullreq: 12318
+ :tickets: 12241
+
+ Reorganization: move recursor specific files to recursordist.
+
+ .. change::
+ :tags: Improvements
+ :pullreq: 12193,12348,12323
+
+ Introducing TCounters.
+
+ .. change::
+ :tags: Improvements
+ :pullreq: 12120
+ :tickets: 12090
+
+ If we encounter a loop in QM, continue with the next iteration.
+
+ .. change::
+ :tags: Improvements
+ :pullreq: 12121
+ :tickets: 12080
+
+ More clear trace message for cache-only lookups.
+
.. toctree::
:maxdepth: 2
+ 4.9
4.8
4.7
4.6
The first line specifies that additional records should be added to the results of ``MX`` queries using the default mode.
The qtype of the records to be added are ``A`` and ``AAAA``.
-The default mode is ``pdns.AdditionalMode.CacheOnlyRequireAuth``, this mode will only look in the record cache.
+The default mode is ``pdns.AdditionalMode.CacheOnlyRequireAuth``; this mode will only look in the record cache.
The second line specifies that three record types should be added to ``NAPTR`` answers.
If needed, the Recursor will do an active resolve to retrieve these records.
+Note that with record types such as ``NAPTR`` which can return records such as ``SRV``, which may themselves return additional
+``A`` or ``AAAA`` records, the above example would not be sufficient to return those additional ``A`` and/or ``AAAA`` records.
+In such a case, you would need to add an additional line to tell the recursor to fetch the additional records for the ``SRV``
+qtype as well. An example configuration for this case is shown below:
+
+.. code-block:: Lua
+
+ addAllowedAdditionalQType(pdns.NAPTR, {pdns.A, pdns.AAAA, pdns.SRV}, {mode=pdns.AdditionalMode.ResolveImmediately})
+ addAllowedAdditionalQType(pdns.SRV, {pdns.A, pdns.AAAA}, {mode=pdns.AdditionalMode.ResolveImmediately})
+
The modes available are:
``pdns.AdditionalMode.Ignore``
When deploying (large scale) IPv6, please be aware some Linux distributions leave IPv6 routing cache tables at very small default values.
Please check and if necessary raise ``sysctl net.ipv6.route.max_size``.
-Set :ref:`setting-threads` to your number of CPU cores minus the number of distributor threads (but values above 8 rarely improve performance).
+Set :ref:`setting-threads` to your number of CPU cores minus the number of distributor threads.
Threading and distribution of queries
-------------------------------------
-When running with several threads, you can either ask PowerDNS to start one or more special threads to dispatch the incoming queries to the workers by setting :ref:`setting-pdns-distributes-queries` to true, or let the worker threads handle the incoming queries themselves.
+When running with several threads, you can either ask PowerDNS to start one or more special threads to dispatch the incoming queries to the workers by setting :ref:`setting-pdns-distributes-queries` to ``yes``, or let the worker threads handle the incoming queries themselves.
+The latter is the default since version 4.9.0.
The dispatch thread enabled by :ref:`setting-pdns-distributes-queries` tries to send the same queries to the same thread to maximize the cache-hit ratio.
If the incoming query rate is so high that the dispatch thread becomes a bottleneck, you can increase :ref:`setting-distributor-threads` to use more than one.
-If :ref:`setting-pdns-distributes-queries` is set to false and either ``SO_REUSEPORT`` support is not available or the :ref:`setting-reuseport` directive is set to false, all worker threads share the same listening sockets.
+If :ref:`setting-pdns-distributes-queries` is set to ``no`` and either ``SO_REUSEPORT`` support is not available or the :ref:`setting-reuseport` directive is set to ``no``, all worker threads share the same listening sockets.
This prevents a single thread from having to handle every incoming queries, but can lead to thundering herd issues where all threads are awoken at once when a query arrives.
-If ``SO_REUSEPORT`` support is available and :ref:`setting-reuseport` is set to true, separate listening sockets are opened for each worker thread and the query distributions is handled by the kernel, avoiding any thundering herd issue as well as preventing the distributor thread from becoming the bottleneck.
+If ``SO_REUSEPORT`` support is available and :ref:`setting-reuseport` is set to ``yes``, which is the
+default since version 4.9.0, separate listening sockets are opened for each worker thread and the query distributions is handled by the kernel, avoiding any thundering herd issue as well as preventing the distributor thread from becoming the bottleneck.
+
+On some systems setting :ref:`setting-reuseport` to ``yes`` does not have the desired effect.
+If your systems shows imbalance in the number of queries processed per thread (as reported by the periodic statistics report), try switching :ref:`setting-reuseport` to ``no`` and/or setting :ref:`setting-pdns-distributes-queries` to ``yes``.
.. versionadded:: 4.1.0
The :ref:`setting-cpu-map` parameter can be used to pin worker threads to specific CPUs, in order to keep caches as warm as possible and optimize memory access on NUMA systems.
.. versionadded:: 4.2.0
The :ref:`setting-distributor-threads` parameter can be used to run more than one distributor thread.
+.. versionchanged:: 4.9.0
+ The :ref:`setting-reuseport` parameter now defaults to ``yes``.
+
+.. versionchanged:: 4.9.0
+ The :ref:`setting-pdns-distributes-queries` parameter now defaults to ``no``.
+
+
MTasker and MThreads
--------------------
Sample Linux command lines would be::
## IPv4
+ ## NOTRACK rules for 53/udp, keep in mind that you also need your regular rules for 53/tcp
iptables -t raw -I OUTPUT -p udp --dport 53 -j CT --notrack
iptables -t raw -I OUTPUT -p udp --sport 53 -j CT --notrack
iptables -t raw -I PREROUTING -p udp --dport 53 -j CT --notrack
iptables -I OUTPUT -p udp --sport 53 -j ACCEPT
## IPv6
+ ## NOTRACK rules for 53/udp, keep in mind that you also need your regular rules for 53/tcp
ip6tables -t raw -I OUTPUT -p udp --dport 53 -j CT --notrack
ip6tables -t raw -I OUTPUT -p udp --sport 53 -j CT --notrack
ip6tables -t raw -I PREROUTING -p udp --sport 53 -j CT --notrack
The settings can be made permanent by using the ``--permanent`` flag::
## IPv4
+ ## NOTRACK rules for 53/udp, keep in mind that you also need your regular rules for 53/tcp
firewall-cmd --direct --add-rule ipv4 raw OUTPUT 0 -p udp --dport 53 -j CT --notrack
firewall-cmd --direct --add-rule ipv4 raw OUTPUT 0 -p udp --sport 53 -j CT --notrack
firewall-cmd --direct --add-rule ipv4 raw PREROUTING 0 -p udp --dport 53 -j CT --notrack
firewall-cmd --direct --add-rule ipv4 filter OUTPUT 0 -p udp --sport 53 -j ACCEPT
## IPv6
+ ## NOTRACK rules for 53/udp, keep in mind that you also need your regular rules for 53/tcp
firewall-cmd --direct --add-rule ipv6 raw OUTPUT 0 -p udp --dport 53 -j CT --notrack
firewall-cmd --direct --add-rule ipv6 raw OUTPUT 0 -p udp --sport 53 -j CT --notrack
firewall-cmd --direct --add-rule ipv6 raw PREROUTING 0 -p udp --dport 53 -j CT --notrack
--- /dev/null
+PowerDNS Security Advisory 2023-02: Deterred spoofing attempts can lead to authoritative servers being marked unavailable
+=========================================================================================================================
+
+- CVE: CVE-2023-26437
+- Date: 29th of March 2023
+- Affects: PowerDNS Recursor up to and including 4.6.5, 4.7.4 and 4.8.3
+- Not affected: PowerDNS Recursor 4.6.6, 4.7.5 and 4.8.4
+- Severity: Low
+- Impact: Denial of service
+- Exploit: Successful spoofing may lead to authoritative servers being marked unavailable
+- Risk of system compromise: None
+- Solution: Upgrade to patched version
+
+When the recursor detects and deters a spoofing attempt or receives certain malformed DNS packets,
+it throttles the server that was the target of the impersonation attempt so that other authoritative
+servers for the same zone will be more likely to be used in the future, in case the attacker
+controls the path to one server only. Unfortunately this mechanism can be used by an attacker with
+the ability to send queries to the recursor, guess the correct source port of the corresponding
+outgoing query and inject packets with a spoofed IP address to force the recursor to mark specific
+authoritative servers as not available, leading a denial of service for the zones served by those
+servers.
+
+CVSS 3.0 score: 3.7 (Low)
+https://www.first.org/cvss/calculator/3.0#CVSS:3.0/AV:N/AC:H/PR:N/UI:R/S:C/C:N/I:N/A:L
+
+Thanks to Xiang Li from Network and Information Security Laboratory, Tsinghua University for reporting this issue.
+
+
The number of records to cache in the aggressive cache. If set to a value greater than 0, the recursor will cache NSEC and NSEC3 records to generate negative answers, as defined in :rfc:`8198`.
To use this, DNSSEC processing or validation must be enabled by setting `dnssec`_ to ``process``, ``log-fail`` or ``validate``.
-.. _setting-aggressive-cache-max-nsec3-hit-ratio:
+.. _setting-aggressive-cache-min-nsec3-hit-ratio:
``aggressive-cache-min-nsec3-hit-ratio``
----------------------------------------
-
-.. versionadded: 4.9.0
+.. versionadded:: 4.9.0
- Integer
- Default: 2000
- Default: 1 if `pdns-distributes-queries`_ is set, 0 otherwise
If `pdns-distributes-queries`_ is set, spawn this number of distributor threads on startup. Distributor threads
-handle incoming queries and distribute them to other threads based on a hash of the query, to maximize the cache hit
-ratio.
+handle incoming queries and distribute them to other threads based on a hash of the query.
.. _setting-dot-to-auth-names:
``packetcache-ttl``
-------------------
- Integer
-- Default: 3600
+- Default: 86400
Maximum number of seconds to cache an item in the packet cache, no matter what the original TTL specified.
+.. versionchanged:: 4.9.0
+
+ The default was changed from 3600 (1 hour) to 86400 (24 hours).
+
+.. _setting-packetcache-negative-ttl:
+
+``packetcache-negative-ttl``
+----------------------------
+.. versionadded:: 4.9.0
+
+- Integer
+- Default: 60
+
+Maximum number of seconds to cache an ``NxDomain`` or ``NoData`` answer in the packetcache.
+This setting's maximum is capped to `packetcache-ttl`_.
+i.e. setting ``packetcache-ttl=15`` and keeping ``packetcache-negative-ttl`` at the default will lower ``packetcache-negative-ttl`` to ``15``.
+
.. _setting-packetcache-servfail-ttl:
``packetcache-servfail-ttl``
Maximum number of seconds to cache an answer indicating a failure to resolve in the packet cache.
Before version 4.6.0 only ``ServFail`` answers were considered as such. Starting with 4.6.0, all responses with a code other than ``NoError`` and ``NXDomain``, or without records in the answer and authority sections, are considered as a failure to resolve.
+Since 4.9.0, negative answers are handled separately from resolving failures.
.. versionchanged:: 4.0.0
This setting's maximum is capped to `packetcache-ttl`_.
i.e. setting ``packetcache-ttl=15`` and keeping ``packetcache-servfail-ttl`` at the default will lower ``packetcache-servfail-ttl`` to ``15``.
+
+.. _setting-packetcache-shards:
+
+``packetcache-shards``
+------------------------
+.. versionadded:: 4.9.0
+
+- Integer
+- Default: 1024
+
+Sets the number of shards in the packet cache. If you have high contention as reported by ``packetcache-contented/packetcache-acquired``,
+you can try to enlarge this value or run with fewer threads.
+
.. _setting-pdns-distributes-queries:
``pdns-distributes-queries``
----------------------------
- Boolean
-- Default: yes
+- Default: no
If set, PowerDNS will use distinct threads to listen to client sockets and distribute that work to worker-threads using a hash of the query.
-This feature should maximize the cache hit ratio.
-To use more than one thread set `distributor-threads` in version 4.2.0 or newer.
-Enabling should improve performance for medium sized resolvers.
+This feature should maximize the cache hit ratio on versions before 4.9.0.
+To use more than one thread set `distributor-threads`_ in version 4.2.0 or newer.
+Enabling should improve performance on systems where `reuseport`_ does not have the effect of
+balancing the queries evenly over multiple worker threads.
+
+.. versionchanged:: 4.9.0
+
+ Default changed to ``no``, previously it was ``yes``.
.. _setting-protobuf-use-kernel-timestamp:
``reuseport``
-------------
- Boolean
-- Default: no
+- Default: yes
If ``SO_REUSEPORT`` support is available, allows multiple threads and processes to open listening sockets for the same port.
-Since 4.1.0, when ``pdns-distributes-queries`` is set to false and ``reuseport`` is enabled, every worker-thread will open a separate listening socket to let the kernel distribute the incoming queries instead of running a distributor thread (which could otherwise be a bottleneck) and avoiding thundering herd issues, thus leading to much higher performance on multi-core boxes.
+Since 4.1.0, when `pdns-distributes-queries`_ is disabled and `reuseport`_ is enabled, every worker-thread will open a separate listening socket to let the kernel distribute the incoming queries instead of running a distributor thread (which could otherwise be a bottleneck) and avoiding thundering herd issues, thus leading to much higher performance on multi-core boxes.
+
+.. versionchanged:: 4.9.0
+
+ The default is changed to ``yes``, previously it was ``no``.
+ If ``SO_REUSEPORT`` support is not available, the setting defaults to ``no``.
.. _setting-rng:
This affects the results shown by ``rec_control get-qtypelist`` and the ``response-by-qtype``, ``response-sizes`` and ``response-by-rcode`` items returned by the ``/api/v1/servers/localhost/statistics`` API endpoint.
Additionally, most ``RCodes`` and ``QTypes`` that are marked ``Unassigned``, ``Reserved`` or ``Obsolete`` by IANA are not accounted, to reduce the memory consumed by these metrics.
+New settings
+~~~~~~~~~~~~
+- The :ref:`setting-packetcache-negative-ttl` settings to control the TTL of negative (NxDomain or NoData) answers in the packet cache has been introduced.
+- The :ref:`setting-stack-cache-size` setting to control the number of allocated mthread stacks has been introduced.
+- The :ref:`setting-packetcache-shards` settings to control the number of shards in the packet cache has been introduced.
+- The :ref:`setting-aggressive-cache-min-nsec3-hit-ratio` setting to control which NSEC3 records are stored in the aggressive NSEC cache has been introduced.
+
+Changed settings
+~~~~~~~~~~~~~~~~
+The first two settings below have effect on the way the recursor distributes queries over threads.
+In some rare cases, this can have negative performance impact.
+In those cases it might be needed to change these settings.
+See :doc:`performance`.
+
+- The :ref:`setting-pdns-distributes-queries` default has been changed to ``no``.
+- The :ref:`setting-reuseport` default has been changed to ``yes``.
+
+- The :ref:`setting-packetcache-ttl` default has been changed to 24 hours.
+
:program:`rec_control`
^^^^^^^^^^^^^^^^^^^^^^
The ``trace_regex`` subcommand has been changed to take a file argument.
The ``dump-nsspeeds`` command has changed format to make it more readable and lists the last round trip time recorded for each address.
The ``get-proxymapping-stats`` and ``get-remotelogger-stats`` subcommands have been added.
-
4.7.2 to 4.7.3
--------------
NotSupported = 21,
NoReachableAuthority = 22,
NetworkError = 23,
- InvalidData = 24
+ InvalidData = 24,
+ SignatureExpiredBeforeValid = 25,
+ TooEarly = 26,
+ UnsupportedNSEC3IterationsValue = 27,
+ UnableToConformToPolicy = 28,
+ Synthesized = 29,
};
uint16_t infoCode;
std::string extraText;
#include <unistd.h>
// On OpenBSD mem used as stack should be marked MAP_STACK
-#if !defined(MAP_STACK)
-#define MAP_STACK 0
+#ifdef __OpenBSD__
+#define PDNS_MAP_STACK MAP_STACK
+#else
+#define PDNS_MAP_STACK 0
#endif
template <typename T>
#else
const int protection = PROT_NONE;
#endif
- void* p = mmap(nullptr, allocatedSize, protection, MAP_PRIVATE | MAP_ANON | MAP_STACK, -1, 0);
+ void* p = mmap(nullptr, allocatedSize, protection, MAP_PRIVATE | MAP_ANON | PDNS_MAP_STACK, -1, 0);
if (p == MAP_FAILED) {
throw std::bad_alloc();
}
map.emplace(key, value.to_string());
mapArguments(map, args...);
}
- void mapArguments(std::map<std::string, std::string>& map) const
- {
- return;
- }
+
+ void mapArguments(std::map<std::string, std::string>& /* map */) const {}
};
using log_t = const std::shared_ptr<Logger>&;
void RecursorLua4::postPrepareContext()
{
- d_lw->registerMember<const DNSName (DNSQuestion::*)>("qname", [](const DNSQuestion& dq) -> const DNSName& { return dq.qname; }, [](DNSQuestion& dq, const DNSName& newName) { (void) newName; });
- d_lw->registerMember<uint16_t (DNSQuestion::*)>("qtype", [](const DNSQuestion& dq) -> uint16_t { return dq.qtype; }, [](DNSQuestion& dq, uint16_t newType) { (void) newType; });
- d_lw->registerMember<bool (DNSQuestion::*)>("isTcp", [](const DNSQuestion& dq) -> bool { return dq.isTcp; }, [](DNSQuestion& dq, bool newTcp) { (void) newTcp; });
- d_lw->registerMember<const ComboAddress (DNSQuestion::*)>("localaddr", [](const DNSQuestion& dq) -> const ComboAddress& { return dq.local; }, [](DNSQuestion& dq, const ComboAddress& newLocal) { (void) newLocal; });
- d_lw->registerMember<const ComboAddress (DNSQuestion::*)>("remoteaddr", [](const DNSQuestion& dq) -> const ComboAddress& { return dq.remote; }, [](DNSQuestion& dq, const ComboAddress& newRemote) { (void) newRemote; });
- d_lw->registerMember<uint8_t (DNSQuestion::*)>("validationState", [](const DNSQuestion& dq) -> uint8_t { return (vStateIsBogus(dq.validationState) ? /* in order not to break older scripts */ static_cast<uint8_t>(255) : static_cast<uint8_t>(dq.validationState)); }, [](DNSQuestion& dq, uint8_t newState) { (void) newState; });
- d_lw->registerMember<vState (DNSQuestion::*)>("detailedValidationState", [](const DNSQuestion& dq) -> vState { return dq.validationState; }, [](DNSQuestion& dq, vState newState) { (void) newState; });
+ d_lw->registerMember<const DNSName (DNSQuestion::*)>("qname", [](const DNSQuestion& dq) -> const DNSName& { return dq.qname; }, [](DNSQuestion& /* dq */, const DNSName& newName) { (void) newName; });
+ d_lw->registerMember<uint16_t (DNSQuestion::*)>("qtype", [](const DNSQuestion& dq) -> uint16_t { return dq.qtype; }, [](DNSQuestion& /* dq */, uint16_t newType) { (void) newType; });
+ d_lw->registerMember<bool (DNSQuestion::*)>("isTcp", [](const DNSQuestion& dq) -> bool { return dq.isTcp; }, [](DNSQuestion& /* dq */, bool newTcp) { (void) newTcp; });
+ d_lw->registerMember<const ComboAddress (DNSQuestion::*)>("localaddr", [](const DNSQuestion& dq) -> const ComboAddress& { return dq.local; }, [](DNSQuestion& /* dq */, const ComboAddress& newLocal) { (void) newLocal; });
+ d_lw->registerMember<const ComboAddress (DNSQuestion::*)>("remoteaddr", [](const DNSQuestion& dq) -> const ComboAddress& { return dq.remote; }, [](DNSQuestion& /* dq */, const ComboAddress& newRemote) { (void) newRemote; });
+ d_lw->registerMember<uint8_t (DNSQuestion::*)>("validationState", [](const DNSQuestion& dq) -> uint8_t { return (vStateIsBogus(dq.validationState) ? /* in order not to break older scripts */ static_cast<uint8_t>(255) : static_cast<uint8_t>(dq.validationState)); }, [](DNSQuestion& /* dq */, uint8_t newState) { (void) newState; });
+ d_lw->registerMember<vState (DNSQuestion::*)>("detailedValidationState", [](const DNSQuestion& dq) -> vState { return dq.validationState; }, [](DNSQuestion& /* dq */, vState newState) { (void) newState; });
d_lw->registerMember<bool (DNSQuestion::*)>("variable", [](const DNSQuestion& dq) -> bool { return dq.variable; }, [](DNSQuestion& dq, bool newVariable) { dq.variable = newVariable; });
d_lw->registerMember<bool (DNSQuestion::*)>("wantsRPZ", [](const DNSQuestion& dq) -> bool { return dq.wantsRPZ; }, [](DNSQuestion& dq, bool newWantsRPZ) { dq.wantsRPZ = newWantsRPZ; });
}
return result;
},
- [](EDNSOptionView& option, uint16_t newSize) { (void) newSize; });
+ [](EDNSOptionView& /* option */, uint16_t newSize) { (void) newSize; });
d_lw->registerFunction<std::string(EDNSOptionView::*)()>("getContent", [](const EDNSOptionView& option) {
if (option.values.empty()) {
return std::string();
return getRegisteredName(dname);
});
- d_lw->registerMember<const DNSName (PolicyEvent::*)>("qname", [](const PolicyEvent& event) -> const DNSName& { return event.qname; }, [](PolicyEvent& event, const DNSName& newName) { (void) newName; });
- d_lw->registerMember<uint16_t (PolicyEvent::*)>("qtype", [](const PolicyEvent& event) -> uint16_t { return event.qtype.getCode(); }, [](PolicyEvent& event, uint16_t newType) { (void) newType; });
- d_lw->registerMember<bool (PolicyEvent::*)>("isTcp", [](const PolicyEvent& event) -> bool { return event.isTcp; }, [](PolicyEvent& event, bool newTcp) { (void) newTcp; });
- d_lw->registerMember<const ComboAddress (PolicyEvent::*)>("remote", [](const PolicyEvent& event) -> const ComboAddress& { return event.remote; }, [](PolicyEvent& event, const ComboAddress& newRemote) { (void) newRemote; });
+ d_lw->registerMember<const DNSName (PolicyEvent::*)>("qname", [](const PolicyEvent& event) -> const DNSName& { return event.qname; }, [](PolicyEvent& /* event */, const DNSName& newName) { (void) newName; });
+ d_lw->registerMember<uint16_t (PolicyEvent::*)>("qtype", [](const PolicyEvent& event) -> uint16_t { return event.qtype.getCode(); }, [](PolicyEvent& /* event */, uint16_t newType) { (void) newType; });
+ d_lw->registerMember<bool (PolicyEvent::*)>("isTcp", [](const PolicyEvent& event) -> bool { return event.isTcp; }, [](PolicyEvent& /* event */, bool newTcp) { (void) newTcp; });
+ d_lw->registerMember<const ComboAddress (PolicyEvent::*)>("remote", [](const PolicyEvent& event) -> const ComboAddress& { return event.remote; }, [](PolicyEvent& /* event */, const ComboAddress& newRemote) { (void) newRemote; });
d_lw->registerMember("appliedPolicy", &PolicyEvent::appliedPolicy);
d_lw->registerFunction<void(PolicyEvent::*)(const std::string&)>("addPolicyTag", [](PolicyEvent& event, const std::string& tag) { if (event.policyTags) { event.policyTags->insert(tag); } });
d_lw->registerFunction<void(PolicyEvent::*)(const std::vector<std::pair<int, std::string> >&)>("setPolicyTags", [](PolicyEvent& event, const std::vector<std::pair<int, std::string> >& tags) {
}
}
-static bool tcpconnect(const struct timeval& now, const ComboAddress& ip, TCPOutConnectionManager::Connection& connection, bool& dnsOverTLS, const std::string& nsName)
+static bool tcpconnect(const ComboAddress& ip, TCPOutConnectionManager::Connection& connection, bool& dnsOverTLS, const std::string& nsName)
{
dnsOverTLS = SyncRes::s_dot_to_port_853 && ip.getPort() == 853;
if (context && !context->d_nsName.empty()) {
nsName = context->d_nsName.toStringNoDot();
}
- isNew = tcpconnect(*now, ip, connection, dnsOverTLS, nsName);
+ isNew = tcpconnect(ip, connection, dnsOverTLS, nsName);
ret = tcpsendrecv(ip, connection, localip, vpacket, len, buf);
#ifdef HAVE_FSTRM
if (fstrmQEnabled) {
extern __thread size_t t_mainStackSize;
#endif /* HAVE_FIBER_SANITIZER */
+#ifdef HAVE_FIBER_SANITIZER
static inline void notifyStackSwitch(const void* startOfStack, size_t stackSize)
{
-#ifdef HAVE_FIBER_SANITIZER
__sanitizer_start_switch_fiber(nullptr, startOfStack, stackSize);
-#endif /* HAVE_FIBER_SANITIZER */
}
+#else
+static inline void notifyStackSwitch(const void* /* startOfStack */, size_t /* stackSize */)
+{}
+#endif /* HAVE_FIBER_SANITIZER */
static inline void notifyStackSwitchToKernel()
{
*
* \param fp A pointer to an open FILE object
*/
-size_t NegCache::doDump(int fd, size_t maxCacheEntries)
+size_t NegCache::doDump(int fd, size_t maxCacheEntries, time_t now)
{
int newfd = dup(fd);
if (newfd == -1) {
}
fprintf(fp.get(), "; negcache dump follows\n;\n");
- struct timeval now;
- Utility::gettimeofday(&now, nullptr);
-
size_t ret = 0;
size_t shard = 0;
auto& sidx = m->d_map.get<SequenceTag>();
for (const NegCacheEntry& ne : sidx) {
ret++;
- int64_t ttl = ne.d_ttd - now.tv_sec;
+ int64_t ttl = ne.d_ttd - now;
fprintf(fp.get(), "%s %" PRId64 " IN %s VIA %s ; (%s) origttl=%" PRIu32 " ss=%hu\n", ne.d_name.toString().c_str(), ttl, ne.d_qtype.toString().c_str(), ne.d_auth.toString().c_str(), vStateToString(ne.d_validationState).c_str(), ne.d_orig_ttl, ne.d_servedStale);
for (const auto& rec : ne.authoritySOA.records) {
fprintf(fp.get(), "%s %" PRId64 " IN %s %s ; (%s)\n", rec.d_name.toString().c_str(), ttl, DNSRecordContent::NumberToType(rec.d_type).c_str(), rec.getContent()->getZoneRepresentation().c_str(), vStateToString(ne.d_validationState).c_str());
size_t count(const DNSName& qname, QType qtype);
void prune(size_t maxEntries);
void clear();
- size_t doDump(int fd, size_t maxCacheEntries);
+ size_t doDump(int fd, size_t maxCacheEntries, time_t now = time(nullptr));
size_t wipe(const DNSName& name, bool subtree = false);
size_t wipeTyped(const DNSName& name, QType qtype);
size_t size() const;
}
public:
- void preRemoval(MapCombo::LockedContent& map, const NegCacheEntry& entry)
- {
- }
+ void preRemoval(MapCombo::LockedContent& /* map */, const NegCacheEntry& /* entry */) {}
};
std::mutex PersistentSBF::d_cachedir_mutex;
-void PersistentSBF::remove_tmp_files(const filesystem::path& p, std::lock_guard<std::mutex>& lock)
+void PersistentSBF::remove_tmp_files(const filesystem::path& p, std::lock_guard<std::mutex>& /* lock */)
{
Regex file_regex(d_prefix + ".*\\." + bf_suffix + "\\..{8}$");
for (filesystem::directory_iterator i(p); i != filesystem::directory_iterator(); ++i) {
thread_local std::unique_ptr<MT_t> MT; // the big MTasker
std::unique_ptr<MemRecursorCache> g_recCache;
std::unique_ptr<NegCache> g_negCache;
+std::unique_ptr<RecursorPacketCache> g_packetCache;
-thread_local std::unique_ptr<RecursorPacketCache> t_packetCache;
thread_local std::unique_ptr<FDMultiplexer> t_fdm;
thread_local std::unique_ptr<addrringbuf_t> t_remotes, t_servfailremotes, t_largeanswerremotes, t_bogusremotes;
thread_local std::unique_ptr<boost::circular_buffer<pair<DNSName, uint16_t>>> t_queryring, t_servfailqueryring, t_bogusqueryring;
thread_local std::unique_ptr<UDPClientSocks> t_udpclientsocks;
/* these two functions are used by LWRes */
-LWResult::Result asendto(const char* data, size_t len, int flags,
+LWResult::Result asendto(const char* data, size_t len, int /* flags */,
const ComboAddress& toaddr, uint16_t id, const DNSName& domain, uint16_t qtype, bool ecs, int* fd)
{
return LWResult::Result::Success;
}
-LWResult::Result arecvfrom(PacketBuffer& packet, int flags, const ComboAddress& fromaddr, size_t* d_len,
+LWResult::Result arecvfrom(PacketBuffer& packet, int /* flags */, const ComboAddress& fromaddr, size_t* d_len,
uint16_t id, const DNSName& domain, uint16_t qtype, int fd, const struct timeval* now)
{
static const unsigned int nearMissLimit = ::arg().asNum("spoof-nearmiss-max");
}
}
-static bool addRecordToPacket(DNSPacketWriter& pw, const DNSRecord& rec, uint32_t& minTTL, uint32_t ttlCap, const uint16_t maxAnswerSize)
+static bool addRecordToPacket(DNSPacketWriter& pw, const DNSRecord& rec, uint32_t& minTTL, uint32_t ttlCap, const uint16_t maxAnswerSize, bool& seenAuthSOA)
{
pw.startRecord(rec.d_name, rec.d_type, (rec.d_ttl > ttlCap ? ttlCap : rec.d_ttl), rec.d_class, rec.d_place);
+ if (rec.d_type == QType::SOA && rec.d_place == DNSResourceRecord::AUTHORITY) {
+ seenAuthSOA = true;
+ }
+
if (rec.d_type != QType::OPT) // their TTL ain't real
minTTL = min(minTTL, rec.d_ttl);
// fclose by unique_ptr does implicit flush
}
+static uint32_t capPacketCacheTTL(const struct dnsheader& hdr, uint32_t ttl, bool seenAuthSOA)
+{
+ if (hdr.rcode == RCode::NXDomain || (hdr.rcode == RCode::NoError && hdr.ancount == 0 && seenAuthSOA)) {
+ ttl = std::min(ttl, SyncRes::s_packetcachenegativettl);
+ }
+ else if ((hdr.rcode != RCode::NoError && hdr.rcode != RCode::NXDomain) || (hdr.ancount == 0 && hdr.nscount == 0)) {
+ ttl = min(ttl, SyncRes::s_packetcacheservfailttl);
+ }
+ else {
+ ttl = std::min(ttl, SyncRes::s_packetcachettl);
+ }
+ return ttl;
+}
+
void startDoResolve(void* p)
{
auto dc = std::unique_ptr<DNSComboWriter>(reinterpret_cast<DNSComboWriter*>(p));
If we have a TTL cap, this value can't be larger than the
cap no matter what. */
uint32_t minTTL = dc->d_ttlCap;
+ bool seenAuthSOA = false;
sr.d_eventTrace = std::move(dc->d_eventTrace);
sr.setId(MT->getTid());
continue;
}
- if (!addRecordToPacket(pw, *i, minTTL, dc->d_ttlCap, maxanswersize)) {
+ if (!addRecordToPacket(pw, *i, minTTL, dc->d_ttlCap, maxanswersize, seenAuthSOA)) {
needCommit = false;
break;
}
#endif
}
- if (t_packetCache && !variableAnswer && !sr.wasVariable()) {
- const auto& hdr = pw.getHeader();
- if ((hdr->rcode != RCode::NoError && hdr->rcode != RCode::NXDomain) || (hdr->ancount == 0 && hdr->nscount == 0)) {
- minTTL = min(minTTL, SyncRes::s_packetcacheservfailttl);
- }
- minTTL = min(minTTL, SyncRes::s_packetcachettl);
- t_packetCache->insertResponsePacket(dc->d_tag, dc->d_qhash, std::move(dc->d_query), dc->d_mdp.d_qname,
+ if (g_packetCache && !variableAnswer && !sr.wasVariable()) {
+ minTTL = capPacketCacheTTL(*pw.getHeader(), minTTL, seenAuthSOA);
+ g_packetCache->insertResponsePacket(dc->d_tag, dc->d_qhash, std::move(dc->d_query), dc->d_mdp.d_qname,
dc->d_mdp.d_qtype, dc->d_mdp.d_qclass,
string((const char*)&*packet.begin(), packet.size()),
g_now.tv_sec,
string& response, uint32_t& qhash,
RecursorPacketCache::OptPBData& pbData, bool tcp, const ComboAddress& source, const ComboAddress& mappedSource)
{
- if (!t_packetCache) {
+ if (!g_packetCache) {
return false;
}
bool cacheHit = false;
vState valState;
if (qnameParsed) {
- cacheHit = t_packetCache->getResponsePacket(tag, data, qname, qtype, qclass, now.tv_sec, &response, &age, &valState, &qhash, &pbData, tcp);
+ cacheHit = g_packetCache->getResponsePacket(tag, data, qname, qtype, qclass, now.tv_sec, &response, &age, &valState, &qhash, &pbData, tcp);
}
else {
- cacheHit = t_packetCache->getResponsePacket(tag, data, qname, &qtype, &qclass, now.tv_sec, &response, &age, &valState, &qhash, &pbData, tcp);
+ cacheHit = g_packetCache->getResponsePacket(tag, data, qname, &qtype, &qclass, now.tv_sec, &response, &age, &valState, &qhash, &pbData, tcp);
}
if (cacheHit) {
return 0;
}
-static void handleNewUDPQuestion(int fd, FDMultiplexer::funcparam_t& var)
+static void handleNewUDPQuestion(int fd, FDMultiplexer::funcparam_t& /* var */)
{
ssize_t len;
static const size_t maxIncomingQuerySize = g_proxyProtocolACL.empty() ? 512 : (512 + g_proxyProtocolMaximumSize);
static void handleUDPServerResponse(int fd, FDMultiplexer::funcparam_t& var)
{
std::shared_ptr<PacketID> pid = boost::any_cast<std::shared_ptr<PacketID>>(var);
- ssize_t len;
PacketBuffer packet;
packet.resize(g_outgoingEDNSBufsize);
ComboAddress fromaddr;
socklen_t addrlen = sizeof(fromaddr);
- len = recvfrom(fd, &packet.at(0), packet.size(), 0, (sockaddr*)&fromaddr, &addrlen);
+ ssize_t len = recvfrom(fd, &packet.at(0), packet.size(), 0, reinterpret_cast<sockaddr*>(&fromaddr), &addrlen);
- if (len < (ssize_t)sizeof(dnsheader)) {
- if (len < 0)
- ; // cerr<<"Error on fd "<<fd<<": "<<stringerror()<<"\n";
- else {
- t_Counters.at(rec::Counter::serverParseError)++;
- if (g_logCommonErrors)
- SLOG(g_log << Logger::Error << "Unable to parse packet from remote UDP server " << fromaddr.toString() << ": packet smaller than DNS header" << endl,
- g_slogout->info(Logr::Error, "Unable to parse packet from remote UDP server", "from", Logging::Loggable(fromaddr)));
- }
+ const ssize_t signed_sizeof_sdnsheader = sizeof(dnsheader);
+ if (len < 0) {
+ // len < 0: error on socket
t_udpclientsocks->returnSocket(fd);
- PacketBuffer empty;
+ PacketBuffer empty;
MT_t::waiters_t::iterator iter = MT->d_waiters.find(pid);
- if (iter != MT->d_waiters.end())
+ if (iter != MT->d_waiters.end()) {
doResends(iter, pid, empty);
+ }
+ MT->sendEvent(pid, &empty); // this denotes error (does retry lookup using other NS)
+ return;
+ }
- MT->sendEvent(pid, &empty); // this denotes error (does lookup again.. at least L1 will be hot)
+ if (len < signed_sizeof_sdnsheader) {
+ // We have received a packet that cannot be a valid DNS packet, as it has no complete header
+ // Drop it, but continue to wait for other packets
+ t_Counters.at(rec::Counter::serverParseError)++;
+ if (g_logCommonErrors) {
+ SLOG(g_log << Logger::Error << "Unable to parse too short packet from remote UDP server " << fromaddr.toString() << ": packet smaller than DNS header" << endl,
+ g_slogout->info(Logr::Error, "Unable to parse too short packet from remote UDP server", "from", Logging::Loggable(fromaddr)));
+ }
return;
}
+ // We have at least a full header
packet.resize(len);
dnsheader dh;
memcpy(&dh, &packet.at(0), sizeof(dh));
}
else {
try {
- if (len > 12)
- pident->domain = DNSName(reinterpret_cast<const char*>(packet.data()), len, 12, false, &pident->type); // don't copy this from above - we need to do the actual read
+ if (len > signed_sizeof_sdnsheader) {
+ pident->domain = DNSName(reinterpret_cast<const char*>(packet.data()), len, static_cast<int>(sizeof(dnsheader)), false, &pident->type); // don't copy this from above - we need to do the actual read
+ }
+ else {
+ // len == sizeof(dnsheader), only header case
+ // We will do a full scan search later to see if we can match this reply even without a domain
+ pident->domain.clear();
+ pident->type = 0;
+ }
}
catch (std::exception& e) {
+ // Parse error, continue waiting for other packets
t_Counters.at(rec::Counter::serverParseError)++; // won't be fed to lwres.cc, so we have to increment
SLOG(g_log << Logger::Warning << "Error in packet from remote nameserver " << fromaddr.toStringWithPort() << ": " << e.what() << endl,
g_slogudpin->error(Logr::Warning, e.what(), "Error in packet from remote nameserver", "from", Logging::Loggable(fromaddr)));
}
}
- MT_t::waiters_t::iterator iter = MT->d_waiters.find(pident);
- if (iter != MT->d_waiters.end()) {
- doResends(iter, pident, packet);
+ if (!pident->domain.empty()) {
+ MT_t::waiters_t::iterator iter = MT->d_waiters.find(pident);
+ if (iter != MT->d_waiters.end()) {
+ doResends(iter, pident, packet);
+ }
}
retryWithName:
- if (!MT->sendEvent(pident, &packet)) {
+ if (pident->domain.empty() || MT->sendEvent(pident, &packet) == 0) {
/* we did not find a match for this response, something is wrong */
// we do a full scan for outstanding queries on unexpected answers. not too bad since we only accept them on the right port number, which is hard enough to guess
::arg().set("quiet") = g_quiet ? "" : "no";
}
-static void checkLinuxIPv6Limits(Logr::log_t log)
+static void checkLinuxIPv6Limits([[maybe_unused]] Logr::log_t log)
{
#ifdef __linux__
string line;
uint64_t cacheMisses = g_recCache->cacheMisses;
uint64_t cacheSize = g_recCache->size();
auto rc_stats = g_recCache->stats();
- double r = rc_stats.second == 0 ? 0.0 : (100.0 * rc_stats.first / rc_stats.second);
+ auto pc_stats = g_packetCache ? g_packetCache->stats() : std::pair<uint64_t, uint64_t>{0, 0};
+ double rrc = rc_stats.second == 0 ? 0.0 : (100.0 * rc_stats.first / rc_stats.second);
+ double rpc = pc_stats.second == 0 ? 0.0 : (100.0 * pc_stats.first / pc_stats.second);
uint64_t negCacheSize = g_negCache->size();
auto taskPushes = getTaskPushes();
auto taskExpired = getTaskExpired();
auto taskSize = getTaskSize();
- uint64_t pcSize = broadcastAccFunction<uint64_t>(pleaseGetPacketCacheSize);
- uint64_t pcHits = broadcastAccFunction<uint64_t>(pleaseGetPacketCacheHits);
+ uint64_t pcSize = g_packetCache ? g_packetCache->size() : 0;
+ uint64_t pcHits = g_packetCache ? g_packetCache->getHits() : 0;
auto log = g_slog->withName("stats");
if (qcounter > 0 && (cacheHits + cacheMisses) > 0 && syncresqueries > 0 && outqueries > 0) {
if (!g_slogStructured) {
g_log << Logger::Notice << "stats: " << qcounter << " questions, " << cacheSize << " cache entries, " << negCacheSize << " negative entries, " << ratePercentage(cacheHits, cacheHits + cacheMisses) << "% cache hits" << endl;
- g_log << Logger::Notice << "stats: cache contended/acquired " << rc_stats.first << '/' << rc_stats.second << " = " << r << '%' << endl;
+ g_log << Logger::Notice << "stats: record cache contended/acquired " << rc_stats.first << '/' << rc_stats.second << " = " << rrc << '%' << endl;
+ g_log << Logger::Notice << "stats: packet cache contended/acquired " << pc_stats.first << '/' << pc_stats.second << " = " << rpc << '%' << endl;
g_log << Logger::Notice << "stats: throttle map: "
<< SyncRes::getThrottledServersSize() << ", ns speeds: "
"record-cache-hitratio-perc", Logging::Loggable(ratePercentage(cacheHits, cacheHits + cacheMisses)),
"record-cache-contended", Logging::Loggable(rc_stats.first),
"record-cache-acquired", Logging::Loggable(rc_stats.second),
- "record-cache-contended-perc", Logging::Loggable(r));
+ "record-cache-contended-perc", Logging::Loggable(rrc),
+ "packetcache-contended", Logging::Loggable(pc_stats.first),
+ "packetcache-acquired", Logging::Loggable(pc_stats.second),
+ "packetcache-contended-perc", Logging::Loggable(rpc));
log->info(Logr::Info, m,
"throttle-entries", Logging::Loggable(SyncRes::getThrottledServersSize()),
"nsspeed-entries", Logging::Loggable(SyncRes::getNSSpeedsSize()),
template ProxyMappingStats_t broadcastAccFunction(const std::function<ProxyMappingStats_t*()>& fun);
template RemoteLoggerStats_t broadcastAccFunction(const std::function<RemoteLoggerStats_t*()>& fun);
-static int serviceMain(int argc, char* argv[], Logr::log_t log)
+static int serviceMain(int /* argc */, char* /* argv */[], Logr::log_t log)
{
g_log.setName(g_programname);
g_log.disableSyslog(::arg().mustDo("disable-syslog"));
g_maxNSEC3Iterations = ::arg().asNum("nsec3-max-iterations");
g_maxCacheEntries = ::arg().asNum("max-cache-entries");
- g_maxPacketCacheEntries = ::arg().asNum("max-packetcache-entries");
luaConfigDelayedThreads delayedLuaThreads;
try {
SyncRes::s_maxnegttl = ::arg().asNum("max-negative-ttl");
SyncRes::s_maxbogusttl = ::arg().asNum("max-cache-bogus-ttl");
SyncRes::s_maxcachettl = max(::arg().asNum("max-cache-ttl"), 15);
+
SyncRes::s_packetcachettl = ::arg().asNum("packetcache-ttl");
- // Cap the packetcache-servfail-ttl to the packetcache-ttl
- uint32_t packetCacheServFailTTL = ::arg().asNum("packetcache-servfail-ttl");
- SyncRes::s_packetcacheservfailttl = (packetCacheServFailTTL > SyncRes::s_packetcachettl) ? SyncRes::s_packetcachettl : packetCacheServFailTTL;
+ // Cap the packetcache-servfail-ttl and packetcache-negative-ttl to packetcache-ttl
+ SyncRes::s_packetcacheservfailttl = std::min(static_cast<unsigned int>(::arg().asNum("packetcache-servfail-ttl")), SyncRes::s_packetcachettl);
+ SyncRes::s_packetcachenegativettl = std::min(static_cast<unsigned int>(::arg().asNum("packetcache-negative-ttl")), SyncRes::s_packetcachettl);
+
SyncRes::s_serverdownmaxfails = ::arg().asNum("server-down-max-fails");
SyncRes::s_serverdownthrottletime = ::arg().asNum("server-down-throttle-time");
SyncRes::s_nonresolvingnsmaxfails = ::arg().asNum("non-resolving-ns-max-fails");
return RecThreadInfo::runThreads(log);
}
-static void handlePipeRequest(int fd, FDMultiplexer::funcparam_t& var)
+static void handlePipeRequest(int fd, FDMultiplexer::funcparam_t& /* var */)
{
ThreadMSG* tmsg = nullptr;
delete tmsg;
}
-static void handleRCC(int fd, FDMultiplexer::funcparam_t& var)
+static void handleRCC(int fd, FDMultiplexer::funcparam_t& /* var */)
{
auto log = g_slog->withName("control");
try {
t_Counters.updateSnap(now, g_regressionTestMode);
// Below are the tasks that run for every recursorThread, including handler and taskThread
- if (t_packetCache) {
- static thread_local PeriodicTask packetCacheTask{"packetCacheTask", 5};
- packetCacheTask.runIfDue(now, []() {
- size_t sz = g_maxPacketCacheEntries / (RecThreadInfo::numWorkers() + RecThreadInfo::numDistributors());
- t_packetCache->setMaxSize(sz); // g_maxPacketCacheEntries might have changed by rec_control
- t_packetCache->doPruneTo(sz);
- });
- }
static thread_local PeriodicTask pruneTCPTask{"pruneTCPTask", 5};
pruneTCPTask.runIfDue(now, [now]() {
});
}
else if (info.isHandler()) {
+ if (g_packetCache) {
+ static PeriodicTask packetCacheTask{"packetCacheTask", 5};
+ packetCacheTask.runIfDue(now, []() {
+ g_packetCache->doPruneTo(g_maxPacketCacheEntries);
+ });
+ }
static PeriodicTask recordCachePruneTask{"RecordCachePruneTask", 5};
recordCachePruneTask.runIfDue(now, []() {
g_recCache->doPrune(g_maxCacheEntries);
}
}
- if (!::arg().mustDo("disable-packetcache") && (threadInfo.isDistributor() || threadInfo.isWorker())) {
- // Only enable packet cache for thread processing queries from the outside world
- t_packetCache = std::make_unique<RecursorPacketCache>(g_maxPacketCacheEntries / (RecThreadInfo::numWorkers() + RecThreadInfo::numDistributors()));
- }
-
#ifdef NOD_ENABLED
if (threadInfo.isWorker())
setupNODThread(log);
::arg().set("max-negative-ttl", "maximum number of seconds to keep a negative cached entry in memory") = "3600";
::arg().set("max-cache-bogus-ttl", "maximum number of seconds to keep a Bogus (positive or negative) cached entry in memory") = "3600";
::arg().set("max-cache-ttl", "maximum number of seconds to keep a cached entry in memory") = "86400";
- ::arg().set("packetcache-ttl", "maximum number of seconds to keep a cached entry in packetcache") = "3600";
+ ::arg().set("packetcache-ttl", "maximum number of seconds to keep a cached entry in packetcache") = "86400";
::arg().set("max-packetcache-entries", "maximum number of entries to keep in the packetcache") = "500000";
::arg().set("packetcache-servfail-ttl", "maximum number of seconds to keep a cached servfail entry in packetcache") = "60";
+ ::arg().set("packetcache-negative-ttl", "maximum number of seconds to keep a cached NxDomain or NoData entry in packetcache") = "60";
::arg().set("server-id", "Returned when queried for 'id.server' TXT or NSID, defaults to hostname, set custom or 'disabled'") = "";
::arg().set("stats-ringbuffer-entries", "maximum number of packets to store statistics for") = "10000";
::arg().set("version-string", "string reported on version.pdns or version.bind") = fullVersionString();
::arg().set("ecs-add-for", "List of client netmasks for which EDNS Client Subnet will be added") = "0.0.0.0/0, ::/0, " LOCAL_NETS_INVERSE;
::arg().set("ecs-scope-zero-address", "Address to send to allow-listed authoritative servers for incoming queries with ECS prefix-length source of 0") = "";
::arg().setSwitch("use-incoming-edns-subnet", "Pass along received EDNS Client Subnet information") = "no";
- ::arg().setSwitch("pdns-distributes-queries", "If PowerDNS itself should distribute queries over threads") = "yes";
+ ::arg().setSwitch("pdns-distributes-queries", "If PowerDNS itself should distribute queries over threads") = "no";
::arg().setSwitch("root-nx-trust", "If set, believe that an NXDOMAIN from the root means the TLD does not exist") = "yes";
::arg().setSwitch("any-to-tcp", "Answer ANY queries with tc=1, shunting to TCP") = "no";
::arg().setSwitch("lowercase-outgoing", "Force outgoing questions to lowercase") = "no";
::arg().set("include-dir", "Include *.conf files from this directory") = "";
::arg().set("security-poll-suffix", "Domain name from which to query security update notifications") = "secpoll.powerdns.com.";
+#ifdef SO_REUSEPORT
+ ::arg().setSwitch("reuseport", "Enable SO_REUSEPORT allowing multiple recursors processes to listen to 1 address") = "yes";
+#else
::arg().setSwitch("reuseport", "Enable SO_REUSEPORT allowing multiple recursors processes to listen to 1 address") = "no";
-
+#endif
::arg().setSwitch("snmp-agent", "If set, register as an SNMP agent") = "no";
::arg().set("snmp-master-socket", "If set and snmp-agent is set, the socket to use to register to the SNMP daemon (deprecated)") = "";
::arg().set("snmp-daemon-socket", "If set and snmp-agent is set, the socket to use to register to the SNMP daemon") = "";
::arg().setSwitch("nothing-below-nxdomain", "When an NXDOMAIN exists in cache for a name with fewer labels than the qname, send NXDOMAIN without doing a lookup (see RFC 8020)") = "dnssec";
::arg().set("max-generate-steps", "Maximum number of $GENERATE steps when loading a zone from a file") = "0";
::arg().set("max-include-depth", "Maximum nested $INCLUDE depth when loading a zone from a file") = "20";
+
::arg().set("record-cache-shards", "Number of shards in the record cache") = "1024";
+ ::arg().set("packetcache-shards", "Number of shards in the packet cache") = "1024";
+
::arg().set("refresh-on-ttl-perc", "If a record is requested from the cache and only this % of original TTL remains, refetch") = "0";
::arg().set("record-cache-locked-ttl-perc", "Replace records in record cache only after this % of original TTL has passed") = "0";
g_recCache = std::make_unique<MemRecursorCache>(::arg().asNum("record-cache-shards"));
g_negCache = std::make_unique<NegCache>(::arg().asNum("record-cache-shards") / 8);
+ if (!::arg().mustDo("disable-packetcache")) {
+ g_maxPacketCacheEntries = ::arg().asNum("max-packetcache-entries");
+ g_packetCache = std::make_unique<RecursorPacketCache>(g_maxPacketCacheEntries, ::arg().asNum("packetcache-shards"));
+ }
ret = serviceMain(argc, argv, startupLog);
}
return broadcastAccFunction<string>([=] { return pleaseUseNewTraceRegex(begin != end ? *begin : "", fileno); });
}
-static uint64_t* pleaseWipePacketCache(const DNSName& canon, bool subtree, uint16_t qtype)
-{
- return new uint64_t(t_packetCache ? t_packetCache->doWipePacketCache(canon, qtype, subtree) : 0);
-}
-
struct WipeCacheResult wipeCaches(const DNSName& canon, bool subtree, uint16_t qtype)
{
struct WipeCacheResult res;
try {
res.record_count = g_recCache->doWipeCache(canon, subtree, qtype);
// scanbuild complains here about an allocated function object that is being leaked. Needs investigation
- res.packet_count = broadcastAccFunction<uint64_t>([=] { return pleaseWipePacketCache(canon, subtree, qtype); });
+ if (g_packetCache) {
+ res.packet_count = g_packetCache->doWipePacketCache(canon, qtype, subtree);
+ }
res.negative_record_count = g_negCache->wipe(canon, subtree);
if (g_aggressiveNSECCache) {
g_aggressiveNSECCache->removeZoneInfo(canon, subtree);
typedef MTasker<std::shared_ptr<PacketID>, PacketBuffer, PacketIDCompare> MT_t;
extern thread_local std::unique_ptr<MT_t> MT; // the big MTasker
-extern thread_local std::unique_ptr<RecursorPacketCache> t_packetCache;
+extern std::unique_ptr<RecursorPacketCache> g_packetCache;
using RemoteLoggerStats_t = std::unordered_map<std::string, RemoteLoggerInterface::Stats>;
static const oid rcode14AnswersOID[] = {RECURSOR_STATS_OID, 143};
static const oid rcode15AnswersOID[] = {RECURSOR_STATS_OID, 144};
+static const oid packetCacheContendedOID[] = {RECURSOR_STATS_OID, 145};
+static const oid packetCacheAcquiredOID[] = {RECURSOR_STATS_OID, 146};
+
static std::unordered_map<oid, std::string> s_statsMap;
/* We are never called for a GETNEXT if it's registered as a
/* a instance handler also only hands us one request at a time, so
we don't need to loop over a list of requests; we'll only get one. */
-static int handleCounter64Stats(netsnmp_mib_handler* handler,
+static int handleCounter64Stats(netsnmp_mib_handler* /* handler */,
netsnmp_handler_registration* reginfo,
netsnmp_agent_request_info* reqinfo,
netsnmp_request_info* requests)
}
}
-static int handleDisabledCounter64Stats(netsnmp_mib_handler* handler,
+static int handleDisabledCounter64Stats(netsnmp_mib_handler* /* handler */,
netsnmp_handler_registration* reginfo,
netsnmp_agent_request_info* reqinfo,
netsnmp_request_info* requests)
registerCounter64Stat("non-resolving-nameserver-entries", nonResolvingNameserverEntriesOID, OID_LENGTH(nonResolvingNameserverEntriesOID));
registerCounter64Stat("maintenance-usec", maintenanceUSecOID, OID_LENGTH(maintenanceUSecOID));
registerCounter64Stat("maintenance-calls", maintenanceCallsOID, OID_LENGTH(maintenanceCallsOID));
+ registerCounter64Stat("packetcache-contended", packetCacheContendedOID, OID_LENGTH(packetCacheContendedOID));
+ registerCounter64Stat("packetcache-acquired", packetCacheAcquiredOID, OID_LENGTH(packetCacheAcquiredOID));
#define RCODE(num) registerCounter64Stat("auth-" + RCode::to_short_s(num) + "-answers", rcode##num##AnswersOID, OID_LENGTH(rcode##num##AnswersOID))
RCODE(0);
{
d_fd = -1;
}
- bool handleTCPReadResult(int fd, ssize_t bytes)
+ bool handleTCPReadResult(int /* fd */, ssize_t bytes)
{
if (bytes == 0) {
/* EOF */
TCPIOHandlerStateChange(pid->lowState, newstate, pid);
}
-void checkFastOpenSysctl(bool active, Logr::log_t log)
+void checkFastOpenSysctl([[maybe_unused]] bool active, [[maybe_unused]] Logr::log_t log)
{
#ifdef __linux__
string line;
return g_aggressiveNSECCache->dumpToFile(fp, now);
}
-static uint64_t* pleaseDump(int fd)
-{
- return new uint64_t(t_packetCache ? t_packetCache->doDump(fd) : 0);
-}
-
static uint64_t* pleaseDumpEDNSMap(int fd)
{
return new uint64_t(SyncRes::doEDNSDump(fd));
}
// Does not follow the generic dump to file pattern, has a more complex lambda
-static RecursorControlChannel::Answer doDumpCache(int s)
+static RecursorControlChannel::Answer doDumpCache(int socket)
{
- auto fdw = getfd(s);
+ auto fdw = getfd(socket);
if (fdw < 0) {
return {1, "Error opening dump file for writing: " + stringerror() + "\n"};
}
uint64_t total = 0;
try {
- int fd = fdw;
- total = g_recCache->doDump(fd, g_maxCacheEntries.load()) + g_negCache->doDump(fd, g_maxCacheEntries.load() / 8) + broadcastAccFunction<uint64_t>([fd] { return pleaseDump(fd); }) + dumpAggressiveNSECCache(fd);
+ total += g_recCache->doDump(fdw, g_maxCacheEntries.load());
+ total += g_negCache->doDump(fdw, g_maxCacheEntries.load() / 8);
+ total += g_packetCache ? g_packetCache->doDump(fdw) : 0;
+ total += dumpAggressiveNSECCache(fdw);
}
catch (...) {
}
}
try {
g_maxPacketCacheEntries = pdns::checked_stoi<uint32_t>(*begin);
+ g_packetCache->setMaxSize(g_maxPacketCacheEntries);
return "New max packetcache entries: " + std::to_string(g_maxPacketCacheEntries) + "\n";
}
catch (const std::exception& e) {
return g_recCache->cacheMisses;
}
-uint64_t* pleaseGetPacketCacheSize()
-{
- return new uint64_t(t_packetCache ? t_packetCache->size() : 0);
-}
-
-static uint64_t* pleaseGetPacketCacheBytes()
-{
- return new uint64_t(t_packetCache ? t_packetCache->bytes() : 0);
-}
-
-static uint64_t doGetPacketCacheSize()
-{
- return broadcastAccFunction<uint64_t>(pleaseGetPacketCacheSize);
-}
-
-static uint64_t doGetPacketCacheBytes()
-{
- return broadcastAccFunction<uint64_t>(pleaseGetPacketCacheBytes);
-}
-
-uint64_t* pleaseGetPacketCacheHits()
-{
- return new uint64_t(t_packetCache ? t_packetCache->d_hits : 0);
-}
-
-static uint64_t doGetPacketCacheHits()
-{
- return broadcastAccFunction<uint64_t>(pleaseGetPacketCacheHits);
-}
-
-static uint64_t* pleaseGetPacketCacheMisses()
-{
- return new uint64_t(t_packetCache ? t_packetCache->d_misses : 0);
-}
-
-static uint64_t doGetPacketCacheMisses()
-{
- return broadcastAccFunction<uint64_t>(pleaseGetPacketCacheMisses);
-}
-
static uint64_t doGetMallocated()
{
// this turned out to be broken
addGetStat("record-cache-contended", []() { return g_recCache->stats().first; });
addGetStat("record-cache-acquired", []() { return g_recCache->stats().second; });
- addGetStat("packetcache-hits", doGetPacketCacheHits);
- addGetStat("packetcache-misses", doGetPacketCacheMisses);
- addGetStat("packetcache-entries", doGetPacketCacheSize);
- addGetStat("packetcache-bytes", doGetPacketCacheBytes);
+ addGetStat("packetcache-hits", [] { return g_packetCache ? g_packetCache->getHits() : 0; });
+ addGetStat("packetcache-misses", [] { return g_packetCache ? g_packetCache->getMisses() : 0; });
+ addGetStat("packetcache-entries", [] { return g_packetCache ? g_packetCache->size() : 0; });
+ addGetStat("packetcache-bytes", [] { return g_packetCache ? g_packetCache->bytes() : 0; });
+ addGetStat("packetcache-contended", []() { return g_packetCache ? g_packetCache->stats().first : 0; });
+ addGetStat("packetcache-acquired", []() { return g_packetCache ? g_packetCache->stats().second : 0; });
addGetStat("aggressive-nsec-cache-entries", []() { return g_aggressiveNSECCache ? g_aggressiveNSECCache->getEntriesCount() : 0; });
addGetStat("aggressive-nsec-cache-nsec-hits", []() { return g_aggressiveNSECCache ? g_aggressiveNSECCache->getNSECHits() : 0; });
unsigned int RecursorPacketCache::s_refresh_ttlperc{0};
-int RecursorPacketCache::doWipePacketCache(const DNSName& name, uint16_t qtype, bool subtree)
+void RecursorPacketCache::setShardSizes(size_t shardSize)
{
- int count = 0;
- auto& idx = d_packetCache.get<NameTag>();
- for (auto iter = idx.lower_bound(name); iter != idx.end();) {
- if (subtree) {
- if (!iter->d_name.isPartOf(name)) { // this is case insensitive
- break;
- }
- }
- else {
- if (iter->d_name != name)
- break;
+ for (auto& shard : d_maps) {
+ auto lock = shard.lock();
+ lock->d_shardSize = shardSize;
+ }
+}
+
+uint64_t RecursorPacketCache::size() const
+{
+ uint64_t count = 0;
+ for (const auto& map : d_maps) {
+ count += map.d_entriesCount;
+ }
+ return count;
+}
+
+uint64_t RecursorPacketCache::bytes()
+{
+ uint64_t sum = 0;
+ for (auto& shard : d_maps) {
+ auto lock = shard.lock();
+ for (const auto& entry : lock->d_map) {
+ sum += sizeof(entry) + entry.d_packet.length() + 4;
}
+ }
+ return sum;
+}
- if (qtype == 0xffff || iter->d_type == qtype) {
- iter = idx.erase(iter);
- count++;
+uint64_t RecursorPacketCache::getHits()
+{
+ uint64_t sum = 0;
+ for (auto& shard : d_maps) {
+ auto lock = shard.lock();
+ sum += lock->d_hits;
+ }
+ return sum;
+}
+
+uint64_t RecursorPacketCache::getMisses()
+{
+ uint64_t sum = 0;
+ for (auto& shard : d_maps) {
+ auto lock = shard.lock();
+ sum += lock->d_misses;
+ }
+ return sum;
+}
+
+pair<uint64_t, uint64_t> RecursorPacketCache::stats()
+{
+ uint64_t contended = 0;
+ uint64_t acquired = 0;
+ for (auto& shard : d_maps) {
+ auto content = shard.lock();
+ contended += content->d_contended_count;
+ acquired += content->d_acquired_count;
+ }
+ return {contended, acquired};
+}
+
+uint64_t RecursorPacketCache::doWipePacketCache(const DNSName& name, uint16_t qtype, bool subtree)
+{
+ uint64_t count = 0;
+ for (auto& map : d_maps) {
+ auto shard = map.lock();
+ auto& idx = shard->d_map.get<NameTag>();
+ for (auto iter = idx.lower_bound(name); iter != idx.end();) {
+ if (subtree) {
+ if (!iter->d_name.isPartOf(name)) { // this is case insensitive
+ break;
+ }
+ }
+ else {
+ if (iter->d_name != name) {
+ break;
+ }
+ }
+ if (qtype == 0xffff || iter->d_type == qtype) {
+ iter = idx.erase(iter);
+ map.d_entriesCount--;
+ count++;
+ }
+ else {
+ ++iter;
+ }
}
- else
- ++iter;
}
return count;
}
return queryMatches(iter->d_query, queryPacket, qname, optionsToSkip);
}
-bool RecursorPacketCache::checkResponseMatches(std::pair<packetCache_t::index<HashTag>::type::iterator, packetCache_t::index<HashTag>::type::iterator> range, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass, time_t now, std::string* responsePacket, uint32_t* age, vState* valState, OptPBData* pbdata)
+bool RecursorPacketCache::checkResponseMatches(MapCombo::LockedContent& shard, std::pair<packetCache_t::index<HashTag>::type::iterator, packetCache_t::index<HashTag>::type::iterator> range, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass, time_t now, std::string* responsePacket, uint32_t* age, vState* valState, OptPBData* pbdata)
{
for (auto iter = range.first; iter != range.second; ++iter) {
// the possibility is VERY real that we get hits that are not right - birthday paradox
if (now < iter->d_ttd) { // it is right, it is fresh!
*age = static_cast<uint32_t>(now - iter->d_creation);
// we know ttl is > 0
- uint32_t ttl = static_cast<uint32_t>(iter->d_ttd - now);
+ auto ttl = static_cast<uint32_t>(iter->d_ttd - now);
if (s_refresh_ttlperc > 0 && !iter->d_submitted) {
const uint32_t deadline = iter->getOrigTTL() * s_refresh_ttlperc / 100;
const bool almostExpired = ttl <= deadline;
responsePacket->replace(sizeof(dnsheader), wirelength, queryPacket, sizeof(dnsheader), wirelength);
}
- d_hits++;
- moveCacheItemToBack<SequencedTag>(d_packetCache, iter);
+ shard.d_hits++;
+ moveCacheItemToBack<SequencedTag>(shard.d_map, iter);
if (pbdata != nullptr) {
if (iter->d_pbdata) {
return true;
}
- else {
- // We used to move the item to the front of "the to be deleted" sequence,
- // but we very likely will update the entry very soon, so leave it
- d_misses++;
- break;
- }
+ // We used to move the item to the front of "the to be deleted" sequence,
+ // but we very likely will update the entry very soon, so leave it
+ shard.d_misses++;
+ break;
}
return false;
}
-bool RecursorPacketCache::getResponsePacket(unsigned int tag, const std::string& queryPacket, time_t now,
- std::string* responsePacket, uint32_t* age, uint32_t* qhash)
-{
- DNSName qname;
- uint16_t qtype, qclass;
- vState valState;
- return getResponsePacket(tag, queryPacket, qname, &qtype, &qclass, now, responsePacket, age, &valState, qhash, nullptr, false);
-}
-
-bool RecursorPacketCache::getResponsePacket(unsigned int tag, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass, time_t now,
- std::string* responsePacket, uint32_t* age, uint32_t* qhash)
-{
- vState valState;
- return getResponsePacket(tag, queryPacket, qname, qtype, qclass, now, responsePacket, age, &valState, qhash, nullptr, false);
-}
-
static const std::unordered_set<uint16_t> s_skipOptions = {EDNSOptionCode::ECS, EDNSOptionCode::COOKIE};
bool RecursorPacketCache::getResponsePacket(unsigned int tag, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass, time_t now,
std::string* responsePacket, uint32_t* age, vState* valState, uint32_t* qhash, OptPBData* pbdata, bool tcp)
{
*qhash = canHashPacket(queryPacket, s_skipOptions);
- const auto& idx = d_packetCache.get<HashTag>();
+ auto& map = getMap(tag, *qhash, tcp);
+ auto shard = map.lock();
+ const auto& idx = shard->d_map.get<HashTag>();
auto range = idx.equal_range(std::tie(tag, *qhash, tcp));
if (range.first == range.second) {
- d_misses++;
+ shard->d_misses++;
return false;
}
- return checkResponseMatches(range, queryPacket, qname, qtype, qclass, now, responsePacket, age, valState, pbdata);
+ return checkResponseMatches(*shard, range, queryPacket, qname, qtype, qclass, now, responsePacket, age, valState, pbdata);
}
bool RecursorPacketCache::getResponsePacket(unsigned int tag, const std::string& queryPacket, DNSName& qname, uint16_t* qtype, uint16_t* qclass, time_t now,
std::string* responsePacket, uint32_t* age, vState* valState, uint32_t* qhash, OptPBData* pbdata, bool tcp)
{
*qhash = canHashPacket(queryPacket, s_skipOptions);
- const auto& idx = d_packetCache.get<HashTag>();
+ auto& map = getMap(tag, *qhash, tcp);
+ auto shard = map.lock();
+ const auto& idx = shard->d_map.get<HashTag>();
auto range = idx.equal_range(std::tie(tag, *qhash, tcp));
if (range.first == range.second) {
- d_misses++;
+ shard->d_misses++;
return false;
}
- qname = DNSName(queryPacket.c_str(), queryPacket.length(), sizeof(dnsheader), false, qtype, qclass, 0);
+ qname = DNSName(queryPacket.c_str(), static_cast<int>(queryPacket.length()), sizeof(dnsheader), false, qtype, qclass);
- return checkResponseMatches(range, queryPacket, qname, *qtype, *qclass, now, responsePacket, age, valState, pbdata);
+ return checkResponseMatches(*shard, range, queryPacket, qname, *qtype, *qclass, now, responsePacket, age, valState, pbdata);
}
void RecursorPacketCache::insertResponsePacket(unsigned int tag, uint32_t qhash, std::string&& query, const DNSName& qname, uint16_t qtype, uint16_t qclass, std::string&& responsePacket, time_t now, uint32_t ttl, const vState& valState, OptPBData&& pbdata, bool tcp)
{
- auto& idx = d_packetCache.get<HashTag>();
+ auto& map = getMap(tag, qhash, tcp);
+ auto shard = map.lock();
+ auto& idx = shard->d_map.get<HashTag>();
auto range = idx.equal_range(std::tie(tag, qhash, tcp));
auto iter = range.first;
continue;
}
- moveCacheItemToBack<SequencedTag>(d_packetCache, iter);
+ moveCacheItemToBack<SequencedTag>(shard->d_map, iter);
iter->d_packet = std::move(responsePacket);
iter->d_query = std::move(query);
iter->d_ttd = now + ttl;
return;
}
- struct Entry e(qname, qtype, qclass, std::move(responsePacket), std::move(query), tcp, qhash, now + ttl, now, tag, valState);
+ struct Entry entry(qname, qtype, qclass, std::move(responsePacket), std::move(query), tcp, qhash, now + ttl, now, tag, valState);
if (pbdata) {
- e.d_pbdata = std::move(*pbdata);
+ entry.d_pbdata = std::move(*pbdata);
}
- d_packetCache.insert(e);
+ shard->d_map.insert(entry);
+ map.d_entriesCount++;
- if (d_packetCache.size() > d_maxSize) {
- auto& seq_idx = d_packetCache.get<SequencedTag>();
+ if (shard->d_map.size() > shard->d_shardSize) {
+ auto& seq_idx = shard->d_map.get<SequencedTag>();
seq_idx.erase(seq_idx.begin());
+ map.d_entriesCount--;
}
+ assert(map.d_entriesCount == shard->d_map.size()); // XXX
}
-uint64_t RecursorPacketCache::bytes() const
-{
- uint64_t sum = 0;
- for (const auto& e : d_packetCache) {
- sum += sizeof(e) + e.d_packet.length() + 4;
- }
- return sum;
-}
-
-void RecursorPacketCache::doPruneTo(size_t maxCached)
+void RecursorPacketCache::doPruneTo(size_t maxSize)
{
- pruneCollection<SequencedTag>(d_packetCache, maxCached);
+ size_t cacheSize = size();
+ pruneMutexCollectionsVector<SequencedTag>(*this, d_maps, maxSize, cacheSize);
}
-uint64_t RecursorPacketCache::doDump(int fd)
+uint64_t RecursorPacketCache::doDump(int file)
{
- auto fp = std::unique_ptr<FILE, int (*)(FILE*)>(fdopen(dup(fd), "w"), fclose);
- if (!fp) { // dup probably failed
+ int fdupped = dup(file);
+ if (fdupped == -1) {
+ return 0;
+ }
+ auto filePtr = std::unique_ptr<FILE, decltype(&fclose)>(fdopen(fdupped, "w"), fclose);
+ if (!filePtr) {
+ close(fdupped);
return 0;
}
- fprintf(fp.get(), "; main packet cache dump from thread follows\n;\n");
-
- const auto& sidx = d_packetCache.get<SequencedTag>();
uint64_t count = 0;
time_t now = time(nullptr);
- for (const auto& i : sidx) {
- count++;
- try {
- fprintf(fp.get(), "%s %" PRId64 " %s ; tag %d %s\n", i.d_name.toString().c_str(), static_cast<int64_t>(i.d_ttd - now), DNSRecordContent::NumberToType(i.d_type).c_str(), i.d_tag, i.d_tcp ? "tcp" : "udp");
- }
- catch (...) {
- fprintf(fp.get(), "; error printing '%s'\n", i.d_name.empty() ? "EMPTY" : i.d_name.toString().c_str());
+ size_t shardNum = 0;
+ size_t min = std::numeric_limits<size_t>::max();
+ size_t max = 0;
+ uint64_t maxSize = 0;
+
+ for (auto& shard : d_maps) {
+ auto lock = shard.lock();
+ const auto& sidx = lock->d_map.get<SequencedTag>();
+ const auto shardSize = lock->d_map.size();
+ fprintf(filePtr.get(), "; packetcache shard %zu; size %zu/%zu\n", shardNum, shardSize, lock->d_shardSize);
+ min = std::min(min, shardSize);
+ max = std::max(max, shardSize);
+ maxSize += lock->d_shardSize;
+ shardNum++;
+ for (const auto& entry : sidx) {
+ count++;
+ try {
+ fprintf(filePtr.get(), "%s %" PRId64 " %s ; tag %d %s\n", entry.d_name.toString().c_str(), static_cast<int64_t>(entry.d_ttd - now), DNSRecordContent::NumberToType(entry.d_type).c_str(), entry.d_tag, entry.d_tcp ? "tcp" : "udp");
+ }
+ catch (...) {
+ fprintf(filePtr.get(), "; error printing '%s'\n", entry.d_name.empty() ? "EMPTY" : entry.d_name.toString().c_str());
+ }
}
}
+ fprintf(filePtr.get(), "; packetcache size: %" PRIu64 "/%" PRIu64 " shards: %zu min/max shard size: %zu/%zu\n", size(), maxSize, d_maps.size(), min, max);
return count;
}
#include "packetcache.hh"
#include "validate.hh"
+#include "lock.hh"
+#include "stat_t.hh"
#ifdef HAVE_CONFIG_H
#include "config.h"
using namespace ::boost::multi_index;
-//! Stores whole packets, ready for lobbing back at the client. Not threadsafe.
-/* Note: we store answers as value AND KEY, and with careful work, we make sure that
- you can use a query as a key too. But query and answer must compare as identical!
-
- This precludes doing anything smart with EDNS directly from the packet */
class RecursorPacketCache : public PacketCache
{
public:
std::string d_response;
bool d_tagged;
};
- typedef boost::optional<PBData> OptPBData;
+ using OptPBData = boost::optional<PBData>;
- RecursorPacketCache(size_t maxsize) :
- d_maxSize(maxsize)
+ RecursorPacketCache(size_t maxsize, size_t shards = 1024) :
+ d_maps(shards)
{
+ setMaxSize(maxsize);
+ }
+
+ bool getResponsePacket(unsigned int tag, const std::string& queryPacket, time_t now,
+ std::string* responsePacket, uint32_t* age, uint32_t* qhash)
+ {
+ DNSName qname;
+ uint16_t qtype{0};
+ uint16_t qclass{0};
+ vState valState{vState::Indeterminate};
+ return getResponsePacket(tag, queryPacket, qname, &qtype, &qclass, now, responsePacket, age, &valState, qhash, nullptr, false);
+ }
+
+ bool getResponsePacket(unsigned int tag, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass, time_t now,
+ std::string* responsePacket, uint32_t* age, uint32_t* qhash)
+ {
+ vState valState{vState::Indeterminate};
+ return getResponsePacket(tag, queryPacket, qname, qtype, qclass, now, responsePacket, age, &valState, qhash, nullptr, false);
}
- bool getResponsePacket(unsigned int tag, const std::string& queryPacket, time_t now, std::string* responsePacket, uint32_t* age, uint32_t* qhash);
- bool getResponsePacket(unsigned int tag, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass, time_t now, std::string* responsePacket, uint32_t* age, uint32_t* qhash);
bool getResponsePacket(unsigned int tag, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass, time_t now, std::string* responsePacket, uint32_t* age, vState* valState, uint32_t* qhash, OptPBData* pbdata, bool tcp);
bool getResponsePacket(unsigned int tag, const std::string& queryPacket, DNSName& qname, uint16_t* qtype, uint16_t* qclass, time_t now, std::string* responsePacket, uint32_t* age, vState* valState, uint32_t* qhash, OptPBData* pbdata, bool tcp);
void insertResponsePacket(unsigned int tag, uint32_t qhash, std::string&& query, const DNSName& qname, uint16_t qtype, uint16_t qclass, std::string&& responsePacket, time_t now, uint32_t ttl, const vState& valState, OptPBData&& pbdata, bool tcp);
- void doPruneTo(size_t maxSize = 250000);
- uint64_t doDump(int fd);
- int doWipePacketCache(const DNSName& name, uint16_t qtype = 0xffff, bool subtree = false);
+ void doPruneTo(size_t maxSize);
+ uint64_t doDump(int file);
+ uint64_t doWipePacketCache(const DNSName& name, uint16_t qtype = 0xffff, bool subtree = false);
- void setMaxSize(size_t sz)
+ void setMaxSize(size_t size)
{
- d_maxSize = sz;
- }
-
- uint64_t size() const
- {
- return d_packetCache.size();
+ if (size < d_maps.size()) {
+ size = d_maps.size();
+ }
+ setShardSizes(size / d_maps.size());
}
- uint64_t bytes() const;
- uint64_t d_hits{0};
- uint64_t d_misses{0};
+ [[nodiscard]] uint64_t size() const;
+ [[nodiscard]] uint64_t bytes();
+ [[nodiscard]] uint64_t getHits();
+ [[nodiscard]] uint64_t getMisses();
+ [[nodiscard]] pair<uint64_t, uint64_t> stats();
private:
- struct HashTag
- {
- };
- struct NameTag
- {
- };
struct Entry
{
Entry(const DNSName& qname, uint16_t qtype, uint16_t qclass, std::string&& packet, std::string&& query, bool tcp,
}
};
+ struct HashTag
+ {
+ };
+ struct NameTag
+ {
+ };
struct SequencedTag
{
};
- typedef multi_index_container<
- Entry,
- indexed_by<
- hashed_non_unique<tag<HashTag>,
- composite_key<Entry,
- member<Entry, uint32_t, &Entry::d_tag>,
- member<Entry, uint32_t, &Entry::d_qhash>,
- member<Entry, bool, &Entry::d_tcp>>>,
- sequenced<tag<SequencedTag>>,
- ordered_non_unique<tag<NameTag>, member<Entry, DNSName, &Entry::d_name>, CanonDNSNameCompare>>>
- packetCache_t;
-
- packetCache_t d_packetCache;
- size_t d_maxSize;
+ using packetCache_t = multi_index_container<Entry,
+ indexed_by<hashed_non_unique<tag<HashTag>,
+ composite_key<Entry,
+ member<Entry, uint32_t, &Entry::d_tag>,
+ member<Entry, uint32_t, &Entry::d_qhash>,
+ member<Entry, bool, &Entry::d_tcp>>>,
+ sequenced<tag<SequencedTag>>,
+ ordered_non_unique<tag<NameTag>, member<Entry, DNSName, &Entry::d_name>, CanonDNSNameCompare>>>;
+
+ struct MapCombo
+ {
+ MapCombo() = default;
+ MapCombo(const MapCombo&) = delete;
+ MapCombo& operator=(const MapCombo&) = delete;
+ struct LockedContent
+ {
+ packetCache_t d_map;
+ size_t d_shardSize{0};
+ uint64_t d_hits{0};
+ uint64_t d_misses{0};
+ uint64_t d_contended_count{0};
+ uint64_t d_acquired_count{0};
+ void invalidate() {}
+ };
+ pdns::stat_t d_entriesCount{0};
+
+ LockGuardedTryHolder<MapCombo::LockedContent> lock()
+ {
+ auto locked = d_content.try_lock();
+ if (!locked.owns_lock()) {
+ locked.lock();
+ ++locked->d_contended_count;
+ }
+ ++locked->d_acquired_count;
+ return locked;
+ }
+
+ private:
+ LockGuarded<LockedContent> d_content;
+ };
+
+ vector<MapCombo> d_maps;
+
+ static size_t combine(unsigned int tag, uint32_t hash, bool tcp)
+ {
+ size_t ret = 0;
+ boost::hash_combine(ret, tag);
+ boost::hash_combine(ret, hash);
+ boost::hash_combine(ret, tcp);
+ return ret;
+ }
+
+ MapCombo& getMap(unsigned int tag, uint32_t hash, bool tcp)
+ {
+ return d_maps.at(combine(tag, hash, tcp) % d_maps.size());
+ }
+
+ [[nodiscard]] const MapCombo& getMap(unsigned int tag, uint32_t hash, bool tcp) const
+ {
+ return d_maps.at(combine(tag, hash, tcp) % d_maps.size());
+ }
static bool qrMatch(const packetCache_t::index<HashTag>::type::iterator& iter, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass);
- bool checkResponseMatches(std::pair<packetCache_t::index<HashTag>::type::iterator, packetCache_t::index<HashTag>::type::iterator> range, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass, time_t now, std::string* responsePacket, uint32_t* age, vState* valState, OptPBData* pbdata);
+ bool checkResponseMatches(MapCombo::LockedContent& shard, std::pair<packetCache_t::index<HashTag>::type::iterator, packetCache_t::index<HashTag>::type::iterator> range, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass, time_t now, std::string* responsePacket, uint32_t* age, vState* valState, OptPBData* pbdata);
+
+ void setShardSizes(size_t shardSize);
+
+public:
+ void preRemoval(MapCombo::LockedContent& /* map */, const Entry& /* entry */)
+ {
+ }
};
size_t MemRecursorCache::size() const
{
size_t count = 0;
- for (const auto& map : d_maps) {
- count += map.d_entriesCount;
+ for (const auto& shard : d_maps) {
+ count += shard.d_entriesCount;
}
return count;
}
pair<uint64_t, uint64_t> MemRecursorCache::stats()
{
- uint64_t c = 0, a = 0;
- for (auto& mc : d_maps) {
- auto content = mc.lock();
- c += content->d_contended_count;
- a += content->d_acquired_count;
- }
- return pair<uint64_t, uint64_t>(c, a);
+ uint64_t contended = 0;
+ uint64_t acquired = 0;
+ for (auto& shard : d_maps) {
+ auto lockedShard = shard.lock();
+ contended += lockedShard->d_contended_count;
+ acquired += lockedShard->d_acquired_count;
+ }
+ return {contended, acquired};
}
size_t MemRecursorCache::ecsIndexSize()
{
// XXX!
size_t count = 0;
- for (auto& mc : d_maps) {
- auto content = mc.lock();
- count += content->d_ecsIndex.size();
+ for (auto& shard : d_maps) {
+ auto lockedShard = shard.lock();
+ count += lockedShard->d_ecsIndex.size();
}
return count;
}
size_t MemRecursorCache::bytes()
{
size_t ret = 0;
- for (auto& mc : d_maps) {
- auto m = mc.lock();
- for (const auto& i : m->d_map) {
+ for (auto& shard : d_maps) {
+ auto lockedShard = shard.lock();
+ for (const auto& entry : lockedShard->d_map) {
ret += sizeof(struct CacheEntry);
- ret += i.d_qname.toString().length();
- for (const auto& record : i.d_records) {
+ ret += entry.d_qname.toString().length();
+ for (const auto& record : entry.d_records) {
ret += sizeof(record); // XXX WRONG we don't know the stored size!
}
}
time_t ttd = entry->d_ttd;
origTTL = entry->d_orig_ttl;
- if (variable && (!entry->d_netmask.empty() || entry->d_rtag)) {
+ if (variable != nullptr && (!entry->d_netmask.empty() || entry->d_rtag)) {
*variable = true;
}
- if (res) {
+ if (res != nullptr) {
res->reserve(res->size() + entry->d_records.size());
- for (const auto& k : entry->d_records) {
- DNSRecord dr;
- dr.d_name = qname;
- dr.d_type = entry->d_qtype;
- dr.d_class = QClass::IN;
- dr.setContent(k);
+ for (const auto& record : entry->d_records) {
+ DNSRecord result;
+ result.d_name = qname;
+ result.d_type = entry->d_qtype;
+ result.d_class = QClass::IN;
+ result.setContent(record);
// coverity[store_truncates_time_t]
- dr.d_ttl = static_cast<uint32_t>(entry->d_ttd);
- dr.d_place = DNSResourceRecord::ANSWER;
- res->push_back(std::move(dr));
+ result.d_ttl = static_cast<uint32_t>(entry->d_ttd);
+ result.d_place = DNSResourceRecord::ANSWER;
+ res->push_back(std::move(result));
}
}
- if (signatures) {
+ if (signatures != nullptr) {
signatures->insert(signatures->end(), entry->d_signatures.begin(), entry->d_signatures.end());
}
- if (authorityRecs) {
+ if (authorityRecs != nullptr) {
authorityRecs->insert(authorityRecs->end(), entry->d_authorityRecs.begin(), entry->d_authorityRecs.end());
}
updateDNSSECValidationStateFromCache(state, entry->d_state);
- if (wasAuth) {
+ if (wasAuth != nullptr) {
*wasAuth = *wasAuth && entry->d_auth;
}
- if (fromAuthZone) {
+ if (fromAuthZone != nullptr) {
*fromAuthZone = entry->d_authZone;
}
- if (fromAuthIP) {
+ if (fromAuthIP != nullptr) {
*fromAuthIP = entry->d_from;
}
return map.d_map.end();
}
-MemRecursorCache::Entries MemRecursorCache::getEntries(MapCombo::LockedContent& map, const DNSName& qname, const QType qt, const OptTag& rtag)
+MemRecursorCache::Entries MemRecursorCache::getEntries(MapCombo::LockedContent& map, const DNSName& qname, const QType /* qt */, const OptTag& rtag)
{
// MUTEX SHOULD BE ACQUIRED
if (!map.d_cachecachevalid || map.d_cachedqname != qname || map.d_cachedrtag != rtag) {
boost::optional<vState> cachedState{boost::none};
uint32_t origTTL;
- if (res) {
+ if (res != nullptr) {
res->clear();
}
const uint16_t qtype = qt.getCode();
- if (wasAuth) {
+ if (wasAuth != nullptr) {
// we might retrieve more than one entry, we need to set that to true
// so it will be set to false if at least one entry is not auth
*wasAuth = true;
}
- auto& mc = getMap(qname);
- auto map = mc.lock();
+ auto& shard = getMap(qname);
+ auto lockedShard = shard.lock();
/* If we don't have any netmask-specific entries at all, let's just skip this
to be able to use the nice d_cachecache hack. */
- if (qtype != QType::ANY && !map->d_ecsIndex.empty() && !routingTag) {
+ if (qtype != QType::ANY && !lockedShard->d_ecsIndex.empty() && !routingTag) {
if (qtype == QType::ADDR) {
time_t ret = -1;
- auto entryA = getEntryUsingECSIndex(*map, now, qname, QType::A, requireAuth, who, serveStale);
- if (entryA != map->d_map.end()) {
- ret = handleHit(*map, entryA, qname, origTTL, res, signatures, authorityRecs, variable, cachedState, wasAuth, fromAuthZone, fromAuthIP);
+ auto entryA = getEntryUsingECSIndex(*lockedShard, now, qname, QType::A, requireAuth, who, serveStale);
+ if (entryA != lockedShard->d_map.end()) {
+ ret = handleHit(*lockedShard, entryA, qname, origTTL, res, signatures, authorityRecs, variable, cachedState, wasAuth, fromAuthZone, fromAuthIP);
}
- auto entryAAAA = getEntryUsingECSIndex(*map, now, qname, QType::AAAA, requireAuth, who, serveStale);
- if (entryAAAA != map->d_map.end()) {
- time_t ttdAAAA = handleHit(*map, entryAAAA, qname, origTTL, res, signatures, authorityRecs, variable, cachedState, wasAuth, fromAuthZone, fromAuthIP);
+ auto entryAAAA = getEntryUsingECSIndex(*lockedShard, now, qname, QType::AAAA, requireAuth, who, serveStale);
+ if (entryAAAA != lockedShard->d_map.end()) {
+ time_t ttdAAAA = handleHit(*lockedShard, entryAAAA, qname, origTTL, res, signatures, authorityRecs, variable, cachedState, wasAuth, fromAuthZone, fromAuthIP);
if (ret > 0) {
ret = std::min(ret, ttdAAAA);
}
return ret > 0 ? (ret - now) : ret;
}
else {
- auto entry = getEntryUsingECSIndex(*map, now, qname, qtype, requireAuth, who, serveStale);
- if (entry != map->d_map.end()) {
- time_t ret = handleHit(*map, entry, qname, origTTL, res, signatures, authorityRecs, variable, cachedState, wasAuth, fromAuthZone, fromAuthIP);
+ auto entry = getEntryUsingECSIndex(*lockedShard, now, qname, qtype, requireAuth, who, serveStale);
+ if (entry != lockedShard->d_map.end()) {
+ time_t ret = handleHit(*lockedShard, entry, qname, origTTL, res, signatures, authorityRecs, variable, cachedState, wasAuth, fromAuthZone, fromAuthIP);
if (state && cachedState) {
*state = *cachedState;
}
}
if (routingTag) {
- auto entries = getEntries(*map, qname, qt, routingTag);
+ auto entries = getEntries(*lockedShard, qname, qt, routingTag);
bool found = false;
time_t ttd;
if (entries.first != entries.second) {
OrderedTagIterator_t firstIndexIterator;
for (auto i = entries.first; i != entries.second; ++i) {
- firstIndexIterator = map->d_map.project<OrderedTag>(i);
+ firstIndexIterator = lockedShard->d_map.project<OrderedTag>(i);
// When serving stale, we consider expired records
if (!i->isEntryUsable(now, serveStale)) {
- moveCacheItemToFront<SequencedTag>(map->d_map, firstIndexIterator);
+ moveCacheItemToFront<SequencedTag>(lockedShard->d_map, firstIndexIterator);
continue;
}
handleServeStaleBookkeeping(now, serveStale, firstIndexIterator);
- ttd = handleHit(*map, firstIndexIterator, qname, origTTL, res, signatures, authorityRecs, variable, cachedState, wasAuth, fromAuthZone, fromAuthIP);
+ ttd = handleHit(*lockedShard, firstIndexIterator, qname, origTTL, res, signatures, authorityRecs, variable, cachedState, wasAuth, fromAuthZone, fromAuthIP);
if (qt != QType::ANY && qt != QType::ADDR) { // normally if we have a hit, we are done
break;
}
}
// Try (again) without tag
- auto entries = getEntries(*map, qname, qt, boost::none);
+ auto entries = getEntries(*lockedShard, qname, qt, boost::none);
if (entries.first != entries.second) {
OrderedTagIterator_t firstIndexIterator;
time_t ttd;
for (auto i = entries.first; i != entries.second; ++i) {
- firstIndexIterator = map->d_map.project<OrderedTag>(i);
+ firstIndexIterator = lockedShard->d_map.project<OrderedTag>(i);
// When serving stale, we consider expired records
if (!i->isEntryUsable(now, serveStale)) {
- moveCacheItemToFront<SequencedTag>(map->d_map, firstIndexIterator);
+ moveCacheItemToFront<SequencedTag>(lockedShard->d_map, firstIndexIterator);
continue;
}
handleServeStaleBookkeeping(now, serveStale, firstIndexIterator);
- ttd = handleHit(*map, firstIndexIterator, qname, origTTL, res, signatures, authorityRecs, variable, cachedState, wasAuth, fromAuthZone, fromAuthIP);
+ ttd = handleHit(*lockedShard, firstIndexIterator, qname, origTTL, res, signatures, authorityRecs, variable, cachedState, wasAuth, fromAuthZone, fromAuthIP);
if (qt != QType::ANY && qt != QType::ADDR) { // normally if we have a hit, we are done
break;
void MemRecursorCache::replace(time_t now, const DNSName& qname, const QType qt, const vector<DNSRecord>& content, const vector<shared_ptr<const RRSIGRecordContent>>& signatures, const std::vector<std::shared_ptr<DNSRecord>>& authorityRecs, bool auth, const DNSName& authZone, boost::optional<Netmask> ednsmask, const OptTag& routingTag, vState state, boost::optional<ComboAddress> from, bool refresh)
{
- auto& mc = getMap(qname);
- auto map = mc.lock();
+ auto& shard = getMap(qname);
+ auto lockedShard = shard.lock();
- map->d_cachecachevalid = false;
+ lockedShard->d_cachecachevalid = false;
if (ednsmask) {
ednsmask = ednsmask->getNormalized();
}
// We only store an ednsmask if we do not have a tag and we do have a mask.
auto key = std::make_tuple(qname, qt.getCode(), ednsmask ? routingTag : boost::none, (ednsmask && !routingTag) ? *ednsmask : Netmask());
bool isNew = false;
- cache_t::iterator stored = map->d_map.find(key);
- if (stored == map->d_map.end()) {
- stored = map->d_map.insert(CacheEntry(key, auth)).first;
- ++mc.d_entriesCount;
+ cache_t::iterator stored = lockedShard->d_map.find(key);
+ if (stored == lockedShard->d_map.end()) {
+ stored = lockedShard->d_map.insert(CacheEntry(key, auth)).first;
+ ++shard.d_entriesCount;
isNew = true;
}
/* don't bother building an ecsIndex if we don't have any netmask-specific entries */
if (!routingTag && ednsmask && !ednsmask->empty()) {
auto ecsIndexKey = std::make_tuple(qname, qt.getCode());
- auto ecsIndex = map->d_ecsIndex.find(ecsIndexKey);
- if (ecsIndex == map->d_ecsIndex.end()) {
- ecsIndex = map->d_ecsIndex.insert(ECSIndexEntry(qname, qt.getCode())).first;
+ auto ecsIndex = lockedShard->d_ecsIndex.find(ecsIndexKey);
+ if (ecsIndex == lockedShard->d_ecsIndex.end()) {
+ ecsIndex = lockedShard->d_ecsIndex.insert(ECSIndexEntry(qname, qt.getCode())).first;
}
ecsIndex->addMask(*ednsmask);
}
}
if (!isNew) {
- moveCacheItemToBack<SequencedTag>(map->d_map, stored);
+ moveCacheItemToBack<SequencedTag>(lockedShard->d_map, stored);
}
ce.d_submitted = false;
ce.d_servedStale = 0;
- map->d_map.replace(stored, ce);
+ lockedShard->d_map.replace(stored, ce);
}
size_t MemRecursorCache::doWipeCache(const DNSName& name, bool sub, const QType qtype)
size_t count = 0;
if (!sub) {
- auto& mc = getMap(name);
- auto map = mc.lock();
- map->d_cachecachevalid = false;
- auto& idx = map->d_map.get<OrderedTag>();
+ auto& shard = getMap(name);
+ auto lockedShard = shard.lock();
+ lockedShard->d_cachecachevalid = false;
+ auto& idx = lockedShard->d_map.get<OrderedTag>();
auto range = idx.equal_range(name);
auto i = range.first;
while (i != range.second) {
if (i->d_qtype == qtype || qtype == 0xffff) {
i = idx.erase(i);
count++;
- --mc.d_entriesCount;
+ --shard.d_entriesCount;
}
else {
++i;
}
if (qtype == 0xffff) {
- auto& ecsIdx = map->d_ecsIndex.get<OrderedTag>();
+ auto& ecsIdx = lockedShard->d_ecsIndex.get<OrderedTag>();
auto ecsIndexRange = ecsIdx.equal_range(name);
ecsIdx.erase(ecsIndexRange.first, ecsIndexRange.second);
}
else {
- auto& ecsIdx = map->d_ecsIndex.get<HashedTag>();
+ auto& ecsIdx = lockedShard->d_ecsIndex.get<HashedTag>();
auto ecsIndexRange = ecsIdx.equal_range(std::tie(name, qtype));
ecsIdx.erase(ecsIndexRange.first, ecsIndexRange.second);
}
// Name should be doLimitTime or so
bool MemRecursorCache::doAgeCache(time_t now, const DNSName& name, const QType qtype, uint32_t newTTL)
{
- auto& mc = getMap(name);
- auto map = mc.lock();
- cache_t::iterator iter = map->d_map.find(std::tie(name, qtype));
- if (iter == map->d_map.end()) {
+ auto& shard = getMap(name);
+ auto lockedShard = shard.lock();
+ cache_t::iterator iter = lockedShard->d_map.find(std::tie(name, qtype));
+ if (iter == lockedShard->d_map.end()) {
return false;
}
CacheEntry ce = *iter;
- if (ce.d_ttd < now)
+ if (ce.d_ttd < now) {
return false; // would be dead anyhow
+ }
uint32_t maxTTL = static_cast<uint32_t>(ce.d_ttd - now);
if (maxTTL > newTTL) {
- map->d_cachecachevalid = false;
+ lockedShard->d_cachecachevalid = false;
time_t newTTD = now + newTTL;
if (ce.d_ttd > newTTD) {
ce.d_ttd = newTTD;
- map->d_map.replace(iter, ce);
+ lockedShard->d_map.replace(iter, ce);
}
return true;
}
fprintf(fp.get(), "; main record cache dump follows\n;\n");
uint64_t count = 0;
- size_t shard = 0;
+ size_t shardNumber = 0;
size_t min = std::numeric_limits<size_t>::max();
size_t max = 0;
- for (auto& mc : d_maps) {
- auto map = mc.lock();
- const auto shardSize = map->d_map.size();
- fprintf(fp.get(), "; record cache shard %zu; size %zu\n", shard, shardSize);
+ for (auto& shard : d_maps) {
+ auto lockedShard = shard.lock();
+ const auto shardSize = lockedShard->d_map.size();
+ fprintf(fp.get(), "; record cache shard %zu; size %zu\n", shardNumber, shardSize);
min = std::min(min, shardSize);
max = std::max(max, shardSize);
- shard++;
- const auto& sidx = map->d_map.get<SequencedTag>();
+ shardNumber++;
+ const auto& sidx = lockedShard->d_map.get<SequencedTag>();
time_t now = time(nullptr);
for (const auto& i : sidx) {
for (const auto& j : i.d_records) {
namespace boost
{
-size_t hash_value(const MemRecursorCache::OptTag& o)
+size_t hash_value(const MemRecursorCache::OptTag& rtag)
{
- return o ? hash_value(o.get()) : 0xcafebaaf;
+ return rtag ? hash_value(rtag.get()) : 0xcafebaaf;
}
}
#include "config.h"
#endif
+#include "arguments.hh"
#include "syncres.hh"
#include "reczones-helpers.hh"
+#include "root-addresses.hh"
+#include "zoneparser-tng.hh"
+
+static void putIntoCache(time_t now, QType qtype, vState state, const ComboAddress& from, const set<DNSName>& seen, const std::multimap<DNSName, DNSRecord>& allRecords)
+{
+ for (const auto& name : seen) {
+ auto records = allRecords.equal_range(name);
+ vector<DNSRecord> aset;
+ for (auto elem = records.first; elem != records.second; ++elem) {
+ aset.emplace_back(elem->second);
+ }
+ // Put non-default root hints into cache as authoritative. As argued below in
+ // putDefaultHintsIntoCache, this is actually wrong, but people might depend on it by having
+ // root-hints that refer to servers that aren't actually capable or willing to serve root data.
+ g_recCache->replace(now, name, qtype, aset, {}, {}, true, g_rootdnsname, boost::none, boost::none, state, from);
+ }
+}
+
+static void parseHintFile(time_t now, const std::string& hintfile, set<DNSName>& seenA, set<DNSName>& seenAAAA, set<DNSName>& seenNS, std::multimap<DNSName, DNSRecord>& aRecords, std::multimap<DNSName, DNSRecord>& aaaaRecords, vector<DNSRecord>& nsvec)
+{
+ ZoneParserTNG zpt(hintfile);
+ zpt.setMaxGenerateSteps(::arg().asNum("max-generate-steps"));
+ zpt.setMaxIncludes(::arg().asNum("max-include-depth"));
+ DNSResourceRecord rrecord;
+
+ while (zpt.get(rrecord)) {
+ rrecord.ttl += now;
+ switch (rrecord.qtype) {
+ case QType::A:
+ seenA.insert(rrecord.qname);
+ aRecords.emplace(rrecord.qname, DNSRecord(rrecord));
+ break;
+ case QType::AAAA:
+ seenAAAA.insert(rrecord.qname);
+ aaaaRecords.emplace(rrecord.qname, DNSRecord(rrecord));
+ break;
+ case QType::NS:
+ seenNS.emplace(rrecord.content);
+ rrecord.content = toLower(rrecord.content);
+ nsvec.emplace_back(rrecord);
+ break;
+ }
+ }
+}
+
+static bool determineReachable(const set<DNSName>& names, const set<DNSName>& nameservers)
+{
+ bool reachable = false;
+ for (auto const& record : names) {
+ if (nameservers.count(record) != 0) {
+ reachable = true;
+ break;
+ }
+ }
+ return reachable;
+}
+
+bool readHintsIntoCache(time_t now, const std::string& hintfile, std::vector<DNSRecord>& nsvec)
+{
+ const ComboAddress from("255.255.255.255");
+ set<DNSName> seenNS;
+ set<DNSName> seenA;
+ set<DNSName> seenAAAA;
+
+ std::multimap<DNSName, DNSRecord> aRecords;
+ std::multimap<DNSName, DNSRecord> aaaaRecords;
+
+ parseHintFile(now, hintfile, seenA, seenAAAA, seenNS, aRecords, aaaaRecords, nsvec);
+
+ putIntoCache(now, QType::A, vState::Insecure, from, seenA, aRecords);
+ putIntoCache(now, QType::AAAA, vState::Insecure, from, seenAAAA, aaaaRecords);
+
+ bool reachableA = determineReachable(seenA, seenNS);
+ bool reachableAAAA = determineReachable(seenAAAA, seenNS);
+
+ auto log = g_slog->withName("config");
+ if (SyncRes::s_doIPv4 && !SyncRes::s_doIPv6 && !reachableA) {
+ SLOG(g_log << Logger::Error << "Running IPv4 only but no IPv4 root hints" << endl,
+ log->info(Logr::Error, "Running IPv4 only but no IPv4 root hints"));
+ return false;
+ }
+ if (!SyncRes::s_doIPv4 && SyncRes::s_doIPv6 && !reachableAAAA) {
+ SLOG(g_log << Logger::Error << "Running IPv6 only but no IPv6 root hints" << endl,
+ log->info(Logr::Error, "Running IPv6 only but no IPv6 root hints"));
+ return false;
+ }
+ if (SyncRes::s_doIPv4 && SyncRes::s_doIPv6 && !reachableA && !reachableAAAA) {
+ SLOG(g_log << Logger::Error << "No valid root hints" << endl,
+ log->info(Logr::Error, "No valid root hints"));
+ return false;
+ }
+ return true;
+}
+
+void putDefaultHintsIntoCache(time_t now, std::vector<DNSRecord>& nsvec)
+{
+ const ComboAddress from("255.255.255.255");
+
+ DNSRecord arr;
+ DNSRecord aaaarr;
+ DNSRecord nsrr;
+
+ nsrr.d_name = g_rootdnsname;
+ arr.d_type = QType::A;
+ aaaarr.d_type = QType::AAAA;
+ nsrr.d_type = QType::NS;
+ arr.d_ttl = aaaarr.d_ttl = nsrr.d_ttl = now + 3600000;
+
+ string templ = "a.root-servers.net.";
+
+ static_assert(rootIps4.size() == rootIps6.size());
+
+ for (size_t letter = 0; letter < rootIps4.size(); ++letter) {
+ templ.at(0) = static_cast<char>(letter + 'a');
+ aaaarr.d_name = arr.d_name = DNSName(templ);
+ nsrr.setContent(std::make_shared<NSRecordContent>(DNSName(templ)));
+ nsvec.push_back(nsrr);
+
+ if (!rootIps4.at(letter).empty()) {
+ arr.setContent(std::make_shared<ARecordContent>(ComboAddress(rootIps4.at(letter))));
+ /*
+ * Originally the hint records were inserted with the auth flag set, with the consequence that
+ * data from AUTHORITY and ADDITIONAL sections (as seen in a . NS response) were not used. This
+ * (together with the long ttl) caused outdated hint to be kept in cache. So insert as non-auth,
+ * and the extra sections in the . NS refreshing cause the cached records to be updated with
+ * up-to-date information received from a real root server.
+ *
+ * Note that if a user query is done for one of the root-server.net names, it will be inserted
+ * into the cache with the auth bit set. Further NS refreshes will not update that entry. If all
+ * root names are queried at the same time by a user, all root-server.net names will be marked
+ * auth and will expire at the same time. A re-prime is then triggered, as before, when the
+ * records were inserted with the auth bit set and the TTD comes.
+ */
+ g_recCache->replace(now, DNSName(templ), QType::A, {arr}, {}, {}, false, g_rootdnsname, boost::none, boost::none, vState::Insecure, from);
+ }
+ if (!rootIps6.at(letter).empty()) {
+ aaaarr.setContent(std::make_shared<AAAARecordContent>(ComboAddress(rootIps6.at(letter))));
+ g_recCache->replace(now, DNSName(templ), QType::AAAA, {aaaarr}, {}, {}, false, g_rootdnsname, boost::none, boost::none, vState::Insecure, from);
+ }
+ }
+}
template <typename T>
static SyncRes::AuthDomain makeSOAAndNSNodes(DNSRecord& dr, T content)
#include "syncres.hh"
#include "logger.hh"
+bool readHintsIntoCache(time_t now, const std::string& hintfile, std::vector<DNSRecord>& nsvec);
+void putDefaultHintsIntoCache(time_t now, std::vector<DNSRecord>& nsvec);
+
void makeIPToNamesZone(const std::shared_ptr<SyncRes::domainmap_t>& newMap,
const vector<string>& parts,
Logr::log_t log);
#endif
#include "reczones-helpers.hh"
-#include "syncres.hh"
#include "arguments.hh"
-#include "zoneparser-tng.hh"
-#include "logger.hh"
#include "dnsrecords.hh"
-#include "root-addresses.hh"
+#include "logger.hh"
+#include "syncres.hh"
+#include "zoneparser-tng.hh"
extern int g_argc;
extern char** g_argv;
-bool primeHints(time_t ignored)
+bool primeHints(time_t now)
{
- // prime root cache
- const vState validationState = vState::Insecure;
- const ComboAddress from("255.255.255.255");
- vector<DNSRecord> nsset;
-
- time_t now = time(nullptr);
-
- auto log = g_slog->withName("config");
const string hintfile = ::arg()["hint-file"];
+ vector<DNSRecord> nsvec;
+ bool ret = true;
+
if (hintfile == "no") {
+ auto log = g_slog->withName("config");
SLOG(g_log << Logger::Debug << "Priming root disabled by hint-file=no" << endl,
log->info(Logr::Debug, "Priming root disabled by hint-file=no"));
- return true;
+ return ret;
}
- if (hintfile.empty()) {
- DNSRecord arr, aaaarr, nsrr;
- nsrr.d_name = g_rootdnsname;
- arr.d_type = QType::A;
- aaaarr.d_type = QType::AAAA;
- nsrr.d_type = QType::NS;
-
- arr.d_ttl = aaaarr.d_ttl = nsrr.d_ttl = now + 3600000;
-
- for (char c = 'a'; c <= 'm'; ++c) {
- char templ[40];
- strncpy(templ, "a.root-servers.net.", sizeof(templ) - 1);
- templ[sizeof(templ) - 1] = '\0';
- *templ = c;
- aaaarr.d_name = arr.d_name = DNSName(templ);
- nsrr.setContent(std::make_shared<NSRecordContent>(DNSName(templ)));
- arr.setContent(std::make_shared<ARecordContent>(ComboAddress(rootIps4[c - 'a'])));
- vector<DNSRecord> aset;
- aset.push_back(arr);
- /*
- * Originally the hint records were inserted with the auth flag set, with the consequence that data from AUTHORITY and
- * ADDITIONAL sections (as seen in a . NS response) were not used. This (together with the long ttl) caused outdated
- * hint to be kept in cache. So insert as non-auth, and the extra sections in the . NS refreshing cause the cached
- * records to be updated with up-to-date information received from a real root server.
- *
- * Note that if a user query is done for one of the root-server.net names, it will be inserted into the cache with the
- * auth bit set. Further NS refreshes will not update that entry. If all root names are queried at the same time by a user,
- * all root-server.net names will be marked auth and will expire at the same time. A re-prime is then triggered,
- * as before, when the records were inserted with the auth bit set and the TTD comes.
- */
- g_recCache->replace(now, DNSName(templ), QType(QType::A), aset, vector<std::shared_ptr<const RRSIGRecordContent>>(), vector<std::shared_ptr<DNSRecord>>(), false, g_rootdnsname, boost::none, boost::none, validationState, from); // auth, nuke it all
- if (rootIps6[c - 'a'] != NULL) {
- aaaarr.setContent(std::make_shared<AAAARecordContent>(ComboAddress(rootIps6[c - 'a'])));
-
- vector<DNSRecord> aaaaset;
- aaaaset.push_back(aaaarr);
- g_recCache->replace(now, DNSName(templ), QType(QType::AAAA), aaaaset, vector<std::shared_ptr<const RRSIGRecordContent>>(), vector<std::shared_ptr<DNSRecord>>(), false, g_rootdnsname, boost::none, boost::none, validationState, from);
- }
- nsset.push_back(nsrr);
- }
+ if (hintfile.empty()) {
+ putDefaultHintsIntoCache(now, nsvec);
}
else {
- ZoneParserTNG zpt(hintfile);
- zpt.setMaxGenerateSteps(::arg().asNum("max-generate-steps"));
- zpt.setMaxIncludes(::arg().asNum("max-include-depth"));
- DNSResourceRecord rr;
- set<DNSName> seenNS;
- set<DNSName> seenA;
- set<DNSName> seenAAAA;
-
- while (zpt.get(rr)) {
- rr.ttl += now;
- if (rr.qtype.getCode() == QType::A) {
- seenA.insert(rr.qname);
- vector<DNSRecord> aset;
- aset.push_back(DNSRecord(rr));
- g_recCache->replace(now, rr.qname, QType(QType::A), aset, vector<std::shared_ptr<const RRSIGRecordContent>>(), vector<std::shared_ptr<DNSRecord>>(), true, g_rootdnsname, boost::none, boost::none, validationState, from); // auth, etc see above
- }
- else if (rr.qtype.getCode() == QType::AAAA) {
- seenAAAA.insert(rr.qname);
- vector<DNSRecord> aaaaset;
- aaaaset.push_back(DNSRecord(rr));
- g_recCache->replace(now, rr.qname, QType(QType::AAAA), aaaaset, vector<std::shared_ptr<const RRSIGRecordContent>>(), vector<std::shared_ptr<DNSRecord>>(), true, g_rootdnsname, boost::none, boost::none, validationState, from);
- }
- else if (rr.qtype.getCode() == QType::NS) {
- seenNS.insert(DNSName(rr.content));
- rr.content = toLower(rr.content);
- nsset.push_back(DNSRecord(rr));
- }
- }
-
- // Check reachability of A and AAAA records
- bool reachableA = false, reachableAAAA = false;
- for (auto const& r : seenA) {
- if (seenNS.count(r)) {
- reachableA = true;
- break;
- }
- }
- for (auto const& r : seenAAAA) {
- if (seenNS.count(r)) {
- reachableAAAA = true;
- break;
- }
- }
- if (SyncRes::s_doIPv4 && !SyncRes::s_doIPv6 && !reachableA) {
- SLOG(g_log << Logger::Error << "Running IPv4 only but no IPv4 root hints" << endl,
- log->info(Logr::Error, "Running IPv4 only but no IPv4 root hints"));
- return false;
- }
- if (!SyncRes::s_doIPv4 && SyncRes::s_doIPv6 && !reachableAAAA) {
- SLOG(g_log << Logger::Error << "Running IPv6 only but no IPv6 root hints" << endl,
- log->info(Logr::Error, "Running IPv6 only but no IPv6 root hints"));
- return false;
- }
- if (SyncRes::s_doIPv4 && SyncRes::s_doIPv6 && !reachableA && !reachableAAAA) {
- SLOG(g_log << Logger::Error << "No valid root hints" << endl,
- log->info(Logr::Error, "No valid root hints"));
- return false;
- }
+ ret = readHintsIntoCache(now, hintfile, nsvec);
}
g_recCache->doWipeCache(g_rootdnsname, false, QType::NS);
- g_recCache->replace(now, g_rootdnsname, QType(QType::NS), nsset, vector<std::shared_ptr<const RRSIGRecordContent>>(), vector<std::shared_ptr<DNSRecord>>(), false, g_rootdnsname, boost::none, boost::none, validationState, from); // and stuff in the cache
- return true;
+ g_recCache->replace(now, g_rootdnsname, QType::NS, nsvec, {}, {}, false, g_rootdnsname, boost::none, boost::none, vState::Insecure, ComboAddress("255.255.255.255")); // and stuff in the cache
+ return ret;
}
static void convertServersForAD(const std::string& zone, const std::string& input, SyncRes::AuthDomain& ad, const char* sepa, Logr::log_t log, bool verbose = true)
*/
#pragma once
-static const char* const rootIps4[] = {
+#include <array>
+#include <string>
+
+const std::array<const std::string, 13> rootIps4 = {
"198.41.0.4", // a.root-servers.net.
"199.9.14.201", // b.root-servers.net.
"192.33.4.12", // c.root-servers.net.
"199.7.83.42", // l.root-servers.net.
"202.12.27.33" // m.root-servers.net.
};
-static size_t const rootIps4Count = sizeof(rootIps4) / sizeof(*rootIps4);
-static const char* const rootIps6[] = {
+const std::array<const std::string, 13> rootIps6 = {
"2001:503:ba3e::2:30", // a.root-servers.net.
"2001:500:200::b", // b.root-servers.net.
"2001:500:2::c", // c.root-servers.net.
"2001:500:9f::42", // l.root-servers.net.
"2001:dc3::35" // m.root-servers.net.
};
-static size_t const rootIps6Count = sizeof(rootIps6) / sizeof(*rootIps6);
unsigned int SyncRes::s_minimumECSTTL;
unsigned int SyncRes::s_packetcachettl;
unsigned int SyncRes::s_packetcacheservfailttl;
+unsigned int SyncRes::s_packetcachenegativettl;
unsigned int SyncRes::s_serverdownmaxfails;
unsigned int SyncRes::s_serverdownthrottletime;
unsigned int SyncRes::s_nonresolvingnsmaxfails;
return true;
}
-bool SyncRes::doOOBResolve(const DNSName& qname, const QType qtype, vector<DNSRecord>& ret, unsigned int depth, const string& prefix, int& res)
+bool SyncRes::doOOBResolve(const DNSName& qname, const QType qtype, vector<DNSRecord>& ret, unsigned int /* depth */, const string& prefix, int& res)
{
DNSName authdomain(qname);
domainmap_t::const_iterator iter = getBestAuthZone(&authdomain);
setQNameMinimization(false);
setQMFallbackMode(true);
- // We might have hit a depth level check, but we still want to allow some recursion levels in the fallback
- // no-qname-minimization case. This has the effect that a qname minimization fallback case might reach 150% of
- // maxdepth.
- res = doResolveNoQNameMinimization(qname, qtype, ret, depth / 2, beenthere, context);
+ auto oldEDE = context.extendedError;
+ res = doResolveNoQNameMinimization(qname, qtype, ret, depth + 1, beenthere, context);
if (res == RCode::NoError) {
t_Counters.at(rec::Counter::qnameminfallbacksuccess)++;
}
+ else {
+ // as doResolveNoQNameMinimization clears the EDE, we put it back here, it is relevant but might not be set by the last effort attempt
+ if (!context.extendedError) {
+ context.extendedError = oldEDE;
+ }
+ }
LOG(prefix << qname << ": Step5 End resolve: " << RCode::to_s(res) << "/" << ret.size() << endl);
return res;
return RCode::ServFail;
}
+unsigned int SyncRes::getAdjustedRecursionBound() const
+{
+ auto bound = s_maxdepth; // 40 is default value of s_maxdepth
+ if (getQMFallbackMode()) {
+ // We might have hit a depth level check, but we still want to allow some recursion levels in the fallback
+ // no-qname-minimization case. This has the effect that a qname minimization fallback case might reach 150% of
+ // maxdepth, taking care to not repeatedly increase the bound.
+ bound += s_maxdepth / 2;
+ }
+ return bound;
+}
+
/*! This function will check the cache and go out to the internet if the answer is not in cache
*
* \param qname The name we need an answer for
*/
int SyncRes::doResolveNoQNameMinimization(const DNSName& qname, const QType qtype, vector<DNSRecord>& ret, unsigned int depth, set<GetBestNSAnswer>& beenthere, Context& context, bool* fromCache, StopAtDelegation* stopAtDelegation)
{
+ context.extendedError.reset();
auto prefix = getPrefix(depth);
LOG(prefix << qname << ": Wants " << (d_doDNSSEC ? "" : "NO ") << "DNSSEC processing, " << (d_requireAuthData ? "" : "NO ") << "auth data required by query for " << qtype << endl);
- if (s_maxdepth > 0 && depth > s_maxdepth) {
- string msg = "More than " + std::to_string(s_maxdepth) + " (max-recursion-depth) levels of recursion needed while resolving " + qname.toLogString();
- LOG(prefix << qname << ": " << msg << endl);
- throw ImmediateServFailException(msg);
+ if (s_maxdepth > 0) {
+ auto bound = getAdjustedRecursionBound();
+ if (depth > bound) {
+ string msg = "More than " + std::to_string(bound) + " (adjusted max-recursion-depth) levels of recursion needed while resolving " + qname.toLogString();
+ LOG(prefix << qname << ": " << msg << endl);
+ throw ImmediateServFailException(msg);
+ }
}
+
int res = 0;
const int iterations = !d_refresh && MemRecursorCache::s_maxServedStaleExtensions > 0 ? 2 : 1;
bool SyncRes::doCNAMECacheCheck(const DNSName& qname, const QType qtype, vector<DNSRecord>& ret, unsigned int depth, const string& prefix, int& res, Context& context, bool wasAuthZone, bool wasForwardRecurse)
{
- if ((depth > 9 && d_outqueries > 10 && d_throttledqueries > 5) || depth > 15) {
+ // Even if s_maxdepth is zero, we want to have this check
+ auto bound = std::max(40U, getAdjustedRecursionBound());
+ // Bounds were > 9 and > 15 originally, now they are derived from s_maxdepth (default 40)
+ // Apply more strict bound if we see throttling
+ if ((depth >= bound / 4 && d_outqueries > 10 && d_throttledqueries > 5) || depth > bound * 3 / 8) {
LOG(prefix << qname << ": Recursing (CNAME or other indirection) too deep, depth=" << depth << endl);
res = RCode::ServFail;
return true;
giveNegative = true;
cachedState = ne.d_validationState;
if (s_addExtendedResolutionDNSErrors) {
- context.extendedError = EDNSExtendedError{0, "Result synthesized by root-nx-trust"};
+ context.extendedError = EDNSExtendedError{static_cast<uint16_t>(EDNSExtendedError::code::Synthesized), "Result synthesized by root-nx-trust"};
}
}
else if (g_negCache->get(qname, qtype, d_now, ne, false, d_serveStale, d_refresh)) {
LOG(prefix << qname << "|" << qtype << ": Is negatively cached via '" << ne.d_auth << "' for another " << sttl << " seconds" << endl);
res = RCode::NoError;
if (s_addExtendedResolutionDNSErrors) {
- context.extendedError = EDNSExtendedError{0, "Result from negative cache"};
+ context.extendedError = EDNSExtendedError{static_cast<uint16_t>(EDNSExtendedError::code::Synthesized), "Result from negative cache"};
}
}
else {
LOG(prefix << qname << ": Entire name '" << qname << "' is negatively cached via '" << ne.d_auth << "' for another " << sttl << " seconds" << endl);
if (s_addExtendedResolutionDNSErrors) {
- context.extendedError = EDNSExtendedError{0, "Result from negative cache for entire name"};
+ context.extendedError = EDNSExtendedError{static_cast<uint16_t>(EDNSExtendedError::code::Synthesized), "Result from negative cache for entire name"};
}
}
}
cachedState = ne.d_validationState;
LOG(prefix << qname << ": Name '" << negCacheName << "' and below, is negatively cached via '" << ne.d_auth << "' for another " << sttl << " seconds" << endl);
if (s_addExtendedResolutionDNSErrors) {
- context.extendedError = EDNSExtendedError{0, "Result synthesized by nothing-below-nxdomain (RFC8020)"};
+ context.extendedError = EDNSExtendedError{static_cast<uint16_t>(EDNSExtendedError::code::Synthesized), "Result synthesized by nothing-below-nxdomain (RFC8020)"};
}
break;
}
if (g_aggressiveNSECCache->getDenial(d_now.tv_sec, qname, qtype, ret, res, d_cacheRemote, d_routingTag, d_doDNSSEC, LogObject(prefix))) {
context.state = vState::Secure;
if (s_addExtendedResolutionDNSErrors) {
- context.extendedError = EDNSExtendedError{0, "Result synthesized from aggressive NSEC cache (RFC8198)"};
+ context.extendedError = EDNSExtendedError{static_cast<uint16_t>(EDNSExtendedError::code::Synthesized), "Result synthesized from aggressive NSEC cache (RFC8198)"};
}
return true;
}
if (rrsig) {
if (rrsig->d_type == QType::SOA) {
ne.authoritySOA.signatures.push_back(rec);
- if (lowestTTL && isRRSIGNotExpired(now, rrsig)) {
+ if (lowestTTL && isRRSIGNotExpired(now, *rrsig)) {
*lowestTTL = min(*lowestTTL, rec.d_ttl);
*lowestTTL = min(*lowestTTL, getRRSIGTTL(now, rrsig));
}
}
if (nsecTypes.count(rrsig->d_type)) {
ne.DNSSECRecords.signatures.push_back(rec);
- if (lowestTTL && isRRSIGNotExpired(now, rrsig)) {
+ if (lowestTTL && isRRSIGNotExpired(now, *rrsig)) {
*lowestTTL = min(*lowestTTL, rec.d_ttl);
*lowestTTL = min(*lowestTTL, getRRSIGTTL(now, rrsig));
}
return false;
}
-vector<ComboAddress> SyncRes::retrieveAddressesForNS(const std::string& prefix, const DNSName& qname, std::vector<std::pair<DNSName, float>>::const_iterator& tns, const unsigned int depth, set<GetBestNSAnswer>& beenthere, const vector<std::pair<DNSName, float>>& rnameservers, NsSet& nameservers, bool& sendRDQuery, bool& pierceDontQuery, bool& flawedNSSet, bool cacheOnly, unsigned int& nretrieveAddressesForNS)
+vector<ComboAddress> SyncRes::retrieveAddressesForNS(const std::string& prefix, const DNSName& qname, std::vector<std::pair<DNSName, float>>::const_iterator& tns, const unsigned int depth, set<GetBestNSAnswer>& beenthere, const vector<std::pair<DNSName, float>>& rnameservers, NsSet& nameservers, bool& sendRDQuery, bool& pierceDontQuery, bool& /* flawedNSSet */, bool cacheOnly, unsigned int& nretrieveAddressesForNS)
{
vector<ComboAddress> result;
lowestTTD = min(lowestTTD, static_cast<uint32_t>(signaturesTTL + d_now.tv_sec));
for (const auto& sig : signatures) {
- if (isRRSIGNotExpired(d_now.tv_sec, sig)) {
+ if (isRRSIGNotExpired(d_now.tv_sec, *sig)) {
// we don't decrement d_sigexpire by 'now' because we actually want a TTD, not a TTL */
lowestTTD = min(lowestTTD, static_cast<uint32_t>(sig->d_sigexpire));
}
if (entry->d_type == QType::RRSIG && validationEnabled()) {
auto rrsig = getRR<RRSIGRecordContent>(*entry);
if (rrsig) {
- if (isRRSIGNotExpired(d_now.tv_sec, rrsig)) {
+ if (isRRSIGNotExpired(d_now.tv_sec, *rrsig)) {
// we don't decrement d_sigexpire by 'now' because we actually want a TTD, not a TTL */
lowestTTD = min(lowestTTD, static_cast<uint32_t>(rrsig->d_sigexpire));
}
count can be lower than the name's label count if it was
synthesized from the wildcard. Note that the difference might
be > 1. */
- if (rec.d_name == qname && isWildcardExpanded(labelCount, rrsig)) {
+ if (rec.d_name == qname && isWildcardExpanded(labelCount, *rrsig)) {
gatherWildcardProof = true;
- if (!isWildcardExpandedOntoItself(rec.d_name, labelCount, rrsig)) {
+ if (!isWildcardExpandedOntoItself(rec.d_name, labelCount, *rrsig)) {
/* if we have a wildcard expanded onto itself, we don't need to prove
that the exact name doesn't exist because it actually does.
We still want to gather the corresponding NSEC/NSEC3 records
wildcard in its non-expanded form in the cache to be able to synthesize wildcard answers later */
const auto& rrsig = i->second.signatures.at(0);
- if (isWildcardExpanded(labelCount, rrsig) && !isWildcardExpandedOntoItself(i->first.name, labelCount, rrsig)) {
+ if (isWildcardExpanded(labelCount, *rrsig) && !isWildcardExpandedOntoItself(i->first.name, labelCount, *rrsig)) {
DNSName realOwner = getNSECOwnerName(i->first.name, i->second.signatures);
std::vector<DNSRecord> content;
if (s_addExtendedResolutionDNSErrors) {
extendedError = EDNSExtendedError{static_cast<uint16_t>(EDNSExtendedError::code::NoReachableAuthority), "Timeout waiting for answer(s)"};
}
- throw ImmediateServFailException("Too much time waiting for " + qname.toLogString() + "|" + qtype.toString() + ", timeouts: " + std::to_string(d_timeouts) + ", throttles: " + std::to_string(d_throttledqueries) + ", queries: " + std::to_string(d_outqueries) + ", " + std::to_string(d_totUsec / 1000) + "msec");
+ throw ImmediateServFailException("Too much time waiting for " + qname.toLogString() + "|" + qtype.toString() + ", timeouts: " + std::to_string(d_timeouts) + ", throttles: " + std::to_string(d_throttledqueries) + ", queries: " + std::to_string(d_outqueries) + ", " + std::to_string(d_totUsec / 1000) + " ms");
}
if (doTCP) {
}
d_totUsec += lwr.d_usec;
+
+ if (resolveret == LWResult::Result::Spoofed) {
+ spoofed = true;
+ return false;
+ }
+
accountAuthLatency(lwr.d_usec, remoteIP.sin4.sin_family);
++t_Counters.at(rec::RCode::auth).rcodeCounters.at(static_cast<uint8_t>(lwr.d_rcode));
if (resolveret == LWResult::Result::Timeout) {
/* Time out */
- LOG(prefix << qname << ": Timeout resolving after " << lwr.d_usec / 1000.0 << "msec " << (doTCP ? "over TCP" : "") << endl);
+ LOG(prefix << qname << ": Timeout resolving after " << lwr.d_usec / 1000.0 << " ms " << (doTCP ? "over TCP" : "") << endl);
d_timeouts++;
t_Counters.at(rec::Counter::outgoingtimeouts)++;
LOG(prefix << qname << ": Hit a local resource limit resolving" << (doTCP ? " over TCP" : "") << ", probable error: " << stringerror() << endl);
t_Counters.at(rec::Counter::resourceLimits)++;
}
- else if (resolveret == LWResult::Result::Spoofed) {
- spoofed = true;
- }
else {
/* LWResult::Result::PermanentError */
t_Counters.at(rec::Counter::unreachables)++;
return true;
}
-void SyncRes::handleNewTarget(const std::string& prefix, const DNSName& qname, const DNSName& newtarget, const QType qtype, std::vector<DNSRecord>& ret, int& rcode, int depth, const std::vector<DNSRecord>& recordsFromAnswer, vState& state)
+void SyncRes::handleNewTarget(const std::string& prefix, const DNSName& qname, const DNSName& newtarget, const QType qtype, std::vector<DNSRecord>& ret, int& rcode, unsigned int depth, const std::vector<DNSRecord>& recordsFromAnswer, vState& state)
{
if (newtarget == qname) {
LOG(prefix << qname << ": Status=got a CNAME referral to self, returning SERVFAIL" << endl);
setQNameMinimization(false);
}
- if (depth > 10) {
+ // Was 10 originally, default s_maxdepth is 40, but even if it is zero we want to apply a bound
+ auto bound = std::max(40U, getAdjustedRecursionBound()) / 4;
+ if (depth > bound) {
LOG(prefix << qname << ": Status=got a CNAME referral, but recursing too deep, returning SERVFAIL" << endl);
rcode = RCode::ServFail;
return;
if(remoteIP->sin4.sin_family==AF_INET6)
lwr.d_usec/=3;
*/
- // cout<<"msec: "<<lwr.d_usec/1000.0<<", "<<g_avgLatency/1000.0<<'\n';
+ // cout<<"ms: "<<lwr.d_usec/1000.0<<", "<<g_avgLatency/1000.0<<'\n';
s_nsSpeeds.lock()->find_or_enter(tns->first.empty() ? DNSName(remoteIP->toStringWithPort()) : tns->first, d_now).submit(*remoteIP, lwr.d_usec, d_now);
static unsigned int s_maxcachettl;
static unsigned int s_packetcachettl;
static unsigned int s_packetcacheservfailttl;
+ static unsigned int s_packetcachenegativettl;
static unsigned int s_serverdownmaxfails;
static unsigned int s_serverdownthrottletime;
static unsigned int s_nonresolvingnsmaxfails;
void initZoneCutsFromTA(const DNSName& from, const string& prefix);
size_t countSupportedDS(const dsmap_t& dsmap, const string& prefix);
- void handleNewTarget(const std::string& prefix, const DNSName& qname, const DNSName& newtarget, QType qtype, std::vector<DNSRecord>& ret, int& rcode, int depth, const std::vector<DNSRecord>& recordsFromAnswer, vState& state);
+ void handleNewTarget(const std::string& prefix, const DNSName& qname, const DNSName& newtarget, QType qtype, std::vector<DNSRecord>& ret, int& rcode, unsigned int depth, const std::vector<DNSRecord>& recordsFromAnswer, vState& state);
void handlePolicyHit(const std::string& prefix, const DNSName& qname, QType qtype, vector<DNSRecord>& ret, bool& done, int& rcode, unsigned int depth);
+ unsigned int getAdjustedRecursionBound() const;
void setUpdatingRootNS()
{
TCPAction highState{TCPAction::DoingRead};
IOState lowState{IOState::NeedRead};
- bool operator<(const PacketID& b) const
+ bool operator<(const PacketID& /* b */) const
{
// We don't want explicit PacketID compare here, but always via predicate classes below
assert(0);
uint64_t* pleaseGetFailedServersSize();
uint64_t* pleaseGetConcurrentQueries();
uint64_t* pleaseGetThrottleSize();
-uint64_t* pleaseGetPacketCacheHits();
-uint64_t* pleaseGetPacketCacheSize();
void doCarbonDump(void*);
bool primeHints(time_t now = time(nullptr));
const char* isoDateTimeMillis(const struct timeval& tv, char* buf, size_t sz);
size_t queriesCount = 0;
- sr->setAsyncCallback([target1, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target1, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS || type == QType::DNSKEY) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS || type == QType::DNSKEY) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS || type == QType::DNSKEY) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS || type == QType::DNSKEY) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS || type == QType::DNSKEY) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target1, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target1, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS || type == QType::DNSKEY) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS || type == QType::DNSKEY) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS || type == QType::DNSKEY) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS || type == QType::DNSKEY) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS || type == QType::DNSKEY) {
#else
-static void willThrow(void* p)
+static void willThrow(void* /* p */)
{
throw std::runtime_error("Help!");
}
if (!fp)
BOOST_FAIL("Temporary file could not be opened");
- cache.doDump(fileno(fp.get()), 0);
+ cache.doDump(fileno(fp.get()), 0, now.tv_sec);
rewind(fp.get());
char* line = nullptr;
BOOST_AUTO_TEST_SUITE(nod_cc)
-static bool pdns_exception(PDNSException const& ex) { return true; }
+static bool pdns_exception(PDNSException const& /* ex */) { return true; }
BOOST_AUTO_TEST_CASE(test_basic)
{
BOOST_TEST_MESSAGE("-----------------------------------------------------");
}
+const std::string hints = ". 3600 IN NS ns.\n"
+ ". 3600 IN NS ns1.\n"
+ "ns. 3600 IN A 192.168.178.16\n"
+ "ns. 3600 IN A 192.168.178.17\n"
+ "ns. 3600 IN A 192.168.178.18\n"
+ "ns. 3600 IN AAAA 1::2\n"
+ "ns. 3600 IN AAAA 1::3\n"
+ "ns1. 3600 IN A 192.168.178.18\n";
+
+BOOST_AUTO_TEST_CASE(test_UserHints)
+{
+
+ g_recCache = make_unique<MemRecursorCache>();
+
+ ::arg().set("max-generate-steps") = "0";
+ ::arg().set("max-include-depth") = "0";
+ char temp[] = "/tmp/hintsXXXXXXXXXX";
+ int fd = mkstemp(temp);
+ BOOST_REQUIRE(fd > 0);
+ FILE* fp = fdopen(fd, "w");
+ BOOST_REQUIRE(fp != nullptr);
+ size_t written = fwrite(hints.data(), 1, hints.length(), fp);
+ BOOST_REQUIRE(written == hints.length());
+ BOOST_REQUIRE(fclose(fp) == 0);
+
+ time_t now = time(nullptr);
+ std::vector<DNSRecord> nsvec;
+
+ auto ok = readHintsIntoCache(now, std::string(temp), nsvec);
+ BOOST_CHECK(ok);
+ BOOST_CHECK_EQUAL(nsvec.size(), 2U);
+
+ const MemRecursorCache::Flags flags = 0;
+
+ BOOST_CHECK(g_recCache->get(now, DNSName("ns"), QType::A, flags, &nsvec, ComboAddress()) > 0);
+ BOOST_CHECK_EQUAL(nsvec.size(), 3U);
+
+ BOOST_CHECK(g_recCache->get(now, DNSName("ns"), QType::AAAA, flags, &nsvec, ComboAddress()) > 0);
+ BOOST_CHECK_EQUAL(nsvec.size(), 2U);
+
+ BOOST_CHECK(g_recCache->get(now, DNSName("ns1"), QType::A, flags, &nsvec, ComboAddress()) > 0);
+ BOOST_CHECK_EQUAL(nsvec.size(), 1U);
+}
+
BOOST_AUTO_TEST_SUITE_END()
{
}
-void BaseLua4::getFeatures(Features&)
+void BaseLua4::getFeatures(Features& /* features */)
{
}
-bool RecursorLua4::preoutquery(const ComboAddress& ns, const ComboAddress& requestor, const DNSName& query, const QType& qtype, bool isTcp, vector<DNSRecord>& res, int& ret, RecEventTrace& et, const struct timeval& tv) const
+bool RecursorLua4::preoutquery(const ComboAddress& /* ns */, const ComboAddress& /* requestor */, const DNSName& /* query */, const QType& /* qtype */, bool /* isTcp */, vector<DNSRecord>& /* res */, int& /* ret */, RecEventTrace& /* et */, const struct timeval& /* tv */) const
{
return false;
}
-bool RecursorLua4::policyHitEventFilter(const ComboAddress& remote, const DNSName& qname, const QType& qtype, bool tcp, DNSFilterEngine::Policy& policy, std::unordered_set<std::string>& tags, std::unordered_map<std::string, bool>& discardedPolicies) const
+bool RecursorLua4::policyHitEventFilter(const ComboAddress& /* remote */, const DNSName& /* qname */, const QType& /* qtype */, bool /* tcp */, DNSFilterEngine::Policy& /* policy */, std::unordered_set<std::string>& /* tags */, std::unordered_map<std::string, bool>& /* discardedPolicies */) const
{
return false;
}
{
}
-void RecursorLua4::getFeatures(Features& features)
+void RecursorLua4::getFeatures(Features& /* features */)
{
}
-LWResult::Result asyncresolve(const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, const std::shared_ptr<std::vector<std::unique_ptr<RemoteLogger>>>& outgoingLoggers, const std::shared_ptr<std::vector<std::unique_ptr<FrameStreamLogger>>>& fstrmLoggers, const std::set<uint16_t>& exportTypes, LWResult* res, bool* chained)
+LWResult::Result asyncresolve(const ComboAddress& /* ip */, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, const std::shared_ptr<std::vector<std::unique_ptr<RemoteLogger>>>& /* outgoingLoggers */, const std::shared_ptr<std::vector<std::unique_ptr<FrameStreamLogger>>>& /* fstrmLoggers */, const std::set<uint16_t>& /* exportTypes */, LWResult* /* res */, bool* /* chained */)
{
return LWResult::Result::Timeout;
}
vector<DNSRecord> aset;
aset.push_back(arr);
g_recCache->replace(now, DNSName(templ), QType(QType::A), aset, vector<std::shared_ptr<const RRSIGRecordContent>>(), vector<std::shared_ptr<DNSRecord>>(), false, g_rootdnsname);
- if (rootIps6[c - 'a'] != NULL) {
+ if (!rootIps6[c - 'a'].empty()) {
aaaarr.setContent(std::make_shared<AAAARecordContent>(ComboAddress(rootIps6[c - 'a'])));
vector<DNSRecord> aaaaset;
bool isRootServer(const ComboAddress& ip)
{
if (ip.isIPv4()) {
- for (size_t idx = 0; idx < rootIps4Count; idx++) {
+ for (size_t idx = 0; idx < rootIps4.size(); idx++) {
if (ip.toString() == rootIps4[idx]) {
return true;
}
}
}
else {
- for (size_t idx = 0; idx < rootIps6Count; idx++) {
+ for (size_t idx = 0; idx < rootIps6.size(); idx++) {
if (ip.toString() == rootIps6[idx]) {
return true;
}
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (domain == target && type == QType::NS) {
size_t queriesCount = 0;
- sr->setAsyncCallback([&queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([&queriesCount](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (domain == g_rootdnsname && type == QType::NS) {
then call getRootNS(), for which at least one of the root servers needs to answer.
None will, so it should ServFail.
*/
- sr->setAsyncCallback([&downServers](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([&downServers](const ComboAddress& ip, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* /* res */, bool* /* chained */) {
downServers.insert(ip);
return LWResult::Result::Timeout;
});
primeHints();
const DNSName target("www.example.com.");
- sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
if (domain == g_rootdnsname && type == QType::NS) {
setLWResult(res, 0, true, false, true);
size_t queriesCount = 0;
- auto asynccb = [target, &queriesCount, aroot, newA, newAAAA](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ auto asynccb = [target, &queriesCount, aroot, newA, newAAAA](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (domain == target && type == QType::NS) {
size_t queriesWithEDNS = 0;
size_t queriesWithoutEDNS = 0;
- sr->setAsyncCallback([&queriesWithEDNS, &queriesWithoutEDNS, &noEDNSServer, sample](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([&queriesWithEDNS, &queriesWithoutEDNS, &noEDNSServer, sample](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool /* sendRDQuery */, int EDNS0Level, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
if (EDNS0Level != 0) {
queriesWithEDNS++;
noEDNSServer = ip;
size_t queriesWithoutEDNS = 0;
std::set<ComboAddress> usedServers;
- sr->setAsyncCallback([&queriesWithEDNS, &queriesWithoutEDNS, &usedServers](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([&queriesWithEDNS, &queriesWithoutEDNS, &usedServers](const ComboAddress& ip, const DNSName& /* domain */, int type, bool /* doTCP */, bool /* sendRDQuery */, int EDNS0Level, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
if (EDNS0Level > 0) {
queriesWithEDNS++;
}
for (const auto qtype : invalidTypes) {
size_t queriesCount = 0;
- sr->setAsyncCallback([&queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([&queriesCount](const ComboAddress& /* ip */, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* /* res */, bool* /* chained */) {
queriesCount++;
return LWResult::Result::Timeout;
});
std::unique_ptr<SyncRes> sr;
initSR(sr);
- sr->setAsyncCallback([](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([](const ComboAddress& /* ip */, const DNSName& domain, int type, bool doTCP, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
if (!doTCP) {
setLWResult(res, 0, false, true, false);
return LWResult::Result::Success;
size_t tcpQueriesCount = 0;
- sr->setAsyncCallback([&tcpQueriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([&tcpQueriesCount](const ComboAddress& /* ip */, const DNSName& domain, int /* type */, bool doTCP, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
if (!doTCP) {
setLWResult(res, 0, true, true, false);
return LWResult::Result::Success;
primeHints();
- sr->setAsyncCallback([&downServers](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([&downServers](const ComboAddress& ip, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
if (isRootServer(ip)) {
setLWResult(res, 0, false, false, true);
addRecordToLW(res, "com.", QType::NS, "a.gtld-servers.net.", DNSResourceRecord::AUTHORITY, 172800);
primeHints();
- sr->setAsyncCallback([&downServers](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([&downServers](const ComboAddress& ip, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
if (isRootServer(ip)) {
setLWResult(res, 0, false, false, true);
addRecordToLW(res, "com.", QType::NS, "a.gtld-servers.net.", DNSResourceRecord::AUTHORITY, 172800);
std::set<ComboAddress> downServers;
- sr->setAsyncCallback([&downServers](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([&downServers](const ComboAddress& ip, const DNSName& /* domain */, int /* type */, bool doTCP, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
if (isRootServer(ip)) {
setLWResult(res, 0, false, false, true);
addRecordToLW(res, "lock-up.", QType::NS, "a.gtld-servers.net.", DNSResourceRecord::AUTHORITY, 172800);
std::set<ComboAddress> downServers;
size_t queriesCount = 0;
- sr->setAsyncCallback([&queriesCount, &downServers](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([&queriesCount, &downServers](const ComboAddress& ip, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
if (isRootServer(ip)) {
setLWResult(res, 0, false, false, true);
addRecordToLW(res, "lock-up.", QType::NS, "a.gtld-servers.net.", DNSResourceRecord::AUTHORITY, 172800);
std::set<ComboAddress> downServers;
size_t queriesCount = 0;
- sr->setAsyncCallback([&queriesCount, &downServers](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([&queriesCount, &downServers](const ComboAddress& ip, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
if (isRootServer(ip)) {
setLWResult(res, 0, false, false, true);
addRecordToLW(res, "refused.", QType::NS, "a.gtld-servers.net.", DNSResourceRecord::AUTHORITY, 172800);
ad.d_servers = forwardedNSs;
(*SyncRes::t_sstorage.domainmap)[target] = ad;
- sr->setAsyncCallback([&queriesCount, &downServers](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([&queriesCount, &downServers](const ComboAddress& ip, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
if (isRootServer(ip)) {
setLWResult(res, 0, false, false, true);
addRecordToLW(res, "refused.", QType::NS, "a.gtld-servers.net.", DNSResourceRecord::AUTHORITY, 172800);
ad.d_servers = forwardedNSs;
(*SyncRes::t_sstorage.domainmap)[DNSName("refused.")] = ad;
- sr->setAsyncCallback([&queriesCount, &downServers](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([&queriesCount, &downServers](const ComboAddress& ip, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
if (isRootServer(ip)) {
setLWResult(res, 0, false, false, true);
addRecordToLW(res, "refused.", QType::NS, "a.gtld-servers.net.", DNSResourceRecord::AUTHORITY, 172800);
DNSName target("www.powerdns.com.");
- sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
if (isRootServer(ip)) {
setLWResult(res, 0, false, false, true);
if (domain == target) {
primeHints();
- sr->setAsyncCallback([&downServers](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([&downServers](const ComboAddress& ip, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
if (isRootServer(ip)) {
setLWResult(res, 0, false, false, true);
addRecordToLW(res, "com.", QType::NS, "a.gtld-servers.net.", DNSResourceRecord::AUTHORITY, 172800);
const DNSName target("powerdns.com.");
- sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
/* this will cause issue with qname minimization if we ever implement it */
if (domain != target) {
return LWResult::Result::Timeout;
const DNSName target("powerdns.com.");
- sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
if (isRootServer(ip)) {
setLWResult(res, 0, false, false, true);
const DNSName target("powerdns.com.");
- sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
if (isRootServer(ip)) {
setLWResult(res, 0, false, false, true);
incomingECS.source = Netmask("192.0.2.128/32");
sr->setQuerySource(ComboAddress(), boost::optional<const EDNSSubnetOpts&>(incomingECS));
- sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
BOOST_REQUIRE(srcmask);
BOOST_CHECK_EQUAL(srcmask->toString(), "192.0.2.0/24");
incomingECS.source = Netmask("2001:DB8::FF/128");
sr->setQuerySource(ComboAddress(), boost::optional<const EDNSSubnetOpts&>(incomingECS));
- sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
if (isRootServer(ip)) {
BOOST_REQUIRE(!srcmask);
// No incoming ECS data
sr->setQuerySource(ComboAddress("192.0.2.127"), boost::none);
- sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
if (isRootServer(ip)) {
BOOST_REQUIRE(!srcmask);
// No incoming ECS data, Requestor IP not in ecs-add-for
sr->setQuerySource(ComboAddress("192.0.2.127"), boost::none);
- sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
if (isRootServer(ip)) {
BOOST_REQUIRE(!srcmask);
incomingECS.source = Netmask("192.0.0.0/16");
sr->setQuerySource(ComboAddress("192.0.2.127"), boost::optional<const EDNSSubnetOpts&>(incomingECS));
- sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
if (isRootServer(ip)) {
BOOST_REQUIRE(!srcmask);
incomingECS.source = Netmask("0.0.0.0/0");
sr->setQuerySource(ComboAddress("192.0.2.127"), boost::optional<const EDNSSubnetOpts&>(incomingECS));
- sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
if (isRootServer(ip)) {
BOOST_REQUIRE(!srcmask);
const DNSName target("cname.powerdns.com.");
const DNSName cnameTarget("cname-target.powerdns.com");
- sr->setAsyncCallback([target, cnameTarget](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, cnameTarget](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
if (isRootServer(ip)) {
setLWResult(res, 0, false, false, true);
addRecordToLW(res, domain, QType::NS, "a.gtld-servers.net.", DNSResourceRecord::AUTHORITY, 172800);
const DNSName target("cname.powerdns.com.");
const DNSName cnameTarget("cname-target.powerdns.com");
- sr->setAsyncCallback([target, cnameTarget](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, cnameTarget](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
if (isRootServer(ip)) {
setLWResult(res, 0, false, false, true);
addRecordToLW(res, "powerdns.com.", QType::NS, "a.gtld-servers.net.", DNSResourceRecord::AUTHORITY, 172800);
const DNSName target("cname.powerdns.com.");
const DNSName cnameTarget("cname-target.powerdns.com");
- sr->setAsyncCallback([target, cnameTarget](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, cnameTarget](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
if (isRootServer(ip)) {
setLWResult(res, 0, false, false, true);
size_t count = 0;
const DNSName target("cname.powerdns.com.");
- sr->setAsyncCallback([target, &count](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &count](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
count++;
if (isRootServer(ip)) {
const DNSName target3("cname3.powerdns.com.");
const DNSName target4("cname4.powerdns.com.");
- sr->setAsyncCallback([target1, target2, target3, target4, &count](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target1, target2, target3, target4, &count](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
count++;
if (isRootServer(ip)) {
size_t depth = 0;
const DNSName target("cname.powerdns.com.");
- sr->setAsyncCallback([target, &depth](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &depth](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
if (isRootServer(ip)) {
setLWResult(res, 0, false, false, true);
size_t queries = 0;
const DNSName target("cname.powerdns.com.");
- sr->setAsyncCallback([target, &queries](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queries](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queries++;
if (isRootServer(ip)) {
size_t queries = 0;
- sr->setAsyncCallback([dnameOwner, dnameTarget, target, cnameTarget, uncachedTarget, uncachedCNAMETarget, &queries](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([dnameOwner, dnameTarget, target, cnameTarget, uncachedTarget, uncachedCNAMETarget, &queries](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queries++;
if (isRootServer(ip)) {
size_t queries = 0;
- sr->setAsyncCallback([dnameOwner, dnameTarget, target, cnameTarget, keys, &queries](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([dnameOwner, dnameTarget, target, cnameTarget, keys, &queries](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queries++;
/* We don't use the genericDSAndDNSKEYHandler here, as it would deny names existing at the wrong level of the tree, due to the way computeZoneCuts works
* As such, we need to do some more work to make the answers correct.
size_t queries = 0;
- sr->setAsyncCallback([dnameOwner, dnameTarget, target, cnameTarget, keys, &queries](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([dnameOwner, dnameTarget, target, cnameTarget, keys, &queries](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queries++;
if (type == QType::DS || type == QType::DNSKEY) {
size_t queries = 0;
- sr->setAsyncCallback([dnameOwner, dnameTarget, target, cnameTarget, keys, &queries](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([dnameOwner, dnameTarget, target, cnameTarget, keys, &queries](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queries++;
if (isRootServer(ip)) {
size_t queries = 0;
- sr->setAsyncCallback([dnameOwner, dnameTarget, target, cnameTarget, &queries](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([dnameOwner, dnameTarget, target, cnameTarget, &queries](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queries++;
if (isRootServer(ip)) {
const DNSName target("powerdns.com.");
- sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
/* this will cause issue with qname minimization if we ever implement it */
if (domain != target) {
return LWResult::Result::Timeout;
int queries = 0;
const DNSName target("powerdns.com.");
- sr->setAsyncCallback([target, &v4Hit, &v6Hit, &queries](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &v4Hit, &v6Hit, &queries](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queries++;
if (isRootServer(ip)) {
setLWResult(res, 0, false, false, true);
int queries = 0;
const DNSName target("powerdns.com.");
- sr->setAsyncCallback([target, &queries](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queries](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queries++;
if (isRootServer(ip)) {
setLWResult(res, 0, false, false, true);
int queries = 0;
const DNSName target("powerdns.com.");
- sr->setAsyncCallback([target, &queries](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queries](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queries++;
if (isRootServer(ip)) {
setLWResult(res, 0, false, false, true);
size_t queriesCount = 0;
- sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS) {
size_t queriesCount = 0;
- sr->setAsyncCallback([targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS) {
size_t queriesCount = 0;
- sr->setAsyncCallback([targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS) {
size_t queriesCount = 0;
- sr->setAsyncCallback([targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS) {
size_t queriesCount = 0;
- sr->setAsyncCallback([targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS) {
size_t queriesCount = 0;
- sr->setAsyncCallback([targetAddr, &queriesCount, keys, wrongKeys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([targetAddr, &queriesCount, keys, wrongKeys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS) {
const int theTTL = 5;
- sr->setAsyncCallback([&downServers, &downCount, &lookupCount, target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([&downServers, &downCount, &lookupCount, target](const ComboAddress& ip, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
/* this will cause issue with qname minimization if we ever implement it */
if (downServers.find(ip) != downServers.end()) {
downCount++;
const int theTTL = 5;
- sr->setAsyncCallback([&downServers, &downCount, &lookupCount, target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([&downServers, &downCount, &lookupCount, target](const ComboAddress& ip, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
/* this will cause issue with qname minimization if we ever implement it */
if (downServers.find(ip) != downServers.end()) {
downCount++;
const int theTTL = 5;
const int negTTL = 60;
- sr->setAsyncCallback([&downServers, &downCount, &lookupCount, &negLookup, target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([&downServers, &downCount, &lookupCount, &negLookup, target](const ComboAddress& ip, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
/* this will cause issue with qname minimization if we ever implement it */
if (downServers.find(ip) != downServers.end()) {
downCount++;
const int theTTL = 5;
const int negTTL = 60;
- sr->setAsyncCallback([&downServers, &downCount, &lookupCount, &cnameOK, target, auth](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([&downServers, &downCount, &lookupCount, &cnameOK, target, auth](const ComboAddress& ip, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
/* this will cause issue with qname minimization if we ever implement it */
if (downServers.find(ip) != downServers.end()) {
downCount++;
const int theTTL = 5;
- sr->setAsyncCallback([&downServers, &downCount, &lookupCount, target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([&downServers, &downCount, &lookupCount, target](const ComboAddress& ip, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
/* this will cause issue with qname minimization if we ever implement it */
if (downServers.find(ip) != downServers.end()) {
const DNSName target1("powerdns.com.");
const DNSName target2("pdns.com.");
- sr->setAsyncCallback([=](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([=](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
/* this will cause issue with qname minimization if we ever implement it */
if (domain != target1 && domain != target2) {
return LWResult::Result::Timeout;
const DNSName target1("powerdns.com.");
const DNSName target2("pdns.com.");
- sr->setAsyncCallback([=](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([=](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
/* this will cause issue with qname minimization if we ever implement it */
if (domain != target1 && domain != target2) {
return LWResult::Result::Timeout;
const DNSName target("powerdns.com.");
- sr->setAsyncCallback([=](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([=](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
/* this will cause issue with qname minimization if we ever implement it */
if (domain != target) {
return LWResult::Result::Timeout;
size_t queries = 0;
const DNSName target("www.powerdns.com.");
- sr->setAsyncCallback([target, &queries](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queries](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queries++;
if (isRootServer(ip)) {
const DNSName target2("powerdns.org.");
size_t queriesToNS = 0;
- sr->setAsyncCallback([target1, target2, &queriesToNS](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target1, target2, &queriesToNS](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesToNS++;
if (isRootServer(ip)) {
const DNSName target2("powerdns.org.");
size_t queriesToNS = 0;
- sr->setAsyncCallback([target1, target2, &queriesToNS](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target1, target2, &queriesToNS](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesToNS++;
if (isRootServer(ip)) {
size_t queryCount = 0;
- sr->setAsyncCallback([target, &queryCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queryCount](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
if (isRootServer(ip)) {
setLWResult(res, 0, false, false, true);
size_t queries = 0;
const DNSName target("cname.powerdns.com.");
- sr->setAsyncCallback([target, &queries](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queries](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queries++;
if (isRootServer(ip)) {
const ComboAddress ns("192.0.2.1:53");
size_t queriesToNS = 0;
- sr->setAsyncCallback([target, ns, &queriesToNS](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, ns, &queriesToNS](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
if (isRootServer(ip)) {
setLWResult(res, 0, false, false, true);
const ComboAddress ns("192.0.2.1:53");
size_t queriesToNS = 0;
- sr->setAsyncCallback([target, ns, &queriesToNS](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, ns, &queriesToNS](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
if (isRootServer(ip)) {
setLWResult(res, 0, false, false, true);
const ComboAddress ns("192.0.2.1:53");
size_t queriesCount = 0;
- sr->setAsyncCallback([target1, target2, ns, &queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target1, target2, ns, &queriesCount](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (isRootServer(ip)) {
/* This time the root denies target1 with a "com." SOA instead of a "." one.
We should add target1 to the negcache, but not "com.". */
- sr->setAsyncCallback([target1, target2, ns, &queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target1, target2, ns, &queriesCount](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (isRootServer(ip)) {
const ComboAddress ns("192.0.2.1:53");
size_t queriesCount = 0;
- sr->setAsyncCallback([target1, target2, ns, &queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target1, target2, ns, &queriesCount](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (isRootServer(ip)) {
const ComboAddress ns("192.0.2.1:53");
size_t queriesCount = 0;
- sr->setAsyncCallback([ns, &queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([ns, &queriesCount](const ComboAddress& ip, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (isRootServer(ip)) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target1, target2, target3, target4, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target1, target2, target3, target4, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
DNSName auth = domain;
const ComboAddress ns("192.0.2.1:53");
size_t queriesCount = 0;
- sr->setAsyncCallback([ns, target1, target2, target3, &queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([ns, target1, target2, target3, &queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (isRootServer(ip)) {
const ComboAddress ns("192.0.2.1:53");
size_t queriesCount = 0;
- sr->setAsyncCallback([ns, target1, target2, target3, &queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([ns, target1, target2, target3, &queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (isRootServer(ip)) {
incomingECS.source = Netmask("192.0.2.128/32");
sr->setQuerySource(ComboAddress(), boost::optional<const EDNSSubnetOpts&>(incomingECS));
- sr->setAsyncCallback([target, cnameTarget](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, cnameTarget](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
BOOST_REQUIRE(srcmask);
BOOST_CHECK_EQUAL(srcmask->toString(), "192.0.2.0/24");
sr->setQuerySource(ComboAddress(), boost::optional<const EDNSSubnetOpts&>(incomingECS));
SyncRes::s_ecsipv4cachelimit = 24;
- sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target](const ComboAddress& /* ip */, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
BOOST_REQUIRE(srcmask);
BOOST_CHECK_EQUAL(srcmask->toString(), "192.0.2.0/24");
sr->setQuerySource(ComboAddress(), boost::optional<const EDNSSubnetOpts&>(incomingECS));
SyncRes::s_ecsipv4cachelimit = 16;
- sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target](const ComboAddress& /* ip */, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
BOOST_REQUIRE(srcmask);
BOOST_CHECK_EQUAL(srcmask->toString(), "192.0.2.0/24");
sr->setQuerySource(ComboAddress(), boost::optional<const EDNSSubnetOpts&>(incomingECS));
SyncRes::s_ecscachelimitttl = 30;
- sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target](const ComboAddress& /* ip */, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
BOOST_REQUIRE(srcmask);
BOOST_CHECK_EQUAL(srcmask->toString(), "192.0.2.0/24");
SyncRes::s_ecscachelimitttl = 100;
SyncRes::s_ecsipv4cachelimit = 24;
- sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target](const ComboAddress& /* ip */, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
BOOST_REQUIRE(srcmask);
BOOST_CHECK_EQUAL(srcmask->toString(), "192.0.2.0/24");
SyncRes::s_ecscachelimitttl = 100;
SyncRes::s_ecsipv4cachelimit = 16;
- sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target](const ComboAddress& /* ip */, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
BOOST_REQUIRE(srcmask);
BOOST_CHECK_EQUAL(srcmask->toString(), "192.0.2.0/24");
std::map<ComboAddress, uint64_t> nsCounts;
- sr->setAsyncCallback([target, &nsCounts](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &nsCounts](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
if (isRootServer(ip)) {
setLWResult(res, 0, false, false, true);
addRecordToLW(res, domain, QType::NS, "pdns-public-ns1.powerdns.com.", DNSResourceRecord::AUTHORITY, 172800);
const DNSName target("powerdns.com.");
- sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
if (isRootServer(ip)) {
setLWResult(res, 0, false, false, true);
addRecordToLW(res, domain, QType::NS, "pdns-public-ns1.powerdns.com.", DNSResourceRecord::AUTHORITY, 172800);
const DNSName target("powerdns.com.");
size_t queriesCount = 0;
- sr->setAsyncCallback([&queriesCount, target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([&queriesCount, target](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (isRootServer(ip) && domain == target) {
const DNSName target("powerdns.com.");
size_t queriesCount = 0;
- sr->setAsyncCallback([&queriesCount, target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([&queriesCount, target](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (isRootServer(ip) && domain == target) {
const DNSName target("powerdns.com.");
- sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target](const ComboAddress& /* ip */, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* /* res */, bool* /* chained */) {
return LWResult::Result::Timeout;
});
sr->setCacheOnly();
- sr->setAsyncCallback([target, &queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount](const ComboAddress& /* ip */, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* /* res */, bool* /* chained */) {
queriesCount++;
return LWResult::Result::Timeout;
});
const DNSName target("cachettl.powerdns.com.");
const ComboAddress ns("192.0.2.1:53");
- sr->setAsyncCallback([target, ns](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, ns](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
if (isRootServer(ip)) {
setLWResult(res, 0, false, false, true);
sr->setQuerySource(ComboAddress(), boost::optional<const EDNSSubnetOpts&>(incomingECS));
SyncRes::addEDNSDomain(target);
- sr->setAsyncCallback([target, ns](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, ns](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
BOOST_REQUIRE(srcmask);
BOOST_CHECK_EQUAL(srcmask->toString(), "192.0.2.0/24");
const DNSName target("powerdns.com.");
- sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
if (isRootServer(ip)) {
setLWResult(res, 0, false, false, true);
addRecordToLW(res, domain, QType::NS, "pdns-public-ns1.powerdns.com.", DNSResourceRecord::AUTHORITY, 172800);
const DNSName target("powerdns.com.");
- auto cb = [target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ auto cb = [target](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
if (isRootServer(ip)) {
setLWResult(res, 0, false, false, true);
addRecordToLW(res, domain, QType::NS, "pdns-public-ns1.powerdns.com.", DNSResourceRecord::AUTHORITY, 172800);
check that we only return one result, and we only cache one too. */
const DNSName target("cache-auth.powerdns.com.");
- sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target](const ComboAddress& /* ip */, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
setLWResult(res, 0, true, false, true);
addRecordToLW(res, domain, QType::A, "192.0.2.2", DNSResourceRecord::ANSWER, 10);
addRecordToLW(res, domain, QType::A, "192.0.2.2", DNSResourceRecord::ADDITIONAL, 10);
const DNSName target("powerdns.com.");
- sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
if (isRootServer(ip)) {
setLWResult(res, 0, false, false, true);
addRecordToLW(res, "com.", QType::NS, "a.gtld-servers.net.", DNSResourceRecord::AUTHORITY, 172800);
const DNSName target("powerdns.com.");
sr->setAsyncCallback(
- [target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level,
- struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context,
- LWResult* res, bool* chained) {
+ [target](const ComboAddress& /* ip */, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */,
+ struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */,
+ LWResult* res, bool* /* chained */) {
setLWResult(res, 0, true, false, true);
return LWResult::Result::Success;
});
const DNSName target2("www2.powerdns.com."); // in bailiwick, but not asked for
const DNSName target3("www.random.net."); // out of bailiwick and not asked for
- sr->setAsyncCallback([target, target2, target3](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, target2, target3](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
if (isRootServer(ip)) {
setLWResult(res, 0, false, false, true);
addRecordToLW(res, "powerdns.com.", QType::NS, "a.gtld-servers.net.", DNSResourceRecord::AUTHORITY, 172800);
generateKeyMaterial(DNSName("powerdns.com"), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys, luaconfsCopy.dsAnchors);
g_luaconfs.setState(luaconfsCopy);
- sr->setAsyncCallback([target, target2, target3, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, target2, target3, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
if (type == QType::DS || type == QType::DNSKEY) {
return genericDSAndDNSKEYHandler(res, domain, domain, type, keys, false);
}
const DNSName target("powerdns.com.");
- sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target](const ComboAddress& /* ip */, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
setLWResult(res, 0, true, false, true);
addRecordToLW(res, domain, QType::A, "192.0.2.42");
addRecordToLW(res, domain, QType::ANY, "\\# 0");
const DNSName target("powerdns.com.");
- sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target](const ComboAddress& /* ip */, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
setLWResult(res, 0, true, false, true);
addRecordToLW(res, domain, QType::SOA, "pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600);
/* the NSEC and RRSIG contents are complete garbage, please ignore them */
const DNSName target("powerdns.com.");
- sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target](const ComboAddress& /* ip */, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
setLWResult(res, 0, true, false, true);
addRecordToLW(res, domain, QType::SOA, "pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600);
/* the NSEC and RRSIG contents are complete garbage, please ignore them */
const DNSName target("powerdns.com.");
- sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target](const ComboAddress& /* ip */, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
setLWResult(res, RCode::NXDomain, true, false, true);
addRecordToLW(res, domain, QType::SOA, "pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600);
/* the NSEC and RRSIG contents are complete garbage, please ignore them */
const DNSName target("powerdns.com.");
- sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target](const ComboAddress& /* ip */, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
setLWResult(res, RCode::NXDomain, true, false, true);
addRecordToLW(res, domain, QType::SOA, "pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600);
/* the NSEC and RRSIG contents are complete garbage, please ignore them */
/* apart from special names and QClass::ANY, anything else than QClass::IN should be rejected right away */
size_t queriesCount = 0;
- sr->setAsyncCallback([&queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([&queriesCount](const ComboAddress& /* ip */, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* /* res */, bool* /* chained */) {
queriesCount++;
return LWResult::Result::Timeout;
});
const DNSName target("powerdns.com.");
- sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target](const ComboAddress& /* ip */, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
setLWResult(res, 0, false, false, true);
addRecordToLW(res, domain, QType::A, "192.0.2.1");
return LWResult::Result::Success;
/* {A,I}XFR, RRSIG and NSEC3 should be rejected right away */
size_t queriesCount = 0;
- sr->setAsyncCallback([&queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([&queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* /* res */, bool* /* chained */) {
cerr << "asyncresolve called to ask " << ip.toStringWithPort() << " about " << domain.toString() << " / " << QType(type).toString() << " over " << (doTCP ? "TCP" : "UDP") << " (rd: " << sendRDQuery << ", EDNS0 level: " << EDNS0Level << ")" << endl;
queriesCount++;
return LWResult::Result::Timeout;
size_t queriesCount = 0;
- sr->setAsyncCallback([&queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([&queriesCount](const ComboAddress& /* ip */, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* /* res */, bool* /* chained */) {
queriesCount++;
return LWResult::Result::Timeout;
});
const DNSName target("rpz.powerdns.com.");
const ComboAddress ns("192.0.2.1:53");
- sr->setAsyncCallback([target, ns](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, ns](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
if (isRootServer(ip)) {
setLWResult(res, false, true, false, true);
addRecordToLW(res, "com.", QType::NS, "a.gtld-servers.net.", DNSResourceRecord::AUTHORITY, 172800);
const DNSName target("rpz.powerdns.com.");
const ComboAddress ns("[2001:DB8::42]:53");
- sr->setAsyncCallback([target, ns](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, ns](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
if (isRootServer(ip)) {
setLWResult(res, 0, false, false, true);
addRecordToLW(res, "com.", QType::NS, "a.gtld-servers.net.", DNSResourceRecord::AUTHORITY, 172800);
const ComboAddress ns("192.0.2.1:53");
const DNSName nsName("ns1.powerdns.com.");
- sr->setAsyncCallback([target, ns, nsName](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, ns, nsName](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
if (isRootServer(ip)) {
setLWResult(res, 0, false, false, true);
addRecordToLW(res, domain, QType::NS, nsName.toString(), DNSResourceRecord::AUTHORITY, 172800);
const ComboAddress ns("192.0.2.1:53");
const DNSName nsName("ns1.powerdns.com.");
- sr->setAsyncCallback([target, ns, nsName](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, ns, nsName](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
if (isRootServer(ip)) {
setLWResult(res, 0, false, false, true);
addRecordToLW(res, domain, QType::NS, nsName.toString(), DNSResourceRecord::AUTHORITY, 172800);
size_t queriesCount = 0;
- sr->setAsyncCallback([forwardedNS, &queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([forwardedNS, &queriesCount](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool sendRDQuery, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
++queriesCount;
if (ip == forwardedNS) {
BOOST_CHECK_EQUAL(sendRDQuery, false);
ad.d_servers.push_back(forwardedNS);
(*SyncRes::t_sstorage.domainmap)[target] = ad;
- sr->setAsyncCallback([forwardedNS, &queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([forwardedNS, &queriesCount](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool sendRDQuery, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (ip == forwardedNS) {
size_t queriesCount = 0;
- sr->setAsyncCallback([forwardedNS, &queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([forwardedNS, &queriesCount](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool sendRDQuery, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
++queriesCount;
if (ip == forwardedNS) {
BOOST_CHECK_EQUAL(sendRDQuery, true);
ad.d_servers.push_back(forwardedNS);
(*SyncRes::t_sstorage.domainmap)[target] = ad;
- sr->setAsyncCallback([forwardedNS](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([forwardedNS](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool sendRDQuery, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
if (ip == forwardedNS) {
BOOST_CHECK_EQUAL(sendRDQuery, true);
ad.d_servers.push_back(forwardedNS);
(*SyncRes::t_sstorage.domainmap)[g_rootdnsname] = ad;
- sr->setAsyncCallback([target, cnameTarget, keys, forwardedNS, &queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, cnameTarget, keys, forwardedNS, &queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool sendRDQuery, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
BOOST_CHECK_EQUAL(sendRDQuery, true);
ad.d_servers.push_back(forwardedNS);
(*SyncRes::t_sstorage.domainmap)[DNSName("test.")] = ad;
- sr->setAsyncCallback([parent, target1, target2, keys, forwardedNS, &queriesCount, &DSforParentCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([parent, target1, target2, keys, forwardedNS, &queriesCount, &DSforParentCount](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool sendRDQuery, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
BOOST_CHECK_EQUAL(sendRDQuery, false);
ad.d_servers.push_back(forwardedNS);
(*SyncRes::t_sstorage.domainmap)[g_rootdnsname] = ad;
- sr->setAsyncCallback([target, cnameTarget, keys, forwardedNS, &queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, cnameTarget, keys, forwardedNS, &queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool sendRDQuery, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
BOOST_CHECK_EQUAL(sendRDQuery, true);
size_t queriesCount = 0;
- sr->setAsyncCallback([target, forwardedNS, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, forwardedNS, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool sendRDQuery, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
BOOST_CHECK_EQUAL(sendRDQuery, true);
(*SyncRes::t_sstorage.domainmap)[authZone] = ad;
- sr->setAsyncCallback([&queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([&queriesCount](const ComboAddress& /* ip */, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* /* res */, bool* /* chained */) {
queriesCount++;
return LWResult::Result::Timeout;
});
(*SyncRes::t_sstorage.domainmap)[authZone] = ad;
- sr->setAsyncCallback([&queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([&queriesCount](const ComboAddress& /* ip */, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* /* res */, bool* /* chained */) {
queriesCount++;
return LWResult::Result::Timeout;
});
(*map)[target] = ad;
SyncRes::setDomainMap(map);
- sr->setAsyncCallback([&queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([&queriesCount](const ComboAddress& /* ip */, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
setLWResult(res, 0, true, false, true);
addRecordToLW(res, domain, QType::A, "192.0.2.42");
(*map)[authZone] = ad;
SyncRes::setDomainMap(map);
- sr->setAsyncCallback([&queriesCount, target, authZone](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([&queriesCount, target, authZone](const ComboAddress& /* ip */, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (domain == target) {
(*map)[target] = ad;
SyncRes::setDomainMap(map);
- sr->setAsyncCallback([&queriesCount, externalCNAME, addr](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([&queriesCount, externalCNAME, addr](const ComboAddress& /* ip */, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (domain == externalCNAME) {
(*map)[target] = ad;
SyncRes::setDomainMap(map);
- sr->setAsyncCallback([&queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([&queriesCount](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type != QType::DS) {
setLWResult(res, 0, true, false, true);
(*map)[authZone] = ad;
SyncRes::setDomainMap(map);
- sr->setAsyncCallback([&queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([&queriesCount](const ComboAddress& /* ip */, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* /* res */, bool* /* chained */) {
queriesCount++;
return LWResult::Result::Timeout;
(*map)[authZone] = ad;
SyncRes::setDomainMap(map);
- sr->setAsyncCallback([&queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([&queriesCount](const ComboAddress& /* ip */, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* /* res */, bool* /* chained */) {
queriesCount++;
return LWResult::Result::Timeout;
takes too long. */
const time_t fixedNow = sr->getNow().tv_sec;
- sr->setAsyncCallback([&queriesCount, target, targetAddr, nsAddr, authZone, keys, fixedNow](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([&queriesCount, target, targetAddr, nsAddr, authZone, keys, fixedNow](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS || type == QType::DNSKEY) {
return genericDSAndDNSKEYHandler(res, domain, DNSName("."), type, keys, domain == DNSName("com.") || domain == authZone, fixedNow);
(*map)[authZone] = ad;
SyncRes::setDomainMap(map);
- sr->setAsyncCallback([&queriesCount, nsAddr, target, targetAddr](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([&queriesCount, nsAddr, target, targetAddr](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (ip == ComboAddress(nsAddr.toString(), 53) && domain == target) {
(*map)[authZone] = ad;
SyncRes::setDomainMap(map);
- sr->setAsyncCallback([&queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([&queriesCount](const ComboAddress& /* ip */, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* /* res */, bool* /* chained */) {
queriesCount++;
return LWResult::Result::Timeout;
(*map)[authZone] = ad;
SyncRes::setDomainMap(map);
- sr->setAsyncCallback([&queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([&queriesCount](const ComboAddress& /* ip */, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* /* res */, bool* /* chained */) {
queriesCount++;
return LWResult::Result::Timeout;
(*map)[authZone] = ad;
SyncRes::setDomainMap(map);
- sr->setAsyncCallback([&queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([&queriesCount](const ComboAddress& /* ip */, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* /* res */, bool* /* chained */) {
queriesCount++;
return LWResult::Result::Timeout;
(*map)[target] = ad;
SyncRes::setDomainMap(map);
- sr->setAsyncCallback([&queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([&queriesCount](const ComboAddress& /* ip */, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
setLWResult(res, 0, true, false, true);
addRecordToLW(res, domain, QType::A, "192.0.2.42");
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (domain == target && type == QType::NS) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, zskeys, kskeys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, zskeys, kskeys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (domain == target && type == QType::NS) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (domain == target && type == QType::NS) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (domain == target && type == QType::NS) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (domain == target && type == QType::NS) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (domain == target && type == QType::NS) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys, rrsigkeys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys, rrsigkeys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (domain == target && type == QType::NS) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (domain == target && type == QType::NS) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (domain == target && type == QType::NS) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (domain == target && type == QType::NS) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (domain == target && type == QType::NS) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys, fixedNow](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys, fixedNow](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (domain == target && type == QType::NS) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (domain == target && type == QType::NS) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
DNSName auth = domain;
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
DNSName auth = domain;
const time_t fixedNow = sr->getNow().tv_sec;
- sr->setAsyncCallback([target, targetAddr, &queriesCount, keys, fixedNow](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, targetAddr, &queriesCount, keys, fixedNow](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
DNSName auth = domain;
size_t queriesCount = 0;
- sr->setAsyncCallback([target, targetAddr, &queriesCount, keys, fixedNow](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, targetAddr, &queriesCount, keys, fixedNow](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
DNSName auth = domain;
size_t queriesCount = 0;
- sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
DNSName auth = domain;
size_t queriesCount = 0;
- sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
DNSName auth = domain;
size_t queriesCount = 0;
- sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
DNSName auth = domain;
size_t queriesCount = 0;
- sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS || type == QType::DNSKEY) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS || type == QType::DNSKEY) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
DNSName auth = domain;
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS || type == QType::DNSKEY) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS || type == QType::DNSKEY) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS || type == QType::DNSKEY) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS || type == QType::DNSKEY) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS || type == QType::DNSKEY) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS || type == QType::DNSKEY) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS || type == QType::DNSKEY) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS || type == QType::DNSKEY) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS || type == QType::DNSKEY) {
g_luaconfs.setState(luaconfsCopy);
- sr->setAsyncCallback([target, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
if (type == QType::DS || type == QType::DNSKEY) {
if (domain == target) {
const auto auth = DNSName("powerdns.com.");
g_luaconfs.setState(luaconfsCopy);
- sr->setAsyncCallback([target, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
if (type == QType::DS || type == QType::DNSKEY) {
if (domain == target) {
const auto auth = DNSName("powerdns.com.");
g_luaconfs.setState(luaconfsCopy);
- sr->setAsyncCallback([target, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
if (type == QType::DS || type == QType::DNSKEY) {
if (domain == target) {
const auto auth = DNSName("powerdns.com.");
size_t queriesCount = 0;
- sr->setAsyncCallback([&queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([&queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
DNSName auth(domain);
const time_t fixedNow = sr->getNow().tv_sec;
- sr->setAsyncCallback([target, targetAddr, &queriesCount, keys, fixedNow](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, targetAddr, &queriesCount, keys, fixedNow](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
DNSName auth = domain;
}
}
-static void dnssec_secure_servfail_dnskey(DNSSECMode mode, vState expectedValidationResult)
+static void dnssec_secure_servfail_dnskey(DNSSECMode mode, vState /* expectedValidationResult */)
{
std::unique_ptr<SyncRes> sr;
initSR(sr, true);
const time_t fixedNow = sr->getNow().tv_sec;
- sr->setAsyncCallback([target, targetAddr, &queriesCount, keys, fixedNow](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, targetAddr, &queriesCount, keys, fixedNow](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
DNSName auth = domain;
const time_t fixedNow = sr->getNow().tv_sec;
- sr->setAsyncCallback([target, targetAddr, &queriesCount, keys, pdnskeys, fixedNow](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, targetAddr, &queriesCount, keys, pdnskeys, fixedNow](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
DNSName auth = domain;
size_t queriesCount = 0;
size_t dsQueriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, &dsQueriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, &dsQueriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DNSKEY || (type == QType::DS && domain != target)) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS) {
size_t queriesCount = 0;
size_t dsQueriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, &dsQueriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, &dsQueriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS || type == QType::DNSKEY) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS || type == QType::DNSKEY) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS || type == QType::DNSKEY) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS || type == QType::DNSKEY) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, targetAddr, &queriesCount, keys, pdnskeys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, targetAddr, &queriesCount, keys, pdnskeys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS || type == QType::DNSKEY) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, targetCName, targetCNameAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, targetCName, targetCNameAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, targetCName1, targetCName2, targetCName2Addr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, targetCName1, targetCName2, targetCName2Addr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS || type == QType::DNSKEY) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, targetCName, targetCNameAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, targetCName, targetCNameAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, targetCName, targetCNameAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, targetCName, targetCNameAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS || type == QType::DNSKEY) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, targetCName, targetCNameAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, targetCName, targetCNameAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS || type == QType::DNSKEY) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, targetCName, targetCNameAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, targetCName, targetCNameAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS || type == QType::DNSKEY) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, targetCName, targetCNameAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, targetCName, targetCNameAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DNSKEY) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DNSKEY) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (domain == target && type == QType::NS) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (domain == target && type == QType::NS) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS || type == QType::DNSKEY) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS || type == QType::DNSKEY) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS || type == QType::DNSKEY) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS || type == QType::DNSKEY) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, targetCName, targetCNameAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, targetCName, targetCNameAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, targetCName, targetCNameAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, targetCName, targetCNameAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS) {
size_t queriesCount = 0;
const time_t fixedNow = sr->getNow().tv_sec;
- sr->setAsyncCallback([target, &queriesCount, keys, fixedNow](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys, fixedNow](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
DNSName auth = domain;
size_t queriesCount = 0;
const time_t fixedNow = sr->getNow().tv_sec;
- sr->setAsyncCallback([&queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([&queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
DNSName auth = domain;
size_t queriesCount = 0;
const time_t tnow = sr->getNow().tv_sec;
- sr->setAsyncCallback([target, targetAddr, &queriesCount, keys, tnow](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, targetAddr, &queriesCount, keys, tnow](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
DNSName auth = domain;
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS || type == QType::DNSKEY) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS || type == QType::DNSKEY) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS || type == QType::DNSKEY) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS || type == QType::DNSKEY) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, cnameTarget, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, cnameTarget, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS || type == QType::DNSKEY) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, cnameTarget, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, cnameTarget, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS || type == QType::DNSKEY) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, cnameTarget, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, cnameTarget, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS || type == QType::DNSKEY) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, addTarget, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, addTarget, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS || type == QType::DNSKEY) {
size_t queriesCount = 0;
const time_t fixedNow = sr->getNow().tv_sec;
- sr->setAsyncCallback([target, &queriesCount, keys, fixedNow](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys, fixedNow](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
DNSName auth = domain;
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (type == QType::DS || type == QType::DNSKEY) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
DNSName auth = domain;
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
DNSName auth = domain;
const DNSName target("WWW.POWERDNS.COM");
const DNSName cname("WWW.PowerDNS.org");
- sr->setAsyncCallback([target, cname, &sentOutQnames](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, cname, &sentOutQnames](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
sentOutQnames.push_back(domain);
if (isRootServer(ip)) {
auto rootkey = keys.find(g_rootdnsname);
keys2.insert(*rootkey);
- sr->setAsyncCallback([target, keys, keys2](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, keys, keys2](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
DNSName auth = domain;
auth.chopOff();
if (type == QType::DS || type == QType::DNSKEY) {
// But add the existing root key otherwise no RRSIG can be created
keys3.insert(*rootkey);
- sr->setAsyncCallback([target, keys, keys2, keys3](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, keys, keys2, keys3](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
DNSName auth = domain;
auth.chopOff();
if (type == QType::DS || type == QType::DNSKEY) {
// But add the existing root key otherwise no RRSIG can be created
keys3.insert(*rootkey);
- sr->setAsyncCallback([target, keys, keys2, keys3](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, keys, keys2, keys3](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
DNSName auth = domain;
auth.chopOff();
if (type == QType::DS || type == QType::DNSKEY) {
const DNSName cnameTarget("cname-target.powerdns.com");
size_t queriesCount = 0;
- sr->setAsyncCallback([target, cnameTarget, &queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, cnameTarget, &queriesCount](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (isRootServer(ip)) {
generateKeyMaterial(DNSName("powerdns.com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys);
g_luaconfs.setState(luaconfsCopy);
- sr->setAsyncCallback([keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
if (type == QType::DS || type == QType::DNSKEY) {
if (domain == DNSName("cname.powerdns.com.")) {
return genericDSAndDNSKEYHandler(res, domain, domain, type, keys, false /* no cut */);
const DNSName target("sanitization.powerdns.com.");
- sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target](const ComboAddress& /* ip */, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
setLWResult(res, 0, true, false, true);
addRecordToLW(res, domain, QType::A, "192.0.2.1");
/* should be scrubbed because it doesn't match the QType */
const DNSName target("sanitization.powerdns.com.");
- sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target](const ComboAddress& /* ip */, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
setLWResult(res, 0, true, false, true);
addRecordToLW(res, domain, QType::A, "192.0.2.1");
addRecordToLW(res, domain, QType::AAAA, "2001:db8::1", DNSResourceRecord::ADDITIONAL);
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount](const ComboAddress& ip, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (isRootServer(ip)) {
const DNSName target("sanitization-ns-nxd.powerdns.com.");
- sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target](const ComboAddress& /* ip */, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
setLWResult(res, RCode::NXDomain, true, false, true);
addRecordToLW(res, "powerdns.com.", QType::SOA, "pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY);
addRecordToLW(res, "powerdns.com.", QType::NS, "spoofed.ns.", DNSResourceRecord::AUTHORITY, 172800);
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (domain.isPartOf(DNSName("signed.ds-ignorant.com.")) && ip == ComboAddress("192.0.2.1:53")) {
size_t queriesCount = 0;
- sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, LWResult* res, bool* chained) {
+ sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional<Netmask>& /* srcmask */, boost::optional<const ResolveContext&> /* context */, LWResult* res, bool* /* chained */) {
queriesCount++;
if (domain.isPartOf(DNSName("signed.ds-ignorant.com.")) && ip == ComboAddress("192.0.2.1:53")) {
{"record-cache-contended",
MetricDefinition(PrometheusMetricType::counter,
- "Number of contented record cache lock acquisitions")},
+ "Number of contended record cache lock acquisitions")},
+
+ {"packetcache-acquired",
+ MetricDefinition(PrometheusMetricType::counter,
+ "Number of packet cache lock acquisitions")},
+
+ {"packetcache-contended",
+ MetricDefinition(PrometheusMetricType::counter,
+ "Number of contended packet cache lock acquisitions")},
{"taskqueue-expired",
MetricDefinition(PrometheusMetricType::counter,
snmp_read2(&fdset);
}
-void SNMPAgent::handleTrapsCB(int fd, FDMultiplexer::funcparam_t& var)
+void SNMPAgent::handleTrapsCB(int /* fd */, FDMultiplexer::funcparam_t& var)
{
SNMPAgent** agent = boost::any_cast<SNMPAgent*>(&var);
if (!agent || !*agent)
cmd();
}
double delta=dt.ndiff()/1000000000.0;
- boost::format fmt("'%s' %.02f seconds: %.1f runs/s, %.02f usec/run");
+ boost::format fmt("'%s' %.02f seconds: %.1f runs/s, %.02f us/run");
cerr<< (fmt % cmd.getName() % delta % (runs/delta) % (delta* 1000000.0/runs)) << endl;
g_totalRuns += runs;
throw SSqlException(string("Error while retrieving SQLite query results: ")+SSQLite3ErrorString(d_db->db()));
}
if(d_dolog)
- g_log<<Logger::Warning<< "Query "<<((long)(void*)this)<<": "<<d_dtime.udiffNoReset()<<" usec to execute"<<endl;
+ g_log<<Logger::Warning<< "Query "<<((long)(void*)this)<<": "<<d_dtime.udiffNoReset()<<" us to execute"<<endl;
return this;
}
bool hasNextRow() {
if(d_dolog && d_rc != SQLITE_ROW) {
- g_log<<Logger::Warning<< "Query "<<((long)(void*)this)<<": "<<d_dtime.udiffNoReset()<<" total usec to last row"<<endl;
+ g_log<<Logger::Warning<< "Query "<<((long)(void*)this)<<": "<<d_dtime.udiffNoReset()<<" us total to last row"<<endl;
}
return d_rc == SQLITE_ROW;
}
private:
/* called in a client context, if the client advertised more than one ALPN values and the server returned more than one as well, to select the one to use. */
#ifndef DISABLE_NPN
- static int npnSelectCallback(SSL* s, unsigned char** out, unsigned char* outlen, const unsigned char* in, unsigned int inlen, void* arg)
+ static int npnSelectCallback(SSL* /* s */, unsigned char** out, unsigned char* outlen, const unsigned char* in, unsigned int inlen, void* arg)
{
if (!arg) {
return SSL_TLSEXT_ERR_ALERT_WARNING;
unsigned int udiff;
DTime dt;
dt.set();
- int records=0;
for(DNSZoneRecord &loopZRR : zrrs) {
- records++;
if(securedZone && (loopZRR.auth || loopZRR.dr.d_type == QType::NS)) {
if (NSEC3Zone || loopZRR.dr.d_type) {
if (presignedZone && NSEC3Zone && loopZRR.dr.d_type == QType::RRSIG && getRR<RRSIGRecordContent>(loopZRR.dr)->d_type == QType::NSEC3) {
BOOST_CHECK_EQUAL(name2.getCommonLabels(name1), DNSName("powerdns.com"));
const DNSName name3("www.powerdns.org");
- BOOST_CHECK_EQUAL(name1.getCommonLabels(name3), DNSName());
- BOOST_CHECK_EQUAL(name2.getCommonLabels(name3), DNSName());
- BOOST_CHECK_EQUAL(name3.getCommonLabels(name1), DNSName());
- BOOST_CHECK_EQUAL(name3.getCommonLabels(name2), DNSName());
+ BOOST_CHECK_EQUAL(name1.getCommonLabels(name3), g_rootdnsname);
+ BOOST_CHECK_EQUAL(name2.getCommonLabels(name3), g_rootdnsname);
+ BOOST_CHECK_EQUAL(name3.getCommonLabels(name1), g_rootdnsname);
+ BOOST_CHECK_EQUAL(name3.getCommonLabels(name2), g_rootdnsname);
const DNSName name4("WWw.PowErDnS.org");
BOOST_CHECK_EQUAL(name3.getCommonLabels(name4), name3);
BOOST_CHECK_EQUAL(name4.getCommonLabels(name3), name4);
+
+ const DNSName(name5);
+ BOOST_CHECK_EQUAL(name1.getCommonLabels(name5), DNSName());
+ BOOST_CHECK_EQUAL(name5.getCommonLabels(name1), DNSName());
}
BOOST_AUTO_TEST_SUITE_END()
ttd.tv_sec -= 5;
bool writeCBCalled = false;
- auto writeCB = [](int fd, FDMultiplexer::funcparam_t& param) {
+ auto writeCB = [](int /* fd */, FDMultiplexer::funcparam_t& param) {
auto calledPtr = boost::any_cast<bool*>(param);
BOOST_REQUIRE(calledPtr != nullptr);
*calledPtr = true;
BOOST_CHECK_EQUAL(ready, 0);
bool readCBCalled = false;
- auto readCB = [](int fd, FDMultiplexer::funcparam_t& param) {
+ auto readCB = [](int /* fd */, FDMultiplexer::funcparam_t& param) {
auto calledPtr = boost::any_cast<bool*>(param);
BOOST_REQUIRE(calledPtr != nullptr);
*calledPtr = true;
bool readCBCalled = false;
bool writeCBCalled = false;
- auto readCB = [](int fd, FDMultiplexer::funcparam_t& param) {
+ auto readCB = [](int /* fd */, FDMultiplexer::funcparam_t& param) {
auto calledPtr = boost::any_cast<bool*>(param);
BOOST_REQUIRE(calledPtr != nullptr);
*calledPtr = true;
};
- auto writeCB = [](int fd, FDMultiplexer::funcparam_t& param) {
+ auto writeCB = [](int /* fd */, FDMultiplexer::funcparam_t& param) {
auto calledPtr = boost::any_cast<bool*>(param);
BOOST_REQUIRE(calledPtr != nullptr);
*calledPtr = true;
LINE1:alloutqueries#00ff00:"outqueries/s"
rrdtool graph $GRAPHOPTS --start -$1 $WWWPREFIX/qa-latency-$2.png -w $WSIZE -h $HSIZE -l 0 \
- -t "Questions/answer latency in milliseconds" \
- -v "msec" \
+ -t "Questions/answer latency in ms" \
+ -v "ms" \
DEF:qalatency=pdns_recursor.rrd:qa-latency:AVERAGE \
CDEF:mqalatency=qalatency,1000,/ \
LINE1:mqalatency#ff0000:"questions/s"
-void Utility::setBindAny(int af, sock_t sock)
+void Utility::setBindAny([[maybe_unused]] int af, [[maybe_unused]] sock_t sock)
{
const int one = 1;
// Returns the current time.
-int Utility::gettimeofday( struct timeval *tv, void *tz )
+int Utility::gettimeofday( struct timeval *tv, void * /* tz */)
{
- return ::gettimeofday(tv,nullptr);
+ return ::gettimeofday(tv, nullptr);
}
// Sets the random seed.
using nsec3HashesCache = std::map<std::tuple<DNSName, std::string, uint16_t>, std::string>;
-static std::string getHashFromNSEC3(const DNSName& qname, const std::shared_ptr<const NSEC3RecordContent>& nsec3, nsec3HashesCache& cache)
+static std::string getHashFromNSEC3(const DNSName& qname, const NSEC3RecordContent& nsec3, nsec3HashesCache& cache)
{
std::string result;
- if (g_maxNSEC3Iterations && nsec3->d_iterations > g_maxNSEC3Iterations) {
+ if (g_maxNSEC3Iterations && nsec3.d_iterations > g_maxNSEC3Iterations) {
return result;
}
- auto key = std::make_tuple(qname, nsec3->d_salt, nsec3->d_iterations);
+ auto key = std::make_tuple(qname, nsec3.d_salt, nsec3.d_iterations);
auto it = cache.find(key);
if (it != cache.end())
{
return it->second;
}
- result = hashQNameWithSalt(nsec3->d_salt, nsec3->d_iterations, qname);
+ result = hashQNameWithSalt(nsec3.d_salt, nsec3.d_iterations, qname);
cache[key] = result;
return result;
}
continue;
}
- const string h = getHashFromNSEC3(zone, nsec3, cache);
+ const string h = getHashFromNSEC3(zone, *nsec3, cache);
if (h.empty()) {
return false;
}
Labels field of the covering RRSIG RR, then the RRset and its
covering RRSIG RR were created as a result of wildcard expansion."
*/
-bool isWildcardExpanded(unsigned int labelCount, const std::shared_ptr<const RRSIGRecordContent>& sign)
+bool isWildcardExpanded(unsigned int labelCount, const RRSIGRecordContent& sign)
{
- if (sign && sign->d_labels < labelCount) {
+ if (sign.d_labels < labelCount) {
return true;
}
const auto& sign = signatures.at(0);
unsigned int labelsCount = owner.countLabels();
- return isWildcardExpanded(labelsCount, sign);
+ return isWildcardExpanded(labelsCount, *sign);
}
-bool isWildcardExpandedOntoItself(const DNSName& owner, unsigned int labelCount, const std::shared_ptr<const RRSIGRecordContent>& sign)
+bool isWildcardExpandedOntoItself(const DNSName& owner, unsigned int labelCount, const RRSIGRecordContent& sign)
{
- if (owner.isWildcard() && (labelCount - 1) == sign->d_labels) {
+ if (owner.isWildcard() && (labelCount - 1) == sign.d_labels) {
/* this is a wildcard alright, but it has not been expanded */
return true;
}
const auto& sign = signatures.at(0);
unsigned int labelsCount = owner.countLabels();
- return isWildcardExpandedOntoItself(owner, labelsCount, sign);
+ return isWildcardExpandedOntoItself(owner, labelsCount, *sign);
}
/* if this is a wildcard NSEC, the owner name has been modified
return result;
}
-static bool isNSECAncestorDelegation(const DNSName& signer, const DNSName& owner, const std::shared_ptr<const NSECRecordContent>& nsec)
+static bool isNSECAncestorDelegation(const DNSName& signer, const DNSName& owner, const NSECRecordContent& nsec)
{
- return nsec->isSet(QType::NS) &&
- !nsec->isSet(QType::SOA) &&
+ return nsec.isSet(QType::NS) &&
+ !nsec.isSet(QType::SOA) &&
signer.countLabels() < owner.countLabels();
}
-bool isNSEC3AncestorDelegation(const DNSName& signer, const DNSName& owner, const std::shared_ptr<const NSEC3RecordContent>& nsec3)
+bool isNSEC3AncestorDelegation(const DNSName& signer, const DNSName& owner, const NSEC3RecordContent& nsec3)
{
- return nsec3->isSet(QType::NS) &&
- !nsec3->isSet(QType::SOA) &&
+ return nsec3.isSet(QType::NS) &&
+ !nsec3.isSet(QType::SOA) &&
signer.countLabels() < owner.countLabels();
}
}
VLOG(log, qname << ":\tWildcard matches");
- if (qtype == 0 || isTypeDenied(nsec, QType(qtype))) {
+ if (qtype == 0 || isTypeDenied(*nsec, QType(qtype))) {
VLOG_NO_PREFIX(log, " and proves that the type did not exist"<<endl);
return true;
}
continue;
}
- string h = getHashFromNSEC3(wildcard, nsec3, cache);
+ string h = getHashFromNSEC3(wildcard, *nsec3, cache);
if (h.empty()) {
return false;
}
that (original) owner name other than DS RRs, and all RRs below that
owner name regardless of type.
*/
- if (qtype != QType::DS && isNSEC3AncestorDelegation(signer, v.first.first, nsec3)) {
+ if (qtype != QType::DS && isNSEC3AncestorDelegation(signer, v.first.first, *nsec3)) {
/* this is an "ancestor delegation" NSEC3 RR */
VLOG_NO_PREFIX(log, " BUT an ancestor delegation NSEC3 RR can only deny the existence of a DS"<<endl);
return false;
}
- if (qtype == 0 || isTypeDenied(nsec3, QType(qtype))) {
+ if (qtype == 0 || isTypeDenied(*nsec3, QType(qtype))) {
VLOG_NO_PREFIX(log, " and proves that the type did not exist"<<endl);
return true;
}
return false;
}
-dState matchesNSEC(const DNSName& name, uint16_t qtype, const DNSName& nsecOwner, const std::shared_ptr<const NSECRecordContent>& nsec, const std::vector<std::shared_ptr<const RRSIGRecordContent>>& signatures, const OptLog& log)
+dState matchesNSEC(const DNSName& name, uint16_t qtype, const DNSName& nsecOwner, const NSECRecordContent& nsec, const std::vector<std::shared_ptr<const RRSIGRecordContent>>& signatures, const OptLog& log)
{
const DNSName signer = getSigner(signatures);
if (!name.isPartOf(signer) || !nsecOwner.isPartOf(signer)) {
return dState::NXQTYPE;
}
- if (name.isPartOf(owner) && nsec->isSet(QType::DNAME)) {
+ if (name.isPartOf(owner) && nsec.isSet(QType::DNAME)) {
/* rfc6672 section 5.3.2: DNAME Bit in NSEC Type Map
In any negative response, the NSEC or NSEC3 [RFC5155] record type
return dState::NODENIAL;
}
- if (isCoveredByNSEC(name, owner, nsec->d_next)) {
- VLOG_NO_PREFIX(log, name << ": is covered by ("<<owner<<" to "<<nsec->d_next<<")");
+ if (isCoveredByNSEC(name, owner, nsec.d_next)) {
+ VLOG_NO_PREFIX(log, name << ": is covered by ("<<owner<<" to "<<nsec.d_next<<")");
- if (nsecProvesENT(name, owner, nsec->d_next)) {
+ if (nsecProvesENT(name, owner, nsec.d_next)) {
VLOG_NO_PREFIX(log, " denies existence of type "<<name<<"/"<<QType(qtype)<<" by proving that "<<name<<" is an ENT"<<endl);
return dState::NXQTYPE;
}
that (original) owner name other than DS RRs, and all RRs below that
owner name regardless of type.
*/
- if (qname.isPartOf(owner) && isNSECAncestorDelegation(signer, owner, nsec)) {
+ if (qname.isPartOf(owner) && isNSECAncestorDelegation(signer, owner, *nsec)) {
/* this is an "ancestor delegation" NSEC RR */
if (!(qtype == QType::DS && qname == owner)) {
VLOG(log, qname << ": An ancestor delegation NSEC RR can only deny the existence of a DS"<<endl);
/* check if the type is denied */
if (qname == owner) {
- if (!isTypeDenied(nsec, QType(qtype))) {
+ if (!isTypeDenied(*nsec, QType(qtype))) {
VLOG(log, qname << ": Does _not_ deny existence of type "<<QType(qtype)<<endl);
return dState::NODENIAL;
}
continue;
}
- string h = getHashFromNSEC3(qname, nsec3, cache);
+ string h = getHashFromNSEC3(qname, *nsec3, cache);
if (h.empty()) {
VLOG(log, qname << ": Unsupported hash, ignoring"<<endl);
return dState::INSECURE;
that (original) owner name other than DS RRs, and all RRs below that
owner name regardless of type.
*/
- if (qtype != QType::DS && isNSEC3AncestorDelegation(signer, qname, nsec3)) {
+ if (qtype != QType::DS && isNSEC3AncestorDelegation(signer, qname, *nsec3)) {
/* this is an "ancestor delegation" NSEC3 RR */
VLOG(log, qname << ": An ancestor delegation NSEC3 RR can only deny the existence of a DS"<<endl);
return dState::NODENIAL;
}
- if (!isTypeDenied(nsec3, QType(qtype))) {
+ if (!isTypeDenied(*nsec3, QType(qtype))) {
VLOG(log, qname << ": Does _not_ deny existence of type "<<QType(qtype)<<" for name "<<qname<<" (not opt-out)."<<endl);
return dState::NODENIAL;
}
continue;
}
- string h = getHashFromNSEC3(closestEncloser, nsec3, cache);
+ string h = getHashFromNSEC3(closestEncloser, *nsec3, cache);
if (h.empty()) {
return dState::INSECURE;
}
VLOG(log, qname << ": Comparing "<<toBase32Hex(h)<<" ("<<closestEncloser<<") against "<<toBase32Hex(beginHash)<<endl);
if (beginHash == h) {
/* If the closest encloser is a delegation NS we know nothing about the names in the child zone. */
- if (isNSEC3AncestorDelegation(signer, v.first.first, nsec3)) {
+ if (isNSEC3AncestorDelegation(signer, v.first.first, *nsec3)) {
VLOG(log, qname << ": An ancestor delegation NSEC3 RR can only deny the existence of a DS"<<endl);
continue;
}
if(!nsec3)
continue;
- string h = getHashFromNSEC3(nextCloser, nsec3, cache);
+ string h = getHashFromNSEC3(nextCloser, *nsec3, cache);
if (h.empty()) {
return dState::INSECURE;
}
return dState::NODENIAL;
}
-bool isRRSIGNotExpired(const time_t now, const shared_ptr<const RRSIGRecordContent>& sig)
+bool isRRSIGNotExpired(const time_t now, const RRSIGRecordContent& sig)
{
// Should use https://www.rfc-editor.org/rfc/rfc4034.txt section 3.1.5
- return sig->d_sigexpire >= now;
+ return sig.d_sigexpire >= now;
}
-bool isRRSIGIncepted(const time_t now, const shared_ptr<const RRSIGRecordContent>& sig)
+bool isRRSIGIncepted(const time_t now, const RRSIGRecordContent& sig)
{
// Should use https://www.rfc-editor.org/rfc/rfc4034.txt section 3.1.5
- return sig->d_siginception - g_signatureInceptionSkew <= now;
+ return sig.d_siginception - g_signatureInceptionSkew <= now;
}
-static bool checkSignatureWithKey(const DNSName& qname, time_t now, const shared_ptr<const RRSIGRecordContent>& sig, const shared_ptr<const DNSKEYRecordContent>& key, const std::string& msg, vState& ede, const OptLog& log)
+static bool checkSignatureWithKey(const DNSName& qname, time_t now, const RRSIGRecordContent& sig, const DNSKEYRecordContent& key, const std::string& msg, vState& ede, const OptLog& log)
{
bool result = false;
try {
- The validator's notion of the current time MUST be greater than or equal to the time listed in the RRSIG RR's Inception field.
*/
if (isRRSIGIncepted(now, sig) && isRRSIGNotExpired(now, sig)) {
- auto dke = DNSCryptoKeyEngine::makeFromPublicKeyString(key->d_algorithm, key->d_key);
- result = dke->verify(msg, sig->d_signature);
- VLOG(log, qname << ": Signature by key with tag "<<sig->d_tag<<" and algorithm "<<DNSSECKeeper::algorithm2name(sig->d_algorithm)<<" was " << (result ? "" : "NOT ")<<"valid"<<endl);
+ auto dke = DNSCryptoKeyEngine::makeFromPublicKeyString(key.d_algorithm, key.d_key);
+ result = dke->verify(msg, sig.d_signature);
+ VLOG(log, qname << ": Signature by key with tag "<<sig.d_tag<<" and algorithm "<<DNSSECKeeper::algorithm2name(sig.d_algorithm)<<" was " << (result ? "" : "NOT ")<<"valid"<<endl);
if (!result) {
ede = vState::BogusNoValidRRSIG;
}
}
else {
- ede = ((sig->d_siginception - g_signatureInceptionSkew) > now) ? vState::BogusSignatureNotYetValid : vState::BogusSignatureExpired;
- VLOG(log, qname << ": Signature is "<<(ede == vState::BogusSignatureNotYetValid ? "not yet valid" : "expired")<<" (inception: "<<sig->d_siginception<<", inception skew: "<<g_signatureInceptionSkew<<", expiration: "<<sig->d_sigexpire<<", now: "<<now<<")"<<endl);
+ ede = ((sig.d_siginception - g_signatureInceptionSkew) > now) ? vState::BogusSignatureNotYetValid : vState::BogusSignatureExpired;
+ VLOG(log, qname << ": Signature is "<<(ede == vState::BogusSignatureNotYetValid ? "not yet valid" : "expired")<<" (inception: "<<sig.d_siginception<<", inception skew: "<<g_signatureInceptionSkew<<", expiration: "<<sig.d_sigexpire<<", now: "<<now<<")"<<endl);
}
}
catch (const std::exception& e) {
string msg = getMessageForRRSET(name, *signature, toSign, true);
for (const auto& key : keysMatchingTag) {
vState ede;
- bool signIsValid = checkSignatureWithKey(name, now, signature, key, msg, ede, log);
+ bool signIsValid = checkSignatureWithKey(name, now, *signature, *key, msg, ede, log);
foundKey = true;
if (signIsValid) {
}
else {
VLOG(log, name << ": signature invalid"<<endl);
- if (isRRSIGIncepted(now, signature)) {
+ if (isRRSIGIncepted(now, *signature)) {
noneIncepted = false;
}
- if (isRRSIGNotExpired(now, signature)) {
+ if (isRRSIGNotExpired(now, *signature)) {
allExpired = false;
}
}
string msg = getMessageForRRSET(zone, *sig, toSign);
for (const auto& key : bytag) {
// cerr<<"validating : ";
- bool signIsValid = checkSignatureWithKey(zone, now, sig, key, msg, ede, log);
+ bool signIsValid = checkSignatureWithKey(zone, now, *sig, *key, msg, ede, log);
- if (signIsValid)
- {
+ if (signIsValid) {
VLOG(log, zone << ": Validation succeeded - whole DNSKEY set is valid"<<endl);
validkeys = tkeys;
break;
bool isSupportedDS(const DSRecordContent& ds, const OptLog&);
DNSName getSigner(const std::vector<std::shared_ptr<const RRSIGRecordContent> >& signatures);
bool denialProvesNoDelegation(const DNSName& zone, const std::vector<DNSRecord>& dsrecords);
-bool isRRSIGNotExpired(const time_t now, const std::shared_ptr<const RRSIGRecordContent>& sig);
-bool isRRSIGIncepted(const time_t now, const shared_ptr<const RRSIGRecordContent>& sig);
-bool isWildcardExpanded(unsigned int labelCount, const std::shared_ptr<const RRSIGRecordContent>& sign);
-bool isWildcardExpandedOntoItself(const DNSName& owner, unsigned int labelCount, const std::shared_ptr<const RRSIGRecordContent>& sign);
+bool isRRSIGNotExpired(const time_t now, const RRSIGRecordContent& sig);
+bool isRRSIGIncepted(const time_t now, const RRSIGRecordContent& sig);
+bool isWildcardExpanded(unsigned int labelCount, const RRSIGRecordContent& sign);
+bool isWildcardExpandedOntoItself(const DNSName& owner, unsigned int labelCount, const RRSIGRecordContent& sign);
void updateDNSSECValidationState(vState& state, const vState stateUpdate);
-dState matchesNSEC(const DNSName& name, uint16_t qtype, const DNSName& nsecOwner, const std::shared_ptr<const NSECRecordContent>& nsec, const std::vector<std::shared_ptr<const RRSIGRecordContent>>& signatures, const OptLog&);
+dState matchesNSEC(const DNSName& name, uint16_t qtype, const DNSName& nsecOwner, const NSECRecordContent& nsec, const std::vector<std::shared_ptr<const RRSIGRecordContent>>& signatures, const OptLog&);
-bool isNSEC3AncestorDelegation(const DNSName& signer, const DNSName& owner, const std::shared_ptr<const NSEC3RecordContent>& nsec3);
+bool isNSEC3AncestorDelegation(const DNSName& signer, const DNSName& owner, const NSEC3RecordContent& nsec3);
DNSName getNSECOwnerName(const DNSName& initialOwner, const std::vector<std::shared_ptr<const RRSIGRecordContent> >& signatures);
DNSName getClosestEncloserFromNSEC(const DNSName& name, const DNSName& owner, const DNSName& next);
template <typename NSEC> bool isTypeDenied(const NSEC& nsec, const QType& type)
{
- if (nsec->isSet(type.getCode())) {
+ if (nsec.isSet(type.getCode())) {
return false;
}
/* RFC 6840 section 4.3 */
- if (nsec->isSet(QType::CNAME)) {
+ if (nsec.isSet(QType::CNAME)) {
return false;
}
}
for(Comment& c : new_comments) {
c.domain_id = di.id;
- di.backend->feedComment(c);
+ if (!di.backend->feedComment(c)) {
+ throw ApiException("Hosting backend does not support editing comments.");
+ }
}
updateDomainSettingsFromDocument(B, di, zonename, document, !new_records.empty());
# Now run pdns and the tests.
print("Launching server...")
print(format_call_args(servercmd))
-serverproc = subprocess.Popen(servercmd, close_fds=True, text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+server_stdout = tempfile.TemporaryFile()
+server_stderr = tempfile.TemporaryFile()
+serverproc = subprocess.Popen(servercmd, close_fds=True, text=True, stdout=server_stdout, stderr=server_stderr)
+
+def finalize_server():
+ serverproc.terminate()
+ serverproc.wait()
+
+ print("==STDOUT==")
+ server_stdout.seek(0, 0)
+ sys.stdout.flush()
+ sys.stdout.buffer.write(server_stdout.read())
+ server_stdout.close()
+
+ print("==STDERR==")
+ server_stderr.seek(0, 0)
+ sys.stdout.flush()
+ sys.stdout.buffer.write(server_stderr.read())
+ server_stderr.close()
+
print("Waiting for webserver port to become available...")
available = False
if not available:
print("Webserver port not reachable after 10 tries, giving up.")
- serverproc.terminate()
- serverproc.wait()
- print("==STDOUT===")
- print(serverproc.stdout.read())
- print("==STDERRR===")
- print(serverproc.stderr.read())
+ finalize_server()
sys.exit(2)
print("Query for example.com/A to create statistic data...")
if wait:
print("Waiting as requested, press ENTER to stop.")
raw_input()
- serverproc.terminate()
- serverproc.wait()
- print("==STDOUT===")
- print(serverproc.stdout.read())
- print("==STDERRR===")
- print(serverproc.stderr.read())
+ finalize_server()
sys.exit(returncode)
import operator
import time
import unittest
+import requests.exceptions
from copy import deepcopy
from parameterized import parameterized
from pprint import pprint
# check our record has appeared
self.assertEqual(get_rrset(data, rrset['name'], 'A')['records'], rrset['records'])
- @unittest.skipIf(is_auth_lmdb(), "No comments in LMDB")
def test_create_zone_with_comments(self):
name = unique_zone_name()
rrsets = [
}],
},
]
+
+ if is_auth_lmdb():
+ with self.assertRaises(requests.exceptions.HTTPError): # No comments in LMDB
+ self.create_zone(name=name, rrsets=rrsets)
+ return
+
name, payload, data = self.create_zone(name=name, rrsets=rrsets)
# NS records have been created
self.assertEqual(len(data['rrsets']), len(rrsets) + 1)
self.assertEqual(r.status_code, 204)
self.assertNotIn('Content-Type', r.headers)
- @unittest.skipIf(is_auth_lmdb(), "No comments in LMDB")
def test_zone_comment_create(self):
name, payload, zone = self.create_zone()
rrset = {
self.url("/api/v1/servers/localhost/zones/" + name),
data=json.dumps(payload),
headers={'content-type': 'application/json'})
- self.assert_success(r)
+ if is_auth_lmdb():
+ self.assert_error_json(r) # No comments in LMDB
+ return
+ else:
+ self.assert_success(r)
# make sure the comments have been set, and that the NS
# records are still present
data = self.session.get(self.url("/api/v1/servers/localhost/zones/" + name)).json()
# verify that TTL is correct (regression test)
self.assertEqual(serverset['ttl'], 3600)
- @unittest.skipIf(is_auth_lmdb(), "No comments in LMDB")
def test_zone_comment_delete(self):
# Test: Delete ONLY comments.
name, payload, zone = self.create_zone()
all.ifportup 3600 IN LUA A "ifportup(8080, {{'{prefix}.101', '{prefix}.102'}})"
some.ifportup 3600 IN LUA A "ifportup(8080, {{'192.168.42.21', '{prefix}.102'}})"
+multi.ifportup 3600 IN LUA A "ifportup(8080, {{ {{'192.168.42.23'}}, {{'192.168.42.21', '{prefix}.102'}}, {{'{prefix}.101'}} }})"
none.ifportup 3600 IN LUA A "ifportup(8080, {{'192.168.42.21', '192.168.21.42'}})"
all.noneup.ifportup 3600 IN LUA A "ifportup(8080, {{'192.168.42.21', '192.168.21.42'}}, {{ backupSelector='all' }})"
config IN LUA LUA ("settings={{stringmatch='Programming in Lua'}} "
"EUWips={{'{prefix}.101','{prefix}.102'}} "
"EUEips={{'192.168.42.101','192.168.42.102'}} "
- "NLips={{'{prefix}.111', '{prefix}.112'}} "
- "USAips={{'{prefix}.103'}} ")
+ "NLips={{'{prefix}.111', '{prefix}.112'}} "
+ "USAips={{'{prefix}.103', '192.168.42.105'}} ")
usa IN LUA A ( ";include('config') "
"return ifurlup('http://www.lua.org:8080/', "
- "{{USAips, EUEips}}, settings) ")
+ "USAips, settings) ")
+
+usa-ext IN LUA A ( ";include('config') "
+ "return ifurlup('http://www.lua.org:8080/', "
+ "{{EUEips, USAips}}, settings) ")
mix.ifurlup IN LUA A ("ifurlup('http://www.other.org:8080/ping.json', "
"{{ '192.168.42.101', '{prefix}.101' }}, "
"{{ stringmatch='pong' }}) ")
-eu-west IN LUA A ( ";include('config') "
- "return ifurlup('http://www.lua.org:8080/', "
- "{{EUWips, EUEips, USAips}}, settings) ")
-
ifurlextup IN LUA A "ifurlextup({{{{['192.168.0.1']='http://{prefix}.101:8080/404',['192.168.0.2']='http://{prefix}.102:8080/404'}}, {{['192.168.0.3']='http://{prefix}.101:8080/'}}}})"
nl IN LUA A ( ";include('config') "
self.assertRcodeEqual(res, dns.rcode.NOERROR)
self.assertAnyRRsetInAnswer(res, expected)
+ def testIfportupWithSomeDownMultiset(self):
+ """
+ Basic ifportup() test with some ports DOWN from multiple sets
+ """
+ query = dns.message.make_query('multi.ifportup.example.org', 'A')
+ expected = [
+ dns.rrset.from_text('multi.ifportup.example.org.', 0, dns.rdataclass.IN, 'A',
+ '192.168.42.21'),
+ dns.rrset.from_text('multi.ifportup.example.org.', 0, dns.rdataclass.IN, 'A',
+ '192.168.42.23'),
+ dns.rrset.from_text('multi.ifportup.example.org.', 0, dns.rdataclass.IN, 'A',
+ '{prefix}.102'.format(prefix=self._PREFIX)),
+ dns.rrset.from_text('multi.ifportup.example.org.', 0, dns.rdataclass.IN, 'A',
+ '{prefix}.101'.format(prefix=self._PREFIX))
+ ]
+
+ # we first expect any of the IPs as no check has been performed yet
+ res = self.sendUDPQuery(query)
+ self.assertRcodeEqual(res, dns.rcode.NOERROR)
+ self.assertAnyRRsetInAnswer(res, expected)
+
+ # An ip is up in 2 sets, but we expect only the one from the middle set
+ expected = [expected[2]]
+ res = self.sendUDPQuery(query)
+ self.assertRcodeEqual(res, dns.rcode.NOERROR)
+ self.assertAnyRRsetInAnswer(res, expected)
+
def testIfportupWithAllDown(self):
"""
Basic ifportup() test with all ports DOWN
reachable = [
'{prefix}.103'.format(prefix=self._PREFIX)
]
- unreachable = ['192.168.42.101', '192.168.42.102']
+ unreachable = ['192.168.42.105']
ips = reachable + unreachable
all_rrs = []
reachable_rrs = []
self.assertRcodeEqual(res, dns.rcode.NOERROR)
self.assertAnyRRsetInAnswer(res, reachable_rrs)
+ def testIfurlupMultiSet(self):
+ """
+ Basic ifurlup() test with mutiple sets
+ """
+ reachable = [
+ '{prefix}.103'.format(prefix=self._PREFIX)
+ ]
+ unreachable = ['192.168.42.101', '192.168.42.102', '192.168.42.105']
+ ips = reachable + unreachable
+ all_rrs = []
+ reachable_rrs = []
+ for ip in ips:
+ rr = dns.rrset.from_text('usa-ext.example.org.', 0, dns.rdataclass.IN, 'A', ip)
+ all_rrs.append(rr)
+ if ip in reachable:
+ reachable_rrs.append(rr)
+
+ query = dns.message.make_query('usa-ext.example.org', 'A')
+ res = self.sendUDPQuery(query)
+ self.assertRcodeEqual(res, dns.rcode.NOERROR)
+ self.assertAnyRRsetInAnswer(res, all_rrs)
+
+ # the timeout in the LUA health checker is 2 second, so we make sure to wait slightly longer here
+ time.sleep(3)
+ res = self.sendUDPQuery(query)
+ self.assertRcodeEqual(res, dns.rcode.NOERROR)
+ self.assertAnyRRsetInAnswer(res, reachable_rrs)
+
def testIfurlextup(self):
expected = [dns.rrset.from_text('ifurlextup.example.org.', 0, dns.rdataclass.IN, dns.rdatatype.A, '192.168.0.3')]
_toResponderQueue = Queue()
_fromResponderQueue = Queue()
_queueTimeout = 1
- _dnsdistStartupDelay = 2.0
_dnsdist = None
_responsesCounter = {}
_config_template = """
_checkConfigExpectedOutput = None
_verboseMode = False
_skipListeningOnCL = False
+ _alternateListeningAddr = None
+ _alternateListeningPort = None
_backgroundThreads = {}
_UDPResponder = None
_TCPResponder = None
with open(logFile, 'w') as fdLog:
cls._dnsdist = subprocess.Popen(dnsdistcmd, close_fds=True, stdout=fdLog, stderr=fdLog)
- cls.waitForTCPSocket(cls._dnsDistListeningAddr, cls._dnsDistPort);
+ if cls._alternateListeningAddr and cls._alternateListeningPort:
+ cls.waitForTCPSocket(cls._alternateListeningAddr, cls._alternateListeningPort)
+ else:
+ cls.waitForTCPSocket(cls._dnsDistListeningAddr, cls._dnsDistPort)
if cls._dnsdist.poll() is not None:
print(f"\n*** startDNSDist log for {logFile} ***")
return
try:
p.terminate()
- for count in range(10):
+ for count in range(20):
x = p.poll()
if x is not None:
break
libnacl>=1.4.3,<1.7
requests>=2.1.0
protobuf>=3.0
+pyasn1==0.4.8
pysnmp>=4.3.4
future>=0.17.1
pycurl>=7.43.0
'doh-query-pipe-full', 'doh-response-pipe-full', 'proxy-protocol-invalid', 'tcp-listen-overflows',
'outgoing-doh-query-pipe-full', 'tcp-query-pipe-full', 'tcp-cross-protocol-query-pipe-full',
'tcp-cross-protocol-response-pipe-full']
+ _verboseMode = True
+
+ @classmethod
+ def setUpClass(cls):
+ cls.startResponders()
+ cls.startDNSDist()
+ cls.setUpSockets()
+ cls.waitForTCPSocket('127.0.0.1', cls._webServerPort)
+ print("Launching tests..")
class TestAPIBasics(APITestsBase):
setWebserverConfig({password="%s", apiKey="%s", maxConcurrentConnections=%d})
"""
+ @classmethod
+ def setUpClass(cls):
+ cls.startResponders()
+ cls.startDNSDist()
+ cls.setUpSockets()
+ # do no check if the web server socket is up, because this
+ # might mess up the concurrent connections counter
+
def testConcurrentConnections(self):
"""
Web: Concurrent connections
_config_params = ['_testServerPort', '_dnsDistPort']
_acl = ['127.0.0.1/32']
_skipListeningOnCL = True
+ _alternateListeningAddr = '127.0.1.19'
+ _alternateListeningPort = DNSDistTest._dnsDistPort
def testAdvancedCheckSourceAddrOnNonDefaultLoopbackBind(self):
"""
_resolverCertificateValidFrom = int(time.time() - 60)
_resolverCertificateValidUntil = int(time.time() + 7200)
- _dnsdistStartupDelay = 10
-
def doDNSCryptQuery(self, client, query, response, tcp):
self._toResponderQueue.put(response)
data = client.query(query.to_wire(), tcp=tcp)
addDOHLocal("127.0.0.1:%s", "%s", "%s", { "/" }, { maxConcurrentTCPConnections=%d })
"""
_config_params = ['_testServerPort', '_dohServerPort', '_serverCert', '_serverKey', '_maxTCPConnsPerDOHFrontend']
+ _alternateListeningAddr = '127.0.0.1'
+ _alternateListeningPort = _dohServerPort
def testTCPConnsPerDOHFrontend(self):
"""
self.checkQueryEDNSWithoutECS(expectedQuery, receivedQuery)
self.assertEqual(response, receivedResponse)
-class TestDOHWithPCKS12Cert(DNSDistDOHTest):
+class TestDOHWithPKCS12Cert(DNSDistDOHTest):
_serverCert = 'server.p12'
_pkcs12Password = 'passw0rd'
_serverName = 'tls.tests.dnsdist.org'
def testProtocolDOH(self):
"""
- DoH: Test Simple DOH Query with a password protected PCKS12 file configured
+ DoH: Test Simple DOH Query with a password protected PKCS12 file configured
"""
name = 'simple.doh.tests.powerdns.com.'
query = dns.message.make_query(name, 'A', 'IN', use_edns=False)
_dohBaseURL = ("https://%s:%d/" % (_serverName, _dohServerPort))
_config_params = ['_tlsServerPort', '_serverCert', '_serverKey', '_dohServerPort', '_serverCert', '_serverKey', '_testServerPort', '_webServerPort', '_webServerAPIKeyHashed']
+ @classmethod
+ def setUpClass(cls):
+ cls.startResponders()
+ cls.startDNSDist()
+ cls.setUpSockets()
+ cls.waitForTCPSocket('127.0.0.1', cls._webServerPort)
+ print("Launching tests..")
+
def getMetric(self, name):
headers = {'x-api-key': self._webServerAPIKey}
url = 'http://127.0.0.1:' + str(self._webServerPort) + '/api/v1/servers/localhost'
addTLSLocal("127.0.0.1:%s", "%s", "%s", { provider="openssl", maxConcurrentTCPConnections=%d })
"""
_config_params = ['_testServerPort', '_tlsServerPort', '_serverCert', '_serverKey', '_maxTCPConnsPerTLSFrontend']
+ _alternateListeningAddr = '127.0.0.1'
+ _alternateListeningPort = _tlsServerPort
def testTCPConnsPerTLSFrontend(self):
"""
do
${MD5SUM} ../regression-tests/zones/$zone
done
+${MD5SUM} ../modules/tinydnsbackend/data
${MD5SUM} ../modules/tinydnsbackend/data.cdb
dee3e8b568549d9450134b555ca73990 ../regression-tests/zones/sub.test.dyndns
e7c0fd528e8aaedb1ea3b6daaead4de2 ../regression-tests/zones/wtest.com
42b442de632686e94bde75acf66cf524 ../regression-tests/zones/nztest.com
-b06133eb32c5bdf346223563501ba8f8 ../regression-tests/zones/dnssec-parent.com
+7f79c98efdb1d3d2318ac666d2fb5642 ../regression-tests/zones/dnssec-parent.com
e9be89b6e5e0da8910c69e46f35d20ab ../regression-tests/zones/insecure.dnssec-parent.com
6510bf48aa3ca3501b73a1f510852a34 ../regression-tests/zones/delegated.dnssec-parent.com
a63dc120391d9df0003f2ec4f461a6af ../regression-tests/zones/secure-delegated.dnssec-parent.com
9aeed2c26d0c3ba3baf22dfa9568c451 ../regression-tests/zones/2.0.192.in-addr.arpa
99c73e8b5db5781fec1ac3fa6a2662a9 ../regression-tests/zones/cryptokeys.org
1f9e19be0cff67330f3a0a5347654f91 ../regression-tests/zones/hiddencryptokeys.org
-ab699fca1a52598202a1494cddd192ff ../modules/tinydnsbackend/data.cdb
+964425367cec0d828222b144c4e1c540 ../modules/tinydnsbackend/data
+f3932b1df41d683f47516455b571c358 ../modules/tinydnsbackend/data.cdb
nose>=1.3.7
protobuf>=2.5; sys_platform != 'darwin'
protobuf>=3.0; sys_platform == 'darwin'
+pyasn1==0.4.8
pysnmp>=4.3.4
requests>=2.1.0
Twisted>0.15.0
self.assertTrue(False)
+ def testNoEDE(self):
+ # This isn't an aggresive cache check, but the strcuture is very similar to the others,
+ # so letys place it here.
+ # It test the issue that an intermediate EDE does not get reported with the final answer
+ # https://github.com/PowerDNS/pdns/pull/12694
+ self.wipe()
+
+ res = self.sendQuery('host1.sub.secure.example.', 'TXT')
+ self.assertRcodeEqual(res, dns.rcode.NOERROR)
+ self.assertAnswerEmpty(res)
+ self.assertAuthorityHasSOA(res)
+ self.assertMessageIsAuthenticated(res)
+ self.assertEqual(res.edns, 0)
+ self.assertEqual(len(res.options), 0)
+
+ res = self.sendQuery('host1.sub.secure.example.', 'A')
+ self.assertRcodeEqual(res, dns.rcode.NOERROR)
+ self.assertMessageIsAuthenticated(res)
+ self.assertEqual(res.edns, 0)
+ self.assertEqual(len(res.options), 0)
+
def testNoData(self):
self.wipe()
self.assertEqual(res.edns, 0)
self.assertEqual(len(res.options), 1)
self.assertEqual(res.options[0].otype, 15)
- self.assertEqual(res.options[0], extendederrors.ExtendedErrorOption(0, b'Result synthesized from aggressive NSEC cache (RFC8198)'))
+ self.assertEqual(res.options[0], extendederrors.ExtendedErrorOption(29, b'Result synthesized from aggressive NSEC cache (RFC8198)'))
class AggressiveNSECCacheNSEC(AggressiveNSECCacheBase):
_confdir = 'AggressiveNSECCacheNSEC'
self.assertEqual(res.edns, 0)
self.assertEqual(len(res.options), 1)
self.assertEqual(res.options[0].otype, 15)
- self.assertEqual(res.options[0], extendederrors.ExtendedErrorOption(0, b'Result synthesized from aggressive NSEC cache (RFC8198)'))
+ self.assertEqual(res.options[0], extendederrors.ExtendedErrorOption(29, b'Result synthesized from aggressive NSEC cache (RFC8198)'))
def testWildcard(self):
self.wipe()
self.assertEqual(res.edns, 0)
self.assertEqual(len(res.options), 1)
self.assertEqual(res.options[0].otype, 15)
- self.assertEqual(res.options[0], extendederrors.ExtendedErrorOption(0, b'Result synthesized from aggressive NSEC cache (RFC8198)'))
+ self.assertEqual(res.options[0], extendederrors.ExtendedErrorOption(29, b'Result synthesized from aggressive NSEC cache (RFC8198)'))
# now we ask for a type that does not exist at the wildcard
hits = self.getMetric('aggressive-nsec-cache-nsec-hits')
self.assertEqual(res.edns, 0)
self.assertEqual(len(res.options), 1)
self.assertEqual(res.options[0].otype, 15)
- self.assertEqual(res.options[0], extendederrors.ExtendedErrorOption(0, b'Result synthesized from aggressive NSEC cache (RFC8198)'))
+ self.assertEqual(res.options[0], extendederrors.ExtendedErrorOption(29, b'Result synthesized from aggressive NSEC cache (RFC8198)'))
# we can also ask a different type, for a different name that is covered
# by the NSEC and matches the wildcard (but the type does not exist)
self.assertEqual(res.edns, 0)
self.assertEqual(len(res.options), 1)
self.assertEqual(res.options[0].otype, 15)
- self.assertEqual(res.options[0], extendederrors.ExtendedErrorOption(0, b'Result synthesized from aggressive NSEC cache (RFC8198)'))
+ self.assertEqual(res.options[0], extendederrors.ExtendedErrorOption(29, b'Result synthesized from aggressive NSEC cache (RFC8198)'))
def test_Bogus(self):
self.wipe()
self.assertEqual(res.edns, 0)
self.assertEqual(len(res.options), 1)
self.assertEqual(res.options[0].otype, 15)
- self.assertEqual(res.options[0], extendederrors.ExtendedErrorOption(0, b'Result synthesized from aggressive NSEC cache (RFC8198)'))
+ self.assertEqual(res.options[0], extendederrors.ExtendedErrorOption(29, b'Result synthesized from aggressive NSEC cache (RFC8198)'))
def testWildcard(self):
self.wipe()
self.assertEqual(res.edns, 0)
self.assertEqual(len(res.options), 1)
self.assertEqual(res.options[0].otype, 15)
- self.assertEqual(res.options[0], extendederrors.ExtendedErrorOption(0, b'Result synthesized from aggressive NSEC cache (RFC8198)'))
+ self.assertEqual(res.options[0], extendederrors.ExtendedErrorOption(29, b'Result synthesized from aggressive NSEC cache (RFC8198)'))
# now we ask for a type that does not exist at the wildcard
nbQueries = self.getMetric('all-outqueries')
self.assertEqual(res.edns, 0)
self.assertEqual(len(res.options), 1)
self.assertEqual(res.options[0].otype, 15)
- self.assertEqual(res.options[0], extendederrors.ExtendedErrorOption(0, b'Result synthesized from aggressive NSEC cache (RFC8198)'))
+ self.assertEqual(res.options[0], extendederrors.ExtendedErrorOption(29, b'Result synthesized from aggressive NSEC cache (RFC8198)'))
# we can also ask a different type, for a different name that is covered
# by the NSEC3s and matches the wildcard (but the type does not exist)
self.assertEqual(res.edns, 0)
self.assertEqual(len(res.options), 1)
self.assertEqual(res.options[0].otype, 15)
- self.assertEqual(res.options[0], extendederrors.ExtendedErrorOption(0, b'Result synthesized from aggressive NSEC cache (RFC8198)'))
+ self.assertEqual(res.options[0], extendederrors.ExtendedErrorOption(29, b'Result synthesized from aggressive NSEC cache (RFC8198)'))
def test_OptOut(self):
self.wipe()
_apiKey = 'secretapikey'
_config_template = """
packetcache-ttl=10
+ packetcache-negative-ttl=8
packetcache-servfail-ttl=5
auth-zones=example=configs/%s/example.zone
webserver=yes
super(PacketCacheRecursorTest, cls).generateRecursorConfig(confdir)
def checkPacketCacheMetrics(self, expectedHits, expectedMisses):
+ self.waitForTCPSocket("127.0.0.1", self._wsPort)
headers = {'x-api-key': self._apiKey}
url = 'http://127.0.0.1:' + str(self._wsPort) + '/api/v1/servers/localhost/statistics'
r = requests.get(url, headers=headers, timeout=self._wsTimeout)
self.assertRRsetInAnswer(res, expected)
self.checkPacketCacheMetrics(6, 4)
- # NXDomain should get default packetcache TTL (10)
+ # NXDomain should get negative packetcache TTL (8)
query = dns.message.make_query('nxdomain.example.', 'A', want_dnssec=True)
res = self.sendUDPQuery(query)
self.assertRcodeEqual(res, dns.rcode.NXDOMAIN)
self.checkPacketCacheMetrics(6, 5)
- # NoData should get default packetcache TTL (10)
+ # NoData should get negative packetcache TTL (8)
query = dns.message.make_query('a.example.', 'AAAA', want_dnssec=True)
res = self.sendUDPQuery(query)
self.assertRcodeEqual(res, dns.rcode.NOERROR)
try:
ret = subprocess.check_output(rec_controlCmd, stderr=subprocess.STDOUT)
self.assertTrue((b"a.example. 10 A ; tag 0 udp\n" in ret) or (b"a.example. 9 A ; tag 0 udp\n" in ret))
- self.assertTrue((b"nxdomain.example. 10 A ; tag 0 udp\n" in ret) or (b"nxdomain.example. 9 A ; tag 0 udp\n" in ret))
- self.assertTrue((b"a.example. 10 AAAA ; tag 0 udp\n" in ret) or (b"a.example. 9 AAAA ; tag 0 udp\n" in ret))
+ self.assertTrue((b"nxdomain.example. 8 A ; tag 0 udp\n" in ret) or (b"nxdomain.example. 7 A ; tag 0 udp\n" in ret))
+ self.assertTrue((b"a.example. 8 AAAA ; tag 0 udp\n" in ret) or (b"a.example. 7 AAAA ; tag 0 udp\n" in ret))
self.assertTrue((b"f.example. 5 A ; tag 0 udp\n" in ret) or (b"f.example. 4 A ; tag 0 udp\n" in ret))
except subprocess.CalledProcessError as e:
self.assertEqual(res.edns, 0)
self.assertEqual(len(res.options), 1)
self.assertEqual(res.options[0].otype, 15)
- self.assertEqual(res.options[0], extendederrors.ExtendedErrorOption(0, b'Result synthesized by root-nx-trust'))
+ self.assertEqual(res.options[0], extendederrors.ExtendedErrorOption(29, b'Result synthesized by root-nx-trust'))
<measurement><name>system CPU seconds</name><value>%S</value></measurement>
<measurement><name>wallclock seconds</name><value>%e</value></measurement>
<measurement><name>%% CPU used</name><value>%P</value></measurement>
-' ${RECURSOR} --daemon=no --local-port=$port --socket-dir=./ --trace=$TRACE --config-dir=. --max-mthreads=$mthreads --query-local-address="0.0.0.0${QLA6}" --threads=$threads --record-cache-shards=$shards --disable-packetcache --refresh-on-ttl-perc=10 --dnssec=validate > recursor.log 2>&1 &
+' ${RECURSOR} --daemon=no --local-port=$port --socket-dir=./ --trace=$TRACE --config-dir=. --max-mthreads=$mthreads --query-local-address="0.0.0.0${QLA6}" --threads=$threads --record-cache-shards=$shards --refresh-on-ttl-perc=10 --dnssec=validate --pdns-distributes-queries --reuseport=no > recursor.log 2>&1 &
sleep 3
if [ ! -e pdns_recursor.pid ]; then
cat recursor.log
*.out
start
step.*
+verify-dnssec-zone/allow-missing
+*.dnssec-parent.com. 3600 IN CNAME secure-delegated.dnssec-parent.com.
delegated.dnssec-parent.com. 3600 IN NS ns1.delegated.dnssec-parent.com.
delegated.dnssec-parent.com. 3600 IN NS ns2.delegated.dnssec-parent.com.
dnssec-parent.com. 3600 IN A 9.9.9.9
+*.dnssec-parent.com. 3600 IN CNAME secure-delegated.dnssec-parent.com.
+*.dnssec-parent.com. 3600 IN NSEC insecure-delegated.ent.ent.auth-ent.dnssec-parent.com. CNAME RRSIG NSEC
+*.dnssec-parent.com. 3600 IN RRSIG CNAME 13 2 3600 [expiry] [inception] [keytag] dnssec-parent.com. ...
+*.dnssec-parent.com. 3600 IN RRSIG NSEC 13 2 3600 [expiry] [inception] [keytag] dnssec-parent.com. ...
delegated.dnssec-parent.com. 3600 IN NS ns1.delegated.dnssec-parent.com.
delegated.dnssec-parent.com. 3600 IN NS ns2.delegated.dnssec-parent.com.
delegated.dnssec-parent.com. 3600 IN NSEC insecure.dnssec-parent.com. NS RRSIG NSEC
dnssec-parent.com. 3600 IN A 9.9.9.9
dnssec-parent.com. 3600 IN NS ns1.dnssec-parent.com.
dnssec-parent.com. 3600 IN NS ns2.dnssec-parent.com.
-dnssec-parent.com. 3600 IN NSEC insecure-delegated.ent.ent.auth-ent.dnssec-parent.com. A NS SOA RRSIG NSEC DNSKEY CDS CDNSKEY
+dnssec-parent.com. 3600 IN NSEC *.dnssec-parent.com. A NS SOA RRSIG NSEC DNSKEY CDS CDNSKEY
dnssec-parent.com. 3600 IN RRSIG A 13 2 3600 [expiry] [inception] [keytag] dnssec-parent.com. ...
dnssec-parent.com. 3600 IN RRSIG NS 13 2 3600 [expiry] [inception] [keytag] dnssec-parent.com. ...
dnssec-parent.com. 3600 IN RRSIG NSEC 13 2 3600 [expiry] [inception] [keytag] dnssec-parent.com. ...
+*.dnssec-parent.com. 3600 IN CNAME secure-delegated.dnssec-parent.com.
+*.dnssec-parent.com. 3600 IN NSEC3 1 0 1 abcd [next owner] CNAME RRSIG
+*.dnssec-parent.com. 3600 IN RRSIG CNAME 13 2 3600 [expiry] [inception] [keytag] dnssec-parent.com. ...
+*.dnssec-parent.com. 3600 IN RRSIG NSEC3 13 3 3600 [expiry] [inception] [keytag] dnssec-parent.com. ...
auth-ent.dnssec-parent.com. 3600 IN NSEC3 1 0 1 abcd [next owner]
auth-ent.dnssec-parent.com. 3600 IN RRSIG NSEC3 13 3 3600 [expiry] [inception] [keytag] dnssec-parent.com. ...
delegated.dnssec-parent.com. 3600 IN NS ns1.delegated.dnssec-parent.com.
+*.dnssec-parent.com. 3600 IN CNAME secure-delegated.dnssec-parent.com.
+*.dnssec-parent.com. 3600 IN NSEC3 1 1 1 abcd [next owner] CNAME RRSIG
+*.dnssec-parent.com. 3600 IN RRSIG CNAME 13 2 3600 [expiry] [inception] [keytag] dnssec-parent.com. ...
+*.dnssec-parent.com. 3600 IN RRSIG NSEC3 13 3 3600 [expiry] [inception] [keytag] dnssec-parent.com. ...
auth-ent.dnssec-parent.com. 3600 IN NSEC3 1 1 1 abcd [next owner]
auth-ent.dnssec-parent.com. 3600 IN RRSIG NSEC3 13 3 3600 [expiry] [inception] [keytag] dnssec-parent.com. ...
delegated.dnssec-parent.com. 3600 IN NS ns1.delegated.dnssec-parent.com.
1 7on3vems0f8k9999ikei0ig4lfijekdr.dnssec-parent.com. 3600 IN RRSIG NSEC3 13 3 3600 [expiry] [inception] [keytag] dnssec-parent.com. ...
1 dnssec-parent.com. 3600 IN RRSIG SOA 13 2 3600 [expiry] [inception] [keytag] dnssec-parent.com. ...
1 dnssec-parent.com. 3600 IN SOA ns1.dnssec-parent.com. ahu.example.com. 2005092501 28800 7200 604800 86400
-1 dvkuo8kja65gcsq600e6di9u719lsj8u.dnssec-parent.com. 3600 IN NSEC3 1 1 1 abcd NIH4L3ODLUG7EN20PENJ8DGNU4OHC98F A NS SOA RRSIG DNSKEY NSEC3PARAM CDS CDNSKEY
+1 dvkuo8kja65gcsq600e6di9u719lsj8u.dnssec-parent.com. 3600 IN NSEC3 1 1 1 abcd K25OPIULTRKGKRMR3UC09CSK20QHT1LJ A NS SOA RRSIG DNSKEY NSEC3PARAM CDS CDNSKEY
1 dvkuo8kja65gcsq600e6di9u719lsj8u.dnssec-parent.com. 3600 IN RRSIG NSEC3 13 3 3600 [expiry] [inception] [keytag] dnssec-parent.com. ...
2 . 32768 IN OPT
Rcode: 0 (No Error), RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0
-1 dnssec-parent.com. 3600 IN NSEC insecure-delegated.ent.ent.auth-ent.dnssec-parent.com. A NS SOA RRSIG NSEC DNSKEY CDS CDNSKEY
-1 dnssec-parent.com. 3600 IN RRSIG NSEC 13 2 3600 [expiry] [inception] [keytag] dnssec-parent.com. ...
+1 *.dnssec-parent.com. 3600 IN NSEC insecure-delegated.ent.ent.auth-ent.dnssec-parent.com. CNAME RRSIG NSEC
+1 *.dnssec-parent.com. 3600 IN RRSIG NSEC 13 2 3600 [expiry] [inception] [keytag] dnssec-parent.com. ...
1 dnssec-parent.com. 3600 IN RRSIG SOA 13 2 3600 [expiry] [inception] [keytag] dnssec-parent.com. ...
1 dnssec-parent.com. 3600 IN SOA ns1.dnssec-parent.com. ahu.example.com. 2005092501 28800 7200 604800 86400
2 . 32768 IN OPT
--- /dev/null
+#!/bin/sh
+cleandig secure-delegated1.dnssec-parent.com A dnssec
--- /dev/null
+Check that we generate the right NSECs when the NSEC name is a delegation point.
--- /dev/null
+0 secure-delegated.dnssec-parent.com. 3600 IN A 9.9.9.9
+0 secure-delegated.dnssec-parent.com. 3600 IN RRSIG A 8 3 3600 [expiry] [inception] [keytag] secure-delegated.dnssec-parent.com. ...
+0 secure-delegated1.dnssec-parent.com. 3600 IN CNAME secure-delegated.dnssec-parent.com.
+0 secure-delegated1.dnssec-parent.com. 3600 IN RRSIG CNAME 13 2 3600 [expiry] [inception] [keytag] dnssec-parent.com. ...
+1 secure-delegated.dnssec-parent.com. 3600 IN NSEC www.dnssec-parent.com. NS DS RRSIG NSEC
+1 secure-delegated.dnssec-parent.com. 3600 IN RRSIG NSEC 13 3 3600 [expiry] [inception] [keytag] dnssec-parent.com. ...
+2 . 32768 IN OPT
+Rcode: 0 (No Error), RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0
+Reply to question for qname='secure-delegated1.dnssec-parent.com.', qtype=A
--- /dev/null
+0 secure-delegated.dnssec-parent.com. 3600 IN A 9.9.9.9
+0 secure-delegated.dnssec-parent.com. 3600 IN RRSIG A 8 3 3600 [expiry] [inception] [keytag] secure-delegated.dnssec-parent.com. ...
+0 secure-delegated1.dnssec-parent.com. 3600 IN CNAME secure-delegated.dnssec-parent.com.
+0 secure-delegated1.dnssec-parent.com. 3600 IN RRSIG CNAME 13 2 3600 [expiry] [inception] [keytag] dnssec-parent.com. ...
+1 1an9kidorpirlabrh3be2n8k5taoe1v0.dnssec-parent.com. 3600 IN NSEC3 1 [flags] 1 abcd 1AN9KIDORPIRLABRH3BE2N8K5TAOE1V2
+1 1an9kidorpirlabrh3be2n8k5taoe1v0.dnssec-parent.com. 3600 IN RRSIG NSEC3 13 3 3600 [expiry] [inception] [keytag] dnssec-parent.com. ...
+2 . 32768 IN OPT
+Rcode: 0 (No Error), RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0
+Reply to question for qname='secure-delegated1.dnssec-parent.com.', qtype=A
--- /dev/null
+0 secure-delegated.dnssec-parent.com. 3600 IN A 9.9.9.9
+0 secure-delegated.dnssec-parent.com. 3600 IN RRSIG A 8 3 3600 [expiry] [inception] [keytag] secure-delegated.dnssec-parent.com. ...
+0 secure-delegated1.dnssec-parent.com. 3600 IN CNAME secure-delegated.dnssec-parent.com.
+0 secure-delegated1.dnssec-parent.com. 3600 IN RRSIG CNAME 13 2 3600 [expiry] [inception] [keytag] dnssec-parent.com. ...
+1 u97st412oa8b4bgjc1dgtb4qi5di8dmv.dnssec-parent.com. 3600 IN NSEC3 1 [flags] 1 abcd 1SCAQA30LQ0DO5EIRNE4KPJFBEBFGR54
+1 u97st412oa8b4bgjc1dgtb4qi5di8dmv.dnssec-parent.com. 3600 IN RRSIG NSEC3 13 3 3600 [expiry] [inception] [keytag] dnssec-parent.com. ...
+2 . 32768 IN OPT
+Rcode: 0 (No Error), RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0
+Reply to question for qname='secure-delegated1.dnssec-parent.com.', qtype=A
--- /dev/null
+0 secure-delegated.dnssec-parent.com. 3600 IN A 9.9.9.9
+0 secure-delegated.dnssec-parent.com. 3600 IN RRSIG A 8 3 3600 [expiry] [inception] [keytag] secure-delegated.dnssec-parent.com. ...
+0 secure-delegated1.dnssec-parent.com. 3600 IN CNAME secure-delegated.dnssec-parent.com.
+0 secure-delegated1.dnssec-parent.com. 3600 IN RRSIG CNAME 13 2 3600 [expiry] [inception] [keytag] dnssec-parent.com. ...
+1 qoqsriqrvi1g1ql3tpph2248q9ldpepf.dnssec-parent.com. 3600 IN NSEC3 1 [flags] 1 abcd 1SCAQA30LQ0DO5EIRNE4KPJFBEBFGR54 A RRSIG
+1 qoqsriqrvi1g1ql3tpph2248q9ldpepf.dnssec-parent.com. 3600 IN RRSIG NSEC3 13 3 3600 [expiry] [inception] [keytag] dnssec-parent.com. ...
+2 . 32768 IN OPT
+Rcode: 0 (No Error), RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0
+Reply to question for qname='secure-delegated1.dnssec-parent.com.', qtype=A
something1.auth-ent IN A 1.1.2.3
insecure IN NS ns.example.com.
www IN CNAME www.insecure
+* IN CNAME secure-delegated
'ruby-dev',
'sqlite3',
'unixodbc-dev',
+ 'cmake',
]
rec_build_deps = [
'libcap-dev',
c.run('git clone https://git.code.sf.net/p/ed448goldilocks/code /tmp/libdecaf')
with c.cd('/tmp/libdecaf'):
c.run('git checkout 41f349')
- c.run('cmake -B build '
+ c.run('CC=clang-12 CXX=clang-12 '
+ 'cmake -B build '
'-DCMAKE_INSTALL_PREFIX=/usr/local '
'-DCMAKE_INSTALL_LIBDIR=lib '
'-DENABLE_STATIC=OFF '
@task
def ci_docs_upload_master(c, docs_host, pdf, username, product, directory=""):
- c.run(f"rsync -crv --delete --no-p --chmod=g=rwX --exclude '*~' ./docs/_build/{product}-html-docs/ {username}@{docs_host}:{directory}")
- c.run(f"rsync -crv --no-p --chmod=g=rwX --exclude '*~' ./docs/_build/{product}-html-docs.tar.bz2 {username}@{docs_host}:{directory}/html-docs.tar.bz2")
- c.run(f"rsync -crv --no-p --chmod=g=rwX --exclude '*~' ./docs/_build/latex/{pdf} {username}@{docs_host}:{directory}")
+ rsync_cmd = " ".join([
+ "rsync",
+ "--checksum",
+ "--recursive",
+ "--verbose",
+ "--no-p",
+ "--chmod=g=rwX",
+ "--exclude '*~'",
+ ])
+ c.run(f"{rsync_cmd} --delete ./docs/_build/{product}-html-docs/ {username}@{docs_host}:{directory}")
+ c.run(f"{rsync_cmd} ./docs/_build/{product}-html-docs.tar.bz2 {username}@{docs_host}:{directory}/html-docs.tar.bz2")
+ c.run(f"{rsync_cmd} ./docs/_build/latex/{pdf} {username}@{docs_host}:{directory}")
@task
def ci_docs_add_ssh(c, ssh_key, host_key):
c.run('chmod 600 ~/.ssh/id_ed25519')
c.run(f'echo "{host_key}" > ~/.ssh/known_hosts')
+
+def get_sanitizers():
+ sanitizers = os.getenv('SANITIZERS')
+ if sanitizers != '':
+ sanitizers = sanitizers.split('+')
+ sanitizers = ['--enable-' + sanitizer for sanitizer in sanitizers]
+ sanitizers = ' '.join(sanitizers)
+ return sanitizers
+
+
+def get_cflags():
+ return " ".join([
+ "-O1",
+ "-Werror=vla",
+ "-Werror=shadow",
+ "-Wformat=2",
+ "-Werror=format-security",
+ "-Werror=string-plus-int",
+ ])
+
+
+def get_cxxflags():
+ return " ".join([
+ get_cflags(),
+ "-Wp,-D_GLIBCXX_ASSERTIONS",
+ ])
+
+
+def get_base_configure_cmd():
+ return " ".join([
+ f'CFLAGS="{get_cflags()}"',
+ f'CXXFLAGS="{get_cxxflags()}"',
+ './configure',
+ "CC='clang-12'",
+ "CXX='clang++-12'",
+ "--enable-option-checking=fatal",
+ "--enable-systemd",
+ "--with-libsodium",
+ "--enable-fortify-source=auto",
+ "--enable-auto-var-init=pattern",
+ ])
+
+
@task
def ci_auth_configure(c):
- sanitizers = ' '.join('--enable-'+x for x in os.getenv('SANITIZERS').split('+')) if os.getenv('SANITIZERS') != '' else ''
- unittests = ' --enable-unit-tests --enable-backend-unit-tests' if os.getenv('UNIT_TESTS') == 'yes' else ''
- fuzzingtargets = ' --enable-fuzz-targets' if os.getenv('FUZZING_TARGETS') == 'yes' else ''
- res = c.run('''CFLAGS="-O1 -Werror=vla -Werror=shadow -Wformat=2 -Werror=format-security -Werror=string-plus-int" \
- CXXFLAGS="-O1 -Werror=vla -Werror=shadow -Wformat=2 -Werror=format-security -Werror=string-plus-int -Wp,-D_GLIBCXX_ASSERTIONS" \
- ./configure \
- CC='clang-12' \
- CXX='clang++-12' \
- LDFLAGS='-L/usr/local/lib -Wl,-rpath,/usr/local/lib' \
- --enable-option-checking=fatal \
- --with-modules='bind geoip gmysql godbc gpgsql gsqlite3 ldap lmdb lua2 pipe remote tinydns' \
- --enable-systemd \
- --enable-tools \
- --enable-fuzz-targets \
- --enable-experimental-pkcs11 \
- --enable-experimental-gss-tsig \
- --enable-remotebackend-zeromq \
- --with-lmdb=/usr \
- --with-libsodium \
- --with-libdecaf \
- --prefix=/opt/pdns-auth \
- --enable-ixfrdist \
- --enable-fortify-source=auto \
- --enable-auto-var-init=pattern ''' + sanitizers + unittests + fuzzingtargets, warn=True)
+ sanitizers = get_sanitizers()
+
+ unittests = os.getenv('UNIT_TESTS')
+ if unittests == 'yes':
+ unittests = '--enable-unit-tests --enable-backend-unit-tests'
+ else:
+ unittests = ''
+
+ fuzz_targets = os.getenv('FUZZING_TARGETS')
+ fuzz_targets = '--enable-fuzz-targets' if fuzz_targets == 'yes' else ''
+
+ modules = " ".join([
+ "bind",
+ "geoip",
+ "gmysql",
+ "godbc",
+ "gpgsql",
+ "gsqlite3",
+ "ldap",
+ "lmdb",
+ "lua2",
+ "pipe",
+ "remote",
+ "tinydns",
+ ])
+ configure_cmd = " ".join([
+ get_base_configure_cmd(),
+ "LDFLAGS='-L/usr/local/lib -Wl,-rpath,/usr/local/lib'",
+ f"--with-modules='{modules}'",
+ "--enable-tools",
+ "--enable-experimental-pkcs11",
+ "--enable-experimental-gss-tsig",
+ "--enable-remotebackend-zeromq",
+ "--with-lmdb=/usr",
+ "--with-libdecaf",
+ "--prefix=/opt/pdns-auth",
+ "--enable-ixfrdist",
+ sanitizers,
+ unittests,
+ fuzz_targets,
+ ])
+ res = c.run(configure_cmd, warn=True)
if res.exited != 0:
c.run('cat config.log')
raise UnexpectedExit(res)
+
+
@task
def ci_rec_configure(c):
- sanitizers = ' '.join('--enable-'+x for x in os.getenv('SANITIZERS').split('+')) if os.getenv('SANITIZERS') != '' else ''
- unittests = ' --enable-unit-tests' if os.getenv('UNIT_TESTS') == 'yes' else ''
- res = c.run(''' CFLAGS="-O1 -Werror=vla -Werror=shadow -Wformat=2 -Werror=format-security -Werror=string-plus-int" \
- CXXFLAGS="-O1 -Werror=vla -Werror=shadow -Wformat=2 -Werror=format-security -Werror=string-plus-int -Wp,-D_GLIBCXX_ASSERTIONS" \
- ./configure \
- CC='clang-12' \
- CXX='clang++-12' \
- --enable-option-checking=fatal \
- --enable-nod \
- --enable-systemd \
- --prefix=/opt/pdns-recursor \
- --with-libsodium \
- --with-lua=luajit \
- --with-libcap \
- --with-net-snmp \
- --enable-fortify-source=auto \
- --enable-auto-var-init=pattern \
- --enable-dns-over-tls ''' + sanitizers + unittests, warn=True)
+ sanitizers = get_sanitizers()
+
+ unittests = os.getenv('UNIT_TESTS')
+ unittests = '--enable-unit-tests' if unittests == 'yes' else ''
+
+ configure_cmd = " ".join([
+ get_base_configure_cmd(),
+ "--enable-nod",
+ "--prefix=/opt/pdns-recursor",
+ "--with-lua=luajit",
+ "--with-libcap",
+ "--with-net-snmp",
+ "--enable-dns-over-tls",
+ sanitizers,
+ unittests,
+ ])
+ res = c.run(configure_cmd, warn=True)
if res.exited != 0:
c.run('cat config.log')
raise UnexpectedExit(res)
+
@task
def ci_dnsdist_configure(c, features):
additional_flags = ''