]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Merge pull request #12698 from omoerbeek/rec-synthesized
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Mon, 3 Apr 2023 11:10:46 +0000 (13:10 +0200)
committerGitHub <noreply@github.com>
Mon, 3 Apr 2023 11:10:46 +0000 (13:10 +0200)
rec: Start using newly assigned "Synthesized" EDE

52 files changed:
.github/actions/spell-check/expect.txt
SECURITY.md
builder-support/debian/recursor/debian-buster/README.source [deleted file]
builder-support/debian/recursor/debian-buster/configure-helpers/net-snmp-config [new file with mode: 0755]
builder-support/debian/recursor/debian-buster/control
builder-support/debian/recursor/debian-buster/copyright
builder-support/debian/recursor/debian-buster/pdns-recursor.default [deleted file]
builder-support/debian/recursor/debian-buster/pdns-recursor.init [deleted file]
builder-support/debian/recursor/debian-buster/pdns-recursor.lintian-overrides
builder-support/debian/recursor/debian-buster/pdns-recursor.postinst
builder-support/debian/recursor/debian-buster/pdns-recursor.preinst [new file with mode: 0644]
builder-support/debian/recursor/debian-buster/pdns-recursor.prerm [deleted file]
builder-support/debian/recursor/debian-buster/rules
builder-support/debian/recursor/debian-buster/source.lintian-overrides [deleted file]
builder-support/debian/recursor/debian-buster/tests/control
builder-support/debian/recursor/debian-buster/tests/smoke
docs/common/security-policy.rst
docs/secpoll.zone
modules/gmysqlbackend/smysql.cc
modules/gpgsqlbackend/spgsql.cc
modules/lmdbbackend/lmdbbackend.cc
pdns/dnsbulktest.cc
pdns/dnsdist-carbon.cc
pdns/dnsdist-lua-actions.cc
pdns/dnsdist-lua-inspection.cc
pdns/dnsdist-lua-rules.cc
pdns/dnsdist-tcp.cc
pdns/dnsdist.cc
pdns/dnsdistdist/docs/changelog.rst
pdns/dnsdistdist/docs/eol.rst
pdns/dnsdistdist/doh.cc
pdns/dnsreplay.cc
pdns/dnsscope.cc
pdns/dnssecinfra.cc
pdns/dnstcpbench.cc
pdns/pdnsutil.cc
pdns/recursordist/docs/changelog/4.6.rst
pdns/recursordist/docs/changelog/4.7.rst
pdns/recursordist/docs/changelog/4.8.rst
pdns/recursordist/docs/performance.rst
pdns/recursordist/docs/security-advisories/powerdns-advisory-2023-02.rst [new file with mode: 0644]
pdns/recursordist/pdns_recursor.cc
pdns/recursordist/reczones-helpers.cc
pdns/recursordist/reczones-helpers.hh
pdns/recursordist/reczones.cc
pdns/recursordist/root-addresses.hh
pdns/recursordist/syncres.cc
pdns/recursordist/test-reczones-helpers.cc
pdns/recursordist/test-syncres_cc.cc
pdns/speedtest.cc
pdns/ssqlite3.cc
pdns/tools/rrd/makegraphs

index 27c23e81a150a471ba47c89e20a0119a1d0e3b1a..a9008ccf60a522b6b56ff753006e58a0fb033df4 100644 (file)
@@ -792,7 +792,6 @@ mbytes
 Meerwald
 Mekking
 memlock
-MEMLOCK
 Memusage
 menuselection
 metadatabase
@@ -1429,6 +1428,7 @@ tsigalgo
 tsigkey
 tsigname
 tsigsecret
+Tsinghua
 tstamp
 TSU
 ttls
@@ -1551,12 +1551,14 @@ xdp
 Xek
 Xeon
 XForwarded
+Xiang
 xorbooter
 xpf
 XRecord
 XXXXXX
 yahttp
 Yehuda
+yeswehack
 Yiu
 Ylitalo
 yml
index 07038efceb4a69e3ed8d9be1d804b1217ea2a087..50bc7f99cdcdbe26a1c965bb779e6cc3bf7fcf08 100644 (file)
@@ -13,7 +13,7 @@ This license is included in this documentation.
 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
 -----------------
diff --git a/builder-support/debian/recursor/debian-buster/README.source b/builder-support/debian/recursor/debian-buster/README.source
deleted file mode 100644 (file)
index cf42723..0000000
+++ /dev/null
@@ -1 +0,0 @@
-See /usr/share/doc/quilt/README.source
diff --git a/builder-support/debian/recursor/debian-buster/configure-helpers/net-snmp-config b/builder-support/debian/recursor/debian-buster/configure-helpers/net-snmp-config
new file mode 100755 (executable)
index 0000000..6d8d6e7
--- /dev/null
@@ -0,0 +1,21 @@
+#!/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
index b5216671c5744d099251d675db336f4c293e3a7f..c9325fc95e2b313adc6a72df5fbfaaedf849072d 100644 (file)
@@ -1,29 +1,36 @@
 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-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},
index 8aba47378c53e7f8d974e782879268ab4e2612d9..b8e649b70869dfcf09bf228ff3a63a2c908b3358 100644 (file)
@@ -1,6 +1,7 @@
 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
@@ -30,8 +31,8 @@ Files: debian/*
 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/*
diff --git a/builder-support/debian/recursor/debian-buster/pdns-recursor.default b/builder-support/debian/recursor/debian-buster/pdns-recursor.default
deleted file mode 100644 (file)
index db03e54..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-# 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
diff --git a/builder-support/debian/recursor/debian-buster/pdns-recursor.init b/builder-support/debian/recursor/debian-buster/pdns-recursor.init
deleted file mode 100644 (file)
index 8b0f44e..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-#!/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
-
index b7f625e555c60fbcc526e88695b46c9255cd2efb..d6aeec23c146125f613c10a9d4bcd47ccb56ef30 100644 (file)
@@ -1,4 +1,2 @@
 # 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
index 4e1da7099252129ed5d1b5683cd92ee006ce0983..5f83e9d07f37b945ac04413ec984f06a85ef614c 100644 (file)
@@ -3,17 +3,8 @@ set -e
 
 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
   ;;
 
   *)
@@ -22,11 +13,6 @@ case "$1" in
   ;;
 esac
 
-# Startup errors should never cause dpkg to fail.
-initscript_error() {
-    return 0
-}
-
 #DEBHELPER#
 
 exit 0
diff --git a/builder-support/debian/recursor/debian-buster/pdns-recursor.preinst b/builder-support/debian/recursor/debian-buster/pdns-recursor.preinst
new file mode 100644 (file)
index 0000000..691107c
--- /dev/null
@@ -0,0 +1,30 @@
+#!/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#
diff --git a/builder-support/debian/recursor/debian-buster/pdns-recursor.prerm b/builder-support/debian/recursor/debian-buster/pdns-recursor.prerm
deleted file mode 100644 (file)
index e78608c..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/sh
-set -e
-
-# Startup errors should never cause dpkg to fail.
-initscript_error() {
-    return 0
-}
-
-#DEBHELPER#
-
-exit 0
index 651c627974949195884d401d7333917b6f0257c2..c393dcb0c01dc68a17ec43d8b53b3b77f785b7a3 100755 (executable)
@@ -1,80 +1,59 @@
 #!/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 \
-               --with-libcap \
-               --with-libsodium \
-               --enable-dns-over-tls \
-               --enable-dnstap \
-               --with-net-snmp \
                --disable-silent-rules \
                --with-service-user=pdns \
                --with-service-group=pdns \
-               $(CONFIGURE_ARGS)
+               --with-libcap \
+               --with-libsodium \
+               --with-lua \
+               --with-net-snmp \
+               --enable-dns-over-tls \
+               --enable-dnstap
 
 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
-
-override_dh_builddeb:
-       dh_builddeb -- -Zgzip
diff --git a/builder-support/debian/recursor/debian-buster/source.lintian-overrides b/builder-support/debian/recursor/debian-buster/source.lintian-overrides
deleted file mode 100644 (file)
index 700fed0..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-# Source is in html/js/d3.js
-pdns-recursor source: source-is-missing html/js/d3.v3.js line length is 32005 characters (>512)
index a0a6fc4a76c1ea62ba6307c592d73033dbbc8af7..bf44d57917264cb38729f55e05571137de3ab19c 100644 (file)
@@ -1,3 +1,4 @@
 Tests: smoke
-Depends: @, dnsutils
+Depends: dnsutils,
+         @
 Restrictions: needs-root
index 797073364207a42caa696d420dcf2ecc78055f51..23f78fefe0fb05d55ee145c16e9cf7f4546db07d 100755 (executable)
@@ -2,6 +2,12 @@
 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
@@ -12,11 +18,11 @@ example.org.           172800  IN      NS      ns1.example.org.
 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
 
index 3f457a9f4433cd5ca9fd54024d9aef1d2c72e26e..d400225b22d8f36acf6adbab7bb4e4fb7fca5914 100644 (file)
@@ -12,10 +12,10 @@ This :doc:`license <../common/license>`  is included in this documentation.
 
 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
 ^^^^^^^^^^^^^^^^^
index 9e20c1bc90f068c90f3cb2090736ce4c2415a321..9c2b988f2a5605ee115d6dd04e23bbc4deb05546 100644 (file)
@@ -1,4 +1,4 @@
-@       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. 2023033001 10800 3600 604800 10800
 @       3600    IN  NS  pdns-public-ns1.powerdns.com.
 @       3600    IN  NS  pdns-public-ns2.powerdns.com.
 
@@ -324,25 +324,28 @@ recursor-4.6.0-rc1.security-status                      60 IN TXT "3 Unsupported
 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 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/"
@@ -496,4 +499,5 @@ dnsdist-1.7.2.security-status                              60 IN TXT "1 OK"
 dnsdist-1.7.3.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"
index db8e6c2f3215305d08f9f935ac6cb56bae363e65..04518bb5ce340d6a63a9d5ba1453865cbdaa959f 100644 (file)
@@ -262,7 +262,7 @@ public:
     }
 
     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;
   }
@@ -270,7 +270,7 @@ public:
   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;
   }
index 9b19b0ce2a7eb4b3246742d27d80298787779ea5..f373c8adf75ef533e5684b4230d44b9a60df73da 100644 (file)
@@ -112,7 +112,7 @@ public:
     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();
@@ -143,7 +143,7 @@ public:
   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;
index 3e1b35a87cb46177ad615e2d5b8588ea9d9aa6ed..c9a47a613a62466239fbf35e2394074f41872c2d 100644 (file)
@@ -1425,13 +1425,13 @@ void LMDBBackend::lookup(const QType& type, const DNSName& qdomain, int zoneId,
   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;
index 7918199caa9dec58e576a3d49de5291beb9cebca..0cba797fa230ef5fe90647c87a9456c8c68985f8 100644 (file)
@@ -188,9 +188,9 @@ struct SendReceive
   {
     (*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();
       }
@@ -351,9 +351,9 @@ try
   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]);
index 74514ab963a0c2b375b612731e2c48857b32daf5..90cdd5acbc8d2ede802cb4aaa7b1cc649295035b 100644 (file)
@@ -282,7 +282,7 @@ static void carbonHandler(Carbon::Endpoint&& endpoint)
           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;
       }
index acbada4e14d7096bd2ebf7c4a3a0067e82922583..905cf3d08f9d84271eef715607d5717e27b562a1 100644 (file)
@@ -118,7 +118,7 @@ public:
   }
   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;
@@ -1755,7 +1755,7 @@ public:
   }
   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;
index 3e5dcd096a77a41e5c5f7665f4f368ac96827aee..f427e2cf2ec46977e2fa528b3f348461e6b8e877 100644 (file)
@@ -633,14 +633,14 @@ void setupLuaInspection(LuaContext& luaCtx)
         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);
index 47639365d9caca4d660d14d7349c1e210ed5131f..ba8f465d23572e22eb16d79978f6df8de1c985ad 100644 (file)
@@ -468,7 +468,7 @@ void setupLuaRules(LuaContext& luaCtx)
         }
       }
       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();
 
     });
 
index b927cbe86dab7496a3f6e354b7349ac7a5b5d727..a5af69e2ced7d1f7caa7989f20fdb487a431b21c 100644 (file)
@@ -241,7 +241,7 @@ static void handleResponseSent(std::shared_ptr<IncomingTCPConnectionState>& stat
   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) {
index 36d279e043e1dba523012e4b17767bc4cb480eba..06aa910ab68f91e832c0853007591d388951f93b 100644 (file)
@@ -696,10 +696,10 @@ static void handleResponseForUDPClient(InternalQueryState& ids, PacketBuffer& re
   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);
index 953b9b8c6c5951b132614c60194668d5d74e030d..33a21b31bd4ec30bf015326b6ed37b031f3ddbb8 100644 (file)
@@ -1,6 +1,28 @@
 Changelog
 =========
 
+.. 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
index 259417be177551c377e9f3d002636eff19df2b21..781d0ef529702ac3b1adb29b89d87eaa2cff8317 100644 (file)
@@ -8,18 +8,22 @@ End of life statements
      - 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
index 8481193d877b901a4c32dbbd63528a154b3b93f8..021eec32d2d00d022753a7ed596933da601dc4ca 100644 (file)
@@ -486,7 +486,7 @@ public:
 
     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) {
@@ -1735,7 +1735,7 @@ void handleUDPResponseForDoH(DOHUnitUniquePtr&& du, PacketBuffer&& udpResponse,
 
     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);
 
index b713ce003e4940dd240d3f127e793f349edeef2b..588ca66026166e2f91dd439da3f53fb9705f2dbe 100644 (file)
@@ -306,9 +306,9 @@ static void emitFlightTimes()
   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;
index 10dc10acc01196babe0dc410b92df5081164e866..06c45dd4e22a7fc63b120f073d09c2c5d417e9d1 100644 (file)
@@ -478,9 +478,9 @@ try
 
         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;
@@ -494,9 +494,9 @@ try
     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;
@@ -507,7 +507,7 @@ try
 
   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());
index f1ed8b91eb323213dcde1947425a226df02471c1..5a8e3cd96fcb9618a8f595c5de4869ca0b1c53b4 100644 (file)
@@ -375,7 +375,7 @@ void DNSCryptoKeyEngine::testMakers(unsigned int algo, maker_t* creator, maker_t
 
   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");
index 51f1e8b3cefd2f2854dbe059b01f582f898f4659..b35ebc7a9607a3a63f9ef826c343b5fc43ac0e18 100644 (file)
@@ -247,7 +247,7 @@ try
   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;
   }
 
@@ -305,8 +305,8 @@ try
   }
 
   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;
index 6ccd24100e3eb9e2a325cd14d107757d5473e8a7..89cf2f638e79d8bf65b636ec96fcd98f2e490732 100644 (file)
@@ -3179,7 +3179,7 @@ try
   }
   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) == ".")
index cd433237a1b1005a7d5b1c57eb2138b2793fb610..4372face88d1af319212631323b974b0b3df1576 100644 (file)
@@ -1,6 +1,16 @@
 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
index 9a605e7ad4bc1f3d100ab5d93a49e43917181aa8..f30e8f1568186b0fd0f1f0849be07c47415f6302 100644 (file)
@@ -1,6 +1,16 @@
 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
index 1bbf0623bf8160a8958faa9f6ff5b6ef79334b3a..888633f8d4068b7acf840345190376689db549ba 100644 (file)
@@ -1,6 +1,16 @@
 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
index 6e5d24616181c8095292ab26dc1fa35651ccac6a..ffa66b9f7b4495e372729a04acfc8f2a51a3f88b 100644 (file)
@@ -74,6 +74,7 @@ For high load operation (thousands of queries/second), It is advised to either t
 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
@@ -84,6 +85,7 @@ Sample Linux command lines would be::
     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
@@ -97,6 +99,7 @@ When using FirewallD (Centos 7+ / Red Hat 7+ / Fedora 21+), connection tracking
 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
@@ -107,6 +110,7 @@ The settings can be made permanent by using the ``--permanent`` flag::
     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
diff --git a/pdns/recursordist/docs/security-advisories/powerdns-advisory-2023-02.rst b/pdns/recursordist/docs/security-advisories/powerdns-advisory-2023-02.rst
new file mode 100644 (file)
index 0000000..f2c4dcc
--- /dev/null
@@ -0,0 +1,28 @@
+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.
+
+
index a09b371961b46d9deefe01898bbcf033df7d32fe..1c6ddf5ff26900138bff93188e3a703945ca1f9c 100644 (file)
@@ -2750,35 +2750,40 @@ static void doResends(MT_t::waiters_t::iterator& iter, const std::shared_ptr<Pac
 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));
@@ -2800,10 +2805,18 @@ static void handleUDPServerResponse(int fd, FDMultiplexer::funcparam_t& var)
   }
   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)));
@@ -2811,14 +2824,16 @@ static void handleUDPServerResponse(int fd, FDMultiplexer::funcparam_t& var)
     }
   }
 
-  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
index 41a36dc7f0214cf49655fba999b1af9a18530bf0..721a8d2e7db42f44259556470773a6d4372cae06 100644 (file)
 #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)
index e68fed2ec08a8f6ddb09bd8c39a44fe863cbdef3..dafeee4daf9f93e91412dd20563613710fa90147 100644 (file)
@@ -32,6 +32,9 @@
 #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);
index 62aaf25d62d428bf7e04d408364b0e787259e016..ba658b19c2be49bded83a19cda84c2a88632dc76 100644 (file)
 #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)
index 3455b9bcfea82a44309dce184adc210e6e753694..e766fd9490ada18d5ce4057b19dc635d67746f83 100644 (file)
  */
 #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.
@@ -36,9 +39,8 @@ static const char* const rootIps4[] = {
   "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.
@@ -53,4 +55,3 @@ static const char* const rootIps6[] = {
   "2001:500:9f::42", // l.root-servers.net.
   "2001:dc3::35" // m.root-servers.net.
 };
-static size_t const rootIps6Count = sizeof(rootIps6) / sizeof(*rootIps6);
index 039b8ecfd3c454ce58fbdfaa9ca935cfb6f68f52..f26c6fc5937b0beb0e99a4ec4eafcbdd9be0b40c 100644 (file)
@@ -5135,7 +5135,7 @@ bool SyncRes::doResolveAtThisIP(const std::string& prefix, const DNSName& qname,
     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) {
@@ -5183,6 +5183,12 @@ bool SyncRes::doResolveAtThisIP(const std::string& prefix, const DNSName& qname,
   }
 
   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));
 
@@ -5197,7 +5203,7 @@ bool SyncRes::doResolveAtThisIP(const std::string& prefix, const DNSName& qname,
     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)++;
 
@@ -5214,9 +5220,6 @@ bool SyncRes::doResolveAtThisIP(const std::string& prefix, const DNSName& qname,
       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)++;
@@ -5688,7 +5691,7 @@ int SyncRes::doResolveAt(NsSet& nameservers, DNSName auth, bool flawedNSSet, con
               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);
 
index 4a7aa30e78d0b34930678e9ce7bfc370d282412c..921c7d1f11c4e016f2921d306362e4caa155df04 100644 (file)
@@ -258,4 +258,48 @@ BOOST_FIXTURE_TEST_CASE(test_loading_etc_hosts, Fixture)
   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()
index 52b773c7658d160c498609a87c873e98bdbc6aae..ae574ebe0383930fbf7398c6b2822cdf136e8d4c 100644 (file)
@@ -101,7 +101,7 @@ bool primeHints(time_t now)
     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;
@@ -273,14 +273,14 @@ void addRecordToLW(LWResult* res, const std::string& name, uint16_t type, const
 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;
       }
index d4c6a3c638a7de4864e530138a4d50215f0cbf50..9c7b5264a1339556e5c702e17cf325913687f7e1 100644 (file)
@@ -53,7 +53,7 @@ template<typename C> void doRun(const C& cmd, int mseconds=100)
     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;
index c2c96ebea7b8bc23700726e832c099c21cf28d3c..85efc190659e1c07d7e07b0bca84bf3f1022efd0 100644 (file)
@@ -97,12 +97,12 @@ public:
       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;
   }
index a0f66998c2e1ee0af69634e650c51e728c6ef6d7..62dfbf6787a38f1c814df6e23fa9474fbd5342bb 100755 (executable)
@@ -78,8 +78,8 @@ function makeGraphs()
         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"