[packages/ldns] - up to 1.7.1, soname changed to so.1(?), add upstream git fixes
baggins
baggins at pld-linux.org
Sun Oct 17 22:03:46 CEST 2021
commit e3e3dab93b4b56bc0b9a79657bb82fe47eab59fe
Author: Jan Rękorajski <baggins at pld-linux.org>
Date: Sun Oct 17 22:02:49 2021 +0200
- up to 1.7.1, soname changed to so.1(?), add upstream git fixes
git.patch | 7842 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
ldns-link.patch | 15 +-
ldns.spec | 26 +-
3 files changed, 7852 insertions(+), 31 deletions(-)
---
diff --git a/ldns.spec b/ldns.spec
index 6e80bf7..d0d0949 100644
--- a/ldns.spec
+++ b/ldns.spec
@@ -7,14 +7,15 @@
Summary: ldns - a library with the aim to simplify DNS programing in C
Summary(pl.UTF-8): ldns - biblioteka mająca na celu uproszczenie programowania DNS w C
Name: ldns
-Version: 1.7.0
-Release: 4
+Version: 1.7.1
+Release: 1
License: BSD
Group: Libraries
Source0: http://www.nlnetlabs.nl/downloads/ldns/%{name}-%{version}.tar.gz
-# Source0-md5: 74b75c9ba69fb3af2a0c26244ecfd9f6
+# Source0-md5: 166262a46995d9972aba417fd091acd5
Patch0: python-install.patch
Patch1: %{name}-link.patch
+Patch100: git.patch
URL: http://www.nlnetlabs.nl/ldns/
BuildRequires: autoconf >= 2.56
BuildRequires: automake
@@ -114,6 +115,7 @@ nie będa wspierane.
%prep
%setup -q
+%patch100 -p1
%patch0 -p1
%patch1 -p1
@@ -123,6 +125,7 @@ nie będa wspierane.
%{__autoconf}
%{__autoheader}
%configure \
+ --with-examples \
--enable-gost-anyway \
%{!?with_dane:--disable-dane-ta-usage} \
--enable-static%{!?with_static_libs:=no} \
@@ -131,15 +134,6 @@ nie będa wspierane.
%{__make}
%{__make} doc
-cd examples
-%{__libtoolize}
-%{__aclocal}
-%{__autoconf}
-%{__autoheader}
-%configure
-%{__make}
-cd ..
-
# change symlinks into .so redirects
cd doc/man/man3
for f in `find . -type l`; do
@@ -164,11 +158,6 @@ rm -rf $RPM_BUILD_ROOT
%py_postclean
%endif
-cd examples
-%{__make} install \
- DESTDIR=$RPM_BUILD_ROOT
-cd ..
-
%clean
rm -rf $RPM_BUILD_ROOT
@@ -179,7 +168,7 @@ rm -rf $RPM_BUILD_ROOT
%defattr(644,root,root,755)
%doc Changelog LICENSE README
%attr(755,root,root) %{_libdir}/libldns.so.*.*.*
-%attr(755,root,root) %ghost %{_libdir}/libldns.so.2
+%attr(755,root,root) %ghost %{_libdir}/libldns.so.1
%files devel
%defattr(644,root,root,755)
@@ -187,6 +176,7 @@ rm -rf $RPM_BUILD_ROOT
%attr(755,root,root) %{_bindir}/ldns-config
%attr(755,root,root) %{_libdir}/libldns.so
%{_libdir}/libldns.la
+%{_pkgconfigdir}/ldns.pc
%{_includedir}/%{name}
%{_mandir}/man1/ldns-config.1*
%{_mandir}/man3/ldns_*.3*
diff --git a/git.patch b/git.patch
new file mode 100644
index 0000000..54208f3
--- /dev/null
+++ b/git.patch
@@ -0,0 +1,7842 @@
+diff -ur ldns-1.7.1/acx_nlnetlabs.m4 ldns/acx_nlnetlabs.m4
+--- ldns-1.7.1/acx_nlnetlabs.m4 2019-07-26 17:07:44.000000000 +0200
++++ ldns/acx_nlnetlabs.m4 2021-10-17 21:21:57.612895984 +0200
+@@ -2,7 +2,15 @@
+ # Copyright 2009, Wouter Wijngaards, NLnet Labs.
+ # BSD licensed.
+ #
+-# Version 34
++# Version 41
++# 2021-07-30 fix for openssl use of lib64 directory.
++# 2021-06-14 fix nonblocking test to use host instead of target for mingw test.
++# 2021-05-17 fix nonblocking socket test from grep on mingw32 to mingw for
++# 64bit compatibility.
++# 2021-03-24 fix ACX_FUNC_DEPRECATED to use CPPFLAGS and CFLAGS.
++# 2021-01-05 fix defun for aclocal
++# 2021-01-05 autoconf 2.70 autoupdate and fixes, no AC_TRY_COMPILE
++# 2020-08-24 Use EVP_sha256 instead of HMAC_Update (for openssl-3.0.0).
+ # 2016-03-21 Check -ldl -pthread for libcrypto for ldns and openssl 1.1.0.
+ # 2016-03-21 Use HMAC_Update instead of HMAC_CTX_Init (for openssl-1.1.0).
+ # 2016-01-04 -D_DEFAULT_SOURCE defined with -D_BSD_SOURCE for Linux glibc 2.20
+@@ -446,15 +454,12 @@
+ AC_MSG_CHECKING(whether the C compiler (${CC-cc}) accepts the "format" attribute)
+ AC_CACHE_VAL(ac_cv_c_format_attribute,
+ [ac_cv_c_format_attribute=no
+-AC_TRY_COMPILE(
+-[#include <stdio.h>
++AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stdio.h>
+ void f (char *format, ...) __attribute__ ((format (printf, 1, 2)));
+ void (*pf) (char *format, ...) __attribute__ ((format (printf, 1, 2)));
+-], [
++]], [[
+ f ("%s", "str");
+-],
+-[ac_cv_c_format_attribute="yes"],
+-[ac_cv_c_format_attribute="no"])
++]])],[ac_cv_c_format_attribute="yes"],[ac_cv_c_format_attribute="no"])
+ ])
+
+ AC_MSG_RESULT($ac_cv_c_format_attribute)
+@@ -483,14 +488,11 @@
+ AC_MSG_CHECKING(whether the C compiler (${CC-cc}) accepts the "unused" attribute)
+ AC_CACHE_VAL(ac_cv_c_unused_attribute,
+ [ac_cv_c_unused_attribute=no
+-AC_TRY_COMPILE(
+-[#include <stdio.h>
++AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stdio.h>
+ void f (char *u __attribute__((unused)));
+-], [
++]], [[
+ f ("x");
+-],
+-[ac_cv_c_unused_attribute="yes"],
+-[ac_cv_c_unused_attribute="no"])
++]])],[ac_cv_c_unused_attribute="yes"],[ac_cv_c_unused_attribute="no"])
+ ])
+
+ dnl Setup ATTR_UNUSED config.h parts.
+@@ -547,7 +549,7 @@
+ dnl because libtools 'AC_REQUIRE' names are right after this one, before
+ dnl this function contents.
+ AC_REQUIRE([ACX_LIBTOOL_C_PRE])
+-AC_PROG_LIBTOOL
++LT_INIT
+ ])
+
+ dnl Detect if u_char type is defined, otherwise define it.
+@@ -646,7 +648,7 @@
+ if test x_$withval != x_no; then
+ AC_MSG_CHECKING(for SSL)
+ if test x_$withval = x_ -o x_$withval = x_yes; then
+- withval="/usr/local/ssl /usr/lib/ssl /usr/ssl /usr/pkg /usr/local /opt/local /usr/local/opt/openssl /usr/sfw /usr"
++ withval="/usr/local/ssl /usr/lib/ssl /usr/ssl /usr/pkg /usr/local /opt/local /usr/sfw /usr"
+ fi
+ for dir in $withval; do
+ ssldir="$dir"
+@@ -668,22 +670,28 @@
+ HAVE_SSL=yes
+ dnl assume /usr is already in the lib and dynlib paths.
+ if test "$ssldir" != "/usr" -a "$ssldir" != ""; then
+- LDFLAGS="$LDFLAGS -L$ssldir/lib"
+- LIBSSL_LDFLAGS="$LIBSSL_LDFLAGS -L$ssldir/lib"
+- ACX_RUNTIME_PATH_ADD([$ssldir/lib])
++ if test ! -d "$ssldir/lib" -a -d "$ssldir/lib64"; then
++ LDFLAGS="$LDFLAGS -L$ssldir/lib64"
++ LIBSSL_LDFLAGS="$LIBSSL_LDFLAGS -L$ssldir/lib64"
++ ACX_RUNTIME_PATH_ADD([$ssldir/lib64])
++ else
++ LDFLAGS="$LDFLAGS -L$ssldir/lib"
++ LIBSSL_LDFLAGS="$LIBSSL_LDFLAGS -L$ssldir/lib"
++ ACX_RUNTIME_PATH_ADD([$ssldir/lib])
++ fi
+ fi
+
+- AC_MSG_CHECKING([for HMAC_Update in -lcrypto])
++ AC_MSG_CHECKING([for EVP_sha256 in -lcrypto])
+ LIBS="$LIBS -lcrypto"
+ LIBSSL_LIBS="$LIBSSL_LIBS -lcrypto"
+- AC_TRY_LINK(, [
+- int HMAC_Update(void);
+- (void)HMAC_Update();
+- ], [
++ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[
++ int EVP_sha256(void);
++ (void)EVP_sha256();
++ ]])],[
+ AC_MSG_RESULT(yes)
+- AC_DEFINE([HAVE_HMAC_UPDATE], 1,
+- [If you have HMAC_Update])
+- ], [
++ AC_DEFINE([HAVE_EVP_SHA256], 1,
++ [If you have EVP_sha256])
++ ],[
+ AC_MSG_RESULT(no)
+ # check if -lwsock32 or -lgdi32 are needed.
+ BAKLIBS="$LIBS"
+@@ -691,12 +699,12 @@
+ 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);
+- (void)HMAC_Update();
+- ],[
+- AC_DEFINE([HAVE_HMAC_UPDATE], 1,
+- [If you have HMAC_Update])
++ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[
++ int EVP_sha256(void);
++ (void)EVP_sha256();
++ ]])],[
++ AC_DEFINE([HAVE_EVP_SHA256], 1,
++ [If you have EVP_sha256])
+ AC_MSG_RESULT(yes)
+ ],[
+ AC_MSG_RESULT(no)
+@@ -705,12 +713,12 @@
+ LIBS="$LIBS -ldl"
+ LIBSSL_LIBS="$LIBSSL_LIBS -ldl"
+ AC_MSG_CHECKING([if -lcrypto needs -ldl])
+- AC_TRY_LINK([], [
+- int HMAC_Update(void);
+- (void)HMAC_Update();
+- ],[
+- AC_DEFINE([HAVE_HMAC_UPDATE], 1,
+- [If you have HMAC_Update])
++ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[
++ int EVP_sha256(void);
++ (void)EVP_sha256();
++ ]])],[
++ AC_DEFINE([HAVE_EVP_SHA256], 1,
++ [If you have EVP_sha256])
+ AC_MSG_RESULT(yes)
+ ],[
+ AC_MSG_RESULT(no)
+@@ -719,12 +727,12 @@
+ LIBS="$LIBS -ldl -pthread"
+ LIBSSL_LIBS="$LIBSSL_LIBS -ldl -pthread"
+ AC_MSG_CHECKING([if -lcrypto needs -ldl -pthread])
+- AC_TRY_LINK([], [
+- int HMAC_Update(void);
+- (void)HMAC_Update();
+- ],[
+- AC_DEFINE([HAVE_HMAC_UPDATE], 1,
+- [If you have HMAC_Update])
++ AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[
++ int EVP_sha256(void);
++ (void)EVP_sha256();
++ ]])],[
++ AC_DEFINE([HAVE_EVP_SHA256], 1,
++ [If you have EVP_sha256])
+ AC_MSG_RESULT(yes)
+ ],[
+ AC_MSG_RESULT(no)
+@@ -749,9 +757,8 @@
+ dnl
+ AC_DEFUN([ACX_WITH_SSL],
+ [
+-AC_ARG_WITH(ssl, AC_HELP_STRING([--with-ssl=pathname],
+- [enable SSL (will check /usr/local/ssl
+- /usr/lib/ssl /usr/ssl /usr/pkg /usr/local /opt/local /usr/local/opt/openssl /usr/sfw /usr)]),[
++AC_ARG_WITH(ssl, AS_HELP_STRING([--with-ssl=pathname],[enable SSL (will check /usr/local/ssl
++ /usr/lib/ssl /usr/ssl /usr/pkg /usr/local /opt/local /usr/sfw /usr)]),[
+ ],[
+ withval="yes"
+ ])
+@@ -768,9 +775,8 @@
+ dnl
+ AC_DEFUN([ACX_WITH_SSL_OPTIONAL],
+ [
+-AC_ARG_WITH(ssl, AC_HELP_STRING([--with-ssl=pathname],
+- [enable SSL (will check /usr/local/ssl
+- /usr/lib/ssl /usr/ssl /usr/pkg /usr/local /opt/local /usr/local/opt/openssl /usr/sfw /usr)]),[
++AC_ARG_WITH(ssl, AS_HELP_STRING([--with-ssl=pathname],[enable SSL (will check /usr/local/ssl
++ /usr/lib/ssl /usr/ssl /usr/pkg /usr/local /opt/local /usr/sfw /usr)]),[
+ ],[
+ withval="yes"
+ ])
+@@ -893,7 +899,7 @@
+ [
+ echo '$3' >conftest.c
+ echo 'void f(){ $2 }' >>conftest.c
+-if test -z "`$CC -c conftest.c 2>&1 | grep deprecated`"; then
++if test -z "`$CC $CPPFLAGS $CFLAGS -c conftest.c 2>&1 | grep -e deprecated -e unavailable`"; then
+ eval "cv_cc_deprecated_$cache=no"
+ else
+ eval "cv_cc_deprecated_$cache=yes"
+@@ -919,7 +925,7 @@
+ AC_DEFUN([ACX_CHECK_NONBLOCKING_BROKEN],
+ [
+ AC_MSG_CHECKING([if nonblocking sockets work])
+-if echo $target | grep mingw32 >/dev/null; then
++if echo $host | grep mingw >/dev/null; then
+ AC_MSG_RESULT([no (windows)])
+ AC_DEFINE([NONBLOCKING_IS_BROKEN], 1, [Define if the network stack does not fully support nonblocking io (causes lower performance).])
+ else
+@@ -1061,7 +1067,7 @@
+ AC_DEFUN([ACX_MKDIR_ONE_ARG],
+ [
+ AC_MSG_CHECKING([whether mkdir has one arg])
+-AC_TRY_COMPILE([
++AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+ #include <stdio.h>
+ #include <unistd.h>
+ #ifdef HAVE_WINSOCK2_H
+@@ -1070,14 +1076,12 @@
+ #ifdef HAVE_SYS_STAT_H
+ #include <sys/stat.h>
+ #endif
+-], [
++]], [[
+ (void)mkdir("directory");
+-],
+-AC_MSG_RESULT(yes)
++]])],[AC_MSG_RESULT(yes)
+ AC_DEFINE(MKDIR_HAS_ONE_ARG, 1, [Define if mkdir has one argument.])
+-,
+-AC_MSG_RESULT(no)
+-)
++],[AC_MSG_RESULT(no)
++])
+ ])dnl end of ACX_MKDIR_ONE_ARG
+
+ dnl Check for ioctlsocket function. works on mingw32 too.
+diff -ur ldns-1.7.1/ax_pkg_swig.m4 ldns/ax_pkg_swig.m4
+--- ldns-1.7.1/ax_pkg_swig.m4 2019-07-26 17:07:44.000000000 +0200
++++ ldns/ax_pkg_swig.m4 2021-10-17 21:21:57.612895984 +0200
+@@ -1,5 +1,5 @@
+ # ===========================================================================
+-# http://www.gnu.org/software/autoconf-archive/ax_pkg_swig.html
++# https://www.gnu.org/software/autoconf-archive/ax_pkg_swig.html
+ # ===========================================================================
+ #
+ # SYNOPSIS
+@@ -32,9 +32,9 @@
+ # LICENSE
+ #
+ # Copyright (c) 2008 Sebastian Huber <sebastian-huber at web.de>
+-# Copyright (c) 2008 Alan W. Irwin <irwin at beluga.phys.uvic.ca>
++# Copyright (c) 2008 Alan W. Irwin
+ # Copyright (c) 2008 Rafael Laboissiere <rafael at laboissiere.net>
+-# Copyright (c) 2008 Andrew Collier <colliera at ukzn.ac.za>
++# Copyright (c) 2008 Andrew Collier
+ # Copyright (c) 2011 Murray Cumming <murrayc at openismus.com>
+ #
+ # This program is free software; you can redistribute it and/or modify it
+@@ -48,7 +48,7 @@
+ # Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License along
+-# with this program. If not, see <http://www.gnu.org/licenses/>.
++# with this program. If not, see <https://www.gnu.org/licenses/>.
+ #
+ # As a special exception, the respective Autoconf Macro's copyright owner
+ # gives unlimited permission to copy, distribute and modify the configure
+@@ -63,11 +63,11 @@
+ # modified version of the Autoconf Macro, you may extend this special
+ # exception to the GPL to apply to your modified version as well.
+
+-#serial 8
++#serial 13
+
+ AC_DEFUN([AX_PKG_SWIG],[
+- # Ubuntu has swig 2.0 as /usr/bin/swig2.0
+- AC_PATH_PROGS([SWIG],[swig2.0 swig])
++ # Find path to the "swig" executable.
++ AC_PATH_PROGS([SWIG],[swig swig3.0 swig2.0])
+ if test -z "$SWIG" ; then
+ m4_ifval([$3],[$3],[:])
+ elif test -n "$1" ; then
+diff -ur ldns-1.7.1/ax_python_devel.m4 ldns/ax_python_devel.m4
+--- ldns-1.7.1/ax_python_devel.m4 2019-07-26 17:07:44.000000000 +0200
++++ ldns/ax_python_devel.m4 2021-10-17 21:21:57.612895984 +0200
+@@ -1,5 +1,5 @@
+ # ===========================================================================
+-# http://www.gnu.org/software/autoconf-archive/ax_python_devel.html
++# https://www.gnu.org/software/autoconf-archive/ax_python_devel.html
+ # ===========================================================================
+ #
+ # SYNOPSIS
+@@ -12,8 +12,8 @@
+ # in your configure.ac.
+ #
+ # This macro checks for Python and tries to get the include path to
+-# 'Python.h'. It provides the $(PYTHON_CPPFLAGS) and $(PYTHON_LDFLAGS)
+-# output variables. It also exports $(PYTHON_EXTRA_LIBS) and
++# 'Python.h'. It provides the $(PYTHON_CPPFLAGS) and $(PYTHON_LIBS) output
++# variables. It also exports $(PYTHON_EXTRA_LIBS) and
+ # $(PYTHON_EXTRA_LDFLAGS) for embedding Python in your code.
+ #
+ # You can search for some particular version of Python by passing a
+@@ -52,7 +52,7 @@
+ # Public License for more details.
+ #
+ # You should have received a copy of the GNU General Public License along
+-# with this program. If not, see <http://www.gnu.org/licenses/>.
++# with this program. If not, see <https://www.gnu.org/licenses/>.
+ #
+ # As a special exception, the respective Autoconf Macro's copyright owner
+ # gives unlimited permission to copy, distribute and modify the configure
+@@ -67,7 +67,7 @@
+ # modified version of the Autoconf Macro, you may extend this special
+ # exception to the GPL to apply to your modified version as well.
+
+-#serial 16
++#serial 21
+
+ AU_ALIAS([AC_PYTHON_DEVEL], [AX_PYTHON_DEVEL])
+ AC_DEFUN([AX_PYTHON_DEVEL],[
+@@ -99,7 +99,7 @@
+ This version of the AC@&t at _PYTHON_DEVEL macro
+ doesn't work properly with versions of Python before
+ 2.1.0. You may need to re-run configure, setting the
+-variables PYTHON_CPPFLAGS, PYTHON_LDFLAGS, PYTHON_SITE_PKG,
++variables PYTHON_CPPFLAGS, PYTHON_LIBS, PYTHON_SITE_PKG,
+ PYTHON_EXTRA_LIBS and PYTHON_EXTRA_LDFLAGS by hand.
+ Moreover, to disable this check, set PYTHON_NOVERSIONCHECK
+ to something else than an empty string.
+@@ -137,7 +137,7 @@
+ #
+ 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 test $? -eq 0; then
+ AC_MSG_RESULT([yes])
+ else
+ AC_MSG_RESULT([no])
+@@ -172,7 +172,7 @@
+ # Check for Python library path
+ #
+ AC_MSG_CHECKING([for Python library path])
+- if test -z "$PYTHON_LDFLAGS"; then
++ if test -z "$PYTHON_LIBS"; then
+ # (makes two attempts to ensure we've got a version number
+ # from the interpreter)
+ ac_python_version=`cat<<EOD | $PYTHON -
+@@ -227,25 +227,25 @@
+ then
+ # use the official shared library
+ ac_python_library=`echo "$ac_python_library" | sed "s/^lib//"`
+- PYTHON_LDFLAGS="-L$ac_python_libdir -l$ac_python_library"
++ PYTHON_LIBS="-L$ac_python_libdir -l$ac_python_library"
+ else
+ # old way: use libpython from python_configdir
+ ac_python_libdir=`$PYTHON -c \
+ "from distutils.sysconfig import get_python_lib as f; \
+ import os; \
+ print (os.path.join(f(plat_specific=1, standard_lib=1), 'config'));"`
+- PYTHON_LDFLAGS="-L$ac_python_libdir -lpython$ac_python_version"
++ PYTHON_LIBS="-L$ac_python_libdir -lpython$ac_python_version"
+ fi
+
+- if test -z "PYTHON_LDFLAGS"; then
++ if test -z "PYTHON_LIBS"; then
+ AC_MSG_ERROR([
+ Cannot determine location of your Python DSO. Please check it was installed with
+- dynamic libraries enabled, or try setting PYTHON_LDFLAGS by hand.
++ dynamic libraries enabled, or try setting PYTHON_LIBS by hand.
+ ])
+ fi
+ fi
+- AC_MSG_RESULT([$PYTHON_LDFLAGS])
+- AC_SUBST([PYTHON_LDFLAGS])
++ AC_MSG_RESULT([$PYTHON_LIBS])
++ AC_SUBST([PYTHON_LIBS])
+
+ #
+ # Check for site packages
+@@ -265,7 +265,7 @@
+ if test -z "$PYTHON_EXTRA_LIBS"; then
+ PYTHON_EXTRA_LIBS=`$PYTHON -c "import distutils.sysconfig; \
+ conf = distutils.sysconfig.get_config_var; \
+- print (conf('LIBS'))"`
++ print (conf('LIBS') + ' ' + conf('SYSLIBS'))"`
+ fi
+ AC_MSG_RESULT([$PYTHON_EXTRA_LIBS])
+ AC_SUBST(PYTHON_EXTRA_LIBS)
+@@ -288,8 +288,10 @@
+ AC_MSG_CHECKING([consistency of all components of python development environment])
+ # save current global flags
+ ac_save_LIBS="$LIBS"
++ ac_save_LDFLAGS="$LDFLAGS"
+ ac_save_CPPFLAGS="$CPPFLAGS"
+- LIBS="$ac_save_LIBS $PYTHON_LDFLAGS $PYTHON_EXTRA_LDFLAGS $PYTHON_EXTRA_LIBS"
++ LIBS="$ac_save_LIBS $PYTHON_LIBS $PYTHON_EXTRA_LIBS $PYTHON_EXTRA_LIBS"
++ LDFLAGS="$ac_save_LDFLAGS $PYTHON_EXTRA_LDFLAGS"
+ CPPFLAGS="$ac_save_CPPFLAGS $PYTHON_CPPFLAGS"
+ AC_LANG_PUSH([C])
+ AC_LINK_IFELSE([
+@@ -300,6 +302,7 @@
+ # turn back to default flags
+ CPPFLAGS="$ac_save_CPPFLAGS"
+ LIBS="$ac_save_LIBS"
++ LDFLAGS="$ac_save_LDFLAGS"
+
+ AC_MSG_RESULT([$pythonexists])
+
+@@ -307,8 +310,8 @@
+ AC_MSG_FAILURE([
+ Could not link test program to Python. Maybe the main Python library has been
+ installed in some non-standard library path. If so, pass it to configure,
+- via the LDFLAGS environment variable.
+- Example: ./configure LDFLAGS="-L/usr/non-standard-path/python/lib"
++ via the LIBS environment variable.
++ Example: ./configure LIBS="-L/usr/non-standard-path/python/lib"
+ ============================================================================
+ ERROR!
+ You probably have to install the development version of the Python package
+diff -ur ldns-1.7.1/buffer.c ldns/buffer.c
+--- ldns-1.7.1/buffer.c 2019-07-26 17:07:44.000000000 +0200
++++ ldns/buffer.c 2021-10-17 21:21:57.612895984 +0200
+@@ -63,6 +63,7 @@
+
+ ldns_buffer_invariant(buffer);
+ assert(buffer->_position <= capacity);
++ assert(!buffer->_fixed);
+
+ data = (uint8_t *) LDNS_XREALLOC(buffer->_data, uint8_t, capacity);
+ if (!data) {
+@@ -79,7 +80,6 @@
+ ldns_buffer_reserve(ldns_buffer *buffer, size_t amount)
+ {
+ ldns_buffer_invariant(buffer);
+- assert(!buffer->_fixed);
+ if (buffer->_capacity < buffer->_position + amount) {
+ size_t new_capacity = buffer->_capacity * 3 / 2;
+
+diff -ur ldns-1.7.1/Changelog ldns/Changelog
+--- ldns-1.7.1/Changelog 2019-07-26 17:07:44.000000000 +0200
++++ ldns/Changelog 2021-10-17 21:21:57.612895984 +0200
+@@ -1,3 +1,57 @@
++1.7.2 2021-??-??
++ * bugfix #38: Print "line" before line number when printing
++ zone parse errors. Thanks Petr Špaček.
++ * bugfix: Revert unused variables in ldns-config removal patch.
++ * bugfix #50: heap Out-of-bound Read vulnerability in
++ rr_frm_str_internal reported by pokerfacett.
++ * bugfix #51: Heap Out-of-bound Read vulnerability in
++ ldns_nsec3_salt_data reported by pokerfacett.
++ * Fix memory leak in examples/ldns-testns handle_tcp routine.
++ * Detect fixed time memory compare for openssl 0.9.8.
++ * Fix compile warning by variable initialisation for older gcc.
++ * Fix #92: ldns-testns.c:429:15: error: 'fork' is unavailable: not
++ available on tvOS.
++ * Fix for #93: fix packaging/libldns.pc Makefile rule.
++ * ZONEMD support in ldns-signzone and ldns-verify-zone
++ * ldns-testns can answer several queries over one tcp connection,
++ if they arrive within 100msec of each other.
++ * Fix so that ldns-testns does not leak sockets if the read fails.
++ * SVCB and HTTPS draft rrtypes.
++ Enable with --enable-rrtype-svcb-https.
++ * bugfix #117: Assertion failure with DNSSEC validating of
++ non existence of RR types at the root. Thanks ZjYwMj
++ * Set NSEC(3) ttls to the minimum of the MINIMUM field of the SOA
++ record and the TTL of the SOA itself. draft-ietf-dnsop-nsec-ttl
++ * bugfix #119: Let example tools read longer RR's than
++ LDNS_MAX_LINELEN
++ * Add SVCPARAMS to python ldns_rdf_type2str function.
++ * PR #134 Miscellaneous spelling fixes. Thanks jsoref!
++ * Fix that ldns-read-zone and ldns_zone_new_frm_fp_l properly return
++ the $INCLUDE not implemented error.
++ * Fix that ldns-read-zone and ldns_zone_new_frm_fp_l count the line
++ number for an empty line after a comment.
++ * Fix #135: Fix compile with OpenSSL-3.0.0-beta2.
++ * PR #107: Added ldns_pkt2buffer_wire_compress() to make dname
++ compression optional when converting packets to wire format.
++ Thanks Eli Lindsey
++ * Option to ldns-keygen to create symlinks with known names
++ (i.e. without the key id) to the created files.
++ Thanks Andreas Schulze
++ * Fix #121: Correct handling of centimetres by LOC parser.
++ Thanks Felipe Gasper
++ * PR #126: Link with libldns.la in Makefile.in.
++ Thanks orbea
++ * PR #127: Addes option -Q to drill to give short answer.
++ Thanks niknah
++ * PR #133: Update m4 files for python modules.
++ Thanks Petr Menšík
++ * Bufix CAA value fields may be empty: Thanks Robert Mortimer
++ * PR #108: Fix for ldns-compare-zones net detecting when first zone
++ has a RRset that shrinks from two to one RRs, or grows from one
++ to two RRs. Thanks Emilio Caballero
++ * Fix #131: Drill sig chasing breaks with gcc-11 and
++ strict-aliasing. Thanks Stanislav Levin
++
+ 1.7.1 2019-07-26
+ * bugfix: Manage verification paths for OpenSSL >= 1.1.0
+ Thanks Marco Davids
+@@ -13,9 +67,9 @@
+ Thanks Bill Parker
+ * bugfix #1260: Anticipate strchr returning NULL on unfound char
+ Thanks Stephan Zeisberg
+- * bugfix #1257: Free after reallocing to 0 size
++ * bugfix #1257: Free after reallocing to 0 size (CVE-2017-1000232)
+ Thanks Stephan Zeisberg
+- * bugfix #1256: Check parse limit before t increment
++ * bugfix #1256: Check parse limit before t increment (CVE-2017-1000231)
+ Thanks Stephan Zeisberg
+ * bugfix #1245: Only one signature per RRset needs to be valid with
+ ldns-verify-zone. Thanks Emil Natan.
+@@ -267,7 +321,7 @@
+ in sync.
+ * Let ldns_pkt_push_rr now return false on (memory) errors.
+ * Make buffer_export comply to documentation and fix buffer2str
+- * Various improvements and fixes of pyldns from Katel Slany
++ * Various improvements and fixes of pyldns from Karel Slany
+ now documented in their own Changelog.
+ * bugfix: Make ldns_resolver_pop_nameserver clear the array when
+ there was only one.
+@@ -306,7 +360,7 @@
+ * bugfix #433: Allocate rdf using ldns_rdf_new in ldns_dname_label
+ * bugfix #432: Use LDNS_MALLOC & LDNS_FREE i.s.o. malloc & free
+ * bugfix #431: Added error message for LDNS_STATUS_INVALID_B32_EXT
+- * bugfix #427: Explicitely link ssl with the programs that use it.
++ * bugfix #427: Explicitly link ssl with the programs that use it.
+ * Fix reading \DDD: Error on values that are outside range (>255).
+ * bugfix #429: fix doxyparse.pl fails on NetBSD because specified
+ path to perl.
+@@ -370,7 +424,7 @@
+ * Update of libdns.vim (thanks Miek Gieben)
+ * Added the ldnsx Python module to our contrib section, which adds even
+ more pythonisticism to the usage of ldns with Python. (Many thanks
+- to Christpher Olah and Paul Wouters)
++ to Christopher Olah and Paul Wouters)
+ The ldnsx module is automatically installed when --with-pyldns is
+ used with configuring, but may explicitly be excluded with the
+ --without-pyldnsx option to configure.
+@@ -398,7 +452,7 @@
+ * bugfix #380: Minimizing effect of discrepancies in sizeof(bool) at
+ build time and when used.
+ * bugfix #383: Fix detection of empty nonterminals of multiple labels.
+- * Fixed the ommission of rrsets in nsec(3)s and rrsigs to all occluded
++ * Fixed the omission of rrsets in nsec(3)s and rrsigs to all occluded
+ names (in stead of just the ones that contain glue only) and all
+ occluded records on the delegation points (in stead of just the glue).
+ * Clarify the operation of ldns_dnssec_mark_glue and the usage of
+@@ -688,7 +742,7 @@
+ from Shane Kerr, bug id 188)
+ * zone.c memory leaks on error and allocation checks fixed (patch
+ from Shane Kerr, bug id 189)
+- * ldns-zplit output and error messages fixed (patch from Shane Kerr,
++ * ldns-zsplit output and error messages fixed (patch from Shane Kerr,
+ bug id 190)
+ * Fixed potential buffer overflow in ldns_str2rdf_dname
+ * Signing code no longer signs delegation NS rrsets
+@@ -717,7 +771,7 @@
+ * DLV RR type added
+ * TCP fallback system has been improved
+ * HMAC-SHA256 TSIG support has been added.
+- * TTLS are now correcly set in NSEC(3) records when signing zones
++ * TTLS are now correctly set in NSEC(3) records when signing zones
+
+ EXAMPLE TOOLS:
+ * New example: ldns-revoke to revoke DNSKEYs according to RFC5011
+@@ -792,7 +846,7 @@
+ 28 Nov 2007 1.2.2:
+ * Added support for HMAC-MD5 keys in generator
+ * Added a new example tool (written by Ondrej Sury): ldns-compare-zones
+- * ldns-keygen now checks key sizes for rfc conformancy
++ * ldns-keygen now checks key sizes for rfc conformance
+ * ldns-signzone outputs SSL error if present
+ * Fixed manpages (thanks to Ondrej Sury)
+ * Fixed Makefile for -j <x>
+@@ -882,7 +936,7 @@
+ * ldns-dpa was added to the examples - this is the Dns Packet
+ Analyzer tool.
+ * ldnsd - as very, very simple nameserver impl.
+- * ldns-zsplit - split zones for parrallel signing
++ * ldns-zsplit - split zones for parallel signing
+ * ldns-zcat - cat split zones back together
+ * ldns-keyfetcher - Fetches DNSKEY records with a few (non-strong,
+ non-DNSSEC) anti-spoofing techniques.
+@@ -901,7 +955,7 @@
+ API:
+ Changed:
+ * renamed ldns/dns.h to ldns/ldns.h
+- * ldns_rr_new_frm_str() is extented with an extra variable which
++ * ldns_rr_new_frm_str() is extended with an extra variable which
+ in common use may be NULL. This trickles through to:
+ o ldns_rr_new_frm_fp
+ o ldns_rr_new_frm_fp_l
+@@ -975,7 +1029,7 @@
+ 13 Jun 2005: 0.65: ldns-team
+ * Repository is online at:
+ http://www.nlnetlabs.nl/ldns/svn/
+- * Apply reference copying throuhgout ldns, except in 2
++ * Apply reference copying throughout ldns, except in 2
+ places in the ldns_resolver structure (._domain and
+ ._nameservers)
+ * Usual array of bugfixes
+diff -ur ldns-1.7.1/configure.ac ldns/configure.ac
+--- ldns-1.7.1/configure.ac 2019-07-26 17:07:44.000000000 +0200
++++ ldns/configure.ac 2021-10-17 21:21:57.616229259 +0200
+@@ -6,7 +6,7 @@
+ # must be numbers. ac_defun because of later processing.
+ m4_define([VERSION_MAJOR],[1])
+ m4_define([VERSION_MINOR],[7])
+-m4_define([VERSION_MICRO],[1])
++m4_define([VERSION_MICRO],[2])
+ AC_INIT(ldns, m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]), libdns at nlnetlabs.nl, libdns)
+ AC_CONFIG_SRCDIR([packet.c])
+ # needed to build correct soname
+@@ -26,10 +26,11 @@
+ # set age to 0
+ #
+ # ldns-1.6.17 and before had a .so with version same as VERSION_INFO
+-# ldns-1.7.0 has libversion 2:0:0
+-# ldns-1.7.1 has libversion 3:0:1
++# ldns-1.7.0 had libversion 2:0:0
++# ldns-1.7.1 had libversion 3:0:1
++# ldns-1.7.2 had libversion 3:0:2
+ #
+-AC_SUBST(VERSION_INFO, [3:0:0])
++AC_SUBST(VERSION_INFO, [3:0:2])
+
+ AC_AIX
+ if test "$ac_cv_header_minix_config_h" = "yes"; then
+@@ -50,7 +51,7 @@
+ # Extra (sp)lint flags for NetBSD
+ AC_CANONICAL_HOST
+ case "$host_os" in
+- netbsd*) LINTFLAGS="'-D__RENAME(x)=' -D_NETINET_IN_H_ $LINTFLAGS"
++ netbsd*) LINTFLAGS="'-D__RENAME(x)=' -D_NETINET_IN_H_ $LINTFLAGS"
+ ;;
+ *) LINTFLAGS="$LINTFLAGS"
+ ;;
+@@ -96,6 +97,7 @@
+ #ACX_CHECK_COMPILER_FLAG(Wshadow, [CFLAGS="-Wshadow $CFLAGS"])
+ ACX_CHECK_COMPILER_FLAG(Wunused-function, [CFLAGS="-Wunused-function $CFLAGS"])
+ ACX_CHECK_COMPILER_FLAG(Wmissing-prototypes, [CFLAGS="-Wmissing-prototypes $CFLAGS"])
++ACX_CHECK_COMPILER_FLAG(fno-strict-aliasing, [CFLAGS="-fno-strict-aliasing $CFLAGS"])
+
+ AC_CHECK_HEADERS([getopt.h time.h],,, [AC_INCLUDES_DEFAULT])
+
+@@ -103,6 +105,9 @@
+ AC_CHECK_HEADERS([winsock2.h ws2tcpip.h],,, [AC_INCLUDES_DEFAULT])
+ # end mingw32 tests
+
++# Check for Apple header. This uncovers TARGET_OS_IPHONE, TARGET_OS_TV or TARGET_OS_WATCH
++AC_CHECK_HEADERS([TargetConditionals.h])
++
+ ACX_DETERMINE_EXT_FLAGS_UNBOUND
+
+ AC_C_INLINE
+@@ -119,12 +124,32 @@
+ AC_CHECK_PROG(doxygen, doxygen, doxygen)
+
+ # check to see if libraries are needed for these functions.
+-AC_SEARCH_LIBS([socket], [socket])
+-AC_SEARCH_LIBS([inet_pton], [nsl])
++AC_CHECK_FUNC([socket],
++ [],
++ [AC_SEARCH_LIBS([socket], [socket])
++])
++
++# modern Linux provides inet_ntop in -lsocket.
++# modern OS X provides inet_ntop in -lc.
++# modern Solaris provides inet_ntop in -lsocket -lnsl.
++# older Solaris provides inet_ntop in -lresolv.
++AC_CHECK_FUNC([inet_ntop],
++ [],
++ [AC_SEARCH_LIBS([inet_ntop], [socket c nsl resolv])
++])
++
++# modern Linux provides inet_pton in -lsocket.
++# modern OS X provides inet_pton in -lc.
++# modern Solaris provides inet_pton in -lsocket -lnsl.
++# older Solaris provides inet_pton in -lresolv.
++AC_CHECK_FUNC([inet_pton],
++ [],
++ [AC_SEARCH_LIBS([inet_pton], [socket c nsl resolv])
++])
+
+
+-AC_ARG_WITH(drill, AC_HELP_STRING([--with-drill],
+- [Also build drill.]),
++AC_ARG_WITH(drill, AC_HELP_STRING([--with-drill],
++ [Also build drill.]),
+ [],[with_drill="no"])
+ if test x_$with_drill != x_no ; then
+ AC_SUBST(DRILL,[drill])
+@@ -136,7 +161,7 @@
+ AC_MSG_ERROR([
+ A config.h was detected in the drill subdirectory.
+ This does not work with the --with-drill option.
+-Please remove the config.h from the drill subdirectory
++Please remove the config.h from the drill subdirectory
+ or do not use the --with-drill option.])
+ fi
+ else
+@@ -148,8 +173,8 @@
+ fi
+
+
+-AC_ARG_WITH(examples, AC_HELP_STRING([--with-examples],
+- [Also build examples.]),
++AC_ARG_WITH(examples, AC_HELP_STRING([--with-examples],
++ [Also build examples.]),
+ [],[with_examples="no"])
+ if test x_$with_examples != x_no ; then
+ AC_SUBST(EXAMPLES,[examples])
+@@ -161,7 +186,7 @@
+ AC_MSG_ERROR([
+ A config.h was detected in the examples subdirectory.
+ This does not work with the --with-examples option.
+-Please remove the config.h from the examples subdirectory
++Please remove the config.h from the examples subdirectory
+ or do not use the --with-examples option.])
+ fi
+ else
+@@ -192,7 +217,7 @@
+ case "$enable_stderr_msgs" in
+ no) dnl default
+ ;;
+- *)
++ *)
+ AC_DEFINE_UNQUOTED([STDERR_MSGS], [1], [Define this to enable messages to stderr.])
+ ;;
+ esac
+@@ -208,8 +233,8 @@
+ PYTHON_X_CFLAGS=""
+ ldns_with_pyldns=no
+ ldns_with_pyldnsx=no
+-AC_ARG_WITH(pyldns, AC_HELP_STRING([--with-pyldns],
+- [generate python library, or --without-pyldns to disable Python support.]),
++AC_ARG_WITH(pyldns, AC_HELP_STRING([--with-pyldns],
++ [generate python library, or --without-pyldns to disable Python support.]),
+ [],[ withval="no" ])
+ ldns_have_python=no
+ if test x_$withval != x_no; then
+@@ -264,8 +289,8 @@
+ AC_SUBST(PYTHON_X_CFLAGS)
+
+ # Check for pyldnsx
+-AC_ARG_WITH(pyldnsx, AC_HELP_STRING([--without-pyldnsx],
+- [Do not install the ldnsx python module, or --with-pyldnsx to install it.]),
++AC_ARG_WITH(pyldnsx, AC_HELP_STRING([--without-pyldnsx],
++ [Do not install the ldnsx python module, or --with-pyldnsx to install it.]),
+ [],[ withval="with_pyldns" ])
+ if test x_$withval != x_no; then
+ if test x_$ldns_with_pyldns != x_no; then
+@@ -295,8 +320,8 @@
+
+ # check for perl
+ ldns_with_p5_dns_ldns=no
+-AC_ARG_WITH(p5-dns-ldns, AC_HELP_STRING([--with-p5-dns-ldns],
+- [generate DNS::LDNS perl bindings]),
++AC_ARG_WITH(p5-dns-ldns, AC_HELP_STRING([--with-p5-dns-ldns],
++ [generate DNS::LDNS perl bindings]),
+ [],[ withval="no" ])
+ ldns_have_perl=no
+ if test x_$withval != x_no; then
+@@ -332,7 +357,8 @@
+ else
+ AC_MSG_RESULT([no])
+ fi
+-AC_CHECK_FUNCS([EVP_sha256 EVP_sha384 EVP_sha512 ENGINE_load_cryptodev EVP_PKEY_keygen ECDSA_SIG_get0 EVP_MD_CTX_new EVP_PKEY_base_id DSA_SIG_set0 DSA_SIG_get0 EVP_dss1 DSA_get0_pqg DSA_get0_key OPENSSL_init_ssl OPENSSL_init_crypto ERR_load_crypto_strings])
++AC_CHECK_HEADERS([openssl/ssl.h openssl/evp.h openssl/engine.h openssl/conf.h])
++AC_CHECK_FUNCS([EVP_sha256 EVP_sha384 EVP_sha512 EVP_PKEY_keygen ECDSA_SIG_get0 EVP_MD_CTX_new EVP_PKEY_base_id DSA_SIG_set0 DSA_SIG_get0 EVP_dss1 DSA_get0_pqg DSA_get0_key EVP_cleanup ENGINE_cleanup ENGINE_free CRYPTO_cleanup_all_ex_data ERR_free_strings CONF_modules_unload OPENSSL_init_ssl OPENSSL_init_crypto ERR_load_crypto_strings CRYPTO_memcmp EVP_PKEY_get_base_id])
+
+ # for macosx, see if glibtool exists and use that
+ # BSD's need to know the version...
+@@ -355,21 +381,33 @@
+ ;;
+ esac
+
+-# check wether gost also works
++# check whether gost also works
+ AC_DEFUN([AC_CHECK_GOST_WORKS],
+ [AC_REQUIRE([AC_PROG_CC])
+ AC_MSG_CHECKING([if GOST works])
+ if test c${cross_compiling} = cno; then
+ BAKCFLAGS="$CFLAGS"
+ if test -n "$ssldir"; then
++ if test ! -d "$ssldir/lib" -a -d "$ssldir/lib64"; then
++ CFLAGS="$CFLAGS -Wl,-rpath,$ssldir/lib64"
++ else
+ CFLAGS="$CFLAGS -Wl,-rpath,$ssldir/lib"
++ fi
+ fi
+ AC_RUN_IFELSE([AC_LANG_SOURCE([[
+ #include <string.h>
++#ifdef HAVE_OPENSSL_SSL_H
+ #include <openssl/ssl.h>
++#endif
++#ifdef HAVE_OPENSSL_EVP_H
+ #include <openssl/evp.h>
++#endif
++#ifdef HAVE_OPENSSL_ENGINE_H
+ #include <openssl/engine.h>
++#endif
++#ifdef HAVE_OPENSSL_CONF_H
+ #include <openssl/conf.h>
++#endif
+ /* routine to load gost (from sldns) */
+ int load_gost_id(void)
+ {
+@@ -414,7 +452,7 @@
+ EVP_PKEY_asn1_get0_info(&gost_id, NULL, NULL, NULL, NULL, meth);
+ return gost_id;
+ }
+-int main(void) {
++int main(void) {
+ EVP_MD_CTX* ctx;
+ const EVP_MD* md;
+ unsigned char digest[64]; /* its a 256-bit digest, so uses 32 bytes */
+@@ -464,7 +502,7 @@
+ AC_CHECK_FUNC(EVP_PKEY_set_type_str, [],[AC_MSG_ERROR([OpenSSL >= 1.0.0 is needed for GOST support or rerun with --disable-gost])])
+ AC_CHECK_FUNC(EC_KEY_new, [], [AC_MSG_ERROR([No ECC functions found in OpenSSL: please upgrade OpenSSL or rerun with --disable-gost])])
+ AC_CHECK_GOST_WORKS
+- AC_ARG_ENABLE(gost-anyway, AC_HELP_STRING([--enable-gost-anyway], [Enable GOST even whithout a GOST engine installed]))
++ AC_ARG_ENABLE(gost-anyway, AC_HELP_STRING([--enable-gost-anyway], [Enable GOST even without a GOST engine installed]))
+ if test "$ac_cv_c_gost_works" != "no" -o "$enable_gost_anyway" = "yes"; then
+ if test "$ac_cv_c_gost_works" = "no"; then
+ AC_MSG_RESULT([no, but compiling with GOST support anyway])
+@@ -584,9 +622,11 @@
+ AC_SUBST(ldns_build_config_use_dane_ta_usage, 0)
+ ;;
+ *) dnl default
+- LIBS="-lssl $LIBS"
++ danetmpLIBS="$LIBS"
++ LIBS="-lssl -lcrypto $LIBS"
+ AC_CHECK_FUNC(SSL_get0_dane, [], [AC_MSG_ERROR([OpenSSL does not support offline DANE verification (Needed for the DANE-TA usage type). Please upgrade OpenSSL to version >= 1.1.0 or rerun with --disable-dane-verify or --disable-dane-ta-usage])])
+ LIBSSL_LIBS="-lssl $LIBSSL_LIBS"
++ LIBS="$danetmpLIBS"
+ AC_SUBST(ldns_build_config_use_dane_ta_usage, 1)
+ AC_DEFINE_UNQUOTED([USE_DANE_TA_USAGE], [1], [Define this to enable DANE-TA usage type support.])
+ ;;
+@@ -651,6 +691,14 @@
+ no|*)
+ ;;
+ esac
++AC_ARG_ENABLE(rrtype-svcb-https, AC_HELP_STRING([--enable-rrtype-svcb-https], [Enable draft RR types SVCB and HTTPS.]))
++case "$enable_rrtype_svcb_https" in
++ yes)
++ AC_DEFINE_UNQUOTED([RRTYPE_SVCB_HTTPS], [], [Define this to enable RR types SVCB and HTTPS.])
++ ;;
++ no|*)
++ ;;
++esac
+
+
+
+@@ -658,7 +706,12 @@
+ AC_SUBST(LIBSSL_LDFLAGS)
+ AC_SUBST(LIBSSL_LIBS)
+ if test "x$HAVE_SSL" = "xyes"; then
+-AC_SUBST(LIBSSL_SSL_LIBS, ["-lssl $LIBSSL_LIBS"])
++ if echo "$LIBSSL_LIBS" | grep -- "-lssl" >/dev/null 2>&1; then
++ LIBSSL_SSL_LIBS="$LIBSSL_LIBS"
++ else
++ LIBSSL_SSL_LIBS="-lssl $LIBSSL_LIBS"
++ fi
++ AC_SUBST(LIBSSL_SSL_LIBS, "$LIBSSL_SSL_LIBS")
+ fi
+ CPPFLAGS=$tmp_CPPFLAGS
+ LDFLAGS=$tmp_LDFLAGS
+@@ -770,7 +823,7 @@
+ ]
+ )
+ AC_CHECK_HEADERS([netinet/in_systm.h net/if.h netinet/ip.h netinet/udp.h netinet/igmp.h netinet/if_ether.h netinet/ip6.h net/ethernet.h netinet/ip_compat.h],,, [
+-AC_INCLUDES_DEFAULT
++AC_INCLUDES_DEFAULT
+ #ifdef HAVE_NETINET_IN_SYSTM_H
+ #include <netinet/in_systm.h>
+ #endif
+@@ -811,8 +864,9 @@
+ #endif])
+ ACX_CHECK_SS_FAMILY
+
+-AC_FUNC_MALLOC
+-AC_FUNC_REALLOC
++# AC_FUNC_MALLOC suffers false failures and causes Asan failures.
++# AC_FUNC_MALLOC
++# AC_FUNC_REALLOC
+
+ AC_REPLACE_FUNCS(b64_pton)
+ AC_REPLACE_FUNCS(b64_ntop)
+@@ -830,6 +884,16 @@
+ AC_REPLACE_FUNCS(strlcpy)
+ AC_REPLACE_FUNCS(memmove)
+ AC_FUNC_FORK
++AC_MSG_CHECKING([compile of fork])
++AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
++#include <unistd.h>
++], [
++ (void)fork();
++])], [
++ AC_MSG_RESULT(yes)
++ AC_DEFINE([HAVE_FORK_AVAILABLE], 1, [if fork is available for compile])
++], [ AC_MSG_RESULT(no)
++])
+ AC_CHECK_FUNCS([endprotoent endservent sleep random fcntl strtoul bzero memset b32_ntop b32_pton])
+ if test "x$HAVE_B32_NTOP" = "xyes"; then
+ AC_SUBST(ldns_build_config_have_b32_ntop, 1)
+@@ -856,12 +920,12 @@
+ ACX_CHECK_FORMAT_ATTRIBUTE
+ ACX_CHECK_UNUSED_ATTRIBUTE
+
+-AC_ARG_WITH(xcode-sdk, AC_HELP_STRING([--with-xcode-sdk],
+- [Set xcode SDK version. Default is autodetect]),
++AC_ARG_WITH(xcode-sdk, AC_HELP_STRING([--with-xcode-sdk],
++ [Set xcode SDK version. Default is autodetect]),
+ [],[with_xcode_sdk="yes"])
+ if test "x_$with_xcode_sdk" != "x_no" ; then
+ # check OSX deployment target, if needed
+- if echo $build_os | grep darwin > /dev/null; then
++ if echo $target_os | grep darwin > /dev/null; then
+ sdk_p=`xcode-select -print-path`;
+ if test "x_$with_xcode_sdk" = "x_yes" ; then
+ sdk_v="$( /usr/bin/xcrun --show-sdk-version 2>/dev/null )"
+@@ -1088,5 +1152,3 @@
+ COPY_HEADER_FILES(ldns/, ldns/)
+
+ dnl AC_CONFIG_SUBDIRS([drill])
+-
+-
+diff -ur ldns-1.7.1/contrib/ldnsx/ldnsx.py ldns/contrib/ldnsx/ldnsx.py
+--- ldns-1.7.1/contrib/ldnsx/ldnsx.py 2019-07-26 17:07:44.000000000 +0200
++++ ldns/contrib/ldnsx/ldnsx.py 2021-10-17 21:21:57.616229259 +0200
+@@ -4,9 +4,9 @@
+
+ """ Easy DNS (including DNSSEC) via ldns.
+
+-ldns is a great library. It is a powerfull tool for
++ldns is a great library. It is a powerful tool for
+ working with DNS. python-ldns it is a straight up clone of the C
+-interface, howver that is not a very good interface for python. Its
++interface, however that is not a very good interface for python. Its
+ documentation is incomplete and some functions don't work as
+ described. And some objects don't have a full python API.
+
+@@ -204,7 +204,7 @@
+ defaults to settings from /etc/resolv.conf
+ * dnssec -- should the resolver try and use dnssec or not?
+ * tcp -- should the resolver use TCP
+- 'auto' is a depricated work around for old ldns problems
++ 'auto' is a deprecated work around for old ldns problems
+ * port -- the port to use, must be the same for all nameservers
+
+ """
+@@ -238,7 +238,7 @@
+ * rr_type -- the record type to query for
+ * rr_class -- the class to query for, defaults to IN (Internet)
+ * flags -- the flags to send the query with
+- * tries -- the number of times to attempt to acheive query in case of packet loss, etc
++ * tries -- the number of times to attempt to achieve query in case of packet loss, etc
+
+ **Examples**
+
+@@ -284,7 +284,7 @@
+
+ If the version of ldnsx you are using is old, it is possible that there could be new rr_types that
+ we don't recognise mnemonic for. You can still use the number XXX or the string "TYPEXXX". To
+- determine what rr_type menmonics we support, please refer to resolver.supported_rr_types()
++ determine what rr_type mnemonics we support, please refer to resolver.supported_rr_types()
+
+ """
+ # Determine rr_type int
+@@ -320,7 +320,7 @@
+ pkt = self._ldns_resolver.query(name, _rr_type, _rr_class, _flags)
+ except KeyboardInterrupt: #Since so much time is spent waiting on ldns, this is very common place for Ctr-C to fall
+ raise
+- except: #Since the ldns exceptiion is not very descriptive...
++ except: #Since the ldns exception is not very descriptive...
+ raise Exception("ldns backend ran into problems. Likely, the name you were querying for, %s, was invalid." % name)
+ #Deal with failed queries
+ if not pkt:
+@@ -497,7 +497,7 @@
+
+ Example returned value: "NOERROR"
+
+- possilbe rcodes (via ldns): "FORMERR", "MASK", "NOERROR",
++ possible rcodes (via ldns): "FORMERR", "MASK", "NOERROR",
+ "NOTAUTH", "NOTIMPL", "NOTZONE", "NXDOMAIN",
+ "NXRSET", "REFUSED", "SERVFAIL", "SHIFT",
+ "YXDOMAIN", "YXRRSET"
+@@ -823,7 +823,7 @@
+ return -1
+
+ def protocol(self):
+- """ Returns proticol of the DNSKEY"""
++ """ Returns protocol of the DNSKEY"""
+ t = self.rr_type()
+ if t == "DNSKEY":
+ return int(self[5])
+diff -ur ldns-1.7.1/contrib/ldnsx/README ldns/contrib/ldnsx/README
+--- ldns-1.7.1/contrib/ldnsx/README 2019-07-26 17:07:44.000000000 +0200
++++ ldns/contrib/ldnsx/README 2021-10-17 21:21:57.616229259 +0200
+@@ -1,8 +1,8 @@
+ LDNSX: Easy DNS (including DNSSEC) via ldns.
+
+-ldns is a great library. It is a powerfull tool for
++ldns is a great library. It is a powerful tool for
+ working with DNS. python-ldns it is a straight up clone of the C
+-interface, howver that is not a very good interface for python. Its
++interface, however that is not a very good interface for python. Its
+ documentation is incomplete and some functions don't work as
+ described. And some objects don't have a full python API.
+
+diff -ur ldns-1.7.1/contrib/ldnsx/source/index.rst ldns/contrib/ldnsx/source/index.rst
+--- ldns-1.7.1/contrib/ldnsx/source/index.rst 2019-07-26 17:07:44.000000000 +0200
++++ ldns/contrib/ldnsx/source/index.rst 2021-10-17 21:21:57.616229259 +0200
+@@ -3,9 +3,9 @@
+
+ LDNSX: Easy DNS (including DNSSEC) via ldns.
+
+-ldns is a great library. It is a powerfull tool for
++ldns is a great library. It is a powerful tool for
+ working with DNS. python-ldns it is a straight up clone of the C
+-interface, howver that is not a very good interface for python. Its
++interface, however that is not a very good interface for python. Its
+ documentation is incomplete and some functions don't work as
+ described. And some objects don't have a full python API.
+
+diff -ur ldns-1.7.1/contrib/python/Changelog ldns/contrib/python/Changelog
+--- ldns-1.7.1/contrib/python/Changelog 2019-07-26 17:07:44.000000000 +0200
++++ ldns/contrib/python/Changelog 2021-10-17 21:21:57.616229259 +0200
+@@ -2,7 +2,7 @@
+ * Added ldns_rdf.data_as_bytearray(). The method returns a bytearray object
+ containing rdf data.
+ * Changed the behaviour of ldns_resolver.trusted_key() in order to prevent
+- memory corrupotion and leaks.
++ memory corruption and leaks.
+ * Fixed memory leaks when destroying ldns_resolver.
+ * Removed ldns_pkt.section_count(), ldns_resolver.set_searchlist_count()
+ because it is marked static in the library.
+diff -ur ldns-1.7.1/contrib/python/docs/source/examples/example1.rst ldns/contrib/python/docs/source/examples/example1.rst
+--- ldns-1.7.1/contrib/python/docs/source/examples/example1.rst 2019-07-26 17:07:44.000000000 +0200
++++ ldns/contrib/python/docs/source/examples/example1.rst 2021-10-17 21:21:57.616229259 +0200
+@@ -50,7 +50,7 @@
+ pkt = resolver.query(dname, ldns.LDNS_RR_TYPE_MX, ldns.LDNS_RR_CLASS_IN, ldns.LDNS_RD)
+
+ The function should return a packet if everything goes well and this packet will contain resource records we asked for.
+-Note that there exists a simplier way. Instead of using a dname variable, we can use a string which will be automatically converted.
++Note that there exists a simpler way. Instead of using a dname variable, we can use a string which will be automatically converted.
+ ::
+
+ pkt = resolver.query("fit.vutbr.cz", ldns.LDNS_RR_TYPE_MX, ldns.LDNS_RR_CLASS_IN, ldns.LDNS_RD)
+diff -ur ldns-1.7.1/contrib/python/docs/source/examples/example8.rst ldns/contrib/python/docs/source/examples/example8.rst
+--- ldns-1.7.1/contrib/python/docs/source/examples/example8.rst 2019-07-26 17:07:44.000000000 +0200
++++ ldns/contrib/python/docs/source/examples/example8.rst 2021-10-17 21:21:57.616229259 +0200
+@@ -10,8 +10,8 @@
+
+ Signing consists of three steps
+
+-1. In the first step, the content of a zone file is readed and parsed. This can be done using :class:`ldns.ldns_zone` class.
++1. In the first step, the content of a zone file is read and parsed. This can be done using :class:`ldns.ldns_zone` class.
+
+-2. In the second step, the private and public key is readed and public key is inserted into zone (as DNSKEY).
++2. In the second step, the private and public key is read and public key is inserted into zone (as DNSKEY).
+
+-3. In the last step, the DNSSEC zone instace is created and all the RRs from zone file are copied here. Then, all the records are signed using :meth:`ldns.ldns_zone.sign` method. If the signing was successfull, the content of DNSSEC zone is written to a file.
++3. In the last step, the DNSSEC zone instance is created and all the RRs from zone file are copied here. Then, all the records are signed using :meth:`ldns.ldns_zone.sign` method. If the signing was successful, the content of DNSSEC zone is written to a file.
+diff -ur ldns-1.7.1/contrib/python/examples/test_buffer.py ldns/contrib/python/examples/test_buffer.py
+--- ldns-1.7.1/contrib/python/examples/test_buffer.py 2019-07-26 17:07:44.000000000 +0200
++++ ldns/contrib/python/examples/test_buffer.py 2021-10-17 21:21:57.619562532 +0200
+@@ -230,7 +230,7 @@
+
+ #if not error_detected:
+ if True:
+- mehod_name = "ldns_buffer.flip()"
++ method_name = "ldns_buffer.flip()"
+ buf.printf("abcdef")
+ try:
+ buf.flip()
+diff -ur ldns-1.7.1/contrib/python/examples/test_dname.py ldns/contrib/python/examples/test_dname.py
+--- ldns-1.7.1/contrib/python/examples/test_dname.py 2019-07-26 17:07:44.000000000 +0200
++++ ldns/contrib/python/examples/test_dname.py 2021-10-17 21:21:57.619562532 +0200
+@@ -44,7 +44,7 @@
+ except:
+ set_error()
+ #
+- # Error when printing a dname wich was created fron an empty string.
++ # Error when printing a dname wich was created from an empty string.
+ # Must find out why.
+ #
+ try:
+diff -ur ldns-1.7.1/contrib/python/ldns_buffer.i ldns/contrib/python/ldns_buffer.i
+--- ldns-1.7.1/contrib/python/ldns_buffer.i 2019-07-26 17:07:44.000000000 +0200
++++ ldns/contrib/python/ldns_buffer.i 2021-10-17 21:21:57.619562532 +0200
+@@ -483,7 +483,7 @@
+ :param amount: Amount to use.
+ :type amount: positive integer
+ :throws TypeError: When `amount` of non-integer type.
+- :return: (bool) hether this failed or succeeded.
++ :return: (bool) Whether this failed or succeeded.
+ """
+ return _ldns.ldns_buffer_reserve(self, amount)
+ #parameters: ldns_buffer *, size_t,
+diff -ur ldns-1.7.1/contrib/python/ldns_dname.i ldns/contrib/python/ldns_dname.i
+--- ldns-1.7.1/contrib/python/ldns_dname.i 2019-07-26 17:07:44.000000000 +0200
++++ ldns/contrib/python/ldns_dname.i 2021-10-17 21:21:57.619562532 +0200
+@@ -36,7 +36,7 @@
+ /* ========================================================================= */
+
+ /*
+- * Not here (with the exception of functions defined in this C code sction),
++ * Not here (with the exception of functions defined in this C code section),
+ * must be set in ldns_rdf.i.
+ */
+
+@@ -46,7 +46,7 @@
+ /* ========================================================================= */
+
+ /*
+- * Not here (with the exception of functions defined in this C code sction),
++ * Not here (with the exception of functions defined in this C code section),
+ * must be set in ldns_rdf.i.
+ */
+
+diff -ur ldns-1.7.1/contrib/python/ldns_dnssec.i ldns/contrib/python/ldns_dnssec.i
+--- ldns-1.7.1/contrib/python/ldns_dnssec.i 2019-07-26 17:07:44.000000000 +0200
++++ ldns/contrib/python/ldns_dnssec.i 2021-10-17 21:21:57.619562532 +0200
+@@ -163,7 +163,7 @@
+
+ @staticmethod
+ def new_frm_rr(raiseException=True):
+- """Create a new instace of dnssec name for the given RR.
++ """Create a new instance of dnssec name for the given RR.
+
+ :returns: (ldns_dnssec_name) instance
+ """
+diff -ur ldns-1.7.1/contrib/python/ldns_key.i ldns/contrib/python/ldns_key.i
+--- ldns-1.7.1/contrib/python/ldns_key.i 2019-07-26 17:07:44.000000000 +0200
++++ ldns/contrib/python/ldns_key.i 2021-10-17 21:21:57.619562532 +0200
+@@ -204,7 +204,7 @@
+ def expiration(self):
+ """return the key's expiration date
+
+- :returns: (uint32_t) the experiration date
++ :returns: (uint32_t) the expiration date
+ """
+ return _ldns.ldns_key_expiration(self)
+ #parameters: const ldns_key *,
+@@ -514,7 +514,7 @@
+ """Set the keylist's key count to count.
+
+ :param count:
+- the cuont
++ the count
+ """
+ _ldns.ldns_key_list_set_key_count(self,count)
+ #parameters: ldns_key_list *,size_t,
+diff -ur ldns-1.7.1/contrib/python/ldns_packet.i ldns/contrib/python/ldns_packet.i
+--- ldns-1.7.1/contrib/python/ldns_packet.i 2019-07-26 17:07:44.000000000 +0200
++++ ldns/contrib/python/ldns_packet.i 2021-10-17 21:21:57.619562532 +0200
+@@ -736,7 +736,7 @@
+ """
+ Return the packet's edns data.
+
+- :return: (:class:`ldns_rdf`) The ensd data.
++ :return: (:class:`ldns_rdf`) The edns data.
+ """
+ return _ldns._ldns_pkt_edns_data(self)
+ #parameters: const ldns_pkt *,
+@@ -1346,7 +1346,7 @@
+
+ def set_rcode(self, c):
+ """
+- Set the packet's respons code.
++ Set the packet's response code.
+
+ :param c: The rcode.
+ :type c: uint8_t
+diff -ur ldns-1.7.1/contrib/python/ldns_rdf.i ldns/contrib/python/ldns_rdf.i
+--- ldns-1.7.1/contrib/python/ldns_rdf.i 2019-07-26 17:07:44.000000000 +0200
++++ ldns/contrib/python/ldns_rdf.i 2021-10-17 21:21:57.619562532 +0200
+@@ -222,6 +222,7 @@
+ case LDNS_RDF_TYPE_TAG: return "TAG";
+ case LDNS_RDF_TYPE_LONG_STR: return "LONG_STR";
+ case LDNS_RDF_TYPE_AMTRELAY: return "AMTRELAY";
++ case LDNS_RDF_TYPE_SVCPARAMS: return "SVCPARAMS";
+ case LDNS_RDF_TYPE_CERTIFICATE_USAGE:
+ return "CERTIFICATE_USAGE";
+ case LDNS_RDF_TYPE_SELECTOR: return "SELECTOR";
+@@ -585,7 +586,7 @@
+ """
+ warnings.warn("The ldns_rdf.dname_new_frm_str() method is" +
+ " scheduled to be deprecated in future releases." +
+- " Use ldsn_dname constructor instead.",
++ " Use ldns_dname constructor instead.",
+ PendingDeprecationWarning, stacklevel=2)
+ return _ldns.ldns_dname_new_frm_str(string)
+
+@@ -608,7 +609,7 @@
+ """
+ warnings.warn("The ldns_rdf.absolute() method is scheduled" +
+ " to be deprecated in future releases." +
+- " Convert the ldns_rdf to ldsn_dname and the use its" +
++ " Convert the ldns_rdf to ldns_dname and the use its" +
+ " methods.", PendingDeprecationWarning, stacklevel=2)
+ if self.get_type() == _ldns.LDNS_RDF_TYPE_DNAME:
+ string = self.__str__()
+@@ -630,7 +631,7 @@
+ """
+ warnings.warn("The ldns_rdf.make_canonical() method is scheduled" +
+ " to be deprecated in future releases." +
+- " Convert the ldns_rdf to ldsn_dname and the use its" +
++ " Convert the ldns_rdf to ldns_dname and the use its" +
+ " methods.", PendingDeprecationWarning, stacklevel=2)
+ _ldns.ldns_dname2canonical(self)
+
+@@ -653,7 +654,7 @@
+ """
+ warnings.warn("The ldns_rdf.dname_compare() method is" +
+ " scheduled to be deprecated in future releases." +
+- " Convert the ldns_rdf to ldsn_dname and the use its" +
++ " Convert the ldns_rdf to ldns_dname and the use its" +
+ " methods.", PendingDeprecationWarning, stacklevel=2)
+ #
+ # The wrapped function generates asserts instead of setting
+@@ -685,7 +686,7 @@
+ """
+ warnings.warn("The ldns_rdf.cat() method is scheduled" +
+ " to be deprecated in future releases." +
+- " Convert the ldns_rdf to ldsn_dname and the use its" +
++ " Convert the ldns_rdf to ldns_dname and the use its" +
+ " methods.", PendingDeprecationWarning, stacklevel=2)
+ return _ldns.ldns_dname_cat(self, rd2)
+ #parameters: ldns_rdf *, ldns_rdf *,
+@@ -710,7 +711,7 @@
+ """
+ warnings.warn("The ldns_rdf.cat_clone() method is scheduled" +
+ " to be deprecated in future releases." +
+- " Convert the ldns_rdf to ldsn_dname and the use its" +
++ " Convert the ldns_rdf to ldns_dname and the use its" +
+ " methods.", PendingDeprecationWarning, stacklevel=2)
+ return _ldns.ldns_dname_cat_clone(self, rd2)
+ #parameters: const ldns_rdf *, const ldns_rdf *,
+@@ -740,7 +741,7 @@
+ """
+ warnings.warn("The ldns_rdf.interval() method is scheduled" +
+ " to be deprecated in future releases." +
+- " Convert the ldns_rdf to ldsn_dname and the use its" +
++ " Convert the ldns_rdf to ldns_dname and the use its" +
+ " methods.", PendingDeprecationWarning, stacklevel=2)
+ #
+ # The wrapped function generates asserts instead of setting
+@@ -779,7 +780,7 @@
+ """
+ warnings.warn("The ldns_rdf.is_subdomain() method is scheduled" +
+ " to be deprecated in future releases." +
+- " Convert the ldns_rdf to ldsn_dname and the use its" +
++ " Convert the ldns_rdf to ldns_dname and the use its" +
+ " methods.", PendingDeprecationWarning, stacklevel=2)
+ return _ldns.ldns_dname_is_subdomain(self, parent)
+ #parameters: const ldns_rdf *, const ldns_rdf *,
+@@ -806,7 +807,7 @@
+ """
+ warnings.warn("The ldns_rdf.label() method is scheduled" +
+ " to be deprecated in future releases." +
+- " Convert the ldns_rdf to ldsn_dname and the use its" +
++ " Convert the ldns_rdf to ldns_dname and the use its" +
+ " methods.", PendingDeprecationWarning, stacklevel=2)
+ return _ldns.ldns_dname_label(self, labelpos)
+ #parameters: const ldns_rdf *, uint8_t,
+@@ -826,7 +827,7 @@
+ """
+ warnings.warn("The ldns_rdf.label_count() method is scheduled" +
+ " to be deprecated in future releases." +
+- " Convert the ldns_rdf to ldsn_dname and the use its" +
++ " Convert the ldns_rdf to ldns_dname and the use its" +
+ " methods.", PendingDeprecationWarning, stacklevel=2)
+ return _ldns.ldns_dname_label_count(self)
+ #parameters: const ldns_rdf *,
+@@ -848,7 +849,7 @@
+ """
+ warnings.warn("The ldns_rdf.left_chop() method is scheduled" +
+ " to be deprecated in future releases." +
+- " Convert the ldns_rdf to ldsn_dname and the use its" +
++ " Convert the ldns_rdf to ldns_dname and the use its" +
+ " methods.", PendingDeprecationWarning, stacklevel=2)
+ return _ldns.ldns_dname_left_chop(self)
+ #parameters: const ldns_rdf *,
+@@ -871,7 +872,7 @@
+ """
+ warnings.warn("The ldns_rdf.reverse() method is scheduled" +
+ " to be deprecated in future releases." +
+- " Convert the ldns_rdf to ldsn_dname and the use its" +
++ " Convert the ldns_rdf to ldns_dname and the use its" +
+ " methods.", PendingDeprecationWarning, stacklevel=2)
+ if self.get_type() != _ldns.LDNS_RDF_TYPE_DNAME:
+ raise Exception("Operand must be a dname rdf.")
+diff -ur ldns-1.7.1/contrib/python/ldns_resolver.i ldns/contrib/python/ldns_resolver.i
+--- ldns-1.7.1/contrib/python/ldns_resolver.i 2019-07-26 17:07:44.000000000 +0200
++++ ldns/contrib/python/ldns_resolver.i 2021-10-17 21:21:57.619562532 +0200
+@@ -35,7 +35,7 @@
+ /* SWIG setting and definitions. */
+ /* ========================================================================= */
+
+-/* Creates temporary instance of (ldns_rersolver *). */
++/* Creates temporary instance of (ldns_resolver *). */
+ %typemap(in,numinputs=0,noblock=1) (ldns_resolver **r)
+ {
+ ldns_resolver *$1_res;
+@@ -431,7 +431,7 @@
+ Ask the resolver about name and return all address records.
+
+ :param name: The name to look for. String is automatically
+- converrted to dname.
++ converted to dname.
+ :type name: :class:`ldns_dname` or str
+ :param aclass: The class to use.
+ :type aclass: ldns_rr_class
+diff -ur ldns-1.7.1/contrib/python/ldns_rr.i ldns/contrib/python/ldns_rr.i
+--- ldns-1.7.1/contrib/python/ldns_rr.i 2019-07-26 17:07:44.000000000 +0200
++++ ldns/contrib/python/ldns_rr.i 2021-10-17 21:21:57.619562532 +0200
+@@ -562,7 +562,7 @@
+ :type prev: :class:`ldns_rdf`
+ :param raiseException: If True, an exception occurs in case a rr
+ instance can't be created.
+- :throws Exception: If `raiseExceprion` is set and fails.
++ :throws Exception: If `raiseException` is set and fails.
+ :throws TypeError: When parameters of incorrect types.
+ :return: (:class:`ldns_rr`) RR instance or None.
+
+@@ -612,7 +612,7 @@
+ :type prev: :class:`ldns_rdf`
+ :param raiseException: If True, an exception occurs in case
+ a rr instance can't be created.
+- :throws Exception: If `raiseExceprion` is set and fails.
++ :throws Exception: If `raiseException` is set and fails.
+ :throws TypeError: When parameters of incorrect types.
+ :return: (:class:`ldns_rr`) RR instance or None. If the object
+ can't be created and `raiseException` is True,
+@@ -657,7 +657,7 @@
+ :type prev: :class:`ldns_rdf`
+ :param raiseException: If True, an exception occurs in case when
+ a rr instance can't be created.
+- :throws Exception: If `raiseExceprion` is set and fails.
++ :throws Exception: If `raiseException` is set and fails.
+ :throws TypeError: When parameters of incorrect types.
+ :return: None when fails, otherwise a tuple containing:
+
+@@ -751,7 +751,7 @@
+ :type origin: :class:`ldns_dname`
+ :param prev: When the owner is white spaces use this.
+ :type prev: :class:`ldns_rdf`
+- :param raiseException: Iif True, an exception occurs in case
++ :param raiseException: If True, an exception occurs in case
+ a resolver object can't be created.
+ :throws Exception: If `raiseException` is set and the input
+ cannot be read.
+@@ -1424,9 +1424,9 @@
+
+ def rrsig_set_expiration(self, f):
+ """
+- Sets the expireation date of a LDNS_RR_TYPE_RRSIG rr.
++ Sets the expiration date of a LDNS_RR_TYPE_RRSIG rr.
+
+- :param f: The expireation date to set.
++ :param f: The expiration date to set.
+ :type f: :class:`ldns_rdf`
+ :throws TypeError: when `f` of non-:class:`ldns_rdf` type.
+ :return: (bool) True on success, False otherwise.
+@@ -1653,7 +1653,7 @@
+ Sets the type in the rr.
+
+ :param rr_type: Set to this type.
+- :type rr_type: ineteger
++ :type rr_type: integer
+ :throws TypeError: when `rr_type` of non-integer type.
+ """
+ _ldns.ldns_rr_set_type(self, rr_type)
+@@ -1695,7 +1695,7 @@
+ """
+ Calculates the uncompressed size of an RR.
+
+- :return: (inetger) size of the rr.
++ :return: (integer) size of the rr.
+ """
+ return _ldns.ldns_rr_uncompressed_size(self)
+ #parameters: const ldns_rr *,
+@@ -2441,7 +2441,7 @@
+
+ :param field: The field number.
+ :type field: positive int
+- :throws TypeError: when `field` of non-inetger type.
++ :throws TypeError: when `field` of non-integer type.
+ :return: (int) the rdf type for the field.
+ """
+ return _ldns.ldns_rr_descriptor_field_type(self, field)
+diff -ur ldns-1.7.1/contrib/python/ldns_zone.i ldns/contrib/python/ldns_zone.i
+--- ldns-1.7.1/contrib/python/ldns_zone.i 2019-07-26 17:07:44.000000000 +0200
++++ ldns/contrib/python/ldns_zone.i 2021-10-17 21:21:57.619562532 +0200
+@@ -132,7 +132,7 @@
+ :param file: a file object
+ :param origin: (ldns_rdf) the zones' origin
+ :param ttl: default ttl to use
+- :param rr_class: efault class to use (IN)
++ :param rr_class: Default class to use (IN)
+ :param raiseException: if True, an exception occurs in case a zone instance can't be created
+ :returns: zone instance or None. If an instance can't be created and raiseException is True, an exception occurs.
+ """
+@@ -149,7 +149,7 @@
+ :param file: a file object
+ :param origin: (ldns_rdf) the zones' origin
+ :param ttl: default ttl to use
+- :param rr_class: efault class to use (IN)
++ :param rr_class: Default class to use (IN)
+ :param raiseException: if True, an exception occurs in case a zone instance can't be created
+ :returns:
+ * zone - zone instance or None. If an instance can't be created and raiseException is True, an exception occurs.
+diff -ur ldns-1.7.1/dane.c ldns/dane.c
+--- ldns-1.7.1/dane.c 2019-07-26 17:07:44.000000000 +0200
++++ ldns/dane.c 2021-10-17 21:21:57.619562532 +0200
+@@ -1,7 +1,7 @@
+ /*
+ * Verify or create TLS authentication with DANE (RFC6698)
+ *
+- * (c) NLnetLabs 2012
++ * (c) NLnetLabs 2012-2020
+ *
+ * See the file LICENSE for the license.
+ *
+@@ -29,6 +29,63 @@
+ #include <openssl/x509v3.h>
+ #endif
+
++/* OpenSSL context options. At the moment, disable SSLv2, SSLv3
++ * and Compression, if available. TLSv1.0 is allowed at the moment.
++ * TLSv1.1 is the first to provide elliptic curves, so it is usually
++ * allowed in a TLS stack. TLSv1.2 is the first to provide authentication
++ * modes of operation, like GCM. The defines below are a moving
++ * target based on OpenSSL library version. Grep is useful to find
++ * the defines: grep -IR SSL_OP_NO_ /usr/include/openssl.
++ */
++#ifdef HAVE_SSL
++# ifdef SSL_OP_NO_SSLv2
++ const long NoOpenSSLv2 = SSL_OP_NO_SSLv2;
++# else
++ const long NoOpenSSLv2 = 0L;
++# endif
++# ifdef SSL_OP_NO_SSLv3
++ const long NoOpenSSLv3 = SSL_OP_NO_SSLv3;
++# else
++ const long NoOpenSSLv3 = 0L;
++# endif
++# ifdef SSL_OP_NO_TLSv1
++ const long NoOpenTLSv1 = SSL_OP_NO_TLSv1;
++# else
++ const long NoOpenTLSv1 = 0L;
++# endif
++# ifdef SSL_OP_NO_DTLSv1
++ const long NoOpenDTLSv1 = SSL_OP_NO_DTLSv1;
++# else
++ const long NoOpenDTLSv1 = 0L;
++# endif
++# ifdef SSL_OP_NO_COMPRESSION
++ const long NoOpenSSLCompression = SSL_OP_NO_COMPRESSION;
++# else
++ const long NoOpenSSLCompression = 0L;
++# endif
++#endif
++
++#ifdef USE_DANE_VERIFY
++static SSL_CTX*
++ldns_dane_new_ssl_context(void)
++{
++ SSL_CTX* ssl_ctx;
++
++ ssl_ctx = SSL_CTX_new(TLS_client_method());
++ if (ssl_ctx != NULL)
++ {
++ /* ldns allows TLS and DTLS v1.0 at the moment. Some may disagree.
++ * Sometime in the future they may be disabled, too. Maybe
++ * --disable-tlsv1 and --disable-dtlsv1 should be configure options.
++ */
++ long flags = NoOpenSSLv2 | NoOpenSSLv3 | NoOpenSSLCompression;
++ SSL_CTX_set_options(ssl_ctx, flags);
++ }
++
++ return ssl_ctx;
++}
++#endif
++
+ ldns_status
+ ldns_dane_create_tlsa_owner(ldns_rdf** tlsa_owner, const ldns_rdf* name,
+ uint16_t port, ldns_dane_transport transport)
+@@ -193,7 +250,7 @@
+ }
+
+
+-/* Orinary PKIX validation of cert (with extra_certs to help)
++/* Ordinary PKIX validation of cert (with extra_certs to help)
+ * against the CA's in store, but also return the validation chain.
+ */
+ static ldns_status
+@@ -641,7 +698,7 @@
+ * verification. We use these undocumented means with the ldns
+ * dane function prototypes which did only offline dane verification.
+ */
+- if (!(ssl_ctx = SSL_CTX_new(TLS_client_method())))
++ if (!(ssl_ctx = ldns_dane_new_ssl_context()))
+ s = LDNS_STATUS_MEM_ERR;
+
+ else if (SSL_CTX_dane_enable(ssl_ctx) <= 0)
+@@ -841,7 +898,7 @@
+ * verification. We use these undocumented means with the ldns
+ * dane function prototypes which did only offline dane verification.
+ */
+- if (!(ssl_ctx = SSL_CTX_new(TLS_client_method())))
++ if (!(ssl_ctx = ldns_dane_new_ssl_context()))
+ s = LDNS_STATUS_MEM_ERR;
+
+ else if (SSL_CTX_dane_enable(ssl_ctx) <= 0)
+diff -ur ldns-1.7.1/dnssec.c ldns/dnssec.c
+--- ldns-1.7.1/dnssec.c 2019-07-26 17:07:44.000000000 +0200
++++ ldns/dnssec.c 2021-10-17 21:21:57.619562532 +0200
+@@ -332,6 +332,7 @@
+ }
+
+ #ifdef HAVE_SSL
++#ifdef USE_DSA
+ DSA *
+ ldns_key_buf2dsa(const ldns_buffer *key)
+ {
+@@ -407,6 +408,7 @@
+ #endif /* OPENSSL_VERSION_NUMBER */
+ return dsa;
+ }
++#endif /* USE_DSA */
+
+ RSA *
+ ldns_key_buf2rsa(const ldns_buffer *key)
+@@ -432,7 +434,7 @@
+ return NULL;
+ /* need some smart comment here XXX*/
+ /* the exponent is too large so it's places
+- * futher...???? */
++ * further...???? */
+ memmove(&int16, key+1, 2);
+ exp = ntohs(int16);
+ offset = 3;
+@@ -910,7 +912,7 @@
+ cur_rrsets = from->rrsets;
+ while (cur_rrsets) {
+ /* Do not include non-authoritative rrsets on the delegation point
+- * in the type bitmap. Potentionally not skipping insecure
++ * in the type bitmap. Potentially not skipping insecure
+ * delegation should have been done earlier, in function
+ * ldns_dnssec_zone_create_nsec3s, or even earlier in:
+ * ldns_dnssec_zone_sign_nsec3_flg .
+@@ -1332,6 +1334,8 @@
+ ldns_rdf *salt_rdf = ldns_nsec3_salt(nsec3_rr);
+ if (salt_rdf && ldns_rdf_size(salt_rdf) > 0) {
+ salt_length = ldns_rdf_data(salt_rdf)[0];
++ if((size_t)salt_length+1 > ldns_rdf_size(salt_rdf))
++ return NULL;
+ salt = LDNS_XMALLOC(uint8_t, salt_length);
+ if(!salt) return NULL;
+ memcpy(salt, &ldns_rdf_data(salt_rdf)[1], salt_length);
+@@ -1904,7 +1908,7 @@
+ const ldns_rdf *sig_rdf)
+ {
+ /* convert from two BIGNUMs in the rdata buffer, to ASN notation.
+- * ASN preable: 30440220 <R 32bytefor256> 0220 <S 32bytefor256>
++ * ASN preamble: 30440220 <R 32bytefor256> 0220 <S 32bytefor256>
+ * the '20' is the length of that field (=bnsize).
+ * the '44' is the total remaining length.
+ * if negative, start with leading zero.
+diff -ur ldns-1.7.1/dnssec_sign.c ldns/dnssec_sign.c
+--- ldns-1.7.1/dnssec_sign.c 2019-07-26 17:07:44.000000000 +0200
++++ ldns/dnssec_sign.c 2021-10-17 21:21:57.619562532 +0200
+@@ -24,6 +24,9 @@
+ #endif
+ #endif /* HAVE_SSL */
+
++#define LDNS_SIGN_WITH_ZONEMD ( LDNS_SIGN_WITH_ZONEMD_SIMPLE_SHA384 \
++ | LDNS_SIGN_WITH_ZONEMD_SIMPLE_SHA512 )
++
+ ldns_rr *
+ ldns_create_empty_rrsig(const ldns_rr_list *rrset,
+ const ldns_key *current_key)
+@@ -413,11 +416,14 @@
+ {
+ EC_KEY* ec;
+ const EC_GROUP* g;
+-#ifdef HAVE_EVP_PKEY_BASE_ID
++#ifdef HAVE_EVP_PKEY_GET_BASE_ID
++ if(EVP_PKEY_get_base_id(pkey) != EVP_PKEY_EC)
++ return 0;
++#elif defined(HAVE_EVP_PKEY_BASE_ID)
+ if(EVP_PKEY_base_id(pkey) != EVP_PKEY_EC)
+ return 0;
+ #else
+- if(EVP_PKEY_type(key->type) != EVP_PKEY_EC)
++ if(EVP_PKEY_type(pkey->type) != EVP_PKEY_EC)
+ return 0;
+ #endif
+ ec = EVP_PKEY_get1_EC_KEY(pkey);
+@@ -529,7 +535,9 @@
+ #ifdef USE_DSA
+ #ifndef S_SPLINT_S
+ /* unfortunately, OpenSSL output is different from DNS DSA format */
+-# ifdef HAVE_EVP_PKEY_BASE_ID
++# ifdef HAVE_EVP_PKEY_GET_BASE_ID
++ if (EVP_PKEY_get_base_id(key) == EVP_PKEY_DSA) {
++# elif defined(HAVE_EVP_PKEY_BASE_ID)
+ if (EVP_PKEY_base_id(key) == EVP_PKEY_DSA) {
+ # else
+ if (EVP_PKEY_type(key->type) == EVP_PKEY_DSA) {
+@@ -541,7 +549,9 @@
+ #endif
+ #if defined(USE_ECDSA)
+ if(
+-# ifdef HAVE_EVP_PKEY_BASE_ID
++# ifdef HAVE_EVP_PKEY_GET_BASE_ID
++ EVP_PKEY_get_base_id(key)
++# elif defined(HAVE_EVP_PKEY_BASE_ID)
+ EVP_PKEY_base_id(key)
+ # else
+ EVP_PKEY_type(key->type)
+@@ -655,7 +665,7 @@
+ /* ldns_rr_list_push_rr()
+ * returns false when unable
+ * to increase the capacity
+- * of the ldsn_rr_list
++ * of the ldns_rr_list
+ */
+ }
+ }
+@@ -691,7 +701,7 @@
+ /* When the cut is caused by a delegation, below_delegation will be 1.
+ * When caused by a DNAME, below_delegation will be 0.
+ */
+- int below_delegation = -1; /* init suppresses comiler warning */
++ int below_delegation = -1; /* init suppresses compiler warning */
+ ldns_status s;
+
+ if (!zone || !zone->names) {
+@@ -713,7 +723,7 @@
+ * FIXME! If there are labels in between the SOA and
+ * the cut, going from the authoritative space (below
+ * the SOA) up into occluded space again, will not be
+- * detected with the contruct below!
++ * detected with the construct below!
+ */
+ if (ldns_dname_is_subdomain(owner, cut) &&
+ !ldns_dnssec_rrsets_contains_type(
+@@ -812,17 +822,24 @@
+ uint32_t nsec_ttl;
+ ldns_dnssec_rrsets *soa;
+
+- /* the TTL of NSEC rrs should be set to the minimum TTL of
+- * the zone SOA (RFC4035 Section 2.3)
++ /* The TTL value for any NSEC RR SHOULD be the same TTL value as the
++ * lesser of the MINIMUM field of the SOA record and the TTL of the SOA
++ * itself. This matches the definition of the TTL for negative
++ * responses in [RFC2308]. (draft-ietf-dnsop-nsec-ttl-01 update of
++ * RFC4035 Section 2.3)
+ */
+ soa = ldns_dnssec_name_find_rrset(zone->soa, LDNS_RR_TYPE_SOA);
+
+ /* did the caller actually set it? if not,
+ * fall back to default ttl
+ */
+- if (soa && soa->rrs && soa->rrs->rr
+- && (ldns_rr_rdf(soa->rrs->rr, 6) != NULL)) {
+- nsec_ttl = ldns_rdf2native_int32(ldns_rr_rdf(soa->rrs->rr, 6));
++ if (soa && soa->rrs && soa->rrs->rr) {
++ ldns_rr *soa_rr = soa->rrs->rr;
++ ldns_rdf *min_rdf = ldns_rr_rdf(soa_rr, 6);
++
++ nsec_ttl = min_rdf == NULL
++ || ldns_rr_ttl(soa_rr) < ldns_rdf2native_int32(min_rdf)
++ ? ldns_rr_ttl(soa_rr) : ldns_rdf2native_int32(min_rdf);
+ } else {
+ nsec_ttl = LDNS_DEFAULT_TTL;
+ }
+@@ -906,17 +923,24 @@
+ return LDNS_STATUS_ERR;
+ }
+
+- /* the TTL of NSEC rrs should be set to the minimum TTL of
+- * the zone SOA (RFC4035 Section 2.3)
++ /* The TTL value for any NSEC RR SHOULD be the same TTL value as the
++ * lesser of the MINIMUM field of the SOA record and the TTL of the SOA
++ * itself. This matches the definition of the TTL for negative
++ * responses in [RFC2308]. (draft-ietf-dnsop-nsec-ttl-01 update of
++ * RFC4035 Section 2.3)
+ */
+ soa = ldns_dnssec_name_find_rrset(zone->soa, LDNS_RR_TYPE_SOA);
+
+ /* did the caller actually set it? if not,
+ * fall back to default ttl
+ */
+- if (soa && soa->rrs && soa->rrs->rr
+- && ldns_rr_rdf(soa->rrs->rr, 6) != NULL) {
+- nsec_ttl = ldns_rdf2native_int32(ldns_rr_rdf(soa->rrs->rr, 6));
++ if (soa && soa->rrs && soa->rrs->rr) {
++ ldns_rr *soa_rr = soa->rrs->rr;
++ ldns_rdf *min_rdf = ldns_rr_rdf(soa_rr, 6);
++
++ nsec_ttl = min_rdf == NULL
++ || ldns_rr_ttl(soa_rr) < ldns_rdf2native_int32(min_rdf)
++ ? ldns_rr_ttl(soa_rr) : ldns_rdf2native_int32(min_rdf);
+ } else {
+ nsec_ttl = LDNS_DEFAULT_TTL;
+ }
+@@ -1365,6 +1389,8 @@
+ return ldns_dnssec_zone_sign_flg(zone, new_rrs, key_list, func, arg, 0);
+ }
+
++ldns_status dnssec_zone_equip_zonemd(ldns_dnssec_zone *zone,
++ ldns_rr_list *new_rrs, ldns_key_list *key_list, int flags);
+ ldns_status
+ ldns_dnssec_zone_sign_flg(ldns_dnssec_zone *zone,
+ ldns_rr_list *new_rrs,
+@@ -1374,25 +1400,46 @@
+ int flags)
+ {
+ ldns_status result = LDNS_STATUS_OK;
++ ldns_dnssec_rrsets zonemd_rrset;
++ bool zonemd_added = false;
+
+ if (!zone || !new_rrs || !key_list) {
+ return LDNS_STATUS_ERR;
+ }
++ if (flags & LDNS_SIGN_WITH_ZONEMD) {
++ ldns_dnssec_rrsets **rrsets_ref = &zone->soa->rrsets;
+
++ while (*rrsets_ref
++ && (*rrsets_ref)->type < LDNS_RR_TYPE_ZONEMD)
++ rrsets_ref = &(*rrsets_ref)->next;
++ if (!*rrsets_ref
++ || (*rrsets_ref)->type > LDNS_RR_TYPE_ZONEMD) {
++ zonemd_rrset.rrs = NULL;
++ zonemd_rrset.type = LDNS_RR_TYPE_ZONEMD;
++ zonemd_rrset.signatures = NULL;
++ zonemd_rrset.next = *rrsets_ref;
++ *rrsets_ref = &zonemd_rrset;
++ zonemd_added = true;
++ }
++ }
+ /* zone is already sorted */
+ result = ldns_dnssec_zone_mark_glue(zone);
+ if (result != LDNS_STATUS_OK) {
+ return result;
+ }
+-
+ /* check whether we need to add nsecs */
+- if (zone->names && !((ldns_dnssec_name *)zone->names->root->data)->nsec) {
++ if ((flags & LDNS_SIGN_NO_KEYS_NO_NSECS)
++ && ldns_key_list_key_count(key_list) < 1)
++ ; /* pass */
++
++ else if (zone->names
++ && !((ldns_dnssec_name *)zone->names->root->data)->nsec) {
++
+ result = ldns_dnssec_zone_create_nsecs(zone, new_rrs);
+ if (result != LDNS_STATUS_OK) {
+ return result;
+ }
+ }
+-
+ result = ldns_dnssec_zone_create_rrsigs_flg(zone,
+ new_rrs,
+ key_list,
+@@ -1400,7 +1447,18 @@
+ arg,
+ flags);
+
+- return result;
++ if (zonemd_added) {
++ ldns_dnssec_rrsets **rrsets_ref
++ = &zone->soa->rrsets;
++
++ while (*rrsets_ref
++ && (*rrsets_ref)->type < LDNS_RR_TYPE_ZONEMD)
++ rrsets_ref = &(*rrsets_ref)->next;
++ *rrsets_ref = zonemd_rrset.next;
++ }
++ return flags & LDNS_SIGN_WITH_ZONEMD
++ ? dnssec_zone_equip_zonemd(zone, new_rrs, key_list, flags)
++ : result;
+ }
+
+ ldns_status
+@@ -1436,6 +1494,8 @@
+ {
+ ldns_rr *nsec3, *nsec3param;
+ ldns_status result = LDNS_STATUS_OK;
++ bool zonemd_added = false;
++ ldns_dnssec_rrsets zonemd_rrset;
+
+ /* zone is already sorted */
+ result = ldns_dnssec_zone_mark_glue(zone);
+@@ -1454,7 +1514,13 @@
+ }
+
+ nsec3 = ((ldns_dnssec_name *)zone->names->root->data)->nsec;
+- if (nsec3 && ldns_rr_get_type(nsec3) == LDNS_RR_TYPE_NSEC3) {
++
++ /* check whether we need to add nsecs */
++ if ((signflags & LDNS_SIGN_NO_KEYS_NO_NSECS)
++ && ldns_key_list_key_count(key_list) < 1)
++ ; /* pass */
++
++ else if (nsec3 && ldns_rr_get_type(nsec3) == LDNS_RR_TYPE_NSEC3) {
+ /* no need to recreate */
+ } else {
+ if (!ldns_dnssec_zone_find_rrset(zone,
+@@ -1481,6 +1547,23 @@
+ }
+ ldns_rr_list_push_rr(new_rrs, nsec3param);
+ }
++ if (signflags & LDNS_SIGN_WITH_ZONEMD) {
++ ldns_dnssec_rrsets **rrsets_ref
++ = &zone->soa->rrsets;
++
++ while (*rrsets_ref
++ && (*rrsets_ref)->type < LDNS_RR_TYPE_ZONEMD)
++ rrsets_ref = &(*rrsets_ref)->next;
++ if (!*rrsets_ref
++ || (*rrsets_ref)->type > LDNS_RR_TYPE_ZONEMD) {
++ zonemd_rrset.rrs = NULL;
++ zonemd_rrset.type = LDNS_RR_TYPE_ZONEMD;
++ zonemd_rrset.signatures = NULL;
++ zonemd_rrset.next = *rrsets_ref;
++ *rrsets_ref = &zonemd_rrset;
++ zonemd_added = true;
++ }
++ }
+ result = ldns_dnssec_zone_create_nsec3s_mkmap(zone,
+ new_rrs,
+ algorithm,
+@@ -1489,6 +1572,15 @@
+ salt_length,
+ salt,
+ map);
++ if (zonemd_added) {
++ ldns_dnssec_rrsets **rrsets_ref
++ = &zone->soa->rrsets;
++
++ while (*rrsets_ref
++ && (*rrsets_ref)->type < LDNS_RR_TYPE_ZONEMD)
++ rrsets_ref = &(*rrsets_ref)->next;
++ *rrsets_ref = zonemd_rrset.next;
++ }
+ if (result != LDNS_STATUS_OK) {
+ return result;
+ }
+@@ -1501,8 +1593,12 @@
+ arg,
+ signflags);
+ }
++ if (result || !zone->names)
++ return result;
+
+- return result;
++ return signflags & LDNS_SIGN_WITH_ZONEMD
++ ? dnssec_zone_equip_zonemd(zone, new_rrs, key_list, signflags)
++ : result;
+ }
+
+ ldns_status
+diff -ur ldns-1.7.1/dnssec_verify.c ldns/dnssec_verify.c
+--- ldns-1.7.1/dnssec_verify.c 2019-07-26 17:07:44.000000000 +0200
++++ ldns/dnssec_verify.c 2021-10-17 21:21:57.619562532 +0200
+@@ -21,7 +21,7 @@
+ ldns_dnssec_data_chain *nc = LDNS_CALLOC(ldns_dnssec_data_chain, 1);
+ if(!nc) return NULL;
+ /*
+- * not needed anymore because CALLOC initalizes everything to zero.
++ * not needed anymore because CALLOC initializes everything to zero.
+
+ nc->rrset = NULL;
+ nc->parent_type = 0;
+@@ -597,7 +597,9 @@
+ if (tree->parent_status[i]
+ == LDNS_STATUS_SSL_ERR) {
+ printf("; SSL Error: ");
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(HAVE_LIBRESSL)
+ ERR_load_crypto_strings();
++#endif
+ ERR_print_errors_fp(stdout);
+ printf("\n");
+ }
+@@ -1501,7 +1503,7 @@
+ ldns_rr_list *rrsigs)
+ {
+ ldns_rdf *rr_name;
+- ldns_rdf *wildcard_name;
++ ldns_rdf *wildcard_name = NULL;
+ ldns_rdf *chopped_dname;
+ ldns_rr *cur_nsec;
+ size_t i;
+@@ -1512,14 +1514,19 @@
+ bool type_covered = false;
+ bool wildcard_covered = false;
+ bool wildcard_type_covered = false;
++ bool rr_name_is_root = false;
+
+- wildcard_name = ldns_dname_new_frm_str("*");
+ rr_name = ldns_rr_owner(rr);
+- chopped_dname = ldns_dname_left_chop(rr_name);
+- result = ldns_dname_cat(wildcard_name, chopped_dname);
+- ldns_rdf_deep_free(chopped_dname);
+- if (result != LDNS_STATUS_OK) {
+- return result;
++ rr_name_is_root = ldns_rdf_size(rr_name) == 1
++ && *ldns_rdf_data(rr_name) == 0;
++ if (!rr_name_is_root) {
++ wildcard_name = ldns_dname_new_frm_str("*");
++ chopped_dname = ldns_dname_left_chop(rr_name);
++ result = ldns_dname_cat(wildcard_name, chopped_dname);
++ ldns_rdf_deep_free(chopped_dname);
++ if (result != LDNS_STATUS_OK) {
++ return result;
++ }
+ }
+
+ for (i = 0; i < ldns_rr_list_rr_count(nsecs); i++) {
+@@ -1546,6 +1553,9 @@
+ name_covered = true;
+ }
+
++ if (rr_name_is_root)
++ continue;
++
+ if (ldns_dname_compare(wildcard_name,
+ ldns_rr_owner(cur_nsec)) == 0) {
+ if (ldns_nsec_bitmap_covers_type(ldns_nsec_get_bitmap(cur_nsec),
+@@ -1566,6 +1576,9 @@
+ return LDNS_STATUS_DNSSEC_NSEC_RR_NOT_COVERED;
+ }
+
++ if (rr_name_is_root)
++ return LDNS_STATUS_OK;
++
+ if (wildcard_type_covered || !wildcard_covered) {
+ return LDNS_STATUS_DNSSEC_NSEC_WILDCARD_NOT_COVERED;
+ }
+@@ -2390,8 +2403,12 @@
+ ldns_rr_list *good_keys)
+ {
+ ldns_status result;
+- ldns_rr_list *valid = ldns_rr_list_new();
+- if (!valid)
++ ldns_rr_list *valid;
++
++ if (!good_keys)
++ valid = NULL;
++
++ else if (!(valid = ldns_rr_list_new()))
+ return LDNS_STATUS_MEM_ERR;
+
+ result = ldns_verify_rrsig_keylist_notime(rrset, rrsig, keys, valid);
+diff -ur ldns-1.7.1/dnssec_zone.c ldns/dnssec_zone.c
+--- ldns-1.7.1/dnssec_zone.c 2019-07-26 17:07:44.000000000 +0200
++++ ldns/dnssec_zone.c 2021-10-17 21:21:57.619562532 +0200
+@@ -323,7 +323,7 @@
+ return NULL;
+ }
+ /*
+- * not needed anymore because CALLOC initalizes everything to zero.
++ * not needed anymore because CALLOC initializes everything to zero.
+
+ new_name->name = NULL;
+ new_name->rrsets = NULL;
+@@ -370,9 +370,10 @@
+ ldns_dnssec_rrs_free_internal(name->nsec_signatures, deep);
+ }
+ if (name->hashed_name) {
+- if (deep) {
+- ldns_rdf_deep_free(name->hashed_name);
+- }
++ /* Hashed name is always allocated when signing,
++ * so always deep free
++ */
++ ldns_rdf_deep_free(name->hashed_name);
+ }
+ LDNS_FREE(name);
+ }
+@@ -588,7 +589,7 @@
+ /* When the zone is first read into an list and then inserted into an
+ * ldns_dnssec_zone (rbtree) the nodes of the rbtree are allocated close (next)
+ * to each other. Because ldns-verify-zone (the only program that uses this
+- * function) uses the rbtree mostly for sequentual walking, this results
++ * function) uses the rbtree mostly for sequential walking, this results
+ * in a speed increase (of 15% on linux) because we have less CPU-cache misses.
+ */
+ #define FASTER_DNSSEC_ZONE_NEW_FRM_FP 1 /* Because of L2 cache efficiency */
+@@ -793,10 +794,21 @@
+ LDNS_FREE(node);
+ }
+
++static void
++ldns_hashed_names_node_free(ldns_rbnode_t *node, void *arg) {
++ (void) arg;
++ LDNS_FREE(node);
++}
++
+ void
+ ldns_dnssec_zone_free(ldns_dnssec_zone *zone)
+ {
+ if (zone) {
++ if (zone->hashed_names) {
++ ldns_traverse_postorder(zone->hashed_names,
++ ldns_hashed_names_node_free, NULL);
++ LDNS_FREE(zone->hashed_names);
++ }
+ if (zone->names) {
+ /* destroy all name structures within the tree */
+ ldns_traverse_postorder(zone->names,
+@@ -812,6 +824,11 @@
+ ldns_dnssec_zone_deep_free(ldns_dnssec_zone *zone)
+ {
+ if (zone) {
++ if (zone->hashed_names) {
++ ldns_traverse_postorder(zone->hashed_names,
++ ldns_hashed_names_node_free, NULL);
++ LDNS_FREE(zone->hashed_names);
++ }
+ if (zone->names) {
+ /* destroy all name structures within the tree */
+ ldns_traverse_postorder(zone->names,
+@@ -834,12 +851,6 @@
+ ldns_dnssec_name* name, ldns_rr* nsec3rr);
+
+ static void
+-ldns_hashed_names_node_free(ldns_rbnode_t *node, void *arg) {
+- (void) arg;
+- LDNS_FREE(node);
+-}
+-
+-static void
+ ldns_dnssec_zone_hashed_names_from_nsec3(
+ ldns_dnssec_zone* zone, ldns_rr* nsec3rr)
+ {
+@@ -908,20 +919,22 @@
+ static ldns_rbnode_t *
+ ldns_dnssec_zone_find_nsec3_original(ldns_dnssec_zone *zone, ldns_rr *rr) {
+ ldns_rdf *hashed_name;
++ ldns_rbnode_t *to_return;
+
+- hashed_name = ldns_dname_label(ldns_rr_owner(rr), 0);
+- if (hashed_name == NULL) {
+- return NULL;
+- }
+ if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_NSEC3 && ! zone->_nsec3params){
+
+ ldns_dnssec_zone_hashed_names_from_nsec3(zone, rr);
+ }
+ if (zone->hashed_names == NULL) {
+- ldns_rdf_deep_free(hashed_name);
+ return NULL;
+ }
+- return ldns_rbtree_search(zone->hashed_names, hashed_name);
++ hashed_name = ldns_dname_label(ldns_rr_owner(rr), 0);
++ if (hashed_name == NULL) {
++ return NULL;
++ }
++ to_return = ldns_rbtree_search(zone->hashed_names, hashed_name);
++ ldns_rdf_deep_free(hashed_name);
++ return to_return;
+ }
+
+ ldns_status
+@@ -1127,6 +1140,7 @@
+ }
+ node = ldns_rbtree_search(nsec3s,
+ ent_hashed_name);
++ ldns_rdf_deep_free(ent_hashed_name);
+ if (!node) {
+ ldns_rdf_deep_free(l1);
+ ldns_rdf_deep_free(l2);
+@@ -1201,3 +1215,706 @@
+ }
+ return false;
+ }
++
++/*
++ * Stuff for calculating and verifying zone digests
++ */
++typedef enum dnssec_zone_rr_iter_state {
++ DNSSEC_ZONE_RR_ITER_LT_RRSIG
++ , DNSSEC_ZONE_RR_ITER_RRSIGs_NO_NSEC
++ , DNSSEC_ZONE_RR_ITER_REST
++ , DNSSEC_ZONE_RR_ITER_RRSIGs_NSEC
++ , DNSSEC_ZONE_RR_ITER_RRSIGs_NSEC_REST
++ , DNSSEC_ZONE_RR_ITER_NSEC3
++ , DNSSEC_ZONE_RR_ITER_FINI
++} dnssec_zone_rr_iter_state;
++
++typedef struct dnssec_zone_rr_iter {
++ ldns_dnssec_zone *zone;
++ ldns_rbnode_t *node;
++ ldns_dnssec_name *name;
++ ldns_dnssec_rrsets *rrsets;
++ ldns_dnssec_rrs *rrs;
++ ldns_dnssec_rrsets *rrsets4rrsigs;
++ ldns_rbnode_t *nsec3_node;
++ ldns_dnssec_name *nsec3_name;
++ dnssec_zone_rr_iter_state state;
++ ldns_rdf *apex_name;
++ uint8_t apex_labs;
++} dnssec_zone_rr_iter;
++
++INLINE void
++dnssec_zone_rr_iter_set_state_for_next_name(dnssec_zone_rr_iter *i)
++{
++ /* Make sure the i->name is "in zone" (i.e. below the apex) */
++ if (i->apex_name) {
++ ldns_rdf *name = (ldns_rdf *)i->node->key;
++
++ while (i->name && name != i->apex_name /* not apex */
++
++ && ( ldns_dname_label_count(name) != i->apex_labs
++ || ldns_dname_compare(name, i->apex_name)) /* not apex */
++
++ && !ldns_dname_is_subdomain(name, i->apex_name) /* no sub */) {
++
++ /* next name */
++ i->node = ldns_rbtree_next(i->node);
++ if (i->node == LDNS_RBTREE_NULL)
++ i->name = NULL;
++ else {
++ i->name = (ldns_dnssec_name *)i->node->data;
++ name = (ldns_rdf *)i->node->key;
++ }
++ }
++ }
++ /* determine state */
++ if (!i->name) {
++ if (!i->nsec3_name)
++ i->state = DNSSEC_ZONE_RR_ITER_FINI;
++ else {
++ i->rrs = i->nsec3_name->nsec_signatures;
++ i->state = DNSSEC_ZONE_RR_ITER_NSEC3;
++ }
++ } else if (!i->nsec3_name) {
++ i->rrsets = i->name->rrsets;
++ i->state = DNSSEC_ZONE_RR_ITER_LT_RRSIG;
++
++ } else if (ldns_dname_compare( ldns_rr_owner(i->nsec3_name->nsec)
++ , (ldns_rdf *)i->node->key) < 0) {
++ i->rrs = i->nsec3_name->nsec_signatures;
++ i->state = DNSSEC_ZONE_RR_ITER_NSEC3;
++ } else {
++ i->rrsets = i->name->rrsets;
++ i->state = DNSSEC_ZONE_RR_ITER_LT_RRSIG;
++ }
++}
++
++/**
++ * Iterate over the RR's in the ldns_dnssec_zone in canonical order.
++ * There are three possible paths through the RR's in a ldns_dnssec_name.
++ *
++ * 1. There is no NSEC:
++ *
++ * 1.1. All the RRs in the name->rrsets with type < RRSIG,
++ * state: DNSSEC_ZONE_RR_ITER_LT_RRSIG
++ *
++ * 1.2. Then all the RRSIGs from name->rrsets (likely none)
++ * state: DNSSEC_ZONE_RR_ITER_RRSIGs_NO_NSEC
++ *
++ * 1.3. Finally the remaining RRs in name->rrsets (type > RRSIG)
++ * state: DNSSEC_ZONE_RR_ITER_REST
++ *
++ *
++ * 2. There is a NSEC of type NSEC with this name:
++ *
++ * 2.1. All the RRs in the name->rrsets with type < RRSIG,
++ * state: DNSSEC_ZONE_RR_ITER_LT_RRSIG
++ *
++ * 2.2. Then all the RRSIGs from name->rrsets with type < NSEC
++ * state: DNSSEC_ZONE_RR_ITER_RRSIGs_NO_NSEC
++ *
++ * 2.3. Then the signatures of the NSEC RR, followed by
++ * the signatures of the remaining name->rrsets (type > NSEC),
++ * followed by the NSEC rr.
++ * state: DNSSEC_ZONE_RR_ITER_RRSIGs_NO_NSEC
++ *
++ * 2.4. Finally the remaining RRs in name->rrsets (type > RRSIG)
++ * state: DNSSEC_ZONE_RR_ITER_REST
++ *
++ *
++ * 3. There is a NSEC of type NSEC3 for this name:
++ *
++ * 3.1. If the NSEC3 name is before the name for other RRsets in the zone,
++ * Then all signatures of the NSEC3 RR, followed by the NSEC3
++ * state: DNSSEC_ZONE_RR_ITER_NSEC3
++ *
++ * otherwise follow path for "no NSEC" for the name for other RRsets
++ */
++static ldns_rr *
++dnssec_zone_rr_iter_next(dnssec_zone_rr_iter *i)
++{
++ ldns_rr *nsec3;
++
++ for (;;) {
++ if (i->rrs) {
++ ldns_rr *rr = i->rrs->rr;
++ i->rrs = i->rrs->next;
++ return rr;
++ }
++ switch (i->state) {
++ case DNSSEC_ZONE_RR_ITER_LT_RRSIG:
++ if (i->rrsets
++ && i->rrsets->type < LDNS_RR_TYPE_RRSIG) {
++
++ i->rrs = i->rrsets->rrs;
++ i->rrsets = i->rrsets->next;
++ break;
++ }
++ i->rrsets4rrsigs = i->name->rrsets;
++ if (i->name->nsec && ldns_rr_get_type(i->name->nsec)
++ == LDNS_RR_TYPE_NSEC) {
++
++ i->state = DNSSEC_ZONE_RR_ITER_RRSIGs_NSEC;
++ break;
++ }
++ i->state = DNSSEC_ZONE_RR_ITER_RRSIGs_NO_NSEC;
++ /* fallthrough */
++
++ case DNSSEC_ZONE_RR_ITER_RRSIGs_NO_NSEC:
++ if (i->rrsets4rrsigs) {
++ i->rrs = i->rrsets4rrsigs->signatures;
++ i->rrsets4rrsigs = i->rrsets4rrsigs->next;
++ break;
++ }
++ i->state = DNSSEC_ZONE_RR_ITER_REST;
++ /* fallthrough */
++
++ case DNSSEC_ZONE_RR_ITER_REST:
++ if (i->rrsets) {
++ i->rrs = i->rrsets->rrs;
++ i->rrsets = i->rrsets->next;
++ break;
++ }
++ /* next name */
++ i->node = ldns_rbtree_next(i->node);
++ i->name = i->node == LDNS_RBTREE_NULL ? NULL
++ : (ldns_dnssec_name *)i->node->data;
++
++ dnssec_zone_rr_iter_set_state_for_next_name(i);
++ break;
++
++ case DNSSEC_ZONE_RR_ITER_RRSIGs_NSEC:
++ if (i->rrsets4rrsigs
++ && i->rrsets4rrsigs->type < LDNS_RR_TYPE_NSEC) {
++
++ i->rrs = i->rrsets4rrsigs->signatures;
++ i->rrsets4rrsigs = i->rrsets4rrsigs->next;
++ break;
++ }
++ i->state = DNSSEC_ZONE_RR_ITER_RRSIGs_NSEC_REST;
++ i->rrs = i->name->nsec_signatures;
++ break;
++
++ case DNSSEC_ZONE_RR_ITER_RRSIGs_NSEC_REST:
++ if (i->rrsets4rrsigs) {
++ i->rrs = i->rrsets4rrsigs->signatures;
++ i->rrsets4rrsigs = i->rrsets4rrsigs->next;
++ break;
++ }
++ i->state = DNSSEC_ZONE_RR_ITER_REST;
++ return i->name->nsec;
++
++ case DNSSEC_ZONE_RR_ITER_NSEC3:
++ nsec3 = i->nsec3_name->nsec;
++
++ /* next nsec3 */
++ do {
++ i->nsec3_node
++ = ldns_rbtree_next(i->nsec3_node);
++ i->nsec3_name
++ = i->nsec3_node == LDNS_RBTREE_NULL ? NULL
++ : (ldns_dnssec_name*)i->nsec3_node->data;
++
++ /* names for glue can be in the hashed_names
++ * tree, but will not have a NSEC3
++ */
++ } while (i->nsec3_name && !i->nsec3_name->nsec);
++
++ dnssec_zone_rr_iter_set_state_for_next_name(i);
++ return nsec3;
++
++ case DNSSEC_ZONE_RR_ITER_FINI:
++ return NULL;
++ }
++ }
++}
++
++static ldns_rr *
++dnssec_zone_rr_iter_first(dnssec_zone_rr_iter *i, ldns_dnssec_zone *zone)
++{
++ if (!i || !zone)
++ return NULL;
++
++ memset(i, 0, sizeof(*i));
++ i->zone = zone;
++ if (zone->soa && zone->soa->name) {
++ i->apex_name = zone->soa->name;
++ i->apex_labs = ldns_dname_label_count(i->apex_name);
++ } else
++ i->apex_name = NULL;
++
++
++ i->node = ldns_rbtree_first(zone->names);
++ i->name = i->node == LDNS_RBTREE_NULL ? NULL
++ : (ldns_dnssec_name *)i->node->data;
++
++ if (zone->hashed_names) {
++ do {
++ i->nsec3_node = ldns_rbtree_first(zone->hashed_names);
++ i->nsec3_name = i->nsec3_node == LDNS_RBTREE_NULL ?NULL
++ : (ldns_dnssec_name*)i->nsec3_node->data;
++ } while (i->nsec3_name && !i->nsec3_name->nsec);
++ }
++ dnssec_zone_rr_iter_set_state_for_next_name(i);
++ return dnssec_zone_rr_iter_next(i);
++}
++
++enum enum_zonemd_scheme {
++ ZONEMD_SCHEME_FIRST = 1,
++ ZONEMD_SCHEME_SIMPLE = 1,
++ ZONEMD_SCHEME_LAST = 1
++};
++typedef enum enum_zonemd_scheme zonemd_scheme;
++
++enum enum_zonemd_hash {
++ ZONEMD_HASH_FIRST = 1,
++ ZONEMD_HASH_SHA384 = 1,
++ ZONEMD_HASH_SHA512 = 2,
++ ZONEMD_HASH_LAST = 2
++};
++typedef enum enum_zonemd_hash zonemd_hash;
++
++struct struct_zone_digester {
++ ldns_sha384_CTX sha384_CTX;
++ ldns_sha512_CTX sha512_CTX;
++ unsigned simple_sha384 : 1;
++ unsigned simple_sha512 : 1;
++ unsigned double_sha384 : 1;
++ unsigned double_sha512 : 1;
++};
++typedef struct struct_zone_digester zone_digester;
++
++INLINE bool zone_digester_set(zone_digester *zd)
++{ return zd && (zd->simple_sha384 || zd->simple_sha512); }
++
++INLINE void zone_digester_init(zone_digester *zd)
++{ memset(zd, 0, sizeof(*zd)); }
++
++static ldns_status
++zone_digester_add(zone_digester *zd, zonemd_scheme scheme, zonemd_hash hash)
++{
++ if (!zd)
++ return LDNS_STATUS_NULL;
++
++ switch (scheme) {
++ case ZONEMD_SCHEME_SIMPLE:
++ switch (hash) {
++ case ZONEMD_HASH_SHA384:
++ if (zd->double_sha384)
++ return LDNS_STATUS_ZONEMD_DOUBLE_OCCURRENCE;
++
++ else if (zd->simple_sha384) {
++ zd->simple_sha384 = 0;
++ zd->double_sha384 = 1;
++ return LDNS_STATUS_ZONEMD_DOUBLE_OCCURRENCE;
++ }
++ ldns_sha384_init(&zd->sha384_CTX);
++ zd->simple_sha384 = 1;
++ break;
++
++ case ZONEMD_HASH_SHA512:
++ if (zd->double_sha512)
++ return LDNS_STATUS_ZONEMD_DOUBLE_OCCURRENCE;
++
++ else if (zd->simple_sha512) {
++ zd->simple_sha512 = 0;
++ zd->double_sha512 = 1;
++ return LDNS_STATUS_ZONEMD_DOUBLE_OCCURRENCE;
++ }
++ ldns_sha512_init(&zd->sha512_CTX);
++ zd->simple_sha512 = 1;
++ break;
++ default:
++ return LDNS_STATUS_ZONEMD_UNKNOWN_HASH;
++ }
++ break;
++ default:
++ return LDNS_STATUS_ZONEMD_UNKNOWN_SCHEME;
++ }
++ return LDNS_STATUS_OK;
++}
++
++static ldns_status
++zone_digester_update(zone_digester *zd, ldns_rr *rr)
++{
++ uint8_t data[65536];
++ ldns_buffer buf;
++ ldns_status st;
++
++ buf._data = data;
++ buf._position = 0;
++ buf._limit = sizeof(data);
++ buf._capacity = sizeof(data);
++ buf._fixed = 1;
++ buf._status = LDNS_STATUS_OK;
++
++ if ((st = ldns_rr2buffer_wire_canonical(&buf, rr, LDNS_SECTION_ANSWER)))
++ return st;
++
++ if (zd->simple_sha384)
++ ldns_sha384_update(&zd->sha384_CTX, data, buf._position);
++
++ if (zd->simple_sha512)
++ ldns_sha512_update(&zd->sha512_CTX, data, buf._position);
++
++ return LDNS_STATUS_OK;
++}
++
++INLINE ldns_rr *
++new_zonemd(ldns_rr *soa, zonemd_hash hash)
++{
++ ldns_rr *rr = NULL;
++ uint8_t *data = NULL;
++ ldns_rdf *rdf;
++ size_t md_len = hash == ZONEMD_HASH_SHA384
++ ? LDNS_SHA384_DIGEST_LENGTH
++ : LDNS_SHA512_DIGEST_LENGTH;
++
++ if (!(rr = ldns_rr_new_frm_type(LDNS_RR_TYPE_ZONEMD)))
++ return NULL;
++
++ if (!(rdf = ldns_rdf_clone(ldns_rr_owner(soa))))
++ goto error;
++
++ ldns_rr_set_owner(rr, rdf);
++ ldns_rr_set_class(rr, ldns_rr_get_class(soa));
++ ldns_rr_set_ttl(rr, ldns_rr_ttl(soa));
++
++ if (!(rdf = ldns_rdf_clone(ldns_rr_rdf(soa, 2))))
++ goto error;
++ ldns_rr_set_rdf(rr, rdf, 0);
++
++ if (!(rdf = ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8, 1)))
++ goto error;
++ ldns_rr_set_rdf(rr, rdf, 1);
++
++ if (!(rdf = ldns_native2rdf_int8(LDNS_RDF_TYPE_INT8, hash)))
++ goto error;
++ ldns_rr_set_rdf(rr, rdf, 2);
++
++ if (!(data = LDNS_XMALLOC(uint8_t, md_len)))
++ goto error;
++
++ if (!(rdf = ldns_rdf_new(LDNS_RDF_TYPE_HEX, md_len, data)))
++ goto error;
++ ldns_rr_set_rdf(rr, rdf, 3);
++
++ return rr;
++error:
++ if (data)
++ LDNS_FREE(data);
++ ldns_rr_free(rr);
++ return NULL;
++}
++
++static ldns_rr_list *
++zone_digester_export(
++ zone_digester *zd, ldns_rr *soa, ldns_status *ret_st)
++{
++ ldns_status st = LDNS_STATUS_OK;
++ ldns_rr_list *rr_list = NULL;
++ ldns_rr *sha384 = NULL;
++ ldns_rr *sha512 = NULL;
++
++ if (!zd || !soa)
++ st = LDNS_STATUS_NULL;
++
++ else if (ldns_rr_get_type(soa) != LDNS_RR_TYPE_SOA
++ || ldns_rr_rd_count(soa) < 3)
++ st = LDNS_STATUS_ZONEMD_INVALID_SOA;
++
++ else if (!(rr_list = ldns_rr_list_new()))
++ st = LDNS_STATUS_MEM_ERR;
++
++ else if (zd->simple_sha384
++ && !(sha384 = new_zonemd(soa, ZONEMD_HASH_SHA384)))
++ st = LDNS_STATUS_MEM_ERR;
++
++ else if (zd->simple_sha512
++ && !(sha512 = new_zonemd(soa, ZONEMD_HASH_SHA512)))
++ st = LDNS_STATUS_MEM_ERR;
++
++ else if (zd->simple_sha384
++ && !ldns_rr_list_push_rr(rr_list, sha384))
++ st = LDNS_STATUS_MEM_ERR;
++
++ else if (zd->simple_sha512
++ && !ldns_rr_list_push_rr(rr_list, sha512)) {
++ if (zd->simple_sha384)
++ sha384 = NULL; /* deleted by ldns_rr_list_deep_free */
++ st = LDNS_STATUS_MEM_ERR;
++
++ } else {
++ if (sha384)
++ ldns_sha384_final( ldns_rdf_data(ldns_rr_rdf(sha384,3))
++ , &zd->sha384_CTX);
++ if (sha512)
++ ldns_sha512_final( ldns_rdf_data(ldns_rr_rdf(sha512,3))
++ , &zd->sha512_CTX);
++ return rr_list;
++ }
++ if (ret_st)
++ *ret_st = st;
++ if (sha384)
++ ldns_rr_free(sha384);
++ if (sha512)
++ ldns_rr_free(sha512);
++ if (rr_list)
++ ldns_rr_list_deep_free(rr_list);
++ return NULL;
++}
++
++static ldns_status
++ldns_digest_zone(ldns_dnssec_zone *zone, zone_digester *zd)
++{
++ ldns_status st = LDNS_STATUS_OK;
++ dnssec_zone_rr_iter rr_iter;
++ ldns_rr *rr;
++ ldns_rdf *apex_name; /* name of zone apex */
++
++ if (!zone || !zd || !zone->soa || !zone->soa->name)
++ return LDNS_STATUS_NULL;
++
++ apex_name = zone->soa->name;
++ for ( rr = dnssec_zone_rr_iter_first(&rr_iter, zone)
++ ; rr && !st
++ ; rr = dnssec_zone_rr_iter_next(&rr_iter)) {
++ /* Skip apex ZONEMD RRs */
++ if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_ZONEMD
++ && !ldns_dname_compare(ldns_rr_owner(rr), apex_name))
++ continue;
++ /* Skip RRSIGs for apex ZONEMD RRs */
++ if (ldns_rr_get_type(rr) == LDNS_RR_TYPE_RRSIG
++ && LDNS_RR_TYPE_ZONEMD == ldns_rdf2rr_type(
++ ldns_rr_rrsig_typecovered(rr))
++ && !ldns_dname_compare(ldns_rr_owner(rr), apex_name))
++ continue;
++ st = zone_digester_update(zd, rr);
++ }
++ return st;
++}
++
++ldns_status
++ldns_dnssec_zone_verify_zonemd(ldns_dnssec_zone *zone)
++{
++ ldns_dnssec_rrsets *zonemd, *soa;
++ zone_digester zd;
++ ldns_dnssec_rrs *rrs;
++ ldns_rr *soa_rr;
++ ldns_status st;
++ uint8_t simple_sha384[LDNS_SHA384_DIGEST_LENGTH];
++ uint8_t simple_sha512[LDNS_SHA512_DIGEST_LENGTH];
++ size_t valid_zonemds;
++
++ if (!zone)
++ return LDNS_STATUS_NULL;
++
++ zonemd = ldns_dnssec_zone_find_rrset(
++ zone, zone->soa->name, LDNS_RR_TYPE_ZONEMD);
++ if (!zonemd) {
++ ldns_rbnode_t *nsec3_node;
++
++ /* we need proof of non-existence for ZONEMD at the apex */
++ if (zone->soa->nsec) {
++ if (ldns_nsec_bitmap_covers_type(ldns_nsec_get_bitmap(
++ zone->soa->nsec),
++ LDNS_RR_TYPE_ZONEMD))
++ return LDNS_STATUS_NO_ZONEMD;
++
++ } else if (!zone->soa->hashed_name || !zone->hashed_names)
++ return LDNS_STATUS_NO_ZONEMD;
++
++ else if (LDNS_RBTREE_NULL ==
++ (nsec3_node = ldns_rbtree_search( zone->hashed_names
++ , zone->soa->hashed_name)))
++ return LDNS_STATUS_NO_ZONEMD;
++ else {
++ ldns_dnssec_name *nsec3
++ = (ldns_dnssec_name *)nsec3_node->data;
++ if (ldns_nsec_bitmap_covers_type(ldns_nsec_get_bitmap(
++ nsec3->nsec),
++ LDNS_RR_TYPE_ZONEMD))
++ return LDNS_STATUS_NO_ZONEMD;
++ }
++ /* ZONEMD at apex does really not exist */
++ return LDNS_STATUS_OK;
++ }
++ soa = ldns_dnssec_zone_find_rrset(
++ zone, zone->soa->name, LDNS_RR_TYPE_SOA);
++ if (!soa || !soa->rrs || !soa->rrs->rr)
++ return LDNS_STATUS_ZONEMD_INVALID_SOA;
++
++ soa_rr = soa->rrs->rr;
++ if (ldns_rr_get_type(soa_rr) != LDNS_RR_TYPE_SOA
++ || ldns_rr_rd_count(soa_rr) < 3)
++ return LDNS_STATUS_ZONEMD_INVALID_SOA;
++
++ zone_digester_init(&zd);
++ for (rrs = zonemd->rrs; rrs; rrs = rrs->next) {
++ if (!rrs->rr
++ || ldns_rr_get_type(rrs->rr) != LDNS_RR_TYPE_ZONEMD
++ || ldns_rr_rd_count(rrs->rr) < 4)
++ continue;
++
++ /* serial should match SOA's serial */
++ if (ldns_rdf2native_int32(ldns_rr_rdf(soa_rr, 2))
++ != ldns_rdf2native_int32(ldns_rr_rdf(rrs->rr, 0)))
++ continue;
++
++ /* Add (scheme, hash) to digester */
++ zone_digester_add(&zd,
++ ldns_rdf2native_int8(ldns_rr_rdf(rrs->rr, 1)),
++ ldns_rdf2native_int8(ldns_rr_rdf(rrs->rr, 2)));
++ }
++ if (!zone_digester_set(&zd))
++ return LDNS_STATUS_NO_VALID_ZONEMD;
++
++ if ((st = ldns_digest_zone(zone, &zd)))
++ return st;
++
++ if (zd.simple_sha384)
++ ldns_sha384_final(simple_sha384, &zd.sha384_CTX);
++ if (zd.simple_sha512)
++ ldns_sha512_final(simple_sha512, &zd.sha512_CTX);
++
++ valid_zonemds = 0;
++ for (rrs = zonemd->rrs; rrs; rrs = rrs->next) {
++ if (!rrs->rr
++ || ldns_rr_get_type(rrs->rr) != LDNS_RR_TYPE_ZONEMD
++ || ldns_rr_rd_count(rrs->rr) < 4)
++ continue;
++
++ /* serial should match SOA's serial */
++ if (ldns_rdf2native_int32(ldns_rr_rdf(soa_rr, 2))
++ != ldns_rdf2native_int32(ldns_rr_rdf(rrs->rr, 0)))
++ continue;
++
++ if (ZONEMD_SCHEME_SIMPLE !=
++ ldns_rdf2native_int8(ldns_rr_rdf(rrs->rr, 1)))
++ continue;
++
++ if (ZONEMD_HASH_SHA384
++ == ldns_rdf2native_int8(ldns_rr_rdf(rrs->rr,2))
++ && LDNS_SHA384_DIGEST_LENGTH
++ == ldns_rdf_size(ldns_rr_rdf(rrs->rr, 3))
++ && memcmp( simple_sha384
++ , ldns_rdf_data(ldns_rr_rdf(rrs->rr, 3))
++ , LDNS_SHA384_DIGEST_LENGTH) == 0)
++
++ valid_zonemds += 1;
++
++ if (ZONEMD_HASH_SHA512
++ == ldns_rdf2native_int8(ldns_rr_rdf(rrs->rr,2))
++ && LDNS_SHA512_DIGEST_LENGTH
++ == ldns_rdf_size(ldns_rr_rdf(rrs->rr, 3))
++ && memcmp( simple_sha512
++ , ldns_rdf_data(ldns_rr_rdf(rrs->rr, 3))
++ , LDNS_SHA512_DIGEST_LENGTH) == 0)
++
++ valid_zonemds += 1;
++ }
++ return valid_zonemds ? LDNS_STATUS_OK : LDNS_STATUS_NO_VALID_ZONEMD;
++}
++
++#ifdef HAVE_SSL
++static ldns_status
++rr_list2dnssec_rrs(ldns_rr_list *rr_list, ldns_dnssec_rrs **rrs,
++ ldns_rr_list *new_rrs)
++{
++ ldns_rr *rr = NULL;
++
++ if (!rr_list || !rrs)
++ return LDNS_STATUS_NULL;
++
++ if (ldns_rr_list_rr_count(rr_list) == 0)
++ return LDNS_STATUS_OK;
++
++ if (!*rrs) {
++ if (!(*rrs = ldns_dnssec_rrs_new()))
++ return LDNS_STATUS_MEM_ERR;
++ (*rrs)->rr = ldns_rr_list_pop_rr(rr_list);
++ if (new_rrs)
++ ldns_rr_list_push_rr(new_rrs, (*rrs)->rr);
++ }
++ while ((rr = ldns_rr_list_pop_rr(rr_list))) {
++ ldns_status st;
++
++ if ((st = ldns_dnssec_rrs_add_rr(*rrs, rr))) {
++ ldns_rr_list_push_rr(rr_list, rr);
++ return st;
++ } else if (new_rrs)
++ ldns_rr_list_push_rr(new_rrs, rr);
++ }
++ return LDNS_STATUS_OK;
++}
++
++
++ldns_status
++dnssec_zone_equip_zonemd(ldns_dnssec_zone *zone,
++ ldns_rr_list *new_rrs, ldns_key_list *key_list, int signflags)
++{
++ ldns_status st = LDNS_STATUS_OK;
++ zone_digester zd;
++ ldns_rr_list *zonemd_rr_list = NULL;
++ ldns_rr_list *zonemd_rrsigs = NULL;
++ ldns_dnssec_rrsets *soa_rrset;
++ ldns_rr *soa_rr = NULL;
++ ldns_dnssec_rrsets **rrset_ref;
++ ldns_dnssec_rrsets *zonemd_rrset;
++
++ zone_digester_init(&zd);
++ if (signflags & LDNS_SIGN_WITH_ZONEMD_SIMPLE_SHA384)
++ zone_digester_add(&zd, ZONEMD_SCHEME_SIMPLE
++ , ZONEMD_HASH_SHA384);
++
++ if (signflags & LDNS_SIGN_WITH_ZONEMD_SIMPLE_SHA512)
++ zone_digester_add(&zd, ZONEMD_SCHEME_SIMPLE
++ , ZONEMD_HASH_SHA512);
++
++ if ((st = ldns_digest_zone(zone, &zd)))
++ return st;
++
++ soa_rrset = ldns_dnssec_zone_find_rrset(
++ zone, zone->soa->name, LDNS_RR_TYPE_SOA);
++ if (!soa_rrset || !soa_rrset->rrs || !soa_rrset->rrs->rr)
++ return LDNS_STATUS_ZONEMD_INVALID_SOA;
++ soa_rr = soa_rrset->rrs->rr;
++
++ if (!(zonemd_rr_list = zone_digester_export(&zd, soa_rr, &st)))
++ return st;
++
++ /* - replace or add ZONEMD rrset */
++ rrset_ref = &zone->soa->rrsets; /* scan rrsets at apex */
++ while (*rrset_ref && (*rrset_ref)->type < LDNS_RR_TYPE_ZONEMD)
++ rrset_ref = &(*rrset_ref)->next;
++ if (*rrset_ref && (*rrset_ref)->type == LDNS_RR_TYPE_ZONEMD) {
++ /* reuse zonemd rrset */
++ zonemd_rrset = *rrset_ref;
++ ldns_dnssec_rrs_free(zonemd_rrset->rrs);
++ zonemd_rrset->rrs = NULL;
++ ldns_dnssec_rrs_free(zonemd_rrset->signatures);
++ zonemd_rrset->signatures = NULL;
++ } else {
++ /* insert zonemd rrset */
++ zonemd_rrset = ldns_dnssec_rrsets_new();
++ if (!zonemd_rrset) {
++ ldns_rr_list_deep_free(zonemd_rr_list);
++ return LDNS_STATUS_MEM_ERR;
++ }
++ zonemd_rrset->type = LDNS_RR_TYPE_ZONEMD;
++ zonemd_rrset->next = *rrset_ref;
++ *rrset_ref = zonemd_rrset;
++ }
++ if ((zonemd_rrsigs = ldns_sign_public(zonemd_rr_list, key_list)))
++ st = rr_list2dnssec_rrs( zonemd_rrsigs
++ , &zonemd_rrset->signatures, new_rrs);
++ if (!st)
++ st = rr_list2dnssec_rrs( zonemd_rr_list
++ , &zonemd_rrset->rrs, new_rrs);
++ ldns_rr_list_deep_free(zonemd_rr_list);
++ ldns_rr_list_deep_free(zonemd_rrsigs);
++ return st;
++}
++
++#endif /* HAVE_SSL */
++
+diff -ur ldns-1.7.1/doc/API-header.xml ldns/doc/API-header.xml
+--- ldns-1.7.1/doc/API-header.xml 2019-07-26 17:07:44.000000000 +0200
++++ ldns/doc/API-header.xml 2021-10-17 21:21:57.619562532 +0200
+@@ -68,7 +68,7 @@
+ <section title="Introduction">
+ <t>
+ LibDNS (or lDNS) is modelled after the Net::DNS perl library. It has
+-been shown that Net::DNS can be used vefficiently for
++been shown that Net::DNS can be used efficiently for
+ programming DNS aware applications. We want to bring the same
+ level of efficiency to C programmers.
+ </t>
+@@ -99,7 +99,7 @@
+ <t>
+ As said, lDNS is modelled after Net::DNS, therefor its application API
+ looks very much like the one used for Net::DNS. Some modification are made
+-ofcourse, because not all functionality of Perl can be caught in C.
++of course, because not all functionality of Perl can be caught in C.
+ </t>
+
+ <t>
+diff -ur ldns-1.7.1/doc/API.xml ldns/doc/API.xml
+--- ldns-1.7.1/doc/API.xml 2019-07-26 17:07:44.000000000 +0200
++++ ldns/doc/API.xml 2021-10-17 21:21:57.619562532 +0200
+@@ -68,7 +68,7 @@
+ <section title="Introduction">
+ <t>
+ LibDNS (or lDNS) is modelled after the Net::DNS perl library. It has
+-been shown that Net::DNS can be used vefficiently for
++been shown that Net::DNS can be used efficiently for
+ programming DNS aware applications. We want to bring the same
+ level of efficiency to C programmers.
+ </t>
+@@ -99,7 +99,7 @@
+ <t>
+ As said, lDNS is modelled after Net::DNS, therefor its application API
+ looks very much like the one used for Net::DNS. Some modification are made
+-ofcourse, because not all functionality of Perl can be caught in C.
++of course, because not all functionality of Perl can be caught in C.
+ </t>
+
+ <t>
+@@ -336,7 +336,7 @@
+ section of the packet.
+
+ </t>
+-<t hangText=" void ldsn_pkt_print(ldns_pkt *pkt):">
++<t hangText=" void ldns_pkt_print(ldns_pkt *pkt):">
+ Prints the packet data on the standard output in an ASCII format similar
+ to that used in DNS zone files. See RFC1035.
+
+@@ -400,7 +400,7 @@
+ <section title="Examples">
+ <t>
+ A small example, which queries a nameserver on localhost
+-to diplay the MX records for miek.nl.
++to display the MX records for miek.nl.
+ </t>
+
+ <t>
+diff -ur ldns-1.7.1/doc/dns-lib-implementations ldns/doc/dns-lib-implementations
+--- ldns-1.7.1/doc/dns-lib-implementations 2019-07-26 17:07:44.000000000 +0200
++++ ldns/doc/dns-lib-implementations 2021-10-17 21:21:57.622895809 +0200
+@@ -20,7 +20,7 @@
+
+ libfiredns is a library for handling asynchronous DNS
+ requests. It provides a very simple interface for sending
+-requests and parsing reponses, as well as low-timeout
++requests and parsing responses, as well as low-timeout
+ blocking functions. libfiredns functions have much lower
+ timeouts than the stock functions and tend to be faster
+ because they send requests to all configured system
+diff -ur ldns-1.7.1/doc/function_manpages ldns/doc/function_manpages
+--- ldns-1.7.1/doc/function_manpages 2019-07-26 17:07:44.000000000 +0200
++++ ldns/doc/function_manpages 2021-10-17 21:21:57.622895809 +0200
+@@ -121,7 +121,7 @@
+
+ ### MIEK TOT HIER TOT HIER
+
+-# errr.h
++# error.h
+ ldns_get_errorstr_by_id, ldns_status - errors
+
+ ### net.h
+@@ -169,7 +169,7 @@
+ ldns_rr_descriptor, ldns_rr_descript, ldns_rr_descriptor_minimum, ldns_rr_descriptor_maximum, ldns_rr_descriptor_field_type | ldns_rr, ldns_rdf - rdata field descriptors
+
+ # packet.h
+-ldns_pkt, ldns_pkt_section, ldns_pkt_type | ldns_pkt_new, ldns_pkt_free, ldns_pkt_print, ldns_pkt_query_new, ldns_pkt_query_new_frm_str, ldns_pkt_reply_type, ldns_pkt_id, ldns_pkt_qr, ldns_pkt_aa, ldns_pkt_tc, ldns_pkt_rd, ldns_pkt_cd, ldns_pkt_ra, ldns_pkt_ad, ldns_pkt_get_opcode, ldns_pkt_get_rcode, ldns_pkt_qdcount, ldns_pkt_ancount, ldns_pkt_nscount, ldns_pkt_arcount, ldns_pkt_answerfrom, ldns_pkt_querytime, ldns_pkt_size, ldns_pkt_tsig, ldns_pkt_question, ldns_pkt_answer, ldns_pkt_authority, ldns_pkt_additional, ldns_pkt_get_section_clone, ldns_pkt_rr_list_by_name, ldns_pkt_rr_list_by_type, ldns_pkt_rr_list_by_name_and_type, ldns_pkt_set_flags, ldns_pkt_set_id, ldns_pkt_set_qr, ldns_pkt_set_aa, ldns_pkt_set_tc, ldns_pkt_set_rd, ldns_pkt_set_cd, ldns_pkt_set_ra, ldns_pkt_set_ad, ldns_pkt_set_opcode, ldns_pkt_set_rcode, ldns_pkt_set_qdcount, ldns_pkt_set_ancount, ldns_pkt_set_nscount, ldns_pkt_set_arcount, ldns_pkt_set_answerfrom, ldns_pkt_set_querytime, ldns_pkt_set_size, ldns_pkt_set_section_count, ldns_pkt_set_tsig, ldns_pkt_edns, ldns_pkt_edns_udp_size, ldns_pkt_edns_extended_rcode, ldns_pkt_edns_version, ldns_pkt_edns_z, ldns_pkt_edns_unassigned, ldns_pkt_edns_data, ldns_pkt_set_edns_udp_size, ldns_pkt_set_edns_extended_rcode, ldns_pkt_set_edns_version, ldns_pkt_set_edns_z, ldns_pkt_set_edns_unassigned, ldns_pkt_set_edns_data - request or anser packets types
++ldns_pkt, ldns_pkt_section, ldns_pkt_type | ldns_pkt_new, ldns_pkt_free, ldns_pkt_print, ldns_pkt_query_new, ldns_pkt_query_new_frm_str, ldns_pkt_reply_type, ldns_pkt_id, ldns_pkt_qr, ldns_pkt_aa, ldns_pkt_tc, ldns_pkt_rd, ldns_pkt_cd, ldns_pkt_ra, ldns_pkt_ad, ldns_pkt_get_opcode, ldns_pkt_get_rcode, ldns_pkt_qdcount, ldns_pkt_ancount, ldns_pkt_nscount, ldns_pkt_arcount, ldns_pkt_answerfrom, ldns_pkt_querytime, ldns_pkt_size, ldns_pkt_tsig, ldns_pkt_question, ldns_pkt_answer, ldns_pkt_authority, ldns_pkt_additional, ldns_pkt_get_section_clone, ldns_pkt_rr_list_by_name, ldns_pkt_rr_list_by_type, ldns_pkt_rr_list_by_name_and_type, ldns_pkt_set_flags, ldns_pkt_set_id, ldns_pkt_set_qr, ldns_pkt_set_aa, ldns_pkt_set_tc, ldns_pkt_set_rd, ldns_pkt_set_cd, ldns_pkt_set_ra, ldns_pkt_set_ad, ldns_pkt_set_opcode, ldns_pkt_set_rcode, ldns_pkt_set_qdcount, ldns_pkt_set_ancount, ldns_pkt_set_nscount, ldns_pkt_set_arcount, ldns_pkt_set_answerfrom, ldns_pkt_set_querytime, ldns_pkt_set_size, ldns_pkt_set_section_count, ldns_pkt_set_tsig, ldns_pkt_edns, ldns_pkt_edns_udp_size, ldns_pkt_edns_extended_rcode, ldns_pkt_edns_version, ldns_pkt_edns_z, ldns_pkt_edns_unassigned, ldns_pkt_edns_data, ldns_pkt_set_edns_udp_size, ldns_pkt_set_edns_extended_rcode, ldns_pkt_set_edns_version, ldns_pkt_set_edns_z, ldns_pkt_set_edns_unassigned, ldns_pkt_set_edns_data - request or answer packets types
+
+ ldns_pkt_new, ldns_pkt_free, ldns_pkt_print, ldns_pkt_query_new, ldns_pkt_query_new_frm_str, ldns_pkt_reply_type | ldns_pkt - ldns_pkt creation, destruction and printing
+ # gets
+diff -ur ldns-1.7.1/drill/ChangeLog.22-nov-2005 ldns/drill/ChangeLog.22-nov-2005
+--- ldns-1.7.1/drill/ChangeLog.22-nov-2005 2019-07-26 17:07:44.000000000 +0200
++++ ldns/drill/ChangeLog.22-nov-2005 2021-10-17 21:21:57.622895809 +0200
+@@ -11,7 +11,7 @@
+ * Lint fixes for the code
+ * Bugzilla was setup for drill
+ * Bug #97 (drill); -S crash was fixed
+- * Add -Q (quiet) flag was added. This supresses output from drill.
++ * Add -Q (quiet) flag was added. This suppresses output from drill.
+
+ 1.0-pre2: 20 Jun 2005: drill-team
+ * Second prerelease
+@@ -60,7 +60,7 @@
+ - CERT RR supported
+ - LOC RR support
+ * All non supported RRs are handled as unknown
+- * If no namservers found in /etc/resolv.conf
++ * If no nameservers found in /etc/resolv.conf
+ default to 127.0.0.1
+ * Various bugs fixed
+ - Close sockets after using them
+@@ -74,7 +74,7 @@
+ * Dig is no longer needed to build drill
+
+ 0.7: Oct 21 2004: Miek
+- * reworked interal code
++ * reworked internal code
+ * DNSSEC is working, except the secure resolving
+ * build updates
+ * more sane options parsing
+diff -ur ldns-1.7.1/drill/chasetrace.c ldns/drill/chasetrace.c
+--- ldns-1.7.1/drill/chasetrace.c 2019-07-26 17:07:44.000000000 +0200
++++ ldns/drill/chasetrace.c 2021-10-17 21:21:57.622895809 +0200
+@@ -171,7 +171,7 @@
+ }
+
+ /* transfer some properties of local_res to res,
+- * because they were given on the commandline */
++ * because they were given on the command line */
+ ldns_resolver_set_ip6(res,
+ ldns_resolver_ip6(local_res));
+ ldns_resolver_set_port(res,
+diff -ur ldns-1.7.1/drill/drill.1.in ldns/drill/drill.1.in
+--- ldns-1.7.1/drill/drill.1.in 2019-07-26 17:07:44.000000000 +0200
++++ ldns/drill/drill.1.in 2021-10-17 21:21:57.622895809 +0200
+@@ -19,7 +19,7 @@
+ ]
+
+ .SH DESCRIPTION
+-\fBdrill\fR is a tool to designed to get all sorts of information out of the
++\fBdrill\fR is a tool designed to get all sorts of information out of the
+ DNS. It is specifically designed to be used with DNSSEC.
+ .PP
+ The name \fBdrill\fR is a pun on \fBdig\fR. With \fBdrill\fR you should be able
+diff -ur ldns-1.7.1/drill/drill.c ldns/drill/drill.c
+--- ldns-1.7.1/drill/drill.c 2019-07-26 17:07:44.000000000 +0200
++++ ldns/drill/drill.c 2021-10-17 21:21:57.622895809 +0200
+@@ -59,7 +59,7 @@
+ fprintf(stream, "\t-6\t\tstay on ip6\n");
+ fprintf(stream, "\t-a\t\tfallback to EDNS0 and TCP if the answer is truncated\n");
+ fprintf(stream, "\t-b <bufsize>\tuse <bufsize> as the buffer size (defaults to 512 b)\n");
+- fprintf(stream, "\t-c <file>\tuse file for rescursive nameserver configuration"
++ fprintf(stream, "\t-c <file>\tuse file for recursive nameserver configuration"
+ "\n\t\t\t(/etc/resolv.conf)\n");
+ fprintf(stream, "\t-k <file>\tspecify a file that contains a trusted DNSSEC key [**]\n");
+ fprintf(stream, "\t\t\tUsed to verify any signatures in the current answer.\n");
+@@ -173,6 +173,8 @@
+ int r;
+ WSADATA wsa_data;
+ #endif
++ ldns_output_format_storage fmt_storage;
++ ldns_output_format* fmt = ldns_output_format_init(&fmt_storage);
+
+ int_type = -1; serv = NULL; type = 0;
+ int_clas = -1; name = NULL; clas = 0;
+@@ -247,6 +249,7 @@
+ verbosity = atoi(optarg);
+ break;
+ case 'Q':
++ fmt->flags |= LDNS_FMT_SHORT;
+ verbosity = -1;
+ break;
+ case 'f':
+@@ -879,8 +882,8 @@
+ mesg("No packet received");
+ result = EXIT_FAILURE;
+ } else {
++ ldns_pkt_print_fmt(stdout, fmt, pkt);
+ if (verbosity != -1) {
+- ldns_pkt_print(stdout, pkt);
+ if (ldns_pkt_tc(pkt)) {
+ fprintf(stdout,
+ "\n;; WARNING: The answer packet was truncated; you might want to\n");
+@@ -994,9 +997,17 @@
+ xfree(tsig_algorithm);
+
+ #ifdef HAVE_SSL
+- CRYPTO_cleanup_all_ex_data();
+- ERR_free_strings();
+- EVP_cleanup();
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(HAVE_LIBRESSL)
++#ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA
++ CRYPTO_cleanup_all_ex_data ();
++#endif
++#ifdef HAVE_ERR_FREE_STRINGS
++ ERR_free_strings ();
++#endif
++#ifdef HAVE_EVP_CLEANUP
++ EVP_cleanup ();
++#endif
++#endif
+ #endif
+ #ifdef USE_WINSOCK
+ WSACleanup();
+diff -ur ldns-1.7.1/drill/securetrace.c ldns/drill/securetrace.c
+--- ldns-1.7.1/drill/securetrace.c 2019-07-26 17:07:44.000000000 +0200
++++ ldns/drill/securetrace.c 2021-10-17 21:21:57.622895809 +0200
+@@ -137,7 +137,7 @@
+ ldns_rr_list *correct_key_list;
+ ldns_rr_list *trusted_ds_rrs;
+ bool new_keys_trusted = false;
+- ldns_rr_list *current_correct_keys;
++ ldns_rr_list *current_correct_keys = NULL;
+ ldns_rr_list *dataset;
+
+ ldns_rr_list *nsec_rrs = NULL;
+diff -ur ldns-1.7.1/duration.c ldns/duration.c
+--- ldns-1.7.1/duration.c 2019-07-26 17:07:44.000000000 +0200
++++ ldns/duration.c 2021-10-17 21:21:57.622895809 +0200
+@@ -190,121 +190,51 @@
+
+
+ /**
+- * Get the number of digits in a number.
+- *
++ * Helper func for ldns_duration2string below. If t > 0,
++ * scan print t and c on buf, forwarding buf. Return 0 on success.
+ */
+-static size_t
+-digits_in_number(time_t duration)
++static inline int dur_scan_print(char **buf, char *eob, char c, time_t t)
+ {
+- unsigned int i = (unsigned int) duration;
+- size_t n = 1;
+-
+- while (i >= 100000000) {
+- n += 8;
+- i /= 100000000;
++ if (t > 0) {
++ int r = snprintf(*buf, eob - *buf, "%u%c", (unsigned)t, c);
++ if (r < 0 || (*buf += r) >= eob)
++ return -1;
+ }
+- if (i >= 10000) { n += 4; i /= 10000; }
+- if (i >= 100 ) { n += 2; i /= 100; }
+- if (i >= 10 ) { n += 1; }
+- return n;
++ return 0;
+ }
+
+-
+ /**
+ * Convert a duration to a string.
+ *
+ */
+ char*
+-ldns_duration2string(const ldns_duration_type* duration)
++ldns_duration2string(const ldns_duration_type* d)
+ {
+- char* str = NULL;
+- size_t count = 2;
+- int T = 0;
+- char num[sizeof(unsigned int) + 2];
+-
+- if (!duration) {
+- return NULL;
+- }
+-
+- if (duration->years > 0) {
+- count = count + 1 + digits_in_number(duration->years);
+- }
+- if (duration->months > 0) {
+- count = count + 1 + digits_in_number(duration->months);
+- }
+- if (duration->weeks > 0) {
+- count = count + 1 + digits_in_number(duration->weeks);
+- }
+- if (duration->days > 0) {
+- count = count + 1 + digits_in_number(duration->days);
+- }
+- if (duration->hours > 0) {
+- count = count + 1 + digits_in_number(duration->hours);
+- T = 1;
+- }
+- if (duration->minutes > 0) {
+- count = count + 1 + digits_in_number(duration->minutes);
+- T = 1;
+- }
+- if (duration->seconds > 0) {
+- count = count + 1 + digits_in_number(duration->seconds);
+- T = 1;
+- }
+- if (T) {
+- count++;
+- }
+-
+- if (!(str = (char*) calloc(count, sizeof(char))))
+- return NULL;
+- str[0] = 'P';
+- str[1] = '\0';
+-
+- if (duration->years > 0) {
+- count = digits_in_number(duration->years);
+- assert(count <= sizeof(num) - 2);
+- snprintf(num, count+2, "%uY", (unsigned int) duration->years);
+- str = strncat(str, num, count+2);
+- }
+- if (duration->months > 0) {
+- count = digits_in_number(duration->months);
+- assert(count <= sizeof(num) - 2);
+- snprintf(num, count+2, "%uM", (unsigned int) duration->months);
+- str = strncat(str, num, count+2);
+- }
+- if (duration->weeks > 0) {
+- count = digits_in_number(duration->weeks);
+- assert(count <= sizeof(num) - 2);
+- snprintf(num, count+2, "%uW", (unsigned int) duration->weeks);
+- str = strncat(str, num, count+2);
+- }
+- if (duration->days > 0) {
+- count = digits_in_number(duration->days);
+- assert(count <= sizeof(num) - 2);
+- snprintf(num, count+2, "%uD", (unsigned int) duration->days);
+- str = strncat(str, num, count+2);
+- }
+- if (T) {
+- str = strcat(str, "T");
+- }
+- if (duration->hours > 0) {
+- count = digits_in_number(duration->hours);
+- assert(count <= sizeof(num) - 2);
+- snprintf(num, count+2, "%uH", (unsigned int) duration->hours);
+- str = strncat(str, num, count+2);
+- }
+- if (duration->minutes > 0) {
+- count = digits_in_number(duration->minutes);
+- assert(count <= sizeof(num) - 2);
+- snprintf(num, count+2, "%uM", (unsigned int) duration->minutes);
+- str = strncat(str, num, count+2);
+- }
+- if (duration->seconds > 0) {
+- count = digits_in_number(duration->seconds);
+- assert(count <= sizeof(num) - 2);
+- snprintf(num, count+2, "%uS", (unsigned int) duration->seconds);
+- str = strncat(str, num, count+2);
+- }
+- return str;
++ /* Max string size should be 7 * 40 + 3 on a 127 bits machine
++ * So 300 (< 273) is more than enough.
++ */
++ char buf[300] = "P0D", *eob = buf + sizeof(buf), *p = buf + 1;
++
++ if (!d)
++ return NULL;
++
++ if (dur_scan_print(&p, eob, 'Y', d->years)
++ || dur_scan_print(&p, eob, 'M', d->months)
++ || dur_scan_print(&p, eob, 'W', d->weeks)
++ || dur_scan_print(&p, eob, 'D', d->days))
++ return NULL;
++
++ if (d->hours || d->minutes || d->seconds) {
++ if (p > (eob - 2))
++ return NULL; /* Error; no space left on buf for 'T' */
++
++ *p++ = 'T'; *p = 0;
++ if (dur_scan_print(&p, eob, 'H', d->hours)
++ || dur_scan_print(&p, eob, 'M', d->minutes)
++ || dur_scan_print(&p, eob, 'S', d->seconds))
++ return NULL;
++ }
++ return strdup(buf);
+ }
+
+
+diff -ur ldns-1.7.1/error.c ldns/error.c
+--- ldns-1.7.1/error.c 2019-07-26 17:07:44.000000000 +0200
++++ ldns/error.c 2021-10-17 21:21:57.622895809 +0200
+@@ -1,6 +1,6 @@
+ /*
+ * a error2str function to make sense of all the
+- * error codes we have laying ardoun
++ * error codes we have laying around
+ *
+ * a Net::DNS like library for C
+ * LibDNS Team @ NLnet Labs
+@@ -157,6 +157,33 @@
+ "X509_STORE_CTX_set0_dane() functions within OpenSSL >= 1.1.0 "
+ "to be able to verify the DANE-TA usage type." },
+ #endif
++ { LDNS_STATUS_ZONEMD_DOUBLE_OCCURRENCE, "A ZONEMD with the same "
++ "<scheme> and hash algorithm occurred more than once." },
++ { LDNS_STATUS_ZONEMD_UNKNOWN_SCHEME, "Unknown ZONEMD <scheme>" },
++ { LDNS_STATUS_ZONEMD_UNKNOWN_HASH, "Unknown ZONEMD hash algorithm" },
++ { LDNS_STATUS_ZONEMD_INVALID_SOA,
++ "Missing or invalid SOA to associate with ZONEMD RR" },
++ { LDNS_STATUS_NO_ZONEMD,
++ "NSEC(3) RRs indicate that a ZONEMD exists, "
++ "but it is not found in the zone" },
++ { LDNS_STATUS_NO_VALID_ZONEMD,
++ "No ZONEMD matching the zone data was found" },
++ { LDNS_STATUS_SYNTAX_SVCPARAM_KEY_ERR, "Syntax error in a key in "
++ "the ServiceParam rdata field of SVCB or HTTPS RR" },
++ { LDNS_STATUS_SYNTAX_SVCPARAM_VALUE_ERR, "Syntax error in a value in "
++ "the ServiceParam rdata field of SVCB or HTTPS RR" },
++ { LDNS_STATUS_RESERVED_SVCPARAM_KEY,
++ "key65535 is reserved and MUST NOT be used "
++ "in the ServiceParam rdata field of SVCB or HTTPS RR" },
++ { LDNS_STATUS_NO_SVCPARAM_VALUE_EXPECTED,
++ "A value was found for a key that SHOULD not have a value "
++ "in the ServiceParam rdata field of SVCB or HTTPS RR" },
++ { LDNS_STATUS_SVCPARAM_KEY_MORE_THAN_ONCE,
++ "A key was found more than once "
++ "in the ServiceParam rdata field of SVCB or HTTPS RR" },
++ { LDNS_STATUS_INVALID_SVCPARAM_VALUE,
++ "Invalid wireformat of a value "
++ "in the ServiceParam rdata field of SVCB or HTTPS RR" },
+ { 0, NULL }
+ };
+
+diff -ur ldns-1.7.1/examples/ldns-compare-zones.1 ldns/examples/ldns-compare-zones.1
+--- ldns-1.7.1/examples/ldns-compare-zones.1 2019-07-26 17:07:44.000000000 +0200
++++ ldns/examples/ldns-compare-zones.1 2021-10-17 21:21:57.622895809 +0200
+@@ -32,7 +32,7 @@
+ From resource records whose owner names are in both zone files, but with different resource records, print the unchanged records too (a.k.a. changed++).
+ .TP
+ \fB-u\fR
+-Print resource records whose owner names are in both zone files, and which resource records are the same. (a.k.a. unchaged)
++Print resource records whose owner names are in both zone files, and which resource records are the same. (a.k.a. unchanged)
+ .TP
+ \fB-i\fR
+ Print resource records whose owner names are present only in ZONEFILE2 (a.k.a. inserted)
+diff -ur ldns-1.7.1/examples/ldns-compare-zones.c ldns/examples/ldns-compare-zones.c
+--- ldns-1.7.1/examples/ldns-compare-zones.c 2019-07-26 17:07:44.000000000 +0200
++++ ldns/examples/ldns-compare-zones.c 2021-10-17 21:21:57.622895809 +0200
+@@ -133,7 +133,7 @@
+ LDNS_RR_CLASS_IN, &line_nr1);
+ if (s != LDNS_STATUS_OK) {
+ fclose(fp1);
+- fprintf(stderr, "%s: %s at %d\n",
++ fprintf(stderr, "%s: %s at line %d\n",
+ fn1,
+ ldns_get_errorstr_by_id(s),
+ line_nr1);
+@@ -153,7 +153,7 @@
+ if (s != LDNS_STATUS_OK) {
+ ldns_zone_deep_free(z1);
+ fclose(fp2);
+- fprintf(stderr, "%s: %s at %d\n",
++ fprintf(stderr, "%s: %s at line %d\n",
+ fn2,
+ ldns_get_errorstr_by_id(s),
+ line_nr2);
+@@ -232,7 +232,6 @@
+ rr_chg = rr_cmp = -1;
+ }
+ if (rr_cmp < 0) {
+- i++;
+ if ((rrx != NULL) && (ldns_dname_compare(ldns_rr_owner(rr1),
+ ldns_rr_owner(rrx)
+ ) != 0)) {
+@@ -254,8 +253,8 @@
+ printf("%c-", op);
+ ldns_rr_print(stdout, rr1);
+ }
++ i++;
+ } else if (rr_cmp > 0) {
+- j++;
+ if ((rrx != NULL) && (ldns_dname_compare(ldns_rr_owner(rr2),
+ ldns_rr_owner(rrx)
+ ) != 0)) {
+@@ -277,9 +276,8 @@
+ printf("%c+", op);
+ ldns_rr_print(stdout, rr2);
+ }
+- } else {
+- i++;
+ j++;
++ } else {
+ if ((rrx != NULL) && (ldns_dname_compare(ldns_rr_owner(rr1),
+ ldns_rr_owner(rrx)
+ ) != 0)) {
+@@ -294,6 +292,7 @@
+ ldns_dname_compare(ldns_rr_owner(rr1),
+ ldns_rr_owner(ldns_rr_list_rr(rrl1, k))) == 0
+ ; k++);
++
+
+ for ( l = j + 1
+ ; l < rrc2 &&
+@@ -308,14 +307,14 @@
+ nc1 = k - i;
+ nc2 = l - j;
+ for ( k = i + 1, l = j + 1
+- ; k < nc1 && l < nc2 &&
+- ldns_rr_compare(ldns_rr_list_rr(rrl1, k),
+- ldns_rr_list_rr(rrl2, l)) == 0
++ ; (k - i) < nc1 && (l - j) < nc2 &&
++ ldns_rr_compare(ldns_rr_list_rr(rrl1, k),
++ ldns_rr_list_rr(rrl2, l)) == 0
+ ; k++, l++);
+- if (k < nc1) {
++ if ((k - i) < nc1) {
+ op = OP_CHG;
+ num_chg++;
+- } else {
++ } else {
+ op = OP_EQ;
+ num_eq++;
+ }
+@@ -326,6 +325,8 @@
+ printf("%c=", op);
+ ldns_rr_print(stdout, rr1);
+ }
++ i++;
++ j++;
+ }
+ }
+
+diff -ur ldns-1.7.1/examples/ldns-dane.c ldns/examples/ldns-dane.c
+--- ldns-1.7.1/examples/ldns-dane.c 2019-07-26 17:07:44.000000000 +0200
++++ ldns/examples/ldns-dane.c 2021-10-17 21:21:57.622895809 +0200
+@@ -1209,9 +1209,9 @@
+ int ai_family = AF_UNSPEC;
+ int transport = LDNS_DANE_TRANSPORT_TCP;
+
+- char* name_str = NULL; /* supress uninitialized warning */
++ char* name_str = NULL; /* suppress uninitialized warning */
+ ldns_rdf* name;
+- uint16_t port = 0; /* supress uninitialized warning */
++ uint16_t port = 0; /* suppress uninitialized warning */
+
+ ldns_resolver* res = NULL;
+ ldns_rdf* nameserver_rdf = NULL;
+@@ -1680,9 +1680,11 @@
+ assert(0);
+ }
+
+- /* ssl inititalize */
++#if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(HAVE_LIBRESSL)
++ /* ssl initialize */
+ SSL_load_error_strings();
+ SSL_library_init();
++#endif
+
+ /* ssl load validation store */
+ if (! assume_pkix_validity || CAfile || CApath) {
+@@ -1703,6 +1705,20 @@
+ if (ctx && SSL_CTX_dane_enable(ctx) <= 0) {
+ ssl_err("could not SSL_CTX_dane_enable");
+ }
++
++ /* Use TLSv1.0 or above for connection. */
++ long flags = 0;
++# ifdef SSL_OP_NO_SSLv2
++ flags |= SSL_OP_NO_SSLv2;
++# endif
++# ifdef SSL_OP_NO_SSLv3
++ flags |= SSL_OP_NO_SSLv3;
++# endif
++# ifdef SSL_OP_NO_COMPRESSION
++ flags |= SSL_OP_NO_COMPRESSION;
++# endif
++ SSL_CTX_set_options(ctx, flags);
++
+ if (CAfile || CApath) {
+ if (!SSL_CTX_load_verify_locations(ctx, CAfile, CApath))
+ ssl_err("could not set verify locations\n");
+diff -ur ldns-1.7.1/examples/ldns-dpa.1 ldns/examples/ldns-dpa.1
+--- ldns-1.7.1/examples/ldns-dpa.1 2019-07-26 17:07:44.000000000 +0200
++++ ldns/examples/ldns-dpa.1 2021-10-17 21:21:57.622895809 +0200
+@@ -112,7 +112,7 @@
+
+ .TP
+ ldns-dpa \-u packetsize \-p test.tr
+-Count all different packetsizes in test.tr and show the precentages.
++Count all different packetsizes in test.tr and show the percentages.
+
+ .TP
+ ldns-dpa \-f "edns=1&qr=0" \-of edns.tr test.tr
+diff -ur ldns-1.7.1/examples/ldns-gen-zone.c ldns/examples/ldns-gen-zone.c
+--- ldns-1.7.1/examples/ldns-gen-zone.c 2019-07-26 17:07:44.000000000 +0200
++++ ldns/examples/ldns-gen-zone.c 2021-10-17 21:21:57.622895809 +0200
+@@ -169,7 +169,7 @@
+ }
+ s = ldns_zone_new_frm_fp_l(&z, fp, origin, 0, LDNS_RR_CLASS_IN, &line_nr);
+ if (s != LDNS_STATUS_OK) {
+- fprintf(stderr, "%s at %d\n", ldns_get_errorstr_by_id(s), line_nr);
++ fprintf(stderr, "%s at line %d\n", ldns_get_errorstr_by_id(s), line_nr);
+ exit(EXIT_FAILURE);
+ }
+ if (!ldns_zone_soa(z)) {
+diff -ur ldns-1.7.1/examples/ldns-keyfetcher.c ldns/examples/ldns-keyfetcher.c
+--- ldns-1.7.1/examples/ldns-keyfetcher.c 2019-07-26 17:07:44.000000000 +0200
++++ ldns/examples/ldns-keyfetcher.c 2021-10-17 21:21:57.622895809 +0200
+@@ -1,6 +1,6 @@
+ /*
+ * ldns-keyfetcher retrieves the DNSKEYS for a certain domain
+- * It traces the authoritatives nameservers down from the root
++ * It traces the authoritative nameservers down from the root
+ * And uses TCP, to minimize spoofing danger.
+ *
+ * (c) NLnet Labs, 2006 - 2008
+@@ -74,7 +74,7 @@
+ }
+
+ /* transfer some properties of local_res to res,
+- * because they were given on the commandline */
++ * because they were given on the command line */
+ ldns_resolver_set_ip6(res,
+ ldns_resolver_ip6(local_res));
+ ldns_resolver_set_port(res,
+@@ -143,7 +143,7 @@
+ /* remove the old nameserver from the resolver */
+ while((pop = ldns_resolver_pop_nameserver(res))) { ldns_rdf_deep_free(pop); }
+
+- /* also check for new_nss emptyness */
++ /* also check for new_nss emptiness */
+
+ if (!new_nss_aaaa && !new_nss_a) {
+ /*
+diff -ur ldns-1.7.1/examples/ldns-keygen.1 ldns/examples/ldns-keygen.1
+--- ldns-1.7.1/examples/ldns-keygen.1 2019-07-26 17:07:44.000000000 +0200
++++ ldns/examples/ldns-keygen.1 2021-10-17 21:21:57.622895809 +0200
+@@ -44,6 +44,16 @@
+ default to /dev/random.
+
+ .TP
++\fB-s\fR
++ldns-keygen will create symbolic links named \fB.private\fR to
++the new generated private key, \fB.key\fR to the public DNSKEY
++and \fB.ds\fR to the file containing DS record data.
++
++.TP
++\fB-f\fR
++force symlinks to be overwritten if they exist.
++
++.TP
+ \fB-v\fR
+ Show the version and exit
+
+diff -ur ldns-1.7.1/examples/ldns-keygen.c ldns/examples/ldns-keygen.c
+--- ldns-1.7.1/examples/ldns-keygen.c 2019-07-26 17:07:44.000000000 +0200
++++ ldns/examples/ldns-keygen.c 2021-10-17 21:21:57.622895809 +0200
+@@ -14,11 +14,12 @@
+ #include <sys/stat.h>
+ #include <fcntl.h>
+ #include <errno.h>
++#include <unistd.h>
+
+ #ifdef HAVE_SSL
+ static void
+ usage(FILE *fp, char *prog) {
+- fprintf(fp, "%s -a <algorithm> [-b bits] [-r /dev/random] [-v] domain\n",
++ fprintf(fp, "%s -a <algorithm> [-b bits] [-r /dev/random] [-s] [-f] [-v] domain\n",
+ prog);
+ fprintf(fp, " generate a new key pair for domain\n");
+ fprintf(fp, " -a <alg>\tuse the specified algorithm (-a list to");
+@@ -27,6 +28,8 @@
+ fprintf(fp, " -b <bits>\tspecify the keylength\n");
+ fprintf(fp, " -r <random>\tspecify a random device (defaults to /dev/random)\n");
+ fprintf(fp, "\t\tto seed the random generator with\n");
++ fprintf(fp, " -s\t\tcreate additional symlinks with constant names\n");
++ fprintf(fp, " -f\t\tforce override of existing symlinks\n");
+ fprintf(fp, " -v\t\tshow the version and exit\n");
+ fprintf(fp, " The following files will be created:\n");
+ fprintf(fp, " K<name>+<alg>+<id>.key\tPublic key in RR format\n");
+@@ -47,6 +50,37 @@
+ }
+ }
+
++static int
++remove_symlink(const char *symlink_name)
++{
++ int result;
++
++ if ((result = unlink(symlink_name)) == -1) {
++ if (errno == ENOENT) {
++ /* it's OK if the link simply didn't exist */
++ result = 0;
++ } else {
++ /* error if unlink fail */
++ fprintf(stderr, "Can't delete symlink %s: %s\n", symlink_name, strerror(errno));
++ }
++ }
++ return result;
++}
++
++static int
++create_symlink(const char *symlink_destination, const char *symlink_name)
++{
++ int result = 0;
++
++ if (!symlink_name)
++ return result; /* no arg "-s" at all */
++
++ if ((result = symlink(symlink_destination, symlink_name)) == -1) {
++ fprintf(stderr, "Unable to create symlink %s -> %s: %s\n", symlink_name, symlink_destination, strerror(errno));
++ }
++ return result;
++}
++
+ int
+ main(int argc, char *argv[])
+ {
+@@ -64,6 +98,8 @@
+ FILE *random;
+ char *filename;
+ char *owner;
++ bool symlink_create;
++ bool symlink_override;
+
+ ldns_signing_algorithm algorithm;
+ ldns_rdf *domain;
+@@ -75,8 +111,10 @@
+ algorithm = 0;
+ random = NULL;
+ ksk = false; /* don't create a ksk per default */
++ symlink_create = false;
++ symlink_override = false;
+
+- while ((c = getopt(argc, argv, "a:kb:r:v")) != -1) {
++ while ((c = getopt(argc, argv, "a:kb:r:sfv")) != -1) {
+ switch (c) {
+ case 'a':
+ if (algorithm != 0) {
+@@ -112,6 +150,12 @@
+ exit(EXIT_FAILURE);
+ }
+ break;
++ case 's':
++ symlink_create = true;
++ break;
++ case 'f':
++ symlink_override = true;
++ break;
+ case 'v':
+ printf("DNSSEC key generator version %s (ldns version %s)\n", LDNS_VERSION, ldns_version());
+ exit(EXIT_SUCCESS);
+@@ -148,6 +192,7 @@
+ exit(1);
+ }
+ break;
++#ifdef USE_DSA
+ case LDNS_SIGN_DSA:
+ case LDNS_SIGN_DSA_NSEC3:
+ if (bits < 512 || bits > 1024) {
+@@ -156,6 +201,7 @@
+ exit(1);
+ }
+ break;
++#endif /* USE_DSA */
+ #ifdef USE_GOST
+ case LDNS_SIGN_ECC_GOST:
+ if(!ldns_key_EVP_load_gost_id()) {
+@@ -303,6 +349,19 @@
+ break;
+ }
+
++ /* maybe a symlinks should be removed */
++ if (symlink_create && symlink_override) {
++ if (remove_symlink(".key") != 0) {
++ exit(EXIT_FAILURE);
++ }
++ if (remove_symlink(".private") != 0) {
++ exit(EXIT_FAILURE);
++ }
++ if (remove_symlink(".ds") != 0) {
++ exit(EXIT_FAILURE);
++ }
++ }
++
+ /* print the public key RR to .key */
+ filename = LDNS_XMALLOC(char, strlen(owner) + 17);
+ snprintf(filename, strlen(owner) + 16, "K%s+%03u+%05u.key", owner, algorithm, (unsigned int) ldns_key_keytag(key));
+@@ -321,6 +380,11 @@
+ ldns_rr_print(file, pubkey);
+ ldns_rr_set_question(pubkey, false);
+ fclose(file);
++ if (symlink_create) {
++ if (create_symlink(filename, ".key") != 0) {
++ goto silentfail;
++ }
++ }
+ LDNS_FREE(filename);
+ }
+
+@@ -340,6 +404,11 @@
+
+ ldns_key_print(file, key);
+ fclose(file);
++ if (symlink_create) {
++ if (create_symlink(filename, ".private") != 0) {
++ goto silentfail;
++ }
++ }
+ LDNS_FREE(filename);
+
+ /* print the DS to .ds */
+@@ -366,6 +435,11 @@
+ ldns_rr_print(file, ds);
+ ldns_rr_set_question(ds, false);
+ fclose(file);
++ if (symlink_create) {
++ if (create_symlink(filename, ".ds") != 0) {
++ goto silentfail;
++ }
++ }
+ LDNS_FREE(filename);
+ }
+ }
+@@ -379,6 +453,7 @@
+
+ fail:
+ fprintf(stderr, "Unable to open %s: %s\n", filename, strerror(errno));
++silentfail:
+ ldns_key_deep_free(key);
+ free(owner);
+ ldns_rr_free(pubkey);
+diff -ur ldns-1.7.1/examples/ldns-notify.1 ldns/examples/ldns-notify.1
+--- ldns-1.7.1/examples/ldns-notify.1 2019-07-26 17:07:44.000000000 +0200
++++ ldns/examples/ldns-notify.1 2021-10-17 21:21:57.626229082 +0200
+@@ -41,7 +41,7 @@
+
+ .TP
+ \fB-y key:data[:algo] \fR
+-Use the given TSIG key and base64-data, and optinally an algorithm to sign
++Use the given TSIG key and base64-data, and optionally an algorithm to sign
+ the NOTIFY. The algorithm defaults to hmac-md5.sig-alg.reg.int.
+
+ .TP
+diff -ur ldns-1.7.1/examples/ldns-read-zone.c ldns/examples/ldns-read-zone.c
+--- ldns-1.7.1/examples/ldns-read-zone.c 2019-07-26 17:07:44.000000000 +0200
++++ ldns/examples/ldns-read-zone.c 2021-10-17 21:21:57.626229082 +0200
+@@ -258,7 +258,7 @@
+
+ fclose(fp);
+ if (s != LDNS_STATUS_OK) {
+- fprintf(stderr, "%s at %d\n",
++ fprintf(stderr, "%s at line %d\n",
+ ldns_get_errorstr_by_id(s),
+ line_nr);
+ exit(EXIT_FAILURE);
+diff -ur ldns-1.7.1/examples/ldns-resolver.1 ldns/examples/ldns-resolver.1
+--- ldns-1.7.1/examples/ldns-resolver.1 2019-07-26 17:07:44.000000000 +0200
++++ ldns/examples/ldns-resolver.1 2021-10-17 21:21:57.626229082 +0200
+@@ -7,7 +7,7 @@
+
+ .SH DESCRIPTION
+ \fBldns-resolver\fR tries to create a resolver from a resolv.conf file.
+-This is only useful to test the library for robusteness with input data.
++This is only useful to test the library for robustness with input data.
+
+ .SH OPTIONS
+ \fBldns-resolver\fR takes a filename of the resolv.conf file as input.
+diff -ur ldns-1.7.1/examples/ldns-resolver.c ldns/examples/ldns-resolver.c
+--- ldns-1.7.1/examples/ldns-resolver.c 2019-07-26 17:07:44.000000000 +0200
++++ ldns/examples/ldns-resolver.c 2021-10-17 21:21:57.626229082 +0200
+@@ -1,6 +1,6 @@
+ /*
+ * ldns-resolver tries to create a resolver structure from /dev/urandom
+- * this is only useful to test the library for robusteness with input data
++ * this is only useful to test the library for robustness with input data
+ *
+ * (c) NLnet Labs 2006 - 2008
+ * See the file LICENSE for the license
+diff -ur ldns-1.7.1/examples/ldns-rrsig.1 ldns/examples/ldns-rrsig.1
+--- ldns-1.7.1/examples/ldns-rrsig.1 2019-07-26 17:07:44.000000000 +0200
++++ ldns/examples/ldns-rrsig.1 2021-10-17 21:21:57.626229082 +0200
+@@ -13,7 +13,7 @@
+ \fBldns-rrsig\fR is used to print the expiration and inception date of
+ a RRSIG. The first argument is a domain name. \fBldns-rrsig\fR will
+ query the authoritative servers for that domain to get a list of RRSIGs.
+-It will then print out the inception and experiration dates for the RRSIG
++It will then print out the inception and expiration dates for the RRSIG
+ covering the SOA record.
+ .PP
+ If the second argument \fBtype\fR is given the RRSIG covering that type will be shown.
+diff -ur ldns-1.7.1/examples/ldns-rrsig.c ldns/examples/ldns-rrsig.c
+--- ldns-1.7.1/examples/ldns-rrsig.c 2019-07-26 17:07:44.000000000 +0200
++++ ldns/examples/ldns-rrsig.c 2021-10-17 21:21:57.626229082 +0200
+@@ -2,7 +2,7 @@
+ * ldns-rrsig prints out the inception and expiration dates in a more readable
+ * way than the normal RRSIG presentation format
+ *
+- * for a particulary domain
++ * for a particularly domain
+ * (c) NLnet Labs, 2005 - 2008
+ * See the file LICENSE for the license
+ */
+@@ -180,7 +180,7 @@
+
+ for(i = 0; i < ldns_rr_list_rr_count(rrsig_type); i++) {
+ memset(&incep, 0, sizeof(incep));
+- if (ldns_serial_arithmitics_gmtime_r(
++ if (ldns_serial_arithmetics_gmtime_r(
+ ldns_rdf2native_time_t(
+ ldns_rr_rrsig_inception(
+ ldns_rr_list_rr(rrsig_type, i))),
+@@ -192,7 +192,7 @@
+ incep_buf[0] = '\0';
+ }
+ memset(&expir, 0, sizeof(expir));
+- if (ldns_serial_arithmitics_gmtime_r(
++ if (ldns_serial_arithmetics_gmtime_r(
+ ldns_rdf2native_time_t(
+ ldns_rr_rrsig_expiration(
+ ldns_rr_list_rr(rrsig_type, i))),
+diff -ur ldns-1.7.1/examples/ldns-signzone.1 ldns/examples/ldns-signzone.1
+--- ldns-1.7.1/examples/ldns-signzone.1 2019-07-26 17:07:44.000000000 +0200
++++ ldns/examples/ldns-signzone.1 2021-10-17 21:21:57.626229082 +0200
+@@ -34,7 +34,7 @@
+ \fB-b\fR
+ Augments the zone and the RR's with extra comment texts for a more readable
+ layout, easier to debug. DS records will have a bubblebabble version of
+-the data in the comment text, NSEC3 records will have the original NSEC3
++the data in the comment text, NSEC3 records will have the unhashed owner names
+ in the comment text.
+
+ Without this option, only DNSKEY RR's will have their Key Tag annotated in
+@@ -66,10 +66,24 @@
+ Use this as the origin of the zone
+
+ .TP
++\fB-u\fR
++set SOA serial to the number of seconds since 1-1-1970
++
++.TP
+ \fB-v\fR
+ Print the version and exit
+
+ .TP
++\fB-z\fR \fI[scheme:]hash\fR
++Calculate the zone's digest and add those as ZONEMD RRs. The (optional)
++`scheme' must be `simple` (or 1) and `hash' should be `sha384' (or 1) or
++`sha512' (or 2). This option can be given more than once.
++
++.TP
++\fB-Z\fR
++Allow ZONEMDs to be added without signing
++
++.TP
+ \fB-A\fR
+ Sign the DNSKEY record with all keys. By default it is signed with a
+ minimal number of keys, to keep the response size for the DNSKEY query
+diff -ur ldns-1.7.1/examples/ldns-signzone.c ldns/examples/ldns-signzone.c
+--- ldns-1.7.1/examples/ldns-signzone.c 2019-07-26 17:07:44.000000000 +0200
++++ ldns/examples/ldns-signzone.c 2021-10-17 21:21:57.626229082 +0200
+@@ -44,6 +44,11 @@
+ fprintf(fp, " -o <domain>\torigin for the zone\n");
+ fprintf(fp, " -u\t\tset SOA serial to the number of seconds since 1-1-1970\n");
+ fprintf(fp, " -v\t\tprint version and exit\n");
++ fprintf(fp, " -z <[scheme:]hash>\tAdd ZONEMD resource record\n");
++ fprintf(fp, "\t\t<scheme> should be \"simple\" (or 1)\n");
++ fprintf(fp, "\t\t<hash> should be \"sha384\" or \"sha512\" (or 1 or 2)\n");
++ fprintf(fp, "\t\tthis option can be given more than once\n");
++ fprintf(fp, " -Z\t\tAllow ZONEMDs to be added without signing\n");
+ fprintf(fp, " -A\t\tsign DNSKEY with all keys instead of minimal\n");
+ fprintf(fp, " -U\t\tSign with every unique algorithm in the provided keys\n");
+ #ifndef OPENSSL_NO_ENGINE
+@@ -72,10 +77,14 @@
+
+ fprintf ( fp, "\n " );
+ __LIST ( RSAMD5 );
++#ifdef USE_DSA
+ __LIST ( DSA );
++#endif
+ __LIST ( RSASHA1 );
+ fprintf ( fp, "\n " );
++#ifdef USE_DSA
+ __LIST ( DSA_NSEC3 );
++#endif
+ __LIST ( RSASHA1_NSEC3 );
+ __LIST ( RSASHA256 );
+ fprintf ( fp, "\n " );
+@@ -328,7 +337,7 @@
+
+ #ifndef OPENSSL_NO_ENGINE
+ /*
+- * For keys coming from the engine (-k or -K), parse algoritm specification.
++ * For keys coming from the engine (-k or -K), parse algorithm specification.
+ */
+ static enum ldns_enum_signing_algorithm
+ parse_algspec ( const char * const p )
+@@ -350,11 +359,15 @@
+
+ __MATCH ( RSAMD5 );
+ __MATCH ( RSASHA1 );
++#ifdef USE_DSA
+ __MATCH ( DSA );
++#endif
+ __MATCH ( RSASHA1_NSEC3 );
+ __MATCH ( RSASHA256 );
+ __MATCH ( RSASHA512 );
++#ifdef USE_DSA
+ __MATCH ( DSA_NSEC3 );
++#endif
+ __MATCH ( ECC_GOST );
+ __MATCH ( ECDSAP256SHA256 );
+ __MATCH ( ECDSAP384SHA384 );
+@@ -419,8 +432,10 @@
+ case LDNS_SIGN_RSASHA1_NSEC3:
+ case LDNS_SIGN_RSASHA256:
+ case LDNS_SIGN_RSASHA512:
++#ifdef USE_DSA
+ case LDNS_SIGN_DSA:
+ case LDNS_SIGN_DSA_NSEC3:
++#endif
+ case LDNS_SIGN_ECC_GOST:
+ #ifdef USE_ECDSA
+ case LDNS_SIGN_ECDSAP256SHA256:
+@@ -526,17 +541,64 @@
+ shutdown_openssl ( ENGINE * const e )
+ {
+ if ( e != NULL ) {
++#ifdef HAVE_ENGINE_FREE
+ ENGINE_free ( e );
++#endif
++#ifdef HAVE_ENGINE_CLEANUP
+ ENGINE_cleanup ();
++#endif
+ }
+
++#ifdef HAVE_CONF_MODULES_UNLOAD
+ CONF_modules_unload ( 1 );
++#endif
++#ifdef HAVE_EVP_CLEANUP
+ EVP_cleanup ();
++#endif
++#ifdef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA
+ CRYPTO_cleanup_all_ex_data ();
++#endif
++#ifdef HAVE_ERR_FREE_STRINGS
+ ERR_free_strings ();
++#endif
+ }
+ #endif
+
++int str2zonemd_signflag(const char *str, const char **reason)
++{
++ char *colon;
++
++ static const char *reasons[] = {
++ "Unknown <scheme>, should be \"simple\""
++ , "Syntax error in <hash>, should be \"sha384\" or \"sha512\""
++ , "Unknown <hash>, should be \"sha384\" or \"sha512\""
++ };
++
++ if (!str)
++ return LDNS_STATUS_NULL;
++
++ if ((colon = strchr(str, ':'))) {
++ if ((colon - str != 1 || str[0] != '1')
++ && (colon - str != 6 || strncasecmp(str, "simple", 6))) {
++ if (reason) *reason = reasons[0];
++ return 0;
++ }
++
++ if (strchr(colon + 1, ':')) {
++ if (reason) *reason = reasons[1];
++ return 0;
++ }
++ return str2zonemd_signflag(colon + 1, reason);
++ }
++ if (!strcasecmp(str, "1") || !strcasecmp(str, "sha384"))
++ return LDNS_SIGN_WITH_ZONEMD_SIMPLE_SHA384;
++ if (!strcasecmp(str, "2") || !strcasecmp(str, "sha512"))
++ return LDNS_SIGN_WITH_ZONEMD_SIMPLE_SHA512;
++
++ if (reason) *reason = reasons[2];
++ return 0;
++}
++
+ int
+ main(int argc, char *argv[])
+ {
+@@ -596,14 +658,18 @@
+
+ ldns_output_format_storage fmt_st;
+ ldns_output_format* fmt = ldns_output_format_init(&fmt_st);
+-
++
++ /* For parson zone digest parameters */
++ int flag;
++ const char *reason = NULL;
++
<Skipped 3984 lines>
================================================================
---- gitweb:
http://git.pld-linux.org/gitweb.cgi/packages/ldns.git/commitdiff/e3e3dab93b4b56bc0b9a79657bb82fe47eab59fe
More information about the pld-cvs-commit
mailing list