[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