aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--share/security/advisories/FreeBSD-EN-20:13.bhyve.asc143
-rw-r--r--share/security/advisories/FreeBSD-EN-20:14.linuxkpi.asc131
-rw-r--r--share/security/advisories/FreeBSD-EN-20:15.mps.asc129
-rw-r--r--share/security/advisories/FreeBSD-SA-20:18.posix_spawnp.asc138
-rw-r--r--share/security/advisories/FreeBSD-SA-20:19.unbound.asc143
-rw-r--r--share/security/advisories/FreeBSD-SA-20:20.ipv6.asc131
-rw-r--r--share/security/patches/EN-20:13/bhyve.patch342
-rw-r--r--share/security/patches/EN-20:13/bhyve.patch.asc18
-rw-r--r--share/security/patches/EN-20:14/linuxkpi.patch12
-rw-r--r--share/security/patches/EN-20:14/linuxkpi.patch.asc18
-rw-r--r--share/security/patches/EN-20:15/mps.patch18
-rw-r--r--share/security/patches/EN-20:15/mps.patch.asc18
-rw-r--r--share/security/patches/SA-20:18/posix_spawnp.patch280
-rw-r--r--share/security/patches/SA-20:18/posix_spawnp.patch.asc18
-rw-r--r--share/security/patches/SA-20:19/unbound.11.3.patch85204
-rw-r--r--share/security/patches/SA-20:19/unbound.11.3.patch.asc18
-rw-r--r--share/security/patches/SA-20:19/unbound.11.4.patch12707
-rw-r--r--share/security/patches/SA-20:19/unbound.11.4.patch.asc18
-rw-r--r--share/security/patches/SA-20:19/unbound.12.1.patch29237
-rw-r--r--share/security/patches/SA-20:19/unbound.12.1.patch.asc18
-rw-r--r--share/security/patches/SA-20:20/ipv6.patch27
-rw-r--r--share/security/patches/SA-20:20/ipv6.patch.asc18
-rw-r--r--share/xml/advisories.xml21
-rw-r--r--share/xml/notices.xml21
24 files changed, 128828 insertions, 0 deletions
diff --git a/share/security/advisories/FreeBSD-EN-20:13.bhyve.asc b/share/security/advisories/FreeBSD-EN-20:13.bhyve.asc
new file mode 100644
index 0000000000..9efccfd020
--- /dev/null
+++ b/share/security/advisories/FreeBSD-EN-20:13.bhyve.asc
@@ -0,0 +1,143 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA512
+
+=============================================================================
+FreeBSD-EN-20:13.bhyve Errata Notice
+ The FreeBSD Project
+
+Topic: Host crash in bhyve with PCI device passthrough
+
+Category: core
+Module: bhyve
+Announced: 2020-07-08
+Credits: Peter Grehan
+Affects: FreeBSD 12.1
+Corrected: 2020-06-01 05:14:01 UTC (stable/12, 12.1-STABLE)
+ 2020-07-08 19:56:34 UTC (releng/12.1, 12.1-RELEASE-p7)
+
+For general information regarding FreeBSD Errata Notices and Security
+Advisories, including descriptions of the fields above, security
+branches, and the following sections, please visit
+<URL:https://security.FreeBSD.org/>.
+
+I. Background
+
+bhyve(8) is a hypervisor that supports running a variety of guest operating
+systems in virtual machines. bhyve(8) includes support for PCI devices
+passthrough (a technique to pass host PCI devices to a virtual machine for its
+exclusive control and use).
+
+II. Problem Description
+
+When an attempt is made to pass through a PCI device to a bhyve(8) VM (causing
+initialization of IOMMU) on certain Intel chipsets using VT-d the PCI bus
+stops working entirely resulting in a host crash. This issue occurs at least
+on the Intel Skylake series processors and those released later.
+
+A device passed through to a guest VM running OpenBSD at least since version
+6.4 on both AMD and Intel processors may not fully work in the guest. OpenBSD
+issues 4-byte PCI configuration-space register reads and writes to consecutive
+2-byte fields, which were not handled correctly by bhyve(8).
+
+III. Impact
+
+These issues prevent using bhyve in production with some combinations of host
+hardware and/or guest operating system.
+
+IV. Workaround
+
+No workaround is available. Systems not using bhyve(8) for virtualization
+with PCI passthrough are not affected.
+
+V. Solution
+
+Upgrade your system to a supported FreeBSD stable or release / security
+branch (releng) dated after the correction date and reboot.
+
+Perform one of the following:
+
+1) To update your system via a binary patch:
+
+Systems running a RELEASE version of FreeBSD on the i386 or amd64
+platforms can be updated via the freebsd-update(8) utility:
+
+# freebsd-update fetch
+# freebsd-update install
+# shutdown -r +10min "Rebooting for errata update"
+
+The first problem requires a reboot as the affected part is the kernel.
+
+The second problem does not require a reboot as the affected part is the
+bhyve userland executable.
+
+2) To update your system via a source code patch:
+
+The following patches have been verified to apply to the applicable
+FreeBSD release branches.
+
+a) Download the relevant patch from the location below, and verify the
+detached PGP signature using your PGP utility.
+
+# fetch https://security.FreeBSD.org/patches/EN-20:13/bhyve.patch
+# fetch https://security.FreeBSD.org/patches/EN-20:13/bhyve.patch.asc
+# gpg --verify bhyve.patch.asc
+
+b) Apply the patch. Execute the following commands as root:
+
+# cd /usr/src
+# patch < /path/to/patch
+
+c) Recompile the operating system using buildworld and installworld as
+described in <URL:https://www.FreeBSD.org/handbook/makeworld.html>.
+
+d) Recompile your kernel as described in
+<URL:https://www.FreeBSD.org/handbook/kernelconfig.html> and reboot the
+system.
+
+VI. Correction details
+
+The following list contains the correction revision numbers for each
+affected branch.
+
+Branch/path Revision
+- -------------------------------------------------------------------------
+stable/12/ r361686
+releng/12.1/ r363022
+- -------------------------------------------------------------------------
+
+To see which files were modified by a particular revision, run the
+following command, replacing NNNNNN with the revision number, on a
+machine with Subversion installed:
+
+# svn diff -cNNNNNN --summarize svn://svn.freebsd.org/base
+
+Or visit the following URL, replacing NNNNNN with the revision number:
+
+<URL:https://svnweb.freebsd.org/base?view=revision&revision=NNNNNN>
+
+VII. References
+
+<URL:https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=229852>
+
+<URL:https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=245392>
+
+The latest revision of this advisory is available at
+<URL:https://security.FreeBSD.org/advisories/FreeBSD-EN-20:13.bhyve.asc>
+-----BEGIN PGP SIGNATURE-----
+
+iQKTBAEBCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAl8GLjVfFIAAAAAALgAo
+aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
+MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
+5cKMwQ/9HxrcUNvL8myn512t+drnCnDg/lNL2cqlc53VyDsvwesgXbGA3k1pQsyV
+VLB2jn56+EWcq0b1eieLavK77YtdrbEfa72YOlTd576586VRroUC3d4o6eaAHKHS
+Hzm/Qh5cQM46065Eoshz8T+N1/RNmU0ANS19ogBmogqhbJwwQUSr402a/BGrTES+
++rx4ywmTOrmXxVQwAlRHp1/7pQ5PL3cK2ByYzuFjKjzNX3scHoMxOul2TC1bYwj6
+IhBT7NNxQuY/g7gxGM/ndifOiJtAlsxJdccWxZAMdYv3mzhnM2vqCmdz8KjB7UKH
+2XOKB1RwSq0b1FBsur8Z0Pg6AlIRcNW952mAn2UJxx9mh/oCSj0sqtdmAKu0EO1e
+Vn6+psOffB28ITvdBsf7D/3ixM8+jdAogFzW00iGPppF02QwM6FVxa3+mogOVtsv
+R+Fu381qwQmqvMtAEXOxQ6NiAk3fTan+VuEDB8FnYPEs5JkWef/fn4SPRUrr04hY
+yTkX8F3XID2XdSMTgJllQzhf1uCK3QT77Y0BcPJH+NPZIZiyKkROxqnpS7LGFlEs
+v8dLXTOFnaHfdrjefB/QCwLMTcX1AfN1n0OxQigtwKC1rvKHweaqZBEujtDmyMOm
+uFXhQjoT3o29i1O139Q/3yINEbVYn6U5INrW5ZUGt1nm/wL9PuA=
+=mH7Y
+-----END PGP SIGNATURE-----
diff --git a/share/security/advisories/FreeBSD-EN-20:14.linuxkpi.asc b/share/security/advisories/FreeBSD-EN-20:14.linuxkpi.asc
new file mode 100644
index 0000000000..4e01cb873a
--- /dev/null
+++ b/share/security/advisories/FreeBSD-EN-20:14.linuxkpi.asc
@@ -0,0 +1,131 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA512
+
+=============================================================================
+FreeBSD-EN-20:14.linuxkpi Errata Notice
+ The FreeBSD Project
+
+Topic: Kernel panic in LinuxKPI subsystem
+
+Category: core
+Module: linuxkpi
+Announced: 2020-07-08
+Affects: FreeBSD 12.1 and 11.3
+Corrected: 2020-01-22 00:30:27 UTC (stable/12, 12.1-STABLE)
+ 2020-07-08 19:57:24 UTC (releng/12.1, 12.1-RELEASE-p7)
+ 2020-01-22 15:51:24 UTC (stable/11, 11.3-STABLE)
+ 2020-07-08 19:57:24 UTC (releng/11.3, 11.3-RELEASE-p11)
+
+Note: FreeBSD 11.4 was branched after the original commit to the stable/11
+branch and already includes this erratum.
+
+For general information regarding FreeBSD Errata Notices and Security
+Advisories, including descriptions of the fields above, security
+branches, and the following sections, please visit
+<URL:https://security.FreeBSD.org/>.
+
+I. Background
+
+The LinuxKPI subsystem allows kernel code ported from Linux to run in the
+FreeBSD kernel without extensive modification. Some graphics drivers make
+use of this subsystem.
+
+II. Problem Description
+
+A bug in one of the LinuxKPI subroutines could cause a kernel panic.
+
+III. Impact
+
+Certain graphical applications may trigger a kernel panic. This is most
+often observed when using X11 forwarding to run an application remotely.
+
+IV. Workaround
+
+No workaround is available.
+
+V. Solution
+
+Upgrade your system to a supported FreeBSD stable or release / security
+branch (releng) dated after the correction date and reboot.
+
+Perform one of the following:
+
+1) To update your system via a binary patch:
+
+Systems running a RELEASE version of FreeBSD on the i386 or amd64
+platforms can be updated via the freebsd-update(8) utility:
+
+# freebsd-update fetch
+# freebsd-update install
+# shutdown -r +10min "Rebooting for errata update"
+
+2) To update your system via a source code patch:
+
+The following patches have been verified to apply to the applicable
+FreeBSD release branches.
+
+a) Download the relevant patch from the location below, and verify the
+detached PGP signature using your PGP utility.
+
+# fetch https://security.FreeBSD.org/patches/EN-20:14/linuxpki.patch
+# fetch https://security.FreeBSD.org/patches/EN-20:14/linuxpki.patch.asc
+# gpg --verify linuxkpi.patch.asc
+
+b) Apply the patch. Execute the following commands as root:
+
+# cd /usr/src
+# patch < /path/to/patch
+
+c) Recompile your kernel as described in
+<URL:https://www.FreeBSD.org/handbook/kernelconfig.html> and reboot the
+system.
+
+VI. Correction details
+
+The following list contains the correction revision numbers for each
+affected branch.
+
+Branch/path Revision
+- -------------------------------------------------------------------------
+stable/12/ r356953
+releng/12.1/ r363023
+stable/11/ r356987
+releng/11.3/ r363023
+- -------------------------------------------------------------------------
+
+To see which files were modified by a particular revision, run the
+following command, replacing NNNNNN with the revision number, on a
+machine with Subversion installed:
+
+# svn diff -cNNNNNN --summarize svn://svn.freebsd.org/base
+
+Or visit the following URL, replacing NNNNNN with the revision number:
+
+<URL:https://svnweb.freebsd.org/base?view=revision&revision=NNNNNN>
+
+VII. References
+
+<other info on the problem>
+
+<URL:https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=242913>
+
+The latest revision of this advisory is available at
+<URL:https://security.FreeBSD.org/advisories/FreeBSD-EN-20:14.linuxkpi.asc>
+-----BEGIN PGP SIGNATURE-----
+
+iQKTBAEBCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAl8GLkpfFIAAAAAALgAo
+aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
+MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
+5cJG7A//RWsupxbp1AMqYFz7KsC6zezh8pYU8rONJvWGgaH5MNTdzKVa+SDAg9il
+HI2IOAsDDRFRQvweyf1yOPMdPFUv15ZPgYpUcx2MoAbLFNa5TsqcodE6t1hEjBrQ
+20x0yjg/Fy6T17BaX3cziBFjxd3YW79jf/+FpzCTOoNasxIteiR5Vt4NbJ7Esqoa
+u7U3uXtIvDmfVASfMYq2NmKWTP8cz+f2FCB3687G4jGmBhrfMK8DNVQ3RI6IjGEm
+RUzmnYLX0Xbs83PTCYEkEqmEdj+o9zRokCPxdhFjd9XxnKaWh5vM0N6FNxBOcYER
+OqGMy0X88wsqvs5l+FnXYdI/BzELrzXmB4lMEh9wXDfrCZt4wVkb0C0NBLGgrafV
+95/YQobMsghe44ysVTmpfTi1++NnEDPgV/klVwBo6u9VluMH3PRxrTtW92SB0DOt
+QABVpgV96LKibsO26PRLS5yqMEgUPJ57W6mQvL9RdsTL/4VBamHQmUinXM1VlMml
+d2WVLguLw2vc86Mv2V4FZiC6A1eG91mUDTUYCeGxqBknl7DxBl+iGyM4Bu3Kw1+p
+eRi1Y6hAR/Vb/VyE4mNTBd0UzZhRymaXkiVm7nAKZjTAvSbpbEe26QCPzZGUgVsT
+UemEPi2lAAn2J3O46sEv8RjFjOOdrbOnyaZkJNBaKSPK7qq6etc=
+=1UKD
+-----END PGP SIGNATURE-----
diff --git a/share/security/advisories/FreeBSD-EN-20:15.mps.asc b/share/security/advisories/FreeBSD-EN-20:15.mps.asc
new file mode 100644
index 0000000000..90936c1a91
--- /dev/null
+++ b/share/security/advisories/FreeBSD-EN-20:15.mps.asc
@@ -0,0 +1,129 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA512
+
+=============================================================================
+FreeBSD-EN-20:15.mps Errata Notice
+ The FreeBSD Project
+
+Topic: Kernel panic in mps(4) driver
+
+Category: core
+Module: mps
+Announced: 2020-07-08
+Affects: All supported version of FreeBSD.
+Corrected: 2020-06-11 14:48:20 UTC (stable/12, 12.1-STABLE)
+ 2020-07-08 19:58:00 UTC (releng/12.1, 12.1-RELEASE-p7)
+ 2020-06-11 14:49:38 UTC (stable/11, 11.4-STABLE)
+ 2020-07-08 19:58:00 UTC (releng/11.4, 11.4-RELEASE-p1)
+ 2020-07-08 19:58:00 UTC (releng/11.3, 11.3-RELEASE-p11)
+
+For general information regarding FreeBSD Errata Notices and Security
+Advisories, including descriptions of the fields above, security
+branches, and the following sections, please visit
+<URL:https://security.FreeBSD.org/>.
+
+I. Background
+
+mps(4) is a disk controller driver. It exports an ioctl(2) interface used by
+several command-line utilities to query for or set properties of the device.
+
+II. Problem Description
+
+mps(4) implements a pass-through interface which allows privileged user
+processes to submit commands directly to disks behind the controller. A bug
+in the code which copies command results out to the requesting process could
+cause a kernel panic.
+
+III. Impact
+
+Administrative commands issued by, e.g., sas2ircu, could cause a kernel panic.
+
+IV. Workaround
+
+No workaround is available. Systems that do not use mps(4) are unaffected.
+
+V. Solution
+
+Upgrade your system to a supported FreeBSD stable or release / security
+branch (releng) dated after the correction date and reboot.
+
+Perform one of the following:
+
+1) To update your system via a binary patch:
+
+Systems running a RELEASE version of FreeBSD on the i386 or amd64
+platforms can be updated via the freebsd-update(8) utility:
+
+# freebsd-update fetch
+# freebsd-update install
+# shutdown -r +10min "Rebooting for errata update"
+
+2) To update your system via a source code patch:
+
+The following patches have been verified to apply to the applicable
+FreeBSD release branches.
+
+a) Download the relevant patch from the location below, and verify the
+detached PGP signature using your PGP utility.
+
+# fetch https://security.FreeBSD.org/patches/EN-20:15/mps.patch
+# fetch https://security.FreeBSD.org/patches/EN-20:15/mps.patch.asc
+# gpg --verify mps.patch.asc
+
+b) Apply the patch. Execute the following commands as root:
+
+# cd /usr/src
+# patch < /path/to/patch
+
+c) Recompile your kernel as described in
+<URL:https://www.FreeBSD.org/handbook/kernelconfig.html> and reboot the
+system.
+
+VI. Correction details
+
+The following list contains the correction revision numbers for each
+affected branch.
+
+Branch/path Revision
+- -------------------------------------------------------------------------
+stable/12/ r362057
+releng/12.1/ r363024
+stable/11/ r362058
+releng/11.4/ r363024
+releng/11.3/ r363024
+- -------------------------------------------------------------------------
+
+To see which files were modified by a particular revision, run the
+following command, replacing NNNNNN with the revision number, on a
+machine with Subversion installed:
+
+# svn diff -cNNNNNN --summarize svn://svn.freebsd.org/base
+
+Or visit the following URL, replacing NNNNNN with the revision number:
+
+<URL:https://svnweb.freebsd.org/base?view=revision&revision=NNNNNN>
+
+VII. References
+
+<URL:https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=223813>
+
+The latest revision of this advisory is available at
+<URL:https://security.FreeBSD.org/advisories/FreeBSD-EN-20:15.mps.asc>
+-----BEGIN PGP SIGNATURE-----
+
+iQKTBAEBCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAl8GLk5fFIAAAAAALgAo
+aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
+MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
+5cLlPxAAgUVjwHuRGD4sTiymH2QgkdjneeE99obAzXDTDDNAOWaJQqmZV2L+ooYq
+2nnNdax0CpNvSaNF7KyEFYy30kcoBkSl8MBfOwtuUbO4fWUTDLIm3nUBn6YLvlkr
+ZdrDEzLN3EXOoHnVez4+dcCostVDWAVMPiGzNitU4htPy3pPvwyEcko9lA4eOF5Q
+ZanF1YjsAJOUvtmmCOr1XGRjzsW05Fbiyv6dAmaK7z508gAUj9t7x1a6XnIdLbJY
+tx4+UcBT3yvdSkXNlqGa8EGtPXz9ue4Aq53PSy+C9pbUiEBPgvnLQB0IJNU5Kynv
+fGlHMhee/Ih9+ZfSXoInvDJ+gVYdhufqQQ3GSUcdm7suUuQ+Gc8xn+KUUUZ8xtub
+3EfDeQ2h2eKlaGs0RrVNHtE9ETn+aimagVp5wcws6JLw3Nm5cEAzJFz8fK8lIbXe
+xONslLH1a6985k8CmHVDh6YULCZV9G3G+DGG3mvBnj+/wtysSaa3nOyQEPFuUXHI
+rf6d9JWzV6Is3nx0+34StQu/lyyixwb1LssSjop08+J2G66/ZBVYoorQ1qVzU1lH
+OkUg00JeHvFI4uKEEsv0/P31vM4aeW5iJsiWvjY6MAZ7VMmJMOrJEdiX+vycNkQ1
+cS7Qi6DCEpnFZCP61cEbYonBK1rgvNexTRTwIHIrATLLKEOtq+U=
+=6tC9
+-----END PGP SIGNATURE-----
diff --git a/share/security/advisories/FreeBSD-SA-20:18.posix_spawnp.asc b/share/security/advisories/FreeBSD-SA-20:18.posix_spawnp.asc
new file mode 100644
index 0000000000..798ff88f5f
--- /dev/null
+++ b/share/security/advisories/FreeBSD-SA-20:18.posix_spawnp.asc
@@ -0,0 +1,138 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA512
+
+=============================================================================
+FreeBSD-SA-20:18.posix_spawnp Security Advisory
+ The FreeBSD Project
+
+Topic: posix_spawnp(3) buffer overflow
+
+Category: core
+Module: libc
+Announced: 2020-07-08
+Credits: Andrew Gierth
+Affects: FreeBSD 11.4
+Corrected: 2020-06-17 16:22:08 UTC (stable/12, 12.1-STABLE)
+ 2020-06-17 16:22:08 UTC (stable/11, 11.4-STABLE)
+ 2020-07-08 20:08:05 UTC (releng/11.4, 11.4-RELEASE-p1)
+CVE Name: CVE-2020-7458
+
+Note: This vulnerability was introduced after the release of FreeBSD 11.3 and
+FreeBSD 12.1; FreeBSD 11.4 is the only affected release.
+
+For general information regarding FreeBSD Security Advisories,
+including descriptions of the fields above, security branches, and the
+following sections, please visit <URL:https://security.FreeBSD.org/>.
+
+I. Background
+
+posix_spawnp(3) is a lightweight process creation mechanism provided by libc
+for general application usage.
+
+II. Problem Description
+
+posix_spawnp spawns a new thread with a limited stack allocated on the heap
+before delegating to execvp for the final execution within that thread.
+
+execvp would previously make unbounded allocations on the stack, directly
+proportional to the length of the user-controlled PATH environment variable.
+
+III. Impact
+
+Long values in the user-controlled PATH environment variable cause
+posix_spawnp to write beyond the end of stack that was allocated, ultimately
+overflowing the heap-allocated stack with a direct copy of the value stored
+in PATH.
+
+IV. Workaround
+
+No workaround is available. Few applications in the base system use
+posix_spawnp(3) and none of them are particularly viable candidates for an
+exploit. Use by third-party applications has not been investigated.
+
+V. Solution
+
+Upgrade your vulnerable system to a supported FreeBSD stable or
+release / security branch (releng) dated after the correction date,
+and reboot.
+
+Perform one of the following:
+
+1) To update your vulnerable system via a binary patch:
+
+Systems running a RELEASE version of FreeBSD on the i386 or amd64
+platforms can be updated via the freebsd-update(8) utility:
+
+# freebsd-update fetch
+# freebsd-update install
+# shutdown -r +10min "Rebooting for a security update"
+
+2) To update your vulnerable system via a source code patch:
+
+The following patches have been verified to apply to the applicable
+FreeBSD release branches.
+
+a) Download the relevant patch from the location below, and verify the
+detached PGP signature using your PGP utility.
+
+[FreeBSD 11.4]
+# fetch https://security.FreeBSD.org/patches/SA-20:18/posix_spawnp.patch
+# fetch https://security.FreeBSD.org/patches/SA-20:18/posix_spawnp.patch.asc
+# gpg --verify posix_spawnp.patch.asc
+
+b) Apply the patch. Execute the following commands as root:
+
+# cd /usr/src
+# patch < /path/to/patch
+
+c) Recompile the operating system using buildworld and installworld as
+described in <URL:https://www.FreeBSD.org/handbook/makeworld.html>.
+
+Restart all daemons that use the library, or reboot the system.
+
+VI. Correction details
+
+The following list contains the correction revision numbers for each
+affected branch.
+
+Branch/path Revision
+- -------------------------------------------------------------------------
+stable/12/ r362281
+stable/11/ r362281
+releng/11.4/ r363025
+- -------------------------------------------------------------------------
+
+To see which files were modified by a particular revision, run the
+following command, replacing NNNNNN with the revision number, on a
+machine with Subversion installed:
+
+# svn diff -cNNNNNN --summarize svn://svn.freebsd.org/base
+
+Or visit the following URL, replacing NNNNNN with the revision number:
+
+<URL:https://svnweb.freebsd.org/base?view=revision&revision=NNNNNN>
+
+VII. References
+
+<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-7458>
+
+The latest revision of this advisory is available at
+<URL:https://security.FreeBSD.org/advisories/FreeBSD-SA-20:18.posix_spawnp.asc>
+-----BEGIN PGP SIGNATURE-----
+
+iQKTBAEBCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAl8GLlNfFIAAAAAALgAo
+aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
+MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
+5cLdthAAgchE9dOcTvmFerK/SEAI7G/+3l1GRQ/hKJfvGbvNuZKKudpMdCmLHzil
+MepCvRO7ft6OTBF66PaAscbdadD54CluQGjD96eLNnQ6dMgU5yZdWTUvvjdJze1R
+200oAlAu2eoZvuRghSNFqh4s8iffYN/T4Tc1ubRCAyZUXYbq5rg3r21P9FugXX+Y
+RZhYzUNRMCi4ZSGkUmcqLltZZtSrI9GOU2H4cKpedYaHJ+b76tALt1fCsSVZwMJK
+7WKiqKkw4ilRH5gbUuTqngVjt7Uy9JGyS2WrAwhnxLIr6+4qxAkiOltwZdFNUhSJ
+HGvTzl2As/gxxjqpqmvzegKfrGOd4pz2i7ZdAhhPWEK0sHNp1NttPQ7wWnU1Ikt3
+bkoiy+eJTF43GL7IpxurOOMDdH9MWL/RAZBZNpTof4XCjhEHvvMaSoeO/GLpcSja
++dYFoip65b1tlBtGt/tlgHVqlzCD86o6pBiRdZ7mYYLTxurDc/dcTpebypQPogcB
+agD3IO0hMXnt1Q/UQVl1pC3LDnSvabeHVI7xuB1T9UP/CsAxTt1nhEM4b9/YnJv5
+Bt1cZFlBvZgrVFVvegYAf7lVz3TsF3xz2pKZD6wxezAk+QbH4ho6aTHWJkRotE4z
+C5bcIEbIz6OX+J7VjOxcgkTu+bFykWb9xcTjtKpRexxICMOef+E=
+=2OBY
+-----END PGP SIGNATURE-----
diff --git a/share/security/advisories/FreeBSD-SA-20:19.unbound.asc b/share/security/advisories/FreeBSD-SA-20:19.unbound.asc
new file mode 100644
index 0000000000..a00f096471
--- /dev/null
+++ b/share/security/advisories/FreeBSD-SA-20:19.unbound.asc
@@ -0,0 +1,143 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA512
+
+=============================================================================
+FreeBSD-SA-20:19.unbound Security Advisory
+ The FreeBSD Project
+
+Topic: Multiple vulnerabilities in unbound
+
+Category: contrib
+Module: unbound
+Announced: 2020-07-08
+Affects: All supported versions of FreeBSD.
+Corrected: 2020-05-24 16:47:27 UTC (stable/12, 12.1-STABLE)
+ 2020-07-08 20:25:06 UTC (releng/12.1, 12.1-RELEASE-p7)
+ 2020-05-24 11:47:27 UTC (stable/11, 11.4-STABLE)
+ 2020-07-08 20:22:38 UTC (releng/11.4, 11.4-RELEASE-p1)
+ 2020-07-08 20:20:59 UTC (releng/11.3, 11.3-RELEASE-p11)
+CVE Name: CVE-2020-12662, CVE-2020-12663
+
+For general information regarding FreeBSD Security Advisories,
+including descriptions of the fields above, security branches, and the
+following sections, please visit <URL:https://security.FreeBSD.org/>.
+
+I. Background
+
+Unbound is a validating, recursive, and caching DNS resolver.
+
+II. Problem Description
+
+Malformed answers from upstream name servers can send Unbound into an infinite
+loop, resulting in denial of service. A malicious query can cause a traffic
+amplification attack against third party authoritative nameservers.
+
+III. Impact
+
+Denial of service of the affected host, or of third parties via traffic
+amplification.
+
+IV. Workaround
+
+No workaround is available. Systems not running Unbound are not affected.
+
+V. Solution
+
+Upgrade your vulnerable system to a supported FreeBSD stable or
+release / security branch (releng) dated after the correction date.
+
+Perform one of the following:
+
+1) To update your vulnerable system via a binary patch:
+
+Systems running a RELEASE version of FreeBSD on the i386 or amd64
+platforms can be updated via the freebsd-update(8) utility:
+
+# freebsd-update fetch
+# freebsd-update install
+
+2) To update your vulnerable system via a source code patch:
+
+The following patches have been verified to apply to the applicable
+FreeBSD release branches.
+
+a) Download the relevant patch from the location below, and verify the
+detached PGP signature using your PGP utility.
+
+[FreeBSD 12.1]
+# fetch https://security.FreeBSD.org/patches/SA-20:19/unbound.12.1.patch
+# fetch https://security.FreeBSD.org/patches/SA-20:19/unbound.12.1.patch.asc
+# gpg --verify unbound.12.1.patch.asc
+
+[FreeBSD 11.4]
+# fetch https://security.FreeBSD.org/patches/SA-20:19/unbound.11.4.patch
+# fetch https://security.FreeBSD.org/patches/SA-20:19/unbound.11.4.patch.asc
+# gpg --verify unbound.11.4.patch.asc
+
+[FreeBSD 11.3]
+# fetch https://security.FreeBSD.org/patches/SA-20:19/unbound.11.3.patch
+# fetch https://security.FreeBSD.org/patches/SA-20:19/unbound.11.3.patch.asc
+# gpg --verify unbound.11.3.patch.asc
+
+b) Apply the patch. Execute the following commands as root:
+
+# cd /usr/src
+# patch -p0 < /path/to/patch
+
+c) Recompile the operating system using buildworld and installworld as
+described in <URL:https://www.FreeBSD.org/handbook/makeworld.html>.
+
+Restart the applicable daemons, or reboot the system.
+
+VI. Correction details
+
+The following list contains the correction revision numbers for each
+affected branch.
+
+Branch/path Revision
+- -------------------------------------------------------------------------
+stable/12/ r361435
+releng/12.1/ r363029
+stable/11/ r361435
+releng/11.4/ r363028
+releng/11.3/ r363027
+- -------------------------------------------------------------------------
+
+To see which files were modified by a particular revision, run the
+following command, replacing NNNNNN with the revision number, on a
+machine with Subversion installed:
+
+# svn diff -cNNNNNN --summarize svn://svn.freebsd.org/base
+
+Or visit the following URL, replacing NNNNNN with the revision number:
+
+<URL:https://svnweb.freebsd.org/base?view=revision&revision=NNNNNN>
+
+VII. References
+
+<URL:https://nlnetlabs.nl/downloads/unbound/CVE-2020-12662_2020-12663.txt>
+
+<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-12662>
+
+<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-12663>
+
+The latest revision of this advisory is available at
+<URL:https://security.FreeBSD.org/advisories/FreeBSD-SA-20:19.unbound.asc>
+-----BEGIN PGP SIGNATURE-----
+
+iQKTBAEBCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAl8GLldfFIAAAAAALgAo
+aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
+MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
+5cLg3g/+KxaCk6wFvqDCYlT2Rx8ZfxuU4cG8anJvdanwI8pV7SWsVIilWvpIuW5Y
+1P/TVmZiXpICToiUXdwaOMj8r/8QhmALXd3icb+QBUBdLlkm6Cuh/lSbEAyA63aF
+YYDF9FsXITVMcUCiUCxpVWSzDUW3LD5jMC/0jjvb7N0VhQyn4vHgEUa74jstnu4r
+36QV1s+ucsJafwAyzfobP+fCGKnVM8rmJ/3jE/eifN9RajFJdlkTtV0j6ReK9XQR
+jWunCgYZs8Ur0RFu98hspeRsXPuygV83sDiVWPQUd+iKXC8fW52f+IpAVO4BB763
+ZOjXaeudVfqorBXpKsldggEaCrxbJlEdwR9oZOrNww4QDqgPnU4Fkdb2TXyl5Gtx
+t0fbvEl2sxfx5M+3rF9ae++DPpmIiu8DiodF8XKfXicFZ2WpJmnwEY0SeEGYGyrO
+MJZW3i45qfe4CneFtt1r1v1feX3XQZKuyjtb++S2/PDiSQ1ZrkdE3Y3VYS3X+pLt
+C1ZFkw6nLDDSVzPiD+1i8VzRoKwS7zZKfAWMBJRiO3Jjh2vXsNRYO6wAMPq4HAvA
+DkB0Ykm0ioDqtUwEKhqAcJEmu6P44BM9SJ0ApFeKQ8L+isNoiaEMEVFG1HW9avl6
+E+I33y5yBtvgrRiyqUvANh/ZYSb7FQDTf5rlUOwG+Pk/kUlMrUA=
+=tonD
+-----END PGP SIGNATURE-----
diff --git a/share/security/advisories/FreeBSD-SA-20:20.ipv6.asc b/share/security/advisories/FreeBSD-SA-20:20.ipv6.asc
new file mode 100644
index 0000000000..bb8e381aa3
--- /dev/null
+++ b/share/security/advisories/FreeBSD-SA-20:20.ipv6.asc
@@ -0,0 +1,131 @@
+-----BEGIN PGP SIGNED MESSAGE-----
+Hash: SHA512
+
+=============================================================================
+FreeBSD-SA-20:20.ipv6 Security Advisory
+ The FreeBSD Project
+
+Topic: IPv6 socket option race condition and use after free
+
+Category: core
+Module: network
+Announced: 2020-07-08
+Credits: syzkaller, Andy Nguyen
+Affects: All supported versions of FreeBSD.
+Corrected: 2020-04-02 15:30:51 UTC (stable/12, 12.1-STABLE)
+ 2020-07-08 20:11:40 UTC (releng/12.1, 12.1-RELEASE-p7)
+ 2020-07-06 20:23:14 UTC (stable/11, 11.4-STABLE)
+ 2020-07-08 20:11:40 UTC (releng/11.4, 11.4-RELEASE-p1)
+ 2020-07-08 20:11:40 UTC (releng/11.3, 11.3-RELEASE-p11)
+CVE Name: CVE-2020-7457
+
+For general information regarding FreeBSD Security Advisories,
+including descriptions of the fields above, security branches, and the
+following sections, please visit <URL:https://security.FreeBSD.org/>.
+
+I. Background
+
+The IPV6_2292PKTOPTIONS socket option allows user code to set IPv6
+header options on a socket.
+
+II. Problem Description
+
+The IPV6_2292PKTOPTIONS set handler was missing synchronization,
+so racing accesses could modify freed memory.
+
+III. Impact
+
+A malicious user application could trigger memory corruption, leading
+to privilege escalation.
+
+IV. Workaround
+
+No workaround is available.
+
+V. Solution
+
+Upgrade your vulnerable system to a supported FreeBSD stable or release /
+security branch (releng) dated after the correction date and reboot.
+
+Perform one of the following:
+
+1) To update your vulnerable system via a binary patch:
+
+Systems running a RELEASE version of FreeBSD on the i386 or amd64
+platforms can be updated via the freebsd-update(8) utility:
+
+# freebsd-update fetch
+# freebsd-update install
+# shutdown -r +10min "Rebooting for a security update"
+
+2) To update your vulnerable system via a source code patch:
+
+The following patches have been verified to apply to the applicable
+FreeBSD release branches.
+
+a) Download the relevant patch from the location below, and verify the
+detached PGP signature using your PGP utility.
+
+# fetch https://security.FreeBSD.org/patches/SA-20:20/ipv6.patch
+# fetch https://security.FreeBSD.org/patches/SA-20:20/ipv6.patch.asc
+# gpg --verify ipv6.patch.asc
+
+b) Apply the patch. Execute the following commands as root:
+
+# cd /usr/src
+# patch < /path/to/patch
+
+c) Recompile your kernel as described in
+<URL:https://www.FreeBSD.org/handbook/kernelconfig.html> and reboot the
+system.
+
+VI. Correction details
+
+The following list contains the correction revision numbers for each
+affected branch.
+
+Branch/path Revision
+- -------------------------------------------------------------------------
+stable/12/ r359565
+releng/12.1/ r363026
+stable/11/ r362975
+releng/11.4/ r363026
+releng/11.3/ r363026
+- -------------------------------------------------------------------------
+
+To see which files were modified by a particular revision, run the
+following command, replacing NNNNNN with the revision number, on a
+machine with Subversion installed:
+
+# svn diff -cNNNNNN --summarize svn://svn.freebsd.org/base
+
+Or visit the following URL, replacing NNNNNN with the revision number:
+
+<URL:https://svnweb.freebsd.org/base?view=revision&revision=NNNNNN>
+
+VII. References
+
+<URL:https://hackerone.com/reports/826026>
+
+<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-7457>
+
+The latest revision of this advisory is available at
+<URL:https://security.FreeBSD.org/advisories/FreeBSD-SA-20:20.ipv6.asc>
+-----BEGIN PGP SIGNATURE-----
+
+iQKTBAEBCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAl8GLvVfFIAAAAAALgAo
+aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
+MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
+5cJqxA/9H58yyRUSUy6BTRw0XkCQFO3r0NpTYPWK4RJFPWO2Jh5zL2QjxuSj3k9t
+zgJXM6a1RRgOxevxSzJJXD74BZz3XLJnC9T0tXsp3nikMrd+NSVN0g2jfAbx0l7R
+RFRUJOI2EfcGkIe0tZy4/nGr+H9eZiJt9a9vJ8DCoJuU9Ph/7w3GrVG+gbJfH4sV
+KhvhrRzla4ePadnHyQZALL5ov554BUa3dB9STz8zbdjt5yFREpvCJ9mIOHKNPBCR
+X5v7OMwhw++2Q0JtoMsmBHMi8zOkDpbjPk5eQNLHg3Iw9ZQrxW8KtM9Ru3KFtPw9
+gisI9e53NkCUGLm9iq3oQG6CnCMulTMAlgN5f0HflEwy3vd7R/ibNLvx2yObmVOU
+cX1Nf0ydFfhoS/YQwArdGTUg12BlYL9lqiXTqojUBG+yikwA3XAIUJccpcYyZDLQ
+jR5N8Ct7fV9Ec5pdu4xkSQhKsto9pQVfS0Kabv7hlwumynVL+S7qsmS7FT3IC/4n
+FiXisrJr5TTNO8p/bIs8qooHYUkd06A5O8xy+gRDDPbgvYfevGWrd/vaHmiXpUsv
+dvv9ZnU8xlaSi66AEPs9kYw/WhF55deqaU1M0p6Ob3+TGyJIR3j3IPTAIIXSgTrq
+YiyvzqXM+ob3aysILYRv48LK7+5N/3hDU48FLUN6q1V99G7TV8o=
+=JUip
+-----END PGP SIGNATURE-----
diff --git a/share/security/patches/EN-20:13/bhyve.patch b/share/security/patches/EN-20:13/bhyve.patch
new file mode 100644
index 0000000000..d9106b4b6a
--- /dev/null
+++ b/share/security/patches/EN-20:13/bhyve.patch
@@ -0,0 +1,342 @@
+--- sys/amd64/vmm/intel/vtd.c.orig
++++ sys/amd64/vmm/intel/vtd.c
+@@ -51,6 +51,8 @@
+ * Architecture Spec, September 2008.
+ */
+
++#define VTD_DRHD_INCLUDE_PCI_ALL(Flags) (((Flags) >> 0) & 0x1)
++
+ /* Section 10.4 "Register Descriptions" */
+ struct vtdmap {
+ volatile uint32_t version;
+@@ -116,10 +118,11 @@
+ static SLIST_HEAD(, domain) domhead;
+
+ #define DRHD_MAX_UNITS 8
+-static int drhd_num;
+-static struct vtdmap *vtdmaps[DRHD_MAX_UNITS];
+-static int max_domains;
+-typedef int (*drhd_ident_func_t)(void);
++static ACPI_DMAR_HARDWARE_UNIT *drhds[DRHD_MAX_UNITS];
++static int drhd_num;
++static struct vtdmap *vtdmaps[DRHD_MAX_UNITS];
++static int max_domains;
++typedef int (*drhd_ident_func_t)(void);
+
+ static uint64_t root_table[PAGE_SIZE / sizeof(uint64_t)] __aligned(4096);
+ static uint64_t ctx_tables[256][PAGE_SIZE / sizeof(uint64_t)] __aligned(4096);
+@@ -175,6 +178,69 @@
+ return (id);
+ }
+
++static struct vtdmap *
++vtd_device_scope(uint16_t rid)
++{
++ int i, remaining, pathremaining;
++ char *end, *pathend;
++ struct vtdmap *vtdmap;
++ ACPI_DMAR_HARDWARE_UNIT *drhd;
++ ACPI_DMAR_DEVICE_SCOPE *device_scope;
++ ACPI_DMAR_PCI_PATH *path;
++
++ for (i = 0; i < drhd_num; i++) {
++ drhd = drhds[i];
++
++ if (VTD_DRHD_INCLUDE_PCI_ALL(drhd->Flags)) {
++ /*
++ * From Intel VT-d arch spec, version 3.0:
++ * If a DRHD structure with INCLUDE_PCI_ALL flag Set is reported
++ * for a Segment, it must be enumerated by BIOS after all other
++ * DRHD structures for the same Segment.
++ */
++ vtdmap = vtdmaps[i];
++ return(vtdmap);
++ }
++
++ end = (char *)drhd + drhd->Header.Length;
++ remaining = drhd->Header.Length - sizeof(ACPI_DMAR_HARDWARE_UNIT);
++ while (remaining > sizeof(ACPI_DMAR_DEVICE_SCOPE)) {
++ device_scope = (ACPI_DMAR_DEVICE_SCOPE *)(end - remaining);
++ remaining -= device_scope->Length;
++
++ switch (device_scope->EntryType){
++ /* 0x01 and 0x02 are PCI device entries */
++ case 0x01:
++ case 0x02:
++ break;
++ default:
++ continue;
++ }
++
++ if (PCI_RID2BUS(rid) != device_scope->Bus)
++ continue;
++
++ pathend = (char *)device_scope + device_scope->Length;
++ pathremaining = device_scope->Length - sizeof(ACPI_DMAR_DEVICE_SCOPE);
++ while (pathremaining >= sizeof(ACPI_DMAR_PCI_PATH)) {
++ path = (ACPI_DMAR_PCI_PATH *)(pathend - pathremaining);
++ pathremaining -= sizeof(ACPI_DMAR_PCI_PATH);
++
++ if (PCI_RID2SLOT(rid) != path->Device)
++ continue;
++ if (PCI_RID2FUNC(rid) != path->Function)
++ continue;
++
++ vtdmap = vtdmaps[i];
++ return (vtdmap);
++ }
++ }
++ }
++
++ /* No matching scope */
++ return (NULL);
++}
++
+ static void
+ vtd_wbflush(struct vtdmap *vtdmap)
+ {
+@@ -240,7 +306,7 @@
+ static int
+ vtd_init(void)
+ {
+- int i, units, remaining;
++ int i, units, remaining, tmp;
+ struct vtdmap *vtdmap;
+ vm_paddr_t ctx_paddr;
+ char *end, envname[32];
+@@ -291,8 +357,9 @@
+ break;
+
+ drhd = (ACPI_DMAR_HARDWARE_UNIT *)hdr;
+- vtdmaps[units++] = (struct vtdmap *)PHYS_TO_DMAP(drhd->Address);
+- if (units >= DRHD_MAX_UNITS)
++ drhds[units] = drhd;
++ vtdmaps[units] = (struct vtdmap *)PHYS_TO_DMAP(drhd->Address);
++ if (++units >= DRHD_MAX_UNITS)
+ break;
+ remaining -= hdr->Length;
+ }
+@@ -302,12 +369,18 @@
+
+ skip_dmar:
+ drhd_num = units;
+- vtdmap = vtdmaps[0];
+
+- if (VTD_CAP_CM(vtdmap->cap) != 0)
+- panic("vtd_init: invalid caching mode");
++ max_domains = 64 * 1024; /* maximum valid value */
++ for (i = 0; i < drhd_num; i++){
++ vtdmap = vtdmaps[i];
++
++ if (VTD_CAP_CM(vtdmap->cap) != 0)
++ panic("vtd_init: invalid caching mode");
+
+- max_domains = vtd_max_domains(vtdmap);
++ /* take most compatible (minimum) value */
++ if ((tmp = vtd_max_domains(vtdmap)) < max_domains)
++ max_domains = tmp;
++ }
+
+ /*
+ * Set up the root-table to point to the context-entry tables
+@@ -373,7 +446,6 @@
+ struct vtdmap *vtdmap;
+ uint8_t bus;
+
+- vtdmap = vtdmaps[0];
+ bus = PCI_RID2BUS(rid);
+ ctxp = ctx_tables[bus];
+ pt_paddr = vtophys(dom->ptp);
+@@ -385,6 +457,10 @@
+ (uint16_t)(ctxp[idx + 1] >> 8));
+ }
+
++ if ((vtdmap = vtd_device_scope(rid)) == NULL)
++ panic("vtd_add_device: device %x is not in scope for "
++ "any DMA remapping unit", rid);
++
+ /*
+ * Order is important. The 'present' bit is set only after all fields
+ * of the context pointer are initialized.
+@@ -568,8 +644,6 @@
+ if (drhd_num <= 0)
+ panic("vtd_create_domain: no dma remapping hardware available");
+
+- vtdmap = vtdmaps[0];
+-
+ /*
+ * Calculate AGAW.
+ * Section 3.4.2 "Adjusted Guest Address Width", Architecture Spec.
+@@ -594,7 +668,14 @@
+ pt_levels = 2;
+ sagaw = 30;
+ addrwidth = 0;
+- tmp = VTD_CAP_SAGAW(vtdmap->cap);
++
++ tmp = ~0;
++ for (i = 0; i < drhd_num; i++) {
++ vtdmap = vtdmaps[i];
++ /* take most compatible value */
++ tmp &= VTD_CAP_SAGAW(vtdmap->cap);
++ }
++
+ for (i = 0; i < 5; i++) {
+ if ((tmp & (1 << i)) != 0 && sagaw >= agaw)
+ break;
+@@ -606,8 +687,8 @@
+ }
+
+ if (i >= 5) {
+- panic("vtd_create_domain: SAGAW 0x%lx does not support AGAW %d",
+- VTD_CAP_SAGAW(vtdmap->cap), agaw);
++ panic("vtd_create_domain: SAGAW 0x%x does not support AGAW %d",
++ tmp, agaw);
+ }
+
+ dom = malloc(sizeof(struct domain), M_VTD, M_ZERO | M_WAITOK);
+@@ -634,7 +715,12 @@
+ * There is not any code to deal with the demotion at the moment
+ * so we disable superpage mappings altogether.
+ */
+- dom->spsmask = VTD_CAP_SPS(vtdmap->cap);
++ dom->spsmask = ~0;
++ for (i = 0; i < drhd_num; i++) {
++ vtdmap = vtdmaps[i];
++ /* take most compatible value */
++ dom->spsmask &= VTD_CAP_SPS(vtdmap->cap);
++ }
+ #endif
+
+ SLIST_INSERT_HEAD(&domhead, dom, next);
+--- usr.sbin/bhyve/pci_emul.c.orig
++++ usr.sbin/bhyve/pci_emul.c
+@@ -868,7 +868,7 @@
+ sizeof(msixcap)));
+ }
+
+-void
++static void
+ msixcap_cfgwrite(struct pci_devinst *pi, int capoff, int offset,
+ int bytes, uint32_t val)
+ {
+@@ -892,7 +892,7 @@
+ CFGWRITE(pi, offset, val, bytes);
+ }
+
+-void
++static void
+ msicap_cfgwrite(struct pci_devinst *pi, int capoff, int offset,
+ int bytes, uint32_t val)
+ {
+@@ -971,30 +971,34 @@
+
+ /*
+ * This function assumes that 'coff' is in the capabilities region of the
+- * config space.
++ * config space. A capoff parameter of zero will force a search for the
++ * offset and type.
+ */
+-static void
+-pci_emul_capwrite(struct pci_devinst *pi, int offset, int bytes, uint32_t val)
++void
++pci_emul_capwrite(struct pci_devinst *pi, int offset, int bytes, uint32_t val,
++ uint8_t capoff, int capid)
+ {
+- int capid;
+- uint8_t capoff, nextoff;
++ uint8_t nextoff;
+
+ /* Do not allow un-aligned writes */
+ if ((offset & (bytes - 1)) != 0)
+ return;
+
+- /* Find the capability that we want to update */
+- capoff = CAP_START_OFFSET;
+- while (1) {
+- nextoff = pci_get_cfgdata8(pi, capoff + 1);
+- if (nextoff == 0)
+- break;
+- if (offset >= capoff && offset < nextoff)
+- break;
++ if (capoff == 0) {
++ /* Find the capability that we want to update */
++ capoff = CAP_START_OFFSET;
++ while (1) {
++ nextoff = pci_get_cfgdata8(pi, capoff + 1);
++ if (nextoff == 0)
++ break;
++ if (offset >= capoff && offset < nextoff)
++ break;
+
+- capoff = nextoff;
++ capoff = nextoff;
++ }
++ assert(offset >= capoff);
++ capid = pci_get_cfgdata8(pi, capoff);
+ }
+- assert(offset >= capoff);
+
+ /*
+ * Capability ID and Next Capability Pointer are readonly.
+@@ -1011,7 +1015,6 @@
+ return;
+ }
+
+- capid = pci_get_cfgdata8(pi, capoff);
+ switch (capid) {
+ case PCIY_MSI:
+ msicap_cfgwrite(pi, capoff, offset, bytes, val);
+@@ -1878,7 +1881,7 @@
+ pci_set_cfgdata32(pi, coff, bar);
+
+ } else if (pci_emul_iscap(pi, coff)) {
+- pci_emul_capwrite(pi, coff, bytes, *eax);
++ pci_emul_capwrite(pi, coff, bytes, *eax, 0, 0);
+ } else if (coff >= PCIR_COMMAND && coff < PCIR_REVID) {
+ pci_emul_cmdsts_write(pi, coff, *eax, bytes);
+ } else {
+--- usr.sbin/bhyve/pci_emul.h.orig
++++ usr.sbin/bhyve/pci_emul.h
+@@ -212,10 +212,6 @@
+ int ioapic_irq, void *arg);
+
+ int init_pci(struct vmctx *ctx);
+-void msicap_cfgwrite(struct pci_devinst *pi, int capoff, int offset,
+- int bytes, uint32_t val);
+-void msixcap_cfgwrite(struct pci_devinst *pi, int capoff, int offset,
+- int bytes, uint32_t val);
+ void pci_callback(void);
+ int pci_emul_alloc_bar(struct pci_devinst *pdi, int idx,
+ enum pcibar_type type, uint64_t size);
+@@ -223,6 +219,8 @@
+ uint64_t hostbase, enum pcibar_type type, uint64_t size);
+ int pci_emul_add_msicap(struct pci_devinst *pi, int msgnum);
+ int pci_emul_add_pciecap(struct pci_devinst *pi, int pcie_device_type);
++void pci_emul_capwrite(struct pci_devinst *pi, int offset, int bytes,
++ uint32_t val, uint8_t capoff, int capid);
+ void pci_generate_msi(struct pci_devinst *pi, int msgnum);
+ void pci_generate_msix(struct pci_devinst *pi, int msgnum);
+ void pci_lintr_assert(struct pci_devinst *pi);
+--- usr.sbin/bhyve/pci_passthru.c.orig
++++ usr.sbin/bhyve/pci_passthru.c
+@@ -828,8 +828,8 @@
+ * MSI capability is emulated
+ */
+ if (msicap_access(sc, coff)) {
+- msicap_cfgwrite(pi, sc->psc_msi.capoff, coff, bytes, val);
+-
++ pci_emul_capwrite(pi, coff, bytes, val, sc->psc_msi.capoff,
++ PCIY_MSI);
+ error = vm_setup_pptdev_msi(ctx, vcpu, sc->psc_sel.pc_bus,
+ sc->psc_sel.pc_dev, sc->psc_sel.pc_func,
+ pi->pi_msi.addr, pi->pi_msi.msg_data,
+@@ -840,7 +840,8 @@
+ }
+
+ if (msixcap_access(sc, coff)) {
+- msixcap_cfgwrite(pi, sc->psc_msix.capoff, coff, bytes, val);
++ pci_emul_capwrite(pi, coff, bytes, val, sc->psc_msix.capoff,
++ PCIY_MSIX);
+ if (pi->pi_msix.enabled) {
+ msix_table_entries = pi->pi_msix.table_count;
+ for (i = 0; i < msix_table_entries; i++) {
diff --git a/share/security/patches/EN-20:13/bhyve.patch.asc b/share/security/patches/EN-20:13/bhyve.patch.asc
new file mode 100644
index 0000000000..cf8961f68f
--- /dev/null
+++ b/share/security/patches/EN-20:13/bhyve.patch.asc
@@ -0,0 +1,18 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQKTBAABCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAl8GLnVfFIAAAAAALgAo
+aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
+MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
+5cJnVQ//a+Sv6tvAbSY/NigpbYLEXFT2iC66yxnL4WkIjy8eDZq4DbE95seOlYa0
+MErgPFCWvpiEbmWmtW4zt9KMOgvUXVPXr3y7siax9wBFbQil87HW+5ujHueKOLo0
+drl+wllxHMNaYFnY3leHCBlQRcMF/vCmQwuh67wvpKm4R3lcJFVw7fzuKRRtOTrU
+Mf621q5NRAiBUlTD9V3jdGbWd7aZ00N+UNmOdErjf2jIm8yKEk/seKEQr+u/dD0l
+HmTxG2HFSggUNiFLaR1OLVYDTQZnnuegAj50YTIR96kBfXNX+RmoT6iUmICbhPGt
+zbEy2ApvUYK2XmfRmcXTT8n1IRDlgSo19Ajf7rEuVaX3i8H8NNQHoeV9pxnNBEs8
+0HaSjeL9hTuWdVbDEIrb4yPyl8ud3ZIOymcegkG5bXgzCBdvTQ1J4DqMJWrndoTE
+Bnvn+DvIKtqTNxxZNMdAW4jgj9xsW9UDKppAKjCM1JChco6VjJoE4qr/H+MClBES
+rRSTUeh9FX2Zt1fr+roGmgjS5lV7YWtEOb1SxsNLTY6ehuyNRoEPmfvmfGkhy+mm
+I9cVql2ZBvJjsd2cA7u5TjrkiSIIuARn8w/itF5t7ETHWjsq5H56OdvrVyfHTKw2
+2s6lc0rXOBwB0kcPIVv0pl1TAei8y0zbKsUgm3rdCORuxG0vAIo=
+=csQT
+-----END PGP SIGNATURE-----
diff --git a/share/security/patches/EN-20:14/linuxkpi.patch b/share/security/patches/EN-20:14/linuxkpi.patch
new file mode 100644
index 0000000000..d4d19172b9
--- /dev/null
+++ b/share/security/patches/EN-20:14/linuxkpi.patch
@@ -0,0 +1,12 @@
+--- sys/compat/linuxkpi/common/src/linux_compat.c.orig
++++ sys/compat/linuxkpi/common/src/linux_compat.c
+@@ -1502,6 +1502,9 @@
+ KASSERT(file_count(filp) == 0,
+ ("File refcount(%d) is not zero", file_count(filp)));
+
++ if (td == NULL)
++ td = curthread;
++
+ error = 0;
+ filp->f_flags = file->f_flag;
+ linux_set_current(td);
diff --git a/share/security/patches/EN-20:14/linuxkpi.patch.asc b/share/security/patches/EN-20:14/linuxkpi.patch.asc
new file mode 100644
index 0000000000..36536fae29
--- /dev/null
+++ b/share/security/patches/EN-20:14/linuxkpi.patch.asc
@@ -0,0 +1,18 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQKTBAABCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAl8GLnpfFIAAAAAALgAo
+aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
+MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
+5cLGGg//YXr2SKIW7W0Rx1KR44PjEp2zkDLPIYVRjwUeQoTO3Jpljpt66WfehbOH
+GS4vb1RfA97KYiOjNxY3NhgRPDzoXR9b6Ht+ezzEtbsAF9tQAtc3Nt+FDoMfYLh8
+sZ6sUZdMUQExF3R5a0qmoi5FoggPaFft5cFSrrYkKRv26VcyaizJhSSCZOtGR91D
+pLWk/napYpaTrDXUnYGjyMHtj2zRimv3fa2T+4+UUTWQnMyWsnwLCd0d4+Ks+dwy
+fULPoLXRu2APflau5kHpAf6A8m/y/geYX3esjC9lj6G6xDCTmlY1ILQsXqm2DIVx
+RYcsSh7z0hsBlfIDcebj/+3GYU0ydyA/0N5mC4J3Xy7hm1HQvVPoCo+QcP/PdKvu
+E1Q4PF1fn7aPR77ghfnPtodznzA2zoSpAC24hHaDSy7H+NVGUgCxXiJNcQ4gsaBn
+/3Fv24bvLcUbu0M+sBn75NMsBf31HY6h/V7h6a6f4fVYnmwe0Qcd+5NQU3kIxcNX
+lO/T8NPn3eBzkWghm8ZpDSm/ql73QslJY2ZIdsUxdX0+YhBZBudgQxJYQ5jQ5I7J
+6NwfJsIaMqNXRz8H9DH6+Jc8vCvd74DiLp2dl7mUHggBeuW1aRpK1MnGAaUJvsgz
+m7iIix9yIJqCNpRnYl0hsdtm8O9pkYF6KiJw0n63nK5O3rBb9Ck=
+=gXbu
+-----END PGP SIGNATURE-----
diff --git a/share/security/patches/EN-20:15/mps.patch b/share/security/patches/EN-20:15/mps.patch
new file mode 100644
index 0000000000..4a6df66229
--- /dev/null
+++ b/share/security/patches/EN-20:15/mps.patch
@@ -0,0 +1,18 @@
+--- sys/dev/mps/mps_user.c.orig
++++ sys/dev/mps/mps_user.c
+@@ -1045,10 +1045,12 @@
+ if (((MPI2_SCSI_IO_REPLY *)rpl)->SCSIState &
+ MPI2_SCSI_STATE_AUTOSENSE_VALID) {
+ sense_len =
+- MIN((le32toh(((MPI2_SCSI_IO_REPLY *)rpl)->SenseCount)),
+- sizeof(struct scsi_sense_data));
++ MIN((le32toh(((MPI2_SCSI_IO_REPLY *)rpl)->
++ SenseCount)), sizeof(struct
++ scsi_sense_data));
+ mps_unlock(sc);
+- copyout(cm->cm_sense, cm->cm_req + 64, sense_len);
++ copyout(cm->cm_sense, (PTRIN(data->PtrReply +
++ sizeof(MPI2_SCSI_IO_REPLY))), sense_len);
+ mps_lock(sc);
+ }
+ }
diff --git a/share/security/patches/EN-20:15/mps.patch.asc b/share/security/patches/EN-20:15/mps.patch.asc
new file mode 100644
index 0000000000..8eff939d62
--- /dev/null
+++ b/share/security/patches/EN-20:15/mps.patch.asc
@@ -0,0 +1,18 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQKTBAABCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAl8GLn5fFIAAAAAALgAo
+aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
+MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
+5cLLmQ/+M8BAUgkejk4cpsJOVpfnRRPol7ap5nUQEU/HnXkkQS9iYMh8tf1gMPh1
+bDG50TfWUR9AyYoN1VQmHbi7fpEefzP2HwcfoNp7sIhI4PIvT2Eep05V+Tciplsc
+vlAMvaHT/kVTDxTMtnmWGU8e64NziJbPMMkTMZiJaU3fQc8o8gAWIA8dtxCD3/21
+XEFV5UEvBVcoAdB1xONM77PeMtKUysOccoVXlZJkscW99o8nUfrI6UZE75aR53KD
++AZbZIHWV6CRHIf/JzZFg7To2gLsi2/bAWPFcXPHzbu9c7z3rka6WmXc8AZCdOPf
+x1yHRzeMb3axbsTOl8Sderew41AWyhwSk58WN+kyWgH5N4UubjOTgS5kZK6rancn
+5H3hq/59n5qIJz2yCVVMg0QSqgh2DwLjxuWJRRg9dfKy6+8FgjIDCrXl4Y20YkI3
+MhpvwPr7nsduiAg/NdHxpTYnN8vXC0PyGgIWbhyJzYvu3nb35gAlGs6HJo4gNId8
+Skc2q8wG059fjG0BbJhsn+n10hzL3N9uienZ+SM7nZdRrhEvxSPGpuzxa7+9lL+C
+RFVMVvdDvgol88FGfxVNxwVQ9s+n4nbwh4JC0YsbP5atvHZnGT+JLpBFgasOkEvA
+/vw+YcCazl2oxOwoq3eXoAkJWkJpn3Xv3eBfxj567k1EDLuGC5I=
+=u0ny
+-----END PGP SIGNATURE-----
diff --git a/share/security/patches/SA-20:18/posix_spawnp.patch b/share/security/patches/SA-20:18/posix_spawnp.patch
new file mode 100644
index 0000000000..1c8a5adcbc
--- /dev/null
+++ b/share/security/patches/SA-20:18/posix_spawnp.patch
@@ -0,0 +1,280 @@
+--- lib/libc/gen/exec.c.orig
++++ lib/libc/gen/exec.c
+@@ -49,6 +49,9 @@
+
+ extern char **environ;
+
++static const char execvPe_err_preamble[] = "execvP: ";
++static const char execvPe_err_trailer[] = ": path too long\n";
++
+ int
+ execl(const char *name, const char *arg, ...)
+ {
+@@ -149,8 +152,8 @@
+ const char **memp;
+ size_t cnt, lp, ln;
+ int eacces, save_errno;
+- char *cur, buf[MAXPATHLEN];
+- const char *p, *bp;
++ char buf[MAXPATHLEN];
++ const char *bp, *np, *op, *p;
+ struct stat sb;
+
+ eacces = 0;
+@@ -158,7 +161,7 @@
+ /* If it's an absolute or relative path name, it's easy. */
+ if (strchr(name, '/')) {
+ bp = name;
+- cur = NULL;
++ op = NULL;
+ goto retry;
+ }
+ bp = buf;
+@@ -169,24 +172,31 @@
+ return (-1);
+ }
+
+- cur = alloca(strlen(path) + 1);
+- if (cur == NULL) {
+- errno = ENOMEM;
+- return (-1);
+- }
+- strcpy(cur, path);
+- while ((p = strsep(&cur, ":")) != NULL) {
++ op = path;
++ ln = strlen(name);
++ while (op != NULL) {
++ np = strchrnul(op, ':');
++
+ /*
+ * It's a SHELL path -- double, leading and trailing colons
+ * mean the current directory.
+ */
+- if (*p == '\0') {
++ if (np == op) {
++ /* Empty component. */
+ p = ".";
+ lp = 1;
+- } else
+- lp = strlen(p);
+- ln = strlen(name);
++ } else {
++ /* Non-empty component. */
++ p = op;
++ lp = np - op;
++ }
+
++ /* Advance to the next component or terminate after this. */
++ if (*np == '\0')
++ op = NULL;
++ else
++ op = np + 1;
++
+ /*
+ * If the path is too long complain. This is a possible
+ * security issue; given a way to make the path too long
+@@ -193,10 +203,11 @@
+ * the user may execute the wrong program.
+ */
+ if (lp + ln + 2 > sizeof(buf)) {
+- (void)_write(STDERR_FILENO, "execvP: ", 8);
++ (void)_write(STDERR_FILENO, execvPe_err_preamble,
++ sizeof(execvPe_err_preamble) - 1);
+ (void)_write(STDERR_FILENO, p, lp);
+- (void)_write(STDERR_FILENO, ": path too long\n",
+- 16);
++ (void)_write(STDERR_FILENO, execvPe_err_trailer,
++ sizeof(execvPe_err_trailer) - 1);
+ continue;
+ }
+ bcopy(p, buf, lp);
+@@ -215,14 +226,28 @@
+ case ENOEXEC:
+ for (cnt = 0; argv[cnt]; ++cnt)
+ ;
+- memp = alloca((cnt + 2) * sizeof(char *));
++
++ /*
++ * cnt may be 0 above; always allocate at least
++ * 3 entries so that we can at least fit "sh", bp, and
++ * the NULL terminator. We can rely on cnt to take into
++ * account the NULL terminator in all other scenarios,
++ * as we drop argv[0].
++ */
++ memp = alloca(MAX(3, cnt + 2) * sizeof(char *));
+ if (memp == NULL) {
+ /* errno = ENOMEM; XXX override ENOEXEC? */
+ goto done;
+ }
+- memp[0] = "sh";
+- memp[1] = bp;
+- bcopy(argv + 1, memp + 2, cnt * sizeof(char *));
++ if (cnt > 0) {
++ memp[0] = argv[0];
++ memp[1] = bp;
++ bcopy(argv + 1, memp + 2, cnt * sizeof(char *));
++ } else {
++ memp[0] = "sh";
++ memp[1] = bp;
++ memp[2] = NULL;
++ }
+ (void)_execve(_PATH_BSHELL,
+ __DECONST(char **, memp), envp);
+ goto done;
+--- lib/libc/gen/posix_spawn.c.orig
++++ lib/libc/gen/posix_spawn.c
+@@ -28,6 +28,7 @@
+ __FBSDID("$FreeBSD$");
+
+ #include "namespace.h"
++#include <sys/param.h>
+ #include <sys/queue.h>
+ #include <sys/wait.h>
+
+@@ -202,8 +203,20 @@
+ volatile int error;
+ };
+
++#define PSPAWN_STACK_ALIGNMENT 16
++#define PSPAWN_STACK_ALIGNBYTES (PSPAWN_STACK_ALIGNMENT - 1)
++#define PSPAWN_STACK_ALIGN(sz) \
++ (((sz) + PSPAWN_STACK_ALIGNBYTES) & ~PSPAWN_STACK_ALIGNBYTES)
++
+ #if defined(__i386__) || defined(__amd64__)
++/*
++ * Below we'll assume that _RFORK_THREAD_STACK_SIZE is appropriately aligned for
++ * the posix_spawn() case where we do not end up calling _execvpe and won't ever
++ * try to allocate space on the stack for argv[].
++ */
+ #define _RFORK_THREAD_STACK_SIZE 4096
++_Static_assert((_RFORK_THREAD_STACK_SIZE % PSPAWN_STACK_ALIGNMENT) == 0,
++ "Inappropriate stack size alignment");
+ #endif
+
+ static int
+@@ -244,10 +257,36 @@
+ pid_t p;
+ #ifdef _RFORK_THREAD_STACK_SIZE
+ char *stack;
++ size_t cnt, stacksz;
+
+- stack = malloc(_RFORK_THREAD_STACK_SIZE);
++ stacksz = _RFORK_THREAD_STACK_SIZE;
++ if (use_env_path) {
++ /*
++ * We need to make sure we have enough room on the stack for the
++ * potential alloca() in execvPe if it gets kicked back an
++ * ENOEXEC from execve(2), plus the original buffer we gave
++ * ourselves; this protects us in the event that the caller
++ * intentionally or inadvertently supplies enough arguments to
++ * make us blow past the stack we've allocated from it.
++ */
++ for (cnt = 0; argv[cnt] != NULL; ++cnt)
++ ;
++ stacksz += MAX(3, cnt + 2) * sizeof(char *);
++ stacksz = PSPAWN_STACK_ALIGN(stacksz);
++ }
++
++ /*
++ * aligned_alloc is not safe to use here, because we can't guarantee
++ * that aligned_alloc and free will be provided by the same
++ * implementation. We've actively hit at least one application that
++ * will provide its own malloc/free but not aligned_alloc leading to
++ * a free by the wrong allocator.
++ */
++ stack = malloc(stacksz);
+ if (stack == NULL)
+ return (ENOMEM);
++ stacksz = (((uintptr_t)stack + stacksz) & ~PSPAWN_STACK_ALIGNBYTES) -
++ (uintptr_t)stack;
+ #endif
+ psa.path = path;
+ psa.fa = fa;
+@@ -271,8 +310,7 @@
+ * parent. Because of this, we must use rfork_thread instead while
+ * almost every other arch stores the return address in a register.
+ */
+- p = rfork_thread(RFSPAWN, stack + _RFORK_THREAD_STACK_SIZE,
+- _posix_spawn_thr, &psa);
++ p = rfork_thread(RFSPAWN, stack + stacksz, _posix_spawn_thr, &psa);
+ free(stack);
+ #else
+ p = rfork(RFSPAWN);
+--- lib/libc/tests/gen/Makefile.orig
++++ lib/libc/tests/gen/Makefile
+@@ -20,6 +20,15 @@
+ # TODO: t_siginfo (fixes require further inspection)
+ # TODO: t_sethostname_test (consistently screws up the hostname)
+
++FILESGROUPS+= posix_spawn_test_FILES
++
++posix_spawn_test_FILES= spawnp_enoexec.sh
++posix_spawn_test_FILESDIR= ${TESTSDIR}
++posix_spawn_test_FILESMODE= 0755
++posix_spawn_test_FILESOWN= root
++posix_spawn_test_FILESGRP= wheel
++posix_spawn_test_FILESPACKAGE= ${PACKAGE}
++
+ CFLAGS+= -DTEST_LONG_DOUBLE
+
+ # Not sure why this isn't defined for all architectures, since most
+--- lib/libc/tests/gen/posix_spawn_test.c.orig
++++ lib/libc/tests/gen/posix_spawn_test.c
+@@ -93,11 +93,50 @@
+ }
+ }
+
++ATF_TC_WITHOUT_HEAD(posix_spawnp_enoexec_fallback);
++ATF_TC_BODY(posix_spawnp_enoexec_fallback, tc)
++{
++ char buf[FILENAME_MAX];
++ char *myargs[2];
++ int error, status;
++ pid_t pid, waitres;
++
++ snprintf(buf, sizeof(buf), "%s/spawnp_enoexec.sh",
++ atf_tc_get_config_var(tc, "srcdir"));
++ myargs[0] = buf;
++ myargs[1] = NULL;
++ error = posix_spawnp(&pid, myargs[0], NULL, NULL, myargs, myenv);
++ ATF_REQUIRE(error == 0);
++ waitres = waitpid(pid, &status, 0);
++ ATF_REQUIRE(waitres == pid);
++ ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == 42);
++}
++
++ATF_TC_WITHOUT_HEAD(posix_spawnp_enoexec_fallback_null_argv0);
++ATF_TC_BODY(posix_spawnp_enoexec_fallback_null_argv0, tc)
++{
++ char buf[FILENAME_MAX];
++ char *myargs[1];
++ int error, status;
++ pid_t pid, waitres;
++
++ snprintf(buf, sizeof(buf), "%s/spawnp_enoexec.sh",
++ atf_tc_get_config_var(tc, "srcdir"));
++ myargs[0] = NULL;
++ error = posix_spawnp(&pid, buf, NULL, NULL, myargs, myenv);
++ ATF_REQUIRE(error == 0);
++ waitres = waitpid(pid, &status, 0);
++ ATF_REQUIRE(waitres == pid);
++ ATF_REQUIRE(WIFEXITED(status) && WEXITSTATUS(status) == 42);
++}
++
+ ATF_TP_ADD_TCS(tp)
+ {
+
+ ATF_TP_ADD_TC(tp, posix_spawn_simple_test);
+ ATF_TP_ADD_TC(tp, posix_spawn_no_such_command_negative_test);
++ ATF_TP_ADD_TC(tp, posix_spawnp_enoexec_fallback);
++ ATF_TP_ADD_TC(tp, posix_spawnp_enoexec_fallback_null_argv0);
+
+ return (atf_no_error());
+ }
+--- lib/libc/tests/gen/spawnp_enoexec.sh.orig
++++ lib/libc/tests/gen/spawnp_enoexec.sh
+@@ -0,0 +1,4 @@
++# $FreeBSD$
++# Intentionally no interpreter
++
++exit 42
diff --git a/share/security/patches/SA-20:18/posix_spawnp.patch.asc b/share/security/patches/SA-20:18/posix_spawnp.patch.asc
new file mode 100644
index 0000000000..414ba01945
--- /dev/null
+++ b/share/security/patches/SA-20:18/posix_spawnp.patch.asc
@@ -0,0 +1,18 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQKTBAABCgB9FiEE/A6HiuWv54gCjWNV05eS9J6n5cIFAl8GLolfFIAAAAAALgAo
+aXNzdWVyLWZwckBub3RhdGlvbnMub3BlbnBncC5maWZ0aGhvcnNlbWFuLm5ldEZD
+MEU4NzhBRTVBRkU3ODgwMjhENjM1NUQzOTc5MkY0OUVBN0U1QzIACgkQ05eS9J6n
+5cKQYhAAnw5pU+TxqHv7BT4v6lXqIAnJhYpoD3TlcbEfqYErN+rYb6PB7c1tuKTR
+/+4YCM4SZVXtHmaL1VkHqQUpWL7hTMLdaGKT3kkycETESZEednEs9A/IPHZ7ooLv
+ZdsK4/PdVac2DxaHN5suENB3054Hmm8TIHTxcEyac1rLGsYpMzo9iA5PzE3imNWH
+hCI7dV8cdFJ20wS+Zq2HsbjxYbXtZ5su0whn+ziQx3ObfMbfC19fKSRL8/oI7MFc
+qASSEj3Aw5bprDLR85fukZNpg2iIxkf4gJ3Yw47BuQ6I/fid52sDhuBcMRKJArHe
+LIK5mhy+NcwOOZH3At1PjGpbjPUU8SUonbeHKAqzcDVC6UtOK88tqYT9cm3qLNR1
+3+aznvpM6R74QZku6kGuYEN6b4iTXsL2BWaGQBNV/KVq2H4qJMqPaYpjJp7yiCj7
+LV3DN+ugYiWuE//llmhDW+WImqdMJ3FALkcwYMvvz3mOEc33B68A/d0t/jU9xUpY
+gStzI7Ze/hI54wvpPg+plTtqTrPAAqwN1uBUfBuboQ5XjZsURGeqE6jZJOIOuQR2
+r6tTb/wYnM0a69YcZKaePdvsNE4bJlsZ7+NbjRcSjJzHPLiFVdGwhYQZjYgfeqP5
+tqt/PuawGkwz08rtfQ7T6BoHoB7/oQzbYNaVlzy8UckwXI41EMM=
+=x3mt
+-----END PGP SIGNATURE-----
diff --git a/share/security/patches/SA-20:19/unbound.11.3.patch b/share/security/patches/SA-20:19/unbound.11.3.patch
new file mode 100644
index 0000000000..60455c2b29
--- /dev/null
+++ b/share/security/patches/SA-20:19/unbound.11.3.patch
@@ -0,0 +1,85204 @@
+--- ObsoleteFiles.inc.orig
++++ ObsoleteFiles.inc
+@@ -474,6 +474,16 @@
+ OLD_FILES+=usr/share/dtrace/watch_execve
+ OLD_FILES+=usr/share/dtrace/watch_kill
+ OLD_FILES+=usr/share/dtrace/watch_vop_remove
++# 20180512: Rename Unbound tools
++OLD_FILES+=usr/sbin/unbound
++OLD_FILES+=usr/sbin/unbound-anchor
++OLD_FILES+=usr/sbin/unbound-checkconf
++OLD_FILES+=usr/sbin/unbound-control
++OLD_FILES+=usr/share/man/man5/unbound.conf.5.gz
++OLD_FILES+=usr/share/man/man8/unbound-anchor.8.gz
++OLD_FILES+=usr/share/man/man8/unbound-checkconf.8.gz
++OLD_FILES+=usr/share/man/man8/unbound-control.8.gz
++OLD_FILES+=usr/share/man/man8/unbound.8.gz
+ # 20180331: new clang import which bumps version from 5.0.1 to 6.0.0.
+ OLD_FILES+=usr/lib/clang/5.0.1/include/sanitizer/allocator_interface.h
+ OLD_FILES+=usr/lib/clang/5.0.1/include/sanitizer/asan_interface.h
+--- contrib/unbound/.gitattributes.orig
++++ contrib/unbound/.gitattributes
+@@ -0,0 +1 @@
++testdata/*.[0-9] linguist-documentation
+--- contrib/unbound/.github/FUNDING.yml.orig
++++ contrib/unbound/.github/FUNDING.yml
+@@ -0,0 +1,12 @@
++# These are supported funding model platforms
++
++github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
++patreon: # Replace with a single Patreon username
++open_collective: # Replace with a single Open Collective username
++ko_fi: # Replace with a single Ko-fi username
++tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
++community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
++liberapay: # Replace with a single Liberapay username
++issuehunt: # Replace with a single IssueHunt username
++otechie: # Replace with a single Otechie username
++custom: ['https://nlnetlabs.nl/funding/']
+--- contrib/unbound/.travis.yml.orig
++++ contrib/unbound/.travis.yml
+@@ -0,0 +1,16 @@
++sudo: false
++language: c
++compiler:
++ - gcc
++addons:
++ apt:
++ packages:
++ - libssl-dev
++ - libevent-dev
++ - libexpat-dev
++ - clang
++script:
++ - ./configure --enable-debug --disable-flto
++ - make
++ - make test
++ - (cd testdata/clang-analysis.tdir; bash clang-analysis.test)
+--- contrib/unbound/Makefile.in.orig
++++ contrib/unbound/Makefile.in
+@@ -23,6 +23,8 @@
+ CHECKLOCK_OBJ=@CHECKLOCK_OBJ@
+ DNSTAP_SRC=@DNSTAP_SRC@
+ DNSTAP_OBJ=@DNSTAP_OBJ@
++DNSCRYPT_SRC=@DNSCRYPT_SRC@
++DNSCRYPT_OBJ=@DNSCRYPT_OBJ@
+ WITH_PYTHONMODULE=@WITH_PYTHONMODULE@
+ WITH_PYUNBOUND=@WITH_PYUNBOUND@
+ PY_MAJOR_VERSION=@PY_MAJOR_VERSION@
+@@ -55,7 +57,7 @@
+ CC=@CC@
+ CPPFLAGS=-I. @CPPFLAGS@
+ PYTHON_CPPFLAGS=-I. @PYTHON_CPPFLAGS@
+-CFLAGS=@CFLAGS@
++CFLAGS=-DSRCDIR=$(srcdir) @CFLAGS@
+ LDFLAGS=@LDFLAGS@
+ LIBS=@LIBS@
+ LIBOBJS=@LIBOBJS@
+@@ -81,7 +83,7 @@
+ # compat with OpenBSD
+ LINTFLAGS+="-Dsigset_t=long"
+ # FreeBSD
+-LINTFLAGS+="-D__uint16_t=uint16_t" "-DEVP_PKEY_ASN1_METHOD=int" "-D_RuneLocale=int" "-D__va_list=va_list" "-D__uint32_t=uint32_t"
++LINTFLAGS+="-D__uint16_t=uint16_t" "-DEVP_PKEY_ASN1_METHOD=int" "-D_RuneLocale=int" "-D__va_list=va_list" "-D__uint32_t=uint32_t" "-D_Alignof(x)=x" "-D__aligned(x)=" "-D__requires_exclusive(x)=" "-D__requires_unlocked(x)=" "-D__locks_exclusive(x)=" "-D__trylocks_exclusive(x)=" "-D__unlocks(x)=" "-D__locks_shared(x)=" "-D__trylocks_shared(x)="
+
+ INSTALL=$(SHELL) $(srcdir)/install-sh
+
+@@ -95,6 +97,12 @@
+ PYUNBOUND_SRC=
+ # libunbound_wrap.lo if python libunbound wrapper enabled.
+ PYUNBOUND_OBJ=@PYUNBOUND_OBJ@
++SUBNET_SRC=edns-subnet/edns-subnet.c edns-subnet/subnetmod.c edns-subnet/addrtree.c edns-subnet/subnet-whitelist.c
++SUBNET_OBJ=@SUBNET_OBJ@
++SUBNET_HEADER=@SUBNET_HEADER@
++IPSECMOD_SRC=ipsecmod/ipsecmod.c ipsecmod/ipsecmod-whitelist.c
++IPSECMOD_OBJ=@IPSECMOD_OBJ@
++IPSECMOD_HEADER=@IPSECMOD_HEADER@
+ COMMON_SRC=services/cache/dns.c services/cache/infra.c services/cache/rrset.c \
+ util/as112.c util/data/dname.c util/data/msgencode.c util/data/msgparse.c \
+ util/data/msgreply.c util/data/packed_rrset.c iterator/iterator.c \
+@@ -101,30 +109,38 @@
+ iterator/iter_delegpt.c iterator/iter_donotq.c iterator/iter_fwd.c \
+ iterator/iter_hints.c iterator/iter_priv.c iterator/iter_resptype.c \
+ iterator/iter_scrub.c iterator/iter_utils.c services/listen_dnsport.c \
+-services/localzone.c services/mesh.c services/modstack.c \
++services/localzone.c services/mesh.c services/modstack.c services/view.c \
++services/rpz.c \
+ services/outbound_list.c services/outside_network.c util/alloc.c \
+ util/config_file.c util/configlexer.c util/configparser.c \
++util/shm_side/shm_main.c services/authzone.c \
+ util/fptr_wlist.c util/locks.c util/log.c util/mini_event.c util/module.c \
+ util/netevent.c util/net_help.c util/random.c util/rbtree.c util/regional.c \
+-util/rtt.c util/storage/dnstree.c util/storage/lookup3.c \
+-util/storage/lruhash.c util/storage/slabhash.c util/timehist.c util/tube.c \
++util/rtt.c util/edns.c util/storage/dnstree.c util/storage/lookup3.c \
++util/storage/lruhash.c util/storage/slabhash.c util/tcp_conn_limit.c \
++util/timehist.c util/tube.c \
+ util/ub_event.c util/ub_event_pluggable.c util/winsock_event.c \
+ validator/autotrust.c validator/val_anchor.c validator/validator.c \
+ validator/val_kcache.c validator/val_kentry.c validator/val_neg.c \
+ validator/val_nsec3.c validator/val_nsec.c validator/val_secalgo.c \
+-validator/val_sigcrypt.c validator/val_utils.c dns64/dns64.c cachedb/cachedb.c $(CHECKLOCK_SRC) \
+-$(DNSTAP_SRC)
++validator/val_sigcrypt.c validator/val_utils.c dns64/dns64.c \
++edns-subnet/edns-subnet.c edns-subnet/subnetmod.c \
++edns-subnet/addrtree.c edns-subnet/subnet-whitelist.c \
++cachedb/cachedb.c cachedb/redis.c respip/respip.c $(CHECKLOCK_SRC) \
++$(DNSTAP_SRC) $(DNSCRYPT_SRC) $(IPSECMOD_SRC) $(IPSET_SRC)
+ COMMON_OBJ_WITHOUT_NETCALL=dns.lo infra.lo rrset.lo dname.lo msgencode.lo \
+ as112.lo msgparse.lo msgreply.lo packed_rrset.lo iterator.lo iter_delegpt.lo \
+ iter_donotq.lo iter_fwd.lo iter_hints.lo iter_priv.lo iter_resptype.lo \
+-iter_scrub.lo iter_utils.lo localzone.lo mesh.lo modstack.lo \
++iter_scrub.lo iter_utils.lo localzone.lo mesh.lo modstack.lo view.lo \
+ outbound_list.lo alloc.lo config_file.lo configlexer.lo configparser.lo \
+-fptr_wlist.lo locks.lo log.lo mini_event.lo module.lo net_help.lo \
++fptr_wlist.lo edns.lo locks.lo log.lo mini_event.lo module.lo net_help.lo \
+ random.lo rbtree.lo regional.lo rtt.lo dnstree.lo lookup3.lo lruhash.lo \
+-slabhash.lo timehist.lo tube.lo winsock_event.lo autotrust.lo val_anchor.lo \
++slabhash.lo tcp_conn_limit.lo timehist.lo tube.lo winsock_event.lo \
++autotrust.lo val_anchor.lo rpz.lo \
+ validator.lo val_kcache.lo val_kentry.lo val_neg.lo val_nsec3.lo val_nsec.lo \
+-val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo cachedb.lo \
+-$(PYTHONMOD_OBJ) $(CHECKLOCK_OBJ) $(DNSTAP_OBJ)
++val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo cachedb.lo redis.lo authzone.lo \
++$(SUBNET_OBJ) $(PYTHONMOD_OBJ) $(CHECKLOCK_OBJ) $(DNSTAP_OBJ) $(DNSCRYPT_OBJ) \
++$(IPSECMOD_OBJ) $(IPSET_OBJ) respip.lo
+ COMMON_OBJ_WITHOUT_UB_EVENT=$(COMMON_OBJ_WITHOUT_NETCALL) netevent.lo listen_dnsport.lo \
+ outside_network.lo
+ COMMON_OBJ=$(COMMON_OBJ_WITHOUT_UB_EVENT) ub_event.lo
+@@ -133,7 +149,7 @@
+ COMPAT_SRC=compat/ctime_r.c compat/fake-rfc2553.c compat/gmtime_r.c \
+ compat/inet_aton.c compat/inet_ntop.c compat/inet_pton.c compat/malloc.c \
+ compat/memcmp.c compat/memmove.c compat/snprintf.c compat/strlcat.c \
+-compat/strlcpy.c compat/strptime.c compat/getentropy_linux.c \
++compat/strlcpy.c compat/strptime.c compat/getentropy_freebsd.c compat/getentropy_linux.c \
+ compat/getentropy_osx.c compat/getentropy_solaris.c compat/getentropy_win.c \
+ compat/explicit_bzero.c compat/arc4random.c compat/arc4random_uniform.c \
+ compat/arc4_lock.c compat/sha512.c compat/reallocarray.c compat/isblank.c \
+@@ -145,18 +161,21 @@
+ sldns/parseutil.c sldns/rrdef.c sldns/str2wire.c
+ SLDNS_OBJ=keyraw.lo sbuffer.lo wire2str.lo parse.lo parseutil.lo rrdef.lo \
+ str2wire.lo
++SLDNS_ALLOCCHECK_EXTRA_OBJ=@SLDNS_ALLOCCHECK_EXTRA_OBJ@
+ UNITTEST_SRC=testcode/unitanchor.c testcode/unitdname.c \
+ testcode/unitlruhash.c testcode/unitmain.c testcode/unitmsgparse.c \
+ testcode/unitneg.c testcode/unitregional.c testcode/unitslabhash.c \
+-testcode/unitverify.c testcode/readhex.c testcode/testpkts.c testcode/unitldns.c
++testcode/unitverify.c testcode/readhex.c testcode/testpkts.c testcode/unitldns.c \
++testcode/unitecs.c testcode/unitauth.c
+ UNITTEST_OBJ=unitanchor.lo unitdname.lo unitlruhash.lo unitmain.lo \
+ unitmsgparse.lo unitneg.lo unitregional.lo unitslabhash.lo unitverify.lo \
+-readhex.lo testpkts.lo unitldns.lo
++readhex.lo testpkts.lo unitldns.lo unitecs.lo unitauth.lo
+ UNITTEST_OBJ_LINK=$(UNITTEST_OBJ) worker_cb.lo $(COMMON_OBJ) $(SLDNS_OBJ) \
+ $(COMPAT_OBJ)
+ DAEMON_SRC=daemon/acl_list.c daemon/cachedump.c daemon/daemon.c \
+ daemon/remote.c daemon/stats.c daemon/unbound.c daemon/worker.c @WIN_DAEMON_SRC@
+-DAEMON_OBJ=acl_list.lo cachedump.lo daemon.lo remote.lo stats.lo unbound.lo \
++DAEMON_OBJ=acl_list.lo cachedump.lo daemon.lo \
++shm_main.lo remote.lo stats.lo unbound.lo \
+ worker.lo @WIN_DAEMON_OBJ@
+ DAEMON_OBJ_LINK=$(DAEMON_OBJ) $(COMMON_OBJ_ALL_SYMBOLS) $(SLDNS_OBJ) \
+ $(COMPAT_OBJ) @WIN_DAEMON_OBJ_LINK@
+@@ -170,17 +189,18 @@
+ $(SLDNS_OBJ) $(COMPAT_OBJ) @WIN_CONTROL_OBJ_LINK@
+ HOST_SRC=smallapp/unbound-host.c
+ HOST_OBJ=unbound-host.lo
+-HOST_OBJ_LINK=$(HOST_OBJ) $(SLDNS_OBJ) $(COMPAT_OBJ_WITHOUT_CTIMEARC4) @WIN_HOST_OBJ_LINK@
++HOST_OBJ_LINK=$(HOST_OBJ) $(SLDNS_OBJ) $(COMPAT_OBJ_WITHOUT_CTIMEARC4) $(SLDNS_ALLOCCHECK_EXTRA_OBJ) @WIN_HOST_OBJ_LINK@
+ UBANCHOR_SRC=smallapp/unbound-anchor.c
+ UBANCHOR_OBJ=unbound-anchor.lo
+ UBANCHOR_OBJ_LINK=$(UBANCHOR_OBJ) parseutil.lo \
+-$(COMPAT_OBJ_WITHOUT_CTIME) @WIN_UBANCHOR_OBJ_LINK@
++$(COMPAT_OBJ_WITHOUT_CTIME) $(SLDNS_ALLOCCHECK_EXTRA_OBJ) @WIN_UBANCHOR_OBJ_LINK@
+ TESTBOUND_SRC=testcode/testbound.c testcode/testpkts.c \
+-daemon/worker.c daemon/acl_list.c daemon/daemon.c daemon/stats.c \
++daemon/worker.c daemon/acl_list.c \
++daemon/daemon.c daemon/stats.c \
+ testcode/replay.c testcode/fake_event.c
+ TESTBOUND_OBJ=testbound.lo replay.lo fake_event.lo
+ TESTBOUND_OBJ_LINK=$(TESTBOUND_OBJ) testpkts.lo worker.lo acl_list.lo \
+-daemon.lo stats.lo $(COMMON_OBJ_WITHOUT_NETCALL) ub_event.lo $(SLDNS_OBJ) \
++daemon.lo stats.lo shm_main.lo $(COMMON_OBJ_WITHOUT_NETCALL) ub_event.lo $(SLDNS_OBJ) \
+ $(COMPAT_OBJ)
+ LOCKVERIFY_SRC=testcode/lock_verify.c
+ LOCKVERIFY_OBJ=lock_verify.lo
+@@ -199,7 +219,7 @@
+ $(SLDNS_OBJ)
+ ASYNCLOOK_SRC=testcode/asynclook.c
+ ASYNCLOOK_OBJ=asynclook.lo
+-ASYNCLOOK_OBJ_LINK=$(ASYNCLOOK_OBJ) log.lo locks.lo $(COMPAT_OBJ)
++ASYNCLOOK_OBJ_LINK=$(ASYNCLOOK_OBJ) log.lo locks.lo $(COMPAT_OBJ) @ASYNCLOOK_ALLOCCHECK_EXTRA_OBJ@
+ STREAMTCP_SRC=testcode/streamtcp.c
+ STREAMTCP_OBJ=streamtcp.lo
+ STREAMTCP_OBJ_LINK=$(STREAMTCP_OBJ) worker_cb.lo $(COMMON_OBJ) $(COMPAT_OBJ) \
+@@ -211,6 +231,8 @@
+ DELAYER_OBJ=delayer.lo
+ DELAYER_OBJ_LINK=$(DELAYER_OBJ) worker_cb.lo $(COMMON_OBJ) $(COMPAT_OBJ) \
+ $(SLDNS_OBJ)
++IPSET_SRC=@IPSET_SRC@
++IPSET_OBJ=@IPSET_OBJ@
+ LIBUNBOUND_SRC=libunbound/context.c libunbound/libunbound.c \
+ libunbound/libworker.c
+ LIBUNBOUND_OBJ=context.lo libunbound.lo libworker.lo ub_event_pluggable.lo
+@@ -238,8 +260,9 @@
+ $(MEMSTATS_SRC) $(CHECKCONF_SRC) $(LIBUNBOUND_SRC) $(HOST_SRC) \
+ $(ASYNCLOOK_SRC) $(STREAMTCP_SRC) $(PERF_SRC) $(DELAYER_SRC) \
+ $(CONTROL_SRC) $(UBANCHOR_SRC) $(PETAL_SRC) \
+- $(PYTHONMOD_SRC) $(PYUNBOUND_SRC) $(WIN_DAEMON_THE_SRC)\
++ $(PYTHONMOD_SRC) $(PYUNBOUND_SRC) $(WIN_DAEMON_THE_SRC) \
+ $(SVCINST_SRC) $(SVCUNINST_SRC) $(ANCHORUPD_SRC) $(SLDNS_SRC)
++
+ ALL_OBJ=$(COMMON_OBJ) $(UNITTEST_OBJ) $(DAEMON_OBJ) \
+ $(TESTBOUND_OBJ) $(LOCKVERIFY_OBJ) $(PKTVIEW_OBJ) \
+ $(MEMSTATS_OBJ) $(CHECKCONF_OBJ) $(LIBUNBOUND_OBJ) $(HOST_OBJ) \
+@@ -250,7 +273,7 @@
+
+ COMPILE=$(LIBTOOL) --tag=CC --mode=compile $(CC) $(CPPFLAGS) $(CFLAGS) @PTHREAD_CFLAGS_ONLY@
+ LINK=$(LIBTOOL) --tag=CC --mode=link $(CC) $(staticexe) $(RUNTIME_PATH) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS)
+-LINK_LIB=$(LIBTOOL) --tag=CC --mode=link $(CC) $(RUNTIME_PATH) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(staticexe) -version-info @LIBUNBOUND_CURRENT@:@LIBUNBOUND_REVISION@:@LIBUNBOUND_AGE@ -no-undefined
++LINK_LIB=$(LIBTOOL) --tag=CC --mode=link $(CC) $(RUNTIME_PATH) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -version-info @LIBUNBOUND_CURRENT@:@LIBUNBOUND_REVISION@:@LIBUNBOUND_AGE@ -no-undefined
+
+ .PHONY: clean realclean doc lint all install uninstall tests test strip lib longtest longcheck check alltargets
+
+@@ -292,10 +315,11 @@
+ test: unittest$(EXEEXT) testbound$(EXEEXT)
+ ./unittest$(EXEEXT)
+ ./testbound$(EXEEXT) -s
+- for x in testdata/*.rpl; do echo -n "$$x "; if ./testbound$(EXEEXT) -p $$x >/dev/null 2>&1; then echo OK; else echo failed; exit 1; fi done
++ for x in $(srcdir)/testdata/*.rpl; do echo -n "$$x "; if ./testbound$(EXEEXT) -p $$x >/dev/null 2>&1; then echo OK; else echo failed; exit 1; fi done
+ @echo test OK
+
+ longtest: tests
++ if test ! $(srcdir)/testdata -ef ./testdata; then rm -rf testcode testdata; mkdir testcode testdata; cp -R $(srcdir)/testdata/*.sh $(srcdir)/testdata/*.tdir $(srcdir)/testdata/*.rpl $(srcdir)/testdata/*.crpl testdata; cp $(srcdir)/testcode/*.sh testcode; if test ! -d util; then mkdir util; fi; cp $(srcdir)/util/iana_ports.inc util; fi
+ if test -x "`which bash`"; then bash testcode/do-tests.sh; else sh testcode/do-tests.sh; fi
+
+ lib: libunbound.la unbound.h
+@@ -313,7 +337,7 @@
+ $(LINK) -o $@ $(CONTROL_OBJ_LINK) $(EXTRALINK) $(SSLLIB) $(LIBS)
+
+ unbound-host$(EXEEXT): $(HOST_OBJ_LINK) libunbound.la
+- $(LINK) -o $@ $(HOST_OBJ_LINK) -L. -L.libs -lunbound $(LIBS)
++ $(LINK) -o $@ $(HOST_OBJ_LINK) -L. -L.libs -lunbound $(SSLLIB) $(LIBS)
+
+ unbound-anchor$(EXEEXT): $(UBANCHOR_OBJ_LINK) libunbound.la
+ $(LINK) -o $@ $(UBANCHOR_OBJ_LINK) -L. -L.libs -lunbound -lexpat $(SSLLIB) $(LIBS)
+@@ -346,7 +370,7 @@
+ $(LINK) -o $@ $(MEMSTATS_OBJ_LINK) $(SSLLIB) $(LIBS)
+
+ asynclook$(EXEEXT): $(ASYNCLOOK_OBJ_LINK) libunbound.la
+- $(LINK) -o $@ $(ASYNCLOOK_OBJ_LINK) $(LIBS) -L. -L.libs -lunbound
++ $(LINK) -o $@ $(ASYNCLOOK_OBJ_LINK) -L. -L.libs -lunbound $(SSLLIB) $(LIBS)
+
+ streamtcp$(EXEEXT): $(STREAMTCP_OBJ_LINK)
+ $(LINK) -o $@ $(STREAMTCP_OBJ_LINK) $(SSLLIB) $(LIBS)
+@@ -375,10 +399,17 @@
+
+ dnstap/dnstap.pb-c.c dnstap/dnstap.pb-c.h: $(srcdir)/dnstap/dnstap.proto
+ @-if test ! -d dnstap; then $(INSTALL) -d dnstap; fi
+- $(PROTOC_C) --c_out=. $(srcdir)/dnstap/dnstap.proto
++ $(PROTOC_C) --c_out=. --proto_path=$(srcdir) $(srcdir)/dnstap/dnstap.proto
+
+ dnstap.pb-c.lo dnstap.pb-c.o: dnstap/dnstap.pb-c.c dnstap/dnstap.pb-c.h
+
++# dnscrypt
++dnscrypt.lo dnscrypt.o: $(srcdir)/dnscrypt/dnscrypt.c config.h \
++ dnscrypt/dnscrypt_config.h \
++ $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/dnscrypt/cert.h \
++ $(srcdir)/util/config_file.h $(srcdir)/util/log.h \
++ $(srcdir)/util/netevent.h
++
+ # Python Module
+ pythonmod.lo pythonmod.o: $(srcdir)/pythonmod/pythonmod.c config.h \
+ pythonmod/interface.h \
+@@ -404,7 +435,7 @@
+
+ # Pyunbound python unbound wrapper
+ _unbound.la: libunbound_wrap.lo libunbound.la
+- $(LIBTOOL) --tag=CC --mode=link $(CC) $(RUNTIME_PATH) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -module -avoid-version -no-undefined -shared -o $@ libunbound_wrap.lo -rpath $(PYTHON_SITE_PKG) L. -L.libs -lunbound
++ $(LIBTOOL) --tag=CC --mode=link $(CC) $(RUNTIME_PATH) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -module -avoid-version -no-undefined -shared -o $@ libunbound_wrap.lo -rpath $(PYTHON_SITE_PKG) -L. -L.libs -lunbound
+
+ util/config_file.c: util/configparser.h
+ util/configlexer.c: $(srcdir)/util/configlexer.lex util/configparser.h
+@@ -426,14 +457,19 @@
+ rm -f _unbound.la libunbound/python/libunbound_wrap.c libunbound/python/unbound.py pythonmod/interface.h pythonmod/unboundmodule.py
+ rm -rf autom4te.cache .libs build doc/html doc/xml
+
+-realclean: clean
+- rm -f config.status config.log config.h.in config.h
+- rm -f configure config.sub config.guess ltmain.sh aclocal.m4 libtool
+- rm -f util/configlexer.c util/configparser.c util/configparser.h
+- rm -f doc/example.conf doc/libunbound.3 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound-control.8 doc/unbound.8 doc/unbound.conf.5
++distclean: clean
++ rm -f config.status config.log config.h
++ rm -f doc/example.conf doc/libunbound.3 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound-control.8 doc/unbound.8 doc/unbound.conf.5 doc/unbound-host.1
++ rm -f smallapp/unbound-control-setup.sh dnstap/dnstap_config.h dnscrypt/dnscrypt_config.h contrib/libunbound.pc contrib/unbound.socket contrib/unbound.service
+ rm -f $(TEST_BIN)
+ rm -f Makefile
+
++maintainer-clean: distclean
++ rm -f util/configlexer.c util/configparser.c util/configparser.h
++
++realclean: maintainer-clean
++ rm -f configure config.h.in config.sub config.guess ltmain.sh aclocal.m4 libtool
++
+ .SUFFIXES: .lint
+ .c.lint:
+ $(LINT) $(LINTFLAGS) -I. -I$(srcdir) $<
+@@ -456,9 +492,9 @@
+ if test -n "$(doxygen)"; then \
+ $(doxygen) $(srcdir)/doc/unbound.doxygen; fi
+ if test "$(WITH_PYUNBOUND)" = "yes" -o "$(WITH_PYTHONMODULE)" = "yes"; \
+- then if test -x "`which sphinx-build 2>&1`"; then \
+- sphinx-build -b html pythonmod/doc doc/html/pythonmod; \
+- sphinx-build -b html libunbound/python/doc doc/html/pyunbound;\
++ then if test -x "`which sphinx-build-$(PY_MAJOR_VERSION) 2>&1`"; then \
++ sphinx-build-$(PY_MAJOR_VERSION) -b html pythonmod/doc doc/html/pythonmod; \
++ sphinx-build-$(PY_MAJOR_VERSION) -b html libunbound/python/doc doc/html/pyunbound;\
+ fi ;\
+ fi
+
+@@ -511,6 +547,8 @@
+ $(INSTALL) -m 755 -d $(DESTDIR)$(mandir)/man8
+ $(INSTALL) -m 755 -d $(DESTDIR)$(mandir)/man5
+ $(INSTALL) -m 755 -d $(DESTDIR)$(mandir)/man1
++ $(INSTALL) -m 755 -d $(DESTDIR)$(libdir)/pkgconfig
++ $(INSTALL) -m 644 contrib/libunbound.pc $(DESTDIR)$(libdir)/pkgconfig
+ $(LIBTOOL) --mode=install cp -f unbound$(EXEEXT) $(DESTDIR)$(sbindir)/unbound$(EXEEXT)
+ $(LIBTOOL) --mode=install cp -f unbound-checkconf$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-checkconf$(EXEEXT)
+ $(LIBTOOL) --mode=install cp -f unbound-control$(EXEEXT) $(DESTDIR)$(sbindir)/unbound-control$(EXEEXT)
+@@ -564,7 +602,7 @@
+ DEPEND_TMP=depend1073.tmp
+ DEPEND_TMP2=depend1074.tmp
+ DEPEND_TARGET=Makefile
+-DEPEND_TARGET2=Makefile.in
++DEPEND_TARGET2=$(srcdir)/Makefile.in
+ # actions: generate deplines from gcc,
+ # then, filter out home/xx, /usr/xx and /opt/xx lines (some cc already do this)
+ # then, remove empty " \" lines
+@@ -572,7 +610,8 @@
+ # then, remove srcdir from the (generated) parser and lexer.
+ # and mention the .lo
+ depend:
+- (cd $(srcdir) ; $(CC) $(DEPFLAG) $(CPPFLAGS) $(CFLAGS) @PTHREAD_CFLAGS_ONLY@ $(ALL_SRC) $(COMPAT_SRC)) | \
++ (BUILDDIR=$$PWD; cd $(srcdir) ; $(CC) $(DEPFLAG) $(CPPFLAGS) $(CFLAGS) -I$$BUILDDIR @PTHREAD_CFLAGS_ONLY@ $(ALL_SRC) $(COMPAT_SRC)) | \
++ sed -e 's?'$$PWD'/config.h?config.h?g' | \
+ sed -e 's!'$$HOME'[^ ]* !!g' -e 's!'$$HOME'[^ ]*$$!!g' \
+ -e 's!/usr[^ ]* !!g' -e 's!/usr[^ ]*$$!!g' \
+ -e 's!/opt[^ ]* !!g' -e 's!/opt[^ ]*$$!!g' | \
+@@ -584,7 +623,12 @@
+ -e 's?$$(srcdir)/util/configparser.c?util/configparser.c?g' \
+ -e 's?$$(srcdir)/util/configparser.h?util/configparser.h?g' \
+ -e 's?$$(srcdir)/dnstap/dnstap_config.h??g' \
++ -e 's?$$(srcdir)/dnstap/dnstap.pb-c.c?dnstap/dnstap.pb-c.c?g' \
++ -e 's?$$(srcdir)/dnstap/dnstap.pb-c.h?dnstap/dnstap.pb-c.h?g' \
++ -e 's?$$(srcdir)/dnscrypt/dnscrypt_config.h??g' \
+ -e 's?$$(srcdir)/pythonmod/pythonmod.h?$$(PYTHONMOD_HEADER)?g' \
++ -e 's?$$(srcdir)/edns-subnet/subnetmod.h $$(srcdir)/edns-subnet/subnet-whitelist.h $$(srcdir)/edns-subnet/edns-subnet.h $$(srcdir)/edns-subnet/addrtree.h?$$(SUBNET_HEADER)?g' \
++ -e 's?$$(srcdir)/ipsecmod/ipsecmod.h $$(srcdir)/ipsecmod/ipsecmod-whitelist.h?$$(IPSECMOD_HEADER)?g' \
+ -e 's!\(.*\)\.o[ :]*!\1.lo \1.o: !g' \
+ > $(DEPEND_TMP)
+ cp $(DEPEND_TARGET) $(DEPEND_TMP2)
+@@ -599,24 +643,30 @@
+ fi
+ rm -f $(DEPEND_TMP) $(DEPEND_TMP2)
+
++# build rules
++ipset.lo ipset.o: $(srcdir)/ipset/ipset.c
++
+ # Dependencies
+ dns.lo dns.o: $(srcdir)/services/cache/dns.c config.h $(srcdir)/iterator/iter_delegpt.h $(srcdir)/util/log.h \
+- $(srcdir)/validator/val_nsec.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
+- $(srcdir)/util/locks.h $(srcdir)/services/cache/dns.h $(srcdir)/util/data/msgreply.h \
+- $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/data/dname.h \
+- $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
++ $(srcdir)/iterator/iter_utils.h $(srcdir)/iterator/iter_resptype.h $(srcdir)/validator/val_nsec.h \
++ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
++ $(srcdir)/validator/val_utils.h $(srcdir)/sldns/pkthdr.h $(srcdir)/services/cache/dns.h \
++ $(srcdir)/util/data/msgreply.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \
++ $(srcdir)/util/data/dname.h $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/rrdef.h \
+ $(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/sldns/sbuffer.h
+ infra.lo infra.o: $(srcdir)/services/cache/infra.c config.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/str2wire.h \
+- $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
+- $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h $(srcdir)/util/storage/slabhash.h \
+- $(srcdir)/util/storage/lookup3.h $(srcdir)/util/data/dname.h $(srcdir)/util/net_help.h \
+- $(srcdir)/util/config_file.h $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h \
+- $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/module.h \
+- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h
++ $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h $(srcdir)/services/cache/infra.h \
++ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/storage/dnstree.h \
++ $(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
++ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
++ $(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/data/dname.h \
++ $(srcdir)/util/net_help.h $(srcdir)/util/config_file.h $(srcdir)/iterator/iterator.h \
++ $(srcdir)/services/outbound_list.h $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h \
++ $(srcdir)/sldns/pkthdr.h
+ rrset.lo rrset.o: $(srcdir)/services/cache/rrset.c config.h $(srcdir)/services/cache/rrset.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/storage/slabhash.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/config_file.h \
+- $(srcdir)/util/data/msgreply.h $(srcdir)/util/regional.h $(srcdir)/util/alloc.h
++ $(srcdir)/util/data/msgreply.h $(srcdir)/util/regional.h $(srcdir)/util/alloc.h $(srcdir)/util/net_help.h
+ as112.lo as112.o: $(srcdir)/util/as112.c $(srcdir)/util/as112.h
+ dname.lo dname.o: $(srcdir)/util/data/dname.c config.h $(srcdir)/util/data/dname.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/msgparse.h \
+@@ -625,7 +675,8 @@
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
+ $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/dname.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h \
+- $(srcdir)/sldns/sbuffer.h
++ $(srcdir)/sldns/sbuffer.h $(srcdir)/services/localzone.h $(srcdir)/util/rbtree.h \
++ $(srcdir)/util/storage/dnstree.h $(srcdir)/util/module.h $(srcdir)/services/view.h
+ msgparse.lo msgparse.o: $(srcdir)/util/data/msgparse.c config.h $(srcdir)/util/data/msgparse.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/sldns/pkthdr.h \
+ $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
+@@ -633,9 +684,15 @@
+ $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/wire2str.h
+ msgreply.lo msgreply.o: $(srcdir)/util/data/msgreply.c config.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/packed_rrset.h \
+- $(srcdir)/util/storage/lookup3.h $(srcdir)/util/alloc.h $(srcdir)/util/netevent.h $(srcdir)/util/net_help.h \
+- $(srcdir)/util/data/dname.h $(srcdir)/util/regional.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
+- $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgencode.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h
++ $(srcdir)/util/storage/lookup3.h $(srcdir)/util/alloc.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
++ $(srcdir)/util/net_help.h $(srcdir)/util/data/dname.h \
++ $(srcdir)/util/regional.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
++ $(srcdir)/util/data/msgencode.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h $(srcdir)/util/module.h \
++ $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
++ $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
++ $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/util/config_file.h \
++ $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \
++ $(srcdir)/respip/respip.h
+ packed_rrset.lo packed_rrset.o: $(srcdir)/util/data/packed_rrset.c config.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
+ $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/alloc.h $(srcdir)/util/regional.h \
+@@ -648,10 +705,13 @@
+ $(srcdir)/util/rbtree.h $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_donotq.h \
+ $(srcdir)/iterator/iter_delegpt.h $(srcdir)/iterator/iter_scrub.h $(srcdir)/iterator/iter_priv.h \
+ $(srcdir)/validator/val_neg.h $(srcdir)/services/cache/dns.h $(srcdir)/services/cache/infra.h \
+- $(srcdir)/util/rtt.h $(srcdir)/util/netevent.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h \
++ $(srcdir)/util/rtt.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
++ $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \
++ $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/services/view.h \
++ $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
++ $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h \
+ $(srcdir)/util/data/dname.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h \
+- $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h $(srcdir)/util/config_file.h $(srcdir)/util/random.h \
+- $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/sbuffer.h
++ $(srcdir)/util/random.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/parseutil.h
+ iter_delegpt.lo iter_delegpt.o: $(srcdir)/iterator/iter_delegpt.c config.h $(srcdir)/iterator/iter_delegpt.h \
+ $(srcdir)/util/log.h $(srcdir)/services/cache/dns.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/regional.h \
+@@ -692,152 +752,267 @@
+ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/iterator/iter_hints.h \
+ $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/iterator/iter_fwd.h \
+ $(srcdir)/iterator/iter_donotq.h $(srcdir)/iterator/iter_delegpt.h $(srcdir)/iterator/iter_priv.h \
+- $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/services/cache/dns.h \
+- $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/net_help.h \
+- $(srcdir)/util/config_file.h $(srcdir)/util/regional.h $(srcdir)/util/data/dname.h $(srcdir)/util/random.h \
+- $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h \
+- $(srcdir)/services/modstack.h $(srcdir)/validator/val_anchor.h $(srcdir)/validator/val_kcache.h \
+- $(srcdir)/validator/val_kentry.h $(srcdir)/validator/val_utils.h $(srcdir)/validator/val_sigcrypt.h \
+- $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h
++ $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
++ $(srcdir)/services/cache/dns.h $(srcdir)/services/cache/rrset.h \
++ $(srcdir)/util/storage/slabhash.h $(srcdir)/util/net_help.h $(srcdir)/util/config_file.h \
++ $(srcdir)/util/regional.h $(srcdir)/util/data/dname.h $(srcdir)/util/random.h $(srcdir)/util/fptr_wlist.h \
++ $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h \
++ $(srcdir)/services/localzone.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h \
++ $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h \
++ $(srcdir)/validator/val_anchor.h $(srcdir)/validator/val_kcache.h $(srcdir)/validator/val_kentry.h \
++ $(srcdir)/validator/val_utils.h $(srcdir)/validator/val_sigcrypt.h $(srcdir)/sldns/str2wire.h
+ listen_dnsport.lo listen_dnsport.o: $(srcdir)/services/listen_dnsport.c config.h \
+- $(srcdir)/services/listen_dnsport.h $(srcdir)/util/netevent.h $(srcdir)/services/outside_network.h \
+- $(srcdir)/util/rbtree.h $(srcdir)/util/log.h $(srcdir)/util/config_file.h \
+- $(srcdir)/util/net_help.h $(srcdir)/sldns/sbuffer.h
++ $(srcdir)/services/listen_dnsport.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
++ $(srcdir)/services/outside_network.h $(srcdir)/util/rbtree.h \
++ $(srcdir)/util/log.h $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h \
++ $(srcdir)/sldns/sbuffer.h $(srcdir)/services/mesh.h $(srcdir)/util/data/msgparse.h \
++ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
++ $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
++ $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
++ $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/services/authzone.h \
++ $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h \
++ $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h
+ localzone.lo localzone.o: $(srcdir)/services/localzone.c config.h $(srcdir)/services/localzone.h \
+ $(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/storage/dnstree.h \
+- $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/regional.h \
+- $(srcdir)/util/config_file.h $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lruhash.h \
+- $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/net_help.h \
+- $(srcdir)/util/netevent.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
+- $(srcdir)/util/as112.h
++ $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.h \
++ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
++ $(srcdir)/sldns/rrdef.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h \
++ $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/util/data/dname.h \
++ $(srcdir)/util/data/msgencode.h $(srcdir)/util/net_help.h $(srcdir)/util/netevent.h \
++ $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/as112.h
+ mesh.lo mesh.o: $(srcdir)/services/mesh.c config.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
+- $(srcdir)/util/netevent.h $(srcdir)/util/data/msgparse.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
+- $(srcdir)/util/log.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h \
+- $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/modstack.h \
++ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
++ $(srcdir)/util/data/msgparse.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
++ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
++ $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h \
++ $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h \
++ $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h \
++ $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h \
+ $(srcdir)/services/outbound_list.h $(srcdir)/services/cache/dns.h $(srcdir)/util/net_help.h \
+- $(srcdir)/util/regional.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/timehist.h $(srcdir)/util/fptr_wlist.h \
+- $(srcdir)/util/tube.h $(srcdir)/util/alloc.h $(srcdir)/util/config_file.h $(srcdir)/sldns/sbuffer.h
++ $(srcdir)/util/regional.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h \
++ $(srcdir)/util/alloc.h $(srcdir)/util/edns.h $(srcdir)/sldns/wire2str.h $(srcdir)/util/data/dname.h \
++ $(srcdir)/services/listen_dnsport.h
+ modstack.lo modstack.o: $(srcdir)/services/modstack.c config.h $(srcdir)/services/modstack.h \
+ $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
+ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h \
+- $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/dns64/dns64.h \
+- $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/validator/validator.h \
+- $(srcdir)/validator/val_utils.h $(PYTHONMOD_HEADER) $(srcdir)/cachedb/cachedb.h
++ $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/tube.h \
++ $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
++ $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \
++ $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
++ $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/dns64/dns64.h $(srcdir)/iterator/iterator.h \
++ $(srcdir)/services/outbound_list.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h
++view.lo view.o: $(srcdir)/services/view.c config.h $(srcdir)/services/view.h $(srcdir)/util/rbtree.h \
++ $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \
++ $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.h \
++ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
++ $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h
++rpz.lo rpz.o: $(srcdir)/services/rpz.c config.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
++ $(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/storage/dnstree.h \
++ $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.h \
++ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
++ $(srcdir)/sldns/rrdef.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h \
++ $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
++ $(srcdir)/services/modstack.h $(srcdir)/libunbound/unbound.h \
++ $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/respip/respip.h $(srcdir)/sldns/wire2str.h \
++ $(srcdir)/sldns/str2wire.h $(srcdir)/util/data/dname.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h
+ outbound_list.lo outbound_list.o: $(srcdir)/services/outbound_list.c config.h \
+ $(srcdir)/services/outbound_list.h $(srcdir)/services/outside_network.h $(srcdir)/util/rbtree.h \
+- $(srcdir)/util/netevent.h
++ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
++
+ outside_network.lo outside_network.o: $(srcdir)/services/outside_network.c config.h \
+ $(srcdir)/services/outside_network.h $(srcdir)/util/rbtree.h $(srcdir)/util/netevent.h \
+- $(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/infra.h \
+- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/storage/dnstree.h \
+- $(srcdir)/util/rtt.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
+- $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgencode.h \
+- $(srcdir)/util/data/dname.h $(srcdir)/util/net_help.h $(srcdir)/util/random.h $(srcdir)/util/fptr_wlist.h \
+- $(srcdir)/util/module.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h \
+- $(srcdir)/sldns/sbuffer.h $(srcdir)/dnstap/dnstap.h
++ $(srcdir)/dnscrypt/dnscrypt.h \
++ $(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/lruhash.h \
++ $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rtt.h \
++ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/iterator/iterator.h \
++ $(srcdir)/services/outbound_list.h $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h \
++ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/dname.h \
++ $(srcdir)/util/net_help.h $(srcdir)/util/random.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h \
++ $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
++ $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h \
++ $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h \
++ $(srcdir)/dnstap/dnstap.h
+ alloc.lo alloc.o: $(srcdir)/util/alloc.c config.h $(srcdir)/util/alloc.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
+ $(srcdir)/util/regional.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
+- $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
++ $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
++ $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \
+- $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h
++ $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h \
++ $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h \
++ $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h \
++ $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h
+ config_file.lo config_file.o: $(srcdir)/util/config_file.c config.h $(srcdir)/util/log.h \
+ $(srcdir)/util/configyyrename.h $(srcdir)/util/config_file.h util/configparser.h \
+ $(srcdir)/util/net_help.h $(srcdir)/util/data/msgparse.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
+ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/regional.h $(srcdir)/util/fptr_wlist.h \
+- $(srcdir)/util/netevent.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
+- $(srcdir)/services/modstack.h $(srcdir)/util/data/dname.h $(srcdir)/util/rtt.h $(srcdir)/services/cache/infra.h \
+- $(srcdir)/util/storage/dnstree.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/parseutil.h \
+- $(srcdir)/util/iana_ports.inc
++ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
++ $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h \
++ $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \
++ $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h \
++ $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/data/dname.h \
++ $(srcdir)/util/rtt.h $(srcdir)/services/cache/infra.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/parseutil.h \
++ $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/util/iana_ports.inc
+ configlexer.lo configlexer.o: util/configlexer.c config.h $(srcdir)/util/configyyrename.h \
+ $(srcdir)/util/config_file.h util/configparser.h
+ configparser.lo configparser.o: util/configparser.c config.h $(srcdir)/util/configyyrename.h \
+ $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h
++shm_main.lo shm_main.o: $(srcdir)/util/shm_side/shm_main.c config.h $(srcdir)/util/shm_side/shm_main.h \
++ $(srcdir)/libunbound/unbound.h $(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
++ $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
++ $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h \
++ $(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
++ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/data/msgreply.h \
++ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h \
++ $(srcdir)/util/timehist.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h $(srcdir)/services/mesh.h \
++ $(srcdir)/util/rbtree.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \
++ $(srcdir)/services/view.h $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/respip/respip.h \
++ $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h \
++ $(srcdir)/util/rtt.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h $(srcdir)/util/fptr_wlist.h \
++ $(srcdir)/util/tube.h
++authzone.lo authzone.o: $(srcdir)/services/authzone.c config.h $(srcdir)/services/authzone.h \
++ $(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/services/mesh.h $(srcdir)/util/netevent.h \
++ $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/data/msgparse.h \
++ $(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h \
++ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/modstack.h \
++ $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \
++ $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/daemon/stats.h \
++ $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/data/dname.h \
++ $(srcdir)/util/data/msgencode.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h $(srcdir)/util/random.h \
++ $(srcdir)/services/cache/dns.h $(srcdir)/services/outside_network.h \
++ $(srcdir)/services/listen_dnsport.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h \
++ $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/keyraw.h $(srcdir)/validator/val_nsec3.h \
++ $(srcdir)/validator/val_secalgo.h
+ fptr_wlist.lo fptr_wlist.o: $(srcdir)/util/fptr_wlist.c config.h $(srcdir)/util/fptr_wlist.h \
+- $(srcdir)/util/netevent.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
+- $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
+- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \
+- $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h $(srcdir)/util/mini_event.h \
+- $(srcdir)/util/rbtree.h $(srcdir)/services/outside_network.h \
+- $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h $(srcdir)/services/cache/infra.h \
++ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
++ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/module.h \
++ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
++ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
++ $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
++ $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \
++ $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
++ $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \
++ $(srcdir)/services/outside_network.h $(srcdir)/services/cache/infra.h \
+ $(srcdir)/util/rtt.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/dns64/dns64.h \
+ $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/iterator/iter_fwd.h \
+ $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h $(srcdir)/validator/val_anchor.h \
+ $(srcdir)/validator/val_nsec3.h $(srcdir)/validator/val_sigcrypt.h $(srcdir)/validator/val_kentry.h \
+ $(srcdir)/validator/val_neg.h $(srcdir)/validator/autotrust.h $(srcdir)/libunbound/libworker.h \
+- $(srcdir)/libunbound/context.h $(srcdir)/util/alloc.h $(srcdir)/libunbound/unbound.h \
+- $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h \
+- $(PYTHONMOD_HEADER) $(srcdir)/cachedb/cachedb.h
++ $(srcdir)/libunbound/context.h $(srcdir)/util/alloc.h $(srcdir)/libunbound/unbound-event.h \
++ $(srcdir)/libunbound/worker.h
+ locks.lo locks.o: $(srcdir)/util/locks.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h
+ log.lo log.o: $(srcdir)/util/log.c config.h $(srcdir)/util/log.h $(srcdir)/util/locks.h $(srcdir)/sldns/sbuffer.h
+ mini_event.lo mini_event.o: $(srcdir)/util/mini_event.c config.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \
+- $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
++ $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
++ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
+ $(srcdir)/util/log.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
+ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \
+- $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h
++ $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h \
++ $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h \
++ $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h \
++ $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h
+ module.lo module.o: $(srcdir)/util/module.c config.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h \
+ $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
+- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h
+-netevent.lo netevent.o: $(srcdir)/util/netevent.c config.h $(srcdir)/util/netevent.h $(srcdir)/util/ub_event.h \
+- $(srcdir)/util/log.h $(srcdir)/util/net_help.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/storage/lruhash.h \
+- $(srcdir)/util/locks.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
+- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \
+- $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h $(srcdir)/sldns/sbuffer.h \
+- $(srcdir)/dnstap/dnstap.h
++ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/wire2str.h
++netevent.lo netevent.o: $(srcdir)/util/netevent.c config.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
++ $(srcdir)/util/ub_event.h $(srcdir)/util/log.h $(srcdir)/util/net_help.h \
++ $(srcdir)/util/tcp_conn_limit.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/locks.h \
++ $(srcdir)/util/fptr_wlist.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/module.h \
++ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
++ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h \
++ $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/services/view.h \
++ $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h \
++ $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/sldns/str2wire.h \
++ $(srcdir)/dnstap/dnstap.h $(srcdir)/services/listen_dnsport.h
+ net_help.lo net_help.o: $(srcdir)/util/net_help.c config.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h \
+ $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/module.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
+- $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/regional.h $(srcdir)/sldns/parseutil.h \
+- $(srcdir)/sldns/wire2str.h
++ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h \
++ $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/wire2str.h
+ random.lo random.o: $(srcdir)/util/random.c config.h $(srcdir)/util/random.h $(srcdir)/util/log.h
+ rbtree.lo rbtree.o: $(srcdir)/util/rbtree.c config.h $(srcdir)/util/log.h $(srcdir)/util/fptr_wlist.h \
+- $(srcdir)/util/netevent.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
+- $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
+- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \
+- $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h
++ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
++ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/module.h \
++ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
++ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
++ $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
++ $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \
++ $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
++ $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h
+ regional.lo regional.o: $(srcdir)/util/regional.c config.h $(srcdir)/util/log.h $(srcdir)/util/regional.h
+-rtt.lo rtt.o: $(srcdir)/util/rtt.c config.h $(srcdir)/util/rtt.h
++rtt.lo rtt.o: $(srcdir)/util/rtt.c config.h $(srcdir)/util/rtt.h $(srcdir)/iterator/iterator.h \
++ $(srcdir)/services/outbound_list.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/storage/lruhash.h \
++ $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/module.h \
++ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h
++edns.lo edns.o: $(srcdir)/util/edns.c config.h $(srcdir)/util/edns.h $(srcdir)/util/config_file.h \
++ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
++ $(srcdir)/util/regional.h $(srcdir)/util/data/msgparse.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
++ $(srcdir)/util/log.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgreply.h \
++ $(srcdir)/util/data/packed_rrset.h
+ dnstree.lo dnstree.o: $(srcdir)/util/storage/dnstree.c config.h $(srcdir)/util/storage/dnstree.h \
+ $(srcdir)/util/rbtree.h $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
+ $(srcdir)/util/log.h $(srcdir)/util/net_help.h
+ lookup3.lo lookup3.o: $(srcdir)/util/storage/lookup3.c config.h $(srcdir)/util/storage/lookup3.h
+ lruhash.lo lruhash.o: $(srcdir)/util/storage/lruhash.c config.h $(srcdir)/util/storage/lruhash.h \
+- $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/util/module.h \
++ $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h \
++ $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/module.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
+ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
+- $(srcdir)/services/modstack.h
++ $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
++ $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \
++ $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
++ $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h
+ slabhash.lo slabhash.o: $(srcdir)/util/storage/slabhash.c config.h $(srcdir)/util/storage/slabhash.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h
++tcp_conn_limit.lo tcp_conn_limit.o: $(srcdir)/util/tcp_conn_limit.c config.h $(srcdir)/util/regional.h \
++ $(srcdir)/util/log.h $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h $(srcdir)/util/tcp_conn_limit.h \
++ $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/services/localzone.h \
++ $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.h \
++ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
++ $(srcdir)/sldns/rrdef.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h
+ timehist.lo timehist.o: $(srcdir)/util/timehist.c config.h $(srcdir)/util/timehist.h $(srcdir)/util/log.h
+ tube.lo tube.o: $(srcdir)/util/tube.c config.h $(srcdir)/util/tube.h $(srcdir)/util/log.h $(srcdir)/util/net_help.h \
+- $(srcdir)/util/netevent.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
+- $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
+- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/services/mesh.h \
+- $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h $(srcdir)/util/ub_event.h
++ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
++ $(srcdir)/util/fptr_wlist.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/module.h \
++ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
++ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
++ $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
++ $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \
++ $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
++ $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/ub_event.h
+ ub_event.lo ub_event.o: $(srcdir)/util/ub_event.c config.h $(srcdir)/util/ub_event.h $(srcdir)/util/log.h \
+- $(srcdir)/util/netevent.h $(srcdir)/util/tube.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h
++ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
++ $(srcdir)/util/tube.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h
+ ub_event_pluggable.lo ub_event_pluggable.o: $(srcdir)/util/ub_event_pluggable.c config.h $(srcdir)/util/ub_event.h \
+- $(srcdir)/libunbound/unbound-event.h $(srcdir)/util/netevent.h $(srcdir)/util/log.h $(srcdir)/util/fptr_wlist.h \
++ $(srcdir)/libunbound/unbound-event.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
++ $(srcdir)/util/log.h $(srcdir)/util/fptr_wlist.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
+ $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
+- $(srcdir)/services/modstack.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h
++ $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
++ $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \
++ $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
++ $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h
+ winsock_event.lo winsock_event.o: $(srcdir)/util/winsock_event.c config.h
+ autotrust.lo autotrust.o: $(srcdir)/validator/autotrust.c config.h $(srcdir)/validator/autotrust.h \
+ $(srcdir)/util/rbtree.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
+ $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/validator/val_anchor.h $(srcdir)/validator/val_utils.h \
+- $(srcdir)/validator/val_sigcrypt.h $(srcdir)/util/data/dname.h $(srcdir)/util/module.h \
+- $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
+- $(srcdir)/util/net_help.h $(srcdir)/util/config_file.h $(srcdir)/util/regional.h $(srcdir)/util/random.h \
+- $(srcdir)/services/mesh.h $(srcdir)/util/netevent.h $(srcdir)/services/modstack.h \
+- $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/validator/val_kcache.h \
+- $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/keyraw.h
++ $(srcdir)/sldns/pkthdr.h $(srcdir)/validator/val_sigcrypt.h $(srcdir)/util/data/dname.h $(srcdir)/util/module.h \
++ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/net_help.h \
++ $(srcdir)/util/config_file.h $(srcdir)/util/regional.h $(srcdir)/util/random.h $(srcdir)/services/mesh.h \
++ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
++ $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
++ $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \
++ $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \
++ $(srcdir)/respip/respip.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \
++ $(srcdir)/validator/val_kcache.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/keyraw.h
+ val_anchor.lo val_anchor.o: $(srcdir)/validator/val_anchor.c config.h $(srcdir)/validator/val_anchor.h \
+ $(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/validator/val_sigcrypt.h \
+- $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/validator/autotrust.h \
+- $(srcdir)/util/data/dname.h $(srcdir)/util/net_help.h $(srcdir)/util/config_file.h $(srcdir)/util/as112.h \
+- $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/str2wire.h
++ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/pkthdr.h \
++ $(srcdir)/validator/autotrust.h $(srcdir)/util/data/dname.h $(srcdir)/util/net_help.h \
++ $(srcdir)/util/config_file.h $(srcdir)/util/as112.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/rrdef.h \
++ $(srcdir)/sldns/str2wire.h
+ validator.lo validator.o: $(srcdir)/validator/validator.c config.h $(srcdir)/validator/validator.h \
+ $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
+@@ -845,10 +1020,14 @@
+ $(srcdir)/validator/val_anchor.h $(srcdir)/util/rbtree.h $(srcdir)/validator/val_kcache.h \
+ $(srcdir)/util/storage/slabhash.h $(srcdir)/validator/val_kentry.h $(srcdir)/validator/val_nsec.h \
+ $(srcdir)/validator/val_nsec3.h $(srcdir)/validator/val_neg.h $(srcdir)/validator/val_sigcrypt.h \
+- $(srcdir)/validator/autotrust.h $(srcdir)/services/cache/dns.h $(srcdir)/util/data/dname.h \
+- $(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/util/fptr_wlist.h \
+- $(srcdir)/util/netevent.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h \
+- $(srcdir)/sldns/wire2str.h
++ $(srcdir)/validator/autotrust.h $(srcdir)/services/cache/dns.h $(srcdir)/services/cache/rrset.h \
++ $(srcdir)/util/data/dname.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h \
++ $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
++ $(srcdir)/util/tube.h $(srcdir)/services/mesh.h \
++ $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
++ $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \
++ $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \
++ $(srcdir)/respip/respip.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h
+ val_kcache.lo val_kcache.o: $(srcdir)/validator/val_kcache.c config.h $(srcdir)/validator/val_kcache.h \
+ $(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
+ $(srcdir)/validator/val_kentry.h $(srcdir)/util/config_file.h $(srcdir)/util/data/dname.h \
+@@ -861,7 +1040,7 @@
+ val_neg.lo val_neg.o: $(srcdir)/validator/val_neg.c config.h $(srcdir)/validator/val_neg.h $(srcdir)/util/locks.h \
+ $(srcdir)/util/log.h $(srcdir)/util/rbtree.h $(srcdir)/validator/val_nsec.h $(srcdir)/util/data/packed_rrset.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/validator/val_nsec3.h $(srcdir)/validator/val_utils.h \
+- $(srcdir)/util/data/dname.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/net_help.h \
++ $(srcdir)/sldns/pkthdr.h $(srcdir)/util/data/dname.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/net_help.h \
+ $(srcdir)/util/config_file.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \
+ $(srcdir)/services/cache/dns.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h
+ val_nsec3.lo val_nsec3.o: $(srcdir)/validator/val_nsec3.c config.h $(srcdir)/validator/val_nsec3.h \
+@@ -873,8 +1052,8 @@
+ $(srcdir)/util/net_help.h $(srcdir)/util/data/dname.h $(srcdir)/validator/val_nsec.h $(srcdir)/sldns/sbuffer.h
+ val_nsec.lo val_nsec.o: $(srcdir)/validator/val_nsec.c config.h $(srcdir)/validator/val_nsec.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
+- $(srcdir)/validator/val_utils.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/dname.h \
+- $(srcdir)/util/net_help.h $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
++ $(srcdir)/validator/val_utils.h $(srcdir)/sldns/pkthdr.h $(srcdir)/util/data/msgreply.h \
++ $(srcdir)/util/data/dname.h $(srcdir)/util/net_help.h $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h \
+ $(srcdir)/sldns/rrdef.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h
+ val_secalgo.lo val_secalgo.o: $(srcdir)/validator/val_secalgo.c config.h $(srcdir)/util/data/packed_rrset.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/validator/val_secalgo.h \
+@@ -882,36 +1061,55 @@
+ $(srcdir)/sldns/sbuffer.h
+ val_sigcrypt.lo val_sigcrypt.o: $(srcdir)/validator/val_sigcrypt.c config.h \
+ $(srcdir)/validator/val_sigcrypt.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
+- $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/validator/val_secalgo.h $(srcdir)/validator/validator.h \
+- $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
+- $(srcdir)/sldns/rrdef.h $(srcdir)/validator/val_utils.h $(srcdir)/util/data/dname.h $(srcdir)/util/rbtree.h \
+- $(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/sldns/keyraw.h $(srcdir)/sldns/sbuffer.h \
+- $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/wire2str.h
++ $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/sldns/pkthdr.h $(srcdir)/validator/val_secalgo.h \
++ $(srcdir)/validator/validator.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
++ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/rrdef.h $(srcdir)/validator/val_utils.h \
++ $(srcdir)/util/data/dname.h $(srcdir)/util/rbtree.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h \
++ $(srcdir)/util/config_file.h $(srcdir)/sldns/keyraw.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/parseutil.h \
++ $(srcdir)/sldns/wire2str.h
+ val_utils.lo val_utils.o: $(srcdir)/validator/val_utils.c config.h $(srcdir)/validator/val_utils.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
+- $(srcdir)/validator/validator.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
+- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/validator/val_kentry.h \
++ $(srcdir)/sldns/pkthdr.h $(srcdir)/validator/validator.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
++ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/rrdef.h $(srcdir)/validator/val_kentry.h \
+ $(srcdir)/validator/val_sigcrypt.h $(srcdir)/validator/val_anchor.h $(srcdir)/util/rbtree.h \
+ $(srcdir)/validator/val_nsec.h $(srcdir)/validator/val_neg.h $(srcdir)/services/cache/rrset.h \
+ $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/dns.h $(srcdir)/util/data/dname.h \
+- $(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/parseutil.h
++ $(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/sldns/wire2str.h \
++ $(srcdir)/sldns/parseutil.h
+ dns64.lo dns64.o: $(srcdir)/dns64/dns64.c config.h $(srcdir)/dns64/dns64.h $(srcdir)/util/module.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
+ $(srcdir)/sldns/rrdef.h $(srcdir)/services/cache/dns.h $(srcdir)/services/cache/rrset.h \
+ $(srcdir)/util/storage/slabhash.h $(srcdir)/util/config_file.h $(srcdir)/util/fptr_wlist.h \
+- $(srcdir)/util/netevent.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
+- $(srcdir)/services/modstack.h $(srcdir)/util/net_help.h $(srcdir)/util/regional.h
+-cachedb.lo cachedb.o: $(srcdir)/cachedb/cachedb.c config.h $(srcdir)/cachedb/cachedb.h $(srcdir)/util/module.h \
+- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/msgreply.h \
+- $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
+- $(srcdir)/sldns/rrdef.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h $(srcdir)/util/config_file.h \
+- $(srcdir)/util/data/msgencode.h $(srcdir)/services/cache/dns.h $(srcdir)/validator/val_neg.h \
+- $(srcdir)/util/rbtree.h $(srcdir)/validator/val_secalgo.h $(srcdir)/iterator/iter_utils.h \
+- $(srcdir)/iterator/iter_resptype.h $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/wire2str.h \
+- $(srcdir)/sldns/sbuffer.h
++ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
++ $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h \
++ $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \
++ $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h \
++ $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/net_help.h \
++ $(srcdir)/util/regional.h $(srcdir)/util/data/dname.h $(srcdir)/sldns/str2wire.h
++edns-subnet.lo edns-subnet.o: $(srcdir)/edns-subnet/edns-subnet.c config.h
++subnetmod.lo subnetmod.o: $(srcdir)/edns-subnet/subnetmod.c config.h
++addrtree.lo addrtree.o: $(srcdir)/edns-subnet/addrtree.c config.h $(srcdir)/util/log.h \
++ $(srcdir)/util/data/msgreply.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
++ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h \
++ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/edns-subnet/addrtree.h
++subnet-whitelist.lo subnet-whitelist.o: $(srcdir)/edns-subnet/subnet-whitelist.c config.h
++cachedb.lo cachedb.o: $(srcdir)/cachedb/cachedb.c config.h
++redis.lo redis.o: $(srcdir)/cachedb/redis.c config.h
++respip.lo respip.o: $(srcdir)/respip/respip.c config.h $(srcdir)/services/localzone.h $(srcdir)/util/rbtree.h \
++ $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/module.h \
++ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
++ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/services/view.h \
++ $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h $(srcdir)/util/netevent.h \
++ $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/services/modstack.h \
++ $(srcdir)/services/rpz.h $(srcdir)/util/config_file.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
++ $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/services/cache/dns.h \
++ $(srcdir)/sldns/str2wire.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/net_help.h \
++ $(srcdir)/util/regional.h
+ checklocks.lo checklocks.o: $(srcdir)/testcode/checklocks.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
+ $(srcdir)/testcode/checklocks.h
++ipsecmod.lo ipsecmod.o: $(srcdir)/ipsecmod/ipsecmod.c config.h
++ipsecmod-whitelist.lo ipsecmod-whitelist.o: $(srcdir)/ipsecmod/ipsecmod-whitelist.c config.h
+ unitanchor.lo unitanchor.o: $(srcdir)/testcode/unitanchor.c config.h $(srcdir)/util/log.h $(srcdir)/util/data/dname.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/testcode/unitmain.h \
+ $(srcdir)/validator/val_anchor.h $(srcdir)/util/rbtree.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/rrdef.h
+@@ -922,9 +1120,13 @@
+ $(srcdir)/util/log.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/storage/slabhash.h
+ unitmain.lo unitmain.o: $(srcdir)/testcode/unitmain.c config.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/keyraw.h \
+ $(srcdir)/util/log.h $(srcdir)/testcode/unitmain.h $(srcdir)/util/alloc.h $(srcdir)/util/locks.h $(srcdir)/util/net_help.h \
+- $(srcdir)/util/config_file.h $(srcdir)/util/rtt.h $(srcdir)/services/cache/infra.h \
+- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h \
+- $(srcdir)/util/random.h
++ $(srcdir)/util/config_file.h $(srcdir)/util/rtt.h $(srcdir)/util/timehist.h $(srcdir)/iterator/iterator.h \
++ $(srcdir)/services/outbound_list.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/storage/lruhash.h \
++ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h \
++ $(srcdir)/sldns/pkthdr.h $(srcdir)/libunbound/unbound.h $(srcdir)/services/cache/infra.h \
++ $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
++ $(srcdir)/util/random.h $(srcdir)/respip/respip.h \
++ $(srcdir)/services/localzone.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h
+ unitmsgparse.lo unitmsgparse.o: $(srcdir)/testcode/unitmsgparse.c config.h $(srcdir)/util/log.h \
+ $(srcdir)/testcode/unitmain.h $(srcdir)/util/data/msgparse.h $(srcdir)/util/storage/lruhash.h \
+ $(srcdir)/util/locks.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgreply.h \
+@@ -941,10 +1143,10 @@
+ $(srcdir)/util/log.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h
+ unitverify.lo unitverify.o: $(srcdir)/testcode/unitverify.c config.h $(srcdir)/util/log.h \
+ $(srcdir)/testcode/unitmain.h $(srcdir)/validator/val_sigcrypt.h $(srcdir)/util/data/packed_rrset.h \
+- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/validator/val_secalgo.h \
+- $(srcdir)/validator/val_nsec.h $(srcdir)/validator/val_nsec3.h $(srcdir)/util/rbtree.h \
+- $(srcdir)/validator/validator.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
+- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/validator/val_utils.h \
++ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/sldns/pkthdr.h \
++ $(srcdir)/validator/val_secalgo.h $(srcdir)/validator/val_nsec.h $(srcdir)/validator/val_nsec3.h \
++ $(srcdir)/util/rbtree.h $(srcdir)/validator/validator.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
++ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/rrdef.h $(srcdir)/validator/val_utils.h \
+ $(srcdir)/testcode/testpkts.h $(srcdir)/util/data/dname.h $(srcdir)/util/regional.h $(srcdir)/util/alloc.h \
+ $(srcdir)/util/net_help.h $(srcdir)/util/config_file.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/keyraw.h \
+ $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h
+@@ -955,15 +1157,29 @@
+ $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h
+ unitldns.lo unitldns.o: $(srcdir)/testcode/unitldns.c config.h $(srcdir)/util/log.h $(srcdir)/testcode/unitmain.h \
+ $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/wire2str.h
++unitecs.lo unitecs.o: $(srcdir)/testcode/unitecs.c config.h
++unitauth.lo unitauth.o: $(srcdir)/testcode/unitauth.c config.h $(srcdir)/services/authzone.h \
++ $(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/services/mesh.h $(srcdir)/util/netevent.h \
++ $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/data/msgparse.h \
++ $(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h \
++ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/modstack.h \
++ $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \
++ $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/daemon/stats.h \
++ $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/testcode/unitmain.h \
++ $(srcdir)/util/regional.h $(srcdir)/util/net_help.h $(srcdir)/services/cache/dns.h $(srcdir)/sldns/str2wire.h \
++ $(srcdir)/sldns/wire2str.h
+ acl_list.lo acl_list.o: $(srcdir)/daemon/acl_list.c config.h $(srcdir)/daemon/acl_list.h \
+- $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/regional.h $(srcdir)/util/log.h \
+- $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h $(srcdir)/services/localzone.h $(srcdir)/util/locks.h \
+- $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h
++ $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h $(srcdir)/util/locks.h \
++ $(srcdir)/util/log.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h \
++ $(srcdir)/services/localzone.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h \
++ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
++ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h
+ cachedump.lo cachedump.o: $(srcdir)/daemon/cachedump.c config.h $(srcdir)/daemon/cachedump.h \
+ $(srcdir)/daemon/remote.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
+- $(srcdir)/util/netevent.h $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h \
+- $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
++ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
++ $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
++ $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \
+ $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \
+ $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/dns.h \
+ $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h \
+@@ -973,25 +1189,30 @@
+ $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h
+ daemon.lo daemon.o: $(srcdir)/daemon/daemon.c config.h $(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h \
+ $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
+- $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
+- $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/netevent.h \
+- $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
+- $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \
++ $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h \
++ $(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
++ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/data/msgreply.h \
++ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h \
++ $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \
+ $(srcdir)/daemon/remote.h $(srcdir)/daemon/acl_list.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h \
+- $(srcdir)/util/config_file.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/storage/slabhash.h \
++ $(srcdir)/services/view.h $(srcdir)/util/config_file.h $(srcdir)/util/shm_side/shm_main.h \
++ $(srcdir)/util/storage/lookup3.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/tcp_conn_limit.h \
+ $(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h \
+- $(srcdir)/util/rtt.h $(srcdir)/services/localzone.h $(srcdir)/util/random.h $(srcdir)/util/tube.h \
+- $(srcdir)/util/net_help.h $(srcdir)/sldns/keyraw.h
++ $(srcdir)/util/rtt.h $(srcdir)/services/localzone.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \
++ $(srcdir)/services/rpz.h $(srcdir)/respip/respip.h $(srcdir)/util/random.h $(srcdir)/util/tube.h $(srcdir)/util/net_help.h \
++ $(srcdir)/sldns/keyraw.h
+ remote.lo remote.o: $(srcdir)/daemon/remote.c config.h $(srcdir)/daemon/remote.h $(srcdir)/daemon/worker.h \
+ $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/netevent.h \
+- $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
+- $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/util/module.h \
++ $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/alloc.h \
++ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
++ $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/util/module.h \
+ $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/daemon.h \
+ $(srcdir)/services/modstack.h $(srcdir)/daemon/cachedump.h $(srcdir)/util/config_file.h \
+ $(srcdir)/util/net_help.h $(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h \
+ $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
+- $(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h $(srcdir)/services/mesh.h $(srcdir)/services/localzone.h \
++ $(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h $(srcdir)/services/mesh.h $(srcdir)/services/rpz.h \
++ $(srcdir)/services/localzone.h $(srcdir)/services/view.h $(srcdir)/services/authzone.h $(srcdir)/respip/respip.h \
+ $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/data/dname.h $(srcdir)/validator/validator.h \
+ $(srcdir)/validator/val_utils.h $(srcdir)/validator/val_kcache.h $(srcdir)/validator/val_kentry.h \
+ $(srcdir)/validator/val_anchor.h $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h \
+@@ -999,51 +1220,62 @@
+ $(srcdir)/services/outside_network.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/parseutil.h \
+ $(srcdir)/sldns/wire2str.h
+ stats.lo stats.o: $(srcdir)/daemon/stats.c config.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
+- $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
++ $(srcdir)/libunbound/unbound.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
+- $(srcdir)/util/netevent.h $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h \
+- $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \
+- $(srcdir)/daemon/daemon.h $(srcdir)/services/modstack.h \
+- $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/outside_network.h \
+- $(srcdir)/services/listen_dnsport.h $(srcdir)/util/config_file.h $(srcdir)/util/tube.h $(srcdir)/util/net_help.h \
+- $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h $(srcdir)/services/cache/rrset.h \
+- $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
+- $(srcdir)/util/rtt.h $(srcdir)/validator/val_kcache.h
++ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
++ $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
++ $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \
++ $(srcdir)/daemon/daemon.h $(srcdir)/services/modstack.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
++ $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \
++ $(srcdir)/services/view.h $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/respip/respip.h \
++ $(srcdir)/services/outside_network.h $(srcdir)/services/listen_dnsport.h $(srcdir)/util/tube.h \
++ $(srcdir)/util/net_help.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h \
++ $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/services/cache/rrset.h \
++ $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \
++ $(srcdir)/validator/val_kcache.h $(srcdir)/validator/val_neg.h
+ unbound.lo unbound.o: $(srcdir)/daemon/unbound.c config.h $(srcdir)/util/log.h $(srcdir)/daemon/daemon.h \
+ $(srcdir)/util/locks.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
+- $(srcdir)/daemon/remote.h $(srcdir)/util/config_file.h $(srcdir)/util/storage/slabhash.h \
+- $(srcdir)/util/storage/lruhash.h $(srcdir)/services/listen_dnsport.h $(srcdir)/util/netevent.h \
+- $(srcdir)/services/cache/rrset.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/cache/infra.h \
+- $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h $(srcdir)/util/fptr_wlist.h \
+- $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
+- $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/net_help.h \
++ $(srcdir)/daemon/remote.h $(srcdir)/util/config_file.h \
++ $(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lruhash.h $(srcdir)/services/listen_dnsport.h \
++ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/services/cache/rrset.h \
++ $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
++ $(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/fptr_wlist.h \
++ $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
++ $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
++ $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h \
++ $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/net_help.h \
+ $(srcdir)/util/ub_event.h
+ worker.lo worker.o: $(srcdir)/daemon/worker.c config.h $(srcdir)/util/log.h $(srcdir)/util/net_help.h \
+ $(srcdir)/util/random.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
+- $(srcdir)/util/netevent.h $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h \
+- $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
++ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
++ $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
++ $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \
+ $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/daemon.h \
+ $(srcdir)/services/modstack.h $(srcdir)/daemon/remote.h $(srcdir)/daemon/acl_list.h \
+- $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/config_file.h $(srcdir)/util/regional.h \
+- $(srcdir)/util/storage/slabhash.h $(srcdir)/services/listen_dnsport.h \
++ $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h $(srcdir)/util/config_file.h \
++ $(srcdir)/util/regional.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/listen_dnsport.h \
+ $(srcdir)/services/outside_network.h $(srcdir)/services/outbound_list.h \
+ $(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \
+- $(srcdir)/services/cache/dns.h $(srcdir)/services/mesh.h $(srcdir)/services/localzone.h \
+- $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/dname.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h \
++ $(srcdir)/services/cache/dns.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h $(srcdir)/services/rpz.h \
++ $(srcdir)/services/localzone.h $(srcdir)/respip/respip.h $(srcdir)/util/data/msgencode.h \
++ $(srcdir)/util/data/dname.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/edns.h \
+ $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h $(srcdir)/validator/autotrust.h \
+- $(srcdir)/validator/val_anchor.h $(srcdir)/libunbound/context.h $(srcdir)/libunbound/unbound.h \
+- $(srcdir)/libunbound/libworker.h
++ $(srcdir)/validator/val_anchor.h $(srcdir)/libunbound/context.h $(srcdir)/libunbound/unbound-event.h \
++ $(srcdir)/libunbound/libworker.h $(srcdir)/sldns/wire2str.h $(srcdir)/util/shm_side/shm_main.h
+ testbound.lo testbound.o: $(srcdir)/testcode/testbound.c config.h $(srcdir)/testcode/testpkts.h \
+- $(srcdir)/testcode/replay.h $(srcdir)/util/netevent.h $(srcdir)/util/rbtree.h $(srcdir)/testcode/fake_event.h \
++ $(srcdir)/testcode/replay.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
++ $(srcdir)/util/rbtree.h $(srcdir)/testcode/fake_event.h \
+ $(srcdir)/daemon/remote.h $(srcdir)/util/config_file.h $(srcdir)/sldns/keyraw.h $(srcdir)/daemon/unbound.c \
+ $(srcdir)/util/log.h $(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
+ $(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lruhash.h \
+ $(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
+- $(srcdir)/util/rtt.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
++ $(srcdir)/util/rtt.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/module.h \
+ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \
+- $(srcdir)/services/mesh.h $(srcdir)/util/net_help.h $(srcdir)/util/ub_event.h
++ $(srcdir)/services/mesh.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/services/view.h \
++ $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
++ $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/net_help.h $(srcdir)/util/ub_event.h
+ testpkts.lo testpkts.o: $(srcdir)/testcode/testpkts.c config.h $(srcdir)/testcode/testpkts.h \
+ $(srcdir)/util/net_help.h $(srcdir)/util/log.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/pkthdr.h \
+ $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h
+@@ -1050,63 +1282,80 @@
+ worker.lo worker.o: $(srcdir)/daemon/worker.c config.h $(srcdir)/util/log.h $(srcdir)/util/net_help.h \
+ $(srcdir)/util/random.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
+- $(srcdir)/util/netevent.h $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h \
+- $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
++ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
++ $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
++ $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h \
+ $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/daemon.h \
+ $(srcdir)/services/modstack.h $(srcdir)/daemon/remote.h $(srcdir)/daemon/acl_list.h \
+- $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/config_file.h $(srcdir)/util/regional.h \
+- $(srcdir)/util/storage/slabhash.h $(srcdir)/services/listen_dnsport.h \
++ $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h $(srcdir)/util/config_file.h \
++ $(srcdir)/util/regional.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/listen_dnsport.h \
+ $(srcdir)/services/outside_network.h $(srcdir)/services/outbound_list.h \
+ $(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \
+- $(srcdir)/services/cache/dns.h $(srcdir)/services/mesh.h $(srcdir)/services/localzone.h \
+- $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/dname.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h \
++ $(srcdir)/services/cache/dns.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h $(srcdir)/services/rpz.h \
++ $(srcdir)/services/localzone.h $(srcdir)/respip/respip.h $(srcdir)/util/data/msgencode.h \
++ $(srcdir)/util/data/dname.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/edns.h \
+ $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h $(srcdir)/validator/autotrust.h \
+- $(srcdir)/validator/val_anchor.h $(srcdir)/libunbound/context.h $(srcdir)/libunbound/unbound.h \
+- $(srcdir)/libunbound/libworker.h
++ $(srcdir)/validator/val_anchor.h $(srcdir)/libunbound/context.h $(srcdir)/libunbound/unbound-event.h \
++ $(srcdir)/libunbound/libworker.h $(srcdir)/sldns/wire2str.h $(srcdir)/util/shm_side/shm_main.h
+ acl_list.lo acl_list.o: $(srcdir)/daemon/acl_list.c config.h $(srcdir)/daemon/acl_list.h \
+- $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/regional.h $(srcdir)/util/log.h \
+- $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h $(srcdir)/services/localzone.h $(srcdir)/util/locks.h \
+- $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h
++ $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h $(srcdir)/util/locks.h \
++ $(srcdir)/util/log.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h \
++ $(srcdir)/services/localzone.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h \
++ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
++ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h
+ daemon.lo daemon.o: $(srcdir)/daemon/daemon.c config.h $(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h \
+ $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
+- $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
+- $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/netevent.h \
+- $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
+- $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \
++ $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h \
++ $(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
++ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/data/msgreply.h \
++ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h \
++ $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \
+ $(srcdir)/daemon/remote.h $(srcdir)/daemon/acl_list.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h \
+- $(srcdir)/util/config_file.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/storage/slabhash.h \
++ $(srcdir)/services/view.h $(srcdir)/util/config_file.h $(srcdir)/util/shm_side/shm_main.h \
++ $(srcdir)/util/storage/lookup3.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/tcp_conn_limit.h \
+ $(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h \
+- $(srcdir)/util/rtt.h $(srcdir)/services/localzone.h $(srcdir)/util/random.h $(srcdir)/util/tube.h \
+- $(srcdir)/util/net_help.h $(srcdir)/sldns/keyraw.h
++ $(srcdir)/util/rtt.h $(srcdir)/services/localzone.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \
++ $(srcdir)/services/rpz.h $(srcdir)/respip/respip.h $(srcdir)/util/random.h $(srcdir)/util/tube.h $(srcdir)/util/net_help.h \
++ $(srcdir)/sldns/keyraw.h
+ stats.lo stats.o: $(srcdir)/daemon/stats.c config.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
+- $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
++ $(srcdir)/libunbound/unbound.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
+- $(srcdir)/util/netevent.h $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h \
+- $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \
+- $(srcdir)/daemon/daemon.h $(srcdir)/services/modstack.h \
+- $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/services/outside_network.h \
+- $(srcdir)/services/listen_dnsport.h $(srcdir)/util/config_file.h $(srcdir)/util/tube.h $(srcdir)/util/net_help.h \
+- $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h $(srcdir)/services/cache/rrset.h \
+- $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
+- $(srcdir)/util/rtt.h $(srcdir)/validator/val_kcache.h
++ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
++ $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
++ $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \
++ $(srcdir)/daemon/daemon.h $(srcdir)/services/modstack.h $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h \
++ $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \
++ $(srcdir)/services/view.h $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/respip/respip.h \
++ $(srcdir)/services/outside_network.h $(srcdir)/services/listen_dnsport.h $(srcdir)/util/tube.h \
++ $(srcdir)/util/net_help.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h \
++ $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/services/cache/rrset.h \
++ $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \
++ $(srcdir)/validator/val_kcache.h $(srcdir)/validator/val_neg.h
+ replay.lo replay.o: $(srcdir)/testcode/replay.c config.h $(srcdir)/util/log.h $(srcdir)/util/net_help.h \
+- $(srcdir)/util/config_file.h $(srcdir)/testcode/replay.h $(srcdir)/util/netevent.h $(srcdir)/testcode/testpkts.h \
+- $(srcdir)/util/rbtree.h $(srcdir)/testcode/fake_event.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h
++ $(srcdir)/util/config_file.h $(srcdir)/testcode/replay.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
++ $(srcdir)/testcode/testpkts.h $(srcdir)/util/rbtree.h \
++ $(srcdir)/testcode/fake_event.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h
+ fake_event.lo fake_event.o: $(srcdir)/testcode/fake_event.c config.h $(srcdir)/testcode/fake_event.h \
+- $(srcdir)/util/netevent.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h $(srcdir)/util/data/msgparse.h \
+- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
+- $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgencode.h \
+- $(srcdir)/util/data/dname.h $(srcdir)/util/config_file.h $(srcdir)/services/listen_dnsport.h \
+- $(srcdir)/services/outside_network.h $(srcdir)/util/rbtree.h \
+- $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rtt.h \
+- $(srcdir)/testcode/replay.h $(srcdir)/testcode/testpkts.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/module.h \
+- $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h $(srcdir)/sldns/sbuffer.h \
+- $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h
++ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
++ $(srcdir)/util/net_help.h $(srcdir)/util/log.h $(srcdir)/util/data/msgparse.h $(srcdir)/util/storage/lruhash.h \
++ $(srcdir)/util/locks.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgreply.h \
++ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/dname.h \
++ $(srcdir)/util/config_file.h $(srcdir)/services/listen_dnsport.h $(srcdir)/services/outside_network.h \
++ $(srcdir)/util/rbtree.h $(srcdir)/services/cache/infra.h \
++ $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rtt.h $(srcdir)/testcode/replay.h $(srcdir)/testcode/testpkts.h \
++ $(srcdir)/util/fptr_wlist.h $(srcdir)/util/module.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h \
++ $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/services/view.h \
++ $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
++ $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h
+ lock_verify.lo lock_verify.o: $(srcdir)/testcode/lock_verify.c config.h $(srcdir)/util/log.h $(srcdir)/util/rbtree.h \
+- $(srcdir)/util/locks.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/util/storage/lruhash.h \
+- $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
+- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \
+- $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h
++ $(srcdir)/util/locks.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
++ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/module.h \
++ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
++ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h \
++ $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
++ $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \
++ $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
++ $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h
+ pktview.lo pktview.o: $(srcdir)/testcode/pktview.c config.h $(srcdir)/util/log.h $(srcdir)/util/data/dname.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
+ $(srcdir)/sldns/rrdef.h $(srcdir)/testcode/unitmain.h $(srcdir)/testcode/readhex.h $(srcdir)/sldns/sbuffer.h \
+@@ -1114,10 +1363,14 @@
+ readhex.lo readhex.o: $(srcdir)/testcode/readhex.c config.h $(srcdir)/testcode/readhex.h $(srcdir)/util/log.h \
+ $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/parseutil.h
+ memstats.lo memstats.o: $(srcdir)/testcode/memstats.c config.h $(srcdir)/util/log.h $(srcdir)/util/rbtree.h \
+- $(srcdir)/util/locks.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/util/storage/lruhash.h \
+- $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
+- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \
+- $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h
++ $(srcdir)/util/locks.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
++ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/module.h \
++ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
++ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h \
++ $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
++ $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h \
++ $(srcdir)/util/config_file.h $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
++ $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h
+ unbound-checkconf.lo unbound-checkconf.o: $(srcdir)/smallapp/unbound-checkconf.c config.h $(srcdir)/util/log.h \
+ $(srcdir)/util/config_file.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
+@@ -1125,20 +1378,31 @@
+ $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/iterator/iter_fwd.h \
+ $(srcdir)/util/rbtree.h $(srcdir)/iterator/iter_hints.h $(srcdir)/util/storage/dnstree.h \
+ $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h $(srcdir)/services/localzone.h \
+- $(srcdir)/sldns/sbuffer.h $(PYTHONMOD_HEADER)
++ $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \
++ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
++ $(srcdir)/services/modstack.h $(srcdir)/services/rpz.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
++ $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h
+ worker_cb.lo worker_cb.o: $(srcdir)/smallapp/worker_cb.c config.h $(srcdir)/libunbound/context.h \
+ $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h \
+- $(srcdir)/libunbound/unbound.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
+- $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h \
+- $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
+- $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h
++ $(srcdir)/libunbound/unbound.h $(srcdir)/libunbound/unbound-event.h $(srcdir)/util/data/packed_rrset.h \
++ $(srcdir)/util/storage/lruhash.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
++ $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
++ $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
++ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h \
++ $(srcdir)/services/mesh.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
++ $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/util/config_file.h \
++ $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/respip/respip.h
+ context.lo context.o: $(srcdir)/libunbound/context.c config.h $(srcdir)/libunbound/context.h \
+ $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h \
+- $(srcdir)/libunbound/unbound.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
+- $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
+- $(srcdir)/sldns/rrdef.h $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h $(srcdir)/services/localzone.h \
+- $(srcdir)/util/storage/dnstree.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \
+- $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/sldns/sbuffer.h
++ $(srcdir)/libunbound/unbound.h $(srcdir)/libunbound/unbound-event.h $(srcdir)/util/data/packed_rrset.h \
++ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
++ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/config_file.h \
++ $(srcdir)/util/net_help.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \
++ $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/cache/rrset.h \
++ $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h \
++ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
++ $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h $(srcdir)/services/rpz.h $(srcdir)/daemon/stats.h \
++ $(srcdir)/util/timehist.h $(srcdir)/respip/respip.h
+ libunbound.lo libunbound.o: $(srcdir)/libunbound/libunbound.c $(srcdir)/libunbound/unbound.h \
+ $(srcdir)/libunbound/unbound-event.h config.h $(srcdir)/libunbound/context.h $(srcdir)/util/locks.h \
+ $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h \
+@@ -1146,19 +1410,23 @@
+ $(srcdir)/util/config_file.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/regional.h \
+ $(srcdir)/util/random.h $(srcdir)/util/net_help.h $(srcdir)/util/tube.h $(srcdir)/util/ub_event.h \
+- $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h $(srcdir)/services/cache/infra.h \
+- $(srcdir)/util/rtt.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \
+- $(srcdir)/sldns/sbuffer.h
++ $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h \
++ $(srcdir)/sldns/sbuffer.h $(srcdir)/services/cache/infra.h $(srcdir)/util/rtt.h $(srcdir)/util/netevent.h \
++ $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/services/cache/rrset.h \
++ $(srcdir)/util/storage/slabhash.h $(srcdir)/services/authzone.h $(srcdir)/services/mesh.h \
++ $(srcdir)/services/rpz.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/respip/respip.h
+ libworker.lo libworker.o: $(srcdir)/libunbound/libworker.c config.h $(srcdir)/libunbound/libworker.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
+ $(srcdir)/libunbound/context.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h \
+- $(srcdir)/libunbound/unbound.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
+- $(srcdir)/libunbound/unbound-event.h $(srcdir)/services/outside_network.h $(srcdir)/util/netevent.h \
+- $(srcdir)/services/mesh.h $(srcdir)/util/data/msgparse.h \
+- $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h \
+- $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h $(srcdir)/services/cache/rrset.h \
+- $(srcdir)/util/storage/slabhash.h $(srcdir)/services/outbound_list.h $(srcdir)/util/fptr_wlist.h \
+- $(srcdir)/util/tube.h $(srcdir)/util/regional.h $(srcdir)/util/random.h $(srcdir)/util/config_file.h \
++ $(srcdir)/libunbound/unbound.h $(srcdir)/libunbound/unbound-event.h $(srcdir)/libunbound/worker.h \
++ $(srcdir)/sldns/sbuffer.h $(srcdir)/services/outside_network.h $(srcdir)/util/netevent.h \
++ $(srcdir)/dnscrypt/dnscrypt.h \
++ $(srcdir)/services/mesh.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
++ $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \
++ $(srcdir)/util/storage/dnstree.h $(srcdir)/services/view.h $(srcdir)/util/config_file.h \
++ $(srcdir)/services/authzone.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/respip/respip.h \
++ $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/services/outbound_list.h \
++ $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h $(srcdir)/util/regional.h $(srcdir)/util/random.h \
+ $(srcdir)/util/storage/lookup3.h $(srcdir)/util/net_help.h $(srcdir)/util/data/dname.h \
+ $(srcdir)/util/data/msgencode.h $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h \
+ $(srcdir)/sldns/str2wire.h
+@@ -1166,8 +1434,8 @@
+ $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/wire2str.h
+ asynclook.lo asynclook.o: $(srcdir)/testcode/asynclook.c config.h $(srcdir)/libunbound/unbound.h \
+ $(srcdir)/libunbound/context.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h \
+- $(srcdir)/services/modstack.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
+- $(srcdir)/sldns/rrdef.h
++ $(srcdir)/services/modstack.h $(srcdir)/libunbound/unbound-event.h $(srcdir)/util/data/packed_rrset.h \
++ $(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/rrdef.h
+ streamtcp.lo streamtcp.o: $(srcdir)/testcode/streamtcp.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
+ $(srcdir)/util/net_help.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/msgparse.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgreply.h \
+@@ -1180,7 +1448,14 @@
+ delayer.lo delayer.o: $(srcdir)/testcode/delayer.c config.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h \
+ $(srcdir)/util/config_file.h $(srcdir)/sldns/sbuffer.h
+ unbound-control.lo unbound-control.o: $(srcdir)/smallapp/unbound-control.c config.h $(srcdir)/util/log.h \
+- $(srcdir)/util/config_file.h $(srcdir)/util/locks.h $(srcdir)/util/net_help.h
++ $(srcdir)/util/config_file.h $(srcdir)/util/locks.h $(srcdir)/util/net_help.h $(srcdir)/util/shm_side/shm_main.h \
++ $(srcdir)/libunbound/unbound.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/sldns/wire2str.h \
++ $(srcdir)/sldns/pkthdr.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h $(srcdir)/util/rbtree.h \
++ $(srcdir)/util/storage/dnstree.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h \
++ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
++ $(srcdir)/sldns/rrdef.h $(srcdir)/services/view.h $(srcdir)/sldns/sbuffer.h $(srcdir)/services/authzone.h \
++ $(srcdir)/services/mesh.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
++ $(srcdir)/services/modstack.h $(srcdir)/respip/respip.h
+ unbound-anchor.lo unbound-anchor.o: $(srcdir)/smallapp/unbound-anchor.c config.h $(srcdir)/libunbound/unbound.h \
+ $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/parseutil.h
+ petal.lo petal.o: $(srcdir)/testcode/petal.c config.h
+@@ -1187,17 +1462,19 @@
+ pythonmod_utils.lo pythonmod_utils.o: $(srcdir)/pythonmod/pythonmod_utils.c config.h $(srcdir)/util/module.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
+- $(srcdir)/sldns/rrdef.h $(srcdir)/util/netevent.h $(srcdir)/util/net_help.h $(srcdir)/services/cache/dns.h \
++ $(srcdir)/sldns/rrdef.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
++ $(srcdir)/util/net_help.h $(srcdir)/services/cache/dns.h \
+ $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h $(srcdir)/util/regional.h \
+- $(srcdir)/iterator/iter_delegpt.h $(srcdir)/sldns/sbuffer.h \
+-
++ $(srcdir)/iterator/iter_delegpt.h $(srcdir)/sldns/sbuffer.h
+ win_svc.lo win_svc.o: $(srcdir)/winrc/win_svc.c config.h $(srcdir)/winrc/win_svc.h $(srcdir)/winrc/w_inst.h \
+ $(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
+- $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h \
+- $(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
+- $(srcdir)/util/netevent.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
+- $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/util/module.h \
+- $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/remote.h $(srcdir)/util/config_file.h $(srcdir)/util/ub_event.h
++ $(srcdir)/daemon/worker.h \
++ $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h \
++ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
++ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
++ $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/util/module.h \
++ $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/remote.h $(srcdir)/util/config_file.h $(srcdir)/util/ub_event.h \
++ $(srcdir)/util/net_help.h
+ w_inst.lo w_inst.o: $(srcdir)/winrc/w_inst.c config.h $(srcdir)/winrc/w_inst.h $(srcdir)/winrc/win_svc.h
+ unbound-service-install.lo unbound-service-install.o: $(srcdir)/winrc/unbound-service-install.c config.h \
+ $(srcdir)/winrc/w_inst.h
+@@ -1209,7 +1486,8 @@
+ sbuffer.lo sbuffer.o: $(srcdir)/sldns/sbuffer.c config.h $(srcdir)/sldns/sbuffer.h
+ wire2str.lo wire2str.o: $(srcdir)/sldns/wire2str.c config.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h \
+ $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/sbuffer.h \
+- $(srcdir)/sldns/keyraw.h
++ $(srcdir)/sldns/keyraw.h $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
++ $(srcdir)/util/log.h
+ parse.lo parse.o: $(srcdir)/sldns/parse.c config.h $(srcdir)/sldns/parse.h $(srcdir)/sldns/parseutil.h \
+ $(srcdir)/sldns/sbuffer.h
+ parseutil.lo parseutil.o: $(srcdir)/sldns/parseutil.c config.h $(srcdir)/sldns/parseutil.h
+@@ -1229,8 +1507,9 @@
+ strlcat.lo strlcat.o: $(srcdir)/compat/strlcat.c config.h
+ strlcpy.lo strlcpy.o: $(srcdir)/compat/strlcpy.c config.h
+ strptime.lo strptime.o: $(srcdir)/compat/strptime.c config.h
++getentropy_freebsd.lo getentropy_freebsd.o: $(srcdir)/compat/getentropy_freebsd.c
+ getentropy_linux.lo getentropy_linux.o: $(srcdir)/compat/getentropy_linux.c config.h
+-getentropy_osx.lo getentropy_osx.o: $(srcdir)/compat/getentropy_osx.c config.h
++getentropy_osx.lo getentropy_osx.o: $(srcdir)/compat/getentropy_osx.c
+ getentropy_solaris.lo getentropy_solaris.o: $(srcdir)/compat/getentropy_solaris.c config.h
+ getentropy_win.lo getentropy_win.o: $(srcdir)/compat/getentropy_win.c
+ explicit_bzero.lo explicit_bzero.o: $(srcdir)/compat/explicit_bzero.c config.h
+--- contrib/unbound/README.md.orig
++++ contrib/unbound/README.md
+@@ -0,0 +1,38 @@
++# Unbound
++
++[![Travis Build Status](https://travis-ci.org/NLnetLabs/unbound.svg?branch=master)](https://travis-ci.org/NLnetLabs/unbound)
++[![Packaging status](https://repology.org/badge/tiny-repos/unbound.svg)](https://repology.org/project/unbound/versions)
++[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/unbound.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:unbound)
++
++Unbound is a validating, recursive, caching DNS resolver. It is designed to be
++fast and lean and incorporates modern features based on open standards. If you
++have any feedback, we would love to hear from you. Don’t hesitate to
++[create an issue on Github](https://github.com/NLnetLabs/unbound/issues/new)
++or post a message on the [Unbound mailing list](https://lists.nlnetlabs.nl/mailman/listinfo/unbound-users).
++You can lean more about Unbound by reading our
++[documentation](https://nlnetlabs.nl/documentation/unbound/).
++
++## Compiling
++
++Make sure you have the C toolchain, OpenSSL and its include files, and libexpat
++installed. Unbound can be compiled and installed using:
++
++```
++./configure && make && make install
++```
++
++You can use libevent if you want. libevent is useful when using many (10000)
++outgoing ports. By default max 256 ports are opened at the same time and the
++builtin alternative is equally capable and a little faster.
++
++Use the `--with-libevent=dir` configure option to compile Unbound with libevent
++support.
++
++## Unbound configuration
++
++All of Unbound's configuration options are described in the man pages, which
++will be installed and are available on the Unbound
++[documentation page](https://nlnetlabs.nl/documentation/unbound/).
++
++An example configuration file is located in
++[doc/example.conf](https://github.com/NLnetLabs/unbound/blob/master/doc/example.conf.in).
+--- contrib/unbound/ac_pkg_swig.m4.orig
++++ contrib/unbound/ac_pkg_swig.m4
+@@ -103,9 +103,20 @@
+ if test -z "$available_patch" ; then
+ [available_patch=0]
+ fi
+- if test $available_major -ne $required_major \
+- -o $available_minor -ne $required_minor \
+- -o $available_patch -lt $required_patch ; then
++ [badversion=0]
++ if test $available_major -lt $required_major ; then
++ [badversion=1]
++ fi
++ if test $available_major -eq $required_major \
++ -a $available_minor -lt $required_minor ; then
++ [badversion=1]
++ fi
++ if test $available_major -eq $required_major \
++ -a $available_minor -eq $required_minor \
++ -a $available_patch -lt $required_patch ; then
++ [badversion=1]
++ fi
++ if test $badversion -eq 1 ; then
+ AC_MSG_WARN([SWIG version >= $1 is required. You have $swig_version. You should look at http://www.swig.org])
+ SWIG='echo "Error: SWIG version >= $1 is required. You have '"$swig_version"'. You should look at http://www.swig.org" ; false'
+ else
+--- contrib/unbound/aclocal.m4.orig
++++ contrib/unbound/aclocal.m4
+@@ -1,6 +1,6 @@
+-# generated automatically by aclocal 1.15 -*- Autoconf -*-
++# generated automatically by aclocal 1.16.1 -*- Autoconf -*-
+
+-# Copyright (C) 1996-2014 Free Software Foundation, Inc.
++# Copyright (C) 1996-2018 Free Software Foundation, Inc.
+
+ # This file is free software; the Free Software Foundation
+ # gives unlimited permission to copy and/or distribute it,
+@@ -9044,3 +9044,397 @@
+ m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])])
+ m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])])
+
++# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
++# serial 11 (pkg-config-0.29.1)
++
++dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
++dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com>
++dnl
++dnl This program is free software; you can redistribute it and/or modify
++dnl it under the terms of the GNU General Public License as published by
++dnl the Free Software Foundation; either version 2 of the License, or
++dnl (at your option) any later version.
++dnl
++dnl This program is distributed in the hope that it will be useful, but
++dnl WITHOUT ANY WARRANTY; without even the implied warranty of
++dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++dnl General Public License for more details.
++dnl
++dnl You should have received a copy of the GNU General Public License
++dnl along with this program; if not, write to the Free Software
++dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
++dnl 02111-1307, USA.
++dnl
++dnl As a special exception to the GNU General Public License, if you
++dnl distribute this file as part of a program that contains a
++dnl configuration script generated by Autoconf, you may include it under
++dnl the same distribution terms that you use for the rest of that
++dnl program.
++
++dnl PKG_PREREQ(MIN-VERSION)
++dnl -----------------------
++dnl Since: 0.29
++dnl
++dnl Verify that the version of the pkg-config macros are at least
++dnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's
++dnl installed version of pkg-config, this checks the developer's version
++dnl of pkg.m4 when generating configure.
++dnl
++dnl To ensure that this macro is defined, also add:
++dnl m4_ifndef([PKG_PREREQ],
++dnl [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])])
++dnl
++dnl See the "Since" comment for each macro you use to see what version
++dnl of the macros you require.
++m4_defun([PKG_PREREQ],
++[m4_define([PKG_MACROS_VERSION], [0.29.1])
++m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,
++ [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])
++])dnl PKG_PREREQ
++
++dnl PKG_PROG_PKG_CONFIG([MIN-VERSION])
++dnl ----------------------------------
++dnl Since: 0.16
++dnl
++dnl Search for the pkg-config tool and set the PKG_CONFIG variable to
++dnl first found in the path. Checks that the version of pkg-config found
++dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is
++dnl used since that's the first version where most current features of
++dnl pkg-config existed.
++AC_DEFUN([PKG_PROG_PKG_CONFIG],
++[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
++m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])
++m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$])
++AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])
++AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path])
++AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path])
++
++if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
++ AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
++fi
++if test -n "$PKG_CONFIG"; then
++ _pkg_min_version=m4_default([$1], [0.9.0])
++ AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
++ if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
++ AC_MSG_RESULT([yes])
++ else
++ AC_MSG_RESULT([no])
++ PKG_CONFIG=""
++ fi
++fi[]dnl
++])dnl PKG_PROG_PKG_CONFIG
++
++dnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
++dnl -------------------------------------------------------------------
++dnl Since: 0.18
++dnl
++dnl Check to see whether a particular set of modules exists. Similar to
++dnl PKG_CHECK_MODULES(), but does not set variables or print errors.
++dnl
++dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
++dnl only at the first occurence in configure.ac, so if the first place
++dnl it's called might be skipped (such as if it is within an "if", you
++dnl have to call PKG_CHECK_EXISTS manually
++AC_DEFUN([PKG_CHECK_EXISTS],
++[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
++if test -n "$PKG_CONFIG" && \
++ AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
++ m4_default([$2], [:])
++m4_ifvaln([$3], [else
++ $3])dnl
++fi])
++
++dnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
++dnl ---------------------------------------------
++dnl Internal wrapper calling pkg-config via PKG_CONFIG and setting
++dnl pkg_failed based on the result.
++m4_define([_PKG_CONFIG],
++[if test -n "$$1"; then
++ pkg_cv_[]$1="$$1"
++ elif test -n "$PKG_CONFIG"; then
++ PKG_CHECK_EXISTS([$3],
++ [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`
++ test "x$?" != "x0" && pkg_failed=yes ],
++ [pkg_failed=yes])
++ else
++ pkg_failed=untried
++fi[]dnl
++])dnl _PKG_CONFIG
++
++dnl _PKG_SHORT_ERRORS_SUPPORTED
++dnl ---------------------------
++dnl Internal check to see if pkg-config supports short errors.
++AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
++[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
++if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
++ _pkg_short_errors_supported=yes
++else
++ _pkg_short_errors_supported=no
++fi[]dnl
++])dnl _PKG_SHORT_ERRORS_SUPPORTED
++
++
++dnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
++dnl [ACTION-IF-NOT-FOUND])
++dnl --------------------------------------------------------------
++dnl Since: 0.4.0
++dnl
++dnl Note that if there is a possibility the first call to
++dnl PKG_CHECK_MODULES might not happen, you should be sure to include an
++dnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
++AC_DEFUN([PKG_CHECK_MODULES],
++[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
++AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
++AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
++
++pkg_failed=no
++AC_MSG_CHECKING([for $1])
++
++_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
++_PKG_CONFIG([$1][_LIBS], [libs], [$2])
++
++m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
++and $1[]_LIBS to avoid the need to call pkg-config.
++See the pkg-config man page for more details.])
++
++if test $pkg_failed = yes; then
++ AC_MSG_RESULT([no])
++ _PKG_SHORT_ERRORS_SUPPORTED
++ if test $_pkg_short_errors_supported = yes; then
++ $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
++ else
++ $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
++ fi
++ # Put the nasty error message in config.log where it belongs
++ echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
++
++ m4_default([$4], [AC_MSG_ERROR(
++[Package requirements ($2) were not met:
++
++$$1_PKG_ERRORS
++
++Consider adjusting the PKG_CONFIG_PATH environment variable if you
++installed software in a non-standard prefix.
++
++_PKG_TEXT])[]dnl
++ ])
++elif test $pkg_failed = untried; then
++ AC_MSG_RESULT([no])
++ m4_default([$4], [AC_MSG_FAILURE(
++[The pkg-config script could not be found or is too old. Make sure it
++is in your PATH or set the PKG_CONFIG environment variable to the full
++path to pkg-config.
++
++_PKG_TEXT
++
++To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl
++ ])
++else
++ $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
++ $1[]_LIBS=$pkg_cv_[]$1[]_LIBS
++ AC_MSG_RESULT([yes])
++ $3
++fi[]dnl
++])dnl PKG_CHECK_MODULES
++
++
++dnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
++dnl [ACTION-IF-NOT-FOUND])
++dnl ---------------------------------------------------------------------
++dnl Since: 0.29
++dnl
++dnl Checks for existence of MODULES and gathers its build flags with
++dnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags
++dnl and VARIABLE-PREFIX_LIBS from --libs.
++dnl
++dnl Note that if there is a possibility the first call to
++dnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to
++dnl include an explicit call to PKG_PROG_PKG_CONFIG in your
++dnl configure.ac.
++AC_DEFUN([PKG_CHECK_MODULES_STATIC],
++[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
++_save_PKG_CONFIG=$PKG_CONFIG
++PKG_CONFIG="$PKG_CONFIG --static"
++PKG_CHECK_MODULES($@)
++PKG_CONFIG=$_save_PKG_CONFIG[]dnl
++])dnl PKG_CHECK_MODULES_STATIC
++
++
++dnl PKG_INSTALLDIR([DIRECTORY])
++dnl -------------------------
++dnl Since: 0.27
++dnl
++dnl Substitutes the variable pkgconfigdir as the location where a module
++dnl should install pkg-config .pc files. By default the directory is
++dnl $libdir/pkgconfig, but the default can be changed by passing
++dnl DIRECTORY. The user can override through the --with-pkgconfigdir
++dnl parameter.
++AC_DEFUN([PKG_INSTALLDIR],
++[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])])
++m4_pushdef([pkg_description],
++ [pkg-config installation directory @<:@]pkg_default[@:>@])
++AC_ARG_WITH([pkgconfigdir],
++ [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],,
++ [with_pkgconfigdir=]pkg_default)
++AC_SUBST([pkgconfigdir], [$with_pkgconfigdir])
++m4_popdef([pkg_default])
++m4_popdef([pkg_description])
++])dnl PKG_INSTALLDIR
++
++
++dnl PKG_NOARCH_INSTALLDIR([DIRECTORY])
++dnl --------------------------------
++dnl Since: 0.27
++dnl
++dnl Substitutes the variable noarch_pkgconfigdir as the location where a
++dnl module should install arch-independent pkg-config .pc files. By
++dnl default the directory is $datadir/pkgconfig, but the default can be
++dnl changed by passing DIRECTORY. The user can override through the
++dnl --with-noarch-pkgconfigdir parameter.
++AC_DEFUN([PKG_NOARCH_INSTALLDIR],
++[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])])
++m4_pushdef([pkg_description],
++ [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@])
++AC_ARG_WITH([noarch-pkgconfigdir],
++ [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],,
++ [with_noarch_pkgconfigdir=]pkg_default)
++AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir])
++m4_popdef([pkg_default])
++m4_popdef([pkg_description])
++])dnl PKG_NOARCH_INSTALLDIR
++
++
++dnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE,
++dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
++dnl -------------------------------------------
++dnl Since: 0.28
++dnl
++dnl Retrieves the value of the pkg-config variable for the given module.
++AC_DEFUN([PKG_CHECK_VAR],
++[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
++AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl
++
++_PKG_CONFIG([$1], [variable="][$3]["], [$2])
++AS_VAR_COPY([$1], [pkg_cv_][$1])
++
++AS_VAR_IF([$1], [""], [$5], [$4])dnl
++])dnl PKG_CHECK_VAR
++
++dnl PKG_WITH_MODULES(VARIABLE-PREFIX, MODULES,
++dnl [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND],
++dnl [DESCRIPTION], [DEFAULT])
++dnl ------------------------------------------
++dnl
++dnl Prepare a "--with-" configure option using the lowercase
++dnl [VARIABLE-PREFIX] name, merging the behaviour of AC_ARG_WITH and
++dnl PKG_CHECK_MODULES in a single macro.
++AC_DEFUN([PKG_WITH_MODULES],
++[
++m4_pushdef([with_arg], m4_tolower([$1]))
++
++m4_pushdef([description],
++ [m4_default([$5], [build with ]with_arg[ support])])
++
++m4_pushdef([def_arg], [m4_default([$6], [auto])])
++m4_pushdef([def_action_if_found], [AS_TR_SH([with_]with_arg)=yes])
++m4_pushdef([def_action_if_not_found], [AS_TR_SH([with_]with_arg)=no])
++
++m4_case(def_arg,
++ [yes],[m4_pushdef([with_without], [--without-]with_arg)],
++ [m4_pushdef([with_without],[--with-]with_arg)])
++
++AC_ARG_WITH(with_arg,
++ AS_HELP_STRING(with_without, description[ @<:@default=]def_arg[@:>@]),,
++ [AS_TR_SH([with_]with_arg)=def_arg])
++
++AS_CASE([$AS_TR_SH([with_]with_arg)],
++ [yes],[PKG_CHECK_MODULES([$1],[$2],$3,$4)],
++ [auto],[PKG_CHECK_MODULES([$1],[$2],
++ [m4_n([def_action_if_found]) $3],
++ [m4_n([def_action_if_not_found]) $4])])
++
++m4_popdef([with_arg])
++m4_popdef([description])
++m4_popdef([def_arg])
++
++])dnl PKG_WITH_MODULES
++
++dnl PKG_HAVE_WITH_MODULES(VARIABLE-PREFIX, MODULES,
++dnl [DESCRIPTION], [DEFAULT])
++dnl -----------------------------------------------
++dnl
++dnl Convenience macro to trigger AM_CONDITIONAL after PKG_WITH_MODULES
++dnl check._[VARIABLE-PREFIX] is exported as make variable.
++AC_DEFUN([PKG_HAVE_WITH_MODULES],
++[
++PKG_WITH_MODULES([$1],[$2],,,[$3],[$4])
++
++AM_CONDITIONAL([HAVE_][$1],
++ [test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"])
++])dnl PKG_HAVE_WITH_MODULES
++
++dnl PKG_HAVE_DEFINE_WITH_MODULES(VARIABLE-PREFIX, MODULES,
++dnl [DESCRIPTION], [DEFAULT])
++dnl ------------------------------------------------------
++dnl
++dnl Convenience macro to run AM_CONDITIONAL and AC_DEFINE after
++dnl PKG_WITH_MODULES check. HAVE_[VARIABLE-PREFIX] is exported as make
++dnl and preprocessor variable.
++AC_DEFUN([PKG_HAVE_DEFINE_WITH_MODULES],
++[
++PKG_HAVE_WITH_MODULES([$1],[$2],[$3],[$4])
++
++AS_IF([test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"],
++ [AC_DEFINE([HAVE_][$1], 1, [Enable ]m4_tolower([$1])[ support])])
++])dnl PKG_HAVE_DEFINE_WITH_MODULES
++
++# AM_CONDITIONAL -*- Autoconf -*-
++
++# Copyright (C) 1997-2018 Free Software Foundation, Inc.
++#
++# This file is free software; the Free Software Foundation
++# gives unlimited permission to copy and/or distribute it,
++# with or without modifications, as long as this notice is preserved.
++
++# AM_CONDITIONAL(NAME, SHELL-CONDITION)
++# -------------------------------------
++# Define a conditional.
++AC_DEFUN([AM_CONDITIONAL],
++[AC_PREREQ([2.52])dnl
++ m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
++ [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
++AC_SUBST([$1_TRUE])dnl
++AC_SUBST([$1_FALSE])dnl
++_AM_SUBST_NOTMAKE([$1_TRUE])dnl
++_AM_SUBST_NOTMAKE([$1_FALSE])dnl
++m4_define([_AM_COND_VALUE_$1], [$2])dnl
++if $2; then
++ $1_TRUE=
++ $1_FALSE='#'
++else
++ $1_TRUE='#'
++ $1_FALSE=
++fi
++AC_CONFIG_COMMANDS_PRE(
++[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
++ AC_MSG_ERROR([[conditional "$1" was never defined.
++Usually this means the macro was only invoked conditionally.]])
++fi])])
++
++# Copyright (C) 2006-2018 Free Software Foundation, Inc.
++#
++# This file is free software; the Free Software Foundation
++# gives unlimited permission to copy and/or distribute it,
++# with or without modifications, as long as this notice is preserved.
++
++# _AM_SUBST_NOTMAKE(VARIABLE)
++# ---------------------------
++# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
++# This macro is traced by Automake.
++AC_DEFUN([_AM_SUBST_NOTMAKE])
++
++# AM_SUBST_NOTMAKE(VARIABLE)
++# --------------------------
++# Public sister of _AM_SUBST_NOTMAKE.
++AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
++
+--- contrib/unbound/acx_nlnetlabs.m4.orig
++++ contrib/unbound/acx_nlnetlabs.m4
+@@ -688,8 +688,8 @@
+ # check if -lwsock32 or -lgdi32 are needed.
+ BAKLIBS="$LIBS"
+ BAKSSLLIBS="$LIBSSL_LIBS"
+- LIBS="$LIBS -lgdi32"
+- LIBSSL_LIBS="$LIBSSL_LIBS -lgdi32"
++ LIBS="$LIBS -lgdi32 -lws2_32"
++ LIBSSL_LIBS="$LIBSSL_LIBS -lgdi32 -lws2_32"
+ AC_MSG_CHECKING([if -lcrypto needs -lgdi32])
+ AC_TRY_LINK([], [
+ int HMAC_Update(void);
+@@ -839,7 +839,11 @@
+ if test "$ac_cv_header_windows_h" = "yes"; then
+ AC_DEFINE(USE_WINSOCK, 1, [Whether the windows socket API is used])
+ USE_WINSOCK="1"
+- LIBS="$LIBS -lws2_32"
++ if echo $LIBS | grep 'lws2_32' >/dev/null; then
++ :
++ else
++ LIBS="$LIBS -lws2_32"
++ fi
+ fi
+ ],
+ dnl no quick getaddrinfo, try mingw32 and winsock2 library.
+--- contrib/unbound/acx_python.m4.orig
++++ contrib/unbound/acx_python.m4
+@@ -22,8 +22,7 @@
+ # Check if you have distutils, else fail
+ #
+ AC_MSG_CHECKING([for the distutils Python package])
+- ac_distutils_result=`$PYTHON -c "import distutils" 2>&1`
+- if test -z "$ac_distutils_result"; then
++ if ac_distutils_result=`$PYTHON -c "import distutils" 2>&1`; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+--- contrib/unbound/cachedb/cachedb.c.orig
++++ contrib/unbound/cachedb/cachedb.c
+@@ -43,6 +43,7 @@
+ #include "config.h"
+ #ifdef USE_CACHEDB
+ #include "cachedb/cachedb.h"
++#include "cachedb/redis.h"
+ #include "util/regional.h"
+ #include "util/net_help.h"
+ #include "util/config_file.h"
+@@ -56,11 +57,39 @@
+ #include "sldns/wire2str.h"
+ #include "sldns/sbuffer.h"
+
+-#define CACHEDB_HASHSIZE 256 /* bit hash */
++/* header file for htobe64 */
++#ifdef HAVE_ENDIAN_H
++# include <endian.h>
++#endif
++#ifdef HAVE_SYS_ENDIAN_H
++# include <sys/endian.h>
++#endif
+
++#ifndef HAVE_HTOBE64
++# ifdef HAVE_LIBKERN_OSBYTEORDER_H
++ /* In practice this is specific to MacOS X. We assume it doesn't have
++ * htobe64/be64toh but has alternatives with a different name. */
++# include <libkern/OSByteOrder.h>
++# define htobe64(x) OSSwapHostToBigInt64(x)
++# define be64toh(x) OSSwapBigToHostInt64(x)
++# else
++ /* not OSX */
++ /* Some compilers do not define __BYTE_ORDER__, like IBM XLC on AIX */
++# if __BIG_ENDIAN__
++# define be64toh(n) (n)
++# define htobe64(n) (n)
++# else
++# define be64toh(n) (((uint64_t)htonl((n) & 0xFFFFFFFF) << 32) | htonl((n) >> 32))
++# define htobe64(n) (((uint64_t)htonl((n) & 0xFFFFFFFF) << 32) | htonl((n) >> 32))
++# endif /* _ENDIAN */
++# endif /* HAVE_LIBKERN_OSBYTEORDER_H */
++#endif /* HAVE_BE64TOH */
++
+ /** the unit test testframe for cachedb, its module state contains
+ * a cache for a couple queries (in memory). */
+ struct testframe_moddata {
++ /** lock for mutex */
++ lock_basic_type lock;
+ /** key for single stored data element, NULL if none */
+ char* stored_key;
+ /** data for single stored data element, NULL if none */
+@@ -72,14 +101,18 @@
+ static int
+ testframe_init(struct module_env* env, struct cachedb_env* cachedb_env)
+ {
++ struct testframe_moddata* d;
+ (void)env;
+ verbose(VERB_ALGO, "testframe_init");
+- cachedb_env->backend_data = (void*)calloc(1,
++ d = (struct testframe_moddata*)calloc(1,
+ sizeof(struct testframe_moddata));
++ cachedb_env->backend_data = (void*)d;
+ if(!cachedb_env->backend_data) {
+ log_err("out of memory");
+ return 0;
+ }
++ lock_basic_init(&d->lock);
++ lock_protect(&d->lock, d, sizeof(*d));
+ return 1;
+ }
+
+@@ -92,6 +125,7 @@
+ verbose(VERB_ALGO, "testframe_deinit");
+ if(!d)
+ return;
++ lock_basic_destroy(&d->lock);
+ free(d->stored_key);
+ free(d->stored_data);
+ free(d);
+@@ -105,9 +139,12 @@
+ cachedb_env->backend_data;
+ (void)env;
+ verbose(VERB_ALGO, "testframe_lookup of %s", key);
++ lock_basic_lock(&d->lock);
+ if(d->stored_key && strcmp(d->stored_key, key) == 0) {
+- if(d->stored_datalen > sldns_buffer_capacity(result_buffer))
++ if(d->stored_datalen > sldns_buffer_capacity(result_buffer)) {
++ lock_basic_unlock(&d->lock);
+ return 0; /* too large */
++ }
+ verbose(VERB_ALGO, "testframe_lookup found %d bytes",
+ (int)d->stored_datalen);
+ sldns_buffer_clear(result_buffer);
+@@ -114,8 +151,10 @@
+ sldns_buffer_write(result_buffer, d->stored_data,
+ d->stored_datalen);
+ sldns_buffer_flip(result_buffer);
++ lock_basic_unlock(&d->lock);
+ return 1;
+ }
++ lock_basic_unlock(&d->lock);
+ return 0;
+ }
+
+@@ -126,6 +165,7 @@
+ struct testframe_moddata* d = (struct testframe_moddata*)
+ cachedb_env->backend_data;
+ (void)env;
++ lock_basic_lock(&d->lock);
+ verbose(VERB_ALGO, "testframe_store %s (%d bytes)", key, (int)data_len);
+
+ /* free old data element (if any) */
+@@ -137,6 +177,7 @@
+
+ d->stored_data = memdup(data, data_len);
+ if(!d->stored_data) {
++ lock_basic_unlock(&d->lock);
+ log_err("out of memory");
+ return;
+ }
+@@ -146,8 +187,10 @@
+ free(d->stored_data);
+ d->stored_data = NULL;
+ d->stored_datalen = 0;
++ lock_basic_unlock(&d->lock);
+ return;
+ }
++ lock_basic_unlock(&d->lock);
+ /* (key,data) successfully stored */
+ }
+
+@@ -160,6 +203,10 @@
+ static struct cachedb_backend*
+ cachedb_find_backend(const char* str)
+ {
++#ifdef USE_REDIS
++ if(strcmp(str, redis_backend.name) == 0)
++ return &redis_backend;
++#endif
+ if(strcmp(str, testframe_backend.name) == 0)
+ return &testframe_backend;
+ /* TODO add more backends here */
+@@ -170,15 +217,13 @@
+ static int
+ cachedb_apply_cfg(struct cachedb_env* cachedb_env, struct config_file* cfg)
+ {
+- const char* backend_str = "testframe"; /* TODO get from cfg */
+- if(backend_str && backend_str[0]) {
+- cachedb_env->backend = cachedb_find_backend(backend_str);
+- if(!cachedb_env->backend) {
+- log_err("cachedb: cannot find backend name '%s",
+- backend_str);
+- return NULL;
+- }
++ const char* backend_str = cfg->cachedb_backend;
++ cachedb_env->backend = cachedb_find_backend(backend_str);
++ if(!cachedb_env->backend) {
++ log_err("cachedb: cannot find backend name '%s'", backend_str);
++ return 0;
+ }
++
+ /* TODO see if more configuration needs to be applied or not */
+ return 1;
+ }
+@@ -195,6 +240,8 @@
+ env->modinfo[id] = (void*)cachedb_env;
+ if(!cachedb_apply_cfg(cachedb_env, env->cfg)) {
+ log_err("cachedb: could not apply configuration settings.");
++ free(cachedb_env);
++ env->modinfo[id] = NULL;
+ return 0;
+ }
+ /* see if a backend is selected */
+@@ -203,9 +250,20 @@
+ if(!(*cachedb_env->backend->init)(env, cachedb_env)) {
+ log_err("cachedb: could not init %s backend",
+ cachedb_env->backend->name);
++ free(cachedb_env);
++ env->modinfo[id] = NULL;
+ return 0;
+ }
+ cachedb_env->enabled = 1;
++ if(env->cfg->serve_expired_reply_ttl)
++ log_warn(
++ "cachedb: serve-expired-reply-ttl is set but not working for data "
++ "originating from the external cache; 0 TLL is used for those.");
++ if(env->cfg->serve_expired_client_timeout)
++ log_warn(
++ "cachedb: serve-expired-client-timeout is set but not working for "
++ "data originating from the external cache; expired data are used "
++ "in the reply without first trying to refresh the data.");
+ return 1;
+ }
+
+@@ -276,9 +334,9 @@
+ size_t clen = 0;
+ uint8_t hash[CACHEDB_HASHSIZE/8];
+ const char* hex = "0123456789ABCDEF";
+- const char* secret = "default"; /* TODO: from qstate->env->cfg */
++ const char* secret = qstate->env->cfg->cachedb_secret;
+ size_t i;
+-
++
+ /* copy the hash info into the clear buffer */
+ if(clen + qstate->qinfo.qname_len < sizeof(clear)) {
+ memmove(clear+clen, qstate->qinfo.qname,
+@@ -299,7 +357,11 @@
+
+ /* hash the buffer */
+ secalgo_hash_sha256(clear, clen, hash);
++#ifdef HAVE_EXPLICIT_BZERO
++ explicit_bzero(clear, clen);
++#else
+ memset(clear, 0, clen);
++#endif
+
+ /* hex encode output for portability (some online dbs need
+ * no nulls, no control characters, and so on) */
+@@ -328,6 +390,13 @@
+
+ if(!qstate->return_msg || !qstate->return_msg->rep)
+ return 0;
++ /* We don't store the reply if its TTL is 0 unless serve-expired is
++ * enabled. Such a reply won't be reusable and simply be a waste for
++ * the backend. It's also compatible with the default behavior of
++ * dns_cache_store_msg(). */
++ if(qstate->return_msg->rep->ttl == 0 &&
++ !qstate->env->cfg->serve_expired)
++ return 0;
+ if(verbosity >= VERB_ALGO)
+ log_dns_msg("cachedb encoding", &qstate->return_msg->qinfo,
+ qstate->return_msg->rep);
+@@ -368,12 +437,55 @@
+ &expiry, sizeof(expiry));
+ expiry = be64toh(expiry);
+
+- if((time_t)expiry < *qstate->env->now)
++ /* Check if we are allowed to return expired entries:
++ * - serve_expired needs to be set
++ * - if SERVE_EXPIRED_TTL is set make sure that the record is not older
++ * than that. */
++ if((time_t)expiry < *qstate->env->now &&
++ (!qstate->env->cfg->serve_expired ||
++ (SERVE_EXPIRED_TTL &&
++ *qstate->env->now - (time_t)expiry > SERVE_EXPIRED_TTL)))
+ return 0;
+
+ return 1;
+ }
+
++/* Adjust the TTL of the given RRset by 'subtract'. If 'subtract' is
++ * negative, set the TTL to 0. */
++static void
++packed_rrset_ttl_subtract(struct packed_rrset_data* data, time_t subtract)
++{
++ size_t i;
++ size_t total = data->count + data->rrsig_count;
++ if(subtract >= 0 && data->ttl > subtract)
++ data->ttl -= subtract;
++ else data->ttl = 0;
++ for(i=0; i<total; i++) {
++ if(subtract >= 0 && data->rr_ttl[i] > subtract)
++ data->rr_ttl[i] -= subtract;
++ else data->rr_ttl[i] = 0;
++ }
++}
++
++/* Adjust the TTL of a DNS message and its RRs by 'adjust'. If 'adjust' is
++ * negative, set the TTLs to 0. */
++static void
++adjust_msg_ttl(struct dns_msg* msg, time_t adjust)
++{
++ size_t i;
++ if(adjust >= 0 && msg->rep->ttl > adjust)
++ msg->rep->ttl -= adjust;
++ else
++ msg->rep->ttl = 0;
++ msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl);
++ msg->rep->serve_expired_ttl = msg->rep->ttl + SERVE_EXPIRED_TTL;
++
++ for(i=0; i<msg->rep->rrset_count; i++) {
++ packed_rrset_ttl_subtract((struct packed_rrset_data*)msg->
++ rep->rrsets[i]->entry.data, adjust);
++ }
++}
++
+ /** convert dns message in buffer to return_msg */
+ static int
+ parse_data(struct module_qstate* qstate, struct sldns_buffer* buf)
+@@ -420,24 +532,34 @@
+ qstate->return_rcode = LDNS_RCODE_NOERROR;
+
+ /* see how much of the TTL expired, and remove it */
++ if(*qstate->env->now <= (time_t)timestamp) {
++ verbose(VERB_ALGO, "cachedb msg adjust by zero");
++ return 1; /* message from the future (clock skew?) */
++ }
+ adjust = *qstate->env->now - (time_t)timestamp;
++ if(qstate->return_msg->rep->ttl < adjust) {
++ verbose(VERB_ALGO, "cachedb msg expired");
++ /* If serve-expired is enabled, we still use an expired message
++ * setting the TTL to 0. */
++ if(qstate->env->cfg->serve_expired)
++ adjust = -1;
++ else
++ return 0; /* message expired */
++ }
+ verbose(VERB_ALGO, "cachedb msg adjusted down by %d", (int)adjust);
+- /*adjust_msg(qstate->return_msg, adjust);*/
+- /* TODO:
+- msg->rep->ttl = r->ttl - adjust;
+- msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl);
+- for(i=0; i<d->count + d->rrsig_count; i++) {
+- if(d->rr_ttl[i] < adjust)
+- d->rr_ttl[i] = 0;
+- else d->rr_ttl[i] -= adjust;
+- }
+- if(d->ttl < adjust)
+- d->ttl = 0;
+- else d->ttl -= adjust;
+- */
+- /* TODO */
++ adjust_msg_ttl(qstate->return_msg, adjust);
+
+- return 0;
++ /* Similar to the unbound worker, if serve-expired is enabled and
++ * the msg would be considered to be expired, mark the state so a
++ * refetch will be scheduled. The comparison between 'expiry' and
++ * 'now' should be redundant given how these values were calculated,
++ * but we check it just in case as does good_expiry_and_qinfo(). */
++ if(qstate->env->cfg->serve_expired &&
++ (adjust == -1 || (time_t)expiry < *qstate->env->now)) {
++ qstate->need_refetch = 1;
++ }
++
++ return 1;
+ }
+
+ /**
+@@ -497,14 +619,18 @@
+ msg = dns_cache_lookup(qstate->env, qstate->qinfo.qname,
+ qstate->qinfo.qname_len, qstate->qinfo.qtype,
+ qstate->qinfo.qclass, qstate->query_flags,
+- qstate->region, qstate->env->scratch);
+- if(!msg && qstate->env->neg_cache) {
++ qstate->region, qstate->env->scratch,
++ 1 /* no partial messages with only a CNAME */
++ );
++ if(!msg && qstate->env->neg_cache &&
++ iter_qname_indicates_dnssec(qstate->env, &qstate->qinfo)) {
+ /* lookup in negative cache; may result in
+ * NOERROR/NODATA or NXDOMAIN answers that need validation */
+ msg = val_neg_getmsg(qstate->env->neg_cache, &qstate->qinfo,
+ qstate->region, qstate->env->rrset_cache,
+ qstate->env->scratch_buffer,
+- *qstate->env->now, 1/*add SOA*/, NULL);
++ *qstate->env->now, 1/*add SOA*/, NULL,
++ qstate->env->cfg);
+ }
+ if(!msg)
+ return 0;
+@@ -520,11 +646,15 @@
+ static void
+ cachedb_intcache_store(struct module_qstate* qstate)
+ {
++ uint32_t store_flags = qstate->query_flags;
++
++ if(qstate->env->cfg->serve_expired)
++ store_flags |= DNSCACHE_STORE_ZEROTTL;
+ if(!qstate->return_msg)
+ return;
+ (void)dns_cache_store(qstate->env, &qstate->qinfo,
+ qstate->return_msg->rep, 0, qstate->prefetch_leeway, 0,
+- qstate->region, qstate->query_flags);
++ qstate->region, store_flags);
+ }
+
+ /**
+@@ -547,19 +677,26 @@
+ return;
+ }
+
+- if(qstate->blacklist) {
+- /* cache is blacklisted */
++ if(qstate->blacklist || qstate->no_cache_lookup) {
++ /* cache is blacklisted or we are instructed from edns to not look */
+ /* pass request to next module */
+ qstate->ext_state[id] = module_wait_module;
+ return;
+ }
+
+- /* lookup inside unbound's internal cache */
++ /* lookup inside unbound's internal cache.
++ * This does not look for expired entries. */
+ if(cachedb_intcache_lookup(qstate)) {
+- if(verbosity >= VERB_ALGO)
+- log_dns_msg("cachedb internal cache lookup",
+- &qstate->return_msg->qinfo,
+- qstate->return_msg->rep);
++ if(verbosity >= VERB_ALGO) {
++ if(qstate->return_msg->rep)
++ log_dns_msg("cachedb internal cache lookup",
++ &qstate->return_msg->qinfo,
++ qstate->return_msg->rep);
++ else log_info("cachedb internal cache lookup: rcode %s",
++ sldns_lookup_by_id(sldns_rcodes, qstate->return_rcode)
++ ?sldns_lookup_by_id(sldns_rcodes, qstate->return_rcode)->name
++ :"??");
++ }
+ /* we are done with the query */
+ qstate->ext_state[id] = module_finished;
+ return;
+@@ -573,6 +710,19 @@
+ qstate->return_msg->rep);
+ /* store this result in internal cache */
+ cachedb_intcache_store(qstate);
++ /* In case we have expired data but there is a client timer for expired
++ * answers, pass execution to next module in order to try updating the
++ * data first.
++ * TODO: this needs revisit. The expired data stored from cachedb has
++ * 0 TTL which is picked up by iterator later when looking in the cache.
++ * Document that ext cachedb does not work properly with
++ * serve_stale_reply_ttl yet. */
++ if(qstate->need_refetch && qstate->serve_expired_data &&
++ qstate->serve_expired_data->timer) {
++ qstate->return_msg = NULL;
++ qstate->ext_state[id] = module_wait_module;
++ return;
++ }
+ /* we are done with the query */
+ qstate->ext_state[id] = module_finished;
+ return;
+@@ -595,8 +745,8 @@
+ cachedb_handle_response(struct module_qstate* qstate,
+ struct cachedb_qstate* ATTR_UNUSED(iq), struct cachedb_env* ie, int id)
+ {
+- /* check if we are enabled, and skip if not */
+- if(!ie->enabled) {
++ /* check if we are not enabled or instructed to not cache, and skip */
++ if(!ie->enabled || qstate->no_cache_store) {
+ /* we are done with the query */
+ qstate->ext_state[id] = module_finished;
+ return;
+@@ -649,6 +799,11 @@
+ (void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
+ return;
+ }
++ if(!iq && (event == module_event_moddone)) {
++ /* during priming, module done but we never started */
++ qstate->ext_state[id] = module_finished;
++ return;
++ }
+
+ log_err("bad event for cachedb");
+ (void)error_response(qstate, id, LDNS_RCODE_SERVFAIL);
+--- contrib/unbound/cachedb/cachedb.h.orig
++++ contrib/unbound/cachedb/cachedb.h
+@@ -87,6 +87,8 @@
+ uint8_t*, size_t);
+ };
+
++#define CACHEDB_HASHSIZE 256 /* bit hash */
++
+ /** Init the cachedb module */
+ int cachedb_init(struct module_env* env, int id);
+ /** Deinit the cachedb module */
+--- contrib/unbound/cachedb/redis.c.orig
++++ contrib/unbound/cachedb/redis.c
+@@ -0,0 +1,283 @@
++/*
++ * cachedb/redis.c - cachedb redis module
++ *
++ * Copyright (c) 2018, NLnet Labs. All rights reserved.
++ *
++ * This software is open source.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ *
++ * Redistributions of source code must retain the above copyright notice,
++ * this list of conditions and the following disclaimer.
++ *
++ * Redistributions in binary form must reproduce the above copyright notice,
++ * this list of conditions and the following disclaimer in the documentation
++ * and/or other materials provided with the distribution.
++ *
++ * Neither the name of the NLNET LABS nor the names of its contributors may
++ * be used to endorse or promote products derived from this software without
++ * specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
++ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
++ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
++ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++
++/**
++ * \file
++ *
++ * This file contains a module that uses the redis database to cache
++ * dns responses.
++ */
++
++#include "config.h"
++#ifdef USE_CACHEDB
++#include "cachedb/redis.h"
++#include "cachedb/cachedb.h"
++#include "util/alloc.h"
++#include "util/config_file.h"
++#include "sldns/sbuffer.h"
++
++#ifdef USE_REDIS
++#include "hiredis/hiredis.h"
++
++struct redis_moddata {
++ redisContext** ctxs; /* thread-specific redis contexts */
++ int numctxs; /* number of ctx entries */
++ const char* server_host; /* server's IP address or host name */
++ int server_port; /* server's TCP port */
++ struct timeval timeout; /* timeout for connection setup and commands */
++};
++
++static redisContext*
++redis_connect(const struct redis_moddata* moddata)
++{
++ redisContext* ctx;
++
++ ctx = redisConnectWithTimeout(moddata->server_host,
++ moddata->server_port, moddata->timeout);
++ if(!ctx || ctx->err) {
++ const char *errstr = "out of memory";
++ if(ctx)
++ errstr = ctx->errstr;
++ log_err("failed to connect to redis server: %s", errstr);
++ goto fail;
++ }
++ if(redisSetTimeout(ctx, moddata->timeout) != REDIS_OK) {
++ log_err("failed to set redis timeout");
++ goto fail;
++ }
++ return ctx;
++
++ fail:
++ if(ctx)
++ redisFree(ctx);
++ return NULL;
++}
++
++static int
++redis_init(struct module_env* env, struct cachedb_env* cachedb_env)
++{
++ int i;
++ struct redis_moddata* moddata = NULL;
++
++ verbose(VERB_ALGO, "redis_init");
++
++ moddata = calloc(1, sizeof(struct redis_moddata));
++ if(!moddata) {
++ log_err("out of memory");
++ return 0;
++ }
++ moddata->numctxs = env->cfg->num_threads;
++ moddata->ctxs = calloc(env->cfg->num_threads, sizeof(redisContext*));
++ if(!moddata->ctxs) {
++ log_err("out of memory");
++ free(moddata);
++ return 0;
++ }
++ /* note: server_host is a shallow reference to configured string.
++ * we don't have to free it in this module. */
++ moddata->server_host = env->cfg->redis_server_host;
++ moddata->server_port = env->cfg->redis_server_port;
++ moddata->timeout.tv_sec = env->cfg->redis_timeout / 1000;
++ moddata->timeout.tv_usec = (env->cfg->redis_timeout % 1000) * 1000;
++ for(i = 0; i < moddata->numctxs; i++)
++ moddata->ctxs[i] = redis_connect(moddata);
++ cachedb_env->backend_data = moddata;
++ return 1;
++}
++
++static void
++redis_deinit(struct module_env* env, struct cachedb_env* cachedb_env)
++{
++ struct redis_moddata* moddata = (struct redis_moddata*)
++ cachedb_env->backend_data;
++ (void)env;
++
++ verbose(VERB_ALGO, "redis_deinit");
++
++ if(!moddata)
++ return;
++ if(moddata->ctxs) {
++ int i;
++ for(i = 0; i < moddata->numctxs; i++) {
++ if(moddata->ctxs[i])
++ redisFree(moddata->ctxs[i]);
++ }
++ free(moddata->ctxs);
++ }
++ free(moddata);
++}
++
++/*
++ * Send a redis command and get a reply. Unified so that it can be used for
++ * both SET and GET. If 'data' is non-NULL the command is supposed to be
++ * SET and GET otherwise, but the implementation of this function is agnostic
++ * about the semantics (except for logging): 'command', 'data', and 'data_len'
++ * are opaquely passed to redisCommand().
++ * This function first checks whether a connection with a redis server has
++ * been established; if not it tries to set up a new one.
++ * It returns redisReply returned from redisCommand() or NULL if some low
++ * level error happens. The caller is responsible to check the return value,
++ * if it's non-NULL, it has to free it with freeReplyObject().
++ */
++static redisReply*
++redis_command(struct module_env* env, struct cachedb_env* cachedb_env,
++ const char* command, const uint8_t* data, size_t data_len)
++{
++ redisContext* ctx;
++ redisReply* rep;
++ struct redis_moddata* d = (struct redis_moddata*)
++ cachedb_env->backend_data;
++
++ /* We assume env->alloc->thread_num is a unique ID for each thread
++ * in [0, num-of-threads). We could treat it as an error condition
++ * if the assumption didn't hold, but it seems to be a fundamental
++ * assumption throughout the unbound architecture, so we simply assert
++ * it. */
++ log_assert(env->alloc->thread_num < d->numctxs);
++ ctx = d->ctxs[env->alloc->thread_num];
++
++ /* If we've not established a connection to the server or we've closed
++ * it on a failure, try to re-establish a new one. Failures will be
++ * logged in redis_connect(). */
++ if(!ctx) {
++ ctx = redis_connect(d);
++ d->ctxs[env->alloc->thread_num] = ctx;
++ }
++ if(!ctx)
++ return NULL;
++
++ /* Send the command and get a reply, synchronously. */
++ rep = (redisReply*)redisCommand(ctx, command, data, data_len);
++ if(!rep) {
++ /* Once an error as a NULL-reply is returned the context cannot
++ * be reused and we'll need to set up a new connection. */
++ log_err("redis_command: failed to receive a reply, "
++ "closing connection: %s", ctx->errstr);
++ redisFree(ctx);
++ d->ctxs[env->alloc->thread_num] = NULL;
++ return NULL;
++ }
++
++ /* Check error in reply to unify logging in that case.
++ * The caller may perform context-dependent checks and logging. */
++ if(rep->type == REDIS_REPLY_ERROR)
++ log_err("redis: %s resulted in an error: %s",
++ data ? "set" : "get", rep->str);
++
++ return rep;
++}
++
++static int
++redis_lookup(struct module_env* env, struct cachedb_env* cachedb_env,
++ char* key, struct sldns_buffer* result_buffer)
++{
++ redisReply* rep;
++ char cmdbuf[4+(CACHEDB_HASHSIZE/8)*2+1]; /* "GET " + key */
++ int n;
++ int ret = 0;
++
++ verbose(VERB_ALGO, "redis_lookup of %s", key);
++
++ n = snprintf(cmdbuf, sizeof(cmdbuf), "GET %s", key);
++ if(n < 0 || n >= (int)sizeof(cmdbuf)) {
++ log_err("redis_lookup: unexpected failure to build command");
++ return 0;
++ }
++
++ rep = redis_command(env, cachedb_env, cmdbuf, NULL, 0);
++ if(!rep)
++ return 0;
++ switch (rep->type) {
++ case REDIS_REPLY_NIL:
++ verbose(VERB_ALGO, "redis_lookup: no data cached");
++ break;
++ case REDIS_REPLY_STRING:
++ verbose(VERB_ALGO, "redis_lookup found %d bytes",
++ (int)rep->len);
++ if((size_t)rep->len > sldns_buffer_capacity(result_buffer)) {
++ log_err("redis_lookup: replied data too long: %lu",
++ (size_t)rep->len);
++ break;
++ }
++ sldns_buffer_clear(result_buffer);
++ sldns_buffer_write(result_buffer, rep->str, rep->len);
++ sldns_buffer_flip(result_buffer);
++ ret = 1;
++ break;
++ case REDIS_REPLY_ERROR:
++ break; /* already logged */
++ default:
++ log_err("redis_lookup: unexpected type of reply for (%d)",
++ rep->type);
++ break;
++ }
++ freeReplyObject(rep);
++ return ret;
++}
++
++static void
++redis_store(struct module_env* env, struct cachedb_env* cachedb_env,
++ char* key, uint8_t* data, size_t data_len)
++{
++ redisReply* rep;
++ char cmdbuf[4+(CACHEDB_HASHSIZE/8)*2+3+1]; /* "SET " + key + " %b" */
++ int n;
++
++ verbose(VERB_ALGO, "redis_store %s (%d bytes)", key, (int)data_len);
++
++ /* build command to set to a binary safe string */
++ n = snprintf(cmdbuf, sizeof(cmdbuf), "SET %s %%b", key);
++ if(n < 0 || n >= (int)sizeof(cmdbuf)) {
++ log_err("redis_store: unexpected failure to build command");
++ return;
++ }
++
++ rep = redis_command(env, cachedb_env, cmdbuf, data, data_len);
++ if(rep) {
++ verbose(VERB_ALGO, "redis_store set completed");
++ if(rep->type != REDIS_REPLY_STATUS &&
++ rep->type != REDIS_REPLY_ERROR) {
++ log_err("redis_store: unexpected type of reply (%d)",
++ rep->type);
++ }
++ freeReplyObject(rep);
++ }
++}
++
++struct cachedb_backend redis_backend = { "redis",
++ redis_init, redis_deinit, redis_lookup, redis_store
++};
++#endif /* USE_REDIS */
++#endif /* USE_CACHEDB */
+--- contrib/unbound/cachedb/redis.h.orig
++++ contrib/unbound/cachedb/redis.h
+@@ -0,0 +1,45 @@
++/*
++ * cachedb/redis.h - cachedb redis module
++ *
++ * Copyright (c) 2018, NLnet Labs. All rights reserved.
++ *
++ * This software is open source.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ *
++ * Redistributions of source code must retain the above copyright notice,
++ * this list of conditions and the following disclaimer.
++ *
++ * Redistributions in binary form must reproduce the above copyright notice,
++ * this list of conditions and the following disclaimer in the documentation
++ * and/or other materials provided with the distribution.
++ *
++ * Neither the name of the NLNET LABS nor the names of its contributors may
++ * be used to endorse or promote products derived from this software without
++ * specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
++ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
++ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
++ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
++ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
++ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
++ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
++ */
++
++/**
++ * \file
++ *
++ * This file contains a module that uses the redis database to cache
++ * dns responses.
++ */
++
++/** the redis backend definition, contains callable functions
++ * and name string */
++extern struct cachedb_backend redis_backend;
+--- contrib/unbound/compat/arc4_lock.c.orig
++++ contrib/unbound/compat/arc4_lock.c
+@@ -33,6 +33,9 @@
+ */
+ #include "config.h"
+ #define LOCKRET(func) func
++#ifdef ENABLE_LOCK_CHECKS
++#undef ENABLE_LOCK_CHECKS
++#endif
+ #include "util/locks.h"
+
+ void _ARC4_LOCK(void);
+@@ -46,9 +49,13 @@
+ void _ARC4_UNLOCK(void)
+ {
+ }
++
++void _ARC4_LOCK_DESTROY(void)
++{
++}
+ #else /* !THREADS_DISABLED */
+
+-static lock_quick_t arc4lock;
++static lock_quick_type arc4lock;
+ static int arc4lockinit = 0;
+
+ void _ARC4_LOCK(void)
+@@ -64,4 +71,12 @@
+ {
+ lock_quick_unlock(&arc4lock);
+ }
++
++void _ARC4_LOCK_DESTROY(void)
++{
++ if(arc4lockinit) {
++ arc4lockinit = 0;
++ lock_quick_destroy(&arc4lock);
++ }
++}
+ #endif /* THREADS_DISABLED */
+--- contrib/unbound/compat/arc4random.c.orig
++++ contrib/unbound/compat/arc4random.c
+@@ -71,9 +71,76 @@
+
+ static inline void _rs_rekey(u_char *dat, size_t datlen);
+
++/*
++ * Basic sanity checking; wish we could do better.
++ */
++static int
++fallback_gotdata(char *buf, size_t len)
++{
++ char any_set = 0;
++ size_t i;
++
++ for (i = 0; i < len; ++i)
++ any_set |= buf[i];
++ if (any_set == 0)
++ return -1;
++ return 0;
++}
++
++/* fallback for getentropy in case libc returns failure */
++static int
++fallback_getentropy_urandom(void *buf, size_t len)
++{
++ size_t i;
++ int fd, flags;
++ int save_errno = errno;
++
++start:
++
++ flags = O_RDONLY;
++#ifdef O_NOFOLLOW
++ flags |= O_NOFOLLOW;
++#endif
++#ifdef O_CLOEXEC
++ flags |= O_CLOEXEC;
++#endif
++ fd = open("/dev/urandom", flags, 0);
++ if (fd == -1) {
++ if (errno == EINTR)
++ goto start;
++ goto nodevrandom;
++ }
++#ifndef O_CLOEXEC
++# ifdef HAVE_FCNTL
++ fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
++# endif
++#endif
++ for (i = 0; i < len; ) {
++ size_t wanted = len - i;
++ ssize_t ret = read(fd, (char*)buf + i, wanted);
++
++ if (ret == -1) {
++ if (errno == EAGAIN || errno == EINTR)
++ continue;
++ close(fd);
++ goto nodevrandom;
++ }
++ i += ret;
++ }
++ close(fd);
++ if (fallback_gotdata(buf, len) == 0) {
++ errno = save_errno;
++ return 0; /* satisfied */
++ }
++nodevrandom:
++ errno = EIO;
++ return -1;
++}
++
+ static inline void
+ _rs_init(u_char *buf, size_t n)
+ {
++ assert(buf);
+ if (n < KEYSZ + IVSZ)
+ return;
+
+@@ -114,11 +181,14 @@
+ u_char rnd[KEYSZ + IVSZ];
+
+ if (getentropy(rnd, sizeof rnd) == -1) {
++ if(errno != ENOSYS ||
++ fallback_getentropy_urandom(rnd, sizeof rnd) == -1) {
+ #ifdef SIGKILL
+- raise(SIGKILL);
++ raise(SIGKILL);
+ #else
+- exit(9); /* windows */
++ exit(9); /* windows */
+ #endif
++ }
+ }
+
+ if (!rs)
+--- contrib/unbound/compat/ctime_r.c.orig
++++ contrib/unbound/compat/ctime_r.c
+@@ -6,7 +6,7 @@
+ #include "util/locks.h"
+
+ /** the lock for ctime buffer */
+-static lock_basic_t ctime_lock;
++static lock_basic_type ctime_lock;
+ /** has it been inited */
+ static int ctime_r_init = 0;
+
+--- contrib/unbound/compat/getentropy_freebsd.c.orig
++++ contrib/unbound/compat/getentropy_freebsd.c
+@@ -0,0 +1,62 @@
++/* $OpenBSD: getentropy_freebsd.c,v 1.3 2016/08/07 03:27:21 tb Exp $ */
++
++/*
++ * Copyright (c) 2014 Pawel Jakub Dawidek <pjd@FreeBSD.org>
++ * Copyright (c) 2014 Brent Cook <bcook@openbsd.org>
++ *
++ * Permission to use, copy, modify, and distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ *
++ * Emulation of getentropy(2) as documented at:
++ * http://man.openbsd.org/getentropy.2
++ */
++
++#include <sys/types.h>
++#include <sys/sysctl.h>
++
++#include <errno.h>
++#include <stddef.h>
++
++/*
++ * Derived from lib/libc/gen/arc4random.c from FreeBSD.
++ */
++static size_t
++getentropy_sysctl(u_char *buf, size_t size)
++{
++ int mib[2];
++ size_t len, done;
++
++ mib[0] = CTL_KERN;
++ mib[1] = KERN_ARND;
++ done = 0;
++
++ do {
++ len = size;
++ if (sysctl(mib, 2, buf, &len, NULL, 0) == -1)
++ return (done);
++ done += len;
++ buf += len;
++ size -= len;
++ } while (size > 0);
++
++ return (done);
++}
++
++int
++getentropy(void *buf, size_t len)
++{
++ if (len <= 256 && getentropy_sysctl(buf, len) == len)
++ return (0);
++
++ errno = EIO;
++ return (-1);
++}
+--- contrib/unbound/compat/getentropy_linux.c.orig
++++ contrib/unbound/compat/getentropy_linux.c
+@@ -1,4 +1,4 @@
+-/* $OpenBSD: getentropy_linux.c,v 1.20 2014/07/12 15:43:49 beck Exp $ */
++/* $OpenBSD: getentropy_linux.c,v 1.46 2018/11/20 08:04:28 deraadt Exp $ */
+
+ /*
+ * Copyright (c) 2014 Theo de Raadt <deraadt@openbsd.org>
+@@ -15,12 +15,15 @@
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ *
++ * Emulation of getentropy(2) as documented at:
++ * http://man.openbsd.org/getentropy.2
+ */
++
+ #include "config.h"
+-
+ /*
+-#define _POSIX_C_SOURCE 199309L
+-#define _GNU_SOURCE 1
++#define _POSIX_C_SOURCE 199309L
++#define _GNU_SOURCE 1
+ */
+ #include <sys/types.h>
+ #include <sys/param.h>
+@@ -27,8 +30,8 @@
+ #include <sys/ioctl.h>
+ #include <sys/resource.h>
+ #include <sys/syscall.h>
+-#ifdef HAVE_SYS_SYSCTL_H
+-#include <sys/sysctl.h>
++#ifdef SYS__sysctl
++#include <linux/sysctl.h>
+ #endif
+ #include <sys/statvfs.h>
+ #include <sys/socket.h>
+@@ -39,6 +42,7 @@
+ #include <stdlib.h>
+ #include <stdint.h>
+ #include <stdio.h>
++#include <link.h>
+ #include <termios.h>
+ #include <fcntl.h>
+ #include <signal.h>
+@@ -46,16 +50,18 @@
+ #include <errno.h>
+ #include <unistd.h>
+ #include <time.h>
+-
+-#if defined(HAVE_SSL)
++#ifndef HAVE_NETTLE
+ #include <openssl/sha.h>
+-#elif defined(HAVE_NETTLE)
++#else
+ #include <nettle/sha.h>
++#define SHA512_CTX struct sha512_ctx
++#define SHA512_Init(x) sha512_init(x)
++#define SHA512_Update(x, b, s) sha512_update(x, s, b)
++#define SHA512_Final(r, c) sha512_digest(c, SHA512_DIGEST_SIZE, r)
+ #endif
+
+ #include <linux/types.h>
+ #include <linux/random.h>
+-#include <linux/sysctl.h>
+ #ifdef HAVE_GETAUXVAL
+ #include <sys/auxv.h>
+ #endif
+@@ -75,29 +81,13 @@
+ HD(b); \
+ } while (0)
+
+-#if defined(HAVE_SSL)
+-#define CRYPTO_SHA512_CTX SHA512_CTX
+-#define CRYPTO_SHA512_INIT(x) SHA512_Init(x)
+-#define CRYPTO_SHA512_FINAL(r, c) SHA512_Final(r, c)
+ #define HR(x, l) (SHA512_Update(&ctx, (char *)(x), (l)))
+ #define HD(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (x)))
+ #define HF(x) (SHA512_Update(&ctx, (char *)&(x), sizeof (void*)))
+-#elif defined(HAVE_NETTLE)
+-#define CRYPTO_SHA512_CTX struct sha512_ctx
+-#define CRYPTO_SHA512_INIT(x) sha512_init(x)
+-#define CRYPTO_SHA512_FINAL(r, c) sha512_digest(c, SHA512_DIGEST_SIZE, r)
+-#define HR(x, l) (sha512_update(&ctx, (l), (uint8_t *)(x)))
+-#define HD(x) (sha512_update(&ctx, sizeof (x), (uint8_t *)&(x)))
+-#define HF(x) (sha512_update(&ctx, sizeof (void*), (uint8_t *)&(x)))
+-#endif
+
+ int getentropy(void *buf, size_t len);
+
+-#ifdef CAN_REFERENCE_MAIN
+-extern int main(int, char *argv[]);
+-#endif
+-static int gotdata(char *buf, size_t len);
+-#if defined(SYS_getrandom) && defined(__NR_getrandom)
++#if defined(SYS_getrandom) && defined(GRND_NONBLOCK)
+ static int getentropy_getrandom(void *buf, size_t len);
+ #endif
+ static int getentropy_urandom(void *buf, size_t len);
+@@ -105,6 +95,7 @@
+ static int getentropy_sysctl(void *buf, size_t len);
+ #endif
+ static int getentropy_fallback(void *buf, size_t len);
++static int getentropy_phdr(struct dl_phdr_info *info, size_t size, void *data);
+
+ int
+ getentropy(void *buf, size_t len)
+@@ -113,18 +104,21 @@
+
+ if (len > 256) {
+ errno = EIO;
+- return -1;
++ return (-1);
+ }
+
+-#if defined(SYS_getrandom) && defined(__NR_getrandom)
++#if defined(SYS_getrandom) && defined(GRND_NONBLOCK)
+ /*
+- * Try descriptor-less getrandom()
++ * Try descriptor-less getrandom(), in non-blocking mode.
++ *
++ * The design of Linux getrandom is broken. It has an
++ * uninitialized phase coupled with blocking behaviour, which
++ * is unacceptable from within a library at boot time without
++ * possible recovery. See http://bugs.python.org/issue26839#msg267745
+ */
+ ret = getentropy_getrandom(buf, len);
+ if (ret != -1)
+ return (ret);
+- if (errno != ENOSYS)
+- return (-1);
+ #endif
+
+ /*
+@@ -178,7 +172,7 @@
+ * - Do the best under the circumstances....
+ *
+ * This code path exists to bring light to the issue that Linux
+- * does not provide a failsafe API for entropy collection.
++ * still does not provide a failsafe API for entropy collection.
+ *
+ * We hope this demonstrates that Linux should either retain their
+ * sysctl ABI, or consider providing a new failsafe API which
+@@ -196,24 +190,8 @@
+ return (ret);
+ }
+
+-/*
+- * Basic sanity checking; wish we could do better.
+- */
++#if defined(SYS_getrandom) && defined(GRND_NONBLOCK)
+ static int
+-gotdata(char *buf, size_t len)
+-{
+- char any_set = 0;
+- size_t i;
+-
+- for (i = 0; i < len; ++i)
+- any_set |= buf[i];
+- if (any_set == 0)
+- return -1;
+- return 0;
+-}
+-
+-#if defined(SYS_getrandom) && defined(__NR_getrandom)
+-static int
+ getentropy_getrandom(void *buf, size_t len)
+ {
+ int pre_errno = errno;
+@@ -221,7 +199,7 @@
+ if (len > 256)
+ return (-1);
+ do {
+- ret = syscall(SYS_getrandom, buf, len, 0);
++ ret = syscall(SYS_getrandom, buf, len, GRND_NONBLOCK);
+ } while (ret == -1 && errno == EINTR);
+
+ if (ret != (int)len)
+@@ -269,7 +247,7 @@
+ }
+ for (i = 0; i < len; ) {
+ size_t wanted = len - i;
+- ssize_t ret = read(fd, (char*)buf + i, wanted);
++ ssize_t ret = read(fd, (char *)buf + i, wanted);
+
+ if (ret == -1) {
+ if (errno == EAGAIN || errno == EINTR)
+@@ -280,13 +258,11 @@
+ i += ret;
+ }
+ close(fd);
+- if (gotdata(buf, len) == 0) {
+- errno = save_errno;
+- return 0; /* satisfied */
+- }
++ errno = save_errno;
++ return (0); /* satisfied */
+ nodevrandom:
+ errno = EIO;
+- return -1;
++ return (-1);
+ }
+
+ #ifdef SYS__sysctl
+@@ -311,17 +287,15 @@
+ goto sysctlfailed;
+ i += chunk;
+ }
+- if (gotdata(buf, len) == 0) {
+- errno = save_errno;
+- return (0); /* satisfied */
+- }
++ errno = save_errno;
++ return (0); /* satisfied */
+ sysctlfailed:
+ errno = EIO;
+- return -1;
++ return (-1);
+ }
+ #endif /* SYS__sysctl */
+
+-static int cl[] = {
++static const int cl[] = {
+ CLOCK_REALTIME,
+ #ifdef CLOCK_MONOTONIC
+ CLOCK_MONOTONIC,
+@@ -347,6 +321,15 @@
+ };
+
+ static int
++getentropy_phdr(struct dl_phdr_info *info, size_t ATTR_UNUSED(size), void *data)
++{
++ SHA512_CTX *ctx = data;
++
++ SHA512_Update(ctx, &info->dlpi_addr, sizeof (info->dlpi_addr));
++ return (0);
++}
++
++static int
+ getentropy_fallback(void *buf, size_t len)
+ {
+ uint8_t results[SHA512_DIGEST_LENGTH];
+@@ -357,7 +340,7 @@
+ struct rusage ru;
+ sigset_t sigset;
+ struct stat st;
+- CRYPTO_SHA512_CTX ctx;
++ SHA512_CTX ctx;
+ static pid_t lastpid;
+ pid_t pid;
+ size_t i, ii, m;
+@@ -374,7 +357,7 @@
+ }
+ for (i = 0; i < len; ) {
+ int j;
+- CRYPTO_SHA512_INIT(&ctx);
++ SHA512_Init(&ctx);
+ for (j = 0; j < repeat; j++) {
+ HX((e = gettimeofday(&tv, NULL)) == -1, tv);
+ if (e != -1) {
+@@ -382,6 +365,8 @@
+ cnt += (int)tv.tv_usec;
+ }
+
++ dl_iterate_phdr(getentropy_phdr, &ctx);
++
+ for (ii = 0; ii < sizeof(cl)/sizeof(cl[0]); ii++)
+ HX(clock_gettime(cl[ii], &ts) == -1, ts);
+
+@@ -401,9 +386,6 @@
+ HX(sigprocmask(SIG_BLOCK, NULL, &sigset) == -1,
+ sigset);
+
+-#ifdef CAN_REFERENCE_MAIN
+- HF(main); /* an addr in program */
+-#endif
+ HF(getentropy); /* an addr in this library */
+ HF(printf); /* an addr in libc */
+ p = (char *)&p;
+@@ -528,33 +510,30 @@
+ HD(cnt);
+ }
+ #ifdef HAVE_GETAUXVAL
+-# ifdef AT_RANDOM
++#ifdef AT_RANDOM
+ /* Not as random as you think but we take what we are given */
+ p = (char *) getauxval(AT_RANDOM);
+ if (p)
+ HR(p, 16);
+-# endif
+-# ifdef AT_SYSINFO_EHDR
++#endif
++#ifdef AT_SYSINFO_EHDR
+ p = (char *) getauxval(AT_SYSINFO_EHDR);
+ if (p)
+ HR(p, pgs);
+-# endif
+-# ifdef AT_BASE
++#endif
++#ifdef AT_BASE
+ p = (char *) getauxval(AT_BASE);
+ if (p)
+ HD(p);
+-# endif
+-#endif /* HAVE_GETAUXVAL */
++#endif
++#endif
+
+- CRYPTO_SHA512_FINAL(results, &ctx);
+- memcpy((char*)buf + i, results, min(sizeof(results), len - i));
++ SHA512_Final(results, &ctx);
++ memcpy((char *)buf + i, results, min(sizeof(results), len - i));
+ i += min(sizeof(results), len - i);
+ }
+- memset(results, 0, sizeof results);
+- if (gotdata(buf, len) == 0) {
+- errno = save_errno;
+- return 0; /* satisfied */
+- }
+- errno = EIO;
+- return -1;
++ explicit_bzero(&ctx, sizeof ctx);
++ explicit_bzero(results, sizeof results);
++ errno = save_errno;
++ return (0); /* satisfied */
+ }
+--- contrib/unbound/compat/getentropy_osx.c.orig
++++ contrib/unbound/compat/getentropy_osx.c
+@@ -1,4 +1,4 @@
+-/* $OpenBSD: getentropy_osx.c,v 1.3 2014/07/12 14:48:00 deraadt Exp $ */
++/* $OpenBSD: getentropy_osx.c,v 1.12 2018/11/20 08:04:28 deraadt Exp $ */
+
+ /*
+ * Copyright (c) 2014 Theo de Raadt <deraadt@openbsd.org>
+@@ -15,9 +15,12 @@
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ *
++ * Emulation of getentropy(2) as documented at:
++ * http://man.openbsd.org/getentropy.2
+ */
+-#include "config.h"
+
++#include <TargetConditionals.h>
+ #include <sys/types.h>
+ #include <sys/param.h>
+ #include <sys/ioctl.h>
+@@ -43,14 +46,18 @@
+ #include <mach/mach_time.h>
+ #include <mach/mach_host.h>
+ #include <mach/host_info.h>
++#if TARGET_OS_OSX
+ #include <sys/socketvar.h>
+ #include <sys/vmmeter.h>
++#endif
+ #include <netinet/in.h>
+ #include <netinet/tcp.h>
++#if TARGET_OS_OSX
+ #include <netinet/udp.h>
+ #include <netinet/ip_var.h>
+ #include <netinet/tcp_var.h>
+ #include <netinet/udp_var.h>
++#endif
+ #include <CommonCrypto/CommonDigest.h>
+ #define SHA512_Update(a, b, c) (CC_SHA512_Update((a), (b), (c)))
+ #define SHA512_Init(xxx) (CC_SHA512_Init((xxx)))
+@@ -75,10 +82,6 @@
+
+ int getentropy(void *buf, size_t len);
+
+-#ifdef CAN_REFERENCE_MAIN
+-extern int main(int, char *argv[]);
+-#endif
+-static int gotdata(char *buf, size_t len);
+ static int getentropy_urandom(void *buf, size_t len);
+ static int getentropy_fallback(void *buf, size_t len);
+
+@@ -89,7 +92,7 @@
+
+ if (len > 256) {
+ errno = EIO;
+- return -1;
++ return (-1);
+ }
+
+ /*
+@@ -138,23 +141,7 @@
+ return (ret);
+ }
+
+-/*
+- * Basic sanity checking; wish we could do better.
+- */
+ static int
+-gotdata(char *buf, size_t len)
+-{
+- char any_set = 0;
+- size_t i;
+-
+- for (i = 0; i < len; ++i)
+- any_set |= buf[i];
+- if (any_set == 0)
+- return -1;
+- return 0;
+-}
+-
+-static int
+ getentropy_urandom(void *buf, size_t len)
+ {
+ struct stat st;
+@@ -188,7 +175,7 @@
+ }
+ for (i = 0; i < len; ) {
+ size_t wanted = len - i;
+- ssize_t ret = read(fd, (char*)buf + i, wanted);
++ ssize_t ret = read(fd, (char *)buf + i, wanted);
+
+ if (ret == -1) {
+ if (errno == EAGAIN || errno == EINTR)
+@@ -199,18 +186,18 @@
+ i += ret;
+ }
+ close(fd);
+- if (gotdata(buf, len) == 0) {
+- errno = save_errno;
+- return 0; /* satisfied */
+- }
++ errno = save_errno;
++ return (0); /* satisfied */
+ nodevrandom:
+ errno = EIO;
+- return -1;
++ return (-1);
+ }
+
++#if TARGET_OS_OSX
+ static int tcpmib[] = { CTL_NET, AF_INET, IPPROTO_TCP, TCPCTL_STATS };
+ static int udpmib[] = { CTL_NET, AF_INET, IPPROTO_UDP, UDPCTL_STATS };
+ static int ipmib[] = { CTL_NET, AF_INET, IPPROTO_IP, IPCTL_STATS };
++#endif
+ static int kmib[] = { CTL_KERN, KERN_USRSTACK };
+ static int hwmib[] = { CTL_HW, HW_USERMEM };
+
+@@ -230,9 +217,11 @@
+ pid_t pid;
+ size_t i, ii, m;
+ char *p;
++#if TARGET_OS_OSX
+ struct tcpstat tcpstat;
+ struct udpstat udpstat;
+ struct ipstat ipstat;
++#endif
+ u_int64_t mach_time;
+ unsigned int idata;
+ void *addr;
+@@ -267,6 +256,7 @@
+ HX(sysctl(hwmib, sizeof(hwmib) / sizeof(hwmib[0]),
+ &idata, &ii, NULL, 0) == -1, idata);
+
++#if TARGET_OS_OSX
+ ii = sizeof(tcpstat);
+ HX(sysctl(tcpmib, sizeof(tcpmib) / sizeof(tcpmib[0]),
+ &tcpstat, &ii, NULL, 0) == -1, tcpstat);
+@@ -278,6 +268,7 @@
+ ii = sizeof(ipstat);
+ HX(sysctl(ipmib, sizeof(ipmib) / sizeof(ipmib[0]),
+ &ipstat, &ii, NULL, 0) == -1, ipstat);
++#endif
+
+ HX((pid = getpid()) == -1, pid);
+ HX((pid = getsid(pid)) == -1, pid);
+@@ -295,9 +286,6 @@
+ HX(sigprocmask(SIG_BLOCK, NULL, &sigset) == -1,
+ sigset);
+
+-#ifdef CAN_REFERENCE_MAIN
+- HF(main); /* an addr in program */
+-#endif
+ HF(getentropy); /* an addr in this library */
+ HF(printf); /* an addr in libc */
+ p = (char *)&p;
+@@ -419,14 +407,11 @@
+ }
+
+ SHA512_Final(results, &ctx);
+- memcpy((char*)buf + i, results, min(sizeof(results), len - i));
++ memcpy((char *)buf + i, results, min(sizeof(results), len - i));
+ i += min(sizeof(results), len - i);
+ }
+- memset(results, 0, sizeof results);
+- if (gotdata(buf, len) == 0) {
+- errno = save_errno;
+- return 0; /* satisfied */
+- }
+- errno = EIO;
+- return -1;
++ explicit_bzero(&ctx, sizeof ctx);
++ explicit_bzero(results, sizeof results);
++ errno = save_errno;
++ return (0); /* satisfied */
+ }
+--- contrib/unbound/compat/getentropy_solaris.c.orig
++++ contrib/unbound/compat/getentropy_solaris.c
+@@ -1,4 +1,4 @@
+-/* $OpenBSD: getentropy_solaris.c,v 1.3 2014/07/12 14:46:31 deraadt Exp $ */
++/* $OpenBSD: getentropy_solaris.c,v 1.4 2014/07/12 20:41:47 wouter Exp $ */
+
+ /*
+ * Copyright (c) 2014 Theo de Raadt <deraadt@openbsd.org>
+@@ -204,7 +204,7 @@
+ }
+ for (i = 0; i < len; ) {
+ size_t wanted = len - i;
+- ssize_t ret = read(fd, (char*)buf + i, wanted);
++ ssize_t ret = read(fd, (char *)buf + i, wanted);
+
+ if (ret == -1) {
+ if (errno == EAGAIN || errno == EINTR)
+@@ -428,7 +428,7 @@
+ HD(cnt);
+ }
+ SHA512_Final(results, &ctx);
+- memcpy((char*)buf + i, results, min(sizeof(results), len - i));
++ memcpy((char *)buf + i, results, min(sizeof(results), len - i));
+ i += min(sizeof(results), len - i);
+ }
+ memset(results, 0, sizeof results);
+--- contrib/unbound/compat/getentropy_win.c.orig
++++ contrib/unbound/compat/getentropy_win.c
+@@ -1,4 +1,4 @@
+-/* $OpenBSD$ */
++/* $OpenBSD: getentropy_win.c,v 1.5 2016/08/07 03:27:21 tb Exp $ */
+
+ /*
+ * Copyright (c) 2014, Theo de Raadt <deraadt@openbsd.org>
+@@ -15,6 +15,9 @@
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ *
++ * Emulation of getentropy(2) as documented at:
++ * http://man.openbsd.org/getentropy.2
+ */
+
+ #include <windows.h>
+@@ -37,7 +40,7 @@
+
+ if (len > 256) {
+ errno = EIO;
+- return -1;
++ return (-1);
+ }
+
+ if (CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL,
+--- contrib/unbound/compat/malloc.c.orig
++++ contrib/unbound/compat/malloc.c
+@@ -5,7 +5,12 @@
+ #undef malloc
+ #include <sys/types.h>
+
++#ifndef USE_WINSOCK
+ void *malloc ();
++#else
++/* provide a prototype */
++void *malloc (size_t n);
++#endif
+
+ /* Allocate an N-byte block of memory from the heap.
+ If N is zero, allocate a 1-byte block. */
+--- contrib/unbound/compat/snprintf.c.orig
++++ contrib/unbound/compat/snprintf.c
+@@ -658,7 +658,7 @@
+ * are not their own functions. */
+
+ /* printout designation:
+- * conversion specifier: x, d, u, s, c, n, m, p
++ * conversion specifier: x, d, u, s, c, m, p
+ * flags: # not supported
+ * 0 zeropad (on the left)
+ * - left adjust (right by default)
+@@ -798,7 +798,10 @@
+ minw, minus);
+ break;
+ case 'n':
+- *va_arg(arg, int*) = ret;
++ /* unsupported to harden against format string
++ * exploitation,
++ * handled like an unknown format specifier. */
++ /* *va_arg(arg, int*) = ret; */
+ break;
+ case 'm':
+ print_str(&at, &left, &ret, strerror(errno),
+--- contrib/unbound/config.guess.orig
++++ contrib/unbound/config.guess
+@@ -1,8 +1,8 @@
+-#! /bin/sh
++#!/usr/bin/sh
+ # Attempt to guess a canonical system name.
+-# Copyright 1992-2013 Free Software Foundation, Inc.
++# Copyright 1992-2016 Free Software Foundation, Inc.
+
+-timestamp='2013-06-10'
++timestamp='2016-10-02'
+
+ # This file is free software; you can redistribute it and/or modify it
+ # under the terms of the GNU General Public License as published by
+@@ -24,12 +24,12 @@
+ # program. This Exception is an additional permission under section 7
+ # of the GNU General Public License, version 3 ("GPLv3").
+ #
+-# Originally written by Per Bothner.
++# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
+ #
+ # You can get the latest version of this script from:
+-# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
++# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
+ #
+-# Please send patches with a ChangeLog entry to config-patches@gnu.org.
++# Please send patches to <config-patches@gnu.org>.
+
+
+ me=`echo "$0" | sed -e 's,.*/,,'`
+@@ -50,7 +50,7 @@
+ GNU config.guess ($timestamp)
+
+ Originally written by Per Bothner.
+-Copyright 1992-2013 Free Software Foundation, Inc.
++Copyright 1992-2016 Free Software Foundation, Inc.
+
+ This is free software; see the source for copying conditions. There is NO
+ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+@@ -149,7 +149,7 @@
+ LIBC=gnu
+ #endif
+ EOF
+- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
++ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
+ ;;
+ esac
+
+@@ -168,8 +168,10 @@
+ # Note: NetBSD doesn't particularly care about the vendor
+ # portion of the name. We always set it to "unknown".
+ sysctl="sysctl -n hw.machine_arch"
+- UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+- /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
++ UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
++ /sbin/$sysctl 2>/dev/null || \
++ /usr/sbin/$sysctl 2>/dev/null || \
++ echo unknown)`
+ case "${UNAME_MACHINE_ARCH}" in
+ armeb) machine=armeb-unknown ;;
+ arm*) machine=arm-unknown ;;
+@@ -176,11 +178,19 @@
+ sh3el) machine=shl-unknown ;;
+ sh3eb) machine=sh-unknown ;;
+ sh5el) machine=sh5le-unknown ;;
++ earmv*)
++ arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
++ endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'`
++ machine=${arch}${endian}-unknown
++ ;;
+ *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+ esac
+ # The Operating System including object format, if it has switched
+- # to ELF recently, or will in the future.
++ # to ELF recently (or will in the future) and ABI.
+ case "${UNAME_MACHINE_ARCH}" in
++ earm*)
++ os=netbsdelf
++ ;;
+ arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+ eval $set_cc_for_build
+ if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+@@ -197,6 +207,13 @@
+ os=netbsd
+ ;;
+ esac
++ # Determine ABI tags.
++ case "${UNAME_MACHINE_ARCH}" in
++ earm*)
++ expr='s/^earmv[0-9]/-eabi/;s/eb$//'
++ abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"`
++ ;;
++ esac
+ # The OS release
+ # Debian GNU/NetBSD machines have a different userland, and
+ # thus, need a distinct triplet. However, they do not need
+@@ -207,13 +224,13 @@
+ release='-gnu'
+ ;;
+ *)
+- release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
++ release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2`
+ ;;
+ esac
+ # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+ # contains redundant information, the shorter form:
+ # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+- echo "${machine}-${os}${release}"
++ echo "${machine}-${os}${release}${abi}"
+ exit ;;
+ *:Bitrig:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
+@@ -223,6 +240,10 @@
+ UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+ exit ;;
++ *:LibertyBSD:*:*)
++ UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'`
++ echo ${UNAME_MACHINE_ARCH}-unknown-libertybsd${UNAME_RELEASE}
++ exit ;;
+ *:ekkoBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+ exit ;;
+@@ -235,6 +256,9 @@
+ *:MirBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
++ *:Sortix:*:*)
++ echo ${UNAME_MACHINE}-unknown-sortix
++ exit ;;
+ alpha:OSF1:*:*)
+ case $UNAME_RELEASE in
+ *4.0)
+@@ -251,35 +275,35 @@
+ ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+ case "$ALPHA_CPU_TYPE" in
+ "EV4 (21064)")
+- UNAME_MACHINE="alpha" ;;
++ UNAME_MACHINE=alpha ;;
+ "EV4.5 (21064)")
+- UNAME_MACHINE="alpha" ;;
++ UNAME_MACHINE=alpha ;;
+ "LCA4 (21066/21068)")
+- UNAME_MACHINE="alpha" ;;
++ UNAME_MACHINE=alpha ;;
+ "EV5 (21164)")
+- UNAME_MACHINE="alphaev5" ;;
++ UNAME_MACHINE=alphaev5 ;;
+ "EV5.6 (21164A)")
+- UNAME_MACHINE="alphaev56" ;;
++ UNAME_MACHINE=alphaev56 ;;
+ "EV5.6 (21164PC)")
+- UNAME_MACHINE="alphapca56" ;;
++ UNAME_MACHINE=alphapca56 ;;
+ "EV5.7 (21164PC)")
+- UNAME_MACHINE="alphapca57" ;;
++ UNAME_MACHINE=alphapca57 ;;
+ "EV6 (21264)")
+- UNAME_MACHINE="alphaev6" ;;
++ UNAME_MACHINE=alphaev6 ;;
+ "EV6.7 (21264A)")
+- UNAME_MACHINE="alphaev67" ;;
++ UNAME_MACHINE=alphaev67 ;;
+ "EV6.8CB (21264C)")
+- UNAME_MACHINE="alphaev68" ;;
++ UNAME_MACHINE=alphaev68 ;;
+ "EV6.8AL (21264B)")
+- UNAME_MACHINE="alphaev68" ;;
++ UNAME_MACHINE=alphaev68 ;;
+ "EV6.8CX (21264D)")
+- UNAME_MACHINE="alphaev68" ;;
++ UNAME_MACHINE=alphaev68 ;;
+ "EV6.9A (21264/EV69A)")
+- UNAME_MACHINE="alphaev69" ;;
++ UNAME_MACHINE=alphaev69 ;;
+ "EV7 (21364)")
+- UNAME_MACHINE="alphaev7" ;;
++ UNAME_MACHINE=alphaev7 ;;
+ "EV7.9 (21364A)")
+- UNAME_MACHINE="alphaev79" ;;
++ UNAME_MACHINE=alphaev79 ;;
+ esac
+ # A Pn.n version is a patched version.
+ # A Vn.n version is a released version.
+@@ -286,7 +310,7 @@
+ # A Tn.n version is a released field test version.
+ # A Xn.n version is an unreleased experimental baselevel.
+ # 1.2 uses "1.2" for uname -r.
+- echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
++ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
+ # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+ exitcode=$?
+ trap '' 0
+@@ -359,16 +383,16 @@
+ exit ;;
+ i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+ eval $set_cc_for_build
+- SUN_ARCH="i386"
++ SUN_ARCH=i386
+ # If there is a compiler, see if it is configured for 64-bit objects.
+ # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+ # This test works for both compilers.
+- if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
++ if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
+ if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+- (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
++ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+- SUN_ARCH="x86_64"
++ SUN_ARCH=x86_64
+ fi
+ fi
+ echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+@@ -393,7 +417,7 @@
+ exit ;;
+ sun*:*:4.2BSD:*)
+ UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+- test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
++ test "x${UNAME_RELEASE}" = x && UNAME_RELEASE=3
+ case "`/bin/arch`" in
+ sun3)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+@@ -579,8 +603,9 @@
+ else
+ IBM_ARCH=powerpc
+ fi
+- if [ -x /usr/bin/oslevel ] ; then
+- IBM_REV=`/usr/bin/oslevel`
++ if [ -x /usr/bin/lslpp ] ; then
++ IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
++ awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+@@ -617,13 +642,13 @@
+ sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+ case "${sc_cpu_version}" in
+- 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+- 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
++ 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0
++ 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1
+ 532) # CPU_PA_RISC2_0
+ case "${sc_kernel_bits}" in
+- 32) HP_ARCH="hppa2.0n" ;;
+- 64) HP_ARCH="hppa2.0w" ;;
+- '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
++ 32) HP_ARCH=hppa2.0n ;;
++ 64) HP_ARCH=hppa2.0w ;;
++ '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20
+ esac ;;
+ esac
+ fi
+@@ -662,11 +687,11 @@
+ exit (0);
+ }
+ EOF
+- (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
++ (CCOPTS="" $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+ test -z "$HP_ARCH" && HP_ARCH=hppa
+ fi ;;
+ esac
+- if [ ${HP_ARCH} = "hppa2.0w" ]
++ if [ ${HP_ARCH} = hppa2.0w ]
+ then
+ eval $set_cc_for_build
+
+@@ -679,12 +704,12 @@
+ # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+ # => hppa64-hp-hpux11.23
+
+- if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
++ if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) |
+ grep -q __LP64__
+ then
+- HP_ARCH="hppa2.0w"
++ HP_ARCH=hppa2.0w
+ else
+- HP_ARCH="hppa64"
++ HP_ARCH=hppa64
+ fi
+ fi
+ echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+@@ -789,14 +814,14 @@
+ echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+- FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
++ FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
++ FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ 5000:UNIX_System_V:4.*:*)
+- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+- FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
++ FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
++ FUJITSU_REL=`echo ${UNAME_RELEASE} | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'`
+ echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+@@ -826,7 +851,7 @@
+ *:MINGW*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit ;;
+- i*:MSYS*:*)
++ *:MSYS*:*)
+ echo ${UNAME_MACHINE}-pc-msys
+ exit ;;
+ i*:windows32*:*)
+@@ -878,7 +903,7 @@
+ exit ;;
+ *:GNU/*:*:*)
+ # other systems with GNU libc and userland
+- echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
++ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
+ exit ;;
+ i*86:Minix:*:*)
+ echo ${UNAME_MACHINE}-pc-minix
+@@ -901,7 +926,7 @@
+ EV68*) UNAME_MACHINE=alphaev68 ;;
+ esac
+ objdump --private-headers /bin/sh | grep -q ld.so.1
+- if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
++ if test "$?" = 0 ; then LIBC=gnulibc1 ; fi
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ arc:Linux:*:* | arceb:Linux:*:*)
+@@ -932,6 +957,9 @@
+ crisv32:Linux:*:*)
+ echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+ exit ;;
++ e2k:Linux:*:*)
++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
++ exit ;;
+ frv:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+@@ -944,6 +972,9 @@
+ ia64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
++ k1om:Linux:*:*)
++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
++ exit ;;
+ m32r*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+@@ -969,10 +1000,13 @@
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
+ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
+ ;;
+- or1k:Linux:*:*)
++ mips64el:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+- or32:Linux:*:*)
++ openrisc*:Linux:*:*)
++ echo or1k-unknown-linux-${LIBC}
++ exit ;;
++ or32:Linux:*:* | or1k*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ padre:Linux:*:*)
+@@ -1001,6 +1035,9 @@
+ ppcle:Linux:*:*)
+ echo powerpcle-unknown-linux-${LIBC}
+ exit ;;
++ riscv32:Linux:*:* | riscv64:Linux:*:*)
++ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
++ exit ;;
+ s390:Linux:*:* | s390x:Linux:*:*)
+ echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
+ exit ;;
+@@ -1020,7 +1057,7 @@
+ echo ${UNAME_MACHINE}-dec-linux-${LIBC}
+ exit ;;
+ x86_64:Linux:*:*)
+- echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
++ echo ${UNAME_MACHINE}-pc-linux-${LIBC}
+ exit ;;
+ xtensa*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+@@ -1099,7 +1136,7 @@
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i586.
+ # Note: whatever this is, it MUST be the same as what config.sub
+- # prints for the "djgpp" host, or else GDB configury will decide that
++ # prints for the "djgpp" host, or else GDB configure will decide that
+ # this is a cross-build.
+ echo i586-pc-msdosdjgpp
+ exit ;;
+@@ -1248,6 +1285,9 @@
+ SX-8R:SUPER-UX:*:*)
+ echo sx8r-nec-superux${UNAME_RELEASE}
+ exit ;;
++ SX-ACE:SUPER-UX:*:*)
++ echo sxace-nec-superux${UNAME_RELEASE}
++ exit ;;
+ Power*:Rhapsody:*:*)
+ echo powerpc-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+@@ -1260,22 +1300,32 @@
+ if test "$UNAME_PROCESSOR" = unknown ; then
+ UNAME_PROCESSOR=powerpc
+ fi
+- if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+- if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+- (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+- grep IS_64BIT_ARCH >/dev/null
+- then
+- case $UNAME_PROCESSOR in
+- i386) UNAME_PROCESSOR=x86_64 ;;
+- powerpc) UNAME_PROCESSOR=powerpc64 ;;
+- esac
++ if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
++ if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
++ if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
++ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
++ grep IS_64BIT_ARCH >/dev/null
++ then
++ case $UNAME_PROCESSOR in
++ i386) UNAME_PROCESSOR=x86_64 ;;
++ powerpc) UNAME_PROCESSOR=powerpc64 ;;
++ esac
++ fi
+ fi
++ elif test "$UNAME_PROCESSOR" = i386 ; then
++ # Avoid executing cc on OS X 10.9, as it ships with a stub
++ # that puts up a graphical alert prompting to install
++ # developer tools. Any system running Mac OS X 10.7 or
++ # later (Darwin 11 and later) is required to have a 64-bit
++ # processor. This is not true of the ARM version of Darwin
++ # that Apple uses in portable devices.
++ UNAME_PROCESSOR=x86_64
+ fi
+ echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+ exit ;;
+ *:procnto*:*:* | *:QNX:[0123456789]*:*)
+ UNAME_PROCESSOR=`uname -p`
+- if test "$UNAME_PROCESSOR" = "x86"; then
++ if test "$UNAME_PROCESSOR" = x86; then
+ UNAME_PROCESSOR=i386
+ UNAME_MACHINE=pc
+ fi
+@@ -1306,7 +1356,7 @@
+ # "uname -m" is not consistent, so use $cputype instead. 386
+ # is converted to i386 for consistency with other x86
+ # operating systems.
+- if test "$cputype" = "386"; then
++ if test "$cputype" = 386; then
+ UNAME_MACHINE=i386
+ else
+ UNAME_MACHINE="$cputype"
+@@ -1348,7 +1398,7 @@
+ echo i386-pc-xenix
+ exit ;;
+ i*86:skyos:*:*)
+- echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
++ echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE} | sed -e 's/ .*$//'`
+ exit ;;
+ i*86:rdos:*:*)
+ echo ${UNAME_MACHINE}-pc-rdos
+@@ -1359,171 +1409,25 @@
+ x86_64:VMkernel:*:*)
+ echo ${UNAME_MACHINE}-unknown-esx
+ exit ;;
++ amd64:Isilon\ OneFS:*:*)
++ echo x86_64-unknown-onefs
++ exit ;;
+ esac
+
+-eval $set_cc_for_build
+-cat >$dummy.c <<EOF
+-#ifdef _SEQUENT_
+-# include <sys/types.h>
+-# include <sys/utsname.h>
+-#endif
+-main ()
+-{
+-#if defined (sony)
+-#if defined (MIPSEB)
+- /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
+- I don't know.... */
+- printf ("mips-sony-bsd\n"); exit (0);
+-#else
+-#include <sys/param.h>
+- printf ("m68k-sony-newsos%s\n",
+-#ifdef NEWSOS4
+- "4"
+-#else
+- ""
+-#endif
+- ); exit (0);
+-#endif
+-#endif
+-
+-#if defined (__arm) && defined (__acorn) && defined (__unix)
+- printf ("arm-acorn-riscix\n"); exit (0);
+-#endif
+-
+-#if defined (hp300) && !defined (hpux)
+- printf ("m68k-hp-bsd\n"); exit (0);
+-#endif
+-
+-#if defined (NeXT)
+-#if !defined (__ARCHITECTURE__)
+-#define __ARCHITECTURE__ "m68k"
+-#endif
+- int version;
+- version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+- if (version < 4)
+- printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+- else
+- printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+- exit (0);
+-#endif
+-
+-#if defined (MULTIMAX) || defined (n16)
+-#if defined (UMAXV)
+- printf ("ns32k-encore-sysv\n"); exit (0);
+-#else
+-#if defined (CMU)
+- printf ("ns32k-encore-mach\n"); exit (0);
+-#else
+- printf ("ns32k-encore-bsd\n"); exit (0);
+-#endif
+-#endif
+-#endif
+-
+-#if defined (__386BSD__)
+- printf ("i386-pc-bsd\n"); exit (0);
+-#endif
+-
+-#if defined (sequent)
+-#if defined (i386)
+- printf ("i386-sequent-dynix\n"); exit (0);
+-#endif
+-#if defined (ns32000)
+- printf ("ns32k-sequent-dynix\n"); exit (0);
+-#endif
+-#endif
+-
+-#if defined (_SEQUENT_)
+- struct utsname un;
+-
+- uname(&un);
+-
+- if (strncmp(un.version, "V2", 2) == 0) {
+- printf ("i386-sequent-ptx2\n"); exit (0);
+- }
+- if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+- printf ("i386-sequent-ptx1\n"); exit (0);
+- }
+- printf ("i386-sequent-ptx\n"); exit (0);
+-
+-#endif
+-
+-#if defined (vax)
+-# if !defined (ultrix)
+-# include <sys/param.h>
+-# if defined (BSD)
+-# if BSD == 43
+- printf ("vax-dec-bsd4.3\n"); exit (0);
+-# else
+-# if BSD == 199006
+- printf ("vax-dec-bsd4.3reno\n"); exit (0);
+-# else
+- printf ("vax-dec-bsd\n"); exit (0);
+-# endif
+-# endif
+-# else
+- printf ("vax-dec-bsd\n"); exit (0);
+-# endif
+-# else
+- printf ("vax-dec-ultrix\n"); exit (0);
+-# endif
+-#endif
+-
+-#if defined (alliant) && defined (i860)
+- printf ("i860-alliant-bsd\n"); exit (0);
+-#endif
+-
+- exit (1);
+-}
+-EOF
+-
+-$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+- { echo "$SYSTEM_NAME"; exit; }
+-
+-# Apollos put the system type in the environment.
+-
+-test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+-
+-# Convex versions that predate uname can use getsysinfo(1)
+-
+-if [ -x /usr/convex/getsysinfo ]
+-then
+- case `getsysinfo -f cpu_type` in
+- c1*)
+- echo c1-convex-bsd
+- exit ;;
+- c2*)
+- if getsysinfo -f scalar_acc
+- then echo c32-convex-bsd
+- else echo c2-convex-bsd
+- fi
+- exit ;;
+- c34*)
+- echo c34-convex-bsd
+- exit ;;
+- c38*)
+- echo c38-convex-bsd
+- exit ;;
+- c4*)
+- echo c4-convex-bsd
+- exit ;;
+- esac
+-fi
+-
+ cat >&2 <<EOF
+ $0: unable to guess system type
+
+-This script, last modified $timestamp, has failed to recognize
+-the operating system you are using. It is advised that you
+-download the most up to date version of the config scripts from
++This script (version $timestamp), has failed to recognize the
++operating system you are using. If your script is old, overwrite
++config.guess and config.sub with the latest versions from:
+
+- http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
++ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
+ and
+- http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
++ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
+
+-If the version you run ($0) is already up to date, please
+-send the following data and any information you think might be
+-pertinent to <config-patches@gnu.org> in order to provide the needed
+-information to handle your system.
++If $0 has already been updated, send the following data and any
++information you think might be pertinent to config-patches@gnu.org to
++provide the necessary information to handle your system.
+
+ config.guess timestamp = $timestamp
+
+--- contrib/unbound/config.h.orig
++++ contrib/unbound/config.h
+@@ -1,1160 +0,0 @@
+-/* config.h. Generated from config.h.in by configure. */
+-/* config.h.in. Generated from configure.ac by autoheader. */
+-
+-/* Directory to chroot to */
+-#define CHROOT_DIR "/var/unbound"
+-
+-/* Do sha512 definitions in config.h */
+-/* #undef COMPAT_SHA512 */
+-
+-/* Pathname to the Unbound configuration file */
+-#define CONFIGFILE "/var/unbound/unbound.conf"
+-
+-/* Define this if on macOSX10.4-darwin8 and setreuid and setregid do not work
+- */
+-/* #undef DARWIN_BROKEN_SETREUID */
+-
+-/* Whether daemon is deprecated */
+-/* #undef DEPRECATED_DAEMON */
+-
+-/* default dnstap socket path */
+-/* #undef DNSTAP_SOCKET_PATH */
+-
+-/* Define if you want to use debug lock checking (slow). */
+-/* #undef ENABLE_LOCK_CHECKS */
+-
+-/* Define this if you enabled-allsymbols from libunbound to link binaries to
+- it for smaller install size, but the libunbound export table is polluted by
+- internal symbols */
+-/* #undef EXPORT_ALL_SYMBOLS */
+-
+-/* Define to 1 if you have the `arc4random' function. */
+-#define HAVE_ARC4RANDOM 1
+-
+-/* Define to 1 if you have the `arc4random_uniform' function. */
+-#define HAVE_ARC4RANDOM_UNIFORM 1
+-
+-/* Define to 1 if you have the <arpa/inet.h> header file. */
+-#define HAVE_ARPA_INET_H 1
+-
+-/* Whether the C compiler accepts the "format" attribute */
+-#define HAVE_ATTR_FORMAT 1
+-
+-/* Whether the C compiler accepts the "unused" attribute */
+-#define HAVE_ATTR_UNUSED 1
+-
+-/* Whether the C compiler accepts the "weak" attribute */
+-#define HAVE_ATTR_WEAK 1
+-
+-/* Define to 1 if you have the `chown' function. */
+-#define HAVE_CHOWN 1
+-
+-/* Define to 1 if you have the `chroot' function. */
+-#define HAVE_CHROOT 1
+-
+-/* Define to 1 if you have the `CRYPTO_cleanup_all_ex_data' function. */
+-#define HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1
+-
+-/* Define to 1 if you have the `ctime_r' function. */
+-#define HAVE_CTIME_R 1
+-
+-/* Define to 1 if you have the `daemon' function. */
+-#define HAVE_DAEMON 1
+-
+-/* Define to 1 if you have the declaration of `arc4random', and to 0 if you
+- don't. */
+-/* #undef HAVE_DECL_ARC4RANDOM */
+-
+-/* Define to 1 if you have the declaration of `arc4random_uniform', and to 0
+- if you don't. */
+-/* #undef HAVE_DECL_ARC4RANDOM_UNIFORM */
+-
+-/* Define to 1 if you have the declaration of `NID_secp384r1', and to 0 if you
+- don't. */
+-#define HAVE_DECL_NID_SECP384R1 1
+-
+-/* Define to 1 if you have the declaration of `NID_X9_62_prime256v1', and to 0
+- if you don't. */
+-#define HAVE_DECL_NID_X9_62_PRIME256V1 1
+-
+-/* Define to 1 if you have the declaration of `reallocarray', and to 0 if you
+- don't. */
+-/* #undef HAVE_DECL_REALLOCARRAY */
+-
+-/* Define to 1 if you have the declaration of `sk_SSL_COMP_pop_free', and to 0
+- if you don't. */
+-#define HAVE_DECL_SK_SSL_COMP_POP_FREE 1
+-
+-/* Define to 1 if you have the declaration of
+- `SSL_COMP_get_compression_methods', and to 0 if you don't. */
+-#define HAVE_DECL_SSL_COMP_GET_COMPRESSION_METHODS 1
+-
+-/* Define to 1 if you have the declaration of `SSL_CTX_set_ecdh_auto', and to
+- 0 if you don't. */
+-#define HAVE_DECL_SSL_CTX_SET_ECDH_AUTO 1
+-
+-/* Define to 1 if you have the declaration of `strlcat', and to 0 if you
+- don't. */
+-/* #undef HAVE_DECL_STRLCAT */
+-
+-/* Define to 1 if you have the declaration of `strlcpy', and to 0 if you
+- don't. */
+-/* #undef HAVE_DECL_STRLCPY */
+-
+-/* Define to 1 if you have the declaration of `XML_StopParser', and to 0 if
+- you don't. */
+-#define HAVE_DECL_XML_STOPPARSER 1
+-
+-/* Define to 1 if you have the <dlfcn.h> header file. */
+-#define HAVE_DLFCN_H 1
+-
+-/* Define to 1 if you have the <endian.h> header file. */
+-/* #undef HAVE_ENDIAN_H */
+-
+-/* Define to 1 if you have the `endprotoent' function. */
+-#define HAVE_ENDPROTOENT 1
+-
+-/* Define to 1 if you have the `endpwent' function. */
+-#define HAVE_ENDPWENT 1
+-
+-/* Define to 1 if you have the `endservent' function. */
+-#define HAVE_ENDSERVENT 1
+-
+-/* Define to 1 if you have the `ERR_free_strings' function. */
+-#define HAVE_ERR_FREE_STRINGS 1
+-
+-/* Define to 1 if you have the `ERR_load_crypto_strings' function. */
+-#define HAVE_ERR_LOAD_CRYPTO_STRINGS 1
+-
+-/* Define to 1 if you have the `event_base_free' function. */
+-/* #undef HAVE_EVENT_BASE_FREE */
+-
+-/* Define to 1 if you have the `event_base_get_method' function. */
+-/* #undef HAVE_EVENT_BASE_GET_METHOD */
+-
+-/* Define to 1 if you have the `event_base_new' function. */
+-/* #undef HAVE_EVENT_BASE_NEW */
+-
+-/* Define to 1 if you have the `event_base_once' function. */
+-/* #undef HAVE_EVENT_BASE_ONCE */
+-
+-/* Define to 1 if you have the <event.h> header file. */
+-/* #undef HAVE_EVENT_H */
+-
+-/* Define to 1 if you have the `EVP_cleanup' function. */
+-#define HAVE_EVP_CLEANUP 1
+-
+-/* Define to 1 if you have the `EVP_MD_CTX_new' function. */
+-/* #undef HAVE_EVP_MD_CTX_NEW */
+-
+-/* Define to 1 if you have the `EVP_sha1' function. */
+-#define HAVE_EVP_SHA1 1
+-
+-/* Define to 1 if you have the `EVP_sha256' function. */
+-#define HAVE_EVP_SHA256 1
+-
+-/* Define to 1 if you have the `EVP_sha512' function. */
+-#define HAVE_EVP_SHA512 1
+-
+-/* Define to 1 if you have the `ev_default_loop' function. */
+-/* #undef HAVE_EV_DEFAULT_LOOP */
+-
+-/* Define to 1 if you have the `ev_loop' function. */
+-/* #undef HAVE_EV_LOOP */
+-
+-/* Define to 1 if you have the <expat.h> header file. */
+-#define HAVE_EXPAT_H 1
+-
+-/* Define to 1 if you have the `fcntl' function. */
+-#define HAVE_FCNTL 1
+-
+-/* Define to 1 if you have the `FIPS_mode' function. */
+-#define HAVE_FIPS_MODE 1
+-
+-/* Define to 1 if you have the `fork' function. */
+-#define HAVE_FORK 1
+-
+-/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
+-#define HAVE_FSEEKO 1
+-
+-/* Define to 1 if you have the `fsync' function. */
+-#define HAVE_FSYNC 1
+-
+-/* Whether getaddrinfo is available */
+-#define HAVE_GETADDRINFO 1
+-
+-/* Define to 1 if you have the `getauxval' function. */
+-/* #undef HAVE_GETAUXVAL */
+-
+-/* Define to 1 if you have the `getentropy' function. */
+-/* #undef HAVE_GETENTROPY */
+-
+-/* Define to 1 if you have the <getopt.h> header file. */
+-#define HAVE_GETOPT_H 1
+-
+-/* Define to 1 if you have the `getpwnam' function. */
+-#define HAVE_GETPWNAM 1
+-
+-/* Define to 1 if you have the `getrlimit' function. */
+-#define HAVE_GETRLIMIT 1
+-
+-/* Define to 1 if you have the `glob' function. */
+-#define HAVE_GLOB 1
+-
+-/* Define to 1 if you have the <glob.h> header file. */
+-#define HAVE_GLOB_H 1
+-
+-/* Define to 1 if you have the `gmtime_r' function. */
+-#define HAVE_GMTIME_R 1
+-
+-/* Define to 1 if you have the <grp.h> header file. */
+-#define HAVE_GRP_H 1
+-
+-/* If you have HMAC_Update */
+-#define HAVE_HMAC_UPDATE 1
+-
+-/* Define to 1 if you have the `inet_aton' function. */
+-#define HAVE_INET_ATON 1
+-
+-/* Define to 1 if you have the `inet_ntop' function. */
+-#define HAVE_INET_NTOP 1
+-
+-/* Define to 1 if you have the `inet_pton' function. */
+-#define HAVE_INET_PTON 1
+-
+-/* Define to 1 if you have the `initgroups' function. */
+-#define HAVE_INITGROUPS 1
+-
+-/* Define to 1 if you have the <inttypes.h> header file. */
+-#define HAVE_INTTYPES_H 1
+-
+-/* if the function 'ioctlsocket' is available */
+-/* #undef HAVE_IOCTLSOCKET */
+-
+-/* Define to 1 if you have the <iphlpapi.h> header file. */
+-/* #undef HAVE_IPHLPAPI_H */
+-
+-/* Define to 1 if you have the `isblank' function. */
+-#define HAVE_ISBLANK 1
+-
+-/* Define to 1 if you have the `kill' function. */
+-#define HAVE_KILL 1
+-
+-/* Define if we have LibreSSL */
+-/* #undef HAVE_LIBRESSL */
+-
+-/* Define to 1 if you have the `localtime_r' function. */
+-#define HAVE_LOCALTIME_R 1
+-
+-/* Define to 1 if you have the <login_cap.h> header file. */
+-#define HAVE_LOGIN_CAP_H 1
+-
+-/* If have GNU libc compatible malloc */
+-#define HAVE_MALLOC 1
+-
+-/* Define to 1 if you have the `memmove' function. */
+-#define HAVE_MEMMOVE 1
+-
+-/* Define to 1 if you have the <memory.h> header file. */
+-#define HAVE_MEMORY_H 1
+-
+-/* Define to 1 if you have the <netdb.h> header file. */
+-#define HAVE_NETDB_H 1
+-
+-/* Define to 1 if you have the <netinet/in.h> header file. */
+-#define HAVE_NETINET_IN_H 1
+-
+-/* Define to 1 if you have the <netinet/tcp.h> header file. */
+-#define HAVE_NETINET_TCP_H 1
+-
+-/* Use libnettle for crypto */
+-/* #undef HAVE_NETTLE */
+-
+-/* Define to 1 if you have the <nettle/dsa-compat.h> header file. */
+-/* #undef HAVE_NETTLE_DSA_COMPAT_H */
+-
+-/* Use libnss for crypto */
+-/* #undef HAVE_NSS */
+-
+-/* Define to 1 if you have the `OpenSSL_add_all_digests' function. */
+-#define HAVE_OPENSSL_ADD_ALL_DIGESTS 1
+-
+-/* Define to 1 if you have the <openssl/bn.h> header file. */
+-#define HAVE_OPENSSL_BN_H 1
+-
+-/* Define to 1 if you have the `OPENSSL_config' function. */
+-#define HAVE_OPENSSL_CONFIG 1
+-
+-/* Define to 1 if you have the <openssl/conf.h> header file. */
+-#define HAVE_OPENSSL_CONF_H 1
+-
+-/* Define to 1 if you have the <openssl/dh.h> header file. */
+-#define HAVE_OPENSSL_DH_H 1
+-
+-/* Define to 1 if you have the <openssl/dsa.h> header file. */
+-#define HAVE_OPENSSL_DSA_H 1
+-
+-/* Define to 1 if you have the <openssl/engine.h> header file. */
+-#define HAVE_OPENSSL_ENGINE_H 1
+-
+-/* Define to 1 if you have the <openssl/err.h> header file. */
+-#define HAVE_OPENSSL_ERR_H 1
+-
+-/* Define to 1 if you have the `OPENSSL_init_crypto' function. */
+-/* #undef HAVE_OPENSSL_INIT_CRYPTO */
+-
+-/* Define to 1 if you have the `OPENSSL_init_ssl' function. */
+-/* #undef HAVE_OPENSSL_INIT_SSL */
+-
+-/* Define to 1 if you have the <openssl/rand.h> header file. */
+-#define HAVE_OPENSSL_RAND_H 1
+-
+-/* Define to 1 if you have the <openssl/rsa.h> header file. */
+-#define HAVE_OPENSSL_RSA_H 1
+-
+-/* Define to 1 if you have the <openssl/ssl.h> header file. */
+-#define HAVE_OPENSSL_SSL_H 1
+-
+-/* Define if you have POSIX threads libraries and header files. */
+-#define HAVE_PTHREAD 1
+-
+-/* Have PTHREAD_PRIO_INHERIT. */
+-#define HAVE_PTHREAD_PRIO_INHERIT 1
+-
+-/* Define to 1 if the system has the type `pthread_rwlock_t'. */
+-#define HAVE_PTHREAD_RWLOCK_T 1
+-
+-/* Define to 1 if the system has the type `pthread_spinlock_t'. */
+-#define HAVE_PTHREAD_SPINLOCK_T 1
+-
+-/* Define to 1 if you have the <pwd.h> header file. */
+-#define HAVE_PWD_H 1
+-
+-/* Define if you have Python libraries and header files. */
+-/* #undef HAVE_PYTHON */
+-
+-/* Define to 1 if you have the `random' function. */
+-#define HAVE_RANDOM 1
+-
+-/* Define to 1 if you have the `RAND_cleanup' function. */
+-#define HAVE_RAND_CLEANUP 1
+-
+-/* Define to 1 if you have the `reallocarray' function. */
+-#define HAVE_REALLOCARRAY 1
+-
+-/* Define to 1 if you have the `recvmsg' function. */
+-#define HAVE_RECVMSG 1
+-
+-/* define if you have the sbrk() call */
+-/* #undef HAVE_SBRK */
+-
+-/* Define to 1 if you have the `sendmsg' function. */
+-#define HAVE_SENDMSG 1
+-
+-/* Define to 1 if you have the `setregid' function. */
+-/* #undef HAVE_SETREGID */
+-
+-/* Define to 1 if you have the `setresgid' function. */
+-#define HAVE_SETRESGID 1
+-
+-/* Define to 1 if you have the `setresuid' function. */
+-#define HAVE_SETRESUID 1
+-
+-/* Define to 1 if you have the `setreuid' function. */
+-/* #undef HAVE_SETREUID */
+-
+-/* Define to 1 if you have the `setrlimit' function. */
+-#define HAVE_SETRLIMIT 1
+-
+-/* Define to 1 if you have the `setsid' function. */
+-#define HAVE_SETSID 1
+-
+-/* Define to 1 if you have the `setusercontext' function. */
+-#define HAVE_SETUSERCONTEXT 1
+-
+-/* Define to 1 if you have the `SHA512_Update' function. */
+-/* #undef HAVE_SHA512_UPDATE */
+-
+-/* Define to 1 if you have the `sigprocmask' function. */
+-#define HAVE_SIGPROCMASK 1
+-
+-/* Define to 1 if you have the `sleep' function. */
+-#define HAVE_SLEEP 1
+-
+-/* Define to 1 if you have the `snprintf' function. */
+-#define HAVE_SNPRINTF 1
+-
+-/* Define to 1 if you have the `socketpair' function. */
+-#define HAVE_SOCKETPAIR 1
+-
+-/* Using Solaris threads */
+-/* #undef HAVE_SOLARIS_THREADS */
+-
+-/* Define to 1 if you have the `srandom' function. */
+-#define HAVE_SRANDOM 1
+-
+-/* Define if you have the SSL libraries installed. */
+-#define HAVE_SSL /**/
+-
+-/* Define to 1 if you have the <stdarg.h> header file. */
+-#define HAVE_STDARG_H 1
+-
+-/* Define to 1 if you have the <stdbool.h> header file. */
+-#define HAVE_STDBOOL_H 1
+-
+-/* Define to 1 if you have the <stdint.h> header file. */
+-#define HAVE_STDINT_H 1
+-
+-/* Define to 1 if you have the <stdlib.h> header file. */
+-#define HAVE_STDLIB_H 1
+-
+-/* Define to 1 if you have the `strftime' function. */
+-#define HAVE_STRFTIME 1
+-
+-/* Define to 1 if you have the <strings.h> header file. */
+-#define HAVE_STRINGS_H 1
+-
+-/* Define to 1 if you have the <string.h> header file. */
+-#define HAVE_STRING_H 1
+-
+-/* Define to 1 if you have the `strlcat' function. */
+-#define HAVE_STRLCAT 1
+-
+-/* Define to 1 if you have the `strlcpy' function. */
+-#define HAVE_STRLCPY 1
+-
+-/* Define to 1 if you have the `strptime' function. */
+-#define HAVE_STRPTIME 1
+-
+-/* Define to 1 if you have the `strsep' function. */
+-#define HAVE_STRSEP 1
+-
+-/* Define to 1 if `ipi_spec_dst' is a member of `struct in_pktinfo'. */
+-/* #undef HAVE_STRUCT_IN_PKTINFO_IPI_SPEC_DST */
+-
+-/* Define to 1 if `sun_len' is a member of `struct sockaddr_un'. */
+-#define HAVE_STRUCT_SOCKADDR_UN_SUN_LEN 1
+-
+-/* Define if you have Swig libraries and header files. */
+-/* #undef HAVE_SWIG */
+-
+-/* Define to 1 if you have the <syslog.h> header file. */
+-#define HAVE_SYSLOG_H 1
+-
+-/* Define to 1 if you have the <sys/param.h> header file. */
+-#define HAVE_SYS_PARAM_H 1
+-
+-/* Define to 1 if you have the <sys/resource.h> header file. */
+-#define HAVE_SYS_RESOURCE_H 1
+-
+-/* Define to 1 if you have the <sys/sha2.h> header file. */
+-/* #undef HAVE_SYS_SHA2_H */
+-
+-/* Define to 1 if you have the <sys/socket.h> header file. */
+-#define HAVE_SYS_SOCKET_H 1
+-
+-/* Define to 1 if you have the <sys/stat.h> header file. */
+-#define HAVE_SYS_STAT_H 1
+-
+-/* Define to 1 if you have the <sys/sysctl.h> header file. */
+-/* #undef HAVE_SYS_SYSCTL_H */
+-
+-/* Define to 1 if you have the <sys/types.h> header file. */
+-#define HAVE_SYS_TYPES_H 1
+-
+-/* Define to 1 if you have the <sys/uio.h> header file. */
+-#define HAVE_SYS_UIO_H 1
+-
+-/* Define to 1 if you have the <sys/un.h> header file. */
+-#define HAVE_SYS_UN_H 1
+-
+-/* Define to 1 if you have the <sys/wait.h> header file. */
+-#define HAVE_SYS_WAIT_H 1
+-
+-/* Define to 1 if you have the <time.h> header file. */
+-#define HAVE_TIME_H 1
+-
+-/* Define to 1 if you have the `tzset' function. */
+-#define HAVE_TZSET 1
+-
+-/* Define to 1 if you have the <unistd.h> header file. */
+-#define HAVE_UNISTD_H 1
+-
+-/* Define to 1 if you have the `usleep' function. */
+-#define HAVE_USLEEP 1
+-
+-/* Define to 1 if you have the `vfork' function. */
+-#define HAVE_VFORK 1
+-
+-/* Define to 1 if you have the <vfork.h> header file. */
+-/* #undef HAVE_VFORK_H */
+-
+-/* Define to 1 if you have the <windows.h> header file. */
+-/* #undef HAVE_WINDOWS_H */
+-
+-/* Using Windows threads */
+-/* #undef HAVE_WINDOWS_THREADS */
+-
+-/* Define to 1 if you have the <winsock2.h> header file. */
+-/* #undef HAVE_WINSOCK2_H */
+-
+-/* Define to 1 if `fork' works. */
+-#define HAVE_WORKING_FORK 1
+-
+-/* Define to 1 if `vfork' works. */
+-#define HAVE_WORKING_VFORK 1
+-
+-/* Define to 1 if you have the `writev' function. */
+-#define HAVE_WRITEV 1
+-
+-/* Define to 1 if you have the <ws2tcpip.h> header file. */
+-/* #undef HAVE_WS2TCPIP_H */
+-
+-/* Define to 1 if you have the `_beginthreadex' function. */
+-/* #undef HAVE__BEGINTHREADEX */
+-
+-/* if lex has yylex_destroy */
+-#define LEX_HAS_YYLEX_DESTROY 1
+-
+-/* Define to the sub-directory where libtool stores uninstalled libraries. */
+-#define LT_OBJDIR ".libs/"
+-
+-/* Define to the maximum message length to pass to syslog. */
+-#define MAXSYSLOGMSGLEN 10240
+-
+-/* Define if memcmp() does not compare unsigned bytes */
+-/* #undef MEMCMP_IS_BROKEN */
+-
+-/* Define if mkdir has one argument. */
+-/* #undef MKDIR_HAS_ONE_ARG */
+-
+-/* Define if the network stack does not fully support nonblocking io (causes
+- lower performance). */
+-/* #undef NONBLOCKING_IS_BROKEN */
+-
+-/* Put -D_ALL_SOURCE define in config.h */
+-/* #undef OMITTED__D_ALL_SOURCE */
+-
+-/* Put -D_BSD_SOURCE define in config.h */
+-/* #undef OMITTED__D_BSD_SOURCE */
+-
+-/* Put -D_DEFAULT_SOURCE define in config.h */
+-/* #undef OMITTED__D_DEFAULT_SOURCE */
+-
+-/* Put -D_GNU_SOURCE define in config.h */
+-/* #undef OMITTED__D_GNU_SOURCE */
+-
+-/* Put -D_LARGEFILE_SOURCE=1 define in config.h */
+-/* #undef OMITTED__D_LARGEFILE_SOURCE_1 */
+-
+-/* Put -D_POSIX_C_SOURCE=200112 define in config.h */
+-/* #undef OMITTED__D_POSIX_C_SOURCE_200112 */
+-
+-/* Put -D_XOPEN_SOURCE=600 define in config.h */
+-/* #undef OMITTED__D_XOPEN_SOURCE_600 */
+-
+-/* Put -D_XOPEN_SOURCE_EXTENDED=1 define in config.h */
+-/* #undef OMITTED__D_XOPEN_SOURCE_EXTENDED_1 */
+-
+-/* Put -D__EXTENSIONS__ define in config.h */
+-/* #undef OMITTED__D__EXTENSIONS__ */
+-
+-/* Define to the address where bug reports for this package should be sent. */
+-#define PACKAGE_BUGREPORT "unbound-bugs@nlnetlabs.nl"
+-
+-/* Define to the full name of this package. */
+-#define PACKAGE_NAME "unbound"
+-
+-/* Define to the full name and version of this package. */
+-#define PACKAGE_STRING "unbound 1.5.10"
+-
+-/* Define to the one symbol short name of this package. */
+-#define PACKAGE_TARNAME "unbound"
+-
+-/* Define to the home page for this package. */
+-#define PACKAGE_URL ""
+-
+-/* Define to the version of this package. */
+-#define PACKAGE_VERSION "1.5.10"
+-
+-/* default pidfile location */
+-#define PIDFILE "/var/unbound/unbound.pid"
+-
+-/* Define to necessary symbol if this constant uses a non-standard name on
+- your system. */
+-/* #undef PTHREAD_CREATE_JOINABLE */
+-
+-/* Define as the return type of signal handlers (`int' or `void'). */
+-#define RETSIGTYPE void
+-
+-/* default rootkey location */
+-#define ROOT_ANCHOR_FILE "/var/unbound/root.key"
+-
+-/* default rootcert location */
+-#define ROOT_CERT_FILE "/var/unbound/icannbundle.pem"
+-
+-/* version number for resource files */
+-#define RSRC_PACKAGE_VERSION 1,5,10,0
+-
+-/* Directory to chdir to */
+-#define RUN_DIR "/var/unbound"
+-
+-/* Shared data */
+-#define SHARE_DIR "/var/unbound"
+-
+-/* The size of `time_t', as computed by sizeof. */
+-#define SIZEOF_TIME_T 8
+-
+-/* define if (v)snprintf does not return length needed, (but length used) */
+-/* #undef SNPRINTF_RET_BROKEN */
+-
+-/* Define to 1 if you have the ANSI C header files. */
+-#define STDC_HEADERS 1
+-
+-/* use default strptime. */
+-#define STRPTIME_WORKS 1
+-
+-/* Use win32 resources and API */
+-/* #undef UB_ON_WINDOWS */
+-
+-/* default username */
+-#define UB_USERNAME "unbound"
+-
+-/* use to enable lightweight alloc assertions, for debug use */
+-/* #undef UNBOUND_ALLOC_LITE */
+-
+-/* use malloc not regions, for debug use */
+-/* #undef UNBOUND_ALLOC_NONREGIONAL */
+-
+-/* use statistics for allocs and frees, for debug use */
+-/* #undef UNBOUND_ALLOC_STATS */
+-
+-/* define this to enable debug checks. */
+-/* #undef UNBOUND_DEBUG */
+-
+-/* Define to 1 to use cachedb support */
+-/* #undef USE_CACHEDB */
+-
+-/* Define to 1 to enable dnstap support */
+-/* #undef USE_DNSTAP */
+-
+-/* Define this to enable DSA support. */
+-#define USE_DSA 1
+-
+-/* Define this to enable ECDSA support. */
+-#define USE_ECDSA 1
+-
+-/* Define this to enable an EVP workaround for older openssl */
+-/* #undef USE_ECDSA_EVP_WORKAROUND */
+-
+-/* Define this to enable GOST support. */
+-#define USE_GOST 1
+-
+-/* Define if you want to use internal select based events */
+-#define USE_MINI_EVENT 1
+-
+-/* Define this to enable client TCP Fast Open. */
+-/* #undef USE_MSG_FASTOPEN */
+-
+-/* Define this to enable client TCP Fast Open. */
+-/* #undef USE_OSX_MSG_FASTOPEN */
+-
+-/* Define this to enable SHA256 and SHA512 support. */
+-#define USE_SHA2 1
+-
+-/* Enable extensions on AIX 3, Interix. */
+-#ifndef _ALL_SOURCE
+-# define _ALL_SOURCE 1
+-#endif
+-/* Enable GNU extensions on systems that have them. */
+-#ifndef _GNU_SOURCE
+-# define _GNU_SOURCE 1
+-#endif
+-/* Enable threading extensions on Solaris. */
+-#ifndef _POSIX_PTHREAD_SEMANTICS
+-# define _POSIX_PTHREAD_SEMANTICS 1
+-#endif
+-/* Enable extensions on HP NonStop. */
+-#ifndef _TANDEM_SOURCE
+-# define _TANDEM_SOURCE 1
+-#endif
+-/* Enable general extensions on Solaris. */
+-#ifndef __EXTENSIONS__
+-# define __EXTENSIONS__ 1
+-#endif
+-
+-
+-/* Define this to enable server TCP Fast Open. */
+-/* #undef USE_TCP_FASTOPEN */
+-
+-/* Whether the windows socket API is used */
+-/* #undef USE_WINSOCK */
+-
+-/* the version of the windows API enabled */
+-#define WINVER 0x0502
+-
+-/* Define if you want Python module. */
+-/* #undef WITH_PYTHONMODULE */
+-
+-/* Define if you want PyUnbound. */
+-/* #undef WITH_PYUNBOUND */
+-
+-/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
+- `char[]'. */
+-#define YYTEXT_POINTER 1
+-
+-/* Enable large inode numbers on Mac OS X 10.5. */
+-#ifndef _DARWIN_USE_64_BIT_INODE
+-# define _DARWIN_USE_64_BIT_INODE 1
+-#endif
+-
+-/* Number of bits in a file offset, on hosts where this is settable. */
+-/* #undef _FILE_OFFSET_BITS */
+-
+-/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */
+-/* #undef _LARGEFILE_SOURCE */
+-
+-/* Define for large files, on AIX-style hosts. */
+-/* #undef _LARGE_FILES */
+-
+-/* Define to 1 if on MINIX. */
+-/* #undef _MINIX */
+-
+-/* Enable for compile on Minix */
+-/* #undef _NETBSD_SOURCE */
+-
+-/* Define to 2 if the system does not provide POSIX.1 features except with
+- this defined. */
+-/* #undef _POSIX_1_SOURCE */
+-
+-/* Define to 1 if you need to in order for `stat' and other things to work. */
+-/* #undef _POSIX_SOURCE */
+-
+-/* Define to empty if `const' does not conform to ANSI C. */
+-/* #undef const */
+-
+-/* Define to `int' if <sys/types.h> doesn't define. */
+-/* #undef gid_t */
+-
+-/* in_addr_t */
+-/* #undef in_addr_t */
+-
+-/* in_port_t */
+-/* #undef in_port_t */
+-
+-/* Define to `__inline__' or `__inline' if that's what the C compiler
+- calls it, or to nothing if 'inline' is not supported under any name. */
+-#ifndef __cplusplus
+-/* #undef inline */
+-#endif
+-
+-/* Define to `short' if <sys/types.h> does not define. */
+-/* #undef int16_t */
+-
+-/* Define to `int' if <sys/types.h> does not define. */
+-/* #undef int32_t */
+-
+-/* Define to `long long' if <sys/types.h> does not define. */
+-/* #undef int64_t */
+-
+-/* Define to `signed char' if <sys/types.h> does not define. */
+-/* #undef int8_t */
+-
+-/* Define if replacement function should be used. */
+-/* #undef malloc */
+-
+-/* Define to `long int' if <sys/types.h> does not define. */
+-/* #undef off_t */
+-
+-/* Define to `int' if <sys/types.h> does not define. */
+-/* #undef pid_t */
+-
+-/* Define to 'int' if not defined */
+-/* #undef rlim_t */
+-
+-/* Define to `unsigned int' if <sys/types.h> does not define. */
+-/* #undef size_t */
+-
+-/* Define to 'int' if not defined */
+-/* #undef socklen_t */
+-
+-/* Define to `int' if <sys/types.h> does not define. */
+-/* #undef ssize_t */
+-
+-/* Define to 'unsigned char if not defined */
+-/* #undef u_char */
+-
+-/* Define to `int' if <sys/types.h> doesn't define. */
+-/* #undef uid_t */
+-
+-/* Define to `unsigned short' if <sys/types.h> does not define. */
+-/* #undef uint16_t */
+-
+-/* Define to `unsigned int' if <sys/types.h> does not define. */
+-/* #undef uint32_t */
+-
+-/* Define to `unsigned long long' if <sys/types.h> does not define. */
+-/* #undef uint64_t */
+-
+-/* Define to `unsigned char' if <sys/types.h> does not define. */
+-/* #undef uint8_t */
+-
+-/* Define as `fork' if `vfork' does not work. */
+-/* #undef vfork */
+-
+-#if defined(OMITTED__D_GNU_SOURCE) && !defined(_GNU_SOURCE)
+-#define _GNU_SOURCE 1
+-#endif
+-
+-#if defined(OMITTED__D_BSD_SOURCE) && !defined(_BSD_SOURCE)
+-#define _BSD_SOURCE 1
+-#endif
+-
+-#if defined(OMITTED__D_DEFAULT_SOURCE) && !defined(_DEFAULT_SOURCE)
+-#define _DEFAULT_SOURCE 1
+-#endif
+-
+-#if defined(OMITTED__D__EXTENSIONS__) && !defined(__EXTENSIONS__)
+-#define __EXTENSIONS__ 1
+-#endif
+-
+-#if defined(OMITTED__D_POSIX_C_SOURCE_200112) && !defined(_POSIX_C_SOURCE)
+-#define _POSIX_C_SOURCE 200112
+-#endif
+-
+-#if defined(OMITTED__D_XOPEN_SOURCE_600) && !defined(_XOPEN_SOURCE)
+-#define _XOPEN_SOURCE 600
+-#endif
+-
+-#if defined(OMITTED__D_XOPEN_SOURCE_EXTENDED_1) && !defined(_XOPEN_SOURCE_EXTENDED)
+-#define _XOPEN_SOURCE_EXTENDED 1
+-#endif
+-
+-#if defined(OMITTED__D_ALL_SOURCE) && !defined(_ALL_SOURCE)
+-#define _ALL_SOURCE 1
+-#endif
+-
+-#if defined(OMITTED__D_LARGEFILE_SOURCE_1) && !defined(_LARGEFILE_SOURCE)
+-#define _LARGEFILE_SOURCE 1
+-#endif
+-
+-
+-
+-
+-#ifndef UNBOUND_DEBUG
+-# define NDEBUG
+-#endif
+-
+-/** Use small-ldns codebase */
+-#define USE_SLDNS 1
+-#ifdef HAVE_SSL
+-# define LDNS_BUILD_CONFIG_HAVE_SSL 1
+-#endif
+-
+-#include <stdio.h>
+-#include <string.h>
+-#include <unistd.h>
+-#include <assert.h>
+-
+-#if STDC_HEADERS
+-#include <stdlib.h>
+-#include <stddef.h>
+-#endif
+-
+-#ifdef HAVE_STDARG_H
+-#include <stdarg.h>
+-#endif
+-
+-#ifdef HAVE_STDINT_H
+-#include <stdint.h>
+-#endif
+-
+-#include <errno.h>
+-
+-#if HAVE_SYS_PARAM_H
+-#include <sys/param.h>
+-#endif
+-
+-#ifdef HAVE_SYS_SOCKET_H
+-#include <sys/socket.h>
+-#endif
+-
+-#ifdef HAVE_SYS_UIO_H
+-#include <sys/uio.h>
+-#endif
+-
+-#ifdef HAVE_NETINET_IN_H
+-#include <netinet/in.h>
+-#endif
+-
+-#ifdef HAVE_NETINET_TCP_H
+-#include <netinet/tcp.h>
+-#endif
+-
+-#ifdef HAVE_ARPA_INET_H
+-#include <arpa/inet.h>
+-#endif
+-
+-#ifdef HAVE_WINSOCK2_H
+-#include <winsock2.h>
+-#endif
+-
+-#ifdef HAVE_WS2TCPIP_H
+-#include <ws2tcpip.h>
+-#endif
+-
+-#ifndef USE_WINSOCK
+-#define ARG_LL "%ll"
+-#else
+-#define ARG_LL "%I64"
+-#endif
+-
+-#ifndef AF_LOCAL
+-#define AF_LOCAL AF_UNIX
+-#endif
+-
+-
+-
+-#ifdef HAVE_ATTR_FORMAT
+-# define ATTR_FORMAT(archetype, string_index, first_to_check) \
+- __attribute__ ((format (archetype, string_index, first_to_check)))
+-#else /* !HAVE_ATTR_FORMAT */
+-# define ATTR_FORMAT(archetype, string_index, first_to_check) /* empty */
+-#endif /* !HAVE_ATTR_FORMAT */
+-
+-
+-#if defined(DOXYGEN)
+-# define ATTR_UNUSED(x) x
+-#elif defined(__cplusplus)
+-# define ATTR_UNUSED(x)
+-#elif defined(HAVE_ATTR_UNUSED)
+-# define ATTR_UNUSED(x) x __attribute__((unused))
+-#else /* !HAVE_ATTR_UNUSED */
+-# define ATTR_UNUSED(x) x
+-#endif /* !HAVE_ATTR_UNUSED */
+-
+-
+-#ifndef HAVE_FSEEKO
+-#define fseeko fseek
+-#define ftello ftell
+-#endif /* HAVE_FSEEKO */
+-
+-
+-#ifndef MAXHOSTNAMELEN
+-#define MAXHOSTNAMELEN 256
+-#endif
+-
+-#if !defined(HAVE_SNPRINTF) || defined(SNPRINTF_RET_BROKEN)
+-#define snprintf snprintf_unbound
+-#define vsnprintf vsnprintf_unbound
+-#include <stdarg.h>
+-int snprintf (char *str, size_t count, const char *fmt, ...);
+-int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);
+-#endif /* HAVE_SNPRINTF or SNPRINTF_RET_BROKEN */
+-
+-#ifndef HAVE_INET_PTON
+-#define inet_pton inet_pton_unbound
+-int inet_pton(int af, const char* src, void* dst);
+-#endif /* HAVE_INET_PTON */
+-
+-
+-#ifndef HAVE_INET_NTOP
+-#define inet_ntop inet_ntop_unbound
+-const char *inet_ntop(int af, const void *src, char *dst, size_t size);
+-#endif
+-
+-
+-#ifndef HAVE_INET_ATON
+-#define inet_aton inet_aton_unbound
+-int inet_aton(const char *cp, struct in_addr *addr);
+-#endif
+-
+-
+-#ifndef HAVE_MEMMOVE
+-#define memmove memmove_unbound
+-void *memmove(void *dest, const void *src, size_t n);
+-#endif
+-
+-
+-#ifndef HAVE_STRLCAT
+-#define strlcat strlcat_unbound
+-size_t strlcat(char *dst, const char *src, size_t siz);
+-#endif
+-
+-
+-#ifndef HAVE_STRLCPY
+-#define strlcpy strlcpy_unbound
+-size_t strlcpy(char *dst, const char *src, size_t siz);
+-#endif
+-
+-
+-#ifndef HAVE_GMTIME_R
+-#define gmtime_r gmtime_r_unbound
+-struct tm *gmtime_r(const time_t *timep, struct tm *result);
+-#endif
+-
+-
+-#ifndef HAVE_REALLOCARRAY
+-#define reallocarray reallocarrayunbound
+-void* reallocarray(void *ptr, size_t nmemb, size_t size);
+-#endif
+-
+-
+-#if !defined(HAVE_SLEEP) || defined(HAVE_WINDOWS_H)
+-#define sleep(x) Sleep((x)*1000) /* on win32 */
+-#endif /* HAVE_SLEEP */
+-
+-
+-#ifndef HAVE_USLEEP
+-#define usleep(x) Sleep((x)/1000 + 1) /* on win32 */
+-#endif /* HAVE_USLEEP */
+-
+-
+-#ifndef HAVE_RANDOM
+-#define random rand /* on win32, for tests only (bad random) */
+-#endif /* HAVE_RANDOM */
+-
+-
+-#ifndef HAVE_SRANDOM
+-#define srandom(x) srand(x) /* on win32, for tests only (bad random) */
+-#endif /* HAVE_SRANDOM */
+-
+-
+-/* detect if we need to cast to unsigned int for FD_SET to avoid warnings */
+-#ifdef HAVE_WINSOCK2_H
+-#define FD_SET_T (u_int)
+-#else
+-#define FD_SET_T
+-#endif
+-
+-
+-#ifndef IPV6_MIN_MTU
+-#define IPV6_MIN_MTU 1280
+-#endif /* IPV6_MIN_MTU */
+-
+-
+-#ifdef MEMCMP_IS_BROKEN
+-#include "compat/memcmp.h"
+-#define memcmp memcmp_unbound
+-int memcmp(const void *x, const void *y, size_t n);
+-#endif
+-
+-
+-
+-#ifndef HAVE_CTIME_R
+-#define ctime_r unbound_ctime_r
+-char *ctime_r(const time_t *timep, char *buf);
+-#endif
+-
+-#ifndef HAVE_STRSEP
+-#define strsep unbound_strsep
+-char *strsep(char **stringp, const char *delim);
+-#endif
+-
+-#ifndef HAVE_ISBLANK
+-#define isblank unbound_isblank
+-int isblank(int c);
+-#endif
+-
+-#if !defined(HAVE_STRPTIME) || !defined(STRPTIME_WORKS)
+-#define strptime unbound_strptime
+-struct tm;
+-char *strptime(const char *s, const char *format, struct tm *tm);
+-#endif
+-
+-#ifdef HAVE_LIBRESSL
+-# if !HAVE_DECL_STRLCPY
+-size_t strlcpy(char *dst, const char *src, size_t siz);
+-# endif
+-# if !HAVE_DECL_STRLCAT
+-size_t strlcat(char *dst, const char *src, size_t siz);
+-# endif
+-# if !HAVE_DECL_ARC4RANDOM && defined(HAVE_ARC4RANDOM)
+-uint32_t arc4random(void);
+-# endif
+-# if !HAVE_DECL_ARC4RANDOM_UNIFORM && defined(HAVE_ARC4RANDOM_UNIFORM)
+-uint32_t arc4random_uniform(uint32_t upper_bound);
+-# endif
+-# if !HAVE_DECL_REALLOCARRAY
+-void *reallocarray(void *ptr, size_t nmemb, size_t size);
+-# endif
+-#endif /* HAVE_LIBRESSL */
+-#ifndef HAVE_ARC4RANDOM
+-void explicit_bzero(void* buf, size_t len);
+-int getentropy(void* buf, size_t len);
+-uint32_t arc4random(void);
+-void arc4random_buf(void* buf, size_t n);
+-void _ARC4_LOCK(void);
+-void _ARC4_UNLOCK(void);
+-#endif
+-#ifndef HAVE_ARC4RANDOM_UNIFORM
+-uint32_t arc4random_uniform(uint32_t upper_bound);
+-#endif
+-#ifdef COMPAT_SHA512
+-#ifndef SHA512_DIGEST_LENGTH
+-#define SHA512_BLOCK_LENGTH 128
+-#define SHA512_DIGEST_LENGTH 64
+-#define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1)
+-typedef struct _SHA512_CTX {
+- uint64_t state[8];
+- uint64_t bitcount[2];
+- uint8_t buffer[SHA512_BLOCK_LENGTH];
+-} SHA512_CTX;
+-#endif /* SHA512_DIGEST_LENGTH */
+-void SHA512_Init(SHA512_CTX*);
+-void SHA512_Update(SHA512_CTX*, void*, size_t);
+-void SHA512_Final(uint8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*);
+-unsigned char *SHA512(void* data, unsigned int data_len, unsigned char *digest);
+-#endif /* COMPAT_SHA512 */
+-
+-
+-
+-#if defined(HAVE_EVENT_H) && !defined(HAVE_EVENT_BASE_ONCE) && !(defined(HAVE_EV_LOOP) || defined(HAVE_EV_DEFAULT_LOOP)) && (defined(HAVE_PTHREAD) || defined(HAVE_SOLARIS_THREADS))
+- /* using version of libevent that is not threadsafe. */
+-# define LIBEVENT_SIGNAL_PROBLEM 1
+-#endif
+-
+-#ifndef CHECKED_INET6
+-# define CHECKED_INET6
+-# ifdef AF_INET6
+-# define INET6
+-# else
+-# define AF_INET6 28
+-# endif
+-#endif /* CHECKED_INET6 */
+-
+-#ifndef HAVE_GETADDRINFO
+-struct sockaddr_storage;
+-#include "compat/fake-rfc2553.h"
+-#endif
+-
+-#ifdef UNBOUND_ALLOC_STATS
+-# define malloc(s) unbound_stat_malloc_log(s, __FILE__, __LINE__, __func__)
+-# define calloc(n,s) unbound_stat_calloc_log(n, s, __FILE__, __LINE__, __func__)
+-# define free(p) unbound_stat_free_log(p, __FILE__, __LINE__, __func__)
+-# define realloc(p,s) unbound_stat_realloc_log(p, s, __FILE__, __LINE__, __func__)
+-void *unbound_stat_malloc(size_t size);
+-void *unbound_stat_calloc(size_t nmemb, size_t size);
+-void unbound_stat_free(void *ptr);
+-void *unbound_stat_realloc(void *ptr, size_t size);
+-void *unbound_stat_malloc_log(size_t size, const char* file, int line,
+- const char* func);
+-void *unbound_stat_calloc_log(size_t nmemb, size_t size, const char* file,
+- int line, const char* func);
+-void unbound_stat_free_log(void *ptr, const char* file, int line,
+- const char* func);
+-void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
+- int line, const char* func);
+-#elif defined(UNBOUND_ALLOC_LITE)
+-# include "util/alloc.h"
+-#endif /* UNBOUND_ALLOC_LITE and UNBOUND_ALLOC_STATS */
+-
+-/** default port for DNS traffic. */
+-#define UNBOUND_DNS_PORT 53
+-/** default port for unbound control traffic, registered port with IANA,
+- ub-dns-control 8953/tcp unbound dns nameserver control */
+-#define UNBOUND_CONTROL_PORT 8953
+-/** the version of unbound-control that this software implements */
+-#define UNBOUND_CONTROL_VERSION 1
+-
+-
+--- contrib/unbound/config.h.in.orig
++++ contrib/unbound/config.h.in
+@@ -1,11 +1,23 @@
+ /* config.h.in. Generated from configure.ac by autoheader. */
+
++/* apply the noreturn attribute to a function that exits the program */
++#undef ATTR_NORETURN
++
++/* apply the weak attribute to a symbol */
++#undef ATTR_WEAK
++
+ /* Directory to chroot to */
+ #undef CHROOT_DIR
+
++/* Define this to enable client subnet option. */
++#undef CLIENT_SUBNET
++
+ /* Do sha512 definitions in config.h */
+ #undef COMPAT_SHA512
+
++/* Command line arguments used with configure */
++#undef CONFCMDLINE
++
+ /* Pathname to the Unbound configuration file */
+ #undef CONFIGFILE
+
+@@ -27,6 +39,9 @@
+ internal symbols */
+ #undef EXPORT_ALL_SYMBOLS
+
++/* Define to 1 if you have the `accept4' function. */
++#undef HAVE_ACCEPT4
++
+ /* Define to 1 if you have the `arc4random' function. */
+ #undef HAVE_ARC4RANDOM
+
+@@ -39,6 +54,9 @@
+ /* Whether the C compiler accepts the "format" attribute */
+ #undef HAVE_ATTR_FORMAT
+
++/* Whether the C compiler accepts the "noreturn" attribute */
++#undef HAVE_ATTR_NORETURN
++
+ /* Whether the C compiler accepts the "unused" attribute */
+ #undef HAVE_ATTR_UNUSED
+
+@@ -45,6 +63,15 @@
+ /* Whether the C compiler accepts the "weak" attribute */
+ #undef HAVE_ATTR_WEAK
+
++/* If we have be64toh */
++#undef HAVE_BE64TOH
++
++/* Define to 1 if you have the <bsd/stdlib.h> header file. */
++#undef HAVE_BSD_STDLIB_H
++
++/* Define to 1 if you have the <bsd/string.h> header file. */
++#undef HAVE_BSD_STRING_H
++
+ /* Define to 1 if you have the `chown' function. */
+ #undef HAVE_CHOWN
+
+@@ -54,6 +81,9 @@
+ /* Define to 1 if you have the `CRYPTO_cleanup_all_ex_data' function. */
+ #undef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA
+
++/* Define to 1 if you have the `CRYPTO_THREADID_set_callback' function. */
++#undef HAVE_CRYPTO_THREADID_SET_CALLBACK
++
+ /* Define to 1 if you have the `ctime_r' function. */
+ #undef HAVE_CTIME_R
+
+@@ -68,6 +98,26 @@
+ if you don't. */
+ #undef HAVE_DECL_ARC4RANDOM_UNIFORM
+
++/* Define to 1 if you have the declaration of `evsignal_assign', and to 0 if
++ you don't. */
++#undef HAVE_DECL_EVSIGNAL_ASSIGN
++
++/* Define to 1 if you have the declaration of `inet_ntop', and to 0 if you
++ don't. */
++#undef HAVE_DECL_INET_NTOP
++
++/* Define to 1 if you have the declaration of `inet_pton', and to 0 if you
++ don't. */
++#undef HAVE_DECL_INET_PTON
++
++/* Define to 1 if you have the declaration of `NID_ED25519', and to 0 if you
++ don't. */
++#undef HAVE_DECL_NID_ED25519
++
++/* Define to 1 if you have the declaration of `NID_ED448', and to 0 if you
++ don't. */
++#undef HAVE_DECL_NID_ED448
++
+ /* Define to 1 if you have the declaration of `NID_secp384r1', and to 0 if you
+ don't. */
+ #undef HAVE_DECL_NID_SECP384R1
+@@ -80,6 +130,10 @@
+ don't. */
+ #undef HAVE_DECL_REALLOCARRAY
+
++/* Define to 1 if you have the declaration of `redisConnect', and to 0 if you
++ don't. */
++#undef HAVE_DECL_REDISCONNECT
++
+ /* Define to 1 if you have the declaration of `sk_SSL_COMP_pop_free', and to 0
+ if you don't. */
+ #undef HAVE_DECL_SK_SSL_COMP_POP_FREE
+@@ -107,6 +161,9 @@
+ /* Define to 1 if you have the <dlfcn.h> header file. */
+ #undef HAVE_DLFCN_H
+
++/* Define to 1 if you have the `DSA_SIG_set0' function. */
++#undef HAVE_DSA_SIG_SET0
++
+ /* Define to 1 if you have the <endian.h> header file. */
+ #undef HAVE_ENDIAN_H
+
+@@ -125,6 +182,9 @@
+ /* Define to 1 if you have the `ERR_load_crypto_strings' function. */
+ #undef HAVE_ERR_LOAD_CRYPTO_STRINGS
+
++/* Define to 1 if you have the `event_assign' function. */
++#undef HAVE_EVENT_ASSIGN
++
+ /* Define to 1 if you have the `event_base_free' function. */
+ #undef HAVE_EVENT_BASE_FREE
+
+@@ -140,9 +200,21 @@
+ /* Define to 1 if you have the <event.h> header file. */
+ #undef HAVE_EVENT_H
+
++/* Define to 1 if you have the `EVP_aes_256_cbc' function. */
++#undef HAVE_EVP_AES_256_CBC
++
+ /* Define to 1 if you have the `EVP_cleanup' function. */
+ #undef HAVE_EVP_CLEANUP
+
++/* Define to 1 if you have the `EVP_DigestVerify' function. */
++#undef HAVE_EVP_DIGESTVERIFY
++
++/* Define to 1 if you have the `EVP_dss1' function. */
++#undef HAVE_EVP_DSS1
++
++/* Define to 1 if you have the `EVP_EncryptInit_ex' function. */
++#undef HAVE_EVP_ENCRYPTINIT_EX
++
+ /* Define to 1 if you have the `EVP_MD_CTX_new' function. */
+ #undef HAVE_EVP_MD_CTX_NEW
+
+@@ -164,6 +236,9 @@
+ /* Define to 1 if you have the <expat.h> header file. */
+ #undef HAVE_EXPAT_H
+
++/* Define to 1 if you have the `explicit_bzero' function. */
++#undef HAVE_EXPLICIT_BZERO
++
+ /* Define to 1 if you have the `fcntl' function. */
+ #undef HAVE_FCNTL
+
+@@ -209,9 +284,18 @@
+ /* Define to 1 if you have the <grp.h> header file. */
+ #undef HAVE_GRP_H
+
++/* Define to 1 if you have the <hiredis/hiredis.h> header file. */
++#undef HAVE_HIREDIS_HIREDIS_H
++
++/* Define to 1 if you have the `HMAC_Init_ex' function. */
++#undef HAVE_HMAC_INIT_EX
++
+ /* If you have HMAC_Update */
+ #undef HAVE_HMAC_UPDATE
+
++/* If we have htobe64 */
++#undef HAVE_HTOBE64
++
+ /* Define to 1 if you have the `inet_aton' function. */
+ #undef HAVE_INET_ATON
+
+@@ -239,6 +323,12 @@
+ /* Define to 1 if you have the `kill' function. */
+ #undef HAVE_KILL
+
++/* Use portable libbsd functions */
++#undef HAVE_LIBBSD
++
++/* Define to 1 if you have the <libkern/OSByteOrder.h> header file. */
++#undef HAVE_LIBKERN_OSBYTEORDER_H
++
+ /* Define if we have LibreSSL */
+ #undef HAVE_LIBRESSL
+
+@@ -272,6 +362,9 @@
+ /* Define to 1 if you have the <nettle/dsa-compat.h> header file. */
+ #undef HAVE_NETTLE_DSA_COMPAT_H
+
++/* Define to 1 if you have the <nettle/eddsa.h> header file. */
++#undef HAVE_NETTLE_EDDSA_H
++
+ /* Use libnss for crypto */
+ #undef HAVE_NSS
+
+@@ -338,15 +431,12 @@
+ /* Define to 1 if you have the `RAND_cleanup' function. */
+ #undef HAVE_RAND_CLEANUP
+
+-/* Define to 1 if you have the `reallocarray' function. */
++/* If we have reallocarray(3) */
+ #undef HAVE_REALLOCARRAY
+
+ /* Define to 1 if you have the `recvmsg' function. */
+ #undef HAVE_RECVMSG
+
+-/* define if you have the sbrk() call */
+-#undef HAVE_SBRK
+-
+ /* Define to 1 if you have the `sendmsg' function. */
+ #undef HAVE_SENDMSG
+
+@@ -374,6 +464,9 @@
+ /* Define to 1 if you have the `SHA512_Update' function. */
+ #undef HAVE_SHA512_UPDATE
+
++/* Define to 1 if you have the `shmget' function. */
++#undef HAVE_SHMGET
++
+ /* Define to 1 if you have the `sigprocmask' function. */
+ #undef HAVE_SIGPROCMASK
+
+@@ -395,6 +488,21 @@
+ /* Define if you have the SSL libraries installed. */
+ #undef HAVE_SSL
+
++/* Define to 1 if you have the `SSL_CTX_set_ciphersuites' function. */
++#undef HAVE_SSL_CTX_SET_CIPHERSUITES
++
++/* Define to 1 if you have the `SSL_CTX_set_security_level' function. */
++#undef HAVE_SSL_CTX_SET_SECURITY_LEVEL
++
++/* Define to 1 if you have the `SSL_CTX_set_tlsext_ticket_key_cb' function. */
++#undef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_CB
++
++/* Define to 1 if you have the `SSL_get0_peername' function. */
++#undef HAVE_SSL_GET0_PEERNAME
++
++/* Define to 1 if you have the `SSL_set1_host' function. */
++#undef HAVE_SSL_SET1_HOST
++
+ /* Define to 1 if you have the <stdarg.h> header file. */
+ #undef HAVE_STDARG_H
+
+@@ -440,6 +548,15 @@
+ /* Define to 1 if you have the <syslog.h> header file. */
+ #undef HAVE_SYSLOG_H
+
++/* Define to 1 if systemd should be used */
++#undef HAVE_SYSTEMD
++
++/* Define to 1 if you have the <sys/endian.h> header file. */
++#undef HAVE_SYS_ENDIAN_H
++
++/* Define to 1 if you have the <sys/ipc.h> header file. */
++#undef HAVE_SYS_IPC_H
++
+ /* Define to 1 if you have the <sys/param.h> header file. */
+ #undef HAVE_SYS_PARAM_H
+
+@@ -449,6 +566,9 @@
+ /* Define to 1 if you have the <sys/sha2.h> header file. */
+ #undef HAVE_SYS_SHA2_H
+
++/* Define to 1 if you have the <sys/shm.h> header file. */
++#undef HAVE_SYS_SHM_H
++
+ /* Define to 1 if you have the <sys/socket.h> header file. */
+ #undef HAVE_SYS_SOCKET_H
+
+@@ -509,9 +629,15 @@
+ /* Define to 1 if you have the <ws2tcpip.h> header file. */
+ #undef HAVE_WS2TCPIP_H
+
++/* Define to 1 if you have the `X509_VERIFY_PARAM_set1_host' function. */
++#undef HAVE_X509_VERIFY_PARAM_SET1_HOST
++
+ /* Define to 1 if you have the `_beginthreadex' function. */
+ #undef HAVE__BEGINTHREADEX
+
++/* If HMAC_Init_ex() returns void */
++#undef HMAC_INIT_EX_RETURNS_VOID
++
+ /* if lex has yylex_destroy */
+ #undef LEX_HAS_YYLEX_DESTROY
+
+@@ -586,6 +712,9 @@
+ /* Define as the return type of signal handlers (`int' or `void'). */
+ #undef RETSIGTYPE
+
++/* if REUSEPORT is enabled by default */
++#undef REUSEPORT_DEFAULT
++
+ /* default rootkey location */
+ #undef ROOT_ANCHOR_FILE
+
+@@ -601,6 +730,9 @@
+ /* Shared data */
+ #undef SHARE_DIR
+
++/* The size of `size_t', as computed by sizeof. */
++#undef SIZEOF_SIZE_T
++
+ /* The size of `time_t', as computed by sizeof. */
+ #undef SIZEOF_TIME_T
+
+@@ -607,6 +739,9 @@
+ /* define if (v)snprintf does not return length needed, (but length used) */
+ #undef SNPRINTF_RET_BROKEN
+
++/* Define to 1 if libsodium supports sodium_set_misuse_handler */
++#undef SODIUM_MISUSE_HANDLER
++
+ /* Define to 1 if you have the ANSI C header files. */
+ #undef STDC_HEADERS
+
+@@ -616,6 +751,9 @@
+ /* Use win32 resources and API */
+ #undef UB_ON_WINDOWS
+
++/* the SYSLOG_FACILITY to use, default LOG_DAEMON */
++#undef UB_SYSLOG_FACILITY
++
+ /* default username */
+ #undef UB_USERNAME
+
+@@ -634,6 +772,12 @@
+ /* Define to 1 to use cachedb support */
+ #undef USE_CACHEDB
+
++/* Define to 1 to enable dnscrypt support */
++#undef USE_DNSCRYPT
++
++/* Define to 1 to enable dnscrypt with xchacha20 support */
++#undef USE_DNSCRYPT_XCHACHA20
++
+ /* Define to 1 to enable dnstap support */
+ #undef USE_DNSTAP
+
+@@ -646,9 +790,21 @@
+ /* Define this to enable an EVP workaround for older openssl */
+ #undef USE_ECDSA_EVP_WORKAROUND
+
++/* Define this to enable ED25519 support. */
++#undef USE_ED25519
++
++/* Define this to enable ED448 support. */
++#undef USE_ED448
++
+ /* Define this to enable GOST support. */
+ #undef USE_GOST
+
++/* Define to 1 to use ipsecmod support. */
++#undef USE_IPSECMOD
++
++/* Define to 1 to use ipset support */
++#undef USE_IPSET
++
+ /* Define if you want to use internal select based events */
+ #undef USE_MINI_EVENT
+
+@@ -658,6 +814,12 @@
+ /* Define this to enable client TCP Fast Open. */
+ #undef USE_OSX_MSG_FASTOPEN
+
++/* Define this to use hiredis client. */
++#undef USE_REDIS
++
++/* Define this to enable SHA1 support. */
++#undef USE_SHA1
++
+ /* Define this to enable SHA256 and SHA512 support. */
+ #undef USE_SHA2
+
+@@ -840,8 +1002,14 @@
+
+
+
++#ifndef _OPENBSD_SOURCE
++#define _OPENBSD_SOURCE 1
++#endif
++
+ #ifndef UNBOUND_DEBUG
++# ifndef NDEBUG
+ # define NDEBUG
++# endif
+ #endif
+
+ /** Use small-ldns codebase */
+@@ -1055,6 +1223,19 @@
+ int isblank(int c);
+ #endif
+
++#ifndef HAVE_EXPLICIT_BZERO
++#define explicit_bzero unbound_explicit_bzero
++void explicit_bzero(void* buf, size_t len);
++#endif
++
++#if defined(HAVE_INET_NTOP) && !HAVE_DECL_INET_NTOP
++const char *inet_ntop(int af, const void *src, char *dst, size_t size);
++#endif
++
++#if defined(HAVE_INET_PTON) && !HAVE_DECL_INET_PTON
++int inet_pton(int af, const char* src, void* dst);
++#endif
++
+ #if !defined(HAVE_STRPTIME) || !defined(STRPTIME_WORKS)
+ #define strptime unbound_strptime
+ struct tm;
+@@ -1061,6 +1242,15 @@
+ char *strptime(const char *s, const char *format, struct tm *tm);
+ #endif
+
++#if !HAVE_DECL_REALLOCARRAY
++void *reallocarray(void *ptr, size_t nmemb, size_t size);
++#endif
++
++#ifdef HAVE_LIBBSD
++#include <bsd/string.h>
++#include <bsd/stdlib.h>
++#endif
++
+ #ifdef HAVE_LIBRESSL
+ # if !HAVE_DECL_STRLCPY
+ size_t strlcpy(char *dst, const char *src, size_t siz);
+@@ -1074,17 +1264,14 @@
+ # if !HAVE_DECL_ARC4RANDOM_UNIFORM && defined(HAVE_ARC4RANDOM_UNIFORM)
+ uint32_t arc4random_uniform(uint32_t upper_bound);
+ # endif
+-# if !HAVE_DECL_REALLOCARRAY
+-void *reallocarray(void *ptr, size_t nmemb, size_t size);
+-# endif
+ #endif /* HAVE_LIBRESSL */
+ #ifndef HAVE_ARC4RANDOM
+-void explicit_bzero(void* buf, size_t len);
+ int getentropy(void* buf, size_t len);
+ uint32_t arc4random(void);
+ void arc4random_buf(void* buf, size_t n);
+ void _ARC4_LOCK(void);
+ void _ARC4_UNLOCK(void);
++void _ARC4_LOCK_DESTROY(void);
+ #endif
+ #ifndef HAVE_ARC4RANDOM_UNIFORM
+ uint32_t arc4random_uniform(uint32_t upper_bound);
+@@ -1150,6 +1337,8 @@
+
+ /** default port for DNS traffic. */
+ #define UNBOUND_DNS_PORT 53
++/** default port for DNS over TLS traffic. */
++#define UNBOUND_DNS_OVER_TLS_PORT 853
+ /** default port for unbound control traffic, registered port with IANA,
+ ub-dns-control 8953/tcp unbound dns nameserver control */
+ #define UNBOUND_CONTROL_PORT 8953
+--- contrib/unbound/config.sub.orig
++++ contrib/unbound/config.sub
+@@ -1,8 +1,8 @@
+-#! /bin/sh
++#!/usr/bin/sh
+ # Configuration validation subroutine script.
+-# Copyright 1992-2013 Free Software Foundation, Inc.
++# Copyright 1992-2016 Free Software Foundation, Inc.
+
+-timestamp='2013-08-10'
++timestamp='2016-09-05'
+
+ # This file is free software; you can redistribute it and/or modify it
+ # under the terms of the GNU General Public License as published by
+@@ -25,7 +25,7 @@
+ # of the GNU General Public License, version 3 ("GPLv3").
+
+
+-# Please send patches with a ChangeLog entry to config-patches@gnu.org.
++# Please send patches to <config-patches@gnu.org>.
+ #
+ # Configuration subroutine to validate and canonicalize a configuration type.
+ # Supply the specified configuration type as an argument.
+@@ -33,7 +33,7 @@
+ # Otherwise, we print the canonical config type on stdout and succeed.
+
+ # You can get the latest version of this script from:
+-# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
++# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
+
+ # This file is supposed to be the same for all GNU packages
+ # and recognize all the CPU types, system types and aliases
+@@ -53,8 +53,7 @@
+ me=`echo "$0" | sed -e 's,.*/,,'`
+
+ usage="\
+-Usage: $0 [OPTION] CPU-MFR-OPSYS
+- $0 [OPTION] ALIAS
++Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS
+
+ Canonicalize a configuration name.
+
+@@ -68,7 +67,7 @@
+ version="\
+ GNU config.sub ($timestamp)
+
+-Copyright 1992-2013 Free Software Foundation, Inc.
++Copyright 1992-2016 Free Software Foundation, Inc.
+
+ This is free software; see the source for copying conditions. There is NO
+ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+@@ -117,8 +116,8 @@
+ case $maybe_os in
+ nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
+ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+- knetbsd*-gnu* | netbsd*-gnu* | \
+- kopensolaris*-gnu* | \
++ knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
++ kopensolaris*-gnu* | cloudabi*-eabi* | \
+ storm-chaos* | os2-emx* | rtmk-nova*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+@@ -255,16 +254,18 @@
+ | arc | arceb \
+ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
+ | avr | avr32 \
++ | ba \
+ | be32 | be64 \
+ | bfin \
+ | c4x | c8051 | clipper \
+ | d10v | d30v | dlx | dsp16xx \
+- | epiphany \
+- | fido | fr30 | frv \
++ | e2k | epiphany \
++ | fido | fr30 | frv | ft32 \
+ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+ | hexagon \
+ | i370 | i860 | i960 | ia64 \
+ | ip2k | iq2000 \
++ | k1om \
+ | le32 | le64 \
+ | lm32 \
+ | m32c | m32r | m32rle | m68000 | m68k | m88k \
+@@ -282,8 +283,10 @@
+ | mips64vr5900 | mips64vr5900el \
+ | mipsisa32 | mipsisa32el \
+ | mipsisa32r2 | mipsisa32r2el \
++ | mipsisa32r6 | mipsisa32r6el \
+ | mipsisa64 | mipsisa64el \
+ | mipsisa64r2 | mipsisa64r2el \
++ | mipsisa64r6 | mipsisa64r6el \
+ | mipsisa64sb1 | mipsisa64sb1el \
+ | mipsisa64sr71k | mipsisa64sr71kel \
+ | mipsr5900 | mipsr5900el \
+@@ -295,14 +298,14 @@
+ | nds32 | nds32le | nds32be \
+ | nios | nios2 | nios2eb | nios2el \
+ | ns16k | ns32k \
+- | open8 \
+- | or1k | or32 \
++ | open8 | or1k | or1knd | or32 \
+ | pdp10 | pdp11 | pj | pjl \
+ | powerpc | powerpc64 | powerpc64le | powerpcle \
+ | pyramid \
++ | riscv32 | riscv64 \
+ | rl78 | rx \
+ | score \
+- | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
++ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+ | sh64 | sh64le \
+ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+@@ -310,6 +313,7 @@
+ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
+ | ubicom32 \
+ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
++ | visium \
+ | we32k \
+ | x86 | xc16x | xstormy16 | xtensa \
+ | z8k | z80)
+@@ -324,7 +328,10 @@
+ c6x)
+ basic_machine=tic6x-unknown
+ ;;
+- m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)
++ leon|leon[3-9])
++ basic_machine=sparc-$basic_machine
++ ;;
++ m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+@@ -369,12 +376,13 @@
+ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
+ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
+ | avr-* | avr32-* \
++ | ba-* \
+ | be32-* | be64-* \
+ | bfin-* | bs2000-* \
+ | c[123]* | c30-* | [cjt]90-* | c4x-* \
+ | c8051-* | clipper-* | craynv-* | cydra-* \
+ | d10v-* | d30v-* | dlx-* \
+- | elxsi-* \
++ | e2k-* | elxsi-* \
+ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+ | h8300-* | h8500-* \
+ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+@@ -381,6 +389,7 @@
+ | hexagon-* \
+ | i*86-* | i860-* | i960-* | ia64-* \
+ | ip2k-* | iq2000-* \
++ | k1om-* \
+ | le32-* | le64-* \
+ | lm32-* \
+ | m32c-* | m32r-* | m32rle-* \
+@@ -400,8 +409,10 @@
+ | mips64vr5900-* | mips64vr5900el-* \
+ | mipsisa32-* | mipsisa32el-* \
+ | mipsisa32r2-* | mipsisa32r2el-* \
++ | mipsisa32r6-* | mipsisa32r6el-* \
+ | mipsisa64-* | mipsisa64el-* \
+ | mipsisa64r2-* | mipsisa64r2el-* \
++ | mipsisa64r6-* | mipsisa64r6el-* \
+ | mipsisa64sb1-* | mipsisa64sb1el-* \
+ | mipsisa64sr71k-* | mipsisa64sr71kel-* \
+ | mipsr5900-* | mipsr5900el-* \
+@@ -413,16 +424,18 @@
+ | nios-* | nios2-* | nios2eb-* | nios2el-* \
+ | none-* | np1-* | ns16k-* | ns32k-* \
+ | open8-* \
++ | or1k*-* \
+ | orion-* \
+ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
+ | pyramid-* \
++ | riscv32-* | riscv64-* \
+ | rl78-* | romp-* | rs6000-* | rx-* \
+ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+ | sparclite-* \
+- | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
++ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \
+ | tahoe-* \
+ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+ | tile*-* \
+@@ -430,6 +443,7 @@
+ | ubicom32-* \
+ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
+ | vax-* \
++ | visium-* \
+ | we32k-* \
+ | x86-* | x86_64-* | xc16x-* | xps100-* \
+ | xstormy16-* | xtensa*-* \
+@@ -506,6 +520,9 @@
+ basic_machine=i386-pc
+ os=-aros
+ ;;
++ asmjs)
++ basic_machine=asmjs-unknown
++ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=-aux
+@@ -626,6 +643,14 @@
+ basic_machine=m68k-bull
+ os=-sysv3
+ ;;
++ e500v[12])
++ basic_machine=powerpc-unknown
++ os=$os"spe"
++ ;;
++ e500v[12]-*)
++ basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
++ os=$os"spe"
++ ;;
+ ebmon29k)
+ basic_machine=a29k-amd
+ os=-ebmon
+@@ -767,6 +792,9 @@
+ basic_machine=m68k-isi
+ os=-sysv
+ ;;
++ leon-*|leon[3-9]-*)
++ basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'`
++ ;;
+ m68knommu)
+ basic_machine=m68k-unknown
+ os=-linux
+@@ -822,6 +850,10 @@
+ basic_machine=powerpc-unknown
+ os=-morphos
+ ;;
++ moxiebox)
++ basic_machine=moxie-unknown
++ os=-moxiebox
++ ;;
+ msdos)
+ basic_machine=i386-pc
+ os=-msdos
+@@ -998,7 +1030,7 @@
+ ppc-* | ppcbe-*)
+ basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+- ppcle | powerpclittle | ppc-le | powerpc-little)
++ ppcle | powerpclittle)
+ basic_machine=powerpcle-unknown
+ ;;
+ ppcle-* | powerpclittle-*)
+@@ -1006,9 +1038,9 @@
+ ;;
+ ppc64) basic_machine=powerpc64-unknown
+ ;;
+- ppc64-* | ppc64p7-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
++ ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+- ppc64le | powerpc64little | ppc64-le | powerpc64-little)
++ ppc64le | powerpc64little)
+ basic_machine=powerpc64le-unknown
+ ;;
+ ppc64le-* | powerpc64little-*)
+@@ -1354,11 +1386,11 @@
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+ | -sym* | -kopensolaris* | -plan9* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+- | -aos* | -aros* \
++ | -aos* | -aros* | -cloudabi* | -sortix* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+- | -bitrig* | -openbsd* | -solidbsd* \
++ | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \
+ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+@@ -1365,9 +1397,9 @@
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+ | -chorusos* | -chorusrdb* | -cegcc* \
+ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+- | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
++ | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
+ | -linux-newlib* | -linux-musl* | -linux-uclibc* \
+- | -uxpv* | -beos* | -mpeix* | -udk* \
++ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
+ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+@@ -1374,7 +1406,8 @@
+ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+- | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
++ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \
++ | -onefs* | -tirtos* | -phoenix*)
+ # Remember, each alternative MUST END IN *, to match a version number.
+ ;;
+ -qnx*)
+@@ -1506,6 +1539,8 @@
+ ;;
+ -nacl*)
+ ;;
++ -ios)
++ ;;
+ -none)
+ ;;
+ *)
+@@ -1592,9 +1627,6 @@
+ mips*-*)
+ os=-elf
+ ;;
+- or1k-*)
+- os=-elf
+- ;;
+ or32-*)
+ os=-coff
+ ;;
+--- contrib/unbound/configure.orig
++++ contrib/unbound/configure
+@@ -1,8 +1,8 @@
+ #! /bin/sh
+ # Guess values for system-dependent variables and create Makefiles.
+-# Generated by GNU Autoconf 2.69 for unbound 1.5.10.
++# Generated by GNU Autoconf 2.69 for unbound 1.10.1.
+ #
+-# Report bugs to <unbound-bugs@nlnetlabs.nl>.
++# Report bugs to <unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues>.
+ #
+ #
+ # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
+@@ -275,10 +275,11 @@
+ $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+ else
+ $as_echo "$0: Please tell bug-autoconf@gnu.org and
+-$0: unbound-bugs@nlnetlabs.nl about your system, including
+-$0: any error possibly output before this message. Then
+-$0: install a modern shell, or manually run the script
+-$0: under such a shell if you do have one."
++$0: unbound-bugs@nlnetlabs.nl or
++$0: https://github.com/NLnetLabs/unbound/issues about your
++$0: system, including any error possibly output before this
++$0: message. Then install a modern shell, or manually run
++$0: the script under such a shell if you do have one."
+ fi
+ exit 1
+ fi
+@@ -590,9 +591,9 @@
+ # Identity of this package.
+ PACKAGE_NAME='unbound'
+ PACKAGE_TARNAME='unbound'
+-PACKAGE_VERSION='1.5.10'
+-PACKAGE_STRING='unbound 1.5.10'
+-PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl'
++PACKAGE_VERSION='1.10.1'
++PACKAGE_STRING='unbound 1.10.1'
++PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues'
+ PACKAGE_URL=''
+
+ # Factoring default headers for most tests.
+@@ -638,6 +639,14 @@
+ ALLTARGET
+ SOURCEFILE
+ SOURCEDETERMINE
++IPSET_OBJ
++IPSET_SRC
++IPSECMOD_HEADER
++IPSECMOD_OBJ
++DNSCRYPT_OBJ
++DNSCRYPT_SRC
++ENABLE_DNSCRYPT
++ENABLE_DNSCRYPT_XCHACHA20
+ DNSTAP_OBJ
+ DNSTAP_SRC
+ opt_dnstap_socket_path
+@@ -659,10 +668,15 @@
+ WINDRES
+ CHECKLOCK_OBJ
+ staticexe
++PC_LIBEVENT_DEPENDENCY
+ UNBOUND_EVENT_UNINSTALL
+ UNBOUND_EVENT_INSTALL
++SUBNET_HEADER
++SUBNET_OBJ
++PC_LIBBSD_DEPENDENCY
+ SSLLIB
+ HAVE_SSL
++PC_CRYPTO_DEPENDENCY
+ CONFIG_DATE
+ NETBSD_LINTFLAGS
+ PYUNBOUND_UNINSTALL
+@@ -678,6 +692,7 @@
+ swig
+ SWIG_LIB
+ SWIG
++PC_PY_DEPENDENCY
+ PY_MAJOR_VERSION
+ PYTHON_SITE_PKG
+ PYTHON_LDFLAGS
+@@ -689,8 +704,19 @@
+ PTHREAD_LIBS
+ PTHREAD_CC
+ ax_pthread_config
++ASYNCLOOK_ALLOCCHECK_EXTRA_OBJ
++SLDNS_ALLOCCHECK_EXTRA_OBJ
++USE_SYSTEMD_FALSE
++USE_SYSTEMD_TRUE
++SYSTEMD_DAEMON_LIBS
++SYSTEMD_DAEMON_CFLAGS
++SYSTEMD_LIBS
++SYSTEMD_CFLAGS
+ RUNTIME_PATH
+ LIBOBJS
++PKG_CONFIG_LIBDIR
++PKG_CONFIG_PATH
++PKG_CONFIG
+ LT_SYS_LIBRARY_PATH
+ OTOOL64
+ OTOOL
+@@ -739,6 +765,9 @@
+ UNBOUND_RUN_DIR
+ ub_conf_dir
+ ub_conf_file
++UNBOUND_LOCALSTATE_DIR
++UNBOUND_SYSCONF_DIR
++UNBOUND_SBIN_DIR
+ EGREP
+ GREP
+ CPP
+@@ -819,26 +848,36 @@
+ enable_libtool_lock
+ enable_rpath
+ enable_largefile
++enable_systemd
+ enable_alloc_checks
+ enable_alloc_lite
+ enable_alloc_nonregional
+ with_pthreads
+ with_solaris_threads
++with_syslog_facility
+ with_pyunbound
+ with_pythonmodule
++enable_swig_version_check
+ with_nss
+ with_nettle
+ with_ssl
++with_libbsd
++enable_sha1
+ enable_sha2
++enable_subnet
+ enable_gost
+ enable_ecdsa
+ enable_dsa
++enable_ed25519
++enable_ed448
+ enable_event_api
+ enable_tfo_client
+ enable_tfo_server
+ with_libevent
+ with_libexpat
++with_libhiredis
+ enable_static_exe
++enable_fully_static
+ enable_lock_checks
+ enable_allsymbols
+ enable_dnstap
+@@ -845,7 +884,12 @@
+ with_dnstap_socket_path
+ with_protobuf_c
+ with_libfstrm
++enable_dnscrypt
++with_libsodium
+ enable_cachedb
++enable_ipsecmod
++enable_ipset
++with_libmnl
+ with_libunbound_only
+ '
+ ac_precious_vars='build_alias
+@@ -860,6 +904,13 @@
+ YACC
+ YFLAGS
+ LT_SYS_LIBRARY_PATH
++PKG_CONFIG
++PKG_CONFIG_PATH
++PKG_CONFIG_LIBDIR
++SYSTEMD_CFLAGS
++SYSTEMD_LIBS
++SYSTEMD_DAEMON_CFLAGS
++SYSTEMD_DAEMON_LIBS
+ PYTHON_VERSION'
+
+
+@@ -1401,7 +1452,7 @@
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat <<_ACEOF
+-\`configure' configures unbound 1.5.10 to adapt to many kinds of systems.
++\`configure' configures unbound 1.10.1 to adapt to many kinds of systems.
+
+ Usage: $0 [OPTION]... [VAR=VALUE]...
+
+@@ -1466,7 +1517,7 @@
+
+ if test -n "$ac_init_help"; then
+ case $ac_init_help in
+- short | recursive ) echo "Configuration of unbound 1.5.10:";;
++ short | recursive ) echo "Configuration of unbound 1.10.1:";;
+ esac
+ cat <<\_ACEOF
+
+@@ -1488,6 +1539,7 @@
+ --disable-libtool-lock avoid locking (might break parallel builds)
+ --disable-rpath disable hardcoded rpath (default=enabled)
+ --disable-largefile omit support for large files
++ --enable-systemd compile with systemd support
+ --enable-alloc-checks enable to memory allocation statistics, for debug
+ purposes
+ --enable-alloc-lite enable for lightweight alloc assertions, for debug
+@@ -1496,16 +1548,25 @@
+ enable nonregional allocs, slow but exposes regional
+ allocations to other memory purifiers, for debug
+ purposes
++ --disable-swig-version-check
++ Disable swig version check to build python modules
++ with older swig even though that is unreliable
++ --disable-sha1 Disable SHA1 RRSIG support, does not disable nsec3
++ support
+ --disable-sha2 Disable SHA256 and SHA512 RRSIG support
++ --enable-subnet Enable client subnet
+ --disable-gost Disable GOST support
+ --disable-ecdsa Disable ECDSA support
+ --disable-dsa Disable DSA support
++ --disable-ed25519 Disable ED25519 support
++ --disable-ed448 Disable ED448 support
+ --enable-event-api Enable (experimental) pluggable event base
+ libunbound API installed to unbound-event.h
+ --enable-tfo-client Enable TCP Fast Open for client mode
+ --enable-tfo-server Enable TCP Fast Open for server mode
+ --enable-static-exe enable to compile executables statically against
+- (event) libs, for debug purposes
++ (event) uninstalled libs, for debug purposes
++ --enable-fully-static enable to compile fully static
+ --enable-lock-checks enable to check lock and unlock calls, for debug
+ purposes
+ --enable-allsymbols export all symbols from libunbound and link binaries
+@@ -1512,8 +1573,12 @@
+ to it, smaller install size but libunbound export
+ table is polluted by internal symbols
+ --enable-dnstap Enable dnstap support (requires fstrm, protobuf-c)
++ --enable-dnscrypt Enable dnscrypt support (requires libsodium)
+ --enable-cachedb enable cachedb module that can use external cache
+ storage
++ --enable-ipsecmod Enable ipsecmod module that facilitates
++ opportunistic IPsec
++ --enable-ipset enable ipset module
+
+ Optional Packages:
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+@@ -1547,6 +1612,8 @@
+ --with-pthreads use pthreads library, or --without-pthreads to
+ disable threading support.
+ --with-solaris-threads use solaris native thread library.
++ --with-syslog-facility=LOCAL0 - LOCAL7
++ set SYSLOG_FACILITY, default DAEMON
+ --with-pyunbound build PyUnbound, or --without-pyunbound to skip it.
+ (default=no)
+ --with-pythonmodule build Python module, or --without-pythonmodule to
+@@ -1556,6 +1623,7 @@
+ --with-ssl=pathname enable SSL (will check /usr/local/ssl /usr/lib/ssl
+ /usr/ssl /usr/pkg /usr/local /opt/local /usr/sfw
+ /usr)
++ --with-libbsd Use portable libbsd functions
+ --with-libevent=pathname
+ use libevent (will check /usr/local /opt/local
+ /usr/lib /usr/pkg /usr/sfw /usr or you can specify
+@@ -1562,10 +1630,13 @@
+ an explicit path). Slower, but allows use of large
+ outgoing port ranges.
+ --with-libexpat=path specify explicit path for libexpat.
++ --with-libhiredis=path specify explicit path for libhiredis.
+ --with-dnstap-socket-path=pathname
+ set default dnstap socket path
+ --with-protobuf-c=path Path where protobuf-c is installed, for dnstap
+ --with-libfstrm=path Path where libfstrm is installed, for dnstap
++ --with-libsodium=path Path where libsodium is installed, for dnscrypt
++ --with-libmnl=path specify explicit path for libmnl.
+ --with-libunbound-only do not build daemon and tool programs
+
+ Some influential environment variables:
+@@ -1585,6 +1656,19 @@
+ default value of `-d' given by some make applications.
+ LT_SYS_LIBRARY_PATH
+ User-defined run-time library search path.
++ PKG_CONFIG path to pkg-config utility
++ PKG_CONFIG_PATH
++ directories to add to pkg-config's search path
++ PKG_CONFIG_LIBDIR
++ path overriding pkg-config's built-in search path
++ SYSTEMD_CFLAGS
++ C compiler flags for SYSTEMD, overriding pkg-config
++ SYSTEMD_LIBS
++ linker flags for SYSTEMD, overriding pkg-config
++ SYSTEMD_DAEMON_CFLAGS
++ C compiler flags for SYSTEMD_DAEMON, overriding pkg-config
++ SYSTEMD_DAEMON_LIBS
++ linker flags for SYSTEMD_DAEMON, overriding pkg-config
+ PYTHON_VERSION
+ The installed Python version to use, for example '2.3'. This
+ string will be appended to the Python interpreter canonical
+@@ -1593,7 +1677,7 @@
+ Use these variables to override the choices made by `configure' or to help
+ it to find libraries and programs with nonstandard names/locations.
+
+-Report bugs to <unbound-bugs@nlnetlabs.nl>.
++Report bugs to <unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues>.
+ _ACEOF
+ ac_status=$?
+ fi
+@@ -1656,7 +1740,7 @@
+ test -n "$ac_init_help" && exit $ac_status
+ if $ac_init_version; then
+ cat <<\_ACEOF
+-unbound configure 1.5.10
++unbound configure 1.10.1
+ generated by GNU Autoconf 2.69
+
+ Copyright (C) 2012 Free Software Foundation, Inc.
+@@ -1815,9 +1899,9 @@
+ $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+ $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+-( $as_echo "## ---------------------------------------- ##
+-## Report this to unbound-bugs@nlnetlabs.nl ##
+-## ---------------------------------------- ##"
++( $as_echo "## --------------------------------------------------------------------------------------- ##
++## Report this to unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues ##
++## --------------------------------------------------------------------------------------- ##"
+ ) | sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+ esac
+@@ -2365,7 +2449,7 @@
+ This file contains any messages produced by compilers while
+ running configure, to aid debugging if configure makes a mistake.
+
+-It was created by unbound $as_me 1.5.10, which was
++It was created by unbound $as_me 1.10.1, which was
+ generated by GNU Autoconf 2.69. Invocation command line was
+
+ $ $0 $@
+@@ -2715,14 +2799,14 @@
+
+ UNBOUND_VERSION_MAJOR=1
+
+-UNBOUND_VERSION_MINOR=5
++UNBOUND_VERSION_MINOR=10
+
+-UNBOUND_VERSION_MICRO=10
++UNBOUND_VERSION_MICRO=1
+
+
+-LIBUNBOUND_CURRENT=6
+-LIBUNBOUND_REVISION=2
+-LIBUNBOUND_AGE=4
++LIBUNBOUND_CURRENT=9
++LIBUNBOUND_REVISION=8
++LIBUNBOUND_AGE=1
+ # 1.0.0 had 0:12:0
+ # 1.0.1 had 0:13:0
+ # 1.0.2 had 0:14:0
+@@ -2771,6 +2855,32 @@
+ # 1.5.8 had 6:0:4 # adds ub_ctx_set_stub
+ # 1.5.9 had 6:1:4
+ # 1.5.10 had 6:2:4
++# 1.6.0 had 6:3:4
++# 1.6.1 had 7:0:5 # ub_callback_t typedef renamed to ub_callback_type
++# 1.6.2 had 7:1:5
++# 1.6.3 had 7:2:5
++# 1.6.4 had 7:3:5
++# 1.6.5 had 7:4:5
++# 1.6.6 had 7:5:5
++# 1.6.7 had 7:6:5
++# 1.6.8 had 7:7:5
++# 1.7.0 had 7:8:5
++# 1.7.1 had 7:9:5
++# 1.7.2 had 7:10:5
++# 1.7.3 had 7:11:5
++# 1.8.0 had 8:0:0 # changes the event callback function signature
++# 1.8.1 had 8:1:0
++# 1.8.2 had 8:2:0
++# 1.8.3 had 8:3:0
++# 1.9.0 had 9:0:1 # add ub_ctx_set_tls
++# 1.9.1 had 9:1:1
++# 1.9.2 had 9:2:1
++# 1.9.3 had 9:3:1
++# 1.9.4 had 9:4:1
++# 1.9.5 had 9:5:1
++# 1.9.6 had 9:6:1
++# 1.10.0 had 9:7:1
++# 1.10.1 had 9:8:1
+
+ # Current -- the number of the binary API that we're implementing
+ # Revision -- which iteration of the implementation of the binary
+@@ -2786,7 +2896,7 @@
+ # Current and Age. Set Revision to 0, since this is the first
+ # implementation of the new API.
+ #
+-# Otherwise, we're changing the binary API and breaking bakward
++# Otherwise, we're changing the binary API and breaking backward
+ # compatibility with old binaries. Increment Current. Set Age to 0,
+ # since we're backward compatible with no previous APIs. Set Revision
+ # to 0 too.
+@@ -2794,6 +2904,14 @@
+
+
+
++
++cmdln="`echo $@ | sed -e 's/\\\\/\\\\\\\\/g' | sed -e 's/"/\\\\"/'g`"
++
++cat >>confdefs.h <<_ACEOF
++#define CONFCMDLINE "$cmdln"
++_ACEOF
++
++
+ CFLAGS="$CFLAGS"
+ ac_ext=c
+ ac_cpp='$CPP $CPPFLAGS'
+@@ -4055,6 +4173,11 @@
+ prefix="/usr/local"
+ ;;
+ esac
++case "$exec_prefix" in
++ NONE)
++ exec_prefix="$prefix"
++ ;;
++esac
+
+ # are we on MinGW?
+ if uname -s 2>&1 | grep MINGW32 >/dev/null; then on_mingw="yes"
+@@ -4066,10 +4189,16 @@
+ #
+ # Determine configuration file
+ # the eval is to evaluate shell expansion twice
++UNBOUND_SBIN_DIR=`eval echo "${sbindir}"`
++
++UNBOUND_SYSCONF_DIR=`eval echo "${sysconfdir}"`
++
++UNBOUND_LOCALSTATE_DIR=`eval echo "${localstatedir}"`
++
+ if test $on_mingw = "no"; then
+ ub_conf_file=`eval echo "${sysconfdir}/unbound/unbound.conf"`
+ else
+- ub_conf_file="C:\\Program Files (x86)\\Unbound\\service.conf"
++ ub_conf_file="C:\\Program Files\\Unbound\\service.conf"
+ fi
+
+ # Check whether --with-conf_file was given.
+@@ -4200,7 +4329,7 @@
+ if test $on_mingw = no; then
+ UNBOUND_ROOTKEY_FILE="$UNBOUND_RUN_DIR/root.key"
+ else
+- UNBOUND_ROOTKEY_FILE="C:\\Program Files (x86)\\Unbound\\root.key"
++ UNBOUND_ROOTKEY_FILE="C:\\Program Files\\Unbound\\root.key"
+ fi
+
+ fi
+@@ -4222,7 +4351,7 @@
+ if test $on_mingw = no; then
+ UNBOUND_ROOTCERT_FILE="$UNBOUND_RUN_DIR/icannbundle.pem"
+ else
+- UNBOUND_ROOTCERT_FILE="C:\\Program Files (x86)\\Unbound\\icannbundle.pem"
++ UNBOUND_ROOTCERT_FILE="C:\\Program Files\\Unbound\\icannbundle.pem"
+ fi
+
+ fi
+@@ -4351,6 +4480,7 @@
+ ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ # allow user to override the -g -O2 flags.
++default_cflags=no
+ if test "x$CFLAGS" = "x" ; then
+
+
+@@ -4414,6 +4544,7 @@
+
+ fi
+
++default_cflags=yes
+ fi
+ ac_ext=c
+ ac_cpp='$CPP $CPPFLAGS'
+@@ -5867,6 +5998,10 @@
+ # nothing to do.
+ ;;
+ esac
++if test "$default_cflags" = "yes"; then
++ # only when CFLAGS was "" at the start, if the users wants to
++ # override we shouldn't add default cflags, because they wouldn't
++ # be able to turn off these options and set the CFLAGS wanted.
+
+ # Check whether --enable-flto was given.
+ if test "${enable_flto+set}" = set; then :
+@@ -6001,6 +6136,7 @@
+
+ fi
+
++fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5
+ $as_echo_n "checking for inline... " >&6; }
+@@ -6167,9 +6303,57 @@
+
+ $as_echo "#define HAVE_ATTR_WEAK 1" >>confdefs.h
+
++
++$as_echo "#define ATTR_WEAK __attribute__((weak))" >>confdefs.h
++
+ fi
+
+
++
++
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler (${CC-cc}) accepts the \"noreturn\" attribute" >&5
++$as_echo_n "checking whether the C compiler (${CC-cc}) accepts the \"noreturn\" attribute... " >&6; }
++if ${ac_cv_c_noreturn_attribute+:} false; then :
++ $as_echo_n "(cached) " >&6
++else
++ ac_cv_c_noreturn_attribute=no
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h. */
++ #include <stdio.h>
++__attribute__((noreturn)) void f(int x) { printf("%d", x); }
++
++int
++main ()
++{
++
++ f(1);
++
++ ;
++ return 0;
++}
++_ACEOF
++if ac_fn_c_try_compile "$LINENO"; then :
++ ac_cv_c_noreturn_attribute="yes"
++else
++ ac_cv_c_noreturn_attribute="no"
++fi
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++
++fi
++
++
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_noreturn_attribute" >&5
++$as_echo "$ac_cv_c_noreturn_attribute" >&6; }
++if test $ac_cv_c_noreturn_attribute = yes; then
++
++$as_echo "#define HAVE_ATTR_NORETURN 1" >>confdefs.h
++
++
++$as_echo "#define ATTR_NORETURN __attribute__((__noreturn__))" >>confdefs.h
++
++fi
++
++
+ if test "$srcdir" != "."; then
+ CPPFLAGS="$CPPFLAGS -I$srcdir"
+ fi
+@@ -6176,6 +6360,8 @@
+
+
+
++
++
+ for ac_prog in flex lex
+ do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+@@ -6335,6 +6521,7 @@
+ rm -f conftest.l $LEX_OUTPUT_ROOT.c
+
+ fi
++if test "$LEX" != "" -a "$LEX" != ":"; then
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for yylex_destroy" >&5
+ $as_echo_n "checking for yylex_destroy... " >&6; }
+@@ -6345,8 +6532,27 @@
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+ $as_echo "yes" >&6; }
+ else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+-$as_echo "no" >&6; }; fi
++$as_echo "no" >&6; };
++ LEX=":"
++ fi
+
++fi
++if test "$LEX" != "" -a "$LEX" != ":"; then
++
++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for lex %option" >&5
++$as_echo_n "checking for lex %option... " >&6; }
++ if cat <<EOF | $LEX -t 2>&1 | grep yy_delete_buffer >/dev/null 2>&1; then
++%option nounput
++%%
++EOF
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
++$as_echo "yes" >&6; }
++ else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; };
++ LEX=":"
++ fi
++
++fi
+ for ac_prog in 'bison -y' byacc
+ do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+@@ -14386,8 +14592,129 @@
+
+
+
++
++
++
++
++
++
++
++if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
++ if test -n "$ac_tool_prefix"; then
++ # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
++set dummy ${ac_tool_prefix}pkg-config; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if ${ac_cv_path_PKG_CONFIG+:} false; then :
++ $as_echo_n "(cached) " >&6
++else
++ case $PKG_CONFIG in
++ [\\/]* | ?:[\\/]*)
++ ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
++ ;;
++ *)
++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ for ac_exec_ext in '' $ac_executable_extensions; do
++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++ ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++ break 2
++ fi
++done
++ done
++IFS=$as_save_IFS
++
++ ;;
++esac
++fi
++PKG_CONFIG=$ac_cv_path_PKG_CONFIG
++if test -n "$PKG_CONFIG"; then
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5
++$as_echo "$PKG_CONFIG" >&6; }
++else
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++
++fi
++if test -z "$ac_cv_path_PKG_CONFIG"; then
++ ac_pt_PKG_CONFIG=$PKG_CONFIG
++ # Extract the first word of "pkg-config", so it can be a program name with args.
++set dummy pkg-config; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if ${ac_cv_path_ac_pt_PKG_CONFIG+:} false; then :
++ $as_echo_n "(cached) " >&6
++else
++ case $ac_pt_PKG_CONFIG in
++ [\\/]* | ?:[\\/]*)
++ ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path.
++ ;;
++ *)
++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ for ac_exec_ext in '' $ac_executable_extensions; do
++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++ ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++ break 2
++ fi
++done
++ done
++IFS=$as_save_IFS
++
++ ;;
++esac
++fi
++ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG
++if test -n "$ac_pt_PKG_CONFIG"; then
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5
++$as_echo "$ac_pt_PKG_CONFIG" >&6; }
++else
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++ if test "x$ac_pt_PKG_CONFIG" = x; then
++ PKG_CONFIG=""
++ else
++ case $cross_compiling:$ac_tool_warned in
++yes:)
++{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
++$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
++ac_tool_warned=yes ;;
++esac
++ PKG_CONFIG=$ac_pt_PKG_CONFIG
++ fi
++else
++ PKG_CONFIG="$ac_cv_path_PKG_CONFIG"
++fi
++
++fi
++if test -n "$PKG_CONFIG"; then
++ _pkg_min_version=0.9.0
++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5
++$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; }
++ if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
++$as_echo "yes" >&6; }
++ else
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++ PKG_CONFIG=""
++ fi
++fi
++
+ # Checks for header files.
+-for ac_header in stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h
++for ac_header in stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/endian.h libkern/OSByteOrder.h sys/ipc.h sys/shm.h
+ do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+@@ -14750,7 +15077,40 @@
+ _ACEOF
+
+
++# The cast to long int works around a bug in the HP C Compiler
++# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
++# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
++# This bug is HP SR number 8606223364.
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of size_t" >&5
++$as_echo_n "checking size of size_t... " >&6; }
++if ${ac_cv_sizeof_size_t+:} false; then :
++ $as_echo_n "(cached) " >&6
++else
++ if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (size_t))" "ac_cv_sizeof_size_t" "$ac_includes_default"; then :
+
++else
++ if test "$ac_cv_type_size_t" = yes; then
++ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
++$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
++as_fn_error 77 "cannot compute sizeof (size_t)
++See \`config.log' for more details" "$LINENO" 5; }
++ else
++ ac_cv_sizeof_size_t=0
++ fi
++fi
++
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_size_t" >&5
++$as_echo "$ac_cv_sizeof_size_t" >&6; }
++
++
++
++cat >>confdefs.h <<_ACEOF
++#define SIZEOF_SIZE_T $ac_cv_sizeof_size_t
++_ACEOF
++
++
++
+ # add option to disable the evil rpath
+
+ # Check whether --enable-rpath was given.
+@@ -15797,6 +16157,208 @@
+ done
+
+
++# check if we can use SO_REUSEPORT
++if echo "$host" | $GREP -i -e linux -e dragonfly >/dev/null; then
++
++$as_echo "#define REUSEPORT_DEFAULT 1" >>confdefs.h
++
++else
++
++$as_echo "#define REUSEPORT_DEFAULT 0" >>confdefs.h
++
++fi
++
++# Include systemd.m4 - begin
++# macros for configuring systemd
++# Copyright 2015, Sami Kerola, CloudFlare.
++# BSD licensed.
++# Check whether --enable-systemd was given.
++if test "${enable_systemd+set}" = set; then :
++ enableval=$enable_systemd;
++else
++ enable_systemd=no
++fi
++
++have_systemd=no
++if test "x$enable_systemd" != xno; then :
++
++
++
++pkg_failed=no
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SYSTEMD" >&5
++$as_echo_n "checking for SYSTEMD... " >&6; }
++
++if test -n "$SYSTEMD_CFLAGS"; then
++ pkg_cv_SYSTEMD_CFLAGS="$SYSTEMD_CFLAGS"
++ elif test -n "$PKG_CONFIG"; then
++ if test -n "$PKG_CONFIG" && \
++ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsystemd\""; } >&5
++ ($PKG_CONFIG --exists --print-errors "libsystemd") 2>&5
++ ac_status=$?
++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++ test $ac_status = 0; }; then
++ pkg_cv_SYSTEMD_CFLAGS=`$PKG_CONFIG --cflags "libsystemd" 2>/dev/null`
++ test "x$?" != "x0" && pkg_failed=yes
++else
++ pkg_failed=yes
++fi
++ else
++ pkg_failed=untried
++fi
++if test -n "$SYSTEMD_LIBS"; then
++ pkg_cv_SYSTEMD_LIBS="$SYSTEMD_LIBS"
++ elif test -n "$PKG_CONFIG"; then
++ if test -n "$PKG_CONFIG" && \
++ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsystemd\""; } >&5
++ ($PKG_CONFIG --exists --print-errors "libsystemd") 2>&5
++ ac_status=$?
++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++ test $ac_status = 0; }; then
++ pkg_cv_SYSTEMD_LIBS=`$PKG_CONFIG --libs "libsystemd" 2>/dev/null`
++ test "x$?" != "x0" && pkg_failed=yes
++else
++ pkg_failed=yes
++fi
++ else
++ pkg_failed=untried
++fi
++
++
++
++if test $pkg_failed = yes; then
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++
++if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
++ _pkg_short_errors_supported=yes
++else
++ _pkg_short_errors_supported=no
++fi
++ if test $_pkg_short_errors_supported = yes; then
++ SYSTEMD_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libsystemd" 2>&1`
++ else
++ SYSTEMD_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libsystemd" 2>&1`
++ fi
++ # Put the nasty error message in config.log where it belongs
++ echo "$SYSTEMD_PKG_ERRORS" >&5
++
++ have_systemd=no
++elif test $pkg_failed = untried; then
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++ have_systemd=no
++else
++ SYSTEMD_CFLAGS=$pkg_cv_SYSTEMD_CFLAGS
++ SYSTEMD_LIBS=$pkg_cv_SYSTEMD_LIBS
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
++$as_echo "yes" >&6; }
++ have_systemd=yes
++fi
++ if test "x$have_systemd" != "xyes"; then :
++
++
++pkg_failed=no
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SYSTEMD_DAEMON" >&5
++$as_echo_n "checking for SYSTEMD_DAEMON... " >&6; }
++
++if test -n "$SYSTEMD_DAEMON_CFLAGS"; then
++ pkg_cv_SYSTEMD_DAEMON_CFLAGS="$SYSTEMD_DAEMON_CFLAGS"
++ elif test -n "$PKG_CONFIG"; then
++ if test -n "$PKG_CONFIG" && \
++ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsystemd-daemon\""; } >&5
++ ($PKG_CONFIG --exists --print-errors "libsystemd-daemon") 2>&5
++ ac_status=$?
++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++ test $ac_status = 0; }; then
++ pkg_cv_SYSTEMD_DAEMON_CFLAGS=`$PKG_CONFIG --cflags "libsystemd-daemon" 2>/dev/null`
++ test "x$?" != "x0" && pkg_failed=yes
++else
++ pkg_failed=yes
++fi
++ else
++ pkg_failed=untried
++fi
++if test -n "$SYSTEMD_DAEMON_LIBS"; then
++ pkg_cv_SYSTEMD_DAEMON_LIBS="$SYSTEMD_DAEMON_LIBS"
++ elif test -n "$PKG_CONFIG"; then
++ if test -n "$PKG_CONFIG" && \
++ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libsystemd-daemon\""; } >&5
++ ($PKG_CONFIG --exists --print-errors "libsystemd-daemon") 2>&5
++ ac_status=$?
++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++ test $ac_status = 0; }; then
++ pkg_cv_SYSTEMD_DAEMON_LIBS=`$PKG_CONFIG --libs "libsystemd-daemon" 2>/dev/null`
++ test "x$?" != "x0" && pkg_failed=yes
++else
++ pkg_failed=yes
++fi
++ else
++ pkg_failed=untried
++fi
++
++
++
++if test $pkg_failed = yes; then
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++
++if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
++ _pkg_short_errors_supported=yes
++else
++ _pkg_short_errors_supported=no
++fi
++ if test $_pkg_short_errors_supported = yes; then
++ SYSTEMD_DAEMON_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libsystemd-daemon" 2>&1`
++ else
++ SYSTEMD_DAEMON_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libsystemd-daemon" 2>&1`
++ fi
++ # Put the nasty error message in config.log where it belongs
++ echo "$SYSTEMD_DAEMON_PKG_ERRORS" >&5
++
++ have_systemd_daemon=no
++elif test $pkg_failed = untried; then
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++ have_systemd_daemon=no
++else
++ SYSTEMD_DAEMON_CFLAGS=$pkg_cv_SYSTEMD_DAEMON_CFLAGS
++ SYSTEMD_DAEMON_LIBS=$pkg_cv_SYSTEMD_DAEMON_LIBS
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
++$as_echo "yes" >&6; }
++ have_systemd_daemon=yes
++fi
++ if test "x$have_systemd_daemon" = "xyes"; then :
++ have_systemd=yes
++fi
++
++fi
++ case $enable_systemd:$have_systemd in #(
++ yes:no) :
++ as_fn_error $? "systemd enabled but libsystemd not found" "$LINENO" 5 ;; #(
++ *:yes) :
++
++$as_echo "#define HAVE_SYSTEMD 1" >>confdefs.h
++
++ LIBS="$LIBS $SYSTEMD_LIBS"
++
++ ;; #(
++ *) :
++ ;;
++esac
++
++
++fi
++ if test "x$have_systemd" = xyes; then
++ USE_SYSTEMD_TRUE=
++ USE_SYSTEMD_FALSE='#'
++else
++ USE_SYSTEMD_TRUE='#'
++ USE_SYSTEMD_FALSE=
++fi
++
++
++# Include systemd.m4 - end
++
+ # set memory allocation checking if requested
+ # Check whether --enable-alloc-checks was given.
+ if test "${enable_alloc_checks+set}" = set; then :
+@@ -15822,6 +16384,10 @@
+
+ $as_echo "#define UNBOUND_ALLOC_STATS 1" >>confdefs.h
+
++ SLDNS_ALLOCCHECK_EXTRA_OBJ="alloc.lo log.lo"
++
++ ASYNCLOOK_ALLOCCHECK_EXTRA_OBJ="alloc.lo"
++
+ else
+ if test x_$enable_alloc_lite = x_yes; then
+
+@@ -16389,7 +16955,9 @@
+
+ $as_echo "#define HAVE_PTHREAD 1" >>confdefs.h
+
+- LIBS="$PTHREAD_LIBS $LIBS"
++ if test -n "$PTHREAD_LIBS"; then
++ LIBS="$PTHREAD_LIBS $LIBS"
++ fi
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+ CC="$PTHREAD_CC"
+ ub_have_pthreads=yes
+@@ -16583,6 +17151,26 @@
+
+ fi # end of non-mingw check of thread libraries
+
++# Check for SYSLOG_FACILITY
++
++# Check whether --with-syslog-facility was given.
++if test "${with_syslog_facility+set}" = set; then :
++ withval=$with_syslog_facility; UNBOUND_SYSLOG_FACILITY="$withval"
++fi
++
++case "${UNBOUND_SYSLOG_FACILITY}" in
++
++ LOCAL[0-7]) UNBOUND_SYSLOG_FACILITY="LOG_${UNBOUND_SYSLOG_FACILITY}" ;;
++
++ *) UNBOUND_SYSLOG_FACILITY="LOG_DAEMON" ;;
++
++esac
++
++cat >>confdefs.h <<_ACEOF
++#define UB_SYSLOG_FACILITY ${UNBOUND_SYSLOG_FACILITY}
++_ACEOF
++
++
+ # Check for PyUnbound
+
+ # Check whether --with-pyunbound was given.
+@@ -16682,8 +17270,7 @@
+ #
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for the distutils Python package" >&5
+ $as_echo_n "checking for the distutils Python package... " >&6; }
+- ac_distutils_result=`$PYTHON -c "import distutils" 2>&1`
+- if test -z "$ac_distutils_result"; then
++ if ac_distutils_result=`$PYTHON -c "import distutils" 2>&1`; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+ $as_echo "yes" >&6; }
+ else
+@@ -16820,13 +17407,38 @@
+
+ $as_echo "#define HAVE_PYTHON 1" >>confdefs.h
+
+- LIBS="$PYTHON_LDFLAGS $LIBS"
+- CPPFLAGS="$CPPFLAGS $PYTHON_CPPFLAGS"
++ if test -n "$LIBS"; then
++ LIBS="$PYTHON_LDFLAGS $LIBS"
++ else
++ LIBS="$PYTHON_LDFLAGS"
++ fi
++ if test -n "$CPPFLAGS"; then
++ CPPFLAGS="$CPPFLAGS $PYTHON_CPPFLAGS"
++ else
++ CPPFLAGS="$PYTHON_CPPFLAGS"
++ fi
+ ub_have_python=yes
++ if test -n "$PKG_CONFIG" && \
++ { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\"python\${PY_MAJOR_VERSION}\"\""; } >&5
++ ($PKG_CONFIG --exists --print-errors ""python${PY_MAJOR_VERSION}"") 2>&5
++ ac_status=$?
++ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++ test $ac_status = 0; }; then
++ PC_PY_DEPENDENCY="python${PY_MAJOR_VERSION}"
++else
++ PC_PY_DEPENDENCY="python"
++fi
+
++
+ # Check for SWIG
+ ub_have_swig=no
++ # Check whether --enable-swig-version-check was given.
++if test "${enable_swig_version_check+set}" = set; then :
++ enableval=$enable_swig_version_check;
++fi
+
++ if test "$enable_swig_version_check" = "yes"; then
++
+ # Extract the first word of "swig", so it can be a program name with args.
+ set dummy swig; ac_word=$2
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+@@ -16871,6 +17483,123 @@
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cannot find 'swig' program. You should look at http://www.swig.org" >&5
+ $as_echo "$as_me: WARNING: cannot find 'swig' program. You should look at http://www.swig.org" >&2;}
+ SWIG='echo "Error: SWIG is not installed. You should look at http://www.swig.org" ; false'
++ elif test -n "2.0.1" ; then
++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SWIG version" >&5
++$as_echo_n "checking for SWIG version... " >&6; }
++ swig_version=`$SWIG -version 2>&1 | grep 'SWIG Version' | sed 's/.*\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*/\1/g'`
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $swig_version" >&5
++$as_echo "$swig_version" >&6; }
++ if test -n "$swig_version" ; then
++ # Calculate the required version number components
++ required=2.0.1
++ required_major=`echo $required | sed 's/[^0-9].*//'`
++ if test -z "$required_major" ; then
++ required_major=0
++ fi
++ required=`echo $required | sed 's/[0-9]*[^0-9]//'`
++ required_minor=`echo $required | sed 's/[^0-9].*//'`
++ if test -z "$required_minor" ; then
++ required_minor=0
++ fi
++ required=`echo $required | sed 's/[0-9]*[^0-9]//'`
++ required_patch=`echo $required | sed 's/[^0-9].*//'`
++ if test -z "$required_patch" ; then
++ required_patch=0
++ fi
++ # Calculate the available version number components
++ available=$swig_version
++ available_major=`echo $available | sed 's/[^0-9].*//'`
++ if test -z "$available_major" ; then
++ available_major=0
++ fi
++ available=`echo $available | sed 's/[0-9]*[^0-9]//'`
++ available_minor=`echo $available | sed 's/[^0-9].*//'`
++ if test -z "$available_minor" ; then
++ available_minor=0
++ fi
++ available=`echo $available | sed 's/[0-9]*[^0-9]//'`
++ available_patch=`echo $available | sed 's/[^0-9].*//'`
++ if test -z "$available_patch" ; then
++ available_patch=0
++ fi
++ badversion=0
++ if test $available_major -lt $required_major ; then
++ badversion=1
++ fi
++ if test $available_major -eq $required_major \
++ -a $available_minor -lt $required_minor ; then
++ badversion=1
++ fi
++ if test $available_major -eq $required_major \
++ -a $available_minor -eq $required_minor \
++ -a $available_patch -lt $required_patch ; then
++ badversion=1
++ fi
++ if test $badversion -eq 1 ; then
++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: SWIG version >= 2.0.1 is required. You have $swig_version. You should look at http://www.swig.org" >&5
++$as_echo "$as_me: WARNING: SWIG version >= 2.0.1 is required. You have $swig_version. You should look at http://www.swig.org" >&2;}
++ SWIG='echo "Error: SWIG version >= 2.0.1 is required. You have '"$swig_version"'. You should look at http://www.swig.org" ; false'
++ else
++ { $as_echo "$as_me:${as_lineno-$LINENO}: SWIG executable is '$SWIG'" >&5
++$as_echo "$as_me: SWIG executable is '$SWIG'" >&6;}
++ SWIG_LIB=`$SWIG -swiglib`
++ { $as_echo "$as_me:${as_lineno-$LINENO}: SWIG library directory is '$SWIG_LIB'" >&5
++$as_echo "$as_me: SWIG library directory is '$SWIG_LIB'" >&6;}
++ fi
++ else
++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cannot determine SWIG version" >&5
++$as_echo "$as_me: WARNING: cannot determine SWIG version" >&2;}
++ SWIG='echo "Error: Cannot determine SWIG version. You should look at http://www.swig.org" ; false'
++ fi
++ fi
++
++
++ else
++
++ # Extract the first word of "swig", so it can be a program name with args.
++set dummy swig; ac_word=$2
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
++$as_echo_n "checking for $ac_word... " >&6; }
++if ${ac_cv_path_SWIG+:} false; then :
++ $as_echo_n "(cached) " >&6
++else
++ case $SWIG in
++ [\\/]* | ?:[\\/]*)
++ ac_cv_path_SWIG="$SWIG" # Let the user override the test with a path.
++ ;;
++ *)
++ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
++for as_dir in $PATH
++do
++ IFS=$as_save_IFS
++ test -z "$as_dir" && as_dir=.
++ for ac_exec_ext in '' $ac_executable_extensions; do
++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
++ ac_cv_path_SWIG="$as_dir/$ac_word$ac_exec_ext"
++ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
++ break 2
++ fi
++done
++ done
++IFS=$as_save_IFS
++
++ ;;
++esac
++fi
++SWIG=$ac_cv_path_SWIG
++if test -n "$SWIG"; then
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SWIG" >&5
++$as_echo "$SWIG" >&6; }
++else
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++
++
++ if test -z "$SWIG" ; then
++ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cannot find 'swig' program. You should look at http://www.swig.org" >&5
++$as_echo "$as_me: WARNING: cannot find 'swig' program. You should look at http://www.swig.org" >&2;}
++ SWIG='echo "Error: SWIG is not installed. You should look at http://www.swig.org" ; false'
+ elif test -n "" ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SWIG version" >&5
+ $as_echo_n "checking for SWIG version... " >&6; }
+@@ -16910,9 +17639,20 @@
+ if test -z "$available_patch" ; then
+ available_patch=0
+ fi
+- if test $available_major -ne $required_major \
+- -o $available_minor -ne $required_minor \
+- -o $available_patch -lt $required_patch ; then
++ badversion=0
++ if test $available_major -lt $required_major ; then
++ badversion=1
++ fi
++ if test $available_major -eq $required_major \
++ -a $available_minor -lt $required_minor ; then
++ badversion=1
++ fi
++ if test $available_major -eq $required_major \
++ -a $available_minor -eq $required_minor \
++ -a $available_patch -lt $required_patch ; then
++ badversion=1
++ fi
++ if test $badversion -eq 1 ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: SWIG version >= is required. You have $swig_version. You should look at http://www.swig.org" >&5
+ $as_echo "$as_me: WARNING: SWIG version >= is required. You have $swig_version. You should look at http://www.swig.org" >&2;}
+ SWIG='echo "Error: SWIG version >= is required. You have '"$swig_version"'. You should look at http://www.swig.org" ; false'
+@@ -16931,6 +17671,7 @@
+ fi
+
+
++ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking SWIG" >&5
+ $as_echo_n "checking SWIG... " >&6; }
+ if test ! -x "$SWIG"; then
+@@ -17023,8 +17764,10 @@
+ fi
+ LIBS="$LIBS -lnss3 -lnspr4"
+ SSLLIB=""
++ PC_CRYPTO_DEPENDENCY="nss nspr"
+
+
++
+ fi
+
+
+@@ -17066,8 +17809,10 @@
+ fi
+ LIBS="$LIBS -lhogweed -lnettle -lgmp"
+ SSLLIB=""
++ PC_CRYPTO_DEPENDENCY="hogweed nettle"
+
+
++
+ fi
+
+
+@@ -17163,8 +17908,8 @@
+ # check if -lwsock32 or -lgdi32 are needed.
+ BAKLIBS="$LIBS"
+ BAKSSLLIBS="$LIBSSL_LIBS"
+- LIBS="$LIBS -lgdi32"
+- LIBSSL_LIBS="$LIBSSL_LIBS -lgdi32"
++ LIBS="$LIBS -lgdi32 -lws2_32"
++ LIBSSL_LIBS="$LIBSSL_LIBS -lgdi32 -lws2_32"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if -lcrypto needs -lgdi32" >&5
+ $as_echo_n "checking if -lcrypto needs -lgdi32... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+@@ -17416,6 +18161,9 @@
+ conftest$ac_exeext conftest.$ac_ext
+ SSLLIB="-lssl"
+
++PC_CRYPTO_DEPENDENCY="libcrypto libssl"
++
++
+ # check if -lcrypt32 is needed because CAPIENG needs that. (on windows)
+ BAKLIBS="$LIBS"
+ LIBS="-lssl $LIBS"
+@@ -17506,17 +18254,7 @@
+ cat >>confdefs.h <<_ACEOF
+ #define HAVE_DECL_ARC4RANDOM_UNIFORM $ac_have_decl
+ _ACEOF
+-ac_fn_c_check_decl "$LINENO" "reallocarray" "ac_cv_have_decl_reallocarray" "$ac_includes_default"
+-if test "x$ac_cv_have_decl_reallocarray" = xyes; then :
+- ac_have_decl=1
+-else
+- ac_have_decl=0
+-fi
+
+-cat >>confdefs.h <<_ACEOF
+-#define HAVE_DECL_REALLOCARRAY $ac_have_decl
+-_ACEOF
+-
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+ $as_echo "no" >&6; }
+@@ -17535,7 +18273,7 @@
+
+ done
+
+-for ac_func in OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup
++for ac_func in OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify SSL_CTX_set_tlsext_ticket_key_cb EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex CRYPTO_THREADID_set_callback
+ do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+@@ -17551,12 +18289,13 @@
+ # these check_funcs need -lssl
+ BAKLIBS="$LIBS"
+ LIBS="-lssl $LIBS"
+-for ac_func in OPENSSL_init_ssl
++for ac_func in OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername X509_VERIFY_PARAM_set1_host SSL_CTX_set_ciphersuites
+ do :
+- ac_fn_c_check_func "$LINENO" "OPENSSL_init_ssl" "ac_cv_func_OPENSSL_init_ssl"
+-if test "x$ac_cv_func_OPENSSL_init_ssl" = xyes; then :
++ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
++ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
++if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+-#define HAVE_OPENSSL_INIT_SSL 1
++#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+ _ACEOF
+
+ fi
+@@ -17655,10 +18394,173 @@
+ #define HAVE_DECL_SSL_CTX_SET_ECDH_AUTO $ac_have_decl
+ _ACEOF
+
++
++if test "$ac_cv_func_HMAC_Init_ex" = "yes"; then
++# check function return type.
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the return type of HMAC_Init_ex" >&5
++$as_echo_n "checking the return type of HMAC_Init_ex... " >&6; }
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h. */
++
++#ifdef HAVE_OPENSSL_ERR_H
++#include <openssl/err.h>
++#endif
++
++#ifdef HAVE_OPENSSL_RAND_H
++#include <openssl/rand.h>
++#endif
++
++#ifdef HAVE_OPENSSL_CONF_H
++#include <openssl/conf.h>
++#endif
++
++#ifdef HAVE_OPENSSL_ENGINE_H
++#include <openssl/engine.h>
++#endif
++#include <openssl/ssl.h>
++#include <openssl/evp.h>
++
++int
++main ()
++{
++
++ HMAC_CTX* hmac_ctx = NULL;
++ void* hmac_key = NULL;
++ const EVP_MD* digest = NULL;
++ int x = HMAC_Init_ex(hmac_ctx, hmac_key, 32, digest, NULL);
++ (void)x;
++
++ ;
++ return 0;
++}
++_ACEOF
++if ac_fn_c_try_compile "$LINENO"; then :
++
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: int" >&5
++$as_echo "int" >&6; }
++
++else
++
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: void" >&5
++$as_echo "void" >&6; }
++
++$as_echo "#define HMAC_INIT_EX_RETURNS_VOID 1" >>confdefs.h
++
++
+ fi
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++fi
+
++fi
+
+
++# libbsd
++
++# Check whether --with-libbsd was given.
++if test "${with_libbsd+set}" = set; then :
++ withval=$with_libbsd;
++ for ac_header in bsd/string.h bsd/stdlib.h
++do :
++ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
++ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
++"
++if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
++ cat >>confdefs.h <<_ACEOF
++#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
++_ACEOF
++
++fi
++
++done
++
++ if test "x$ac_cv_header_bsd_string_h" = xyes -a "x$ac_cv_header_bsd_stdlib_h" = xyes; then
++ for func in strlcpy strlcat arc4random arc4random_uniform reallocarray; do
++ as_ac_Search=`$as_echo "ac_cv_search_$func" | $as_tr_sh`
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing $func" >&5
++$as_echo_n "checking for library containing $func... " >&6; }
++if eval \${$as_ac_Search+:} false; then :
++ $as_echo_n "(cached) " >&6
++else
++ ac_func_search_save_LIBS=$LIBS
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h. */
++
++/* Override any GCC internal prototype to avoid an error.
++ Use char because int might match the return type of a GCC
++ builtin and then its argument prototype would still apply. */
++#ifdef __cplusplus
++extern "C"
++#endif
++char $func ();
++int
++main ()
++{
++return $func ();
++ ;
++ return 0;
++}
++_ACEOF
++for ac_lib in '' bsd; do
++ if test -z "$ac_lib"; then
++ ac_res="none required"
++ else
++ ac_res=-l$ac_lib
++ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
++ fi
++ if ac_fn_c_try_link "$LINENO"; then :
++ eval "$as_ac_Search=\$ac_res"
++fi
++rm -f core conftest.err conftest.$ac_objext \
++ conftest$ac_exeext
++ if eval \${$as_ac_Search+:} false; then :
++ break
++fi
++done
++if eval \${$as_ac_Search+:} false; then :
++
++else
++ eval "$as_ac_Search=no"
++fi
++rm conftest.$ac_ext
++LIBS=$ac_func_search_save_LIBS
++fi
++eval ac_res=\$$as_ac_Search
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
++$as_echo "$ac_res" >&6; }
++eval ac_res=\$$as_ac_Search
++if test "$ac_res" != no; then :
++ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
++
++
++$as_echo "#define HAVE_LIBBSD 1" >>confdefs.h
++
++ PC_LIBBSD_DEPENDENCY=libbsd
++
++
++fi
++
++ done
++ fi
++
++fi
++
++
++# Check whether --enable-sha1 was given.
++if test "${enable_sha1+set}" = set; then :
++ enableval=$enable_sha1;
++fi
++
++case "$enable_sha1" in
++ no)
++ ;;
++ yes|*)
++
++$as_echo "#define USE_SHA1 1" >>confdefs.h
++
++ ;;
++esac
++
++
+ # Check whether --enable-sha2 was given.
+ if test "${enable_sha2+set}" = set; then :
+ enableval=$enable_sha2;
+@@ -17674,6 +18576,25 @@
+ ;;
+ esac
+
++# Check whether --enable-subnet was given.
++if test "${enable_subnet+set}" = set; then :
++ enableval=$enable_subnet;
++fi
++
++case "$enable_subnet" in
++ yes)
++
++$as_echo "#define CLIENT_SUBNET 1" >>confdefs.h
++
++ SUBNET_OBJ="edns-subnet.lo subnetmod.lo addrtree.lo subnet-whitelist.lo"
++
++ SUBNET_HEADER='$(srcdir)/edns-subnet/subnetmod.h $(srcdir)/edns-subnet/edns-subnet.h $(srcdir)/edns-subnet/subnet-whitelist.h $(srcdir)/edns-subnet/addrtree.h'
++
++ ;;
++ no|*)
++ ;;
++esac
++
+ # check wether gost also works
+
+ # Check whether --enable-gost was given.
+@@ -17925,15 +18846,36 @@
+ fi
+
+ use_dsa="no"
+-case "$enable_ecdsa" in
+- no)
+- ;;
+- *)
++case "$enable_dsa" in
++ yes)
+ # detect if DSA is supported, and turn it off if not.
+- ac_fn_c_check_func "$LINENO" "EVP_dss1" "ac_cv_func_EVP_dss1"
+-if test "x$ac_cv_func_EVP_dss1" = xyes; then :
++ if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
++ ac_fn_c_check_func "$LINENO" "DSA_SIG_new" "ac_cv_func_DSA_SIG_new"
++if test "x$ac_cv_func_DSA_SIG_new" = xyes; then :
+
++ as_ac_Type=`$as_echo "ac_cv_type_DSA_SIG*" | $as_tr_sh`
++ac_fn_c_check_type "$LINENO" "DSA_SIG*" "$as_ac_Type" "
++$ac_includes_default
++#ifdef HAVE_OPENSSL_ERR_H
++#include <openssl/err.h>
++#endif
+
++#ifdef HAVE_OPENSSL_RAND_H
++#include <openssl/rand.h>
++#endif
++
++#ifdef HAVE_OPENSSL_CONF_H
++#include <openssl/conf.h>
++#endif
++
++#ifdef HAVE_OPENSSL_ENGINE_H
++#include <openssl/engine.h>
++#endif
++
++"
++if eval test \"x\$"$as_ac_Type"\" = x"yes"; then :
++
++
+ cat >>confdefs.h <<_ACEOF
+ #define USE_DSA 1
+ _ACEOF
+@@ -17944,10 +18886,129 @@
+ fi
+ fi
+
++
++else
++ if test "x$enable_dsa" = "xyes"; then as_fn_error $? "OpenSSL does not support DSA and you used --enable-dsa." "$LINENO" 5
++ fi
++fi
++
++ else
++
++cat >>confdefs.h <<_ACEOF
++#define USE_DSA 1
++_ACEOF
++
++ fi
+ ;;
++ *)
++ # disable dsa by default, RFC 8624 section 3.1, validators MUST NOT
++ # support DSA for DNSSEC Validation.
++ ;;
+ esac
+
++# Check whether --enable-ed25519 was given.
++if test "${enable_ed25519+set}" = set; then :
++ enableval=$enable_ed25519;
++fi
+
++use_ed25519="no"
++case "$enable_ed25519" in
++ no)
++ ;;
++ *)
++ if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
++ ac_fn_c_check_decl "$LINENO" "NID_ED25519" "ac_cv_have_decl_NID_ED25519" "$ac_includes_default
++#include <openssl/evp.h>
++
++"
++if test "x$ac_cv_have_decl_NID_ED25519" = xyes; then :
++ ac_have_decl=1
++else
++ ac_have_decl=0
++fi
++
++cat >>confdefs.h <<_ACEOF
++#define HAVE_DECL_NID_ED25519 $ac_have_decl
++_ACEOF
++if test $ac_have_decl = 1; then :
++
++ use_ed25519="yes"
++
++else
++ if test "x$enable_ed25519" = "xyes"; then as_fn_error $? "OpenSSL does not support ED25519 and you used --enable-ed25519." "$LINENO" 5
++ fi
++fi
++
++ fi
++ if test $USE_NETTLE = "yes"; then
++ for ac_header in nettle/eddsa.h
++do :
++ ac_fn_c_check_header_compile "$LINENO" "nettle/eddsa.h" "ac_cv_header_nettle_eddsa_h" "$ac_includes_default
++"
++if test "x$ac_cv_header_nettle_eddsa_h" = xyes; then :
++ cat >>confdefs.h <<_ACEOF
++#define HAVE_NETTLE_EDDSA_H 1
++_ACEOF
++ use_ed25519="yes"
++fi
++
++done
++
++ fi
++ if test $use_ed25519 = "yes"; then
++
++cat >>confdefs.h <<_ACEOF
++#define USE_ED25519 1
++_ACEOF
++
++ fi
++ ;;
++esac
++
++# Check whether --enable-ed448 was given.
++if test "${enable_ed448+set}" = set; then :
++ enableval=$enable_ed448;
++fi
++
++use_ed448="no"
++case "$enable_ed448" in
++ no)
++ ;;
++ *)
++ if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
++ ac_fn_c_check_decl "$LINENO" "NID_ED448" "ac_cv_have_decl_NID_ED448" "$ac_includes_default
++#include <openssl/evp.h>
++
++"
++if test "x$ac_cv_have_decl_NID_ED448" = xyes; then :
++ ac_have_decl=1
++else
++ ac_have_decl=0
++fi
++
++cat >>confdefs.h <<_ACEOF
++#define HAVE_DECL_NID_ED448 $ac_have_decl
++_ACEOF
++if test $ac_have_decl = 1; then :
++
++ use_ed448="yes"
++
++else
++ if test "x$enable_ed448" = "xyes"; then as_fn_error $? "OpenSSL does not support ED448 and you used --enable-ed448." "$LINENO" 5
++ fi
++fi
++
++ fi
++ if test $use_ed448 = "yes"; then
++
++cat >>confdefs.h <<_ACEOF
++#define USE_ED448 1
++_ACEOF
++
++ fi
++ ;;
++esac
++
+ # Check whether --enable-event-api was given.
+ if test "${enable_event_api+set}" = set; then :
+ enableval=$enable_event_api;
+@@ -18378,6 +19439,37 @@
+ fi
+ done
+ # only in libev. (tested on 4.00)
++ for ac_func in event_assign
++do :
++ ac_fn_c_check_func "$LINENO" "event_assign" "ac_cv_func_event_assign"
++if test "x$ac_cv_func_event_assign" = xyes; then :
++ cat >>confdefs.h <<_ACEOF
++#define HAVE_EVENT_ASSIGN 1
++_ACEOF
++
++fi
++done
++ # in libevent, for thread-safety
++ ac_fn_c_check_decl "$LINENO" "evsignal_assign" "ac_cv_have_decl_evsignal_assign" "$ac_includes_default
++#ifdef HAVE_EVENT_H
++# include <event.h>
++#else
++# include \"event2/event.h\"
++#endif
++
++"
++if test "x$ac_cv_have_decl_evsignal_assign" = xyes; then :
++ ac_have_decl=1
++else
++ ac_have_decl=0
++fi
++
++cat >>confdefs.h <<_ACEOF
++#define HAVE_DECL_EVSIGNAL_ASSIGN $ac_have_decl
++_ACEOF
++
++ PC_LIBEVENT_DEPENDENCY="libevent"
++
+ if test -n "$BAK_LDFLAGS_SET"; then
+ LDFLAGS="$BAK_LDFLAGS"
+ fi
+@@ -18442,8 +19534,72 @@
+ _ACEOF
+
+
+-# set static linking if requested
++# hiredis (redis C client for cachedb)
+
++# Check whether --with-libhiredis was given.
++if test "${with_libhiredis+set}" = set; then :
++ withval=$with_libhiredis;
++else
++ withval="no"
++fi
++
++found_libhiredis="no"
++if test x_$withval = x_yes -o x_$withval != x_no; then
++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libhiredis" >&5
++$as_echo_n "checking for libhiredis... " >&6; }
++ if test x_$withval = x_ -o x_$withval = x_yes; then
++ withval="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr"
++ fi
++ for dir in $withval ; do
++ if test -f "$dir/include/hiredis/hiredis.h"; then
++ found_libhiredis="yes"
++ if test "$dir" != "/usr"; then
++ CPPFLAGS="$CPPFLAGS -I$dir/include"
++ LDFLAGS="$LDFLAGS -L$dir/lib"
++ fi
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: found in $dir" >&5
++$as_echo "found in $dir" >&6; }
++
++$as_echo "#define USE_REDIS 1" >>confdefs.h
++
++ LIBS="$LIBS -lhiredis"
++ break;
++ fi
++ done
++ if test x_$found_libhiredis != x_yes; then
++ as_fn_error $? "Could not find libhiredis, hiredis.h" "$LINENO" 5
++ fi
++ for ac_header in hiredis/hiredis.h
++do :
++ ac_fn_c_check_header_compile "$LINENO" "hiredis/hiredis.h" "ac_cv_header_hiredis_hiredis_h" "$ac_includes_default
++"
++if test "x$ac_cv_header_hiredis_hiredis_h" = xyes; then :
++ cat >>confdefs.h <<_ACEOF
++#define HAVE_HIREDIS_HIREDIS_H 1
++_ACEOF
++
++fi
++
++done
++
++ ac_fn_c_check_decl "$LINENO" "redisConnect" "ac_cv_have_decl_redisConnect" "$ac_includes_default
++ #include <hiredis/hiredis.h>
++
++"
++if test "x$ac_cv_have_decl_redisConnect" = xyes; then :
++ ac_have_decl=1
++else
++ ac_have_decl=0
++fi
++
++cat >>confdefs.h <<_ACEOF
++#define HAVE_DECL_REDISCONNECT $ac_have_decl
++_ACEOF
++
++fi
++
++# set static linking for uninstalled libraries if requested
++
+ staticexe=""
+ # Check whether --enable-static-exe was given.
+ if test "${enable_static_exe+set}" = set; then :
+@@ -18455,10 +19611,34 @@
+ if test "$on_mingw" = yes; then
+ staticexe="-all-static"
+ # for static compile, include gdi32 and zlib here.
+- LIBS="$LIBS -lgdi32 -lz"
++ if echo $LIBS | grep 'lgdi32' >/dev/null; then
++ :
++ else
++ LIBS="$LIBS -lgdi32"
++ fi
++ LIBS="$LIBS -lz"
+ fi
+ fi
+
++# set full static linking if requested
++# Check whether --enable-fully-static was given.
++if test "${enable_fully_static+set}" = set; then :
++ enableval=$enable_fully_static;
++fi
++
++if test x_$enable_fully_static = x_yes; then
++ staticexe="-all-static"
++ if test "$on_mingw" = yes; then
++ # for static compile, include gdi32 and zlib here.
++ if echo $LIBS | grep 'lgdi32' >/dev/null; then
++ :
++ else
++ LIBS="$LIBS -lgdi32"
++ fi
++ LIBS="$LIBS -lz"
++ fi
++fi
++
+ # set lock checking if requested
+ # Check whether --enable-lock_checks was given.
+ if test "${enable_lock_checks+set}" = set; then :
+@@ -18502,7 +19682,11 @@
+ $as_echo "#define USE_WINSOCK 1" >>confdefs.h
+
+ USE_WINSOCK="1"
+- LIBS="$LIBS -lws2_32"
++ if echo $LIBS | grep 'lws2_32' >/dev/null; then
++ :
++ else
++ LIBS="$LIBS -lws2_32"
++ fi
+ fi
+
+ else
+@@ -18666,7 +19850,7 @@
+ WINDRES="$ac_cv_prog_WINDRES"
+ fi
+
+- LIBS="$LIBS -liphlpapi"
++ LIBS="$LIBS -liphlpapi -lcrypt32"
+ WINAPPS="unbound-service-install.exe unbound-service-remove.exe anchor-update.exe"
+
+ WIN_DAEMON_SRC="winrc/win_svc.c winrc/w_inst.c"
+@@ -18844,6 +20028,75 @@
+
+ fi
+
++
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for htobe64" >&5
++$as_echo_n "checking for htobe64... " >&6; }
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h. */
++
++#include <stdio.h>
++#ifdef HAVE_ENDIAN_H
++# include <endian.h>
++#endif
++#ifdef HAVE_SYS_ENDIAN_H
++# include <sys/endian.h>
++#endif
++
++int
++main ()
++{
++unsigned long long x = htobe64(0); printf("%u", (unsigned)x);
++ ;
++ return 0;
++}
++_ACEOF
++if ac_fn_c_try_link "$LINENO"; then :
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
++$as_echo "yes" >&6; }
++
++$as_echo "#define HAVE_HTOBE64 1" >>confdefs.h
++
++else
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++rm -f core conftest.err conftest.$ac_objext \
++ conftest$ac_exeext conftest.$ac_ext
++
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for be64toh" >&5
++$as_echo_n "checking for be64toh... " >&6; }
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h. */
++
++#include <stdio.h>
++#ifdef HAVE_ENDIAN_H
++# include <endian.h>
++#endif
++#ifdef HAVE_SYS_ENDIAN_H
++# include <sys/endian.h>
++#endif
++
++int
++main ()
++{
++unsigned long long x = be64toh(0); printf("%u", (unsigned)x);
++ ;
++ return 0;
++}
++_ACEOF
++if ac_fn_c_try_link "$LINENO"; then :
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
++$as_echo "yes" >&6; }
++
++$as_echo "#define HAVE_BE64TOH 1" >>confdefs.h
++
++else
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++fi
++rm -f core conftest.err conftest.$ac_objext \
++ conftest$ac_exeext conftest.$ac_ext
++
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing setusercontext" >&5
+ $as_echo_n "checking for library containing setusercontext... " >&6; }
+ if ${ac_cv_search_setusercontext+:} false; then :
+@@ -18900,7 +20153,7 @@
+
+ fi
+
+-for ac_func in tzset sigprocmask fcntl getpwnam endpwent getrlimit setrlimit setsid chroot kill chown sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent fsync
++for ac_func in tzset sigprocmask fcntl getpwnam endpwent getrlimit setrlimit setsid chroot kill chown sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent fsync shmget accept4
+ do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+@@ -18959,39 +20212,77 @@
+ done
+
+
+-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sbrk" >&5
+-$as_echo_n "checking for sbrk... " >&6; }
+-# catch the warning of deprecated sbrk
+-old_cflags="$CFLAGS"
+-CFLAGS="$CFLAGS -Werror"
+-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+-/* end confdefs.h. */
++# check if setreuid en setregid fail, on MacOSX10.4(darwin8).
++if echo $target_os | grep darwin8 > /dev/null; then
++
++$as_echo "#define DARWIN_BROKEN_SETREUID 1" >>confdefs.h
++
++fi
++ac_fn_c_check_decl "$LINENO" "inet_pton" "ac_cv_have_decl_inet_pton" "
+ $ac_includes_default
++#ifdef HAVE_NETINET_IN_H
++#include <netinet/in.h>
++#endif
+
+-int main(void) { void* cur = sbrk(0); printf("%u\n", (unsigned)(size_t)((char*)cur - (char*)sbrk(0))); return 0; }
++#ifdef HAVE_NETINET_TCP_H
++#include <netinet/tcp.h>
++#endif
+
++#ifdef HAVE_ARPA_INET_H
++#include <arpa/inet.h>
++#endif
++
++#ifdef HAVE_WINSOCK2_H
++#include <winsock2.h>
++#endif
++
++#ifdef HAVE_WS2TCPIP_H
++#include <ws2tcpip.h>
++#endif
++
++"
++if test "x$ac_cv_have_decl_inet_pton" = xyes; then :
++ ac_have_decl=1
++else
++ ac_have_decl=0
++fi
++
++cat >>confdefs.h <<_ACEOF
++#define HAVE_DECL_INET_PTON $ac_have_decl
+ _ACEOF
+-if ac_fn_c_try_compile "$LINENO"; then :
++ac_fn_c_check_decl "$LINENO" "inet_ntop" "ac_cv_have_decl_inet_ntop" "
++$ac_includes_default
++#ifdef HAVE_NETINET_IN_H
++#include <netinet/in.h>
++#endif
+
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+-$as_echo "yes" >&6; }
++#ifdef HAVE_NETINET_TCP_H
++#include <netinet/tcp.h>
++#endif
+
+-$as_echo "#define HAVE_SBRK 1" >>confdefs.h
++#ifdef HAVE_ARPA_INET_H
++#include <arpa/inet.h>
++#endif
+
++#ifdef HAVE_WINSOCK2_H
++#include <winsock2.h>
++#endif
+
++#ifdef HAVE_WS2TCPIP_H
++#include <ws2tcpip.h>
++#endif
++
++"
++if test "x$ac_cv_have_decl_inet_ntop" = xyes; then :
++ ac_have_decl=1
+ else
+- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+-$as_echo "no" >&6; }
++ ac_have_decl=0
+ fi
+-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+-CFLAGS="$old_cflags"
+
+-# check if setreuid en setregid fail, on MacOSX10.4(darwin8).
+-if echo $build_os | grep darwin8 > /dev/null; then
++cat >>confdefs.h <<_ACEOF
++#define HAVE_DECL_INET_NTOP $ac_have_decl
++_ACEOF
+
+-$as_echo "#define DARWIN_BROKEN_SETREUID 1" >>confdefs.h
+-
+-fi
+ ac_fn_c_check_func "$LINENO" "inet_aton" "ac_cv_func_inet_aton"
+ if test "x$ac_cv_func_inet_aton" = xyes; then :
+ $as_echo "#define HAVE_INET_ATON 1" >>confdefs.h
+@@ -19160,21 +20451,70 @@
+ fi
+
+
++ac_fn_c_check_func "$LINENO" "explicit_bzero" "ac_cv_func_explicit_bzero"
++if test "x$ac_cv_func_explicit_bzero" = xyes; then :
++ $as_echo "#define HAVE_EXPLICIT_BZERO 1" >>confdefs.h
++
++else
++ case " $LIBOBJS " in
++ *" explicit_bzero.$ac_objext "* ) ;;
++ *) LIBOBJS="$LIBOBJS explicit_bzero.$ac_objext"
++ ;;
++esac
++
++fi
++
++
+ LIBOBJ_WITHOUT_CTIMEARC4="$LIBOBJS"
+
+-ac_fn_c_check_func "$LINENO" "reallocarray" "ac_cv_func_reallocarray"
+-if test "x$ac_cv_func_reallocarray" = xyes; then :
+- $as_echo "#define HAVE_REALLOCARRAY 1" >>confdefs.h
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for reallocarray" >&5
++$as_echo_n "checking for reallocarray... " >&6; }
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h. */
++$ac_includes_default
+
++#ifndef _OPENBSD_SOURCE
++#define _OPENBSD_SOURCE 1
++#endif
++#include <stdlib.h>
++int main(void) {
++ void* p = reallocarray(NULL, 10, 100);
++ free(p);
++ return 0;
++}
++
++_ACEOF
++if ac_fn_c_try_link "$LINENO"; then :
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
++$as_echo "yes" >&6; }
++
++$as_echo "#define HAVE_REALLOCARRAY 1" >>confdefs.h
++
++
+ else
+- case " $LIBOBJS " in
++
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++ case " $LIBOBJS " in
+ *" reallocarray.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS reallocarray.$ac_objext"
+ ;;
+ esac
+
++
+ fi
++rm -f core conftest.err conftest.$ac_objext \
++ conftest$ac_exeext conftest.$ac_ext
++ac_fn_c_check_decl "$LINENO" "reallocarray" "ac_cv_have_decl_reallocarray" "$ac_includes_default"
++if test "x$ac_cv_have_decl_reallocarray" = xyes; then :
++ ac_have_decl=1
++else
++ ac_have_decl=0
++fi
+
++cat >>confdefs.h <<_ACEOF
++#define HAVE_DECL_REALLOCARRAY $ac_have_decl
++_ACEOF
+
+ if test "$USE_NSS" = "no"; then
+ ac_fn_c_check_func "$LINENO" "arc4random" "ac_cv_func_arc4random"
+@@ -19207,12 +20547,6 @@
+
+ if test "$ac_cv_func_arc4random" = "no"; then
+ case " $LIBOBJS " in
+- *" explicit_bzero.$ac_objext "* ) ;;
+- *) LIBOBJS="$LIBOBJS explicit_bzero.$ac_objext"
+- ;;
+-esac
+-
+- case " $LIBOBJS " in
+ *" arc4_lock.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS arc4_lock.$ac_objext"
+ ;;
+@@ -19236,8 +20570,8 @@
+ esac
+
+ else
+- case `uname` in
+- Darwin)
++ case "$host" in
++ Darwin|*darwin*)
+ case " $LIBOBJS " in
+ *" getentropy_osx.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS getentropy_osx.$ac_objext"
+@@ -19245,7 +20579,7 @@
+ esac
+
+ ;;
+- SunOS)
++ *solaris*|*sunos*|SunOS)
+ case " $LIBOBJS " in
+ *" getentropy_solaris.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS getentropy_solaris.$ac_objext"
+@@ -19349,8 +20683,16 @@
+ fi
+
+ ;;
+- Linux|*)
++ *freebsd*|*FreeBSD)
+ case " $LIBOBJS " in
++ *" getentropy_freebsd.$ac_objext "* ) ;;
++ *) LIBOBJS="$LIBOBJS getentropy_freebsd.$ac_objext"
++ ;;
++esac
++
++ ;;
++ *linux*|Linux|*)
++ case " $LIBOBJS " in
+ *" getentropy_linux.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS getentropy_linux.$ac_objext"
+ ;;
+@@ -19781,6 +21123,234 @@
+ fi
+
+
++# check for dnscrypt if requested
++
++ # Check whether --enable-dnscrypt was given.
++if test "${enable_dnscrypt+set}" = set; then :
++ enableval=$enable_dnscrypt; opt_dnscrypt=$enableval
++else
++ opt_dnscrypt=no
++fi
++
++
++ if test "x$opt_dnscrypt" != "xno"; then
++
++# Check whether --with-libsodium was given.
++if test "${with_libsodium+set}" = set; then :
++ withval=$with_libsodium;
++ CFLAGS="$CFLAGS -I$withval/include"
++ LDFLAGS="$LDFLAGS -L$withval/lib"
++
++fi
++
++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing sodium_init" >&5
++$as_echo_n "checking for library containing sodium_init... " >&6; }
++if ${ac_cv_search_sodium_init+:} false; then :
++ $as_echo_n "(cached) " >&6
++else
++ ac_func_search_save_LIBS=$LIBS
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h. */
++
++/* Override any GCC internal prototype to avoid an error.
++ Use char because int might match the return type of a GCC
++ builtin and then its argument prototype would still apply. */
++#ifdef __cplusplus
++extern "C"
++#endif
++char sodium_init ();
++int
++main ()
++{
++return sodium_init ();
++ ;
++ return 0;
++}
++_ACEOF
++for ac_lib in '' sodium; do
++ if test -z "$ac_lib"; then
++ ac_res="none required"
++ else
++ ac_res=-l$ac_lib
++ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
++ fi
++ if ac_fn_c_try_link "$LINENO"; then :
++ ac_cv_search_sodium_init=$ac_res
++fi
++rm -f core conftest.err conftest.$ac_objext \
++ conftest$ac_exeext
++ if ${ac_cv_search_sodium_init+:} false; then :
++ break
++fi
++done
++if ${ac_cv_search_sodium_init+:} false; then :
++
++else
++ ac_cv_search_sodium_init=no
++fi
++rm conftest.$ac_ext
++LIBS=$ac_func_search_save_LIBS
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_sodium_init" >&5
++$as_echo "$ac_cv_search_sodium_init" >&6; }
++ac_res=$ac_cv_search_sodium_init
++if test "$ac_res" != no; then :
++ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
++
++else
++ as_fn_error $? "The sodium library was not found. Please install sodium!" "$LINENO" 5
++fi
++
++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing crypto_box_curve25519xchacha20poly1305_beforenm" >&5
++$as_echo_n "checking for library containing crypto_box_curve25519xchacha20poly1305_beforenm... " >&6; }
++if ${ac_cv_search_crypto_box_curve25519xchacha20poly1305_beforenm+:} false; then :
++ $as_echo_n "(cached) " >&6
++else
++ ac_func_search_save_LIBS=$LIBS
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h. */
++
++/* Override any GCC internal prototype to avoid an error.
++ Use char because int might match the return type of a GCC
++ builtin and then its argument prototype would still apply. */
++#ifdef __cplusplus
++extern "C"
++#endif
++char crypto_box_curve25519xchacha20poly1305_beforenm ();
++int
++main ()
++{
++return crypto_box_curve25519xchacha20poly1305_beforenm ();
++ ;
++ return 0;
++}
++_ACEOF
++for ac_lib in '' sodium; do
++ if test -z "$ac_lib"; then
++ ac_res="none required"
++ else
++ ac_res=-l$ac_lib
++ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
++ fi
++ if ac_fn_c_try_link "$LINENO"; then :
++ ac_cv_search_crypto_box_curve25519xchacha20poly1305_beforenm=$ac_res
++fi
++rm -f core conftest.err conftest.$ac_objext \
++ conftest$ac_exeext
++ if ${ac_cv_search_crypto_box_curve25519xchacha20poly1305_beforenm+:} false; then :
++ break
++fi
++done
++if ${ac_cv_search_crypto_box_curve25519xchacha20poly1305_beforenm+:} false; then :
++
++else
++ ac_cv_search_crypto_box_curve25519xchacha20poly1305_beforenm=no
++fi
++rm conftest.$ac_ext
++LIBS=$ac_func_search_save_LIBS
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_crypto_box_curve25519xchacha20poly1305_beforenm" >&5
++$as_echo "$ac_cv_search_crypto_box_curve25519xchacha20poly1305_beforenm" >&6; }
++ac_res=$ac_cv_search_crypto_box_curve25519xchacha20poly1305_beforenm
++if test "$ac_res" != no; then :
++ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
++
++ ENABLE_DNSCRYPT_XCHACHA20=1
++
++
++$as_echo "#define USE_DNSCRYPT_XCHACHA20 1" >>confdefs.h
++
++
++else
++
++ ENABLE_DNSCRYPT_XCHACHA20=0
++
++
++fi
++
++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing sodium_set_misuse_handler" >&5
++$as_echo_n "checking for library containing sodium_set_misuse_handler... " >&6; }
++if ${ac_cv_search_sodium_set_misuse_handler+:} false; then :
++ $as_echo_n "(cached) " >&6
++else
++ ac_func_search_save_LIBS=$LIBS
++cat confdefs.h - <<_ACEOF >conftest.$ac_ext
++/* end confdefs.h. */
++
++/* Override any GCC internal prototype to avoid an error.
++ Use char because int might match the return type of a GCC
++ builtin and then its argument prototype would still apply. */
++#ifdef __cplusplus
++extern "C"
++#endif
++char sodium_set_misuse_handler ();
++int
++main ()
++{
++return sodium_set_misuse_handler ();
++ ;
++ return 0;
++}
++_ACEOF
++for ac_lib in '' sodium; do
++ if test -z "$ac_lib"; then
++ ac_res="none required"
++ else
++ ac_res=-l$ac_lib
++ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
++ fi
++ if ac_fn_c_try_link "$LINENO"; then :
++ ac_cv_search_sodium_set_misuse_handler=$ac_res
++fi
++rm -f core conftest.err conftest.$ac_objext \
++ conftest$ac_exeext
++ if ${ac_cv_search_sodium_set_misuse_handler+:} false; then :
++ break
++fi
++done
++if ${ac_cv_search_sodium_set_misuse_handler+:} false; then :
++
++else
++ ac_cv_search_sodium_set_misuse_handler=no
++fi
++rm conftest.$ac_ext
++LIBS=$ac_func_search_save_LIBS
++fi
++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_sodium_set_misuse_handler" >&5
++$as_echo "$ac_cv_search_sodium_set_misuse_handler" >&6; }
++ac_res=$ac_cv_search_sodium_set_misuse_handler
++if test "$ac_res" != no; then :
++ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
++
++
++$as_echo "#define SODIUM_MISUSE_HANDLER 1" >>confdefs.h
++
++
++fi
++
++
++
++$as_echo "#define USE_DNSCRYPT 1" >>confdefs.h
++
++ ENABLE_DNSCRYPT=1
++
++
++ DNSCRYPT_SRC="dnscrypt/dnscrypt.c"
++
++ DNSCRYPT_OBJ="dnscrypt.lo"
++
++
++ else
++ ENABLE_DNSCRYPT_XCHACHA20=0
++
++
++ ENABLE_DNSCRYPT=0
++
++
++
++ fi
++
++
+ # check for cachedb if requested
+ # Check whether --enable-cachedb was given.
+ if test "${enable_cachedb+set}" = set; then :
+@@ -19787,6 +21357,8 @@
+ enableval=$enable_cachedb;
+ fi
+
++# turn on cachedb when hiredis support is enabled.
++if test "$found_libhiredis" = "yes"; then enable_cachedb="yes"; fi
+ case "$enable_cachedb" in
+ yes)
+
+@@ -19798,6 +21370,80 @@
+ ;;
+ esac
+
++# check for ipsecmod if requested
++# Check whether --enable-ipsecmod was given.
++if test "${enable_ipsecmod+set}" = set; then :
++ enableval=$enable_ipsecmod;
++fi
++
++case "$enable_ipsecmod" in
++ yes)
++
++$as_echo "#define USE_IPSECMOD 1" >>confdefs.h
++
++ IPSECMOD_OBJ="ipsecmod.lo ipsecmod-whitelist.lo"
++
++ IPSECMOD_HEADER='$(srcdir)/ipsecmod/ipsecmod.h $(srcdir)/ipsecmod/ipsecmod-whitelist.h'
++
++ ;;
++ no|*)
++ # nothing
++ ;;
++esac
++
++# check for ipset if requested
++# Check whether --enable-ipset was given.
++if test "${enable_ipset+set}" = set; then :
++ enableval=$enable_ipset;
++fi
++
++case "$enable_ipset" in
++ yes)
++
++$as_echo "#define USE_IPSET 1" >>confdefs.h
++
++ IPSET_SRC="ipset/ipset.c"
++
++ IPSET_OBJ="ipset.lo"
++
++
++ # mnl
++
++# Check whether --with-libmnl was given.
++if test "${with_libmnl+set}" = set; then :
++ withval=$with_libmnl;
++else
++ withval="yes"
++fi
++
++ found_libmnl="no"
++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libmnl" >&5
++$as_echo_n "checking for libmnl... " >&6; }
++ if test x_$withval = x_ -o x_$withval = x_yes; then
++ withval="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr"
++ fi
++ for dir in $withval ; do
++ if test -f "$dir/include/libmnl/libmnl.h"; then
++ found_libmnl="yes"
++ if test "$dir" != "/usr"; then
++ CPPFLAGS="$CPPFLAGS -I$dir/include"
++ LDFLAGS="$LDFLAGS -L$dir/lib"
++ fi
++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: found in $dir" >&5
++$as_echo "found in $dir" >&6; }
++ LIBS="$LIBS -lmnl"
++ break;
++ fi
++ done
++ if test x_$found_libmnl != x_yes; then
++ as_fn_error $? "Could not find libmnl, libmnl.h" "$LINENO" 5
++ fi
++ ;;
++ no|*)
++ # nothing
++ ;;
++esac
++
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if ${MAKE:-make} supports $< with implicit rule in scope" >&5
+ $as_echo_n "checking if ${MAKE:-make} supports $< with implicit rule in scope... " >&6; }
+ # on openBSD, the implicit rule make $< work.
+@@ -19850,10 +21496,19 @@
+
+ fi
+
++if test $ALLTARGET = "alltargets"; then
++ if test $USE_NSS = "yes"; then
++ as_fn_error $? "--with-nss can only be used in combination with --with-libunbound-only." "$LINENO" 5
++ fi
++ if test $USE_NETTLE = "yes"; then
++ as_fn_error $? "--with-nettle can only be used in combination with --with-libunbound-only." "$LINENO" 5
++ fi
++fi
+
+
+
+
++
+ { $as_echo "$as_me:${as_lineno-$LINENO}: Stripping extension flags..." >&5
+ $as_echo "$as_me: Stripping extension flags..." >&6;}
+
+@@ -19929,7 +21584,12 @@
+ fi
+
+
+-LDFLAGS="$LATE_LDFLAGS $LDFLAGS"
++if test -n "$LATE_LDFLAGS"; then
++ LDFLAGS="$LATE_LDFLAGS $LDFLAGS"
++fi
++# remove start spaces
++LDFLAGS=`echo "$LDFLAGS"|sed -e 's/^ *//'`
++LIBS=`echo "$LIBS"|sed -e 's/^ *//'`
+
+
+ cat >>confdefs.h <<_ACEOF
+@@ -19939,12 +21599,12 @@
+
+
+
+-version=1.5.10
++version=1.10.1
+
+ date=`date +'%b %e, %Y'`
+
+
+-ac_config_files="$ac_config_files Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound.conf.5 doc/unbound-control.8 doc/unbound-host.1 smallapp/unbound-control-setup.sh dnstap/dnstap_config.h contrib/libunbound.pc"
++ac_config_files="$ac_config_files Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound.conf.5 doc/unbound-control.8 doc/unbound-host.1 smallapp/unbound-control-setup.sh dnstap/dnstap_config.h dnscrypt/dnscrypt_config.h contrib/libunbound.pc contrib/unbound.socket contrib/unbound.service contrib/unbound_portable.service"
+
+ ac_config_headers="$ac_config_headers config.h"
+
+@@ -20057,6 +21717,10 @@
+ LTLIBOBJS=$ac_ltlibobjs
+
+
++if test -z "${USE_SYSTEMD_TRUE}" && test -z "${USE_SYSTEMD_FALSE}"; then
++ as_fn_error $? "conditional \"USE_SYSTEMD\" was never defined.
++Usually this means the macro was only invoked conditionally." "$LINENO" 5
++fi
+
+ : "${CONFIG_STATUS=./config.status}"
+ ac_write_fail=0
+@@ -20454,7 +22118,7 @@
+ # report actual input values of CONFIG_FILES etc. instead of their
+ # values after options handling.
+ ac_log="
+-This file was extended by unbound $as_me 1.5.10, which was
++This file was extended by unbound $as_me 1.10.1, which was
+ generated by GNU Autoconf 2.69. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+@@ -20514,13 +22178,13 @@
+ Configuration commands:
+ $config_commands
+
+-Report bugs to <unbound-bugs@nlnetlabs.nl>."
++Report bugs to <unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues>."
+
+ _ACEOF
+ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ ac_cs_version="\\
+-unbound config.status 1.5.10
++unbound config.status 1.10.1
+ configured by $0, generated by GNU Autoconf 2.69,
+ with options \\"\$ac_cs_config\\"
+
+@@ -20942,7 +22606,11 @@
+ "doc/unbound-host.1") CONFIG_FILES="$CONFIG_FILES doc/unbound-host.1" ;;
+ "smallapp/unbound-control-setup.sh") CONFIG_FILES="$CONFIG_FILES smallapp/unbound-control-setup.sh" ;;
+ "dnstap/dnstap_config.h") CONFIG_FILES="$CONFIG_FILES dnstap/dnstap_config.h" ;;
++ "dnscrypt/dnscrypt_config.h") CONFIG_FILES="$CONFIG_FILES dnscrypt/dnscrypt_config.h" ;;
+ "contrib/libunbound.pc") CONFIG_FILES="$CONFIG_FILES contrib/libunbound.pc" ;;
++ "contrib/unbound.socket") CONFIG_FILES="$CONFIG_FILES contrib/unbound.socket" ;;
++ "contrib/unbound.service") CONFIG_FILES="$CONFIG_FILES contrib/unbound.service" ;;
++ "contrib/unbound_portable.service") CONFIG_FILES="$CONFIG_FILES contrib/unbound_portable.service" ;;
+ "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+
+ *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+--- contrib/unbound/configure.ac.orig
++++ contrib/unbound/configure.ac
+@@ -6,19 +6,20 @@
+ sinclude(acx_python.m4)
+ sinclude(ac_pkg_swig.m4)
+ sinclude(dnstap/dnstap.m4)
++sinclude(dnscrypt/dnscrypt.m4)
+
+ # must be numbers. ac_defun because of later processing
+ m4_define([VERSION_MAJOR],[1])
+-m4_define([VERSION_MINOR],[5])
+-m4_define([VERSION_MICRO],[10])
+-AC_INIT(unbound, m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]), unbound-bugs@nlnetlabs.nl, unbound)
++m4_define([VERSION_MINOR],[10])
++m4_define([VERSION_MICRO],[1])
++AC_INIT(unbound, m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]), unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues, unbound)
+ AC_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR])
+ AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR])
+ AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO])
+
+-LIBUNBOUND_CURRENT=6
+-LIBUNBOUND_REVISION=2
+-LIBUNBOUND_AGE=4
++LIBUNBOUND_CURRENT=9
++LIBUNBOUND_REVISION=8
++LIBUNBOUND_AGE=1
+ # 1.0.0 had 0:12:0
+ # 1.0.1 had 0:13:0
+ # 1.0.2 had 0:14:0
+@@ -67,6 +68,32 @@
+ # 1.5.8 had 6:0:4 # adds ub_ctx_set_stub
+ # 1.5.9 had 6:1:4
+ # 1.5.10 had 6:2:4
++# 1.6.0 had 6:3:4
++# 1.6.1 had 7:0:5 # ub_callback_t typedef renamed to ub_callback_type
++# 1.6.2 had 7:1:5
++# 1.6.3 had 7:2:5
++# 1.6.4 had 7:3:5
++# 1.6.5 had 7:4:5
++# 1.6.6 had 7:5:5
++# 1.6.7 had 7:6:5
++# 1.6.8 had 7:7:5
++# 1.7.0 had 7:8:5
++# 1.7.1 had 7:9:5
++# 1.7.2 had 7:10:5
++# 1.7.3 had 7:11:5
++# 1.8.0 had 8:0:0 # changes the event callback function signature
++# 1.8.1 had 8:1:0
++# 1.8.2 had 8:2:0
++# 1.8.3 had 8:3:0
++# 1.9.0 had 9:0:1 # add ub_ctx_set_tls
++# 1.9.1 had 9:1:1
++# 1.9.2 had 9:2:1
++# 1.9.3 had 9:3:1
++# 1.9.4 had 9:4:1
++# 1.9.5 had 9:5:1
++# 1.9.6 had 9:6:1
++# 1.10.0 had 9:7:1
++# 1.10.1 had 9:8:1
+
+ # Current -- the number of the binary API that we're implementing
+ # Revision -- which iteration of the implementation of the binary
+@@ -82,7 +109,7 @@
+ # Current and Age. Set Revision to 0, since this is the first
+ # implementation of the new API.
+ #
+-# Otherwise, we're changing the binary API and breaking bakward
++# Otherwise, we're changing the binary API and breaking backward
+ # compatibility with old binaries. Increment Current. Set Age to 0,
+ # since we're backward compatible with no previous APIs. Set Revision
+ # to 0 too.
+@@ -90,6 +117,10 @@
+ AC_SUBST(LIBUNBOUND_REVISION)
+ AC_SUBST(LIBUNBOUND_AGE)
+
++
++cmdln="`echo $@ | sed -e 's/\\\\/\\\\\\\\/g' | sed -e 's/"/\\\\"/'g`"
++AC_DEFINE_UNQUOTED(CONFCMDLINE, ["$cmdln"], [Command line arguments used with configure])
++
+ CFLAGS="$CFLAGS"
+ AC_AIX
+ if test "$ac_cv_header_minix_config_h" = "yes"; then
+@@ -104,6 +135,11 @@
+ prefix="/usr/local"
+ ;;
+ esac
++case "$exec_prefix" in
++ NONE)
++ exec_prefix="$prefix"
++ ;;
++esac
+
+ # are we on MinGW?
+ if uname -s 2>&1 | grep MINGW32 >/dev/null; then on_mingw="yes"
+@@ -115,10 +151,16 @@
+ #
+ # Determine configuration file
+ # the eval is to evaluate shell expansion twice
++UNBOUND_SBIN_DIR=`eval echo "${sbindir}"`
++AC_SUBST(UNBOUND_SBIN_DIR)
++UNBOUND_SYSCONF_DIR=`eval echo "${sysconfdir}"`
++AC_SUBST(UNBOUND_SYSCONF_DIR)
++UNBOUND_LOCALSTATE_DIR=`eval echo "${localstatedir}"`
++AC_SUBST(UNBOUND_LOCALSTATE_DIR)
+ if test $on_mingw = "no"; then
+ ub_conf_file=`eval echo "${sysconfdir}/unbound/unbound.conf"`
+ else
+- ub_conf_file="C:\\Program Files (x86)\\Unbound\\service.conf"
++ ub_conf_file="C:\\Program Files\\Unbound\\service.conf"
+ fi
+ AC_ARG_WITH([conf_file],
+ AC_HELP_STRING([--with-conf-file=path],
+@@ -188,7 +230,7 @@
+ if test $on_mingw = no; then
+ UNBOUND_ROOTKEY_FILE="$UNBOUND_RUN_DIR/root.key"
+ else
+- UNBOUND_ROOTKEY_FILE="C:\\Program Files (x86)\\Unbound\\root.key"
++ UNBOUND_ROOTKEY_FILE="C:\\Program Files\\Unbound\\root.key"
+ fi
+ )
+ AC_SUBST(UNBOUND_ROOTKEY_FILE)
+@@ -202,7 +244,7 @@
+ if test $on_mingw = no; then
+ UNBOUND_ROOTCERT_FILE="$UNBOUND_RUN_DIR/icannbundle.pem"
+ else
+- UNBOUND_ROOTCERT_FILE="C:\\Program Files (x86)\\Unbound\\icannbundle.pem"
++ UNBOUND_ROOTCERT_FILE="C:\\Program Files\\Unbound\\icannbundle.pem"
+ fi
+ )
+ AC_SUBST(UNBOUND_ROOTCERT_FILE)
+@@ -225,9 +267,11 @@
+ AC_C_CONST
+ AC_LANG_C
+ # allow user to override the -g -O2 flags.
++default_cflags=no
+ if test "x$CFLAGS" = "x" ; then
+ ACX_CHECK_COMPILER_FLAG(g, [CFLAGS="$CFLAGS -g"])
+ ACX_CHECK_COMPILER_FLAG(O2, [CFLAGS="$CFLAGS -O2"])
++default_cflags=yes
+ fi
+ AC_PROG_CC
+ ACX_DEPFLAG
+@@ -251,9 +295,14 @@
+ # nothing to do.
+ ;;
+ esac
+-ACX_CHECK_FLTO
+-ACX_CHECK_PIE
+-ACX_CHECK_RELRO_NOW
++if test "$default_cflags" = "yes"; then
++ # only when CFLAGS was "" at the start, if the users wants to
++ # override we shouldn't add default cflags, because they wouldn't
++ # be able to turn off these options and set the CFLAGS wanted.
++ ACX_CHECK_FLTO
++ ACX_CHECK_PIE
++ ACX_CHECK_RELRO_NOW
++fi
+
+ AC_C_INLINE
+ ACX_CHECK_FORMAT_ATTRIBUTE
+@@ -277,11 +326,36 @@
+ AC_MSG_RESULT($ac_cv_c_weak_attribute)
+ if test $ac_cv_c_weak_attribute = yes; then
+ AC_DEFINE(HAVE_ATTR_WEAK, 1, [Whether the C compiler accepts the "weak" attribute])
++ AC_DEFINE(ATTR_WEAK, [__attribute__((weak))], [apply the weak attribute to a symbol])
+ fi
+ ])dnl End of CHECK_WEAK_ATTRIBUTE
+
+ CHECK_WEAK_ATTRIBUTE
+
++AC_DEFUN([CHECK_NORETURN_ATTRIBUTE],
++[AC_REQUIRE([AC_PROG_CC])
++AC_MSG_CHECKING(whether the C compiler (${CC-cc}) accepts the "noreturn" attribute)
++AC_CACHE_VAL(ac_cv_c_noreturn_attribute,
++[ac_cv_c_noreturn_attribute=no
++AC_TRY_COMPILE(
++[ #include <stdio.h>
++__attribute__((noreturn)) void f(int x) { printf("%d", x); }
++], [
++ f(1);
++],
++[ac_cv_c_noreturn_attribute="yes"],
++[ac_cv_c_noreturn_attribute="no"])
++])
++
++AC_MSG_RESULT($ac_cv_c_noreturn_attribute)
++if test $ac_cv_c_noreturn_attribute = yes; then
++ AC_DEFINE(HAVE_ATTR_NORETURN, 1, [Whether the C compiler accepts the "noreturn" attribute])
++ AC_DEFINE(ATTR_NORETURN, [__attribute__((__noreturn__))], [apply the noreturn attribute to a function that exits the program])
++fi
++])dnl End of CHECK_NORETURN_ATTRIBUTE
++
++CHECK_NORETURN_ATTRIBUTE
++
+ if test "$srcdir" != "."; then
+ CPPFLAGS="$CPPFLAGS -I$srcdir"
+ fi
+@@ -291,18 +365,39 @@
+ if echo %% | $LEX -t 2>&1 | grep yylex_destroy >/dev/null 2>&1; then
+ AC_DEFINE(LEX_HAS_YYLEX_DESTROY, 1, [if lex has yylex_destroy])
+ AC_MSG_RESULT(yes)
+- else AC_MSG_RESULT(no); fi
++ else AC_MSG_RESULT(no);
++ LEX=":"
++ fi
+ ])
+
++AC_DEFUN([ACX_YYLEX_OPTION], [
++ AC_MSG_CHECKING([for lex %option])
++ if cat <<EOF | $LEX -t 2>&1 | grep yy_delete_buffer >/dev/null 2>&1; then
++%option nounput
++%%
++EOF
++ AC_MSG_RESULT(yes)
++ else AC_MSG_RESULT(no);
++ LEX=":"
++ fi
++])
++
+ AC_PROG_LEX
++if test "$LEX" != "" -a "$LEX" != ":"; then
+ ACX_YYLEX_DESTROY
++fi
++if test "$LEX" != "" -a "$LEX" != ":"; then
++ACX_YYLEX_OPTION
++fi
+ AC_PROG_YACC
+ AC_CHECK_PROG(doxygen, doxygen, doxygen)
+ AC_CHECK_TOOL(STRIP, strip)
+ ACX_LIBTOOL_C_ONLY
+
++PKG_PROG_PKG_CONFIG
++
+ # Checks for header files.
+-AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h],,, [AC_INCLUDES_DEFAULT])
++AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/endian.h libkern/OSByteOrder.h sys/ipc.h sys/shm.h],,, [AC_INCLUDES_DEFAULT])
+
+ # check for types.
+ # Using own tests for int64* because autoconf builtin only give 32bit.
+@@ -339,6 +434,7 @@
+ # endif
+ #endif
+ ])
++AC_CHECK_SIZEOF(size_t)
+
+ # add option to disable the evil rpath
+ ACX_ARG_RPATH
+@@ -383,6 +479,17 @@
+ ACX_MKDIR_ONE_ARG
+ AC_CHECK_FUNCS([strptime],[AC_CHECK_STRPTIME_WORKS],[AC_LIBOBJ([strptime])])
+
++# check if we can use SO_REUSEPORT
++if echo "$host" | $GREP -i -e linux -e dragonfly >/dev/null; then
++ AC_DEFINE(REUSEPORT_DEFAULT, 1, [if REUSEPORT is enabled by default])
++else
++ AC_DEFINE(REUSEPORT_DEFAULT, 0, [if REUSEPORT is enabled by default])
++fi
++
++# Include systemd.m4 - begin
++sinclude(systemd.m4)
++# Include systemd.m4 - end
++
+ # set memory allocation checking if requested
+ AC_ARG_ENABLE(alloc-checks, AC_HELP_STRING([--enable-alloc-checks],
+ [ enable to memory allocation statistics, for debug purposes ]),
+@@ -398,6 +505,10 @@
+ fi
+ if test x_$enable_alloc_checks = x_yes; then
+ AC_DEFINE(UNBOUND_ALLOC_STATS, 1, [use statistics for allocs and frees, for debug use])
++ SLDNS_ALLOCCHECK_EXTRA_OBJ="alloc.lo log.lo"
++ AC_SUBST(SLDNS_ALLOCCHECK_EXTRA_OBJ)
++ ASYNCLOOK_ALLOCCHECK_EXTRA_OBJ="alloc.lo"
++ AC_SUBST(ASYNCLOOK_ALLOCCHECK_EXTRA_OBJ)
+ else
+ if test x_$enable_alloc_lite = x_yes; then
+ AC_DEFINE(UNBOUND_ALLOC_LITE, 1, [use to enable lightweight alloc assertions, for debug use])
+@@ -438,7 +549,9 @@
+ if test x_$withval != x_no; then
+ AX_PTHREAD([
+ AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.])
+- LIBS="$PTHREAD_LIBS $LIBS"
++ if test -n "$PTHREAD_LIBS"; then
++ LIBS="$PTHREAD_LIBS $LIBS"
++ fi
+ CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+ CC="$PTHREAD_CC"
+ ub_have_pthreads=yes
+@@ -499,6 +612,18 @@
+
+ fi # end of non-mingw check of thread libraries
+
++# Check for SYSLOG_FACILITY
++AC_ARG_WITH(syslog-facility, AC_HELP_STRING([--with-syslog-facility=LOCAL0 - LOCAL7], [ set SYSLOG_FACILITY, default DAEMON ]),
++ [ UNBOUND_SYSLOG_FACILITY="$withval" ], [])
++case "${UNBOUND_SYSLOG_FACILITY}" in
++
++ LOCAL[[0-7]]) UNBOUND_SYSLOG_FACILITY="LOG_${UNBOUND_SYSLOG_FACILITY}" ;;
++
++ *) UNBOUND_SYSLOG_FACILITY="LOG_DAEMON" ;;
++
++esac
++AC_DEFINE_UNQUOTED(UB_SYSLOG_FACILITY,${UNBOUND_SYSLOG_FACILITY},[the SYSLOG_FACILITY to use, default LOG_DAEMON])
++
+ # Check for PyUnbound
+ AC_ARG_WITH(pyunbound,
+ AC_HELP_STRING([--with-pyunbound],
+@@ -540,13 +665,30 @@
+ AC_SUBST(PY_MAJOR_VERSION)
+ # Have Python
+ AC_DEFINE(HAVE_PYTHON,1,[Define if you have Python libraries and header files.])
+- LIBS="$PYTHON_LDFLAGS $LIBS"
+- CPPFLAGS="$CPPFLAGS $PYTHON_CPPFLAGS"
++ if test -n "$LIBS"; then
++ LIBS="$PYTHON_LDFLAGS $LIBS"
++ else
++ LIBS="$PYTHON_LDFLAGS"
++ fi
++ if test -n "$CPPFLAGS"; then
++ CPPFLAGS="$CPPFLAGS $PYTHON_CPPFLAGS"
++ else
++ CPPFLAGS="$PYTHON_CPPFLAGS"
++ fi
+ ub_have_python=yes
++ PKG_CHECK_EXISTS(["python${PY_MAJOR_VERSION}"],
++ [PC_PY_DEPENDENCY="python${PY_MAJOR_VERSION}"],
++ [PC_PY_DEPENDENCY="python"])
++ AC_SUBST(PC_PY_DEPENDENCY)
+
+ # Check for SWIG
+ ub_have_swig=no
+- AC_PROG_SWIG
++ AC_ARG_ENABLE(swig-version-check, AC_HELP_STRING([--disable-swig-version-check], [Disable swig version check to build python modules with older swig even though that is unreliable]))
++ if test "$enable_swig_version_check" = "yes"; then
++ AC_PROG_SWIG(2.0.1)
++ else
++ AC_PROG_SWIG
++ fi
+ AC_MSG_CHECKING(SWIG)
+ if test ! -x "$SWIG"; then
+ AC_ERROR([failed to find swig tool, install it, or do not build Python module and PyUnbound])
+@@ -620,6 +762,8 @@
+ fi
+ LIBS="$LIBS -lnss3 -lnspr4"
+ SSLLIB=""
++ PC_CRYPTO_DEPENDENCY="nss nspr"
++ AC_SUBST(PC_CRYPTO_DEPENDENCY)
+ ]
+ )
+
+@@ -640,6 +784,8 @@
+ fi
+ LIBS="$LIBS -lhogweed -lnettle -lgmp"
+ SSLLIB=""
++ PC_CRYPTO_DEPENDENCY="hogweed nettle"
++ AC_SUBST(PC_CRYPTO_DEPENDENCY)
+ ]
+ )
+
+@@ -649,6 +795,9 @@
+ ACX_LIB_SSL
+ SSLLIB="-lssl"
+
++PC_CRYPTO_DEPENDENCY="libcrypto libssl"
++AC_SUBST(PC_CRYPTO_DEPENDENCY)
++
+ # check if -lcrypt32 is needed because CAPIENG needs that. (on windows)
+ BAKLIBS="$LIBS"
+ LIBS="-lssl $LIBS"
+@@ -668,17 +817,17 @@
+ AC_DEFINE([HAVE_LIBRESSL], [1], [Define if we have LibreSSL])
+ # libressl provides these compat functions, but they may also be
+ # declared by the OS in libc. See if they have been declared.
+- AC_CHECK_DECLS([strlcpy,strlcat,arc4random,arc4random_uniform,reallocarray])
++ AC_CHECK_DECLS([strlcpy,strlcat,arc4random,arc4random_uniform])
+ else
+ AC_MSG_RESULT([no])
+ fi
+ AC_CHECK_HEADERS([openssl/conf.h openssl/engine.h openssl/bn.h openssl/dh.h openssl/dsa.h openssl/rsa.h],,, [AC_INCLUDES_DEFAULT])
+-AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup])
++AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify SSL_CTX_set_tlsext_ticket_key_cb EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex CRYPTO_THREADID_set_callback])
+
+ # these check_funcs need -lssl
+ BAKLIBS="$LIBS"
+ LIBS="-lssl $LIBS"
+-AC_CHECK_FUNCS([OPENSSL_init_ssl])
++AC_CHECK_FUNCS([OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername X509_VERIFY_PARAM_set1_host SSL_CTX_set_ciphersuites])
+ LIBS="$BAKLIBS"
+
+ AC_CHECK_DECLS([SSL_COMP_get_compression_methods,sk_SSL_COMP_pop_free,SSL_CTX_set_ecdh_auto], [], [], [
+@@ -701,10 +850,69 @@
+ #include <openssl/ssl.h>
+ #include <openssl/evp.h>
+ ])
++
++if test "$ac_cv_func_HMAC_Init_ex" = "yes"; then
++# check function return type.
++AC_MSG_CHECKING(the return type of HMAC_Init_ex)
++AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
++#ifdef HAVE_OPENSSL_ERR_H
++#include <openssl/err.h>
++#endif
++
++#ifdef HAVE_OPENSSL_RAND_H
++#include <openssl/rand.h>
++#endif
++
++#ifdef HAVE_OPENSSL_CONF_H
++#include <openssl/conf.h>
++#endif
++
++#ifdef HAVE_OPENSSL_ENGINE_H
++#include <openssl/engine.h>
++#endif
++#include <openssl/ssl.h>
++#include <openssl/evp.h>
++], [
++ HMAC_CTX* hmac_ctx = NULL;
++ void* hmac_key = NULL;
++ const EVP_MD* digest = NULL;
++ int x = HMAC_Init_ex(hmac_ctx, hmac_key, 32, digest, NULL);
++ (void)x;
++])], [
++ AC_MSG_RESULT(int)
++], [
++ AC_MSG_RESULT(void)
++ AC_DEFINE([HMAC_INIT_EX_RETURNS_VOID], 1, [If HMAC_Init_ex() returns void])
++])
+ fi
++
++fi
+ AC_SUBST(SSLLIB)
+
++# libbsd
++AC_ARG_WITH([libbsd], AC_HELP_STRING([--with-libbsd], [Use portable libbsd functions]), [
++ AC_CHECK_HEADERS([bsd/string.h bsd/stdlib.h],,, [AC_INCLUDES_DEFAULT])
++ if test "x$ac_cv_header_bsd_string_h" = xyes -a "x$ac_cv_header_bsd_stdlib_h" = xyes; then
++ for func in strlcpy strlcat arc4random arc4random_uniform reallocarray; do
++ AC_SEARCH_LIBS([$func], [bsd], [
++ AC_DEFINE(HAVE_LIBBSD, 1, [Use portable libbsd functions])
++ PC_LIBBSD_DEPENDENCY=libbsd
++ AC_SUBST(PC_LIBBSD_DEPENDENCY)
++ ])
++ done
++ fi
++])
+
++AC_ARG_ENABLE(sha1, AC_HELP_STRING([--disable-sha1], [Disable SHA1 RRSIG support, does not disable nsec3 support]))
++case "$enable_sha1" in
++ no)
++ ;;
++ yes|*)
++ AC_DEFINE([USE_SHA1], [1], [Define this to enable SHA1 support.])
++ ;;
++esac
++
++
+ AC_ARG_ENABLE(sha2, AC_HELP_STRING([--disable-sha2], [Disable SHA256 and SHA512 RRSIG support]))
+ case "$enable_sha2" in
+ no)
+@@ -714,6 +922,19 @@
+ ;;
+ esac
+
++AC_ARG_ENABLE(subnet, AC_HELP_STRING([--enable-subnet], [Enable client subnet]))
++case "$enable_subnet" in
++ yes)
++ AC_DEFINE([CLIENT_SUBNET], [1], [Define this to enable client subnet option.])
++ SUBNET_OBJ="edns-subnet.lo subnetmod.lo addrtree.lo subnet-whitelist.lo"
++ AC_SUBST(SUBNET_OBJ)
++ SUBNET_HEADER='$(srcdir)/edns-subnet/subnetmod.h $(srcdir)/edns-subnet/edns-subnet.h $(srcdir)/edns-subnet/subnet-whitelist.h $(srcdir)/edns-subnet/addrtree.h'
++ AC_SUBST(SUBNET_HEADER)
++ ;;
++ no|*)
++ ;;
++esac
++
+ # check wether gost also works
+ AC_DEFUN([AC_CHECK_GOST_WORKS],
+ [AC_REQUIRE([AC_PROG_CC])
+@@ -864,19 +1085,87 @@
+
+ AC_ARG_ENABLE(dsa, AC_HELP_STRING([--disable-dsa], [Disable DSA support]))
+ use_dsa="no"
+-case "$enable_ecdsa" in
+- no)
+- ;;
+- *)
++case "$enable_dsa" in
++ yes)
+ # detect if DSA is supported, and turn it off if not.
+- AC_CHECK_FUNC(EVP_dss1, [
++ if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
++ AC_CHECK_FUNC(DSA_SIG_new, [
++ AC_CHECK_TYPE(DSA_SIG*, [
+ AC_DEFINE_UNQUOTED([USE_DSA], [1], [Define this to enable DSA support.])
+ ], [if test "x$enable_dsa" = "xyes"; then AC_MSG_ERROR([OpenSSL does not support DSA and you used --enable-dsa.])
++ fi ], [
++AC_INCLUDES_DEFAULT
++#ifdef HAVE_OPENSSL_ERR_H
++#include <openssl/err.h>
++#endif
++
++#ifdef HAVE_OPENSSL_RAND_H
++#include <openssl/rand.h>
++#endif
++
++#ifdef HAVE_OPENSSL_CONF_H
++#include <openssl/conf.h>
++#endif
++
++#ifdef HAVE_OPENSSL_ENGINE_H
++#include <openssl/engine.h>
++#endif
++ ])
++ ], [if test "x$enable_dsa" = "xyes"; then AC_MSG_ERROR([OpenSSL does not support DSA and you used --enable-dsa.])
+ fi ])
++ else
++ AC_DEFINE_UNQUOTED([USE_DSA], [1], [Define this to enable DSA support.])
++ fi
+ ;;
++ *)
++ # disable dsa by default, RFC 8624 section 3.1, validators MUST NOT
++ # support DSA for DNSSEC Validation.
++ ;;
+ esac
+
++AC_ARG_ENABLE(ed25519, AC_HELP_STRING([--disable-ed25519], [Disable ED25519 support]))
++use_ed25519="no"
++case "$enable_ed25519" in
++ no)
++ ;;
++ *)
++ if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
++ AC_CHECK_DECLS([NID_ED25519], [
++ use_ed25519="yes"
++ ], [ if test "x$enable_ed25519" = "xyes"; then AC_MSG_ERROR([OpenSSL does not support ED25519 and you used --enable-ed25519.])
++ fi ], [AC_INCLUDES_DEFAULT
++#include <openssl/evp.h>
++ ])
++ fi
++ if test $USE_NETTLE = "yes"; then
++ AC_CHECK_HEADERS([nettle/eddsa.h], use_ed25519="yes",, [AC_INCLUDES_DEFAULT])
++ fi
++ if test $use_ed25519 = "yes"; then
++ AC_DEFINE_UNQUOTED([USE_ED25519], [1], [Define this to enable ED25519 support.])
++ fi
++ ;;
++esac
+
++AC_ARG_ENABLE(ed448, AC_HELP_STRING([--disable-ed448], [Disable ED448 support]))
++use_ed448="no"
++case "$enable_ed448" in
++ no)
++ ;;
++ *)
++ if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
++ AC_CHECK_DECLS([NID_ED448], [
++ use_ed448="yes"
++ ], [ if test "x$enable_ed448" = "xyes"; then AC_MSG_ERROR([OpenSSL does not support ED448 and you used --enable-ed448.])
++ fi ], [AC_INCLUDES_DEFAULT
++#include <openssl/evp.h>
++ ])
++ fi
++ if test $use_ed448 = "yes"; then
++ AC_DEFINE_UNQUOTED([USE_ED448], [1], [Define this to enable ED448 support.])
++ fi
++ ;;
++esac
++
+ AC_ARG_ENABLE(event-api, AC_HELP_STRING([--enable-event-api], [Enable (experimental) pluggable event base libunbound API installed to unbound-event.h]))
+ case "$enable_event_api" in
+ yes)
+@@ -1000,6 +1289,16 @@
+ AC_CHECK_FUNCS([event_base_get_method]) # only in libevent 1.4.3 and later
+ AC_CHECK_FUNCS([ev_loop]) # only in libev. (tested on 3.51)
+ AC_CHECK_FUNCS([ev_default_loop]) # only in libev. (tested on 4.00)
++ AC_CHECK_FUNCS([event_assign]) # in libevent, for thread-safety
++ AC_CHECK_DECLS([evsignal_assign], [], [], [AC_INCLUDES_DEFAULT
++#ifdef HAVE_EVENT_H
++# include <event.h>
++#else
++# include "event2/event.h"
++#endif
++ ])
++ PC_LIBEVENT_DEPENDENCY="libevent"
++ AC_SUBST(PC_LIBEVENT_DEPENDENCY)
+ if test -n "$BAK_LDFLAGS_SET"; then
+ LDFLAGS="$BAK_LDFLAGS"
+ fi
+@@ -1033,11 +1332,44 @@
+ #include <expat.h>
+ ])
+
+-# set static linking if requested
++# hiredis (redis C client for cachedb)
++AC_ARG_WITH(libhiredis, AC_HELP_STRING([--with-libhiredis=path],
++ [specify explicit path for libhiredis.]),
++ [ ],[ withval="no" ])
++found_libhiredis="no"
++if test x_$withval = x_yes -o x_$withval != x_no; then
++ AC_MSG_CHECKING(for libhiredis)
++ if test x_$withval = x_ -o x_$withval = x_yes; then
++ withval="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr"
++ fi
++ for dir in $withval ; do
++ if test -f "$dir/include/hiredis/hiredis.h"; then
++ found_libhiredis="yes"
++ dnl assume /usr is in default path.
++ if test "$dir" != "/usr"; then
++ CPPFLAGS="$CPPFLAGS -I$dir/include"
++ LDFLAGS="$LDFLAGS -L$dir/lib"
++ fi
++ AC_MSG_RESULT(found in $dir)
++ AC_DEFINE([USE_REDIS], [1], [Define this to use hiredis client.])
++ LIBS="$LIBS -lhiredis"
++ break;
++ fi
++ done
++ if test x_$found_libhiredis != x_yes; then
++ AC_ERROR([Could not find libhiredis, hiredis.h])
++ fi
++ AC_CHECK_HEADERS([hiredis/hiredis.h],,, [AC_INCLUDES_DEFAULT])
++ AC_CHECK_DECLS([redisConnect], [], [], [AC_INCLUDES_DEFAULT
++ #include <hiredis/hiredis.h>
++ ])
++fi
++
++# set static linking for uninstalled libraries if requested
+ AC_SUBST(staticexe)
+ staticexe=""
+ AC_ARG_ENABLE(static-exe, AC_HELP_STRING([--enable-static-exe],
+- [ enable to compile executables statically against (event) libs, for debug purposes ]),
++ [ enable to compile executables statically against (event) uninstalled libs, for debug purposes ]),
+ , )
+ if test x_$enable_static_exe = x_yes; then
+ staticexe="-static"
+@@ -1044,10 +1376,32 @@
+ if test "$on_mingw" = yes; then
+ staticexe="-all-static"
+ # for static compile, include gdi32 and zlib here.
+- LIBS="$LIBS -lgdi32 -lz"
++ if echo $LIBS | grep 'lgdi32' >/dev/null; then
++ :
++ else
++ LIBS="$LIBS -lgdi32"
++ fi
++ LIBS="$LIBS -lz"
+ fi
+ fi
+
++# set full static linking if requested
++AC_ARG_ENABLE(fully-static, AC_HELP_STRING([--enable-fully-static],
++ [ enable to compile fully static ]),
++ , )
++if test x_$enable_fully_static = x_yes; then
++ staticexe="-all-static"
++ if test "$on_mingw" = yes; then
++ # for static compile, include gdi32 and zlib here.
++ if echo $LIBS | grep 'lgdi32' >/dev/null; then
++ :
++ else
++ LIBS="$LIBS -lgdi32"
++ fi
++ LIBS="$LIBS -lz"
++ fi
++fi
++
+ # set lock checking if requested
+ AC_ARG_ENABLE(lock_checks, AC_HELP_STRING([--enable-lock-checks],
+ [ enable to check lock and unlock calls, for debug purposes ]),
+@@ -1065,7 +1419,7 @@
+ #include <windows.h>
+ ])
+ AC_CHECK_TOOL(WINDRES, windres)
+- LIBS="$LIBS -liphlpapi"
++ LIBS="$LIBS -liphlpapi -lcrypt32"
+ WINAPPS="unbound-service-install.exe unbound-service-remove.exe anchor-update.exe"
+ AC_SUBST(WINAPPS)
+ WIN_DAEMON_SRC="winrc/win_svc.c winrc/w_inst.c"
+@@ -1137,28 +1491,66 @@
+ #include <ws2tcpip.h>
+ #endif
+ ])
++
++AC_MSG_CHECKING([for htobe64])
++AC_LINK_IFELSE([AC_LANG_PROGRAM([
++#include <stdio.h>
++#ifdef HAVE_ENDIAN_H
++# include <endian.h>
++#endif
++#ifdef HAVE_SYS_ENDIAN_H
++# include <sys/endian.h>
++#endif
++], [unsigned long long x = htobe64(0); printf("%u", (unsigned)x);])],
++ AC_MSG_RESULT(yes)
++ AC_DEFINE(HAVE_HTOBE64, 1, [If we have htobe64]),
++ AC_MSG_RESULT(no))
++
++AC_MSG_CHECKING([for be64toh])
++AC_LINK_IFELSE([AC_LANG_PROGRAM([
++#include <stdio.h>
++#ifdef HAVE_ENDIAN_H
++# include <endian.h>
++#endif
++#ifdef HAVE_SYS_ENDIAN_H
++# include <sys/endian.h>
++#endif
++], [unsigned long long x = be64toh(0); printf("%u", (unsigned)x);])],
++ AC_MSG_RESULT(yes)
++ AC_DEFINE(HAVE_BE64TOH, 1, [If we have be64toh]),
++ AC_MSG_RESULT(no))
++
+ AC_SEARCH_LIBS([setusercontext], [util])
+-AC_CHECK_FUNCS([tzset sigprocmask fcntl getpwnam endpwent getrlimit setrlimit setsid chroot kill chown sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent fsync])
++AC_CHECK_FUNCS([tzset sigprocmask fcntl getpwnam endpwent getrlimit setrlimit setsid chroot kill chown sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent fsync shmget accept4])
+ AC_CHECK_FUNCS([setresuid],,[AC_CHECK_FUNCS([setreuid])])
+ AC_CHECK_FUNCS([setresgid],,[AC_CHECK_FUNCS([setregid])])
+
+-AC_MSG_CHECKING([for sbrk])
+-# catch the warning of deprecated sbrk
+-old_cflags="$CFLAGS"
+-CFLAGS="$CFLAGS -Werror"
+-AC_COMPILE_IFELSE([AC_LANG_SOURCE(AC_INCLUDES_DEFAULT
+-[[
+-int main(void) { void* cur = sbrk(0); printf("%u\n", (unsigned)(size_t)((char*)cur - (char*)sbrk(0))); return 0; }
+-]])], [
+- AC_MSG_RESULT(yes)
+- AC_DEFINE(HAVE_SBRK, 1, [define if you have the sbrk() call])
+- ], [AC_MSG_RESULT(no)])
+-CFLAGS="$old_cflags"
+-
+ # check if setreuid en setregid fail, on MacOSX10.4(darwin8).
+-if echo $build_os | grep darwin8 > /dev/null; then
++if echo $target_os | grep darwin8 > /dev/null; then
+ AC_DEFINE(DARWIN_BROKEN_SETREUID, 1, [Define this if on macOSX10.4-darwin8 and setreuid and setregid do not work])
+ fi
++AC_CHECK_DECLS([inet_pton,inet_ntop], [], [], [
++AC_INCLUDES_DEFAULT
++#ifdef HAVE_NETINET_IN_H
++#include <netinet/in.h>
++#endif
++
++#ifdef HAVE_NETINET_TCP_H
++#include <netinet/tcp.h>
++#endif
++
++#ifdef HAVE_ARPA_INET_H
++#include <arpa/inet.h>
++#endif
++
++#ifdef HAVE_WINSOCK2_H
++#include <winsock2.h>
++#endif
++
++#ifdef HAVE_WS2TCPIP_H
++#include <ws2tcpip.h>
++#endif
++])
+ AC_REPLACE_FUNCS(inet_aton)
+ AC_REPLACE_FUNCS(inet_pton)
+ AC_REPLACE_FUNCS(inet_ntop)
+@@ -1182,25 +1574,43 @@
+ AC_REPLACE_FUNCS(memmove)
+ AC_REPLACE_FUNCS(gmtime_r)
+ AC_REPLACE_FUNCS(isblank)
++AC_REPLACE_FUNCS(explicit_bzero)
+ dnl without CTIME, ARC4-functions and without reallocarray.
+ LIBOBJ_WITHOUT_CTIMEARC4="$LIBOBJS"
+ AC_SUBST(LIBOBJ_WITHOUT_CTIMEARC4)
+-AC_REPLACE_FUNCS(reallocarray)
++AC_MSG_CHECKING([for reallocarray])
++AC_LINK_IFELSE([AC_LANG_SOURCE(AC_INCLUDES_DEFAULT
++[[
++#ifndef _OPENBSD_SOURCE
++#define _OPENBSD_SOURCE 1
++#endif
++#include <stdlib.h>
++int main(void) {
++ void* p = reallocarray(NULL, 10, 100);
++ free(p);
++ return 0;
++}
++]])], [AC_MSG_RESULT(yes)
++ AC_DEFINE(HAVE_REALLOCARRAY, 1, [If we have reallocarray(3)])
++], [
++ AC_MSG_RESULT(no)
++ AC_LIBOBJ(reallocarray)
++])
++AC_CHECK_DECLS([reallocarray])
+ if test "$USE_NSS" = "no"; then
+ AC_REPLACE_FUNCS(arc4random)
+ AC_REPLACE_FUNCS(arc4random_uniform)
+ if test "$ac_cv_func_arc4random" = "no"; then
+- AC_LIBOBJ(explicit_bzero)
+ AC_LIBOBJ(arc4_lock)
+ AC_CHECK_FUNCS([getentropy],,[
+ if test "$USE_WINSOCK" = 1; then
+ AC_LIBOBJ(getentropy_win)
+ else
+- case `uname` in
+- Darwin)
++ case "$host" in
++ Darwin|*darwin*)
+ AC_LIBOBJ(getentropy_osx)
+ ;;
+- SunOS)
++ *solaris*|*sunos*|SunOS)
+ AC_LIBOBJ(getentropy_solaris)
+ AC_CHECK_HEADERS([sys/sha2.h],, [
+ AC_CHECK_FUNCS([SHA512_Update],,[
+@@ -1213,7 +1623,10 @@
+ fi
+ AC_SEARCH_LIBS([clock_gettime], [rt])
+ ;;
+- Linux|*)
++ *freebsd*|*FreeBSD)
++ AC_LIBOBJ(getentropy_freebsd)
++ ;;
++ *linux*|Linux|*)
+ AC_LIBOBJ(getentropy_linux)
+ AC_CHECK_FUNCS([SHA512_Update],,[
+ AC_DEFINE([COMPAT_SHA512], [1], [Do sha512 definitions in config.h])
+@@ -1284,8 +1697,23 @@
+ ]
+ )
+
++# check for dnscrypt if requested
++dnsc_DNSCRYPT([
++ AC_DEFINE([USE_DNSCRYPT], [1], [Define to 1 to enable dnscrypt support])
++ AC_SUBST([ENABLE_DNSCRYPT], [1])
++
++ AC_SUBST([DNSCRYPT_SRC], ["dnscrypt/dnscrypt.c"])
++ AC_SUBST([DNSCRYPT_OBJ], ["dnscrypt.lo"])
++ ],
++ [
++ AC_SUBST([ENABLE_DNSCRYPT], [0])
++ ]
++)
++
+ # check for cachedb if requested
+ AC_ARG_ENABLE(cachedb, AC_HELP_STRING([--enable-cachedb], [enable cachedb module that can use external cache storage]))
++# turn on cachedb when hiredis support is enabled.
++if test "$found_libhiredis" = "yes"; then enable_cachedb="yes"; fi
+ case "$enable_cachedb" in
+ yes)
+ AC_DEFINE([USE_CACHEDB], [1], [Define to 1 to use cachedb support])
+@@ -1295,6 +1723,62 @@
+ ;;
+ esac
+
++# check for ipsecmod if requested
++AC_ARG_ENABLE(ipsecmod, AC_HELP_STRING([--enable-ipsecmod], [Enable ipsecmod module that facilitates opportunistic IPsec]))
++case "$enable_ipsecmod" in
++ yes)
++ AC_DEFINE([USE_IPSECMOD], [1], [Define to 1 to use ipsecmod support.])
++ IPSECMOD_OBJ="ipsecmod.lo ipsecmod-whitelist.lo"
++ AC_SUBST(IPSECMOD_OBJ)
++ IPSECMOD_HEADER='$(srcdir)/ipsecmod/ipsecmod.h $(srcdir)/ipsecmod/ipsecmod-whitelist.h'
++ AC_SUBST(IPSECMOD_HEADER)
++ ;;
++ no|*)
++ # nothing
++ ;;
++esac
++
++# check for ipset if requested
++AC_ARG_ENABLE(ipset, AC_HELP_STRING([--enable-ipset], [enable ipset module]))
++case "$enable_ipset" in
++ yes)
++ AC_DEFINE([USE_IPSET], [1], [Define to 1 to use ipset support])
++ IPSET_SRC="ipset/ipset.c"
++ AC_SUBST(IPSET_SRC)
++ IPSET_OBJ="ipset.lo"
++ AC_SUBST(IPSET_OBJ)
++
++ # mnl
++ AC_ARG_WITH(libmnl, AC_HELP_STRING([--with-libmnl=path],
++ [specify explicit path for libmnl.]),
++ [ ],[ withval="yes" ])
++ found_libmnl="no"
++ AC_MSG_CHECKING(for libmnl)
++ if test x_$withval = x_ -o x_$withval = x_yes; then
++ withval="/usr/local /opt/local /usr/lib /usr/pkg /usr/sfw /usr"
++ fi
++ for dir in $withval ; do
++ if test -f "$dir/include/libmnl/libmnl.h"; then
++ found_libmnl="yes"
++ dnl assume /usr is in default path.
++ if test "$dir" != "/usr"; then
++ CPPFLAGS="$CPPFLAGS -I$dir/include"
++ LDFLAGS="$LDFLAGS -L$dir/lib"
++ fi
++ AC_MSG_RESULT(found in $dir)
++ LIBS="$LIBS -lmnl"
++ break;
++ fi
++ done
++ if test x_$found_libmnl != x_yes; then
++ AC_ERROR([Could not find libmnl, libmnl.h])
++ fi
++ ;;
++ no|*)
++ # nothing
++ ;;
++esac
++
+ AC_MSG_CHECKING([if ${MAKE:-make} supports $< with implicit rule in scope])
+ # on openBSD, the implicit rule make $< work.
+ # on Solaris, it does not work ($? is changed sources, $^ lists dependencies).
+@@ -1341,11 +1825,25 @@
+ INSTALLTARGET="install-lib"
+ fi
+ ])
++if test $ALLTARGET = "alltargets"; then
++ if test $USE_NSS = "yes"; then
++ AC_ERROR([--with-nss can only be used in combination with --with-libunbound-only.])
++ fi
++ if test $USE_NETTLE = "yes"; then
++ AC_ERROR([--with-nettle can only be used in combination with --with-libunbound-only.])
++ fi
++fi
++
+ AC_SUBST(ALLTARGET)
+ AC_SUBST(INSTALLTARGET)
+
+ ACX_STRIP_EXT_FLAGS
+-LDFLAGS="$LATE_LDFLAGS $LDFLAGS"
++if test -n "$LATE_LDFLAGS"; then
++ LDFLAGS="$LATE_LDFLAGS $LDFLAGS"
++fi
++# remove start spaces
++LDFLAGS=`echo "$LDFLAGS"|sed -e 's/^ *//'`
++LIBS=`echo "$LIBS"|sed -e 's/^ *//'`
+
+ AC_DEFINE_UNQUOTED([MAXSYSLOGMSGLEN], [10240], [Define to the maximum message length to pass to syslog.])
+
+@@ -1355,8 +1853,14 @@
+
+ dnl includes
+ [
++#ifndef _OPENBSD_SOURCE
++#define _OPENBSD_SOURCE 1
++#endif
++
+ #ifndef UNBOUND_DEBUG
++# ifndef NDEBUG
+ # define NDEBUG
++# endif
+ #endif
+
+ /** Use small-ldns codebase */
+@@ -1471,6 +1975,19 @@
+ int isblank(int c);
+ #endif
+
++#ifndef HAVE_EXPLICIT_BZERO
++#define explicit_bzero unbound_explicit_bzero
++void explicit_bzero(void* buf, size_t len);
++#endif
++
++#if defined(HAVE_INET_NTOP) && !HAVE_DECL_INET_NTOP
++const char *inet_ntop(int af, const void *src, char *dst, size_t size);
++#endif
++
++#if defined(HAVE_INET_PTON) && !HAVE_DECL_INET_PTON
++int inet_pton(int af, const char* src, void* dst);
++#endif
++
+ #if !defined(HAVE_STRPTIME) || !defined(STRPTIME_WORKS)
+ #define strptime unbound_strptime
+ struct tm;
+@@ -1477,6 +1994,15 @@
+ char *strptime(const char *s, const char *format, struct tm *tm);
+ #endif
+
++#if !HAVE_DECL_REALLOCARRAY
++void *reallocarray(void *ptr, size_t nmemb, size_t size);
++#endif
++
++#ifdef HAVE_LIBBSD
++#include <bsd/string.h>
++#include <bsd/stdlib.h>
++#endif
++
+ #ifdef HAVE_LIBRESSL
+ # if !HAVE_DECL_STRLCPY
+ size_t strlcpy(char *dst, const char *src, size_t siz);
+@@ -1490,17 +2016,14 @@
+ # if !HAVE_DECL_ARC4RANDOM_UNIFORM && defined(HAVE_ARC4RANDOM_UNIFORM)
+ uint32_t arc4random_uniform(uint32_t upper_bound);
+ # endif
+-# if !HAVE_DECL_REALLOCARRAY
+-void *reallocarray(void *ptr, size_t nmemb, size_t size);
+-# endif
+ #endif /* HAVE_LIBRESSL */
+ #ifndef HAVE_ARC4RANDOM
+-void explicit_bzero(void* buf, size_t len);
+ int getentropy(void* buf, size_t len);
+ uint32_t arc4random(void);
+ void arc4random_buf(void* buf, size_t n);
+ void _ARC4_LOCK(void);
+ void _ARC4_UNLOCK(void);
++void _ARC4_LOCK_DESTROY(void);
+ #endif
+ #ifndef HAVE_ARC4RANDOM_UNIFORM
+ uint32_t arc4random_uniform(uint32_t upper_bound);
+@@ -1566,6 +2089,8 @@
+
+ /** default port for DNS traffic. */
+ #define UNBOUND_DNS_PORT 53
++/** default port for DNS over TLS traffic. */
++#define UNBOUND_DNS_OVER_TLS_PORT 853
+ /** default port for unbound control traffic, registered port with IANA,
+ ub-dns-control 8953/tcp unbound dns nameserver control */
+ #define UNBOUND_CONTROL_PORT 8953
+@@ -1579,6 +2104,6 @@
+ AC_SUBST(version, [VERSION_MAJOR.VERSION_MINOR.VERSION_MICRO])
+ AC_SUBST(date, [`date +'%b %e, %Y'`])
+
+-AC_CONFIG_FILES([Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound.conf.5 doc/unbound-control.8 doc/unbound-host.1 smallapp/unbound-control-setup.sh dnstap/dnstap_config.h contrib/libunbound.pc])
++AC_CONFIG_FILES([Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound.conf.5 doc/unbound-control.8 doc/unbound-host.1 smallapp/unbound-control-setup.sh dnstap/dnstap_config.h dnscrypt/dnscrypt_config.h contrib/libunbound.pc contrib/unbound.socket contrib/unbound.service contrib/unbound_portable.service])
+ AC_CONFIG_HEADER([config.h])
+ AC_OUTPUT
+--- contrib/unbound/contrib/README.orig
++++ contrib/unbound/contrib/README
+@@ -27,5 +27,29 @@
+ works like the BIND feature (removes AAAA records unless AAAA-only domain).
+ Useful for certain 'broken IPv6 default route' scenarios.
+ Patch from Stephane Lapie for ASAHI Net.
+-* unbound_smf22.tar.gz: Solaris SMF installation/removal scripts.
++* unbound_smf23.tar.gz: Solaris SMF installation/removal scripts.
+ Contributed by Yuri Voinov.
++* unbound.socket and unbound.service: systemd files for unbound, install them
++ in /usr/lib/systemd/system. Contributed by Sami Kerola and Pavel Odintsov.
++* unbound_portable.service.in: systemd file for use unbound as portable service,
++ see comments in the file. Contributed by Frzk.
++* redirect-bogus.patch: Return configured address for bogus A and AAAA answers,
++ instead of SERVFAIL. Contributed by SIDN.
++* fastrpz.patch: fastrpz support from Farsight Security.
++* libunbound.so.conf: ltrace.conf file, see ltrace.conf(5), for libunbound.
++* unbound-querycachedb.py: utility to show data stored in cachedb backend
++ for a particular query name and type. It requires dnspython and (for
++ redis backend) redis Python modules.
++* unbound-fuzzme.patch: adds unbound-fuzzme program that parses a packet from
++ stdin. Used with fuzzers, patch from Jacob Hoffman-Andrews.
++* unbound-fuzzers.tar.bz2: three programs for fuzzing, that are 1:1
++ replacements for unbound-fuzzme.c that gets created after applying
++ the contrib/unbound-fuzzme.patch. They are contributed by
++ Eric Sesterhenn from X41 D-Sec.
++* drop-tld.diff: adds option drop-tld: yesno that drops 2 label queries,
++ to stop random floods. Apply with patch -p1 < contrib/drop-tld.diff and
++ compile. From Saksham Manchanda (Secure64). Please note that we think
++ this will drop DNSKEY and DS lookups for tlds and hence break DNSSEC
++ lookups for downstream clients.
++* drop2rpz: perl script that converts the Spamhaus DROP-List in RPZ-Format,
++ contributed by Andreas Schulze.
+--- contrib/unbound/contrib/aaaa-filter-iterator.patch.orig
++++ contrib/unbound/contrib/aaaa-filter-iterator.patch
+@@ -1,10 +1,10 @@
+ Index: trunk/doc/unbound.conf.5.in
+ ===================================================================
+---- trunk/doc/unbound.conf.5.in (revision 3587)
++--- trunk/doc/unbound.conf.5.in (revision 4357)
+ +++ trunk/doc/unbound.conf.5.in (working copy)
+-@@ -593,6 +593,13 @@
+- possible. Best effort approach, full QNAME and original QTYPE will be sent when
+- upstream replies with a RCODE other than NOERROR. Default is off.
++@@ -701,6 +701,13 @@
++ this option in enabled. Only use if you know what you are doing.
++ This option only has effect when qname-minimisation is enabled. Default is off.
+ .TP
+ +.B aaaa\-filter: \fI<yes or no>
+ +Activate behavior similar to BIND's AAAA-filter.
+@@ -18,7 +18,7 @@
+ on your private network, and are not allowed to be returned for
+ Index: trunk/iterator/iter_scrub.c
+ ===================================================================
+---- trunk/iterator/iter_scrub.c (revision 3587)
++--- trunk/iterator/iter_scrub.c (revision 4357)
+ +++ trunk/iterator/iter_scrub.c (working copy)
+ @@ -617,6 +617,32 @@
+ }
+@@ -75,10 +75,11 @@
+ /* At this point, we brutally remove ALL rrsets that aren't
+ * children of the originating zone. The idea here is that,
+ * as far as we know, the server that we contacted is ONLY
+-@@ -681,6 +715,24 @@
++@@ -680,6 +714,24 @@
++ prev = NULL;
+ rrset = msg->rrset_first;
+ while(rrset) {
+-
+++
+ + /* ASN: For AAAA records only... */
+ + if((ie->aaaa_filter) && (rrset->type == LDNS_RR_TYPE_AAAA)) {
+ + /* ASN: If this is not a AAAA query, then remove AAAA
+@@ -96,13 +97,12 @@
+ + LDNS_RR_TYPE_AAAA, qinfo->qclass);
+ + }
+ + /* ASN: End of added code */
+-+
++
+ /* remove private addresses */
+ if( (rrset->type == LDNS_RR_TYPE_A ||
+- rrset->type == LDNS_RR_TYPE_AAAA)) {
+ Index: trunk/iterator/iter_utils.c
+ ===================================================================
+---- trunk/iterator/iter_utils.c (revision 3587)
++--- trunk/iterator/iter_utils.c (revision 4357)
+ +++ trunk/iterator/iter_utils.c (working copy)
+ @@ -175,6 +175,7 @@
+ }
+@@ -114,9 +114,9 @@
+
+ Index: trunk/iterator/iterator.c
+ ===================================================================
+---- trunk/iterator/iterator.c (revision 3587)
++--- trunk/iterator/iterator.c (revision 4357)
+ +++ trunk/iterator/iterator.c (working copy)
+-@@ -1776,6 +1776,53 @@
++@@ -1847,6 +1847,53 @@
+
+ return 0;
+ }
+@@ -170,7 +170,7 @@
+
+ /**
+ * This is the request event state where the request will be sent to one of
+-@@ -1823,6 +1870,13 @@
++@@ -1894,6 +1941,13 @@
+ return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
+ }
+
+@@ -184,7 +184,7 @@
+ /* Make sure we have a delegation point, otherwise priming failed
+ * or another failure occurred */
+ if(!iq->dp) {
+-@@ -2922,6 +2976,61 @@
++@@ -3095,6 +3149,61 @@
+ return 0;
+ }
+
+@@ -244,9 +244,9 @@
+ +/* ASN: End of added code */
+ +
+ /*
+- * Return priming query results to interestes super querystates.
++ * Return priming query results to interested super querystates.
+ *
+-@@ -2941,6 +3050,9 @@
++@@ -3114,6 +3223,9 @@
+ else if(super->qinfo.qtype == LDNS_RR_TYPE_DS && ((struct iter_qstate*)
+ super->minfo[id])->state == DSNS_FIND_STATE)
+ processDSNSResponse(qstate, id, super);
+@@ -256,7 +256,7 @@
+ else if(qstate->return_rcode != LDNS_RCODE_NOERROR)
+ error_supers(qstate, id, super);
+ else if(qstate->is_priming)
+-@@ -2978,6 +3090,9 @@
++@@ -3151,6 +3263,9 @@
+ case INIT_REQUEST_3_STATE:
+ cont = processInitRequest3(qstate, iq, id);
+ break;
+@@ -266,7 +266,7 @@
+ case QUERYTARGETS_STATE:
+ cont = processQueryTargets(qstate, iq, ie, id);
+ break;
+-@@ -3270,6 +3385,8 @@
++@@ -3460,6 +3575,8 @@
+ return "INIT REQUEST STATE (stage 2)";
+ case INIT_REQUEST_3_STATE:
+ return "INIT REQUEST STATE (stage 3)";
+@@ -275,7 +275,7 @@
+ case QUERYTARGETS_STATE :
+ return "QUERY TARGETS STATE";
+ case PRIME_RESP_STATE :
+-@@ -3294,6 +3411,7 @@
++@@ -3484,6 +3601,7 @@
+ case INIT_REQUEST_STATE :
+ case INIT_REQUEST_2_STATE :
+ case INIT_REQUEST_3_STATE :
+@@ -285,9 +285,9 @@
+ return 0;
+ Index: trunk/iterator/iterator.h
+ ===================================================================
+---- trunk/iterator/iterator.h (revision 3587)
++--- trunk/iterator/iterator.h (revision 4357)
+ +++ trunk/iterator/iterator.h (working copy)
+-@@ -113,6 +113,9 @@
++@@ -130,6 +130,9 @@
+ */
+ int* target_fetch_policy;
+
+@@ -294,10 +294,10 @@
+ + /** ASN: AAAA-filter flag */
+ + int aaaa_filter;
+ +
+- /** ip6.arpa dname in wireformat, used for qname-minimisation */
+- uint8_t* ip6arpa_dname;
+- };
+-@@ -163,6 +166,14 @@
++ /** lock on ratelimit counter */
++ lock_basic_type queries_ratelimit_lock;
++ /** number of queries that have been ratelimited */
++@@ -182,6 +185,14 @@
+ INIT_REQUEST_3_STATE,
+
+ /**
+@@ -311,11 +311,12 @@
+ + /**
+ * Each time a delegation point changes for a given query or a
+ * query times out and/or wakes up, this state is (re)visited.
+- * This state is reponsible for iterating through a list of
+-@@ -346,6 +357,13 @@
++ * This state is responsible for iterating through a list of
++@@ -364,6 +375,13 @@
++ * be used when creating the state. A higher one will be attempted.
+ */
+ int refetch_glue;
+-
+++
+ + /**
+ + * ASN: This is a flag that, if true, means that this query is
+ + * for fetching A records to populate cache and determine if we must
+@@ -322,15 +323,14 @@
+ + * return AAAA records or not.
+ + */
+ + int fetch_a_for_aaaa;
+-+
++
+ /** list of pending queries to authoritative servers. */
+ struct outbound_list outlist;
+-
+ Index: trunk/pythonmod/interface.i
+ ===================================================================
+---- trunk/pythonmod/interface.i (revision 3587)
++--- trunk/pythonmod/interface.i (revision 4357)
+ +++ trunk/pythonmod/interface.i (working copy)
+-@@ -632,6 +632,7 @@
++@@ -851,6 +851,7 @@
+ int harden_dnssec_stripped;
+ int harden_referral_path;
+ int use_caps_bits_for_id;
+@@ -340,9 +340,9 @@
+ size_t unwanted_threshold;
+ Index: trunk/util/config_file.c
+ ===================================================================
+---- trunk/util/config_file.c (revision 3587)
++--- trunk/util/config_file.c (revision 4357)
+ +++ trunk/util/config_file.c (working copy)
+-@@ -176,6 +176,7 @@
++@@ -195,6 +195,7 @@
+ cfg->harden_referral_path = 0;
+ cfg->harden_algo_downgrade = 0;
+ cfg->use_caps_bits_for_id = 0;
+@@ -352,9 +352,9 @@
+ cfg->private_domain = NULL;
+ Index: trunk/util/config_file.h
+ ===================================================================
+---- trunk/util/config_file.h (revision 3587)
++--- trunk/util/config_file.h (revision 4357)
+ +++ trunk/util/config_file.h (working copy)
+-@@ -179,6 +179,8 @@
++@@ -209,6 +209,8 @@
+ int harden_algo_downgrade;
+ /** use 0x20 bits in query as random ID bits */
+ int use_caps_bits_for_id;
+@@ -365,9 +365,9 @@
+ /** strip away these private addrs from answers, no DNS Rebinding */
+ Index: trunk/util/configlexer.lex
+ ===================================================================
+---- trunk/util/configlexer.lex (revision 3587)
++--- trunk/util/configlexer.lex (revision 4357)
+ +++ trunk/util/configlexer.lex (working copy)
+-@@ -267,6 +267,7 @@
++@@ -279,6 +279,7 @@
+ use-caps-for-id{COLON} { YDVAR(1, VAR_USE_CAPS_FOR_ID) }
+ caps-whitelist{COLON} { YDVAR(1, VAR_CAPS_WHITELIST) }
+ unwanted-reply-threshold{COLON} { YDVAR(1, VAR_UNWANTED_REPLY_THRESHOLD) }
+@@ -377,9 +377,9 @@
+ prefetch-key{COLON} { YDVAR(1, VAR_PREFETCH_KEY) }
+ Index: trunk/util/configparser.y
+ ===================================================================
+---- trunk/util/configparser.y (revision 3587)
++--- trunk/util/configparser.y (revision 4357)
+ +++ trunk/util/configparser.y (working copy)
+-@@ -92,6 +92,7 @@
++@@ -95,6 +95,7 @@
+ %token VAR_STATISTICS_CUMULATIVE VAR_OUTGOING_PORT_PERMIT
+ %token VAR_OUTGOING_PORT_AVOID VAR_DLV_ANCHOR_FILE VAR_DLV_ANCHOR
+ %token VAR_NEG_CACHE_SIZE VAR_HARDEN_REFERRAL_PATH VAR_PRIVATE_ADDRESS
+@@ -387,7 +387,7 @@
+ %token VAR_PRIVATE_DOMAIN VAR_REMOTE_CONTROL VAR_CONTROL_ENABLE
+ %token VAR_CONTROL_INTERFACE VAR_CONTROL_PORT VAR_SERVER_KEY_FILE
+ %token VAR_SERVER_CERT_FILE VAR_CONTROL_KEY_FILE VAR_CONTROL_CERT_FILE
+-@@ -169,6 +170,7 @@
++@@ -203,6 +204,7 @@
+ server_dlv_anchor_file | server_dlv_anchor | server_neg_cache_size |
+ server_harden_referral_path | server_private_address |
+ server_private_domain | server_extended_statistics |
+@@ -395,10 +395,12 @@
+ server_local_data_ptr | server_jostle_timeout |
+ server_unwanted_reply_threshold | server_log_time_ascii |
+ server_domain_insecure | server_val_sig_skew_min |
+-@@ -893,6 +895,15 @@
++@@ -1183,6 +1185,15 @@
++ OUTYY(("P(server_caps_whitelist:%s)\n", $2));
++ if(!cfg_strlist_insert(&cfg_parser->cfg->caps_whitelist, $2))
+ yyerror("out of memory");
+- }
+- ;
+++ }
+++ ;
+ +server_aaaa_filter: VAR_AAAA_FILTER STRING_ARG
+ + {
+ + OUTYY(("P(server_aaaa_filter:%s)\n", $2));
+@@ -406,8 +408,6 @@
+ + yyerror("expected yes or no.");
+ + else cfg_parser->cfg->aaaa_filter = (strcmp($2, "yes")==0);
+ + free($2);
+-+ }
+-+ ;
++ }
++ ;
+ server_private_address: VAR_PRIVATE_ADDRESS STRING_ARG
+- {
+- OUTYY(("P(server_private_address:%s)\n", $2));
+--- contrib/unbound/contrib/create_unbound_ad_servers.sh.orig
++++ contrib/unbound/contrib/create_unbound_ad_servers.sh
+@@ -9,12 +9,13 @@
+ # Variables
+ dst_dir="/etc/opt/csw/unbound"
+ work_dir="/tmp"
+-list_addr="http://pgl.yoyo.org/adservers/serverlist.php?hostformat=nohtml&showintro=1&startdate%5Bday%5D=&startdate%5Bmonth%5D=&startdate%5Byear%5D="
++list_addr="https://pgl.yoyo.org/adservers/serverlist.php?hostformat=nohtml&showintro=1&startdate%5Bday%5D=&startdate%5Bmonth%5D=&startdate%5Byear%5D="
+
+ # OS commands
+ CAT=`which cat`
+ ECHO=`which echo`
+ WGET=`which wget`
++TR=`which tr`
+
+ # Check Wget installed
+ if [ ! -f $WGET ]; then
+@@ -22,8 +23,10 @@
+ exit 1
+ fi
+
++# remove special characters with tr to protect unbound.conf
+ $WGET -O $work_dir/yoyo_ad_servers "$list_addr" && \
+ $CAT $work_dir/yoyo_ad_servers | \
++$TR -d '";$\\' | \
+ while read line ; \
+ do \
+ $ECHO "local-zone: \"$line\" redirect" ;\
+@@ -36,4 +39,4 @@
+ # the unbound_ad_servers file:
+ #
+ # include: $dst_dir/unbound_ad_servers
+-#
+\ No newline at end of file
++#
+--- contrib/unbound/contrib/drop-tld.diff.orig
++++ contrib/unbound/contrib/drop-tld.diff
+@@ -0,0 +1,82 @@
++diff --git a/daemon/worker.c b/daemon/worker.c
++index 263fcdd..f787b70 100644
++--- a/daemon/worker.c
+++++ b/daemon/worker.c
++@@ -1213,6 +1213,15 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
++ addr_to_str(&repinfo->addr, repinfo->addrlen, ip, sizeof(ip));
++ log_query_in(ip, qinfo.qname, qinfo.qtype, qinfo.qclass);
++ }
+++
+++ if(worker->env.cfg->drop_tld) {
+++ int lab = dname_count_labels(qinfo.qname);
+++ if (lab == 2) {
+++ comm_point_drop_reply(repinfo);
+++ verbose(VERB_ALGO, "Dropping one label query.");
+++ return 0;
+++ }
+++ }
++ if(qinfo.qtype == LDNS_RR_TYPE_AXFR ||
++ qinfo.qtype == LDNS_RR_TYPE_IXFR) {
++ verbose(VERB_ALGO, "worker request: refused zone transfer.");
++diff --git a/util/config_file.h b/util/config_file.h
++index b3ef930..2791541 100644
++--- a/util/config_file.h
+++++ b/util/config_file.h
++@@ -274,6 +274,8 @@ struct config_file {
++ int prefetch_key;
++ /** deny queries of type ANY with an empty answer */
++ int deny_any;
+++ /** Drop TLD queries from clients **/
+++ int drop_tld;
++
++ /** chrootdir, if not "" or chroot will be done */
++ char* chrootdir;
++diff --git a/util/configlexer.lex b/util/configlexer.lex
++index a86ddf5..9bbedbb 100644
++--- a/util/configlexer.lex
+++++ b/util/configlexer.lex
++@@ -299,6 +299,7 @@ private-domain{COLON} { YDVAR(1, VAR_PRIVATE_DOMAIN) }
++ prefetch-key{COLON} { YDVAR(1, VAR_PREFETCH_KEY) }
++ prefetch{COLON} { YDVAR(1, VAR_PREFETCH) }
++ deny-any{COLON} { YDVAR(1, VAR_DENY_ANY) }
+++drop-tld{COLON} { YDVAR(1, VAR_DROP_TLD) }
++ stub-zone{COLON} { YDVAR(0, VAR_STUB_ZONE) }
++ name{COLON} { YDVAR(1, VAR_NAME) }
++ stub-addr{COLON} { YDVAR(1, VAR_STUB_ADDR) }
++diff --git a/util/configparser.y b/util/configparser.y
++index 10227a2..567d68e 100644
++--- a/util/configparser.y
+++++ b/util/configparser.y
++@@ -164,6 +164,7 @@ extern struct config_parser_state* cfg_parser;
++ %token VAR_FAST_SERVER_PERMIL VAR_FAST_SERVER_NUM
++ %token VAR_ALLOW_NOTIFY VAR_TLS_WIN_CERT VAR_TCP_CONNECTION_LIMIT
++ %token VAR_FORWARD_NO_CACHE VAR_STUB_NO_CACHE VAR_LOG_SERVFAIL VAR_DENY_ANY
+++%token VAR_DROP_TLD
++ %token VAR_UNKNOWN_SERVER_TIME_LIMIT VAR_LOG_TAG_QUERYREPLY
++ %token VAR_STREAM_WAIT_SIZE VAR_TLS_CIPHERS VAR_TLS_CIPHERSUITES
++ %token VAR_TLS_SESSION_TICKET_KEYS
++@@ -266,6 +267,7 @@ content_server: server_num_threads | server_verbosity | server_port |
++ server_tls_cert_bundle | server_tls_additional_port | server_low_rtt |
++ server_fast_server_permil | server_fast_server_num | server_tls_win_cert |
++ server_tcp_connection_limit | server_log_servfail | server_deny_any |
+++ server_drop_tld |
++ server_unknown_server_time_limit | server_log_tag_queryreply |
++ server_stream_wait_size | server_tls_ciphers |
++ server_tls_ciphersuites | server_tls_session_ticket_keys
++@@ -1466,6 +1468,16 @@ server_deny_any: VAR_DENY_ANY STRING_ARG
++ free($2);
++ }
++ ;
+++
+++server_drop_tld: VAR_DROP_TLD STRING_ARG
+++ {
+++ OUTYY(("P(server_drop_tld:%s)\n", $2));
+++ if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
+++ yyerror("expected yes or no.");
+++ else cfg_parser->cfg->drop_tld = (strcmp($2, "yes")==0);
+++ free($2);
+++ }
+++ ;
++ server_unwanted_reply_threshold: VAR_UNWANTED_REPLY_THRESHOLD STRING_ARG
++ {
++ OUTYY(("P(server_unwanted_reply_threshold:%s)\n", $2));
+--- contrib/unbound/contrib/drop2rpz.orig
++++ contrib/unbound/contrib/drop2rpz
+@@ -0,0 +1,39 @@
++#!/usr/bin/perl
++
++# usage: curl --silent https://www.spamhaus.org/drop/drop.txt | $0 > /path/to/spamhaus-drop.rpz.local
++#
++# unbound.conf:
++# rpz:
++# name: "spamhaus-drop.rpz.local."
++# zonefile: "/path/tp/spamhaus-drop.rpz.local"
++# rpz-log: yes
++# rpz-log-name: "spamhaus-drop"
++#
++
++use strict;
++use vars qw{$o1 $o2 $o3 $o4 $m};
++
++# trailing dots required
++my $origin = 'drop.spamhaus.org.rpz.local.';
++my $mname = 'localhost.';
++my $rname = 'root.localhost.';
++my $ns = $mname;
++
++my $rpz_action = '.'; # return NXDOMAIN
++#my $rpz_action = '*.'; # return NODATA
++#my $rpz_action = 'rpz-drop.'; # drop the query
++
++print "$origin SOA $mname $rname 1 43200 7200 2419200 3600\n";
++print "$origin NS $ns\n";
++while(<>) {
++ if(($o1, $o2, $o3, $o4, $m) = m{(\d+)\.(\d+)\.(\d+)\.(\d+)/(\d+)}) {
++ print "$m.$o4.$o3.$o2.$o1.rpz-ip.$origin CNAME $rpz_action\n";
++ } else {
++ print "$_";
++ }
++}
++
++# add a testpoint: ask for "dns.google"
++# print "32.8.8.8.8.rpz-ip.$origin CNAME $rpz_action\n";
++
++exit;
+--- contrib/unbound/contrib/fastrpz.patch.orig
++++ contrib/unbound/contrib/fastrpz.patch
+@@ -0,0 +1,3504 @@
++Description: based on the included patch contrib/fastrpz.patch
++Author: fastrpz@farsightsecurity.com
++---
++diff --git a/Makefile.in b/Makefile.in
++index a20058cc..495779cc 100644
++--- a/Makefile.in
+++++ b/Makefile.in
++@@ -23,6 +23,8 @@ CHECKLOCK_SRC=testcode/checklocks.c
++ CHECKLOCK_OBJ=@CHECKLOCK_OBJ@
++ DNSTAP_SRC=@DNSTAP_SRC@
++ DNSTAP_OBJ=@DNSTAP_OBJ@
+++FASTRPZ_SRC=@FASTRPZ_SRC@
+++FASTRPZ_OBJ=@FASTRPZ_OBJ@
++ DNSCRYPT_SRC=@DNSCRYPT_SRC@
++ DNSCRYPT_OBJ=@DNSCRYPT_OBJ@
++ WITH_PYTHONMODULE=@WITH_PYTHONMODULE@
++@@ -127,7 +129,7 @@ validator/val_sigcrypt.c validator/val_utils.c dns64/dns64.c \
++ edns-subnet/edns-subnet.c edns-subnet/subnetmod.c \
++ edns-subnet/addrtree.c edns-subnet/subnet-whitelist.c \
++ cachedb/cachedb.c cachedb/redis.c respip/respip.c $(CHECKLOCK_SRC) \
++-$(DNSTAP_SRC) $(DNSCRYPT_SRC) $(IPSECMOD_SRC) $(IPSET_SRC)
+++$(DNSTAP_SRC) $(FASTRPZ_SRC) $(DNSCRYPT_SRC) $(IPSECMOD_SRC) $(IPSET_SRC)
++ COMMON_OBJ_WITHOUT_NETCALL=dns.lo infra.lo rrset.lo dname.lo msgencode.lo \
++ as112.lo msgparse.lo msgreply.lo packed_rrset.lo iterator.lo iter_delegpt.lo \
++ iter_donotq.lo iter_fwd.lo iter_hints.lo iter_priv.lo iter_resptype.lo \
++@@ -140,7 +142,7 @@ autotrust.lo val_anchor.lo rpz.lo \
++ validator.lo val_kcache.lo val_kentry.lo val_neg.lo val_nsec3.lo val_nsec.lo \
++ val_secalgo.lo val_sigcrypt.lo val_utils.lo dns64.lo cachedb.lo redis.lo authzone.lo \
++ $(SUBNET_OBJ) $(PYTHONMOD_OBJ) $(CHECKLOCK_OBJ) $(DNSTAP_OBJ) $(DNSCRYPT_OBJ) \
++-$(IPSECMOD_OBJ) $(IPSET_OBJ) respip.lo
+++$(FASTRPZ_OBJ) $(IPSECMOD_OBJ) $(IPSET_OBJ) respip.lo
++ COMMON_OBJ_WITHOUT_UB_EVENT=$(COMMON_OBJ_WITHOUT_NETCALL) netevent.lo listen_dnsport.lo \
++ outside_network.lo
++ COMMON_OBJ=$(COMMON_OBJ_WITHOUT_UB_EVENT) ub_event.lo
++@@ -410,6 +412,11 @@ dnscrypt.lo dnscrypt.o: $(srcdir)/dnscrypt/dnscrypt.c config.h \
++ $(srcdir)/util/config_file.h $(srcdir)/util/log.h \
++ $(srcdir)/util/netevent.h
++
+++# fastrpz
+++rpz.lo rpz.o: $(srcdir)/fastrpz/rpz.c config.h fastrpz/rpz.h fastrpz/librpz.h \
+++ $(srcdir)/util/config_file.h $(srcdir)/daemon/daemon.h \
+++ $(srcdir)/util/log.h
+++
++ # Python Module
++ pythonmod.lo pythonmod.o: $(srcdir)/pythonmod/pythonmod.c config.h \
++ pythonmod/interface.h \
++diff --git a/config.h.in b/config.h.in
++index 78d47fed..e33073e4 100644
++--- a/config.h.in
+++++ b/config.h.in
++@@ -1345,4 +1345,11 @@ void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file,
++ /** the version of unbound-control that this software implements */
++ #define UNBOUND_CONTROL_VERSION 1
++
++-
+++/* have __attribute__s used in librpz.h */
+++#undef LIBRPZ_HAVE_ATTR
+++/** fastrpz librpz.so */
+++#undef FASTRPZ_LIBRPZ_PATH
+++/** 0=no fastrpz 1=static link 2=dlopen() */
+++#undef FASTRPZ_LIB_OPEN
+++/** turn on fastrpz response policy zones */
+++#undef ENABLE_FASTRPZ
++diff --git a/configure.ac b/configure.ac
++index 2b91dd3c..e6063d17 100644
++--- a/configure.ac
+++++ b/configure.ac
++@@ -6,6 +6,7 @@ sinclude(ax_pthread.m4)
++ sinclude(acx_python.m4)
++ sinclude(ac_pkg_swig.m4)
++ sinclude(dnstap/dnstap.m4)
+++sinclude(fastrpz/rpz.m4)
++ sinclude(dnscrypt/dnscrypt.m4)
++
++ # must be numbers. ac_defun because of later processing
++@@ -1778,6 +1779,9 @@ case "$enable_ipset" in
++ ;;
++ esac
++
+++# check for Fastrpz with fastrpz/rpz.m4
+++ck_FASTRPZ
+++
++ AC_MSG_CHECKING([if ${MAKE:-make} supports $< with implicit rule in scope])
++ # on openBSD, the implicit rule make $< work.
++ # on Solaris, it does not work ($? is changed sources, $^ lists dependencies).
++diff --git a/daemon/daemon.c b/daemon/daemon.c
++index 8b0fc348..7ffb9221 100644
++--- a/daemon/daemon.c
+++++ b/daemon/daemon.c
++@@ -91,6 +91,9 @@
++ #include "sldns/keyraw.h"
++ #include "respip/respip.h"
++ #include <signal.h>
+++#ifdef ENABLE_FASTRPZ
+++#include "fastrpz/rpz.h"
+++#endif
++
++ #ifdef HAVE_SYSTEMD
++ #include <systemd/sd-daemon.h>
++@@ -458,6 +461,14 @@ daemon_create_workers(struct daemon* daemon)
++ dt_apply_cfg(daemon->dtenv, daemon->cfg);
++ #else
++ fatal_exit("dnstap enabled in config but not built with dnstap support");
+++#endif
+++ }
+++ if(daemon->cfg->rpz_enable) {
+++#ifdef ENABLE_FASTRPZ
+++ rpz_init(&daemon->rpz_clist, &daemon->rpz_client, daemon->cfg);
+++#else
+++ fatal_exit("fastrpz enabled in config"
+++ " but not built with fastrpz");
++ #endif
++ }
++ for(i=0; i<daemon->num; i++) {
++@@ -731,6 +742,9 @@ daemon_cleanup(struct daemon* daemon)
++ #ifdef USE_DNSCRYPT
++ dnsc_delete(daemon->dnscenv);
++ daemon->dnscenv = NULL;
+++#endif
+++#ifdef ENABLE_FASTRPZ
+++ rpz_delete(&daemon->rpz_clist, &daemon->rpz_client);
++ #endif
++ daemon->cfg = NULL;
++ }
++diff --git a/daemon/daemon.h b/daemon/daemon.h
++index 3effbafb..4d4c34da 100644
++--- a/daemon/daemon.h
+++++ b/daemon/daemon.h
++@@ -138,6 +138,11 @@ struct daemon {
++ /** the dnscrypt environment */
++ struct dnsc_env* dnscenv;
++ #endif
+++#ifdef ENABLE_FASTRPZ
+++ /** global opaque rpz handles */
+++ struct librpz_clist *rpz_clist;
+++ struct librpz_client *rpz_client;
+++#endif
++ };
++
++ /**
++diff --git a/daemon/worker.c b/daemon/worker.c
++index eb7fdf2f..1982228d 100644
++--- a/daemon/worker.c
+++++ b/daemon/worker.c
++@@ -76,6 +76,9 @@
++ #include "libunbound/context.h"
++ #include "libunbound/libworker.h"
++ #include "sldns/sbuffer.h"
+++#ifdef ENABLE_FASTRPZ
+++#include "fastrpz/rpz.h"
+++#endif
++ #include "sldns/wire2str.h"
++ #include "util/shm_side/shm_main.h"
++ #include "dnscrypt/dnscrypt.h"
++@@ -534,8 +537,27 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
++ /* not secure */
++ secure = 0;
++ break;
+++#ifdef ENABLE_FASTRPZ
+++ case sec_status_rpz_rewritten:
+++ case sec_status_rpz_drop:
+++ fatal_exit("impossible cached RPZ sec_status");
+++ break;
+++#endif
++ }
++ }
+++#ifdef ENABLE_FASTRPZ
+++ if(repinfo->rpz) {
+++ /* Scan the cached answer for RPZ hits.
+++ * ret=1 use cache entry
+++ * ret=-1 rewritten response already sent or dropped
+++ * ret=0 deny a cached entry exists
+++ */
+++ int ret = rpz_worker_cache(worker, msg->rep, qinfo,
+++ id, flags, edns, repinfo);
+++ if(ret != 1)
+++ return ret;
+++ }
+++#endif
++ /* return this delegation from the cache */
++ edns_bak = *edns;
++ edns->edns_version = EDNS_ADVERTISED_VERSION;
++@@ -710,6 +732,23 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
++ *is_secure_answer = 0;
++ }
++ } else *is_secure_answer = 0;
+++#ifdef ENABLE_FASTRPZ
+++ if(repinfo->rpz) {
+++ /* Scan the cached answer for RPZ hits.
+++ * ret=1 use cache entry
+++ * ret=-1 rewritten response already sent or dropped
+++ * ret=0 deny a cached entry exists
+++ */
+++ int ret = rpz_worker_cache(worker, rep, qinfo, id, flags, edns,
+++ repinfo);
+++ if(ret != 1) {
+++ rrset_array_unlock_touch(worker->env.rrset_cache,
+++ worker->scratchpad, rep->ref,
+++ rep->rrset_count);
+++ return ret;
+++ }
+++ }
+++#endif
++
++ edns_bak = *edns;
++ edns->edns_version = EDNS_ADVERTISED_VERSION;
++@@ -1435,6 +1474,15 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
++ log_addr(VERB_ALGO, "refused nonrec (cache snoop) query from",
++ &repinfo->addr, repinfo->addrlen);
++ goto send_reply;
+++#ifdef ENABLE_FASTRPZ
+++ } else {
+++ /* Start to rewrite for response policy zones.
+++ * This can hit a qname trigger and be done. */
+++ if(rpz_start(worker, &qinfo, repinfo, &edns)) {
+++ regional_free_all(worker->scratchpad);
+++ return 0;
+++ }
+++#endif
++ }
++
++ /* If we've found a local alias, replace the qname with the alias
++@@ -1485,12 +1533,21 @@ lookup_cache:
++ h = query_info_hash(lookup_qinfo, sldns_buffer_read_u16_at(c->buffer, 2));
++ if((e=slabhash_lookup(worker->env.msg_cache, h, lookup_qinfo, 0))) {
++ /* answer from cache - we have acquired a readlock on it */
++- if(answer_from_cache(worker, &qinfo,
+++ ret = answer_from_cache(worker, &qinfo,
++ cinfo, &need_drop, &is_expired_answer, &is_secure_answer,
++ &alias_rrset, &partial_rep, (struct reply_info*)e->data,
++ *(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
++ sldns_buffer_read_u16_at(c->buffer, 2), repinfo,
++- &edns)) {
+++ &edns);
+++#ifdef ENABLE_FASTRPZ
+++ if(ret < 0) {
+++ /* RPZ already dropped or sent a response. */
+++ lock_rw_unlock(&e->lock);
+++ regional_free_all(worker->scratchpad);
+++ return 0;
+++ }
+++#endif
+++ if(ret) {
++ /* prefetch it if the prefetch TTL expired.
++ * Note that if there is more than one pass
++ * its qname must be that used for cache
++@@ -1547,11 +1604,19 @@ lookup_cache:
++ lock_rw_unlock(&e->lock);
++ }
++ if(!LDNS_RD_WIRE(sldns_buffer_begin(c->buffer))) {
++- if(answer_norec_from_cache(worker, &qinfo,
+++ ret = answer_norec_from_cache(worker, &qinfo,
++ *(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
++ sldns_buffer_read_u16_at(c->buffer, 2), repinfo,
++- &edns)) {
+++ &edns);
+++ if(ret) {
++ regional_free_all(worker->scratchpad);
+++#ifdef ENABLE_FASTRPZ
+++ if(ret < 0) {
+++ /* RPZ already dropped
+++ * or sent a response. */
+++ return 0;
+++ }
+++#endif
++ goto send_reply;
++ }
++ verbose(VERB_ALGO, "answer norec from cache -- "
++diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in
++index 38c2d298..3b07f392 100644
++--- a/doc/unbound.conf.5.in
+++++ b/doc/unbound.conf.5.in
++@@ -1828,6 +1828,81 @@ List domain for which the AAAA records are ignored and the A record is
++ used by dns64 processing instead. Can be entered multiple times, list a
++ new domain for which it applies, one per line. Applies also to names
++ underneath the name given.
+++.SS "Response Policy Zone Rewriting"
+++.LP
+++Response policy zone rewriting is controlled with the
+++.B rpz
+++clause.
+++It must contain a
+++.B rpz\-enable:
+++option, and one or more
+++.B rpz\-zone:
+++options.
+++It will usually also contain
+++.B rpz\-option:
+++clauses with general rewriting options or specifying dnsrpzd parameters.
+++Beneath the surface, the text in
+++.B rpz\-zone: \fI<"domain">\fR
+++is converted to \fI"zone domain\\n"\fR and added to the configuration string
+++given to
+++\fIlibrpz\fR(3).
+++The text in
+++.B rpz-option \fI<"text">\fR
+++is also added to that configuration string.
+++.LP
+++If using chroot, then the chroot directory must contain the \fIdnsrpzd\fR(3)
+++command and the shared libraries that it uses.
+++Those can be found with the \fIldd\fR(1) command.
+++.LP
+++Resolver zone and rewriting options and response policy zone triggers and
+++actions are described in \fIlibrpz\fR(3).
+++The separate control file that specifies the policy zones maintained by
+++the dnsrpzd daemon is described in \fIdnsrpzd\fR(8).
+++.LP
+++Many installations need a local whitelist that exempts local
+++domains from rewriting.
+++Whitelist records can be in zones transferred by dnsrpzd from
+++authorities or in a local zone file.
+++.TP
+++.B rpz-enable: \fI<yes or no>
+++enables Fastrpz.
+++If not enabled, the other options in the
+++.B rpz:
+++clause are ignored.
+++.TP
+++.B rpz-zone: \fI<"zone and options">
+++specifies a policy zone and optional per-zone rewriting parameters.
+++.TP
+++.B rpz-option: \fI<"option">
+++specifies general Fastrpz options.
+++.LP
+++Fastrpz is available only on POSIX compliant UNIX-like systems with the
+++\fImmap\fR(2) system call.
+++.LP
+++Fastrpz in Unbound differs from rpz and fastrpz in BIND by
+++.RS 3
+++.HP 4
+++RPZ-CLIENT-IP triggers can only be used in the first policy zone
+++specified with
+++.B rpz-zone:
+++.HP
+++Policy zone rewriting is disabled by the DO bit in DNS requests
+++even when no DNSSEC signatures are supplied by authorities.
+++.HP
+++Unbound local zones are not subject to rpz rewriting.
+++.HP
+++Like Fastrpz with BIND but unlike classic BIND rpz,
+++the ADDITIONAL sections of rewritten responses contain the SOA record from
+++the policy zone used to rewrite the response.
+++.RE
+++.P
+++.nf
+++# example Fastrpz settings for use with chroot on Freebsd
+++rpz:
+++ rpz-zone: "rpz.example.org"
+++ rpz-zone: "other.rpz.example.org ip-as-ns yes"
+++ rpz-option: "dnsrpzd ./dnsrpzd"
+++.fi
++ .SS "DNSCrypt Options"
++ .LP
++ The
++diff --git a/fastrpz/librpz.h b/fastrpz/librpz.h
++new file mode 100644
++index 00000000..645279d1
++--- /dev/null
+++++ b/fastrpz/librpz.h
++@@ -0,0 +1,957 @@
+++/*
+++ * Define the interface from a DNS resolver to the Response Policy Zone
+++ * library, librpz.
+++ *
+++ * This file should be included only the interface functions between the
+++ * resolver and librpz to avoid name space pollution.
+++ *
+++ * Copyright (c) 2016-2017 Farsight Security, Inc.
+++ *
+++ * Licensed under the Apache License, Version 2.0 (the "License");
+++ * you may not use this file except in compliance with the License.
+++ * You may obtain a copy of the License at
+++ * http://www.apache.org/licenses/LICENSE-2.0
+++ *
+++ * Unless required by applicable law or agreed to in writing, software
+++ * distributed under the License is distributed on an "AS IS" BASIS,
+++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+++ * See the License for the specific language governing permissions and
+++ * limitations under the License.
+++ *
+++ * Fastrpz version 1.2.10
+++ */
+++
+++#ifndef LIBRPZ_H
+++#define LIBRPZ_H
+++
+++#include <arpa/nameser.h>
+++#include <netinet/in.h>
+++#include <stdarg.h>
+++#include <stdbool.h>
+++#include <stdio.h>
+++#include <sys/types.h>
+++
+++
+++/*
+++ * Allow either ordinary or dlopen() linking.
+++ */
+++#ifdef LIBRPZ_INTERNAL
+++#define LIBDEF(t,s) extern t s;
+++#define LIBDEF_F(f) LIBDEF(librpz_##f##_t, librpz_##f)
+++#else
+++#define LIBDEF(t,s)
+++#define LIBDEF_F(f)
+++#endif
+++
+++/*
+++ * Response Policy Zone triggers.
+++ * Comparisons of trigger precedences require
+++ * LIBRPZ_TRIG_CLIENT_IP < LIBRPZ_TRIG_QNAME < LIBRPZ_TRIG_IP
+++ * < LIBRPZ_TRIG_NSDNAME < LIBRPZ_TRIG_NSIP}
+++ */
+++typedef enum {
+++ LIBRPZ_TRIG_BAD =0,
+++ LIBRPZ_TRIG_CLIENT_IP =1,
+++ LIBRPZ_TRIG_QNAME =2,
+++ LIBRPZ_TRIG_IP =3,
+++ LIBRPZ_TRIG_NSDNAME =4,
+++ LIBRPZ_TRIG_NSIP =5
+++} librpz_trig_t;
+++#define LIBRPZ_TRIG_SIZE 3 /* sizeof librpz_trig_t in bits */
+++typedef uint8_t librpz_tbit_t; /* one bit for each of the TRIGS_NUM
+++ * trigger types */
+++
+++
+++/*
+++ * Response Policy Zone Actions or policies
+++ */
+++typedef enum {
+++ LIBRPZ_POLICY_UNDEFINED =0, /* an empty entry or no decision yet */
+++ LIBRPZ_POLICY_DELETED =1, /* placeholder for a deleted policy */
+++
+++ LIBRPZ_POLICY_PASSTHRU =2, /* 'passthru': do not rewrite */
+++ LIBRPZ_POLICY_DROP =3, /* 'drop': do not respond */
+++ LIBRPZ_POLICY_TCP_ONLY =4, /* 'tcp-only': answer UDP with TC=1 */
+++ LIBRPZ_POLICY_NXDOMAIN =5, /* 'nxdomain': answer with NXDOMAIN */
+++ LIBRPZ_POLICY_NODATA =6, /* 'nodata': answer with ANCOUNT=0 */
+++ LIBRPZ_POLICY_RECORD =7, /* rewrite with the policy's RR */
+++
+++ /* only in client configurations to override the zone */
+++ LIBRPZ_POLICY_GIVEN, /* 'given': what policy record says */
+++ LIBRPZ_POLICY_DISABLED, /* at most log */
+++ LIBRPZ_POLICY_CNAME, /* answer with 'cname x' */
+++} librpz_policy_t;
+++#define LIBRPZ_POLICY_BITS 4
+++
+++/*
+++ * Special policies that appear as targets of CNAMEs
+++ * NXDOMAIN is signaled by a CNAME with a "." target.
+++ * NODATA is signaled by a CNAME with a "*." target.
+++ */
+++#define LIBRPZ_RPZ_PREFIX "rpz-"
+++#define LIBRPZ_RPZ_PASSTHRU LIBRPZ_RPZ_PREFIX"passthru"
+++#define LIBRPZ_RPZ_DROP LIBRPZ_RPZ_PREFIX"drop"
+++#define LIBRPZ_RPZ_TCP_ONLY LIBRPZ_RPZ_PREFIX"tcp-only"
+++
+++
+++typedef uint16_t librpz_dznum_t; /* dnsrpzd zone # in [0,DZNUM_MAX] */
+++typedef uint8_t librpz_cznum_t; /* client zone # in [0,CZNUM_MAX] */
+++
+++
+++/*
+++ * CIDR block
+++ */
+++typedef struct librpz_prefix {
+++ union {
+++ struct in_addr in;
+++ struct in6_addr in6;
+++ } addr;
+++ uint8_t family;
+++ uint8_t len;
+++} librpz_prefix_t;
+++
+++/*
+++ * A domain
+++ */
+++typedef uint8_t librpz_dsize_t;
+++typedef struct librpz_domain {
+++ librpz_dsize_t size; /* of only .d */
+++ uint8_t d[0]; /* variable length wire format */
+++} librpz_domain_t;
+++
+++/*
+++ * A maximal domain buffer
+++ */
+++typedef struct librpz_domain_buf {
+++ librpz_dsize_t size;
+++ uint8_t d[NS_MAXCDNAME];
+++} librpz_domain_buf_t;
+++
+++/*
+++ * A resource record without the owner name.
+++ * C compilers say that sizeof(librpz_rr_t)=12 instead of 10.
+++ */
+++typedef struct {
+++ uint16_t type; /* network byte order */
+++ uint16_t class; /* network byte order */
+++ uint32_t ttl; /* network byte order */
+++ uint16_t rdlength; /* network byte order */
+++ uint8_t rdata[0]; /* variable length */
+++} librpz_rr_t;
+++
+++/*
+++ * The database file might be mapped with different starting addresses
+++ * by concurrent clients (resolvers), and so all pointers are offsets.
+++ */
+++typedef uint32_t librpz_idx_t;
+++#define LIBRPZ_IDX_NULL 0
+++#define LIBRPZ_IDX_MIN 1
+++#define LIBRPZ_IDX_BAD ((librpz_idx_t)-1)
+++/**
+++ * Partial decoded results of a set of RPZ queries for a single DNS response
+++ * or interation through the mapped file.
+++ */
+++typedef int16_t librpz_result_id_t;
+++typedef struct librpz_result {
+++ librpz_idx_t next_rr;
+++ librpz_result_id_t hit_id; /* trigger ID from resolver */
+++ librpz_policy_t zpolicy; /* policy from zone */
+++ librpz_policy_t policy; /* adjusted by client configuration */
+++ librpz_dznum_t dznum; /* dnsrpzd zone number */
+++ librpz_cznum_t cznum; /* librpz client zone number */
+++ librpz_trig_t trig:LIBRPZ_TRIG_SIZE;
+++ bool log:1; /* log rewrite given librpz_log_level */
+++} librpz_result_t;
+++
+++
+++/**
+++ * librpz trace or log levels.
+++ */
+++typedef enum {
+++ LIBRPZ_LOG_FATAL =0, /* always print fatal errors */
+++ LIBRPZ_LOG_ERROR =1, /* errors have this level */
+++ LIBRPZ_LOG_TRACE1 =2, /* big events such as dnsrpzd starts */
+++ LIBRPZ_LOG_TRACE2 =3, /* smaller dnsrpzd zone transfers */
+++ LIBRPZ_LOG_TRACE3 =4, /* librpz hits */
+++ LIBRPZ_LOG_TRACE4 =5, /* librpz lookups */
+++ LIBRPZ_LOG_INVALID =999,
+++} librpz_log_level_t;
+++typedef librpz_log_level_t (librpz_log_level_val_t)(librpz_log_level_t level);
+++LIBDEF_F(log_level_val)
+++
+++/**
+++ * Logging function that can be supplied by the resolver.
+++ * @param level is one of librpz_log_level_t
+++ * @param ctx is for use by the resolver's logging system.
+++ * NULL mean a context-free message.
+++ */
+++typedef void(librpz_log_fnc_t)(librpz_log_level_t level, void *ctx,
+++ const char *buf);
+++
+++/**
+++ * Point librpz logging functions to the resolver's choice.
+++ */
+++typedef void (librpz_set_log_t)(librpz_log_fnc_t *new_log, const char *prog_nm);
+++LIBDEF_F(set_log)
+++
+++
+++/**
+++ * librpz error messages are put in these buffers.
+++ * Use a structure intead of naked char* to let the compiler check the length.
+++ * A function defined with "foo(char buf[120])" can be called with
+++ * "char sbuf[2]; foo(sbuf)" and suffer a buffer overrun.
+++ */
+++typedef struct {
+++ char c[120];
+++} librpz_emsg_t;
+++
+++
+++#ifdef LIBRPZ_HAVE_ATTR
+++#define LIBRPZ_UNUSED __attribute__((unused))
+++#define LIBRPZ_PF(f,l) __attribute__((format(printf,f,l)))
+++#define LIBRPZ_NORET __attribute__((__noreturn__))
+++#else
+++#define LIBRPZ_UNUSED
+++#define LIBRPZ_PF(f,l)
+++#define LIBRPZ_NORET
+++#endif
+++
+++#ifdef HAVE_BUILTIN_EXPECT
+++#define LIBRPZ_LIKELY(c) __builtin_expect(!!(c), 1)
+++#define LIBRPZ_UNLIKELY(c) __builtin_expect(!!(c), 0)
+++#else
+++#define LIBRPZ_LIKELY(c) (c)
+++#define LIBRPZ_UNLIKELY(c) (c)
+++#endif
+++
+++typedef bool (librpz_parse_log_opt_t)(librpz_emsg_t *emsg, const char *arg);
+++LIBDEF_F(parse_log_opt)
+++
+++typedef void (librpz_vpemsg_t)(librpz_emsg_t *emsg,
+++ const char *p, va_list args);
+++LIBDEF_F(vpemsg)
+++typedef void (librpz_pemsg_t)(librpz_emsg_t *emsg,
+++ const char *p, ...) LIBRPZ_PF(2,3);
+++LIBDEF_F(pemsg)
+++
+++typedef void (librpz_vlog_t)(librpz_log_level_t level, void *ctx,
+++ const char *p, va_list args);
+++LIBDEF_F(vlog)
+++typedef void (librpz_log_t)(librpz_log_level_t level, void *ctx,
+++ const char *p, ...) LIBRPZ_PF(3,4);
+++LIBDEF_F(log)
+++
+++typedef void (librpz_fatal_t)(int ex_code,
+++ const char *p, ...) LIBRPZ_PF(2,3);
+++extern void librpz_fatal(int ex_code,
+++ const char *p, ...) LIBRPZ_PF(2,3) LIBRPZ_NORET;
+++
+++typedef void (librpz_rpz_assert_t)(const char *file, unsigned line,
+++ const char *p, ...) LIBRPZ_PF(3,4);
+++extern void librpz_rpz_assert(const char *file, unsigned line,
+++ const char *p, ...) LIBRPZ_PF(3,4) LIBRPZ_NORET;
+++
+++typedef void (librpz_rpz_vassert_t)(const char *file, uint line,
+++ const char *p, va_list args);
+++extern void librpz_rpz_vassert(const char *file, uint line,
+++ const char *p, va_list args) LIBRPZ_NORET;
+++
+++
+++/*
+++ * As far as clients are concerned, all relative pointers or indexes in a
+++ * version of the mapped file except trie node parent pointers remain valid
+++ * forever. A client must release a version so that it can be garbage
+++ * collected by the file system. When dnsrpzd needs to expand the file,
+++ * it copies the old file to a new, larger file. Clients can continue
+++ * using the old file.
+++ *
+++ * Versions can also appear in a single file. Old nodes and trie values
+++ * within the file are not destroyed until all clients using the version
+++ * that contained the old values release the version.
+++ *
+++ * A client is marked as using version by connecting to the deamon. It is
+++ * marked as using all subsequent versions. A client releases all versions
+++ * by closing the connection or a range of versions by updating is slot
+++ * in the shared memory version table.
+++ *
+++ * As far as clients are concerned, there are the following possible librpz
+++ * failures:
+++ * - malloc() or other fatal internal librpz problems indicated by
+++ * a failing return from a librpz function
+++ * All operations will fail until client handle is destroyed and
+++ * recreated with librpz_client_detach() and librpz_client_create().
+++ * - corrupt database detected by librpz code, corrupt database detected
+++ * by dnsrpzd, or disconnection from the daemon.
+++ * Current operations will fail.
+++ *
+++ * Clients assume that the file has already been unlinked before
+++ * the corrupt flag is set so that they do not race with the server
+++ * over the corruption of a single file. A client that finds the
+++ * corrupt set knows that dnsrpzd has already crashed with
+++ * abort() and is restarting. The client can re-connect to dnsrpzd
+++ * and retransmit its configuration, backing off as usual if anything
+++ * goes wrong.
+++ *
+++ * Searchs of the database by a client do not need locks against dnsrpzd or
+++ * other clients, but a lock is used to protect changes to the connection
+++ * by competing threads in the client. The client provides fuctions
+++ * to serialize the conncurrent use of any single client handle.
+++ * Functions that do nothing are appropriate for applications that are
+++ * not "threaded" or that do not share client handles among threads.
+++ * Otherwise, functions must be provided to librpz_clientcreate().
+++ * Something like the following works with pthreads:
+++ *
+++ * static void
+++ * lock(void *mutex) { assert(pthread_mutex_lock(mutex) == 0); }
+++ *
+++ * static void
+++ * unlock(void *mutex) { assert(pthread_mutex_unlock(mutex) == 0); }
+++ *
+++ * static void
+++ * mutex_destroy(void *mutex) { assert(pthread_mutex_destroy(mutex) == 0); }
+++ *
+++ *
+++ *
+++ * At every instant, all of the data and pointers in the mapped file are valid.
+++ * Changes to trie node or other data are always made so that it and
+++ * all pointers in and to it remain valid for a time. Old versions are
+++ * eventually discarded.
+++ *
+++ * Dnsrpzd periodically defines a new version by setting asside all changes
+++ * made since the previous version was defined. Subsequent changes
+++ * made (only!) by dnsrpzd will be part of the next version.
+++ *
+++ * To discard an old version, dnsrpzd must know that all clients have stopped
+++ * using that version. Clients do that by using part of the mapped file
+++ * to tell dnsrpzd the oldest version that each client is using.
+++ * Dnsrpzd assigns each connecting client an entry in the cversions array
+++ * in the mapped file. The client puts version numbers into that entry
+++ * to signal to dnsrpzd which versions that can be discarded.
+++ * Dnsrpzd is free, as far as that client is concerned, to discard all
+++ * numerically smaller versions. A client can disclaim all versions with
+++ * the version number VERSIONS_ALL or 0.
+++ *
+++ * The race between a client changing its entry and dnsrpzd discarding a
+++ * version is resolved by allowing dnsrpzd to discard all versions
+++ * smaller or equal to the client's version number. If dnsrpzd is in
+++ * the midst of discarding or about to discard version N when the
+++ * client asserts N, no harm is done. The client depends only on
+++ * the consistency of version N+1.
+++ *
+++ * This version mechanism depends in part on not being exercised too frequently
+++ * Version numbers are 32 bits long and dnsrpzd creates new versions
+++ * at most once every 30 seconds.
+++ */
+++
+++
+++/*
+++ * Lock functions for concurrent use of a single librpz_client_t client handle.
+++ */
+++typedef void(librpz_mutex_t)(void *mutex);
+++
+++/*
+++ * List of connections to dnsrpzd daemons.
+++ */
+++typedef struct librpz_clist librpz_clist_t;
+++
+++/*
+++ * Client's handle on dnsrpzd.
+++ */
+++typedef struct librpz_client librpz_client_t;
+++
+++/**
+++ * Create the list of connections to the dnsrpzd daemon.
+++ * @param[out] emsg: error message
+++ * @param lock: start exclusive access to the client handle
+++ * @param unlock: end exclusive access to the client handle
+++ * @param mutex_destroy: release the lock
+++ * @param mutex: pointer to the lock for the client handle
+++ * @param log_ctx: NULL or resolver's context log messages
+++ */
+++typedef librpz_clist_t *(librpz_clist_create_t)(librpz_emsg_t *emsg,
+++ librpz_mutex_t *lock,
+++ librpz_mutex_t *unlock,
+++ librpz_mutex_t *mutex_destroy,
+++ void *mutex, void *log_ctx);
+++LIBDEF_F(clist_create)
+++
+++
+++/**
+++ * Release the list of dnsrpzd connections.
+++ */
+++typedef void (librpz_clist_detach_t)(librpz_clist_t **clistp);
+++LIBDEF_F(clist_detach)
+++
+++/**
+++ * Create a librpz client handle.
+++ * @param[out] emsg: error message
+++ * @param: list of dnsrpzd connections
+++ * @param cstr: string of configuration settings separated by ';' or '\n'
+++ * @param use_expired: true to not ignore expired zones
+++ * @return client handle or NULL if the handle could not be created
+++ */
+++typedef librpz_client_t *(librpz_client_create_t)(librpz_emsg_t *emsg,
+++ librpz_clist_t *clist,
+++ const char *cstr,
+++ bool use_expired);
+++LIBDEF_F(client_create)
+++
+++/**
+++ * Start (if necessary) dnsrpzd and connect to it.
+++ * @param[out] emsg: error message
+++ * @param client handle
+++ * @param optional: true if it is ok if starting the daemon is not allowed
+++ */
+++typedef bool (librpz_connect_t)(librpz_emsg_t *emsg, librpz_client_t *client,
+++ bool optional);
+++LIBDEF_F(connect)
+++
+++/**
+++ * Start to destroy a librpz client handle.
+++ * It will not be destroyed until the last set of RPZ queries represented
+++ * by a librpz_rsp_t ends.
+++ * @param client handle to be released
+++ * @return false on error
+++ */
+++typedef void (librpz_client_detach_t)(librpz_client_t **clientp);
+++LIBDEF_F(client_detach)
+++
+++/**
+++ * State for a set of RPZ queries for a single DNS response
+++ * or for listing the database.
+++ */
+++typedef struct librpz_rsp librpz_rsp_t;
+++
+++/**
+++ * Start a set of RPZ queries for a single DNS response.
+++ * @param[out] emsg: error message for false return or *rspp=NULL
+++ * @param[out] rspp created context or NULL
+++ * @param[out] min_ns_dotsp: NULL or pointer to configured MIN-NS-DOTS value
+++ * @param client state
+++ * @param have_rd: RD=1 in the DNS request
+++ * @param have_do: DO=1 in the DNS request
+++ * @return false on error
+++ */
+++typedef bool (librpz_rsp_create_t)(librpz_emsg_t *emsg, librpz_rsp_t **rspp,
+++ int *min_ns_dotsp, librpz_client_t *client,
+++ bool have_rd, bool have_do);
+++LIBDEF_F(rsp_create)
+++
+++/**
+++ * Finish RPZ work for a DNS response.
+++ */
+++typedef void (librpz_rsp_detach_t)(librpz_rsp_t **rspp);
+++LIBDEF_F(rsp_detach)
+++
+++/**
+++ * Get the final, accumulated result of a set of RPZ queries.
+++ * Yield LIBRPZ_POLICY_UNDEFINED if
+++ * - there were no hits,
+++ * - there was a dispositive hit, be we have not recursed and are required
+++ * to recurse so that evil DNS authories will not know we are using RPZ
+++ * - we have a hit and have recursed, but later data such as NSIP could
+++ * override
+++ * @param[out] emsg
+++ * @param[out] result describes the hit
+++ * or result->policy=LIBRPZ_POLICY_UNDEFINED without a hit
+++ * @param[out] result: current policy rewrite values
+++ * @param recursed: recursion has now been done even if it was not done
+++ * when the hit was found
+++ * @param[in,out] rsp state from librpz_itr_start()
+++ * @return false on error
+++ */
+++typedef bool (librpz_rsp_result_t)(librpz_emsg_t *emsg, librpz_result_t *result,
+++ bool recursed, const librpz_rsp_t *rsp);
+++LIBDEF_F(rsp_result)
+++
+++/**
+++ * Might looking for a trigger be worthwhile?
+++ * @param trig: look for this type of trigger
+++ * @param ipv6: true if trig is LIBRPZ_TRIG_CLIENT_IP, LIBRPZ_TRIG_IP,
+++ * or LIBRPZ_TRIG_NSIP and the IP address is IPv6
+++ * @return: true if looking could be worthwhile
+++ */
+++typedef bool (librpz_have_trig_t)(librpz_trig_t trig, bool ipv6,
+++ const librpz_rsp_t *rsp);
+++LIBDEF_F(have_trig)
+++
+++/**
+++ * Might looking for NSDNAME and NSIP triggers be worthwhile?
+++ * @return: true if looking could be worthwhile
+++ */
+++typedef bool (librpz_have_ns_trig_t)(const librpz_rsp_t *rsp);
+++LIBDEF_F(have_ns_trig)
+++
+++/**
+++ * Convert the found client IP trie key to a CIDR block
+++ * @param[out] emsg
+++ * @param[out] prefix trigger
+++ * @param[in,out] rsp state from librpz_itr_start()
+++ * @return false on error
+++ */
+++typedef bool (librpz_rsp_clientip_prefix_t)(librpz_emsg_t *emsg,
+++ librpz_prefix_t *prefix,
+++ librpz_rsp_t *rsp);
+++LIBDEF_F(rsp_clientip_prefix)
+++
+++/**
+++ * Compute the owner name of the found or result trie key, usually to log it.
+++ * An IP address key might be returned as 8.0.0.0.127.rpz-client-ip.
+++ * example.com. might be a qname trigger. example.com.rpz-nsdname. could
+++ * be an NSDNAME trigger.
+++ * @param[out] emsg
+++ * @param[out] owner domain
+++ * @param[in,out] rsp state from librpz_itr_start()
+++ * @return false on error
+++ */
+++typedef bool (librpz_rsp_domain_t)(librpz_emsg_t *emsg,
+++ librpz_domain_buf_t *owner,
+++ librpz_rsp_t *rsp);
+++LIBDEF_F(rsp_domain)
+++
+++/**
+++ * Get the next RR of the LIBRPZ_POLICY_RECORD result after an initial use of
+++ * librpz_rsp_result() or librpz_itr_node() or after a previous use of
+++ * librpz_rsp_rr(). The RR is in uncompressed wire format including type,
+++ * class, ttl and length in network byte order.
+++ * @param[out] emsg
+++ * @param[out] typep: optional host byte order record type or ns_t_invalid (0)
+++ * @param[out] classp: class such as ns_c_in
+++ * @param[out] ttlp: TTL
+++ * @param[out] rrp: optionall malloc() buffer containting the next RR or
+++ * NULL after the last RR
+++ * @param[out] result: current policy rewrite values
+++ * @param qname: used construct a wildcard CNAME
+++ * @param qname_size
+++ * @param[in,out] rsp state from librpz_itr_start()
+++ * @return false on error
+++ */
+++typedef bool (librpz_rsp_rr_t)(librpz_emsg_t *emsg, uint16_t *typep,
+++ uint16_t *classp, uint32_t *ttlp,
+++ librpz_rr_t **rrp, librpz_result_t *result,
+++ const uint8_t *qname, size_t qname_size,
+++ librpz_rsp_t *rsp);
+++LIBDEF_F(rsp_rr)
+++
+++/**
+++ * Get the next RR of the LIBRPZ_POLICY_RECORD result.
+++ * @param[out] emsg
+++ * @param[out] ttlp: TTL
+++ * @param[out] rrp: malloc() buffer with SOA RR without owner name
+++ * @param[out] result: current policy rewrite values
+++ * @param[out] origin: SOA owner name
+++ * @param[out] origin_size
+++ * @param[in,out] rsp state from librpz_itr_start()
+++ * @return false on error
+++ */
+++typedef bool (librpz_rsp_soa_t)(librpz_emsg_t *emsg, uint32_t *ttlp,
+++ librpz_rr_t **rrp, librpz_domain_buf_t *origin,
+++ librpz_result_t *result, librpz_rsp_t *rsp);
+++LIBDEF_F(rsp_soa)
+++
+++/**
+++ * Get the SOA serial number for a policy zone to compare with a known value
+++ * to check whether a zone tranfer is complete.
+++ */
+++typedef bool (librpz_soa_serial_t)(librpz_emsg_t *emsg, uint32_t *serialp,
+++ const char *domain_nm, librpz_rsp_t *rsp);
+++LIBDEF_F(soa_serial)
+++
+++/**
+++ * Save the current policy checking state.
+++ * @param[out] emsg
+++ * @param[in,out] rsp state from librpz_itr_start()
+++ * @return false on error
+++ */
+++typedef bool (librpz_rsp_push_t)(librpz_emsg_t *emsg, librpz_rsp_t *rsp);
+++LIBDEF_F(rsp_push)
+++#define LIBRPZ_RSP_STACK_DEPTH 3
+++
+++/**
+++ * Restore the previous policy checking state.
+++ * @param[out] emsg
+++ * @param[out] result: NULL or restored policy rewrite values
+++ * @param[in,out] rsp state from librpz_itr_start()
+++ * @return false on error
+++ */
+++typedef bool (librpz_rsp_pop_t)(librpz_emsg_t *emsg, librpz_result_t *result,
+++ librpz_rsp_t *rsp);
+++LIBDEF_F(rsp_pop)
+++
+++/**
+++ * Discard the most recently save policy checking state.
+++ * @param[out] emsg
+++ * @param[out] result: NULL or restored policy rewrite values
+++ * @return false on error
+++ */
+++typedef bool (librpz_rsp_pop_discard_t)(librpz_emsg_t *emsg, librpz_rsp_t *rsp);
+++LIBDEF_F(rsp_pop_discard)
+++
+++/**
+++ * Disable a zone.
+++ * @param[out] emsg
+++ * @param znum
+++ * @param[in,out] rsp state from librpz_itr_start()
+++ * @return false on error
+++ */
+++typedef bool (librpz_rsp_forget_zone_t)(librpz_emsg_t *emsg,
+++ librpz_cznum_t znum, librpz_rsp_t *rsp);
+++LIBDEF_F(rsp_forget_zone)
+++
+++/**
+++ * Apply RPZ to an IP address.
+++ * @param[out] emsg
+++ * @param addr: address to check
+++ * @param ipv6: true for 16 byte IPv6 instead of 4 byte IPv4
+++ * @param trig LIBRPZ_TRIG_CLIENT_IP, LIBRPZ_TRIG_IP, or LIBRPZ_TRIG_NSIP
+++ * @param hit_id: caller chosen
+++ * @param recursed: recursion has been done
+++ * @param[in,out] rsp state from librpz_itr_start()
+++ * @return false on error
+++ */
+++typedef bool (librpz_ck_ip_t)(librpz_emsg_t *emsg,
+++ const void *addr, uint family,
+++ librpz_trig_t trig, librpz_result_id_t hit_id,
+++ bool recursed, librpz_rsp_t *rsp);
+++LIBDEF_F(ck_ip)
+++
+++/**
+++ * Apply RPZ to a wire-format domain.
+++ * @param[out] emsg
+++ * @param domain in wire format
+++ * @param domain_size
+++ * @param trig LIBRPZ_TRIG_QNAME or LIBRPZ_TRIG_NSDNAME
+++ * @param hit_id: caller chosen
+++ * @param recursed: recursion has been done
+++ * @param[in,out] rsp state from librpz_itr_start()
+++ * @return false on error
+++ */
+++typedef bool (librpz_ck_domain_t)(librpz_emsg_t *emsg,
+++ const uint8_t *domain, size_t domain_size,
+++ librpz_trig_t trig, librpz_result_id_t hit_id,
+++ bool recursed, librpz_rsp_t *rsp);
+++LIBDEF_F(ck_domain)
+++
+++/**
+++ * Ask dnsrpzd to refresh a zone.
+++ * @param[out] emsg error message
+++ * @param librpz_domain_t domain to refresh
+++ * @param client context
+++ * @return false after error
+++ */
+++typedef bool (librpz_zone_refresh_t)(librpz_emsg_t *emsg, const char *domain,
+++ librpz_rsp_t *rsp);
+++LIBDEF_F(zone_refresh)
+++
+++/**
+++ * Get a string describing the the databasse
+++ * @param license: include the license
+++ * @param cfiles: include the configuration file names
+++ * @param listens: include the local notify IP addresses
+++ * @param[out] emsg error message if the result is null
+++ * @param client context
+++ * @return malloc'ed string or NULL after error
+++ */
+++typedef char *(librpz_db_info_t)(librpz_emsg_t *emsg,
+++ bool license, bool cfiles, bool listens,
+++ librpz_rsp_t *rsp);
+++LIBDEF_F(db_info)
+++
+++/**
+++ * Start a context for listing the nodes and/or zones in the mapped file
+++ * @param[out] emsg: error message for false return or *rspp=NULL
+++ * @param[out[ rspp created context or NULL
+++ * @param client context
+++ * @return false after error
+++ */
+++typedef bool (librpz_itr_start_t)(librpz_emsg_t *emsg, librpz_rsp_t **rspp,
+++ librpz_client_t *client);
+++LIBDEF_F(itr_start)
+++
+++/**
+++ * Get mapped file memory allocation statistics.
+++ * @param[out] emsg: error message
+++ * @param rsp state from librpz_itr_start()
+++ * @return malloc'ed string or NULL after error
+++ */
+++typedef char *(librpz_mf_stats_t)(librpz_emsg_t *emsg, librpz_rsp_t *rsp);
+++LIBDEF_F(mf_stats)
+++
+++/**
+++ * Get versions currently used by clients.
+++ * @param[out] emsg: error message
+++ * @param[in,out] rsp: state from librpz_itr_start()
+++ * @return malloc'ed string or NULL after error
+++ */
+++typedef char *(librpz_vers_stats_t)(librpz_emsg_t *emsg, librpz_rsp_t *rsp);
+++LIBDEF_F(vers_stats)
+++
+++/**
+++ * Allocate a string describing the next zone or "" after the last zone.
+++ * @param[out] emsg
+++ * @param all_zones to list all instead of only requested zones
+++ * @param[in,out] rsp state from librpz_rsp_start()
+++ * @return malloc'ed string or NULL after error
+++ */
+++typedef char *(librpz_itr_zone_t)(librpz_emsg_t *emsg, bool all_zones,
+++ librpz_rsp_t *rsp);
+++LIBDEF_F(itr_zone)
+++
+++/**
+++ * Describe the next trie node while dumping the database.
+++ * @param[out] emsg
+++ * @param[out] result describes node
+++ * or result->policy=LIBRPZ_POLICY_UNDEFINED after the last node.
+++ * @param all_zones to list all instead of only requested zones
+++ * @param[in,out] rsp state from librpz_itr_start()
+++ * @return: false on error
+++ */
+++typedef bool (librpz_itr_node_t)(librpz_emsg_t *emsg, librpz_result_t *result,
+++ bool all_zones, librpz_rsp_t *rsp);
+++LIBDEF_F(itr_node)
+++
+++/**
+++ * RPZ policy to string with a backup buffer of POLICY2STR_SIZE size
+++ */
+++typedef const char *(librpz_policy2str_t)(librpz_policy_t policy,
+++ char *buf, size_t buf_size);
+++#define POLICY2STR_SIZE sizeof("policy xxxxxx")
+++LIBDEF_F(policy2str)
+++
+++/**
+++ * Trigger type to string.
+++ */
+++typedef const char *(librpz_trig2str_t)(librpz_trig_t trig);
+++LIBDEF_F(trig2str)
+++
+++/**
+++ * Convert a number of seconds to a zone file duration string
+++ */
+++typedef const char *(librpz_secs2str_t)(time_t secs,
+++ char *buf, size_t buf_size);
+++#define SECS2STR_SIZE sizeof("1234567w7d24h59m59s")
+++LIBDEF_F(secs2str)
+++
+++/**
+++ * Parse a duration with 's', 'm', 'h', 'd', and 'w' units.
+++ */
+++typedef bool (librpz_str2secs_t)(librpz_emsg_t *emsg, time_t *val,
+++ const char *str0);
+++LIBDEF_F(str2secs)
+++
+++/**
+++ * Translate selected rtypes to strings
+++ */
+++typedef const char *(librpz_rtype2str_t)(uint type, char *buf, size_t buf_size);
+++#define RTYPE2STR_SIZE sizeof("type xxxxx")
+++LIBDEF_F(rtype2str)
+++
+++/**
+++ * Local version of ns_name_ntop() for portability.
+++ */
+++typedef int (librpz_domain_ntop_t)(const u_char *src, char *dst, size_t dstsiz);
+++LIBDEF_F(domain_ntop)
+++
+++/**
+++ * Local version of ns_name_pton().
+++ */
+++typedef int (librpz_domain_pton2_t)(const char *src, u_char *dst, size_t dstsiz,
+++ size_t *dstlen, bool lower);
+++LIBDEF_F(domain_pton2)
+++
+++typedef union socku socku_t;
+++typedef socku_t *(librpz_mk_inet_su_t)(socku_t *su, const struct in_addr *addrp,
+++ in_port_t port);
+++LIBDEF_F(mk_inet_su)
+++
+++typedef socku_t *(librpz_mk_inet6_su_t)(socku_t *su, const
+++ struct in6_addr *addrp,
+++ uint32_t scope_id, in_port_t port);
+++LIBDEF_F(mk_inet6_su)
+++
+++typedef bool (librpz_str2su_t)(socku_t *sup, const char *str);
+++LIBDEF_F(str2su)
+++
+++typedef char *(librpz_su2str_t)(char *str, size_t str_len, const socku_t *su);
+++LIBDEF_F(su2str)
+++#define SU2STR_SIZE (INET6_ADDRSTRLEN+1+6+1)
+++
+++
+++/**
+++ * default path to dnsrpzd
+++ */
+++const char *librpz_dnsrpzd_path;
+++
+++
+++#undef LIBDEF
+++
+++/*
+++ * This is the dlopen() interface to librpz.
+++ */
+++typedef const struct {
+++ const char *dnsrpzd_path;
+++ const char *version;
+++ librpz_parse_log_opt_t *parse_log_opt;
+++ librpz_log_level_val_t *log_level_val;
+++ librpz_set_log_t *set_log;
+++ librpz_vpemsg_t *vpemsg;
+++ librpz_pemsg_t *pemsg;
+++ librpz_vlog_t *vlog;
+++ librpz_log_t *log;
+++ librpz_fatal_t *fatal LIBRPZ_NORET;
+++ librpz_rpz_assert_t *rpz_assert LIBRPZ_NORET;
+++ librpz_rpz_vassert_t *rpz_vassert LIBRPZ_NORET;
+++ librpz_clist_create_t *clist_create;
+++ librpz_clist_detach_t *clist_detach;
+++ librpz_client_create_t *client_create;
+++ librpz_connect_t *connect;
+++ librpz_client_detach_t *client_detach;
+++ librpz_rsp_create_t *rsp_create;
+++ librpz_rsp_detach_t *rsp_detach;
+++ librpz_rsp_result_t *rsp_result;
+++ librpz_have_trig_t *have_trig;
+++ librpz_have_ns_trig_t *have_ns_trig;
+++ librpz_rsp_clientip_prefix_t *rsp_clientip_prefix;
+++ librpz_rsp_domain_t *rsp_domain;
+++ librpz_rsp_rr_t *rsp_rr;
+++ librpz_rsp_soa_t *rsp_soa;
+++ librpz_soa_serial_t *soa_serial;
+++ librpz_rsp_push_t *rsp_push;
+++ librpz_rsp_pop_t *rsp_pop;
+++ librpz_rsp_pop_discard_t *rsp_pop_discard;
+++ librpz_rsp_forget_zone_t *rsp_forget_zone;
+++ librpz_ck_ip_t *ck_ip;
+++ librpz_ck_domain_t *ck_domain;
+++ librpz_zone_refresh_t *zone_refresh;
+++ librpz_db_info_t *db_info;
+++ librpz_itr_start_t *itr_start;
+++ librpz_mf_stats_t *mf_stats;
+++ librpz_vers_stats_t *vers_stats;
+++ librpz_itr_zone_t *itr_zone;
+++ librpz_itr_node_t *itr_node;
+++ librpz_policy2str_t *policy2str;
+++ librpz_trig2str_t *trig2str;
+++ librpz_secs2str_t *secs2str;
+++ librpz_str2secs_t *str2secs;
+++ librpz_rtype2str_t *rtype2str;
+++ librpz_domain_ntop_t *domain_ntop;
+++ librpz_domain_pton2_t *domain_pton2;
+++ librpz_mk_inet_su_t *mk_inet_su;
+++ librpz_mk_inet6_su_t *mk_inet6_su;
+++ librpz_str2su_t *str2su;
+++ librpz_su2str_t *su2str;
+++} librpz_0_t;
+++extern librpz_0_t librpz_def_0;
+++
+++/*
+++ * Future versions can be upward compatible by defining LIBRPZ_DEF as
+++ * librpz_X_t.
+++ */
+++#define LIBRPZ_DEF librpz_def_0
+++#define LIBRPZ_DEF_STR "librpz_def_0"
+++
+++typedef librpz_0_t librpz_t;
+++extern librpz_t *librpz;
+++
+++
+++#if LIBRPZ_LIB_OPEN == 2
+++#include <dlfcn.h>
+++
+++/**
+++ * link-load librpz
+++ * @param[out] emsg: error message
+++ * @param[in,out] dl_handle: NULL or pointer to new dlopen handle
+++ * @param[in] path: librpz.so path
+++ * @return address of interface structure or NULL on failure
+++ */
+++static inline librpz_t *
+++librpz_lib_open(librpz_emsg_t *emsg, void **dl_handle, const char *path)
+++{
+++ void *handle;
+++ librpz_t *new_librpz;
+++
+++ emsg->c[0] = '\0';
+++
+++ /*
+++ * Close a previously opened handle on librpz.so.
+++ */
+++ if (dl_handle != NULL && *dl_handle != NULL) {
+++ if (dlclose(*dl_handle) != 0) {
+++ snprintf(emsg->c, sizeof(librpz_emsg_t),
+++ "dlopen(NULL): %s", dlerror());
+++ return (NULL);
+++ }
+++ *dl_handle = NULL;
+++ }
+++
+++ /*
+++ * First try the main executable of the process in case it was
+++ * linked to librpz.
+++ * Do not worry if we cannot search the main executable of the process.
+++ */
+++ handle = dlopen(NULL, RTLD_NOW | RTLD_LOCAL);
+++ if (handle != NULL) {
+++ new_librpz = dlsym(handle, LIBRPZ_DEF_STR);
+++ if (new_librpz != NULL) {
+++ if (dl_handle != NULL)
+++ *dl_handle = handle;
+++ return (new_librpz);
+++ }
+++ if (dlclose(handle) != 0) {
+++ snprintf(emsg->c, sizeof(librpz_emsg_t),
+++ "dlsym(NULL, "LIBRPZ_DEF_STR"): %s",
+++ dlerror());
+++ return (NULL);
+++ }
+++ }
+++
+++ if (path == NULL || path[0] == '\0') {
+++ snprintf(emsg->c, sizeof(librpz_emsg_t),
+++ "librpz not linked and no dlopen() path provided");
+++ return (NULL);
+++ }
+++
+++ handle = dlopen(path, RTLD_NOW | RTLD_LOCAL);
+++ if (handle == NULL) {
+++ snprintf(emsg->c, sizeof(librpz_emsg_t), "dlopen(%s): %s",
+++ path, dlerror());
+++ return (NULL);
+++ }
+++ new_librpz = dlsym(handle, LIBRPZ_DEF_STR);
+++ if (new_librpz != NULL) {
+++ if (dl_handle != NULL)
+++ *dl_handle = handle;
+++ return (new_librpz);
+++ }
+++ snprintf(emsg->c, sizeof(librpz_emsg_t),
+++ "dlsym(%s, "LIBRPZ_DEF_STR"): %s",
+++ path, dlerror());
+++ dlclose(handle);
+++ return (NULL);
+++}
+++
+++#elif defined(LIBRPZ_LIB_OPEN)
+++
+++/*
+++ * Statically link to the librpz.so DSO on systems without dlopen()
+++ */
+++static inline librpz_t *
+++librpz_lib_open(librpz_emsg_t *emsg, void **dl_handle, const char *path)
+++{
+++ (void)(path);
+++
+++ if (dl_handle != NULL)
+++ *dl_handle = NULL;
+++
+++#if LIBRPZ_LIB_OPEN == 1
+++ emsg->c[0] = '\0';
+++ return (&LIBRPZ_DEF);
+++#else
+++ snprintf(emsg->c, sizeof(librpz_emsg_t),
+++ "librpz not available via ./configure");
+++ return (NULL);
+++#endif /* LIBRPZ_LIB_OPEN */
+++}
+++#endif /* LIBRPZ_LIB_OPEN */
+++
+++#endif /* LIBRPZ_H */
++diff --git a/fastrpz/rpz.c b/fastrpz/rpz.c
++new file mode 100644
++index 00000000..c5ab7801
++--- /dev/null
+++++ b/fastrpz/rpz.c
++@@ -0,0 +1,1352 @@
+++/*
+++ * fastrpz/rpz.c - interface to the fastrpz response policy zone library
+++ *
+++ * Optimize no-rewrite cases for speed but optimize rewriting for
+++ * simplicity and size.
+++ */
+++
+++#include "config.h"
+++
+++#ifdef ENABLE_FASTRPZ
+++#include "daemon/daemon.h"
+++#define LIBRPZ_LIB_OPEN FASTRPZ_LIB_OPEN
+++#include "fastrpz/rpz.h"
+++#include "daemon/worker.h"
+++#include "iterator/iter_delegpt.h"
+++#include "iterator/iter_utils.h"
+++#include "iterator/iterator.h"
+++#include "util/data/dname.h"
+++#include "util/data/msgencode.h"
+++#include "util/data/msgparse.h"
+++#include "util/data/msgreply.h"
+++#include "util/log.h"
+++#include "util/netevent.h"
+++#include "util/net_help.h"
+++#include "util/regional.h"
+++#include "util/storage/slabhash.h"
+++#include "services/cache/dns.h"
+++#include "services/cache/rrset.h"
+++#include "services/mesh.h"
+++#include "sldns/sbuffer.h"
+++#include "sldns/rrdef.h"
+++
+++
+++typedef enum state {
+++ /* No more rewriting */
+++ st_off = 1,
+++ /* Send SERVFAIL */
+++ st_servfail,
+++ /* No dispositive hit yet */
+++ st_unknown,
+++ /* Let the iterator resolve a CNAME or get a delegation point. */
+++ st_iterate,
+++ /* Let the iterator resolve NS to check NSIP or NSDNAME triggers. */
+++ st_ck_ns,
+++ /* We have an answer */
+++ st_rewritten,
+++} st_t;
+++
+++
+++/* RPZ state pointed to by struct comm_reply */
+++typedef struct commreply_rpz {
+++ /* librpz state */
+++ librpz_rsp_t* rsp;
+++ /* ID for log messages */
+++ int log_id;
+++
+++ /* from configuration */
+++ int min_ns_dots;
+++
+++ /* Running in the iterator */
+++ bool iterating;
+++
+++ /* current and previous state and librpz result */
+++ st_t st;
+++ st_t saved_st[LIBRPZ_RSP_STACK_DEPTH-1];
+++ librpz_result_t result;
+++
+++ /* Stop adding CNAMEs to the prepend list before this owner name. */
+++ librpz_domain_buf_t cname_hit;
+++ /* It is not the first CNAME */
+++ bool cname_hit_2nd;
+++ librpz_result_id_t hit_id;
+++} commreply_rpz_t;
+++
+++
+++/* Generate an ID for log messages. */
+++static int log_id;
+++
+++librpz_t *librpz;
+++
+++
+++static void LIBRPZ_NORET
+++rpz_assert(const char *s)
+++{
+++ fatal_exit("%s", s);
+++ exit(1);
+++}
+++#define RPZ_ASSERT(c) ((c) ? (void)0 : rpz_assert(#c), (void)0)
+++
+++/*
+++ * librpz client handle locking
+++ */
+++static void
+++lock_destroy(void* mutex)
+++{
+++ lock_basic_destroy(mutex);
+++ free(mutex);
+++}
+++
+++static void
+++lock(void* mutex)
+++{
+++ lock_basic_lock(mutex);
+++}
+++
+++static void
+++unlock(void* mutex)
+++{
+++ lock_basic_unlock(mutex);
+++}
+++
+++
+++static void
+++log_fnc(librpz_log_level_t level, void* ATTR_UNUSED(ctx), const char* buf)
+++{
+++ /* Setting librpz_log_level overrides the unbound "verbose" level. */
+++ if(level > LIBRPZ_LOG_TRACE1 &&
+++ level <= librpz->log_level_val(LIBRPZ_LOG_INVALID))
+++ level = LIBRPZ_LOG_TRACE1;
+++
+++ switch(level) {
+++ case LIBRPZ_LOG_FATAL:
+++ case LIBRPZ_LOG_ERROR: /* errors */
+++ default:
+++ log_err("rpz: %s", buf);
+++ break;
+++
+++ case LIBRPZ_LOG_TRACE1: /* big events such as dnsrpzd starts */
+++ verbose(VERB_OPS, "rpz: %s", buf);
+++ break;
+++
+++ case LIBRPZ_LOG_TRACE2: /* smaller dnsrpzd zone transfers */
+++ verbose(VERB_DETAIL, "rpz: %s", buf);
+++ break;
+++
+++ case LIBRPZ_LOG_TRACE3: /* librpz hits */
+++ verbose(VERB_QUERY, "rpz: %s", buf);
+++ break;
+++
+++ case LIBRPZ_LOG_TRACE4: /* librpz lookups */
+++ verbose(VERB_CLIENT, "rpz: %s", buf);
+++ break;
+++ }
+++}
+++
+++
+++/* Release the librpz version. */
+++static void
+++rpz_off(commreply_rpz_t* rpz, st_t st)
+++{
+++ if(!rpz)
+++ return;
+++ rpz->st = st;
+++ librpz->rsp_detach(&rpz->rsp);
+++}
+++
+++
+++static void LIBRPZ_PF(2,3)
+++log_fail(commreply_rpz_t* rpz, const char* p, ...)
+++{
+++ va_list args;
+++
+++ if(rpz->st == st_servfail)
+++ return;
+++
+++ va_start(args, p);
+++ librpz->vlog(LIBRPZ_LOG_ERROR, rpz, p, args);
+++ va_end(args);
+++ if(!rpz)
+++ return;
+++ rpz_off(rpz, st_servfail);
+++}
+++
+++
+++/* Announce a rewrite. */
+++static void
+++log_rewrite(uint8_t* qname, librpz_policy_t policy, const char* msg,
+++ commreply_rpz_t* rpz)
+++{
+++ char policy_buf[POLICY2STR_SIZE];
+++ char qname_nm[LDNS_MAX_DOMAINLEN+1];
+++ librpz_domain_buf_t tdomain;
+++ char tdomain_nm[LDNS_MAX_DOMAINLEN+1];
+++ librpz_emsg_t emsg;
+++
+++ if(rpz->st == st_servfail || !rpz->result.log)
+++ return;
+++ if(librpz->log_level_val(LIBRPZ_LOG_INVALID) < LIBRPZ_LOG_TRACE1)
+++ return;
+++
+++ dname_str(qname, qname_nm);
+++
+++ if(!librpz->rsp_domain(&emsg, &tdomain, rpz->rsp)) {
+++ librpz->log(LIBRPZ_LOG_ERROR, rpz, "%s", emsg.c);
+++ return;
+++ }
+++ dname_str(tdomain.d, tdomain_nm);
+++
+++ librpz->log(LIBRPZ_LOG_TRACE3, rpz, "%srewriting %s via %s %s to %s",
+++ msg, qname_nm, tdomain_nm,
+++ librpz->trig2str(rpz->result.trig),
+++ librpz->policy2str(policy, policy_buf,
+++ sizeof(policy_buf)));
+++}
+++
+++
+++/* Connect to and start dnsrpzd if necessary for the unbound daemon.
+++ * Require "rpz-conf: path" to specify the rpz configuration file.
+++ * The unbound server directory name is the default rpz working
+++ * directory. If unbound uses chroot, then the dnsrpzd working
+++ * directory must be in the chroot tree.
+++ * The database and socket are closed and re-opened.
+++ */
+++void
+++rpz_init(librpz_clist_t** pclist, librpz_client_t** pclient,
+++ const struct config_file* cfg)
+++{
+++ lock_basic_type* mutex;
+++ librpz_emsg_t emsg;
+++
+++ if(!librpz) {
+++ librpz = librpz_lib_open(&emsg, NULL, FASTRPZ_LIBRPZ_PATH);
+++ if(!librpz)
+++ fatal_exit("rpz: %s", emsg.c);
+++ }
+++
+++ librpz->set_log(&log_fnc, NULL);
+++
+++ if(!cfg->rpz_cstr)
+++ fatal_exit("rpz: rpz-zone: not set");
+++
+++ librpz->client_detach(pclient);
+++ librpz->clist_detach(pclist);
+++
+++ mutex = malloc(sizeof(*mutex));
+++ if(!mutex)
+++ fatal_exit("rpz: no memory for lock");
+++ lock_basic_init(mutex);
+++
+++ *pclist = librpz->clist_create(&emsg, &lock, &unlock, &lock_destroy,
+++ mutex, NULL);
+++ if(!pclist)
+++ fatal_exit("rpz: %s", emsg.c);
+++
+++ *pclient = librpz->client_create(&emsg, *pclist, cfg->rpz_cstr, false);
+++ if(!*pclient)
+++ fatal_exit("rpz: %s", emsg.c);
+++
+++ if(!librpz->connect(&emsg, *pclient, true))
+++ fatal_exit("rpz: %s", emsg.c);
+++
+++ verbose(VERB_OPS, "rpz: librpz version %s", librpz->version);
+++}
+++
+++
+++/* Stop using librpz on behalf of a worker thread. */
+++void
+++rpz_delete(librpz_clist_t** pclist, librpz_client_t** pclient)
+++{
+++ if(librpz) {
+++ librpz->client_detach(pclient);
+++ librpz->clist_detach(pclist);
+++ }
+++}
+++
+++
+++/* Release the librpz resources held for a DNS client request. */
+++void
+++rpz_end(struct comm_reply* commreply)
+++{
+++ if(!commreply->rpz)
+++ return;
+++ rpz_off(commreply->rpz, commreply->rpz->st);
+++ free(commreply->rpz);
+++ commreply->rpz = NULL;
+++}
+++
+++
+++static bool
+++push_st(commreply_rpz_t* rpz)
+++{
+++ librpz_emsg_t emsg;
+++
+++ if(rpz->st == st_off || rpz->st == st_servfail) {
+++ librpz->log(LIBRPZ_LOG_ERROR, rpz,
+++ "state %d in push_st()", rpz->st);
+++ return false;
+++ }
+++ if(!librpz->rsp_push(&emsg, rpz->rsp))
+++ log_fail(rpz, "%s", emsg.c);
+++ memmove(&rpz->saved_st[1], &rpz->saved_st[0],
+++ sizeof(rpz->saved_st) - sizeof(rpz->saved_st[0]));
+++ rpz->saved_st[0] = rpz->st;
+++ return rpz->st != st_servfail;
+++}
+++
+++
+++static bool
+++pop_st(commreply_rpz_t* rpz)
+++{
+++ librpz_emsg_t emsg;
+++
+++ if(rpz->rsp && !librpz->rsp_pop(&emsg, &rpz->result, rpz->rsp))
+++ log_fail(rpz, "%s", emsg.c);
+++ if(rpz->st != st_servfail)
+++ rpz->st = rpz->saved_st[0];
+++ memmove(&rpz->saved_st[0], &rpz->saved_st[1],
+++ sizeof(rpz->saved_st) - sizeof(rpz->saved_st[0]));
+++ return rpz->st != st_servfail;
+++}
+++
+++static bool
+++pop_discard_st(commreply_rpz_t* rpz)
+++{
+++ librpz_emsg_t emsg;
+++
+++ if(rpz->rsp && !librpz->rsp_pop_discard(&emsg, rpz->rsp))
+++ log_fail(rpz, "%s", emsg.c);
+++ memmove(&rpz->saved_st[0], &rpz->saved_st[1],
+++ sizeof(rpz->saved_st) - sizeof(rpz->saved_st[0]));
+++ return rpz->st != st_servfail;
+++}
+++
+++/* Check a rewrite attempt for errors and a disabled zone. */
+++static bool /* true=repeat the check */
+++ck_after(uint8_t* qname, bool recursed, librpz_trig_t trig,
+++ commreply_rpz_t* rpz)
+++{
+++ librpz_emsg_t emsg;
+++
+++ if(rpz->st == st_servfail)
+++ return false;
+++
+++ if(!librpz->rsp_result(&emsg, &rpz->result, recursed, rpz->rsp)) {
+++ log_fail(rpz, "%s", emsg.c);
+++ return false;
+++ }
+++
+++ if(rpz->result.policy == LIBRPZ_POLICY_DISABLED) {
+++ /* Log the hit on the disabled zone, do not try the zone again,
+++ * and restore the state from before the check to forget the hit
+++ * before trying again. */
+++ log_rewrite(qname, rpz->result.zpolicy, "disabled ", rpz);
+++ if(!librpz->rsp_forget_zone(&emsg, rpz->result.cznum, rpz->rsp))
+++ log_fail(rpz, "%s", emsg.c);
+++ return pop_st(rpz);
+++ }
+++
+++ /* Complain about and forget client-IP address hit that is not
+++ * dispositive. Client-IP triggers have the highest priority
+++ * within a policy zone, but can be overridden by any hit in a policy
+++ * earlier in the client's (resolver's) list of zones, including
+++ * policies that cannot be hit until after recursion. If we allowed
+++ * client-IP triggers in secondary zones, then than two DNS requests
+++ * that differ only in DNS client-IP addresses could properly
+++ * have differing results. The Unbound iterator treats identical
+++ * DNS requests the same regardless of DNS client-IP address.
+++ * struct query_info would need to be modified to have an optional
+++ * librpz_prefix_t containing the prefix of the client-IP address hit
+++ * from librpz->rsp_clientip_prefix(). Adding to struct query_info
+++ * would require finding and changing the many and obscure places
+++ * including the Unbound tests to memset(0) the struct query_info
+++ * that they create. */
+++ if(trig == LIBRPZ_TRIG_CLIENT_IP) {
+++ if(rpz->result.cznum != 0) {
+++ log_rewrite(qname, rpz->result.policy,
+++ "ignore secondary ", rpz);
+++ if(!pop_st(rpz))
+++ log_fail(rpz, "%s", emsg.c);
+++ return (false);
+++ }
+++ }
+++
+++ /* Forget the state from before the check and keep the new state
+++ * if we do not have a hit on a disabled policy zone. */
+++ pop_discard_st(rpz);
+++ return false;
+++}
+++
+++
+++/* Get the next RR from the policy record. */
+++static bool
+++next_rr(librpz_rr_t** rrp, const uint8_t* qname, size_t qname_len,
+++ commreply_rpz_t* rpz)
+++{
+++ librpz_emsg_t emsg;
+++
+++ if(!librpz->rsp_rr(&emsg, NULL, NULL, NULL, rrp, &rpz->result,
+++ qname, qname_len, rpz->rsp)) {
+++ log_fail(rpz, "%s", emsg.c);
+++ *rrp = NULL;
+++ return false;
+++ }
+++ return true;
+++}
+++
+++
+++static bool /* false=fatal error to be logged */
+++add_rr(struct sldns_buffer* pkt, const uint8_t* owner, size_t owner_len,
+++ librpz_rr_t* rr, commreply_rpz_t* rpz)
+++{
+++ size_t rdlength;
+++
+++ rdlength = ntohs(rr->rdlength);
+++
+++ if(!sldns_buffer_available(pkt, owner_len + 10 + rdlength)) {
+++ log_fail(rpz, "comm_reply buffer exhausted");
+++ free(rr);
+++ return false;
+++ }
+++ sldns_buffer_write(pkt, owner, owner_len);
+++ /* sizeof(librpz_rr_t)=12 instead of 10 */
+++ sldns_buffer_write(pkt, rr, 10 + rdlength);
+++ return true;
+++}
+++
+++
+++/* Convert a fake incoming DNS message to an Unbound struct dns_msg */
+++static void
+++pkt2dns_msg(struct dns_msg** dnsmsg, struct sldns_buffer* pkt,
+++ commreply_rpz_t* rpz, struct regional* region)
+++{
+++ struct msg_parse* msgparse;
+++
+++ msgparse = regional_alloc(region, sizeof(*msgparse));
+++ if(!msgparse) {
+++ log_fail(rpz, "out of memory for msgparse");
+++ *dnsmsg = NULL;
+++ return;
+++ }
+++ memset(msgparse, 0, sizeof(*msgparse));
+++ if(parse_packet(pkt, msgparse, region) != LDNS_RCODE_NOERROR) {
+++ log_fail(rpz, "packet parse error");
+++ *dnsmsg = NULL;
+++ return;
+++ }
+++ *dnsmsg = dns_alloc_msg(pkt, msgparse, region);
+++ if(!*dnsmsg) {
+++ log_fail(rpz, "dns_alloc_msg() failed");
+++ *dnsmsg = NULL;
+++ return;
+++ }
+++ (*dnsmsg)->rep->security = sec_status_rpz_rewritten;
+++}
+++
+++
+++static bool /* false=SERVFAIL */
+++ck_ip_rrset(const void* vdata, int family, librpz_trig_t trig,
+++ uint8_t* qname, commreply_rpz_t* rpz)
+++{
+++ const struct packed_rrset_data* data;
+++ uint rr_n;
+++ size_t len;
+++ librpz_emsg_t emsg;
+++
+++ data = vdata;
+++
+++ /* Loop to ignore disabled zones. */
+++ do {
+++ if(!push_st(rpz))
+++ return false;
+++ for(rr_n = 0; rr_n < data->count; ++rr_n) {
+++ len = data->rr_len[rr_n];
+++ /* Skip bogus including negative placeholding rdata. */
+++ if((family == AF_INET &&
+++ len != sizeof(struct in_addr)+2) ||
+++ (family == AF_INET6 &&
+++ len != sizeof(struct in6_addr)+2))
+++ continue;
+++ if(!librpz->ck_ip(&emsg, data->rr_data[rr_n]+2,
+++ family, trig, rpz->hit_id, true,
+++ rpz->rsp)) {
+++ log_fail(rpz, "%s", emsg.c);
+++ return false;
+++ }
+++ }
+++ } while(ck_after(qname, true, trig, rpz));
+++ return rpz->st != st_servfail;
+++}
+++
+++
+++static bool /* false=SERVFAIL */
+++ck_dname(uint8_t* dname, size_t dname_size, librpz_trig_t trig,
+++ uint8_t* qname, bool recursed, commreply_rpz_t* rpz)
+++{
+++ librpz_emsg_t emsg;
+++
+++ /* Refuse to check the root. */
+++ if(dname_is_root(dname))
+++ return rpz->st != st_servfail;
+++
+++ /* Loop to ignore disabled zones. */
+++ do {
+++ if(!push_st(rpz))
+++ return false;
+++ if(!librpz->ck_domain(&emsg, dname, dname_size, trig,
+++ rpz->hit_id, recursed, rpz->rsp)) {
+++ log_fail(rpz, "%s", emsg.c);
+++ return false;
+++ }
+++ } while(ck_after(qname, recursed, trig, rpz));
+++
+++ return rpz->st != st_servfail;
+++}
+++
+++
+++/* Check the IPv4 or IPv6 addresses for one NS name. */
+++static bool /* false=st_servfail */
+++ck_1nsip(uint8_t* nsname, size_t nsname_size, int family, int qtype,
+++ bool* have_ns, commreply_rpz_t* rpz, struct module_env* env)
+++{
+++ struct ub_packed_rrset_key* akey;
+++
+++ akey = rrset_cache_lookup(env->rrset_cache, nsname, nsname_size,
+++ qtype, LDNS_RR_CLASS_IN, 0, 0, 0);
+++ if(akey) {
+++ *have_ns = true;
+++
+++ if(!ck_ip_rrset(akey->entry.data, family, LIBRPZ_TRIG_NSIP,
+++ nsname, rpz)) {
+++ lock_rw_unlock(&akey->entry.lock);
+++ return false;
+++ }
+++ lock_rw_unlock(&akey->entry.lock);
+++ }
+++ return true;
+++}
+++
+++
+++static bool /* false=st_servfail */
+++ck_qname(uint8_t* qname, size_t qname_len,
+++ bool recursed, /* recursion done */
+++ bool wait_ns, /* willing to iterate for NS data */
+++ commreply_rpz_t* rpz, struct module_env* env)
+++{
+++ uint8_t* dname;
+++ size_t dname_size;
+++ int cur_lab;
+++ struct ub_packed_rrset_key* nskey;
+++ const struct packed_rrset_data* nsdata;
+++ uint8_t* nsname;
+++ size_t nsname_size;
+++ uint rr_n;
+++ bool have_ns, tried_ns;
+++
+++ if(!ck_dname(qname, qname_len, LIBRPZ_TRIG_QNAME, qname, false, rpz))
+++ return false;
+++
+++ /* Do not waste time looking for NSDNAME and NSIP hits when there
+++ * are no currently relevant triggers. */
+++ if(!librpz->have_ns_trig(rpz->rsp))
+++ return true;
+++
+++ have_ns = false;
+++ tried_ns = false;
+++ dname = qname;
+++ dname_size = qname_len;
+++ for(cur_lab = dname_count_labels(dname) - 2;
+++ cur_lab > rpz->min_ns_dots;
+++ --cur_lab) {
+++ tried_ns = true;
+++ dname_remove_label(&dname, &dname_size);
+++ nskey = rrset_cache_lookup(env->rrset_cache, dname, dname_size,
+++ LDNS_RR_TYPE_NS, LDNS_RR_CLASS_IN,
+++ 0, 0, 0);
+++ if(!nskey)
+++ continue;
+++
+++ nsdata = (const struct packed_rrset_data*)nskey->entry.data;
+++ for(rr_n = 0;
+++ rr_n < nsdata->count && rpz->st == st_unknown;
+++ ++rr_n) {
+++ nsname = nsdata->rr_data[rr_n]+2;
+++ nsname_size = nsdata->rr_len[rr_n];
+++ if(nsname_size <= 2)
+++ continue;
+++ nsname_size -= 2;
+++ if(!ck_dname(nsname, nsname_size, LIBRPZ_TRIG_NSDNAME,
+++ qname, recursed, rpz))
+++ return false;
+++ if(!ck_1nsip(nsname, nsname_size, AF_INET,
+++ LDNS_RR_TYPE_A, &have_ns, rpz, env))
+++ return false;
+++ if(!ck_1nsip(nsname, nsname_size, AF_INET6,
+++ LDNS_RR_TYPE_AAAA, &have_ns, rpz, env))
+++ return false;
+++ }
+++ lock_rw_unlock(&nskey->entry.lock);
+++ }
+++
+++ /* If we failed to find NS records, then stop building the response
+++ * before a CNAME with this owner name. */
+++ if(!have_ns && tried_ns && (!recursed || wait_ns)) {
+++ rpz->cname_hit.size = qname_len;
+++ RPZ_ASSERT(rpz->cname_hit.size <= sizeof(rpz->cname_hit.d));
+++ memcpy(rpz->cname_hit.d, qname, qname_len);
+++ rpz->result.hit_id = rpz->hit_id;
+++ rpz->st = st_ck_ns;
+++ }
+++ return true;
+++}
+++
+++
+++/*
+++ * Are we ready to rewrite the response?
+++ */
+++static bool /* true=send rewritten response */
+++ck_result(uint8_t* qname, bool recursed,
+++ commreply_rpz_t* rpz, const struct comm_point* commpoint)
+++{
+++ librpz_emsg_t emsg;
+++
+++ switch(rpz->st) {
+++ case st_off:
+++ case st_servfail:
+++ case st_rewritten:
+++ return false;
+++ case st_unknown:
+++ break;
+++ case st_iterate:
+++ return false;
+++ case st_ck_ns:
+++ /* An NSDNAME or NSIP check failed for lack of cached data. */
+++ return false;
+++ default:
+++ fatal_exit("impossible RPZ state %d in rpz_worker_cache()",
+++ rpz->st);
+++ }
+++
+++ /* Wait for a trigger. */
+++ if(rpz->result.policy == LIBRPZ_POLICY_UNDEFINED) {
+++ if(recursed &&
+++ rpz->result.zpolicy != LIBRPZ_POLICY_UNDEFINED &&
+++ !librpz->rsp_result(&emsg, &rpz->result, true, rpz->rsp)) {
+++ log_fail(rpz, "%s", emsg.c);
+++ return false;
+++ }
+++ if(rpz->result.policy == LIBRPZ_POLICY_UNDEFINED)
+++ return false;
+++ }
+++
+++ if(rpz->result.policy == LIBRPZ_POLICY_PASSTHRU) {
+++ log_rewrite(qname, rpz->result.policy, "", rpz);
+++ rpz_off(rpz, st_off);
+++ return false;
+++ }
+++
+++ /* The TCP-only policy answers UDP requests with truncated responses. */
+++ if(rpz->result.policy == LIBRPZ_POLICY_TCP_ONLY &&
+++ commpoint->type == comm_tcp) {
+++ rpz_off(rpz, st_off);
+++ return false;
+++ }
+++
+++ return true;
+++}
+++
+++
+++/*
+++ * Convert an RPZ hit to a struct dns_msg
+++ */
+++static void
+++get_result_msg(struct dns_msg** dnsmsg, struct query_info* qinfo,
+++ uint16_t id, uint16_t flags, bool recursed, commreply_rpz_t* rpz,
+++ struct comm_point* commpoint, struct regional* region)
+++{
+++ librpz_rr_t* rr;
+++ librpz_domain_buf_t origin;
+++ struct sldns_buffer* pkt;
+++ uint16_t num_rrs;
+++ librpz_emsg_t emsg;
+++
+++ *dnsmsg = NULL;
+++ if(!ck_result(qinfo->qname, recursed, rpz, commpoint))
+++ return;
+++
+++ rpz->st = st_rewritten;
+++
+++ if(rpz->result.policy == LIBRPZ_POLICY_DROP) {
+++ log_rewrite(qinfo->qname, rpz->result.policy, "", rpz);
+++ /* Make a fake cached message to carry
+++ * sec_status_rpz_drop and be dropped. */
+++ error_encode(commpoint->buffer, LDNS_RCODE_NOERROR,
+++ qinfo, id, flags, NULL);
+++ pkt2dns_msg(dnsmsg, commpoint->buffer, rpz, region);
+++ (*dnsmsg)->rep->security = sec_status_rpz_drop;
+++ return;
+++ }
+++
+++ /* Create a DNS message of the RPZ data.
+++ * In many cases that message could be sent directly to the DNS client,
+++ * but sometimes iteration must be used to resolve a CNAME.
+++ * This need not be fast, because rewriting responses should be rare.
+++ * Therefore, use the simpler but slower tactic of generating a
+++ * parsed version of the message. */
+++
+++ flags &= ~BIT_AA;
+++ flags |= BIT_QR | BIT_RA;
+++ rr = NULL;
+++
+++ /* The TCP-only policy answers UDP requests with truncated responses. */
+++ if(rpz->result.policy == LIBRPZ_POLICY_TCP_ONLY) {
+++ flags |= BIT_TC;
+++
+++ } else if(rpz->result.policy == LIBRPZ_POLICY_NXDOMAIN) {
+++ flags |= LDNS_RCODE_NXDOMAIN;
+++
+++ } else if(rpz->result.policy == LIBRPZ_POLICY_CNAME) {
+++ if(!rpz->iterating &&
+++ qinfo->qtype != LDNS_RR_TYPE_CNAME) {
+++ /* The new DNS message would be a CNAME and
+++ * the external request was not for a CNAME.
+++ * The worker must punt to the iterator so that
+++ * the iterator can resolve the CNAME. */
+++ rpz->st = st_iterate;
+++ return;
+++ }
+++ next_rr(&rr, qinfo->qname, qinfo->qname_len, rpz);
+++
+++ } else if(rpz->result.policy == LIBRPZ_POLICY_RECORD ||
+++ rpz->result.policy == LIBRPZ_POLICY_NODATA) {
+++ next_rr(&rr, qinfo->qname, qinfo->qname_len, rpz);
+++ /* Punt to the iterator if the new DNS message would
+++ * be a CNAME that must be resolved. */
+++ if(!rpz->iterating &&
+++ qinfo->qtype != LDNS_RR_TYPE_CNAME &&
+++ rr && rr->type == ntohs(LDNS_RR_TYPE_CNAME)) {
+++ free(rr);
+++ rpz->st = st_iterate;
+++ return;
+++ }
+++ }
+++ log_rewrite(qinfo->qname, rpz->result.policy, "", rpz);
+++
+++ /* Make a buffer containing a DNS message with the RPZ data. */
+++ pkt = commpoint->buffer;
+++ sldns_buffer_clear(pkt);
+++ if(sldns_buffer_remaining(pkt) < LDNS_HEADER_SIZE) {
+++ log_fail(rpz, "comm_reply buffer too small for header");
+++ if(rr)
+++ free(rr);
+++ return;
+++ }
+++
+++ /* Install ID, flags, QDCOUNT=1, ANCOUNT=# of RPZ RRs, NSCOUNT=0,
+++ * and ARCOUNT=1 for the RPZ SOA. */
+++ sldns_buffer_write_u16(pkt, id);
+++ sldns_buffer_write_u16(pkt, flags);
+++ sldns_buffer_write_u16(pkt, 1); /* QDCOUNT */
+++ sldns_buffer_write_u16(pkt, 0); /* ANCOUNT will be set later */
+++ sldns_buffer_write_u16(pkt, 0); /* NSCOUNT */
+++ sldns_buffer_write_u16(pkt, 1); /* ARCOUNT */
+++
+++ /* Install the question with the LDNS_RR_CLASS_RPZ bit to
+++ * to distinguish this supposed cache entry from the real deal. */
+++ sldns_buffer_write(pkt, qinfo->qname, qinfo->qname_len);
+++ sldns_buffer_write_u16(pkt, qinfo->qtype);
+++ sldns_buffer_write_u16(pkt, LDNS_RR_CLASS_IN);
+++
+++ /* Install the RPZ RRs in the answer section */
+++ num_rrs = 0;
+++ while(rr) {
+++ /* Include only the requested RRs. */
+++ if(qinfo->qtype == LDNS_RR_TYPE_ANY ||
+++ rr->type == htons(qinfo->qtype) ||
+++ rr->type == htons(LDNS_RR_TYPE_CNAME)) {
+++ if(!add_rr(pkt, qinfo->qname, qinfo->qname_len,
+++ rr, rpz))
+++ return;
+++
+++ ++num_rrs;
+++ }
+++ free(rr);
+++
+++ next_rr(&rr, qinfo->qname, qinfo->qname_len, rpz);
+++ }
+++ /* Finish ANCOUNT. */
+++ if(num_rrs != 0)
+++ sldns_buffer_write_u16_at(pkt, 6, num_rrs);
+++
+++ /* All rewritten responses have an identifying SOA record in the
+++ * additional section. */
+++ if(!librpz->rsp_soa(&emsg, NULL, &rr, &origin,
+++ &rpz->result, rpz->rsp)) {
+++ log_fail(rpz, "no soa");
+++ return;
+++ }
+++ if(!add_rr(pkt, origin.d, origin.size, rr, rpz))
+++ return;
+++ free(rr);
+++
+++ /* Create a dns_msg representation of the fake incoming message. */
+++ sldns_buffer_flip(pkt);
+++ pkt2dns_msg(dnsmsg, pkt, rpz, region);
+++}
+++
+++
+++/* Check the RRs in the ANSWER section of a reply_info. */
+++static void
+++ck_reply(struct reply_info* reply, uint8_t* qname, bool wait_ns,
+++ commreply_rpz_t* rpz, struct module_env* env)
+++{
+++ struct ub_packed_rrset_key* rrset;
+++ enum sldns_enum_rr_type type;
+++ uint rrset_n;
+++
+++ /* Check the RRs in the ANSWER section. */
+++ rpz->cname_hit.size = 0;
+++ rpz->cname_hit_2nd = false;
+++ for(rrset_n = 0; rrset_n < reply->an_numrrsets; ++rrset_n) {
+++ /* Check all of the RRs before deciding. */
+++ if(rpz->st != st_unknown)
+++ return;
+++
+++ rrset = reply->rrsets[rrset_n];
+++ if(ntohs(rrset->rk.rrset_class) != LDNS_RR_CLASS_IN)
+++ continue;
+++ type = ntohs(rrset->rk.type);
+++
+++ if(type == LDNS_RR_TYPE_A) {
+++ if(!ck_ip_rrset(rrset->entry.data, AF_INET,
+++ LIBRPZ_TRIG_IP, qname, rpz))
+++ break;
+++
+++ } else if(type == LDNS_RR_TYPE_AAAA) {
+++ if(!ck_ip_rrset(rrset->entry.data, AF_INET6,
+++ LIBRPZ_TRIG_IP, qname, rpz))
+++ break;
+++
+++ } else if(type == LDNS_RR_TYPE_CNAME) {
+++ /* Check CNAME owners unless we already have a hit. */
+++ ++rpz->hit_id;
+++ if(!ck_qname(rrset->rk.dname, rrset->rk.dname_len,
+++ true, wait_ns, rpz, env))
+++ break;
+++
+++ /* Do not worry about the CNAME if it did not hit,
+++ * but note the miss so that it can be prepended
+++ * if we do hit. */
+++ if(rpz->result.hit_id != rpz->hit_id) {
+++ rpz->cname_hit_2nd = true;
+++ continue;
+++ }
+++
+++ /* Stop after hitting a CNAME.
+++ * The iterator must be used to include CNAMEs before
+++ * the CNAME that hit in the rewritten response. */
+++ rpz->cname_hit.size = rrset->rk.dname_len;
+++ RPZ_ASSERT(rpz->cname_hit.size <= sizeof(rpz->cname_hit.d));
+++ memcpy(rpz->cname_hit.d, rrset->rk.dname,
+++ rpz->cname_hit.size);
+++ break;
+++ }
+++ }
+++}
+++
+++
+++static void
+++worker_servfail(struct worker* worker, struct query_info* qinfo,
+++ uint16_t id, uint16_t flags, struct comm_reply* commreply)
+++{
+++ error_encode(commreply->c->buffer, LDNS_RCODE_SERVFAIL,
+++ qinfo, id, flags, NULL);
+++ regional_free_all(worker->scratchpad);
+++ comm_point_send_reply(commreply);
+++}
+++
+++
+++/* Send an RPZ answer before the iterator has started.
+++ * @return: 1=continue normal unbound processing
+++ * 0=punt to the iterator
+++ * -1=rewritten response already sent or dropped. */
+++static int
+++worker_send(struct dns_msg* dnsmsg, struct worker* worker,
+++ struct query_info* qinfo, uint16_t id, uint16_t flags,
+++ struct edns_data* edns, struct comm_reply* commreply)
+++{
+++ switch (commreply->rpz->st) {
+++ case st_off:
+++ return 1;
+++ case st_servfail:
+++ worker_servfail(worker, qinfo, id, flags, commreply);
+++ return -1;
+++ case st_unknown:
+++ return 1;
+++ case st_iterate:
+++ case st_ck_ns:
+++ return 0; /* punt to the iterator */
+++ case st_rewritten:
+++ break;
+++ default:
+++ fatal_exit("impossible RPZ state %d in worker_send()",
+++ commreply->rpz->st);
+++ }
+++
+++ if(dnsmsg->rep->security == sec_status_rpz_drop) {
+++ regional_free_all(worker->scratchpad);
+++ comm_point_drop_reply(commreply);
+++ return -1;
+++ }
+++
+++ edns->edns_version = EDNS_ADVERTISED_VERSION;
+++ edns->udp_size = EDNS_ADVERTISED_SIZE;
+++ edns->ext_rcode = 0;
+++ edns->bits = 0; /* rewritten response cannot verify. */
+++ if(!reply_info_answer_encode(qinfo, dnsmsg->rep,
+++ id, flags | BIT_QR,
+++ commreply->c->buffer, 0, 1,
+++ worker->scratchpad,
+++ edns->udp_size, edns, 0, 0)) {
+++ worker_servfail(worker, qinfo, id, flags, commreply);
+++ } else {
+++ regional_free_all(worker->scratchpad);
+++ comm_point_send_reply(commreply);
+++ }
+++ return -1;
+++}
+++
+++
+++/* Set commreply to an RPZ context if the response might be rewritten.
+++ * Try to answer now with a hit allowed before recursion (iteration). */
+++bool /* true=response sent or dropped */
+++rpz_start(struct worker* worker, struct query_info* qinfo,
+++ struct comm_reply* commreply, struct edns_data* edns)
+++{
+++ commreply_rpz_t* rpz;
+++ uint16_t id, flags;
+++ struct dns_msg* dnsmsg;
+++ int family;
+++ const void* addr;
+++ librpz_emsg_t emsg;
+++
+++ /* Quit if rpz not configured. */
+++ if(!worker->daemon->rpz_client)
+++ return false;
+++
+++ /* Rewrite only the Internet class */
+++ if(qinfo->qclass != LDNS_RR_CLASS_IN)
+++ return false;
+++
+++ rpz = commreply->rpz;
+++ RPZ_ASSERT(!rpz);
+++
+++ dnsmsg = NULL;
+++ id = htons(sldns_buffer_read_u16_at(commreply->c->buffer, 0));
+++ flags = sldns_buffer_read_u16_at(commreply->c->buffer, 2);
+++
+++ rpz = malloc(sizeof(*rpz));
+++ if(!rpz) {
+++ librpz->log(LIBRPZ_LOG_ERROR, NULL, "no memory for rpz");
+++ return 0 > worker_send(dnsmsg, worker, qinfo,
+++ id, flags, edns, commreply);
+++ }
+++ memset(rpz, 0, sizeof(*rpz));
+++ rpz->st = st_unknown;
+++ commreply->rpz = rpz;
+++
+++ /* Make a new ID for log messages */
+++ rpz->log_id = __sync_add_and_fetch(&log_id, 1);
+++
+++ /* Get access to the librpz data. */
+++ if(!librpz->rsp_create(&emsg, &rpz->rsp, &rpz->min_ns_dots,
+++ worker->daemon->rpz_client,
+++ (flags & BIT_RD) != 0,
+++ (edns->bits & EDNS_DO) != 0)) {
+++ log_fail(rpz, "%s", emsg.c);
+++ return false;
+++ }
+++ /* Quit if benign reasons prevent rewriting. */
+++ if(!rpz->rsp) {
+++ rpz->st = st_off;
+++ librpz->log(LIBRPZ_LOG_TRACE1, rpz, "%s", emsg.c);
+++ return false;
+++ }
+++
+++ /* Check the client IP address.
+++ * Do not use commreply->srctype because it is often 0. */
+++ family = ((struct sockaddr*)&commreply->addr)->sa_family;
+++ switch(family) {
+++ case AF_INET:
+++ addr = &((struct sockaddr_in*)&commreply->addr)->sin_addr;
+++ break;
+++ case AF_INET6:
+++ addr = &((struct sockaddr_in6*)&commreply->addr)->sin6_addr;
+++ break;
+++ default:
+++ /* Maybe the client is on a UNIX domain socket. */
+++ librpz->log(LIBRPZ_LOG_TRACE2, rpz,
+++ "unknown client address family %d", family);
+++ addr = NULL;
+++ break;
+++ }
+++ /* Loop to ignore disabled zones. */
+++ while(addr) {
+++ if(!push_st(rpz))
+++ break;
+++ if(!librpz->ck_ip(&emsg, addr, family, LIBRPZ_TRIG_CLIENT_IP,
+++ rpz->hit_id, true, rpz->rsp)) {
+++ log_fail(rpz, "%s", emsg.c);
+++ break;
+++ }
+++ if(!ck_after(qinfo->qname, false, LIBRPZ_TRIG_CLIENT_IP, rpz))
+++ break;
+++ }
+++ if(rpz->st == st_servfail)
+++ return 0 > worker_send(dnsmsg, worker, qinfo,
+++ id, flags, edns, commreply);
+++
+++ /* Check the QNAME and possibly replace a client-IP hit. */
+++ ck_qname(qinfo->qname, qinfo->qname_len, false, true,
+++ rpz, &worker->env);
+++
+++ get_result_msg(&dnsmsg, qinfo, id, flags, false,
+++ rpz, commreply->c, worker->scratchpad);
+++ return 0 > worker_send(dnsmsg, worker, qinfo,
+++ id, flags, edns, commreply);
+++}
+++
+++
+++/* Check a cached reply before iteration.
+++ * @return: 1=use cache entry
+++ * 0=deny a cached entry exists in order to punt to the iterator
+++ * -1=rewritten response already sent or dropped */
+++int
+++rpz_worker_cache(struct worker* worker, struct reply_info* reply,
+++ struct query_info* qinfo, uint16_t id, uint16_t flags,
+++ struct edns_data* edns, struct comm_reply* commreply)
+++{
+++ commreply_rpz_t* rpz;
+++ struct dns_msg* dnsmsg;
+++ st_t new_st;
+++ librpz_rr_t* rr;
+++
+++ dnsmsg = NULL;
+++
+++ rpz = commreply->rpz;
+++ switch(rpz->st) {
+++ case st_off:
+++ return 1; /* Send the cache entry. */
+++ case st_servfail:
+++ return worker_send(dnsmsg, worker, qinfo, id, flags,
+++ edns, commreply);
+++ case st_unknown:
+++ break;
+++ case st_iterate:
+++ case st_ck_ns:
+++ return 0; /* Punt to the iterator. */
+++ case st_rewritten:
+++ default:
+++ fatal_exit("impossible RPZ state %d in rpz_worker_cache()",
+++ rpz->st);
+++ }
+++
+++ /* Check the RRs in the ANSWER section. */
+++ if(!push_st(rpz))
+++ return worker_send(dnsmsg, worker, qinfo, id, flags, edns,
+++ commreply);
+++
+++ ck_reply(reply, qinfo->qname, true, rpz, &worker->env);
+++ if(!ck_result(qinfo->qname, true, rpz, commreply->c))
+++ return worker_send(dnsmsg, worker, qinfo, id, flags, edns,
+++ commreply);
+++
+++ if(rpz->cname_hit.size != 0) {
+++ /* Punt to the iterator if leading CNAMEs must be
+++ * included in the rewritten response. */
+++ rpz->cname_hit.size = 0;
+++ new_st = st_iterate;
+++
+++ } else if(rpz->result.policy == LIBRPZ_POLICY_CNAME) {
+++ /* Punt if the rewritten response is to a CNAME. */
+++ new_st = st_iterate;
+++
+++ } else {
+++ if(rpz->result.policy == LIBRPZ_POLICY_RECORD) {
+++ next_rr(&rr, qinfo->qname, qinfo->qname_len, rpz);
+++ if(rr) {
+++ /* Punt we are rewriting to a CNAME. */
+++ if(rr->type == ntohs(LDNS_RR_TYPE_CNAME)) {
+++ free(rr);
+++ rpz->st = st_iterate;
+++ } else {
+++ free(rr);
+++ }
+++ }
+++ }
+++ get_result_msg(&dnsmsg, qinfo, id, flags, true,
+++ rpz, commreply->c, worker->scratchpad);
+++ new_st = rpz->st;
+++ }
+++
+++ switch(new_st) {
+++ case st_off:
+++ case st_servfail:
+++ break;
+++ case st_unknown:
+++ pop_discard_st(rpz);
+++ break;
+++ case st_iterate:
+++ case st_ck_ns:
+++ if(pop_st(rpz))
+++ rpz->st = new_st;
+++ break;
+++ case st_rewritten:
+++ pop_discard_st(rpz);
+++ break;
+++ default:
+++ fatal_exit("impossible RPZ state %d in rpz_worker_cache()",
+++ rpz->st);
+++ }
+++
+++ return worker_send(dnsmsg, worker, qinfo, id, flags, edns, commreply);
+++}
+++
+++
+++/* Check a cache hit or miss for the iterator.
+++ * A cache miss can already have a QNAME hit that was ignored before checking
+++ * the iterator because of "QNAME-WAIT-RECURSE yes".
+++ * Cache hits are treated like responses from authorities. */
+++bool /* false=SERVFAIL */
+++rpz_iter_cache(struct dns_msg** msg, enum response_type* type,
+++ struct module_qstate* qstate, struct iter_qstate* iq)
+++{
+++ struct comm_reply* commreply;
+++ commreply_rpz_t* rpz;
+++ struct dns_msg* dnsmsg;
+++
+++ commreply = &qstate->mesh_info->reply_list->query_reply;
+++ rpz = commreply->rpz;
+++
+++ rpz->iterating = true;
+++
+++ switch(rpz->st) {
+++ case st_off:
+++ iq->rpz_rewritten = 1; /* RPZ has nothing to say. */
+++ return true;
+++ case st_servfail:
+++ return false;
+++ case st_unknown:
+++ break;
+++ case st_iterate:
+++ case st_ck_ns:
+++ rpz->st = st_unknown;
+++ if(!ck_qname(iq->qchase.qname, iq->qchase.qname_len,
+++ *msg != NULL, true, rpz, qstate->env))
+++ return false;
+++ /* If we must recurse regardless and if NSIP/NSDNAME
+++ * checking failed, then delay in the hope that
+++ * recursion will also get NS data. */
+++ if(rpz->st == st_ck_ns)
+++ return true;
+++ break;
+++ case st_rewritten:
+++ default:
+++ fatal_exit("impossible RPZ state %d in rpz_iter_cache()",
+++ rpz->st);
+++ }
+++
+++ push_st(rpz);
+++
+++ /* Check the cache hit. */
+++ if(*msg)
+++ ck_reply((*msg)->rep, iq->qchase.qname, true, rpz, qstate->env);
+++
+++ /* The DNS ID does not matter, because the generated dns_msg
+++ * is nominally from an authority and not to the DNS client. */
+++ get_result_msg(&dnsmsg, &iq->qchase, 1, qstate->query_flags, true,
+++ rpz, commreply->c, qstate->region);
+++
+++ switch(rpz->st) {
+++ case st_off:
+++ iq->rpz_rewritten = 1; /* RPZ has nothing to say. */
+++ return true;
+++ case st_servfail:
+++ return false;
+++ case st_unknown:
+++ /* RPZ has nothing to say yet. Maybe there will be a hit
+++ * later in the CNAME chain. */
+++ return pop_discard_st(rpz);
+++ case st_ck_ns:
+++ /* Try to get NS data for a CNAME found by ck_reply() */
+++ *type = RESPONSE_TYPE_CNAME;
+++ return pop_discard_st(rpz);
+++ case st_iterate:
+++ default:
+++ fatal_exit("impossible RPZ state %d in rpz_iter_cache()",
+++ rpz->st);
+++ case st_rewritten:
+++ break;
+++ }
+++
+++ if(*msg && rpz->cname_hit.size != 0 && rpz->cname_hit_2nd) {
+++ /* We hit a CNAME owner in the cached msg after not hitting one
+++ * or more CNAME owners. We need to add those leading CNAMEs
+++ * to the prepend list. Tell the iterator to treat the cached
+++ * message as a RESPONSE_TYPE_CNAME even if it contains answers.
+++ * handle_cname_response() will stop prepending CNAMEs before
+++ * the triggering CNAME. handle_cname_response() will cause
+++ * a restart to resolve the target of the preceding CNAME,
+++ * which is the same as the hit CNAME owner. */
+++ rpz->st = st_unknown;
+++ *type = RESPONSE_TYPE_CNAME;
+++ return pop_discard_st(rpz);
+++ }
+++
+++ *msg = dnsmsg;
+++ iq->rpz_security = dnsmsg->rep->security;
+++
+++ if(dnsmsg && dnsmsg->rep->an_numrrsets != 0 &&
+++ dnsmsg->rep->rrsets[0]->rk.type == htons(LDNS_RR_TYPE_CNAME)) {
+++ /* The cached msg triggered a rule that rewrites to a
+++ * CNAME that must be resolved.
+++ * We have a replacement dns_msg with that CNAME and also
+++ * an SOA RR in the ADDITIONAL section that the iterator
+++ * will lose as it adds the CNAME to the prepend list.
+++ * Save the SOA RR in iq->rpz_soa. */
+++ iq->rpz_soa = dnsmsg->rep->rrsets[1];
+++ iq->rpz_rewritten = 1;
+++ *type = RESPONSE_TYPE_CNAME;
+++ return true;
+++ }
+++
+++ /* Otherwise we have rewritten to zero or more non-CNAME RRs.
+++ * (DNAMEs are not supported.)
+++ * Tell the iterator to send the rewritten message. */
+++ *type = RESPONSE_TYPE_ANSWER;
+++ iq->rpz_rewritten = 1;
+++ return true;
+++}
+++
+++
+++/* Check a RESPONSE_TYPE_ANSWER response from an authority in the iterator. */
+++rpz_iter_resp_t
+++rpz_iter_resp(struct module_qstate* qstate, struct iter_qstate* iq,
+++ struct dns_msg** resp, bool* is_cname)
+++{
+++ struct comm_reply* commreply;
+++ commreply_rpz_t* rpz;
+++ struct reply_info* rep;
+++
+++ *is_cname = false;
+++
+++ commreply = &qstate->mesh_info->reply_list->query_reply;
+++ rpz = commreply->rpz;
+++ switch(rpz->st) {
+++ case st_off:
+++ case st_servfail:
+++ case st_iterate:
+++ case st_rewritten:
+++ default:
+++ fatal_exit("impossible RPZ state %d in rpz_iter_resp()",
+++ rpz->st);
+++ case st_ck_ns:
+++ case st_unknown:
+++ break;
+++ }
+++
+++ /* We know !iq->rpz_rewritten and so the response was after a simple
+++ * cache miss when the original QNAME did not trigger a response
+++ * or after a CNAME whose owner name did hit but was then forgotten
+++ * with pop_st().
+++ * In either case, it is necessary to check the QNAME here.
+++ * Checking the QNAME will not lose a better hit. */
+++ rpz->st = st_unknown;
+++ ck_qname(iq->qchase.qname, iq->qchase.qname_len, true, false,
+++ rpz, qstate->env);
+++
+++ /* Check the RRs in the ANSWER section. */
+++ if(!push_st(rpz))
+++ return rpz_iter_resp_fail;
+++ ck_reply(iq->response->rep, iq->qchase.qname, false, rpz, qstate->env);
+++ get_result_msg(resp, &qstate->qinfo, 1, qstate->query_flags, true,
+++ rpz, commreply->c, qstate->region);
+++ switch(rpz->st) {
+++ case st_off:
+++ iq->rpz_rewritten = 1; /* Do not come back. */
+++ return rpz_iter_resp_done;
+++ case st_servfail: /* Send SERVFAIL */
+++ return rpz_iter_resp_fail;
+++ case st_unknown:
+++ case st_ck_ns:
+++ return rpz_iter_resp_done; /* continue without change */
+++ case st_iterate:
+++ default:
+++ fatal_exit("impossible RPZ state %d in rpz_iter_resp()",
+++ rpz->st);
+++ case st_rewritten:
+++ /* Tell the iterator to use handle_cname_response() to
+++ * prepend any preceding CNAMEs.
+++ * We have a replacement dns_msg that also has an SOA RR in the
+++ * ADDITIONAL section that the iterator will lose if it is a
+++ * CNAME. Save that SOA in that case. */
+++ rep = (*resp)->rep;
+++ if(rep->an_numrrsets != 0 &&
+++ rep->rrsets[0]->rk.type == ntohs(LDNS_RR_TYPE_CNAME)) {
+++ *is_cname = true;
+++ iq->rpz_soa = rep->rrsets[1];
+++ }
+++ return rpz_iter_resp_rewrite;
+++ }
+++}
+++
+++
+++/* Tell handle_cname_response() to stop adding to the answer prepend list
+++ * after adding CNAME with a target that hits a QNAME trigger.
+++ * Do not change any RPZ state, but expect the call of handle_cname_response()
+++ * to try to resolve the CNAME and hit the same QNAME trigger and rewrite
+++ * the response. */
+++rpz_cname_t
+++rpz_cname(struct module_qstate* qstate,
+++ uint8_t* oname, size_t oname_size)
+++{
+++ struct mesh_reply* reply_list;
+++ struct comm_reply* commreply;
+++ commreply_rpz_t* rpz;
+++ rpz_cname_t ret;
+++
+++ /* Quit if RPZ is off */
+++ reply_list = qstate->mesh_info->reply_list;
+++ if(!reply_list)
+++ return rpz_cname_prepend;
+++ commreply = &reply_list->query_reply;
+++ rpz = commreply->rpz;
+++
+++ if(!rpz || rpz->st == st_off)
+++ return rpz_cname_prepend;
+++
+++ /* Stop on a 2nd or later CNAME for rpz_iter_resp(). */
+++ if(rpz->cname_hit.size != 0) {
+++ if(!query_dname_compare(rpz->cname_hit.d, oname))
+++ return rpz_cname_stop;
+++ return rpz_cname_prepend;
+++ }
+++
+++ if(rpz->st != st_unknown)
+++ fatal_exit("impossible RPZ state %d in rpz_cname()", rpz->st);
+++
+++ ret = rpz_cname_prepend;
+++ if(!push_st(rpz))
+++ return rpz_cname_fail;
+++ /* Stop before prepending a CNAME that would preempt a
+++ * rewritten response or before a possible NSDNAME or NSIP trigger. */
+++ ++rpz->hit_id;
+++ ck_qname(oname, oname_size, true, true, rpz, qstate->env);
+++ if(rpz->st != st_unknown)
+++ ret = rpz_cname_stop;
+++ if(!pop_st(rpz))
+++ return rpz_cname_fail;
+++ return ret;
+++}
+++
+++#endif /* ENABLE_FASTRPZ */
++diff --git a/fastrpz/rpz.h b/fastrpz/rpz.h
++new file mode 100644
++index 00000000..5d7e31c5
++--- /dev/null
+++++ b/fastrpz/rpz.h
++@@ -0,0 +1,138 @@
+++/*
+++ * fastrpz/rpz.h - interface to the fastrpz response policy zone library
+++ *
+++ * Copyright (c) 2016 Farsight Security, Inc.
+++ *
+++ * Licensed under the Apache License, Version 2.0 (the "License");
+++ * you may not use this file except in compliance with the License.
+++ * You may obtain a copy of the License at
+++ * http://www.apache.org/licenses/LICENSE-2.0
+++ *
+++ * Unless required by applicable law or agreed to in writing, software
+++ * distributed under the License is distributed on an "AS IS" BASIS,
+++ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+++ * See the License for the specific language governing permissions and
+++ * limitations under the License.
+++ */
+++
+++#ifndef UNBOUND_FASTRPZ_RPZ_H
+++#define UNBOUND_FASTRPZ_RPZ_H
+++
+++#ifndef PACKAGE_VERSION
+++/* Ensure that config.h has been included to correctly set ENABLE_FASTRPZ */
+++#include "config.h"
+++#endif
+++
+++#ifdef ENABLE_FASTRPZ
+++
+++#include "librpz.h"
+++
+++#include "daemon/daemon.h"
+++#include "util/config_file.h"
+++
+++struct comm_point; /* forward references */
+++struct comm_reply;
+++struct dns_msg;
+++struct edns_data;
+++struct iter_qstate;
+++struct query_info;
+++struct reply_info;
+++enum response_type; /* iterator/iter_utils.h */
+++
+++
+++struct commreply_rpz;
+++
+++/**
+++ * Connect to the librpz database.
+++ * @param pclist: future pointer to opaque librpz client data
+++ * @param pclient: future pointer to opaque librpz client data
+++ * @param cfg: parsed unbound configuration
+++ */
+++void rpz_init(librpz_clist_t** pclist, librpz_client_t** pclient,
+++ const struct config_file* cfg);
+++
+++/**
+++ * Disconnect from the librpz database
+++ * @param client: opaque librpz client data
+++ */
+++void rpz_delete(librpz_clist_t** pclist, librpz_client_t** pclient);
+++
+++/**
+++ * Start working on a DNS request and check for client IP address triggers.
+++ * @param worker: the DNS request context
+++ * @param qinfo: the DNS question
+++ * @param[in,out] commreply: the answer
+++ * @param c: where to send the response
+++ * @param[in,out] edns for the DO flag
+++ * @return true if response already sent or dropped
+++ */
+++bool rpz_start(struct worker* worker, struct query_info* qinfo,
+++ struct comm_reply* commreply, struct edns_data* edns);
+++
+++/**
+++ * Release resources held for a DNS request
+++ * @param rspp: pointer to pointer to rpz client context.
+++ */
+++void rpz_end(struct comm_reply* comm_rep);
+++
+++/**
+++ * Check a cached reply for RPZ hits before iteration
+++ * @param worker: the DNS request context
+++ * @param casheresp: cache reply
+++ * @param qinfo: the DNS question
+++ * @param id from the DNS request
+++ * @param flags from the DNS request
+++ * @param[in,out] edns for the DO flag
+++ * @param[in,out] commreply: RPZ state
+++ * @return 1=use cache entry, -1=rewritten response already sent or dropped,
+++ * 0=deny a cached entry exists
+++ */
+++int rpz_worker_cache(struct worker* worker, struct reply_info* cacheresp,
+++ struct query_info* qinfo, uint16_t id, uint16_t flags,
+++ struct edns_data* edns, struct comm_reply* commreply);
+++
+++/**
+++ * Check for an existing RPZ CNAME rewrite with "QNAME-WAIT-RECURSE no"
+++ * that needs to be resolved before resolving the external request.
+++ * @param[out] msg: rewritten CNAME response.
+++ * @param qstate: query state.
+++ * @param iq: iterator query state.
+++ * @return false=send SERVFAIL
+++ */
+++bool rpz_iter_cache(struct dns_msg** msg, enum response_type* type,
+++ struct module_qstate* qstate, struct iter_qstate* iq);
+++
+++/**
+++ * Check a response from an authority in the iterator.
+++ * @param[out] type: of the final response
+++ * @param qstate: query state.
+++ * @param iq: iterator query state.
+++ * @param is_cname: true if the rewritten response is a CNAME
+++ * @return one of rpz_resp_t
+++ */
+++typedef enum {
+++ rpz_iter_resp_fail, /* Send SERVFAIL. */
+++ rpz_iter_resp_rewrite, /* We rewrote the response. */
+++ rpz_iter_resp_done, /* Restart to refetch glue. */
+++} rpz_iter_resp_t;
+++rpz_iter_resp_t rpz_iter_resp(struct module_qstate* qstate,
+++ struct iter_qstate* iq, struct dns_msg** resp,
+++ bool* is_cname);
+++
+++/**
+++ * Check a CNAME RR
+++ * @param qstate: query state.
+++ * @param oname: cname owner name
+++ * @param oname_size: length of oname
+++ * @return: one of rpz_cname_t
+++ */
+++typedef enum {
+++ rpz_cname_fail, /* send SERVFAIL */
+++ rpz_cname_prepend, /* prepend CNAME as usual */
+++ rpz_cname_stop, /* stop before prepending this CNAME */
+++} rpz_cname_t;
+++rpz_cname_t rpz_cname(struct module_qstate* qstate,
+++ uint8_t* oname, size_t oname_size);
+++
+++#endif /* ENABLE_FASTRPZ */
+++#endif /* UNBOUND_FASTRPZ_RPZ_H */
++diff --git a/fastrpz/rpz.m4 b/fastrpz/rpz.m4
++new file mode 100644
++index 00000000..21235355
++--- /dev/null
+++++ b/fastrpz/rpz.m4
++@@ -0,0 +1,64 @@
+++# fastrpz/rpz.m4
+++
+++# ck_FASTRPZ
+++# --------------------------------------------------------------------------
+++# check for Fastrpz
+++# --enable-fastrpz enable Fastrpz response policy zones
+++# --enable-fastrpz-dl Fastrpz delayed link [default=have dlopen]
+++# --with-fastrpz-dir directory containing librpz.so
+++#
+++# Fastrpz can be compiled into Unbound everywhere with a reasonably
+++# modern C compiler. It is enabled on systems with dlopen() and librpz.so.
+++
+++AC_DEFUN([ck_FASTRPZ],
+++[
+++ fastrpz_avail=yes
+++ AC_MSG_CHECKING([for librpz __attribute__s])
+++ AC_TRY_COMPILE(,[
+++ extern void f(char *p __attribute__((unused)), ...)
+++ __attribute__((format(printf,1,2))) __attribute__((__noreturn__));],
+++ librpz_have_attr=yes
+++ AC_DEFINE([LIBRPZ_HAVE_ATTR], 1, [have __attribute__s used in librpz.h])
+++ AC_MSG_RESULT([yes]),
+++ librpz_have_attr=no
+++ AC_MSG_RESULT([no]))
+++
+++ AC_SEARCH_LIBS(dlopen, dl)
+++ librpz_dl=yes
+++ AC_CHECK_FUNCS(dlopen dlclose dlsym,,librpz_dl=no)
+++ AC_ARG_ENABLE([fastrpz-dl],
+++ [ --enable-fastrpz-dl Fastrpz delayed link [[default=$librpz_dl]]],
+++ [enable_librpz_dl="$enableval"],
+++ [enable_librpz_dl="$librpz_dl"])
+++ AC_ARG_WITH([fastrpz-dir],
+++ [ --with-fastrpz-dir directory containing librpz.so],
+++ [librpz_path="$withval/librpz.so"], [librpz_path="librpz.so"])
+++ AC_DEFINE_UNQUOTED([FASTRPZ_LIBRPZ_PATH], ["$librpz_path"],
+++ [fastrpz librpz.so])
+++ if test "x$enable_librpz_dl" = "xyes"; then
+++ fastrpz_lib_open=2
+++ else
+++ fastrpz_lib_open=1
+++ # Add librpz.so to linked libraries if we are not using dlopen()
+++ AC_SEARCH_LIBS([librpz_client_create], [rpz], [],
+++ [fastrpz_lib_open=0
+++ fastrpz_avail=no])
+++ fi
+++ AC_DEFINE_UNQUOTED([FASTRPZ_LIB_OPEN], [$fastrpz_lib_open],
+++ [0=no fastrpz 1=static link 2=dlopen()])
+++
+++ AC_ARG_ENABLE([fastrpz],
+++ AS_HELP_STRING([--enable-fastrpz],[enable Fastrpz response policy zones]),
+++ [enable_fastrpz=$enableval],[enable_fastrpz=$fastrpz_avail])
+++ if test "x$enable_fastrpz" = xyes; then
+++ AC_DEFINE([ENABLE_FASTRPZ], [1], [Enable fastrpz])
+++ if test "x$fastrpz_lib_open" = "x0"; then
+++ AC_MSG_ERROR([[dlopen and librpz.so needed for fastrpz]])
+++ fi
+++ # used in Makefile.in
+++ AC_SUBST([FASTRPZ_SRC], [fastrpz/rpz.c])
+++ AC_SUBST([FASTRPZ_OBJ], [rpz.lo])
+++ elif test "x$fastrpz_avail" = "x0"; then
+++ AC_MSG_WARN([[dlopen and librpz.so needed for fastrpz]])
+++ fi
+++])
++diff --git a/iterator/iterator.c b/iterator/iterator.c
++index 1e0113a8..2fcbf547 100644
++--- a/iterator/iterator.c
+++++ b/iterator/iterator.c
++@@ -68,6 +68,9 @@
++ #include "sldns/str2wire.h"
++ #include "sldns/parseutil.h"
++ #include "sldns/sbuffer.h"
+++#ifdef ENABLE_FASTRPZ
+++#include "fastrpz/rpz.h"
+++#endif
++
++ /* in msec */
++ int UNKNOWN_SERVER_NICENESS = 376;
++@@ -555,6 +558,23 @@ handle_cname_response(struct module_qstate* qstate, struct iter_qstate* iq,
++ if(ntohs(r->rk.type) == LDNS_RR_TYPE_CNAME &&
++ query_dname_compare(*mname, r->rk.dname) == 0 &&
++ !iter_find_rrset_in_prepend_answer(iq, r)) {
+++#ifdef ENABLE_FASTRPZ
+++ /* Stop adding CNAME rrsets to the prepend list
+++ * before defining an RPZ hit. */
+++ if(!iq->rpz_rewritten) {
+++ switch (rpz_cname(qstate, *mname, *mname_len)) {
+++ case rpz_cname_fail:
+++ /* send SERVFAIL */
+++ return 0;
+++ case rpz_cname_prepend:
+++ /* save the CNAME. */
+++ break;
+++ case rpz_cname_stop:
+++ /* Pause before adding the CNAME. */
+++ goto stop_short;
+++ }
+++ }
+++#endif
++ /* Add this relevant CNAME rrset to the prepend list.*/
++ if(!iter_add_prepend_answer(qstate, iq, r))
++ return 0;
++@@ -563,6 +583,9 @@ handle_cname_response(struct module_qstate* qstate, struct iter_qstate* iq,
++
++ /* Other rrsets in the section are ignored. */
++ }
+++#ifdef ENABLE_FASTRPZ
+++stop_short: ;
+++#endif
++ /* add authority rrsets to authority prepend, for wildcarded CNAMEs */
++ for(i=msg->rep->an_numrrsets; i<msg->rep->an_numrrsets +
++ msg->rep->ns_numrrsets; i++) {
++@@ -1199,6 +1222,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
++ uint8_t* delname;
++ size_t delnamelen;
++ struct dns_msg* msg = NULL;
+++ enum response_type type;
++
++ log_query_info(VERB_DETAIL, "resolving", &qstate->qinfo);
++ /* check effort */
++@@ -1285,8 +1309,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
++ }
++ if(msg) {
++ /* handle positive cache response */
++- enum response_type type = response_type_from_cache(msg,
++- &iq->qchase);
+++ type = response_type_from_cache(msg, &iq->qchase);
++ if(verbosity >= VERB_ALGO) {
++ log_dns_msg("msg from cache lookup", &msg->qinfo,
++ msg->rep);
++@@ -1294,7 +1317,22 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
++ (int)msg->rep->ttl,
++ (int)msg->rep->prefetch_ttl);
++ }
+++#ifdef ENABLE_FASTRPZ
+++ }
+++ /* Check for an RPZ hit in the cached DNS message or an existing
+++ * RPZ CNAME rewrite that can be resolved now after a hit on the QNAME
+++ * or client IP address. This can involve a creating a fake cache
+++ * hit. It can also involve overriding an RESPONSE_TYPE_ANSWER
+++ * result from response_type_from_cache(). Or it can ignore
+++ * the cached result to refetch glue. */
+++ if(!iq->rpz_rewritten &&
+++ qstate->mesh_info->reply_list &&
+++ qstate->mesh_info->reply_list->query_reply.rpz &&
+++ !rpz_iter_cache(&msg, &type, qstate, iq))
+++ return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
++
+++ if(msg) {
+++#endif
++ if(type == RESPONSE_TYPE_CNAME) {
++ uint8_t* sname = 0;
++ size_t slen = 0;
++@@ -2718,6 +2756,62 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
++ sock_list_insert(&qstate->reply_origin,
++ &qstate->reply->addr, qstate->reply->addrlen,
++ qstate->region);
+++#ifdef ENABLE_FASTRPZ
+++ /* Check the response for an RPZ hit. The response has already
+++ * been saved in the cache. This should have the same effect
+++ * as finding that response in the cache.
+++ * We have already used rpz_iter_cache() at least once. */
+++ if(!iq->rpz_rewritten &&
+++ qstate->mesh_info->reply_list &&
+++ qstate->mesh_info->reply_list->query_reply.rpz) {
+++ struct dns_msg* resp;
+++ bool is_cname;
+++ uint8_t* sname;
+++ size_t slen;
+++
+++ switch (rpz_iter_resp(qstate, iq, &resp, &is_cname)) {
+++ case rpz_iter_resp_fail:
+++ return error_response(qstate, id,
+++ LDNS_RCODE_SERVFAIL);
+++ case rpz_iter_resp_rewrite:
+++ /* Prepend any initial CNAMEs from the original
+++ * response up to a hit. */
+++ if(!handle_cname_response(qstate, iq,
+++ iq->response,
+++ &sname, &slen))
+++ return error_response(qstate, id,
+++ LDNS_RCODE_SERVFAIL);
+++ if (resp) {
+++ iq->response = resp;
+++ iq->rpz_security = resp->rep->security;
+++ iq->rpz_rewritten = 1;
+++
+++ /* Send the rewritten record if it
+++ * is not a CNAME. */
+++ if(!is_cname)
+++ break;
+++
+++ /* Prepend the new CNAME
+++ * and restart to resolve it. */
+++ if(!handle_cname_response(qstate, iq,
+++ resp, &sname, &slen))
+++ return error_response(qstate, id,
+++ LDNS_RCODE_SERVFAIL);
+++ }
+++ iq->qchase.qname = sname;
+++ iq->qchase.qname_len = slen;
+++ iq->dp = NULL;
+++ iq->refetch_glue = 0;
+++ iq->query_restart_count++;
+++ iq->sent_count = 0;
+++ iq->state = INIT_REQUEST_STATE;
+++ return 1;
+++
+++ case rpz_iter_resp_done:
+++ break;
+++ }
+++ }
+++#endif
++ if(iq->minimisation_state != DONOT_MINIMISE_STATE
++ && !(iq->chase_flags & BIT_RD)) {
++ if(FLAGS_GET_RCODE(iq->response->rep->flags) !=
++@@ -3471,12 +3565,44 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq,
++ * but only if we did recursion. The nonrecursion referral
++ * from cache does not need to be stored in the msg cache. */
++ if(!qstate->no_cache_store && qstate->query_flags&BIT_RD) {
+++#ifdef ENABLE_FASTRPZ
+++ /* Do not save RPZ rewritten messages. */
+++ if(!iq->rpz_rewritten)
+++#endif
++ iter_dns_store(qstate->env, &qstate->qinfo,
++ iq->response->rep, 0, qstate->prefetch_leeway,
++ iq->dp&&iq->dp->has_parent_side_NS,
++ qstate->region, qstate->query_flags);
++ }
++ }
+++#ifdef ENABLE_FASTRPZ
+++ if(iq->rpz_rewritten) {
+++ /* Restore RPZ marks on a rewritten response. The marks
+++ * are lost if the rewrite is to a CNAME. */
+++ iq->response->rep->security = iq->rpz_security;
+++
+++ /* Append the RPZ SOA to rewritten CNAME chains. */
+++ if(iq->rpz_soa) {
+++ struct ub_packed_rrset_key** sets;
+++ uint n;
+++
+++ n = iq->response->rep->rrset_count;
+++ sets = regional_alloc(qstate->region,
+++ (1+n) * sizeof(*sets));
+++ if(!sets) {
+++ log_err("append RPZ SOA: out of memory");
+++ return error_response(qstate, id,
+++ LDNS_RCODE_SERVFAIL);
+++ }
+++ memcpy(sets, iq->response->rep->rrsets,
+++ n * sizeof(struct ub_packed_rrset_key*));
+++ sets[n] = iq->rpz_soa;
+++ iq->response->rep->rrsets = sets;
+++ ++iq->response->rep->rrset_count;
+++ ++iq->response->rep->ar_numrrsets;
+++ }
+++ }
+++#endif
++ qstate->return_rcode = LDNS_RCODE_NOERROR;
++ qstate->return_msg = iq->response;
++ return 0;
++diff --git a/iterator/iterator.h b/iterator/iterator.h
++index a2f1b570..e1e4a738 100644
++--- a/iterator/iterator.h
+++++ b/iterator/iterator.h
++@@ -386,6 +386,16 @@ struct iter_qstate {
++ */
++ int minimise_count;
++
+++
+++#ifdef ENABLE_FASTRPZ
+++ /** The response has been rewritten by RPZ. */
+++ int rpz_rewritten;
+++ /** RPZ SOA RR for the ADDITIONAL section */
+++ struct ub_packed_rrset_key* rpz_soa;
+++ /** sec_status_rpz_rewritten or sec_status_rpz_drop if rewritten. */
+++ enum sec_status rpz_security;
+++#endif
+++
++ /**
++ * Count number of time-outs. Used to prevent resolving failures when
++ * the QNAME minimisation QTYPE is blocked. */
++diff --git a/services/cache/dns.c b/services/cache/dns.c
++index 2a5bca4a..6de8863a 100644
++--- a/services/cache/dns.c
+++++ b/services/cache/dns.c
++@@ -967,6 +967,14 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf,
++ struct regional* region, uint32_t flags)
++ {
++ struct reply_info* rep = NULL;
+++
+++#ifdef ENABLE_FASTRPZ
+++ /* Never save RPZ rewritten data. */
+++ if (msgrep->security == sec_status_rpz_drop ||
+++ msgrep->security == sec_status_rpz_rewritten)
+++ return 1;
+++#endif
+++
++ /* alloc, malloc properly (not in region, like msg is) */
++ rep = reply_info_copy(msgrep, env->alloc, NULL);
++ if(!rep)
++diff --git a/services/mesh.c b/services/mesh.c
++index 9114ef4c..3dc518e5 100644
++--- a/services/mesh.c
+++++ b/services/mesh.c
++@@ -61,6 +61,9 @@
++ #include "sldns/wire2str.h"
++ #include "services/localzone.h"
++ #include "util/data/dname.h"
+++#ifdef ENABLE_FASTRPZ
+++#include "fastrpz/rpz.h"
+++#endif
++ #include "respip/respip.h"
++ #include "services/listen_dnsport.h"
++
++@@ -1195,6 +1198,13 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
++ else secure = 0;
++ if(!rep && rcode == LDNS_RCODE_NOERROR)
++ rcode = LDNS_RCODE_SERVFAIL;
+++#ifdef ENABLE_FASTRPZ
+++ /* Drop the response here for LIBRPZ_POLICY_DROP after iteration. */
+++ if(rep && rep->security == sec_status_rpz_drop) {
+++ log_query_info(VERB_QUERY, "rpz drop", &m->s.qinfo);
+++ secure = 0;
+++ } else
+++#endif
++ /* send the reply */
++ /* We don't reuse the encoded answer if either the previous or current
++ * response has a local alias. We could compare the alias records
++@@ -1415,6 +1425,7 @@ struct mesh_state* mesh_area_find(struct mesh_area* mesh,
++ key.s.is_valrec = valrec;
++ key.s.qinfo = *qinfo;
++ key.s.query_flags = qflags;
+++ key.reply_list = NULL;
++ /* We are searching for a similar mesh state when we DO want to
++ * aggregate the state. Thus unique is set to NULL. (default when we
++ * desire aggregation).*/
++@@ -1461,6 +1472,10 @@ int mesh_state_add_reply(struct mesh_state* s, struct edns_data* edns,
++ if(!r)
++ return 0;
++ r->query_reply = *rep;
+++#ifdef ENABLE_FASTRPZ
+++ /* The new reply structure owns the RPZ state. */
+++ rep->rpz = NULL;
+++#endif
++ r->edns = *edns;
++ if(edns->opt_list) {
++ r->edns.opt_list = edns_opt_copy_region(edns->opt_list,
++diff --git a/util/config_file.c b/util/config_file.c
++index 52ca5a18..0660248f 100644
++--- a/util/config_file.c
+++++ b/util/config_file.c
++@@ -1460,6 +1460,8 @@ config_delete(struct config_file* cfg)
++ free(cfg->dnstap_socket_path);
++ free(cfg->dnstap_identity);
++ free(cfg->dnstap_version);
+++ if (cfg->rpz_cstr)
+++ free(cfg->rpz_cstr);
++ config_deldblstrlist(cfg->ratelimit_for_domain);
++ config_deldblstrlist(cfg->ratelimit_below_domain);
++ config_delstrlist(cfg->python_script);
++diff --git a/util/config_file.h b/util/config_file.h
++index 8739ca2a..a2dcf215 100644
++--- a/util/config_file.h
+++++ b/util/config_file.h
++@@ -499,6 +499,11 @@ struct config_file {
++ /** true to disable DNSSEC lameness check in iterator */
++ int disable_dnssec_lame_check;
++
+++ /** true to enable RPZ */
+++ int rpz_enable;
+++ /** RPZ configuration */
+++ char* rpz_cstr;
+++
++ /** ratelimit for ip addresses. 0 is off, otherwise qps (unless overridden) */
++ int ip_ratelimit;
++ /** number of slabs for ip_ratelimit cache */
++diff --git a/util/configlexer.lex b/util/configlexer.lex
++index deedffa5..301458a3 100644
++--- a/util/configlexer.lex
+++++ b/util/configlexer.lex
++@@ -446,6 +446,10 @@ dnstap-log-forwarder-query-messages{COLON} {
++ YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES) }
++ dnstap-log-forwarder-response-messages{COLON} {
++ YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES) }
+++rpz{COLON} { YDVAR(0, VAR_RPZ) }
+++rpz-enable{COLON} { YDVAR(1, VAR_RPZ_ENABLE) }
+++rpz-zone{COLON} { YDVAR(1, VAR_RPZ_ZONE) }
+++rpz-option{COLON} { YDVAR(1, VAR_RPZ_OPTION) }
++ disable-dnssec-lame-check{COLON} { YDVAR(1, VAR_DISABLE_DNSSEC_LAME_CHECK) }
++ ip-ratelimit{COLON} { YDVAR(1, VAR_IP_RATELIMIT) }
++ ratelimit{COLON} { YDVAR(1, VAR_RATELIMIT) }
++diff --git a/util/configparser.y b/util/configparser.y
++index d471babe..cb6b1d63 100644
++--- a/util/configparser.y
+++++ b/util/configparser.y
++@@ -125,6 +125,7 @@ extern struct config_parser_state* cfg_parser;
++ %token VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES
++ %token VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES
++ %token VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES
+++%token VAR_RPZ VAR_RPZ_ENABLE VAR_RPZ_ZONE VAR_RPZ_OPTION
++ %token VAR_RESPONSE_IP_TAG VAR_RESPONSE_IP VAR_RESPONSE_IP_DATA
++ %token VAR_HARDEN_ALGO_DOWNGRADE VAR_IP_TRANSPARENT
++ %token VAR_DISABLE_DNSSEC_LAME_CHECK
++@@ -173,7 +174,7 @@ extern struct config_parser_state* cfg_parser;
++
++ %%
++ toplevelvars: /* empty */ | toplevelvars toplevelvar ;
++-toplevelvar: serverstart contents_server | stubstart contents_stub |
+++toplevelvar: serverstart contents_server | stubstart contents_stub | rpzstart contents_rpz |
++ forwardstart contents_forward | pythonstart contents_py |
++ rcstart contents_rc | dtstart contents_dt | viewstart contents_view |
++ dnscstart contents_dnsc | cachedbstart contents_cachedb |
++@@ -2837,6 +2838,50 @@ dt_dnstap_log_forwarder_response_messages: VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MES
++ free($2);
++ }
++ ;
+++rpzstart: VAR_RPZ
+++ {
+++ OUTYY(("\nP(rpz:)\n"));
+++ }
+++ ;
+++contents_rpz: contents_rpz content_rpz
+++ | ;
+++content_rpz: rpz_enable | rpz_zone | rpz_option
+++ ;
+++rpz_enable: VAR_RPZ_ENABLE STRING_ARG
+++ {
+++ OUTYY(("P(rpz_enable:%s)\n", $2));
+++ if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
+++ yyerror("expected yes or no.");
+++ else cfg_parser->cfg->rpz_enable = (strcmp($2, "yes")==0);
+++ free($2);
+++ }
+++ ;
+++rpz_zone: VAR_RPZ_ZONE STRING_ARG
+++ {
+++ char *new_cstr, *old_cstr;
+++
+++ OUTYY(("P(rpz_zone:%s)\n", $2));
+++ old_cstr = cfg_parser->cfg->rpz_cstr;
+++ if(asprintf(&new_cstr, "%s\nzone %s", old_cstr?old_cstr:"", $2) == -1) {new_cstr = NULL; yyerror("out of memory");}
+++ else if(!new_cstr)
+++ yyerror("out of memory");
+++ free(old_cstr);
+++ cfg_parser->cfg->rpz_cstr = new_cstr;
+++ }
+++ ;
+++rpz_option: VAR_RPZ_OPTION STRING_ARG
+++ {
+++ char *new_cstr, *old_cstr;
+++
+++ OUTYY(("P(rpz_option:%s)\n", $2));
+++ old_cstr = cfg_parser->cfg->rpz_cstr;
+++ if(asprintf(&new_cstr, "%s\n%s", old_cstr ? old_cstr : "", $2) == -1) {new_cstr = NULL; yyerror("out of memory");}
+++ else if(!new_cstr)
+++ yyerror("out of memory");
+++ free(old_cstr);
+++ cfg_parser->cfg->rpz_cstr = new_cstr;
+++ }
+++ ;
++ pythonstart: VAR_PYTHON
++ {
++ OUTYY(("\nP(python:)\n"));
++diff --git a/util/data/msgencode.c b/util/data/msgencode.c
++index be69f628..f10773aa 100644
++--- a/util/data/msgencode.c
+++++ b/util/data/msgencode.c
++@@ -592,6 +592,35 @@ insert_section(struct reply_info* rep, size_t num_rrsets, uint16_t* num_rrs,
++ return RETVAL_OK;
++ }
++
+++#ifdef ENABLE_FASTRPZ
+++/* Insert the RPZ SOA even with MINIMAL_RESPONSES */
+++static int
+++insert_rpz_soa(struct reply_info* rep, size_t num_rrsets, uint16_t* num_rrs,
+++ sldns_buffer* pkt, size_t rrsets_before, time_t timenow,
+++ struct regional* region, struct compress_tree_node** tree,
+++ size_t rr_offset)
+++{
+++ int r;
+++ size_t i, setstart;
+++
+++ *num_rrs = 0;
+++ for(i=0; i<num_rrsets; i++) {
+++ if (rep->rrsets[rrsets_before+i]->rk.type != LDNS_RR_TYPE_SOA)
+++ continue;
+++ setstart = sldns_buffer_position(pkt);
+++ if((r=packed_rrset_encode(rep->rrsets[rrsets_before+i],
+++ pkt, num_rrs, timenow, region,
+++ 1, 0, tree, LDNS_SECTION_ADDITIONAL,
+++ LDNS_RR_TYPE_ANY, 0, rr_offset))
+++ != RETVAL_OK) {
+++ sldns_buffer_set_position(pkt, setstart);
+++ return r;
+++ }
+++ }
+++ return RETVAL_OK;
+++}
+++
+++#endif
++ /** store query section in wireformat buffer, return RETVAL */
++ static int
++ insert_query(struct query_info* qinfo, struct compress_tree_node** tree,
++@@ -779,6 +808,19 @@ reply_info_encode(struct query_info* qinfo, struct reply_info* rep,
++ }
++ sldns_buffer_write_u16_at(buffer, 10, arcount);
++ }
+++#ifdef ENABLE_FASTRPZ
+++ } else if(rep->security == sec_status_rpz_rewritten) {
+++ /* Insert the RPZ SOA for rpz even with MINIMAL_RESPONSES */
+++ r = insert_rpz_soa(rep, rep->ar_numrrsets, &arcount, buffer,
+++ rep->an_numrrsets + rep->ns_numrrsets,
+++ timenow, region, &tree, rr_offset);
+++ if(r!= RETVAL_OK) {
+++ if(r != RETVAL_TRUNC)
+++ return 0;
+++ /* no need to set TC bit, this is the additional */
+++ sldns_buffer_write_u16_at(buffer, 10, arcount);
+++ }
+++#endif
++ }
++ sldns_buffer_flip(buffer);
++ return 1;
++diff --git a/util/data/packed_rrset.c b/util/data/packed_rrset.c
++index 4b0294f9..3b3838f6 100644
++--- a/util/data/packed_rrset.c
+++++ b/util/data/packed_rrset.c
++@@ -256,6 +256,10 @@ sec_status_to_string(enum sec_status s)
++ case sec_status_insecure: return "sec_status_insecure";
++ case sec_status_secure_sentinel_fail: return "sec_status_secure_sentinel_fail";
++ case sec_status_secure: return "sec_status_secure";
+++#ifdef ENABLE_FASTRPZ
+++ case sec_status_rpz_rewritten: return "sec_status_rpz_rewritten";
+++ case sec_status_rpz_drop: return "sec_status_rpz_drop";
+++#endif
++ }
++ return "unknown_sec_status_value";
++ }
++diff --git a/util/data/packed_rrset.h b/util/data/packed_rrset.h
++index 729877ba..ccd1a0c2 100644
++--- a/util/data/packed_rrset.h
+++++ b/util/data/packed_rrset.h
++@@ -193,7 +193,15 @@ enum sec_status {
++ sec_status_secure_sentinel_fail,
++ /** SECURE means that the object (RRset or message) validated
++ * according to local policy. */
++- sec_status_secure
+++ sec_status_secure,
+++#ifdef ENABLE_FASTRPZ
+++ /** RPZ_REWRITTEN means that the response has been rewritten by
+++ * rpz and so cannot be verified. */
+++ sec_status_rpz_rewritten,
+++ /** RPZ_DROP means that the response has been rewritten by rpz
+++ * as silence. */
+++ sec_status_rpz_drop
+++#endif
++ };
++
++ /**
++diff --git a/util/netevent.c b/util/netevent.c
++index 9fe5da2d..037e70d1 100644
++--- a/util/netevent.c
+++++ b/util/netevent.c
++@@ -57,6 +57,9 @@
++ #ifdef HAVE_OPENSSL_ERR_H
++ #include <openssl/err.h>
++ #endif
+++#ifdef ENABLE_FASTRPZ
+++#include "fastrpz/rpz.h"
+++#endif
++
++ /* -------- Start of local definitions -------- */
++ /** if CMSG_ALIGN is not defined on this platform, a workaround */
++@@ -590,6 +593,9 @@ comm_point_udp_ancil_callback(int fd, short event, void* arg)
++ struct cmsghdr* cmsg;
++ #endif /* S_SPLINT_S */
++
+++#ifdef ENABLE_FASTRPZ
+++ rep.rpz = NULL;
+++#endif
++ rep.c = (struct comm_point*)arg;
++ log_assert(rep.c->type == comm_udp);
++
++@@ -679,6 +685,9 @@ comm_point_udp_callback(int fd, short event, void* arg)
++ int i;
++ struct sldns_buffer *buffer;
++
+++#ifdef ENABLE_FASTRPZ
+++ rep.rpz = NULL;
+++#endif
++ rep.c = (struct comm_point*)arg;
++ log_assert(rep.c->type == comm_udp);
++
++@@ -722,6 +731,9 @@ comm_point_udp_callback(int fd, short event, void* arg)
++ (void)comm_point_send_udp_msg(rep.c, buffer,
++ (struct sockaddr*)&rep.addr, rep.addrlen);
++ }
+++#ifdef ENABLE_FASTRPZ
+++ rpz_end(&rep);
+++#endif
++ if(!rep.c || rep.c->fd != fd) /* commpoint closed to -1 or reused for
++ another UDP port. Note rep.c cannot be reused with TCP fd. */
++ break;
++@@ -3192,6 +3204,9 @@ comm_point_send_reply(struct comm_reply *repinfo)
++ repinfo->c->tcp_timeout_msec);
++ }
++ }
+++#ifdef ENABLE_FASTRPZ
+++ rpz_end(repinfo);
+++#endif
++ }
++
++ void
++@@ -3201,6 +3216,9 @@ comm_point_drop_reply(struct comm_reply* repinfo)
++ return;
++ log_assert(repinfo->c);
++ log_assert(repinfo->c->type != comm_tcp_accept);
+++#ifdef ENABLE_FASTRPZ
+++ rpz_end(repinfo);
+++#endif
++ if(repinfo->c->type == comm_udp)
++ return;
++ if(repinfo->c->tcp_req_info)
++@@ -3222,6 +3240,9 @@ comm_point_start_listening(struct comm_point* c, int newfd, int msec)
++ {
++ verbose(VERB_ALGO, "comm point start listening %d (%d msec)",
++ c->fd==-1?newfd:c->fd, msec);
+++#ifdef ENABLE_FASTRPZ
+++ rpz_end(&c->repinfo);
+++#endif
++ if(c->type == comm_tcp_accept && !c->tcp_free) {
++ /* no use to start listening no free slots. */
++ return;
++diff --git a/util/netevent.h b/util/netevent.h
++index d80c72b3..0233292f 100644
++--- a/util/netevent.h
+++++ b/util/netevent.h
++@@ -120,6 +120,10 @@ struct comm_reply {
++ /** return type 0 (none), 4(IP4), 6(IP6) */
++ int srctype;
++ /* DnsCrypt context */
+++#ifdef ENABLE_FASTRPZ
+++ /** per-request RPZ state */
+++ struct commreply_rpz* rpz;
+++#endif
++ #ifdef USE_DNSCRYPT
++ uint8_t client_nonce[crypto_box_HALF_NONCEBYTES];
++ uint8_t nmkey[crypto_box_BEFORENMBYTES];
++diff --git a/validator/validator.c b/validator/validator.c
++index c3ca0a27..15251988 100644
++--- a/validator/validator.c
+++++ b/validator/validator.c
++@@ -2761,6 +2761,12 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
++ default:
++ /* NSEC proof did not work, try next */
++ break;
+++#ifdef ENABLE_FASTRPZ
+++ case sec_status_rpz_rewritten:
+++ case sec_status_rpz_drop:
+++ fatal_exit("impossible RPZ sec_status");
+++ break;
+++#endif
++ }
++
++ sec = nsec3_prove_nods(qstate->env, ve,
++@@ -2794,6 +2800,12 @@ ds_response_to_ke(struct module_qstate* qstate, struct val_qstate* vq,
++ default:
++ /* NSEC3 proof did not work */
++ break;
+++#ifdef ENABLE_FASTRPZ
+++ case sec_status_rpz_rewritten:
+++ case sec_status_rpz_drop:
+++ fatal_exit("impossible RPZ sec_status");
+++ break;
+++#endif
++ }
++
++ /* Apparently, no available NSEC/NSEC3 proved NODATA, so
+--- contrib/unbound/contrib/libunbound.pc.in.orig
++++ contrib/unbound/contrib/libunbound.pc.in
+@@ -7,7 +7,8 @@
+ Description: Library with validating, recursive, and caching DNS resolver
+ URL: http://www.unbound.net
+ Version: @PACKAGE_VERSION@
+-Requires:
+-Libs: -L${libdir} -lunbound @SSLLIB@ @LIBS@
+-Libs.private: @LDFLAGS@
+-Cflags: -I${includedir}
++Requires: @PC_CRYPTO_DEPENDENCY@ @PC_LIBEVENT_DEPENDENCY@
++Requires.private: @PC_PY_DEPENDENCY@ @PC_LIBBSD_DEPENDENCY@
++Libs: -L${libdir} -lunbound
++Libs.private: @SSLLIB@ @LIBS@
++Cflags: -I${includedir}
+--- contrib/unbound/contrib/libunbound.so.conf.orig
++++ contrib/unbound/contrib/libunbound.so.conf
+@@ -0,0 +1,42 @@
++# See ltrace.conf(5) for description of syntax of this file.
++typedef ub_type = enum(TYPE_A=1,TYPE_NS=2,TYPE_SOA=6,TYPE_MX=15,TYPE_TXT=16,TYPE_AAAA=28,TYPE_DS=43,TYPE_DNSKEY=48,TYPE_TLSA=52,TYPE_ANY=255);
++typedef ub_class = enum(CLASS_IN=1,CLASS_CH=3,CLASS_NONE=254,CLASS_ANY=255);
++typedef ub_rcode = enum(RCODE_NOERROR,RCODE_FORMERR,RCODE_SERVFAIL,RCODE_NXDOMAIN,RCODE_NOTIMPL,RCODE_REFUSED,RCODE_YXDOMAIN,RCODE_YXRRSET,RCODE_NXRRSET,RCODE_NOTAUTH,RCODE_NOTZONE);
++typedef ub_havedata = enum(no_data, have_data);
++typedef ub_nxdomain = enum(name_exists, nxdomain);
++typedef ub_secure = enum(not_secure, secure);
++typedef ub_bogus = enum(not_bogus, bogus);
++typedef ub_result = struct(string, ub_type, ub_class, array(void*,zero)*, array(int,zero)*, string, ub_rcode, void*, int, ub_havedata, ub_nxdomain, ub_secure, ub_bogus, string, int);
++typedef ub_ctx = void;
++ub_ctx* ub_ctx_create(void);
++void ub_ctx_delete(ub_ctx*);
++int ub_ctx_set_option(ub_ctx*, string, string);
++int ub_ctx_get_option(ub_ctx*, string, +string*);
++int ub_ctx_config(ub_ctx*, string);
++int ub_ctx_set_fwd(ub_ctx*, string);
++int ub_ctx_set_tls(ub_ctx*, bool(int));
++int ub_ctx_set_stub(ub_ctx*, string, string, bool(int));
++int ub_ctx_resolvconf(ub_ctx*, string);
++int ub_ctx_hosts(ub_ctx*, string);
++int ub_ctx_add_ta(ub_ctx*, string);
++int ub_ctx_add_ta_file(ub_ctx*, string);
++int ub_ctx_add_ta_autr(ub_ctx*, string);
++int ub_ctx_trustedkeys(ub_ctx*, string);
++int ub_ctx_debugout(ub_ctx*, void*);
++int ub_ctx_debuglevel(ub_ctx*, int);
++int ub_ctx_async(ub_ctx*, bool(int));
++int ub_poll(ub_ctx*);
++int ub_wait(ub_ctx*);
++int ub_fd(ub_ctx*);
++int ub_process(ub_ctx*);
++int ub_resolve(ub_ctx*, string, ub_type, ub_class, +ub_result**);
++int ub_resolve_async(ub_ctx*, string, ub_type, ub_class, void*, void*, +int*);
++int ub_cancel(ub_ctx*, int);
++void ub_resolve_free(ub_result*);
++string ub_strerror(int);
++int ub_ctx_print_local_zones(ub_ctx*);
++int ub_ctx_zone_add(ub_ctx*, string, string);
++int ub_ctx_zone_remove(ub_ctx*, string);
++int ub_ctx_data_add(ub_ctx*, string);
++int ub_ctx_data_remove(ub_ctx*, string);
++string ub_version(void);
+--- contrib/unbound/contrib/parseunbound.pl.orig
++++ contrib/unbound/contrib/parseunbound.pl
+@@ -91,7 +91,7 @@
+ $allstats{$inthread}->{outstandingexc} = $4;
+ }
+ elsif ( $line =~ m/info: average recursion processing time ([0-9\.]+) sec/ ) {
+- $allstats{$inthread}->{recursionavg} = int($1 * 1000); # change sec to milisec.
++ $allstats{$inthread}->{recursionavg} = int($1 * 1000); # change sec to millisec.
+ }
+ elsif ( $line =~ m/info: histogram of recursion processing times/ ) {
+ next;
+@@ -103,7 +103,7 @@
+ }
+ elsif ( $line =~ m/info: lower\(secs\) upper\(secs\) recursions/ ) {
+ # since after this line we're unsure if we get these numbers
+- # at all, we sould consider this marker as the end of the
++ # at all, we should consider this marker as the end of the
+ # block. Chances that we're parsing a file halfway written
+ # at this stage are small. Bold statement.
+ $donestats{$inthread} = 1;
+--- contrib/unbound/contrib/redirect-bogus.patch.orig
++++ contrib/unbound/contrib/redirect-bogus.patch
+@@ -0,0 +1,344 @@
++Index: daemon/worker.c
++===================================================================
++--- daemon/worker.c (revision 4191)
+++++ daemon/worker.c (working copy)
++@@ -663,8 +663,21 @@
++ if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, rep,
++ LDNS_RCODE_SERVFAIL, edns, worker->scratchpad))
++ goto bail_out;
++- error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
++- qinfo, id, flags, edns);
+++ if (qinfo->qtype == LDNS_RR_TYPE_A &&
+++ worker->env.cfg->redirect_bogus_ipv4) {
+++ /* BAD cached */
+++ fixed_address_encode(repinfo->c->buffer,
+++ LDNS_RCODE_NOERROR, qinfo, id, flags, edns,
+++ worker->env.cfg->redirect_bogus_ipv4);
+++ } else if (qinfo->qtype == LDNS_RR_TYPE_AAAA &&
+++ worker->env.cfg->redirect_bogus_ipv6) {
+++ fixed_address_encode(repinfo->c->buffer,
+++ LDNS_RCODE_NOERROR, qinfo, id, flags, edns,
+++ worker->env.cfg->redirect_bogus_ipv6);
+++ } else {
+++ error_encode(repinfo->c->buffer, LDNS_RCODE_SERVFAIL,
+++ qinfo, id, flags, edns);
+++ }
++ rrset_array_unlock_touch(worker->env.rrset_cache,
++ worker->scratchpad, rep->ref, rep->rrset_count);
++ if(worker->stats.extended) {
++Index: doc/unbound.conf.5.in
++===================================================================
++--- doc/unbound.conf.5.in (revision 4191)
+++++ doc/unbound.conf.5.in (working copy)
++@@ -1244,6 +1244,18 @@
++ This can make ordinary queries complete (if repeatedly queried for),
++ and enter the cache, whilst also mitigating the traffic flow by the
++ factor given.
+++.TP 5
+++.B redirect-bogus-ipv4: \fI<IPv4 address>
+++Set a fixed address for DNSSEC failures that are cached
+++Instead of responding to A queries with SERVFAIL, respond
+++with NOERROR and the address specified here
+++The TTL of the response will be 5 seconds
+++.TP 5
+++.B redirect-bogus-ipv6: \fI<IPv4 address>
+++Set a fixed address for DNSSEC failures that are cached
+++Instead of responding to AAAA queries with SERVFAIL, respond
+++with NOERROR and the address specified here
+++The TTL of the response will be 5 seconds
++ .SS "Remote Control Options"
++ In the
++ .B remote\-control:
++Index: services/mesh.c
++===================================================================
++--- services/mesh.c (revision 4191)
+++++ services/mesh.c (working copy)
++@@ -1006,6 +1006,7 @@
++ struct timeval end_time;
++ struct timeval duration;
++ int secure;
+++ int bogus_override = 0;
++ /* Copy the client's EDNS for later restore, to make sure the edns
++ * compare is with the correct edns options. */
++ struct edns_data edns_bak = r->edns;
++@@ -1016,6 +1017,7 @@
++ rcode = LDNS_RCODE_SERVFAIL;
++ if(m->s.env->cfg->stat_extended)
++ m->s.env->mesh->ans_bogus++;
+++ bogus_override = 1;
++ }
++ if(rep && rep->security == sec_status_secure)
++ secure = 1;
++@@ -1047,17 +1049,34 @@
++ } else if(rcode) {
++ m->s.qinfo.qname = r->qname;
++ m->s.qinfo.local_alias = r->local_alias;
++- if(rcode == LDNS_RCODE_SERVFAIL) {
++- if(!inplace_cb_reply_servfail_call(m->s.env, &m->s.qinfo, &m->s,
++- rep, rcode, &r->edns, m->s.region))
++- r->edns.opt_list = NULL;
++- } else {
++- if(!inplace_cb_reply_call(m->s.env, &m->s.qinfo, &m->s, rep, rcode,
++- &r->edns, m->s.region))
++- r->edns.opt_list = NULL;
+++ if(bogus_override && m->s.qinfo.qtype == LDNS_RR_TYPE_A &&
+++ m->s.env->cfg->redirect_bogus_ipv4) {
+++ fixed_address_encode(r->query_reply.c->buffer,
+++ LDNS_RCODE_NOERROR, &m->s.qinfo, r->qid,
+++ r->qflags, &r->edns,
+++ m->s.env->cfg->redirect_bogus_ipv4);
+++ } else if(bogus_override &&
+++ m->s.qinfo.qtype == LDNS_RR_TYPE_AAAA &&
+++ m->s.env->cfg->redirect_bogus_ipv6) {
+++ fixed_address_encode(r->query_reply.c->buffer,
+++ LDNS_RCODE_NOERROR, &m->s.qinfo, r->qid,
+++ r->qflags, &r->edns,
+++ m->s.env->cfg->redirect_bogus_ipv6);
+++ } else {
+++ if(rcode == LDNS_RCODE_SERVFAIL) {
+++ if(!inplace_cb_reply_servfail_call(m->s.env,
+++ &m->s.qinfo, &m->s,
+++ rep, rcode, &r->edns, m->s.region))
+++ r->edns.opt_list = NULL;
+++ } else {
+++ if(!inplace_cb_reply_call(m->s.env, &m->s.qinfo,
+++ &m->s, rep, rcode, &r->edns,
+++ m->s.region))
+++ r->edns.opt_list = NULL;
+++ }
+++ error_encode(r->query_reply.c->buffer, rcode,
+++ &m->s.qinfo, r->qid, r->qflags, &r->edns);
++ }
++- error_encode(r->query_reply.c->buffer, rcode, &m->s.qinfo,
++- r->qid, r->qflags, &r->edns);
++ comm_point_send_reply(&r->query_reply);
++ } else {
++ size_t udp_size = r->edns.udp_size;
++Index: util/config_file.c
++===================================================================
++--- util/config_file.c (revision 4191)
+++++ util/config_file.c (working copy)
++@@ -273,6 +273,8 @@
++ cfg->ratelimit_factor = 10;
++ cfg->qname_minimisation = 0;
++ cfg->qname_minimisation_strict = 0;
+++ cfg->redirect_bogus_ipv4 = NULL;
+++ cfg->redirect_bogus_ipv6 = NULL;
++ cfg->shm_enable = 0;
++ cfg->shm_key = 11777;
++ cfg->dnscrypt = 0;
++@@ -602,6 +604,10 @@
++ }
++ oi[cfg->num_out_ifs++] = d;
++ cfg->out_ifs = oi;
+++ } else if (strcmp(opt, "redirect-bogus-ipv4:") == 0) {
+++ cfg->redirect_bogus_ipv4 = strdup(val);
+++ } else if (strcmp(opt, "redirect-bogus-ipv6:") == 0) {
+++ cfg->redirect_bogus_ipv6 = strdup(val);
++ } else {
++ /* unknown or unsupported (from the set_option interface):
++ * interface, outgoing-interface, access-control,
++@@ -1250,6 +1256,12 @@
++ free(cfg->dnstap_version);
++ config_deldblstrlist(cfg->ratelimit_for_domain);
++ config_deldblstrlist(cfg->ratelimit_below_domain);
+++ if (cfg->redirect_bogus_ipv4) {
+++ free(cfg->redirect_bogus_ipv4);
+++ }
+++ if (cfg->redirect_bogus_ipv6) {
+++ free(cfg->redirect_bogus_ipv6);
+++ }
++ #ifdef USE_IPSECMOD
++ free(cfg->ipsecmod_hook);
++ config_delstrlist(cfg->ipsecmod_whitelist);
++Index: util/config_file.h
++===================================================================
++--- util/config_file.h (revision 4191)
+++++ util/config_file.h (working copy)
++@@ -444,6 +444,9 @@
++ /** minimise QNAME in strict mode, minimise according to RFC.
++ * Do not apply fallback */
++ int qname_minimisation_strict;
+++ /** construct fake responses for DNSSEC failures */
+++ char *redirect_bogus_ipv4;
+++ char *redirect_bogus_ipv6;
++ /** SHM data - true if shm is enabled */
++ int shm_enable;
++ /** SHM data - key for the shm */
++Index: util/configlexer.lex
++===================================================================
++--- util/configlexer.lex (revision 4191)
+++++ util/configlexer.lex (working copy)
++@@ -410,6 +410,8 @@
++ response-ip-tag{COLON} { YDVAR(2, VAR_RESPONSE_IP_TAG) }
++ response-ip{COLON} { YDVAR(2, VAR_RESPONSE_IP) }
++ response-ip-data{COLON} { YDVAR(2, VAR_RESPONSE_IP_DATA) }
+++redirect-bogus-ipv4{COLON} { YDVAR(1, VAR_REDIRECT_BOGUS_IPV4) }
+++redirect-bogus-ipv6{COLON} { YDVAR(1, VAR_REDIRECT_BOGUS_IPV6) }
++ dnscrypt{COLON} { YDVAR(0, VAR_DNSCRYPT) }
++ dnscrypt-enable{COLON} { YDVAR(1, VAR_DNSCRYPT_ENABLE) }
++ dnscrypt-port{COLON} { YDVAR(1, VAR_DNSCRYPT_PORT) }
++Index: util/configparser.y
++===================================================================
++--- util/configparser.y (revision 4191)
+++++ util/configparser.y (working copy)
++@@ -44,6 +44,7 @@
++ #include <stdlib.h>
++ #include <assert.h>
++
+++#include "sldns/str2wire.h"
++ #include "util/configyyrename.h"
++ #include "util/config_file.h"
++ #include "util/net_help.h"
++@@ -141,6 +142,7 @@
++ %token VAR_ACCESS_CONTROL_TAG_DATA VAR_VIEW VAR_ACCESS_CONTROL_VIEW
++ %token VAR_VIEW_FIRST VAR_SERVE_EXPIRED VAR_FAKE_DSA VAR_FAKE_SHA1
++ %token VAR_LOG_IDENTITY VAR_HIDE_TRUSTANCHOR VAR_TRUST_ANCHOR_SIGNALING
+++%token VAR_REDIRECT_BOGUS_IPV4 VAR_REDIRECT_BOGUS_IPV6
++ %token VAR_USE_SYSTEMD VAR_SHM_ENABLE VAR_SHM_KEY
++ %token VAR_DNSCRYPT VAR_DNSCRYPT_ENABLE VAR_DNSCRYPT_PORT VAR_DNSCRYPT_PROVIDER
++ %token VAR_DNSCRYPT_SECRET_KEY VAR_DNSCRYPT_PROVIDER_CERT
++@@ -228,6 +230,7 @@
++ server_access_control_tag_data | server_access_control_view |
++ server_qname_minimisation_strict | server_serve_expired |
++ server_fake_dsa | server_log_identity | server_use_systemd |
+++ server_redirect_bogus_ipv4 | server_redirect_bogus_ipv6 |
++ server_response_ip_tag | server_response_ip | server_response_ip_data |
++ server_shm_enable | server_shm_key | server_fake_sha1 |
++ server_hide_trustanchor | server_trust_anchor_signaling |
++@@ -1873,6 +1876,34 @@
++ #endif
++ }
++ ;
+++server_redirect_bogus_ipv4: VAR_REDIRECT_BOGUS_IPV4 STRING_ARG
+++ {
+++ uint8_t data[4];
+++ size_t data_len = 4;
+++ OUTYY(("P(name:%s)\n", $2));
+++ if(cfg_parser->cfg->redirect_bogus_ipv4) {
+++ yyerror("redirect-bogus-ipv4, can only use one address");
+++ }
+++ if(sldns_str2wire_a_buf($2, data, &data_len) != LDNS_WIREPARSE_ERR_OK) {
+++ yyerror("redirect-bogus-ipv4, not a valid IPv4 address");
+++ }
+++ free(cfg_parser->cfg->redirect_bogus_ipv4);
+++ cfg_parser->cfg->redirect_bogus_ipv4 = $2;
+++ }
+++server_redirect_bogus_ipv6: VAR_REDIRECT_BOGUS_IPV6 STRING_ARG
+++ {
+++ uint8_t data[16];
+++ size_t data_len = 16;
+++ OUTYY(("P(name:%s)\n", $2));
+++ if(cfg_parser->cfg->redirect_bogus_ipv6) {
+++ yyerror("redirect-bogus-ipv6, can only use one address");
+++ }
+++ if(sldns_str2wire_aaaa_buf($2, data, &data_len) != LDNS_WIREPARSE_ERR_OK) {
+++ yyerror("redirect-bogus-ipv6, not a valid IPv6 address");
+++ }
+++ free(cfg_parser->cfg->redirect_bogus_ipv6);
+++ cfg_parser->cfg->redirect_bogus_ipv6 = $2;
+++ }
++ stub_name: VAR_NAME STRING_ARG
++ {
++ OUTYY(("P(name:%s)\n", $2));
++Index: util/data/msgencode.c
++===================================================================
++--- util/data/msgencode.c (revision 4191)
+++++ util/data/msgencode.c (working copy)
++@@ -48,6 +48,7 @@
++ #include "util/regional.h"
++ #include "util/net_help.h"
++ #include "sldns/sbuffer.h"
+++#include "sldns/str2wire.h"
++ #include "services/localzone.h"
++
++ /** return code that means the function ran out of memory. negative so it does
++@@ -914,3 +915,63 @@
++ attach_edns_record(buf, &es);
++ }
++ }
+++
+++void
+++fixed_address_encode(sldns_buffer* buf, int r, struct query_info* qinfo,
+++ uint16_t qid, uint16_t qflags, struct edns_data* edns, char* data)
+++{
+++ uint16_t flags;
+++ uint8_t addr_data[16];
+++ size_t addr_len = 16;
+++ if (qinfo->qtype == LDNS_RR_TYPE_A) {
+++ sldns_str2wire_a_buf(data, addr_data, &addr_len);
+++ } else if (qinfo->qtype == LDNS_RR_TYPE_AAAA) {
+++ sldns_str2wire_aaaa_buf(data, addr_data, &addr_len);
+++ } else {
+++ return error_encode(buf, LDNS_RCODE_NOERROR, qinfo, qid, qflags, edns);
+++ }
+++ sldns_buffer_clear(buf);
+++ sldns_buffer_write(buf, &qid, sizeof(uint16_t));
+++ flags = (uint16_t)(BIT_QR | BIT_RA | r); /* QR and retcode*/
+++ flags |= (qflags & (BIT_RD|BIT_CD)); /* copy RD and CD bit */
+++ sldns_buffer_write_u16(buf, flags);
+++ if(qinfo) flags = 1;
+++ else flags = 0;
+++ sldns_buffer_write_u16(buf, flags);
+++ sldns_buffer_write_u16(buf, 1);
+++ flags = 0;
+++ sldns_buffer_write(buf, &flags, sizeof(uint16_t));
+++ sldns_buffer_write(buf, &flags, sizeof(uint16_t));
+++ if(qinfo) {
+++ // query
+++ if(sldns_buffer_current(buf) == qinfo->qname)
+++ sldns_buffer_skip(buf, (ssize_t)qinfo->qname_len);
+++ else sldns_buffer_write(buf, qinfo->qname, qinfo->qname_len);
+++ sldns_buffer_write_u16(buf, qinfo->qtype);
+++ sldns_buffer_write_u16(buf, qinfo->qclass);
+++ // faked answer
+++ if(sldns_buffer_current(buf) == qinfo->qname)
+++ sldns_buffer_skip(buf, (ssize_t)qinfo->qname_len);
+++ else sldns_buffer_write(buf, qinfo->qname, qinfo->qname_len);
+++ sldns_buffer_write_u16(buf, qinfo->qtype);
+++ sldns_buffer_write_u16(buf, qinfo->qclass);
+++ sldns_buffer_write_u16(buf, 0);
+++ // TTL. Should we make this configurable too?
+++ sldns_buffer_write_u16(buf, 5);
+++ sldns_buffer_write_u16(buf, addr_len);
+++ sldns_buffer_write(buf, addr_data, addr_len);
+++ fflush(stderr);
+++ }
+++ sldns_buffer_flip(buf);
+++ if(edns) {
+++ struct edns_data es = *edns;
+++ es.edns_version = EDNS_ADVERTISED_VERSION;
+++ es.udp_size = EDNS_ADVERTISED_SIZE;
+++ es.ext_rcode = 0;
+++ es.bits &= EDNS_DO;
+++ if(sldns_buffer_limit(buf) + calc_edns_field_size(&es) >
+++ edns->udp_size)
+++ return;
+++ attach_edns_record(buf, &es);
+++ }
+++}
++Index: util/data/msgencode.h
++===================================================================
++--- util/data/msgencode.h (revision 4191)
+++++ util/data/msgencode.h (working copy)
++@@ -128,4 +128,20 @@
++ void error_encode(struct sldns_buffer* pkt, int r, struct query_info* qinfo,
++ uint16_t qid, uint16_t qflags, struct edns_data* edns);
++
+++/**
+++ * Encode a fixed address response.
+++ * This is a fake answer to either an A or AAA query
+++ *
+++ * It will answer with that address
+++ *
+++ * @param pkt: where to store the packet.
+++ * @param r: RCODE value to encode.
+++ * @param qinfo: if not NULL, the query is included.
+++ * @param qid: query ID to set in packet. network order.
+++ * @param qflags: original query flags (to copy RD and CD bits). host order.
+++ * @param edns: if not NULL, this is the query edns info,
+++ * and an edns reply is attached. Only attached if EDNS record fits reply.
+++ */
+++void fixed_address_encode(struct sldns_buffer* pkt, int r, struct query_info* qinfo,
+++ uint16_t qid, uint16_t qflags, struct edns_data* edns, char* address);
++ #endif /* UTIL_DATA_MSGENCODE_H */
+--- contrib/unbound/contrib/unbound-fuzzme.patch.orig
++++ contrib/unbound/contrib/unbound-fuzzme.patch
+@@ -0,0 +1,148 @@
++>From cc9b927f8f29d989ddb8415fe6508a538546abca Mon Sep 17 00:00:00 2001
++From: Jacob Hoffman-Andrews <github@hoffman-andrews.com>
++Date: Wed, 2 Jan 2019 22:52:51 -0800
++Subject: [PATCH] Add unbound-fuzzme.
++
++This is a small program that simply parses a packet provided on stdout,
++for the purposes of fuzzing.
++---
++ .gitignore | 1 +
++ Makefile.in | 22 ++++++++++++++++++++--
++ smallapp/unbound-fuzzme.c | 38 ++++++++++++++++++++++++++++++++++++++
++ 3 files changed, 59 insertions(+), 2 deletions(-)
++ create mode 100644 smallapp/unbound-fuzzme.c
++
++diff --git a/.gitignore b/.gitignore
++index f4527fd8..6163f905 100644
++--- a/.gitignore
+++++ b/.gitignore
++@@ -24,6 +24,7 @@
++ /unbound-checkconf
++ /unbound-control
++ /unbound-control-setup
+++/unbound-fuzzme
++ /unbound-host
++ /unbound.h
++ /asynclook
++diff --git a/Makefile.in b/Makefile.in
++index af5b10f6..dacf1ab5 100644
++--- a/Makefile.in
+++++ b/Makefile.in
++@@ -177,6 +177,10 @@ shm_main.lo remote.lo stats.lo unbound.lo \
++ worker.lo @WIN_DAEMON_OBJ@
++ DAEMON_OBJ_LINK=$(DAEMON_OBJ) $(COMMON_OBJ_ALL_SYMBOLS) $(SLDNS_OBJ) \
++ $(COMPAT_OBJ) @WIN_DAEMON_OBJ_LINK@
+++FUZZME_SRC=smallapp/unbound-fuzzme.c
+++FUZZME_OBJ=unbound-fuzzme.lo
+++FUZZME_OBJ_LINK=$(FUZZME_OBJ) worker_cb.lo $(COMMON_OBJ_ALL_SYMBOLS) $(SLDNS_OBJ) \
+++$(COMPAT_OBJ)
++ CHECKCONF_SRC=smallapp/unbound-checkconf.c smallapp/worker_cb.c
++ CHECKCONF_OBJ=unbound-checkconf.lo worker_cb.lo
++ CHECKCONF_OBJ_LINK=$(CHECKCONF_OBJ) $(COMMON_OBJ_ALL_SYMBOLS) $(SLDNS_OBJ) \
++@@ -252,6 +256,7 @@ RSRC_OBJ=rsrc_svcinst.o rsrc_svcuninst.o rsrc_anchorupd.o rsrc_unbound.o \
++ rsrc_unbound_checkconf.o
++
++ ALL_SRC=$(COMMON_SRC) $(UNITTEST_SRC) $(DAEMON_SRC) \
+++ $(FUZZME_SRC) \
++ $(TESTBOUND_SRC) $(LOCKVERIFY_SRC) $(PKTVIEW_SRC) \
++ $(MEMSTATS_SRC) $(CHECKCONF_SRC) $(LIBUNBOUND_SRC) $(HOST_SRC) \
++ $(ASYNCLOOK_SRC) $(STREAMTCP_SRC) $(PERF_SRC) $(DELAYER_SRC) \
++@@ -259,6 +264,7 @@ ALL_SRC=$(COMMON_SRC) $(UNITTEST_SRC) $(DAEMON_SRC) \
++ $(PYTHONMOD_SRC) $(PYUNBOUND_SRC) $(WIN_DAEMON_THE_SRC)\
++ $(SVCINST_SRC) $(SVCUNINST_SRC) $(ANCHORUPD_SRC) $(SLDNS_SRC)
++ ALL_OBJ=$(COMMON_OBJ) $(UNITTEST_OBJ) $(DAEMON_OBJ) \
+++ $(FUZZME_OBJ) \
++ $(TESTBOUND_OBJ) $(LOCKVERIFY_OBJ) $(PKTVIEW_OBJ) \
++ $(MEMSTATS_OBJ) $(CHECKCONF_OBJ) $(LIBUNBOUND_OBJ) $(HOST_OBJ) \
++ $(ASYNCLOOK_OBJ) $(STREAMTCP_OBJ) $(PERF_OBJ) $(DELAYER_OBJ) \
++@@ -274,7 +280,7 @@ LINK_LIB=$(LIBTOOL) --tag=CC --mode=link $(CC) $(RUNTIME_PATH) $(CPPFLAGS) $(CFL
++
++ all: $(COMMON_OBJ) $(ALLTARGET)
++
++-alltargets: unbound$(EXEEXT) unbound-checkconf$(EXEEXT) lib unbound-host$(EXEEXT) unbound-control$(EXEEXT) unbound-anchor$(EXEEXT) unbound-control-setup $(WINAPPS) $(PYUNBOUND_TARGET)
+++alltargets: unbound$(EXEEXT) unbound-checkconf$(EXEEXT) lib unbound-host$(EXEEXT) unbound-control$(EXEEXT) unbound-anchor$(EXEEXT) unbound-control-setup unbound-fuzzme$(EXEEXT) $(WINAPPS) $(PYUNBOUND_TARGET)
++
++ # compat with BSD make, register suffix, and an implicit rule to actualise it.
++ .SUFFIXES: .lo
++@@ -325,6 +331,9 @@ libunbound.la: $(LIBUNBOUND_OBJ_LINK)
++ unbound$(EXEEXT): $(DAEMON_OBJ_LINK) libunbound.la
++ $(LINK) -o $@ $(DAEMON_OBJ_LINK) $(EXTRALINK) $(SSLLIB) $(LIBS)
++
+++unbound-fuzzme$(EXEEXT): $(FUZZME_OBJ_LINK) libunbound.la
+++ $(LINK) -o $@ $(FUZZME_OBJ_LINK) $(EXTRALINK) $(SSLLIB) $(LIBS)
+++
++ unbound-checkconf$(EXEEXT): $(CHECKCONF_OBJ_LINK) libunbound.la
++ $(LINK) -o $@ $(CHECKCONF_OBJ_LINK) $(EXTRALINK) $(SSLLIB) $(LIBS)
++
++@@ -447,7 +456,7 @@ util/configparser.c util/configparser.h: $(srcdir)/util/configparser.y
++
++ clean:
++ rm -f *.o *.d *.lo *~ tags
++- rm -f unbound$(EXEEXT) unbound-checkconf$(EXEEXT) unbound-host$(EXEEXT) unbound-control$(EXEEXT) unbound-anchor$(EXEEXT) unbound-control-setup libunbound.la unbound.h
+++ rm -f unbound$(EXEEXT) unbound-checkconf$(EXEEXT) unbound-fuzzme$(EXEEXT) unbound-host$(EXEEXT) unbound-control$(EXEEXT) unbound-anchor$(EXEEXT) unbound-control-setup libunbound.la unbound.h
++ rm -f $(ALL_SRC:.c=.lint)
++ rm -f _unbound.la libunbound/python/libunbound_wrap.c libunbound/python/unbound.py pythonmod/interface.h pythonmod/unboundmodule.py
++ rm -rf autom4te.cache .libs build doc/html doc/xml
++@@ -1183,6 +1192,15 @@ stats.lo stats.o: $(srcdir)/daemon/stats.c config.h $(srcdir)/daemon/stats.h $(s
++ $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
++ $(srcdir)/util/rtt.h $(srcdir)/services/authzone.h $(srcdir)/validator/val_kcache.h \
++ $(srcdir)/validator/val_neg.h
+++unbound-fuzzme.lo unbound-fuzzme.o: $(srcdir)/smallapp/unbound-fuzzme.c \
+++ $(srcdir)/util/locks.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
+++ $(srcdir)/daemon/remote.h $(srcdir)/util/config_file.h \
+++ $(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lruhash.h $(srcdir)/services/listen_dnsport.h \
+++ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/services/cache/rrset.h \
+++ $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
+++ $(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/fptr_wlist.h \
+++ $(srcdir)/util/module.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
+++ $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/net_help.h $(srcdir)/util/ub_event.h
++ unbound.lo unbound.o: $(srcdir)/daemon/unbound.c config.h $(srcdir)/util/log.h $(srcdir)/daemon/daemon.h \
++ $(srcdir)/util/locks.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
++ $(srcdir)/daemon/remote.h \
++diff --git a/smallapp/unbound-fuzzme.c b/smallapp/unbound-fuzzme.c
++new file mode 100644
++index 00000000..74ae5204
++--- /dev/null
+++++ b/smallapp/unbound-fuzzme.c
++@@ -0,0 +1,38 @@
+++/*
+++ * unbound-fuzzme.c - parse a packet provided on stdin (for fuzzing).
+++ *
+++ */
+++#include "config.h"
+++#include "util/regional.h"
+++#include "util/fptr_wlist.h"
+++#include "sldns/sbuffer.h"
+++
+++#define SZ 10000
+++
+++int main() {
+++ char buffer[SZ];
+++ size_t n_read = fread(buffer, 1, SZ, stdin);
+++ if (n_read == SZ) {
+++ printf("input too big\n");
+++ return 1;
+++ }
+++ sldns_buffer *pkt = sldns_buffer_new(n_read);
+++ sldns_buffer_init_frm_data(pkt, buffer, n_read);
+++
+++ struct regional *region = regional_create();
+++
+++ struct msg_parse* prs;
+++ struct edns_data edns;
+++ prs = (struct msg_parse*)malloc(sizeof(struct msg_parse));
+++ if(!prs) {
+++ printf("out of memory on incoming message\n");
+++ return 1;
+++ }
+++ memset(prs, 0, sizeof(*prs));
+++ memset(&edns, 0, sizeof(edns));
+++ sldns_buffer_set_position(pkt, 0);
+++ if(parse_packet(pkt, prs, region) != LDNS_RCODE_NOERROR) {
+++ printf("parse error\n");
+++ return 1;
+++ }
+++}
++--
++2.17.1
++
+--- contrib/unbound/contrib/unbound-querycachedb.py.orig
++++ contrib/unbound/contrib/unbound-querycachedb.py
+@@ -0,0 +1,77 @@
++#!/usr/bin/env python
++
++import hashlib
++import sys
++import struct
++import socket
++import time
++from optparse import OptionParser
++
++import dns.message
++import dns.name
++import dns.rdataclass
++import dns.rdatatype
++
++def _calc_hashkey(qname, secret, qtype):
++ qclass = 'IN' # CLASS is fixed for simplicity
++ hobj = hashlib.sha256()
++ hobj.update(dns.name.from_text(qname).to_wire())
++ hobj.update(struct.pack('HH',
++ socket.htons(dns.rdatatype.from_text(qtype)),
++ socket.htons(dns.rdataclass.from_text(qclass))))
++ hobj.update(secret)
++ return hobj.hexdigest().upper()
++
++def _redis_get(options, key):
++ import redis
++ return redis.Redis(options.address, int(options.port)).get(key)
++
++def _dump_value(options, qname, key, value):
++ print(';; query=%s/IN/%s' % (qname, options.qtype))
++ print(';; key=%s' % key)
++ if value is None:
++ print(';; no value')
++ return
++ if len(value) < 16:
++ print(';; broken value, short length: %d' % len(value))
++ return
++ now = int(time.time())
++ timestamp = struct.unpack('!Q', value[-16:-8])[0]
++ expire = struct.unpack('!Q', value[-8:])[0]
++ print(';; Now=%d, TimeStamp=%d, Expire=%d, TTL=%d' %
++ (now, timestamp, expire, max(expire - now, 0)))
++ print(dns.message.from_wire(value[:-16]))
++
++def main():
++ parser = OptionParser(usage='usage: %prog [options] query_name')
++ parser.add_option("-a", "--address", dest="address", action="store",
++ default='127.0.0.1', help="backend-server address",
++ metavar='ADDRESS')
++ parser.add_option("-b", "--backend", dest="backend", action="store",
++ default='redis', help="backend name",
++ metavar='BACKEND')
++ parser.add_option("-p", "--port", dest="port", action="store",
++ default='6379', help="backend-server port",
++ metavar='PORT')
++ parser.add_option("-s", "--secret", dest="secret", action="store",
++ default='default', help="secret seed", metavar='SECRET')
++ parser.add_option("-t", "--qtype", dest="qtype", action="store",
++ default='A', help="query RR type", metavar='QTYPE')
++
++ (options, args) = parser.parse_args()
++ if len(args) < 1:
++ parser.error('qname is missing')
++ if options.backend == 'redis':
++ get_func = _redis_get
++ else:
++ raise Exception('unknown backend name: %s\n' % options.backend)
++ key = _calc_hashkey(args[0], options.secret, options.qtype)
++ value = get_func(options, key)
++ _dump_value(options, args[0], key, value)
++
++if __name__ == '__main__':
++ try:
++ main()
++ except Exception as e:
++ sys.stderr.write('%s\n' % e)
++ exit(1)
+--- contrib/unbound/contrib/unbound.init.orig
++++ contrib/unbound/contrib/unbound.init
+@@ -39,13 +39,13 @@
+ # setup root jail
+ if [ -s /etc/localtime ]; then
+ [ -d ${rootdir}/etc ] || mkdir -p ${rootdir}/etc ;
+- if [ ! -e ${rootdir}/etc/localtime ] || /usr/bin/cmp -s /etc/localtime ${rootdir}/etc/localtime; then
++ if [ ! -e ${rootdir}/etc/localtime ] || ! /usr/bin/cmp -s /etc/localtime ${rootdir}/etc/localtime; then
+ cp -fp /etc/localtime ${rootdir}/etc/localtime
+ fi;
+ fi;
+ if [ -s /etc/resolv.conf ]; then
+ [ -d ${rootdir}/etc ] || mkdir -p ${rootdir}/etc ;
+- if [ ! -e ${rootdir}/etc/resolv.conf ] || /usr/bin/cmp -s /etc/resolv.conf ${rootdir}/etc/resolv.conf; then
++ if [ ! -e ${rootdir}/etc/resolv.conf ] || ! /usr/bin/cmp -s /etc/resolv.conf ${rootdir}/etc/resolv.conf; then
+ cp -fp /etc/resolv.conf ${rootdir}/etc/resolv.conf
+ fi;
+ fi;
+@@ -54,10 +54,10 @@
+ [ -e ${rootdir}/dev/log ] || touch ${rootdir}/dev/log
+ mount --bind -n /dev/log ${rootdir}/dev/log >/dev/null 2>&1;
+ fi;
+- if ! egrep -q '^/[^[:space:]]+[[:space:]]+'${rootdir}'/dev/random' /proc/mounts; then
++ if ! egrep -q '^/[^[:space:]]+[[:space:]]+'${rootdir}'/dev/urandom' /proc/mounts; then
+ [ -d ${rootdir}/dev ] || mkdir -p ${rootdir}/dev ;
+- [ -e ${rootdir}/dev/random ] || touch ${rootdir}/dev/random
+- mount --bind -n /dev/random ${rootdir}/dev/random >/dev/null 2>&1;
++ [ -e ${rootdir}/dev/urandom ] || touch ${rootdir}/dev/urandom
++ mount --bind -n /dev/urandom ${rootdir}/dev/urandom >/dev/null 2>&1;
+ fi;
+
+ # if not running, start it up here
+@@ -78,8 +78,8 @@
+ if egrep -q '^/[^[:space:]]+[[:space:]]+'${rootdir}'/dev/log' /proc/mounts; then
+ umount ${rootdir}/dev/log >/dev/null 2>&1
+ fi;
+- if egrep -q '^/[^[:space:]]+[[:space:]]+'${rootdir}'/dev/random' /proc/mounts; then
+- umount ${rootdir}/dev/random >/dev/null 2>&1
++ if egrep -q '^/[^[:space:]]+[[:space:]]+'${rootdir}'/dev/urandom' /proc/mounts; then
++ umount ${rootdir}/dev/urandom >/dev/null 2>&1
+ fi;
+ return $retval
+ }
+--- contrib/unbound/contrib/unbound.init_fedora.orig
++++ contrib/unbound/contrib/unbound.init_fedora
+@@ -42,7 +42,7 @@
+ cp -fp /etc/localtime ${rootdir}/etc/localtime
+ fi;
+ mount --bind -n /dev/log ${rootdir}/dev/log >/dev/null 2>&1;
+- mount --bind -n /dev/random ${rootdir}/dev/random >/dev/null 2>&1;
++ mount --bind -n /dev/urandom ${rootdir}/dev/urandom >/dev/null 2>&1;
+ mount --bind -n /var/run/unbound ${rootdir}/var/run/unbound >/dev/null 2>&1;
+
+ # if not running, start it up here
+@@ -58,7 +58,7 @@
+ killproc -p $pidfile unbound
+ retval=$?
+ [ $retval -eq 0 ] && rm -f $lockfile
+- for mountfile in /dev/log /dev/random /etc/localtime /etc/resolv.conf /var/run/unbound
++ for mountfile in /dev/log /dev/urandom /etc/localtime /etc/resolv.conf /var/run/unbound
+ do
+ if egrep -q '^/[^[:space:]]+[[:space:]]+'${rootdir}''${mountfile}'' /proc/mounts; then
+ umount ${rootdir}$mountfile >/dev/null 2>&1
+--- contrib/unbound/contrib/unbound.service.in.orig
++++ contrib/unbound/contrib/unbound.service.in
+@@ -0,0 +1,84 @@
++; For further details about the directives used in this unit file, including
++; the below, please refer to systemd's official documentation, available at
++; https://www.freedesktop.org/software/systemd/man/systemd.exec.html.
++;
++;
++; - `ProtectSystem=strict` implies we mount the entire file system hierarchy
++; read-only for the processes invoked by the unit except for the API file
++; system subtrees /dev, /proc and /sys (which are protected by
++; PrivateDevices=, ProtectKernelTunables=, ProtectControlGroups=).
++;
++; - `PrivateTmp=yes` secures access to temporary files of the process, and
++; makes sharing between processes via /tmp or /var/tmp impossible.
++;
++; - `ProtectHome=yes` makes the directories /home, /root, and /run/user
++; inaccessible and empty for processes invoked by the unit.
++;
++; - `ProtectControlGroups=yes` makes the Linux Control Groups hierarchies
++; (accessible through /sys/fs/cgroup) read-only to all processes invoked by
++; the unit. It also implies `MountAPIVFS=yes`.
++;
++; - `RuntimeDirectory=unbound` creates a /run/unbound directory, owned by the
++; unit User and Group with read-write permissions (0755) as soon as the
++; unit starts. This allows unbound to store its pidfile. The directory and
++; its content are automatically removed by systemd when the unit stops.
++;
++; - `NoNewPrivileges=yes` ensures that the service process and all its
++; children can never gain new privileges through execve().
++;
++; - `RestrictSUIDSGID=yes` ensures that any attempts to set the set-user-ID
++; (SUID) or set-group-ID (SGID) bits on files or directories will be denied.
++;
++; - `RestrictRealTime=yes` ensures that any attempts to enable realtime
++; scheduling in a process invoked by the unit will be denied.
++;
++; - `RestrictNamespaces=yes` ensures that access to any kind of namespacing
++; is prohibited.
++;
++; - `LockPersonality=yes` locks down the personality system call so that the
++; kernel execution domain may not be changed from the default.
++;
++;
++[Unit]
++Description=Validating, recursive, and caching DNS resolver
++Documentation=man:unbound(8)
++After=network.target
++Before=network-online.target nss-lookup.target
++Wants=nss-lookup.target
++
++[Install]
++WantedBy=multi-user.target
++
++[Service]
++ExecReload=+/bin/kill -HUP $MAINPID
++ExecStart=@UNBOUND_SBIN_DIR@/unbound -d -p
++NotifyAccess=main
++Type=notify
++CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_SYS_RESOURCE CAP_NET_RAW
++MemoryDenyWriteExecute=true
++NoNewPrivileges=true
++PrivateDevices=true
++PrivateTmp=true
++ProtectHome=true
++ProtectControlGroups=true
++ProtectKernelModules=true
++ProtectSystem=strict
++RuntimeDirectory=unbound
++ConfigurationDirectory=unbound
++StateDirectory=unbound
++RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
++RestrictRealtime=true
++SystemCallArchitectures=native
++SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module mount @obsolete @resources
++RestrictNamespaces=yes
++LockPersonality=yes
++RestrictSUIDSGID=yes
++ReadWritePaths=@UNBOUND_RUN_DIR@ @UNBOUND_CHROOT_DIR@
++
++# Below rules are needed when chroot is enabled (usually it's enabled by default).
++# If chroot is disabled like chrooot: "" then they may be safely removed.
++TemporaryFileSystem=@UNBOUND_CHROOT_DIR@/dev:ro
++TemporaryFileSystem=@UNBOUND_CHROOT_DIR@/run:ro
++BindReadOnlyPaths=-/run/systemd/notify:@UNBOUND_CHROOT_DIR@/run/systemd/notify
++BindReadOnlyPaths=-/dev/urandom:@UNBOUND_CHROOT_DIR@/dev/urandom
++BindPaths=-/dev/log:@UNBOUND_CHROOT_DIR@/dev/log
+--- contrib/unbound/contrib/unbound.socket.in.orig
++++ contrib/unbound/contrib/unbound.socket.in
+@@ -0,0 +1,6 @@
++[Socket]
++ListenDatagram=127.0.0.1:1153
++ListenStream=127.0.0.1:1153
++# ListenStream=@UNBOUND_RUN_DIR@/control
++[Install]
++WantedBy=sockets.target
+--- contrib/unbound/contrib/unbound_munin_.orig
++++ contrib/unbound/contrib/unbound_munin_
+@@ -150,7 +150,7 @@
+ fi
+ done
+ # try to get it
+- echo $$ >$lock
++ if echo $$ >$lock ; then : ; else break; fi
+ done
+ # do not refetch if the file exists and only LEE seconds old
+ if test -f $state; then
+@@ -242,6 +242,8 @@
+ p_config "total.num.prefetch" "cache prefetch" "ABSOLUTE"
+ p_config "num.query.tcp" "TCP queries" "ABSOLUTE"
+ p_config "num.query.tcpout" "TCP out queries" "ABSOLUTE"
++ p_config "num.query.tls" "TLS queries" "ABSOLUTE"
++ p_config "num.query.tls.resume" "TLS resumes" "ABSOLUTE"
+ p_config "num.query.ipv6" "IPv6 queries" "ABSOLUTE"
+ p_config "unwanted.queries" "queries that failed acl" "ABSOLUTE"
+ p_config "unwanted.replies" "unwanted or unsolicited replies" "ABSOLUTE"
+@@ -266,7 +268,6 @@
+ echo "graph_args --base 1024 -l 0"
+ echo "graph_vlabel memory used in bytes"
+ echo "graph_category DNS"
+- p_config "mem.total.sbrk" "Total memory" "GAUGE"
+ p_config "mem.cache.rrset" "RRset cache memory" "GAUGE"
+ p_config "mem.cache.message" "Message cache memory" "GAUGE"
+ p_config "mem.mod.iterator" "Iterator module memory" "GAUGE"
+@@ -444,7 +445,8 @@
+ for x in `grep "^thread[0-9][0-9]*\.num\.queries=" $state |
+ sed -e 's/=.*//'` total.num.queries \
+ total.num.cachehits total.num.prefetch num.query.tcp \
+- num.query.tcpout num.query.ipv6 unwanted.queries \
++ num.query.tcpout num.query.tls num.query.tls.resume \
++ num.query.ipv6 unwanted.queries \
+ unwanted.replies; do
+ if grep "^"$x"=" $state >/dev/null 2>&1; then
+ print_value $x
+@@ -458,20 +460,6 @@
+ done
+ ;;
+ memory)
+- mn=`echo mem.total.sbrk | sed $ABBREV | tr . _`
+- get_value 'mem.total.sbrk'
+- if test $value -eq 0; then
+- chk=`echo $ctrl | sed -e 's/-control$/-checkconf/'`
+- pidf=`$chk -o pidfile $conf 2>&1`
+- pid=`cat $pidf 2>&1`
+- value=`ps -p "$pid" -o rss= 2>&1`
+- if test "`expr $value + 1 - 1 2>&1`" -eq "$value" 2>&1; then
+- value=`expr $value \* 1024`
+- else
+- value=0
+- fi
+- fi
+- echo "$mn.value" $value
+ for x in mem.cache.rrset mem.cache.message mem.mod.iterator \
+ mem.mod.validator msg.cache.count rrset.cache.count \
+ infra.cache.count key.cache.count; do
+--- contrib/unbound/contrib/unbound_portable.service.in.orig
++++ contrib/unbound/contrib/unbound_portable.service.in
+@@ -0,0 +1,49 @@
++; This unit file is provided to run unbound as portable service.
++; https://systemd.io/PORTABLE_SERVICES/
++;
++; To use this unit file, please make sure you either compile unbound with the
++; following options:
++;
++; - --with-chroot-dir=""
++;
++; Or put the following options in your unbound configuration file:
++;
++; - chroot: ""
++;
++;
++[Unit]
++Description=Validating, recursive, and caching DNS resolver
++Documentation=man:unbound(8)
++After=network.target
++Before=network-online.target nss-lookup.target
++Wants=nss-lookup.target
++
++[Install]
++WantedBy=multi-user.target
++
++[Service]
++ExecReload=+/bin/kill -HUP $MAINPID
++ExecStart=@UNBOUND_SBIN_DIR@/unbound -d -p
++NotifyAccess=main
++Type=notify
++CapabilityBoundingSet=CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_CHROOT CAP_SYS_RESOURCE CAP_NET_RAW
++MemoryDenyWriteExecute=true
++NoNewPrivileges=true
++PrivateDevices=true
++PrivateTmp=true
++ProtectHome=true
++ProtectControlGroups=true
++ProtectKernelModules=true
++ProtectSystem=strict
++RuntimeDirectory=unbound
++ConfigurationDirectory=unbound
++StateDirectory=unbound
++RestrictAddressFamilies=AF_INET AF_INET6 AF_UNIX
++RestrictRealtime=true
++SystemCallArchitectures=native
++SystemCallFilter=~@clock @cpu-emulation @debug @keyring @module mount @obsolete @resources
++RestrictNamespaces=yes
++LockPersonality=yes
++RestrictSUIDSGID=yes
++BindPaths=/run/systemd/notify
++BindReadOnlyPaths=/dev/log /run/systemd/journal/socket /run/systemd/journal/stdout
+--- contrib/unbound/daemon/acl_list.c.orig
++++ contrib/unbound/daemon/acl_list.c
+@@ -111,6 +111,8 @@
+ control = acl_refuse_non_local;
+ else if(strcmp(s2, "allow_snoop") == 0)
+ control = acl_allow_snoop;
++ else if(strcmp(s2, "allow_setrd") == 0)
++ control = acl_allow_setrd;
+ else {
+ log_err("access control type %s unknown", str);
+ return 0;
+@@ -170,6 +172,23 @@
+ return 1;
+ }
+
++/** apply acl_view string */
++static int
++acl_list_view_cfg(struct acl_list* acl, const char* str, const char* str2,
++ struct views* vs)
++{
++ struct acl_addr* node;
++ if(!(node=acl_find_or_create(acl, str)))
++ return 0;
++ node->view = views_find_view(vs, str2, 0 /* get read lock*/);
++ if(!node->view) {
++ log_err("no view with name: %s", str2);
++ return 0;
++ }
++ lock_rw_unlock(&node->view->lock);
++ return 1;
++}
++
+ /** apply acl_tag_action string */
+ static int
+ acl_list_tag_action_cfg(struct acl_list* acl, struct config_file* cfg,
+@@ -210,15 +229,47 @@
+
+ /** check wire data parse */
+ static int
+-check_data(const char* data)
++check_data(const char* data, const struct config_strlist* head)
+ {
+ char buf[65536];
+ uint8_t rr[LDNS_RR_BUF_SIZE];
+ size_t len = sizeof(rr);
+ int res;
+- snprintf(buf, sizeof(buf), "%s %s", "example.com.", data);
++ /* '.' is sufficient for validation, and it makes the call to
++ * sldns_wirerr_get_type() simpler below. */
++ snprintf(buf, sizeof(buf), "%s %s", ".", data);
+ res = sldns_str2wire_rr_buf(buf, rr, &len, NULL, 3600, NULL, 0,
+ NULL, 0);
++
++ /* Reject it if we would end up having CNAME and other data (including
++ * another CNAME) for the same tag. */
++ if(res == 0 && head) {
++ const char* err_data = NULL;
++
++ if(sldns_wirerr_get_type(rr, len, 1) == LDNS_RR_TYPE_CNAME) {
++ /* adding CNAME while other data already exists. */
++ err_data = data;
++ } else {
++ snprintf(buf, sizeof(buf), "%s %s", ".", head->str);
++ len = sizeof(rr);
++ res = sldns_str2wire_rr_buf(buf, rr, &len, NULL, 3600,
++ NULL, 0, NULL, 0);
++ if(res != 0) {
++ /* This should be impossible here as head->str
++ * has been validated, but we check it just in
++ * case. */
++ return 0;
++ }
++ if(sldns_wirerr_get_type(rr, len, 1) ==
++ LDNS_RR_TYPE_CNAME) /* already have CNAME */
++ err_data = head->str;
++ }
++ if(err_data) {
++ log_err("redirect tag data '%s' must not coexist with "
++ "other data.", err_data);
++ return 0;
++ }
++ }
+ if(res == 0)
+ return 1;
+ log_err("rr data [char %d] parse error %s",
+@@ -258,7 +309,7 @@
+ }
+
+ /* check data? */
+- if(!check_data(data)) {
++ if(!check_data(data, node->tag_datas[tagid])) {
+ log_err("cannot parse access-control-tag data: %s %s '%s'",
+ str, tag, data);
+ return 0;
+@@ -312,6 +363,27 @@
+ return 1;
+ }
+
++/** read acl view config */
++static int
++read_acl_view(struct acl_list* acl, struct config_file* cfg, struct views* v)
++{
++ struct config_str2list* np, *p = cfg->acl_view;
++ cfg->acl_view = NULL;
++ while(p) {
++ log_assert(p->str && p->str2);
++ if(!acl_list_view_cfg(acl, p->str, p->str2, v)) {
++ return 0;
++ }
++ /* free the items as we go to free up memory */
++ np = p->next;
++ free(p->str);
++ free(p->str2);
++ free(p);
++ p = np;
++ }
++ return 1;
++}
++
+ /** read acl tag actions config */
+ static int
+ read_acl_tag_actions(struct acl_list* acl, struct config_file* cfg)
+@@ -362,12 +434,15 @@
+ }
+
+ int
+-acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg)
++acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg,
++ struct views* v)
+ {
+ regional_free_all(acl->region);
+ addr_tree_init(&acl->tree);
+ if(!read_acl_list(acl, cfg))
+ return 0;
++ if(!read_acl_view(acl, cfg, v))
++ return 0;
+ if(!read_acl_tags(acl, cfg))
+ return 0;
+ if(!read_acl_tag_actions(acl, cfg))
+--- contrib/unbound/daemon/acl_list.h.orig
++++ contrib/unbound/daemon/acl_list.h
+@@ -43,6 +43,7 @@
+ #ifndef DAEMON_ACL_LIST_H
+ #define DAEMON_ACL_LIST_H
+ #include "util/storage/dnstree.h"
++#include "services/view.h"
+ struct config_file;
+ struct regional;
+
+@@ -62,7 +63,9 @@
+ /** allow full access for recursion (+RD) queries */
+ acl_allow,
+ /** allow full access for all queries, recursion and cache snooping */
+- acl_allow_snoop
++ acl_allow_snoop,
++ /** allow full access for recursion queries and set RD flag regardless of request */
++ acl_allow_setrd
+ };
+
+ /**
+@@ -75,7 +78,7 @@
+ * Tree of the addresses that are allowed/blocked.
+ * contents of type acl_addr.
+ */
+- rbtree_t tree;
++ rbtree_type tree;
+ };
+
+ /**
+@@ -100,6 +103,8 @@
+ struct config_strlist** tag_datas;
+ /** size of the tag_datas array */
+ size_t tag_datas_size;
++ /* view element, NULL if none */
++ struct view* view;
+ };
+
+ /**
+@@ -118,9 +123,11 @@
+ * Process access control config.
+ * @param acl: where to store.
+ * @param cfg: config options.
++ * @param v: views structure
+ * @return 0 on error.
+ */
+-int acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg);
++int acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg,
++ struct views* v);
+
+ /**
+ * Lookup access control status for acl structure.
+--- contrib/unbound/daemon/cachedump.c.orig
++++ contrib/unbound/daemon/cachedump.c
+@@ -62,7 +62,7 @@
+
+ /** dump one rrset zonefile line */
+ static int
+-dump_rrset_line(SSL* ssl, struct ub_packed_rrset_key* k, time_t now, size_t i)
++dump_rrset_line(RES* ssl, struct ub_packed_rrset_key* k, time_t now, size_t i)
+ {
+ char s[65535];
+ if(!packed_rr_to_string(k, i, now, s, sizeof(s))) {
+@@ -73,12 +73,13 @@
+
+ /** dump rrset key and data info */
+ static int
+-dump_rrset(SSL* ssl, struct ub_packed_rrset_key* k,
++dump_rrset(RES* ssl, struct ub_packed_rrset_key* k,
+ struct packed_rrset_data* d, time_t now)
+ {
+ size_t i;
+ /* rd lock held by caller */
+ if(!k || !d) return 1;
++ if(k->id == 0) return 1; /* deleted */
+ if(d->ttl < now) return 1; /* expired */
+
+ /* meta line */
+@@ -98,7 +99,7 @@
+
+ /** dump lruhash rrset cache */
+ static int
+-dump_rrset_lruhash(SSL* ssl, struct lruhash* h, time_t now)
++dump_rrset_lruhash(RES* ssl, struct lruhash* h, time_t now)
+ {
+ struct lruhash_entry* e;
+ /* lruhash already locked by caller */
+@@ -117,7 +118,7 @@
+
+ /** dump rrset cache */
+ static int
+-dump_rrset_cache(SSL* ssl, struct worker* worker)
++dump_rrset_cache(RES* ssl, struct worker* worker)
+ {
+ struct rrset_cache* r = worker->env.rrset_cache;
+ size_t slab;
+@@ -136,7 +137,7 @@
+
+ /** dump message to rrset reference */
+ static int
+-dump_msg_ref(SSL* ssl, struct ub_packed_rrset_key* k)
++dump_msg_ref(RES* ssl, struct ub_packed_rrset_key* k)
+ {
+ char* nm, *tp, *cl;
+ nm = sldns_wire2str_dname(k->rk.dname, k->rk.dname_len);
+@@ -163,7 +164,7 @@
+
+ /** dump message entry */
+ static int
+-dump_msg(SSL* ssl, struct query_info* k, struct reply_info* d,
++dump_msg(RES* ssl, struct query_info* k, struct reply_info* d,
+ time_t now)
+ {
+ size_t i;
+@@ -245,7 +246,7 @@
+
+ /** dump lruhash msg cache */
+ static int
+-dump_msg_lruhash(SSL* ssl, struct worker* worker, struct lruhash* h)
++dump_msg_lruhash(RES* ssl, struct worker* worker, struct lruhash* h)
+ {
+ struct lruhash_entry* e;
+ struct query_info* k;
+@@ -273,7 +274,7 @@
+
+ /** dump msg cache */
+ static int
+-dump_msg_cache(SSL* ssl, struct worker* worker)
++dump_msg_cache(RES* ssl, struct worker* worker)
+ {
+ struct slabhash* sh = worker->env.msg_cache;
+ size_t slab;
+@@ -290,7 +291,7 @@
+ }
+
+ int
+-dump_cache(SSL* ssl, struct worker* worker)
++dump_cache(RES* ssl, struct worker* worker)
+ {
+ if(!dump_rrset_cache(ssl, worker))
+ return 0;
+@@ -301,7 +302,7 @@
+
+ /** read a line from ssl into buffer */
+ static int
+-ssl_read_buf(SSL* ssl, sldns_buffer* buf)
++ssl_read_buf(RES* ssl, sldns_buffer* buf)
+ {
+ return ssl_read_line(ssl, (char*)sldns_buffer_begin(buf),
+ sldns_buffer_capacity(buf));
+@@ -309,7 +310,7 @@
+
+ /** check fixed text on line */
+ static int
+-read_fixed(SSL* ssl, sldns_buffer* buf, const char* str)
++read_fixed(RES* ssl, sldns_buffer* buf, const char* str)
+ {
+ if(!ssl_read_buf(ssl, buf)) return 0;
+ return (strcmp((char*)sldns_buffer_begin(buf), str) == 0);
+@@ -317,7 +318,7 @@
+
+ /** load an RR into rrset */
+ static int
+-load_rr(SSL* ssl, sldns_buffer* buf, struct regional* region,
++load_rr(RES* ssl, sldns_buffer* buf, struct regional* region,
+ struct ub_packed_rrset_key* rk, struct packed_rrset_data* d,
+ unsigned int i, int is_rrsig, int* go_on, time_t now)
+ {
+@@ -434,7 +435,7 @@
+
+ /** load an rrset entry */
+ static int
+-load_rrset(SSL* ssl, sldns_buffer* buf, struct worker* worker)
++load_rrset(RES* ssl, sldns_buffer* buf, struct worker* worker)
+ {
+ char* s = (char*)sldns_buffer_begin(buf);
+ struct regional* region = worker->scratchpad;
+@@ -518,7 +519,7 @@
+
+ /** load rrset cache */
+ static int
+-load_rrset_cache(SSL* ssl, struct worker* worker)
++load_rrset_cache(RES* ssl, struct worker* worker)
+ {
+ sldns_buffer* buf = worker->env.scratch_buffer;
+ if(!read_fixed(ssl, buf, "START_RRSET_CACHE")) return 0;
+@@ -563,6 +564,7 @@
+ qinfo->qclass = sldns_wirerr_get_class(rr, rr_len, dname_len);
+ qinfo->qname_len = dname_len;
+ qinfo->qname = (uint8_t*)regional_alloc_init(region, rr, dname_len);
++ qinfo->local_alias = NULL;
+ if(!qinfo->qname) {
+ log_warn("error out of memory");
+ return NULL;
+@@ -573,7 +575,7 @@
+
+ /** load a msg rrset reference */
+ static int
+-load_ref(SSL* ssl, sldns_buffer* buf, struct worker* worker,
++load_ref(RES* ssl, sldns_buffer* buf, struct worker* worker,
+ struct regional *region, struct ub_packed_rrset_key** rrset,
+ int* go_on)
+ {
+@@ -618,7 +620,7 @@
+
+ /** load a msg entry */
+ static int
+-load_msg(SSL* ssl, sldns_buffer* buf, struct worker* worker)
++load_msg(RES* ssl, sldns_buffer* buf, struct worker* worker)
+ {
+ struct regional* region = worker->scratchpad;
+ struct query_info qinf;
+@@ -651,6 +653,7 @@
+ rep.qdcount = (uint16_t)qdcount;
+ rep.ttl = (time_t)ttl;
+ rep.prefetch_ttl = PREFETCH_TTL_CALC(rep.ttl);
++ rep.serve_expired_ttl = rep.ttl + SERVE_EXPIRED_TTL;
+ rep.security = (enum sec_status)security;
+ if(an > RR_COUNT_MAX || ns > RR_COUNT_MAX || ar > RR_COUNT_MAX) {
+ log_warn("error too many rrsets");
+@@ -683,7 +686,7 @@
+
+ /** load msg cache */
+ static int
+-load_msg_cache(SSL* ssl, struct worker* worker)
++load_msg_cache(RES* ssl, struct worker* worker)
+ {
+ sldns_buffer* buf = worker->env.scratch_buffer;
+ if(!read_fixed(ssl, buf, "START_MSG_CACHE")) return 0;
+@@ -696,7 +699,7 @@
+ }
+
+ int
+-load_cache(SSL* ssl, struct worker* worker)
++load_cache(RES* ssl, struct worker* worker)
+ {
+ if(!load_rrset_cache(ssl, worker))
+ return 0;
+@@ -707,7 +710,7 @@
+
+ /** print details on a delegation point */
+ static void
+-print_dp_details(SSL* ssl, struct worker* worker, struct delegpt* dp)
++print_dp_details(RES* ssl, struct worker* worker, struct delegpt* dp)
+ {
+ char buf[257];
+ struct delegpt_addr* a;
+@@ -783,7 +786,7 @@
+
+ /** print main dp info */
+ static void
+-print_dp_main(SSL* ssl, struct delegpt* dp, struct dns_msg* msg)
++print_dp_main(RES* ssl, struct delegpt* dp, struct dns_msg* msg)
+ {
+ size_t i, n_ns, n_miss, n_addr, n_res, n_avail;
+
+@@ -811,7 +814,7 @@
+ return;
+ }
+
+-int print_deleg_lookup(SSL* ssl, struct worker* worker, uint8_t* nm,
++int print_deleg_lookup(RES* ssl, struct worker* worker, uint8_t* nm,
+ size_t nmlen, int ATTR_UNUSED(nmlabs))
+ {
+ /* deep links into the iterator module */
+@@ -826,6 +829,7 @@
+ qinfo.qname_len = nmlen;
+ qinfo.qtype = LDNS_RR_TYPE_A;
+ qinfo.qclass = LDNS_RR_CLASS_IN;
++ qinfo.local_alias = NULL;
+
+ dname_str(nm, b);
+ if(!ssl_printf(ssl, "The following name servers are used for lookup "
+--- contrib/unbound/daemon/cachedump.h.orig
++++ contrib/unbound/daemon/cachedump.h
+@@ -72,6 +72,7 @@
+ #ifndef DAEMON_DUMPCACHE_H
+ #define DAEMON_DUMPCACHE_H
+ struct worker;
++#include "daemon/remote.h"
+
+ /**
+ * Dump cache(s) to text
+@@ -80,7 +81,7 @@
+ * ptrs to the caches.
+ * @return false on ssl print error.
+ */
+-int dump_cache(SSL* ssl, struct worker* worker);
++int dump_cache(RES* ssl, struct worker* worker);
+
+ /**
+ * Load cache(s) from text
+@@ -89,7 +90,7 @@
+ * ptrs to the caches.
+ * @return false on ssl error.
+ */
+-int load_cache(SSL* ssl, struct worker* worker);
++int load_cache(RES* ssl, struct worker* worker);
+
+ /**
+ * Print the delegation used to lookup for this name.
+@@ -101,7 +102,7 @@
+ * @param nmlabs: labels in name.
+ * @return false on ssl error.
+ */
+-int print_deleg_lookup(SSL* ssl, struct worker* worker, uint8_t* nm,
++int print_deleg_lookup(RES* ssl, struct worker* worker, uint8_t* nm,
+ size_t nmlen, int nmlabs);
+
+ #endif /* DAEMON_DUMPCACHE_H */
+--- contrib/unbound/daemon/daemon.c.orig
++++ contrib/unbound/daemon/daemon.c
+@@ -73,20 +73,29 @@
+ #include "util/log.h"
+ #include "util/config_file.h"
+ #include "util/data/msgreply.h"
++#include "util/shm_side/shm_main.h"
+ #include "util/storage/lookup3.h"
+ #include "util/storage/slabhash.h"
++#include "util/tcp_conn_limit.h"
+ #include "services/listen_dnsport.h"
+ #include "services/cache/rrset.h"
+ #include "services/cache/infra.h"
+ #include "services/localzone.h"
++#include "services/view.h"
+ #include "services/modstack.h"
++#include "services/authzone.h"
+ #include "util/module.h"
+ #include "util/random.h"
+ #include "util/tube.h"
+ #include "util/net_help.h"
+ #include "sldns/keyraw.h"
++#include "respip/respip.h"
+ #include <signal.h>
+
++#ifdef HAVE_SYSTEMD
++#include <systemd/sd-daemon.h>
++#endif
++
+ /** How many quit requests happened. */
+ static int sig_record_quit = 0;
+ /** How many reload requests happened. */
+@@ -96,10 +105,8 @@
+ /** cleaner ssl memory freeup */
+ static void* comp_meth = NULL;
+ #endif
+-#ifdef LEX_HAS_YYLEX_DESTROY
+ /** remove buffers for parsing and init */
+ int ub_c_lex_destroy(void);
+-#endif
+
+ /** used when no other sighandling happens, so we don't die
+ * when multiple signals in quick succession are sent to us.
+@@ -207,12 +214,16 @@
+ # ifdef HAVE_ERR_LOAD_CRYPTO_STRINGS
+ ERR_load_crypto_strings();
+ # endif
++#if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL)
+ ERR_load_SSL_strings();
++#endif
+ # ifdef USE_GOST
+ (void)sldns_key_EVP_load_gost_id();
+ # endif
+ # if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_CRYPTO)
++# ifndef S_SPLINT_S
+ OpenSSL_add_all_algorithms();
++# endif
+ # else
+ OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS
+ | OPENSSL_INIT_ADD_ALL_DIGESTS
+@@ -225,7 +236,7 @@
+ # if OPENSSL_VERSION_NUMBER < 0x10100000 || !defined(HAVE_OPENSSL_INIT_SSL)
+ (void)SSL_library_init();
+ # else
+- (void)OPENSSL_init_ssl(0, NULL);
++ (void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL);
+ # endif
+ # if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED)
+ if(!ub_openssl_lock_init())
+@@ -239,8 +250,6 @@
+ /* init timezone info while we are not chrooted yet */
+ tzset();
+ #endif
+- /* open /dev/random if needed */
+- ub_systemseed((unsigned)time(NULL)^(unsigned)getpid()^0xe67);
+ daemon->need_to_exit = 0;
+ modstack_init(&daemon->mods);
+ if(!(daemon->env = (struct module_env*)calloc(1,
+@@ -248,16 +257,39 @@
+ free(daemon);
+ return NULL;
+ }
++ /* init edns_known_options */
++ if(!edns_known_options_init(daemon->env)) {
++ free(daemon->env);
++ free(daemon);
++ return NULL;
++ }
+ alloc_init(&daemon->superalloc, NULL, 0);
+ daemon->acl = acl_list_create();
+ if(!daemon->acl) {
++ edns_known_options_delete(daemon->env);
+ free(daemon->env);
+ free(daemon);
+ return NULL;
+ }
++ daemon->tcl = tcl_list_create();
++ if(!daemon->tcl) {
++ acl_list_delete(daemon->acl);
++ edns_known_options_delete(daemon->env);
++ free(daemon->env);
++ free(daemon);
++ return NULL;
++ }
+ if(gettimeofday(&daemon->time_boot, NULL) < 0)
+ log_err("gettimeofday: %s", strerror(errno));
+ daemon->time_last_stat = daemon->time_boot;
++ if((daemon->env->auth_zones = auth_zones_create()) == 0) {
++ acl_list_delete(daemon->acl);
++ tcl_list_delete(daemon->tcl);
++ edns_known_options_delete(daemon->env);
++ free(daemon->env);
++ free(daemon);
++ return NULL;
++ }
+ return daemon;
+ }
+
+@@ -347,6 +379,7 @@
+ daemon->env)) {
+ fatal_exit("failed to setup modules");
+ }
++ log_edns_known_options(VERB_ALGO, daemon->env);
+ }
+
+ /**
+@@ -394,13 +427,11 @@
+ int* shufport;
+ log_assert(daemon && daemon->cfg);
+ if(!daemon->rand) {
+- unsigned int seed = (unsigned int)time(NULL) ^
+- (unsigned int)getpid() ^ 0x438;
+- daemon->rand = ub_initstate(seed, NULL);
++ daemon->rand = ub_initstate(NULL);
+ if(!daemon->rand)
+ fatal_exit("could not init random generator");
++ hash_set_raninit((uint32_t)ub_random(daemon->rand));
+ }
+- hash_set_raninit((uint32_t)ub_random(daemon->rand));
+ shufport = (int*)calloc(65536, sizeof(int));
+ if(!shufport)
+ fatal_exit("out of memory during daemon init");
+@@ -541,17 +572,71 @@
+ void
+ daemon_fork(struct daemon* daemon)
+ {
++ int have_view_respip_cfg = 0;
++#ifdef HAVE_SYSTEMD
++ int ret;
++#endif
++
+ log_assert(daemon);
+- if(!acl_list_apply_cfg(daemon->acl, daemon->cfg))
++ if(!(daemon->views = views_create()))
++ fatal_exit("Could not create views: out of memory");
++ /* create individual views and their localzone/data trees */
++ if(!views_apply_cfg(daemon->views, daemon->cfg))
++ fatal_exit("Could not set up views");
++
++ if(!acl_list_apply_cfg(daemon->acl, daemon->cfg, daemon->views))
+ fatal_exit("Could not setup access control list");
++ if(!tcl_list_apply_cfg(daemon->tcl, daemon->cfg))
++ fatal_exit("Could not setup TCP connection limits");
++ if(daemon->cfg->dnscrypt) {
++#ifdef USE_DNSCRYPT
++ daemon->dnscenv = dnsc_create();
++ if (!daemon->dnscenv)
++ fatal_exit("dnsc_create failed");
++ dnsc_apply_cfg(daemon->dnscenv, daemon->cfg);
++#else
++ fatal_exit("dnscrypt enabled in config but unbound was not built with "
++ "dnscrypt support");
++#endif
++ }
++ /* create global local_zones */
+ if(!(daemon->local_zones = local_zones_create()))
+ fatal_exit("Could not create local zones: out of memory");
+ if(!local_zones_apply_cfg(daemon->local_zones, daemon->cfg))
+ fatal_exit("Could not set up local zones");
+
++ /* process raw response-ip configuration data */
++ if(!(daemon->respip_set = respip_set_create()))
++ fatal_exit("Could not create response IP set");
++ if(!respip_global_apply_cfg(daemon->respip_set, daemon->cfg))
++ fatal_exit("Could not set up response IP set");
++ if(!respip_views_apply_cfg(daemon->views, daemon->cfg,
++ &have_view_respip_cfg))
++ fatal_exit("Could not set up per-view response IP sets");
++ daemon->use_response_ip = !respip_set_is_empty(daemon->respip_set) ||
++ have_view_respip_cfg;
++
++ /* read auth zonefiles */
++ if(!auth_zones_apply_cfg(daemon->env->auth_zones, daemon->cfg, 1,
++ &daemon->use_rpz))
++ fatal_exit("auth_zones could not be setup");
++
+ /* setup modules */
+ daemon_setup_modules(daemon);
+
++ /* response-ip-xxx options don't work as expected without the respip
++ * module. To avoid run-time operational surprise we reject such
++ * configuration. */
++ if(daemon->use_response_ip &&
++ modstack_find(&daemon->mods, "respip") < 0)
++ fatal_exit("response-ip options require respip module");
++ /* RPZ response ip triggers don't work as expected without the respip
++ * module. To avoid run-time operational surprise we reject such
++ * configuration. */
++ if(daemon->use_rpz &&
++ modstack_find(&daemon->mods, "respip") < 0)
++ fatal_exit("RPZ requires the respip module");
++
+ /* first create all the worker structures, so we can pass
+ * them to the newly created threads.
+ */
+@@ -578,14 +663,34 @@
+ #endif
+ signal_handling_playback(daemon->workers[0]);
+
++ if (!shm_main_init(daemon))
++ log_warn("SHM has failed");
++
+ /* Start resolver service on main thread. */
++#ifdef HAVE_SYSTEMD
++ ret = sd_notify(0, "READY=1");
++ if(ret <= 0 && getenv("NOTIFY_SOCKET"))
++ fatal_exit("sd_notify failed %s: %s. Make sure that unbound has "
++ "access/permission to use the socket presented by systemd.",
++ getenv("NOTIFY_SOCKET"),
++ (ret==0?"no $NOTIFY_SOCKET": strerror(-ret)));
++#endif
+ log_info("start of service (%s).", PACKAGE_STRING);
+ worker_work(daemon->workers[0]);
++#ifdef HAVE_SYSTEMD
++ if (daemon->workers[0]->need_to_exit)
++ sd_notify(0, "STOPPING=1");
++ else
++ sd_notify(0, "RELOADING=1");
++#endif
+ log_info("service stopped (%s).", PACKAGE_STRING);
+
+ /* we exited! a signal happened! Stop other threads */
+ daemon_stop_others(daemon);
+
++ /* Shutdown SHM */
++ shm_main_shutdown(daemon);
++
+ daemon->need_to_exit = daemon->workers[0]->need_to_exit;
+ }
+
+@@ -605,6 +710,12 @@
+ slabhash_clear(daemon->env->msg_cache);
+ local_zones_delete(daemon->local_zones);
+ daemon->local_zones = NULL;
++ respip_set_delete(daemon->respip_set);
++ daemon->respip_set = NULL;
++ views_delete(daemon->views);
++ daemon->views = NULL;
++ if(daemon->env->auth_zones)
++ auth_zones_cleanup(daemon->env->auth_zones);
+ /* key cache is cleared by module desetup during next daemon_fork() */
+ daemon_remote_clear(daemon->rc);
+ for(i=0; i<daemon->num; i++)
+@@ -612,9 +723,15 @@
+ free(daemon->workers);
+ daemon->workers = NULL;
+ daemon->num = 0;
++ alloc_clear_special(&daemon->superalloc);
+ #ifdef USE_DNSTAP
+ dt_delete(daemon->dtenv);
++ daemon->dtenv = NULL;
+ #endif
++#ifdef USE_DNSCRYPT
++ dnsc_delete(daemon->dnscenv);
++ daemon->dnscenv = NULL;
++#endif
+ daemon->cfg = NULL;
+ }
+
+@@ -634,22 +751,24 @@
+ slabhash_delete(daemon->env->msg_cache);
+ rrset_cache_delete(daemon->env->rrset_cache);
+ infra_delete(daemon->env->infra_cache);
++ edns_known_options_delete(daemon->env);
++ auth_zones_delete(daemon->env->auth_zones);
+ }
+ ub_randfree(daemon->rand);
+ alloc_clear(&daemon->superalloc);
+ acl_list_delete(daemon->acl);
++ tcl_list_delete(daemon->tcl);
+ free(daemon->chroot);
+ free(daemon->pidfile);
+ free(daemon->env);
+ #ifdef HAVE_SSL
++ listen_sslctx_delete_ticket_keys();
+ SSL_CTX_free((SSL_CTX*)daemon->listen_sslctx);
+ SSL_CTX_free((SSL_CTX*)daemon->connect_sslctx);
+ #endif
+ free(daemon);
+-#ifdef LEX_HAS_YYLEX_DESTROY
+ /* lex cleanup */
+ ub_c_lex_destroy();
+-#endif
+ /* libcrypto cleanup */
+ #ifdef HAVE_SSL
+ # if defined(USE_GOST) && defined(HAVE_LDNS_KEY_EVP_UNLOAD_GOST)
+@@ -664,7 +783,7 @@
+ # endif
+ # ifdef HAVE_OPENSSL_CONFIG
+ EVP_cleanup();
+-# if OPENSSL_VERSION_NUMBER < 0x10100000
++# if (OPENSSL_VERSION_NUMBER < 0x10100000) && !defined(OPENSSL_NO_ENGINE)
+ ENGINE_cleanup();
+ # endif
+ CONF_modules_free();
+@@ -681,6 +800,9 @@
+ # if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED)
+ ub_openssl_lock_delete();
+ # endif
++#ifndef HAVE_ARC4RANDOM
++ _ARC4_LOCK_DESTROY();
++#endif
+ #elif defined(HAVE_NSS)
+ NSS_Shutdown();
+ #endif /* HAVE_SSL or HAVE_NSS */
+@@ -697,9 +819,8 @@
+ {
+ daemon->cfg = cfg;
+ config_apply(cfg);
+- if(!daemon->env->msg_cache ||
+- cfg->msg_cache_size != slabhash_get_size(daemon->env->msg_cache) ||
+- cfg->msg_cache_slabs != daemon->env->msg_cache->size) {
++ if(!slabhash_is_size(daemon->env->msg_cache, cfg->msg_cache_size,
++ cfg->msg_cache_slabs)) {
+ slabhash_delete(daemon->env->msg_cache);
+ daemon->env->msg_cache = slabhash_create(cfg->msg_cache_slabs,
+ HASH_DEFAULT_STARTARRAY, cfg->msg_cache_size,
+--- contrib/unbound/daemon/daemon.h.orig
++++ contrib/unbound/daemon/daemon.h
+@@ -53,8 +53,11 @@
+ struct rrset_cache;
+ struct acl_list;
+ struct local_zones;
++struct views;
+ struct ub_randstate;
+ struct daemon_remote;
++struct respip_set;
++struct shm_main_info;
+
+ #include "dnstap/dnstap_config.h"
+ #ifdef USE_DNSTAP
+@@ -61,6 +64,11 @@
+ struct dt_env;
+ #endif
+
++#include "dnscrypt/dnscrypt_config.h"
++#ifdef USE_DNSCRYPT
++struct dnsc_env;
++#endif
++
+ /**
+ * Structure holding worker list.
+ * Holds globally visible information.
+@@ -105,6 +113,8 @@
+ struct module_stack mods;
+ /** access control, which client IPs are allowed to connect */
+ struct acl_list* acl;
++ /** TCP connection limit, limit connections from client IPs */
++ struct tcl_list* tcl;
+ /** local authority zones */
+ struct local_zones* local_zones;
+ /** last time of statistics printout */
+@@ -111,10 +121,23 @@
+ struct timeval time_last_stat;
+ /** time when daemon started */
+ struct timeval time_boot;
++ /** views structure containing view tree */
++ struct views* views;
+ #ifdef USE_DNSTAP
+ /** the dnstap environment master value, copied and changed by threads*/
+ struct dt_env* dtenv;
+ #endif
++ struct shm_main_info* shm_info;
++ /** response-ip set with associated actions and tags. */
++ struct respip_set* respip_set;
++ /** some response-ip tags or actions are configured if true */
++ int use_response_ip;
++ /** some RPZ policies are configured */
++ int use_rpz;
++#ifdef USE_DNSCRYPT
++ /** the dnscrypt environment */
++ struct dnsc_env* dnscenv;
++#endif
+ };
+
+ /**
+--- contrib/unbound/daemon/remote.c.orig
++++ contrib/unbound/daemon/remote.c
+@@ -68,6 +68,8 @@
+ #include "services/cache/infra.h"
+ #include "services/mesh.h"
+ #include "services/localzone.h"
++#include "services/authzone.h"
++#include "services/rpz.h"
+ #include "util/storage/slabhash.h"
+ #include "util/fptr_wlist.h"
+ #include "util/data/dname.h"
+@@ -124,7 +126,7 @@
+
+ /** divide sum of timers to get average */
+ static void
+-timeval_divide(struct timeval* avg, const struct timeval* sum, size_t d)
++timeval_divide(struct timeval* avg, const struct timeval* sum, long long d)
+ {
+ #ifndef S_SPLINT_S
+ size_t leftover;
+@@ -141,125 +143,20 @@
+ #endif
+ }
+
+-/*
+- * The following function was generated using the openssl utility, using
+- * the command : "openssl dhparam -C 2048"
+- * (some openssl versions reject DH that is 'too small', eg. 512).
+- */
+-#ifndef S_SPLINT_S
+-static DH *get_dh2048(void)
++static int
++remote_setup_ctx(struct daemon_remote* rc, struct config_file* cfg)
+ {
+- static unsigned char dh2048_p[]={
+- 0xE7,0x36,0x28,0x3B,0xE4,0xC3,0x32,0x1C,0x01,0xC3,0x67,0xD6,
+- 0xF5,0xF3,0xDA,0xDC,0x71,0xC0,0x42,0x8B,0xE6,0xEB,0x8D,0x80,
+- 0x35,0x7F,0x09,0x45,0x30,0xE5,0xB2,0x92,0x81,0x3F,0x08,0xCD,
+- 0x36,0x5E,0x19,0x83,0x62,0xCC,0xAE,0x9B,0x81,0x66,0x24,0xEE,
+- 0x16,0x6F,0xA9,0x9E,0xF4,0x82,0x1B,0xDD,0x46,0xC7,0x33,0x5D,
+- 0xF4,0xCA,0xE6,0x8F,0xFC,0xD4,0xD8,0x58,0x94,0x24,0x5D,0xFF,
+- 0x0A,0xE8,0xEF,0x3D,0xCE,0xBB,0x50,0x94,0xE0,0x5F,0xE8,0x41,
+- 0xC3,0x35,0x30,0x37,0xD5,0xCB,0x8F,0x3D,0x95,0x15,0x1A,0x77,
+- 0x42,0xB2,0x06,0x86,0xF6,0x09,0x66,0x0E,0x9A,0x25,0x94,0x3E,
+- 0xD2,0x04,0x25,0x25,0x1D,0x23,0xEB,0xDC,0x4D,0x0C,0x83,0x28,
+- 0x2E,0x15,0x81,0x2D,0xC1,0xAF,0x8D,0x36,0x64,0xE3,0x9A,0x83,
+- 0x78,0xC2,0x8D,0xC0,0x9D,0xD9,0x3A,0x1C,0xC5,0x2B,0x50,0x68,
+- 0x07,0xA9,0x4B,0x8C,0x07,0x57,0xD6,0x15,0x03,0x4E,0x9E,0x01,
+- 0xF2,0x6F,0x35,0xAC,0x26,0x9C,0x92,0x68,0x61,0x13,0xFB,0x01,
+- 0xBA,0x22,0x36,0x01,0x55,0xB6,0x62,0xD9,0xB2,0x98,0xCE,0x5D,
+- 0x4B,0xA5,0x41,0xD6,0xE5,0x70,0x78,0x12,0x1F,0x64,0xB6,0x6F,
+- 0xB0,0x91,0x51,0x91,0x92,0xC0,0x94,0x3A,0xD1,0x28,0x4D,0x30,
+- 0x84,0x3E,0xE4,0xE4,0x7F,0x47,0x89,0xB1,0xB6,0x8C,0x8E,0x0E,
+- 0x26,0xDB,0xCD,0x17,0x07,0x2A,0x21,0x7A,0xCC,0x68,0xE8,0x57,
+- 0x94,0x9E,0x59,0x61,0xEC,0x20,0x34,0x26,0x0D,0x66,0x44,0xEB,
+- 0x6F,0x02,0x58,0xE2,0xED,0xF6,0xF3,0x1B,0xBF,0x9E,0x45,0x52,
+- 0x5A,0x49,0xA1,0x5B,
+- };
+- static unsigned char dh2048_g[]={
+- 0x02,
+- };
+- DH *dh = NULL;
+- BIGNUM *p = NULL, *g = NULL;
+-
+- dh = DH_new();
+- p = BN_bin2bn(dh2048_p, sizeof(dh2048_p), NULL);
+- g = BN_bin2bn(dh2048_g, sizeof(dh2048_g), NULL);
+- if (!dh || !p || !g)
+- goto err;
+-
+-#if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL)
+- dh->p = p;
+- dh->g = g;
+-#else
+- if (!DH_set0_pqg(dh, p, NULL, g))
+- goto err;
+-#endif
+- return dh;
+-err:
+- if (p)
+- BN_free(p);
+- if (g)
+- BN_free(g);
+- if (dh)
+- DH_free(dh);
+- return NULL;
+-}
+-#endif /* SPLINT */
+-
+-struct daemon_remote*
+-daemon_remote_create(struct config_file* cfg)
+-{
+ char* s_cert;
+ char* s_key;
+- struct daemon_remote* rc = (struct daemon_remote*)calloc(1,
+- sizeof(*rc));
+- if(!rc) {
+- log_err("out of memory in daemon_remote_create");
+- return NULL;
+- }
+- rc->max_active = 10;
+-
+- if(!cfg->remote_control_enable) {
+- rc->ctx = NULL;
+- return rc;
+- }
+ rc->ctx = SSL_CTX_new(SSLv23_server_method());
+ if(!rc->ctx) {
+ log_crypto_err("could not SSL_CTX_new");
+- free(rc);
+- return NULL;
++ return 0;
+ }
+- /* no SSLv2, SSLv3 because has defects */
+- if((SSL_CTX_set_options(rc->ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2)
+- != SSL_OP_NO_SSLv2){
+- log_crypto_err("could not set SSL_OP_NO_SSLv2");
+- daemon_remote_delete(rc);
+- return NULL;
++ if(!listen_sslctx_setup(rc->ctx)) {
++ return 0;
+ }
+- if((SSL_CTX_set_options(rc->ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3)
+- != SSL_OP_NO_SSLv3){
+- log_crypto_err("could not set SSL_OP_NO_SSLv3");
+- daemon_remote_delete(rc);
+- return NULL;
+- }
+
+- if (cfg->remote_control_use_cert == 0) {
+- /* No certificates are requested */
+- if(!SSL_CTX_set_cipher_list(rc->ctx, "aNULL")) {
+- log_crypto_err("Failed to set aNULL cipher list");
+- daemon_remote_delete(rc);
+- return NULL;
+- }
+-
+- /* Since we have no certificates and hence no source of
+- * DH params, let's generate and set them
+- */
+- if(!SSL_CTX_set_tmp_dh(rc->ctx,get_dh2048())) {
+- log_crypto_err("Wanted to set DH param, but failed");
+- daemon_remote_delete(rc);
+- return NULL;
+- }
+- return rc;
+- }
+- rc->use_cert = 1;
+ s_cert = fname_after_chroot(cfg->server_cert_file, cfg, 1);
+ s_key = fname_after_chroot(cfg->server_key_file, cfg, 1);
+ if(!s_cert || !s_key) {
+@@ -282,36 +179,52 @@
+ log_crypto_err("Error in SSL_CTX check_private_key");
+ goto setup_error;
+ }
+-#if HAVE_DECL_SSL_CTX_SET_ECDH_AUTO
+- if(!SSL_CTX_set_ecdh_auto(rc->ctx,1)) {
+- log_crypto_err("Error in SSL_CTX_ecdh_auto, not enabling ECDHE");
+- }
+-#elif defined(USE_ECDSA)
+- if(1) {
+- EC_KEY *ecdh = EC_KEY_new_by_curve_name (NID_X9_62_prime256v1);
+- if (!ecdh) {
+- log_crypto_err("could not find p256, not enabling ECDHE");
+- } else {
+- if (1 != SSL_CTX_set_tmp_ecdh (rc->ctx, ecdh)) {
+- log_crypto_err("Error in SSL_CTX_set_tmp_ecdh, not enabling ECDHE");
+- }
+- EC_KEY_free (ecdh);
+- }
+- }
+-#endif
++ listen_sslctx_setup_2(rc->ctx);
+ if(!SSL_CTX_load_verify_locations(rc->ctx, s_cert, NULL)) {
+ log_crypto_err("Error setting up SSL_CTX verify locations");
+ setup_error:
+ free(s_cert);
+ free(s_key);
+- daemon_remote_delete(rc);
+- return NULL;
++ return 0;
+ }
+ SSL_CTX_set_client_CA_list(rc->ctx, SSL_load_client_CA_file(s_cert));
+ SSL_CTX_set_verify(rc->ctx, SSL_VERIFY_PEER, NULL);
+ free(s_cert);
+ free(s_key);
++ return 1;
++}
+
++struct daemon_remote*
++daemon_remote_create(struct config_file* cfg)
++{
++ struct daemon_remote* rc = (struct daemon_remote*)calloc(1,
++ sizeof(*rc));
++ if(!rc) {
++ log_err("out of memory in daemon_remote_create");
++ return NULL;
++ }
++ rc->max_active = 10;
++
++ if(!cfg->remote_control_enable) {
++ rc->ctx = NULL;
++ return rc;
++ }
++ if(options_remote_is_address(cfg) && cfg->control_use_cert) {
++ if(!remote_setup_ctx(rc, cfg)) {
++ daemon_remote_delete(rc);
++ return NULL;
++ }
++ rc->use_cert = 1;
++ } else {
++ struct config_strlist* p;
++ rc->ctx = NULL;
++ rc->use_cert = 0;
++ if(!options_remote_is_address(cfg))
++ for(p = cfg->control_ifs.first; p; p = p->next) {
++ if(p->str && p->str[0] != '/')
++ log_warn("control-interface %s is not using TLS, but plain transfer, because first control-interface in config file is a local socket (starts with a /).", p->str);
++ }
++ }
+ return rc;
+ }
+
+@@ -363,16 +276,17 @@
+ struct addrinfo hints;
+ struct addrinfo* res;
+ struct listen_port* n;
+- int noproto;
++ int noproto = 0;
+ int fd, r;
+ char port[15];
+ snprintf(port, sizeof(port), "%d", nr);
+ port[sizeof(port)-1]=0;
+ memset(&hints, 0, sizeof(hints));
++ log_assert(ip);
+
+ if(ip[0] == '/') {
+ /* This looks like a local socket */
+- fd = create_local_accept_sock(ip, &noproto);
++ fd = create_local