Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package pdns for openSUSE:Factory checked in 
at 2025-08-21 16:59:42
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/pdns (Old)
 and      /work/SRC/openSUSE:Factory/.pdns.new.29662 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "pdns"

Thu Aug 21 16:59:42 2025 rev:97 rq:1300708 version:4.9.8

Changes:
--------
--- /work/SRC/openSUSE:Factory/pdns/pdns.changes        2025-04-10 
21:59:26.585087864 +0200
+++ /work/SRC/openSUSE:Factory/.pdns.new.29662/pdns.changes     2025-08-21 
17:00:09.840062446 +0200
@@ -1,0 +2,9 @@
+Thu Aug 14 01:58:34 UTC 2025 - Marcus Rueckert <mrueck...@suse.de>
+
+- Update to version 4.9.8
+  https://doc.powerdns.com/authoritative/changelog/4.9.html#change-4.9.5
+  https://doc.powerdns.com/authoritative/changelog/4.9.html#change-4.9.7
+  https://doc.powerdns.com/authoritative/changelog/4.9.html#change-4.9.8
+- enable luajit support where possible
+
+-------------------------------------------------------------------

Old:
----
  pdns-4.9.4.tar.bz2
  pdns-4.9.4.tar.bz2.sig

New:
----
  pdns-4.9.8.tar.bz2
  pdns-4.9.8.tar.bz2.sig

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ pdns.spec ++++++
--- /var/tmp/diff_new_pack.Pyal2O/_old  2025-08-21 17:00:10.440087573 +0200
+++ /var/tmp/diff_new_pack.Pyal2O/_new  2025-08-21 17:00:10.444087740 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package pdns
 #
-# Copyright (c) 2025 SUSE LLC
+# Copyright (c) 2025 SUSE LLC and contributors
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -16,6 +16,16 @@
 #
 
 
+%ifarch ppc64le
+%bcond_with     pdns_luajit
+%else
+%if 0%{?sle_version} >= 150400 || 0%{?suse_version} >= 1599
+%bcond_without  pdns_luajit
+%else
+%bcond_with     pdns_luajit
+%endif
+%endif
+
 %if 0%{?fedora_version} >= 24 || 0%{?fc24}%{?fc25}
 %bcond_with    systemd_separetedlibs
 %else
@@ -59,7 +69,7 @@
 %endif
 
 Name:           pdns
-Version:        4.9.4
+Version:        4.9.8
 Release:        0
 Summary:        Authoritative-only nameserver
 License:        GPL-2.0-only
@@ -105,7 +115,11 @@
 BuildRequires:  pkgconfig(libmaxminddb)
 %endif
 %if %{with pdns_lua}
-BuildRequires:  lua-devel
+%if %{with pdns_luajit}
+BuildRequires:  pkgconfig(luajit)
+%else
+BuildRequires:  pkgconfig(lua)
+%endif
 %endif
 %if %{with pdns_tinydns}
 # FIXME: Could not find libcdb/tinycdb

++++++ pdns-4.9.4.tar.bz2 -> pdns-4.9.8.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-4.9.4/configure new/pdns-4.9.8/configure
--- old/pdns-4.9.4/configure    2025-02-06 16:18:00.000000000 +0100
+++ new/pdns-4.9.8/configure    2025-08-07 10:48:23.000000000 +0200
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.71 for pdns 4.9.4.
+# Generated by GNU Autoconf 2.71 for pdns 4.9.8.
 #
 #
 # Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation,
@@ -618,8 +618,8 @@
 # Identity of this package.
 PACKAGE_NAME='pdns'
 PACKAGE_TARNAME='pdns'
-PACKAGE_VERSION='4.9.4'
-PACKAGE_STRING='pdns 4.9.4'
+PACKAGE_VERSION='4.9.8'
+PACKAGE_STRING='pdns 4.9.8'
 PACKAGE_BUGREPORT=''
 PACKAGE_URL=''
 
@@ -1698,7 +1698,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures pdns 4.9.4 to adapt to many kinds of systems.
+\`configure' configures pdns 4.9.8 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1769,7 +1769,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of pdns 4.9.4:";;
+     short | recursive ) echo "Configuration of pdns 4.9.8:";;
    esac
   cat <<\_ACEOF
 
@@ -2040,7 +2040,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-pdns configure 4.9.4
+pdns configure 4.9.8
 generated by GNU Autoconf 2.71
 
 Copyright (C) 2021 Free Software Foundation, Inc.
@@ -2529,7 +2529,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by pdns $as_me 4.9.4, which was
+It was created by pdns $as_me 4.9.8, which was
 generated by GNU Autoconf 2.71.  Invocation command line was
 
   $ $0$ac_configure_args_raw
@@ -4027,7 +4027,7 @@
 
 # Define the identity of the package.
  PACKAGE='pdns'
- VERSION='4.9.4'
+ VERSION='4.9.8'
 
 
 printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h
@@ -32467,7 +32467,7 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by pdns $as_me 4.9.4, which was
+This file was extended by pdns $as_me 4.9.8, which was
 generated by GNU Autoconf 2.71.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -32535,7 +32535,7 @@
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config='$ac_cs_config_escaped'
 ac_cs_version="\\
-pdns config.status 4.9.4
+pdns config.status 4.9.8
 configured by $0, generated by GNU Autoconf 2.71,
   with options \\"\$ac_cs_config\\"
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-4.9.4/configure.ac new/pdns-4.9.8/configure.ac
--- old/pdns-4.9.4/configure.ac 2025-02-06 16:17:52.000000000 +0100
+++ new/pdns-4.9.8/configure.ac 2025-08-07 10:48:15.000000000 +0200
@@ -1,6 +1,6 @@
 AC_PREREQ([2.69])
 
-AC_INIT([pdns], [4.9.4])
+AC_INIT([pdns], [4.9.8])
 AC_CONFIG_AUX_DIR([build-aux])
 AM_INIT_AUTOMAKE([foreign dist-bzip2 no-dist-gzip tar-ustar -Wno-portability 
subdir-objects parallel-tests 1.11])
 AM_SILENT_RULES([yes])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-4.9.4/docs/calidns.1 
new/pdns-4.9.8/docs/calidns.1
--- old/pdns-4.9.4/docs/calidns.1       2025-02-06 16:19:08.000000000 +0100
+++ new/pdns-4.9.8/docs/calidns.1       2025-08-07 10:49:28.000000000 +0200
@@ -27,7 +27,7 @@
 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
 .in \\n[rst2man-indent\\n[rst2man-indent-level]]u
 ..
-.TH "CALIDNS" "1" "Feb 06, 2025" "" "PowerDNS Authoritative Server"
+.TH "CALIDNS" "1" "Aug 07, 2025" "" "PowerDNS Authoritative Server"
 .SH NAME
 calidns \- A DNS recursor testing tool
 .SH SYNOPSIS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-4.9.4/docs/dnsbulktest.1 
new/pdns-4.9.8/docs/dnsbulktest.1
--- old/pdns-4.9.4/docs/dnsbulktest.1   2025-02-06 16:19:08.000000000 +0100
+++ new/pdns-4.9.8/docs/dnsbulktest.1   2025-08-07 10:49:28.000000000 +0200
@@ -27,7 +27,7 @@
 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
 .in \\n[rst2man-indent\\n[rst2man-indent-level]]u
 ..
-.TH "DNSBULKTEST" "1" "Feb 06, 2025" "" "PowerDNS Authoritative Server"
+.TH "DNSBULKTEST" "1" "Aug 07, 2025" "" "PowerDNS Authoritative Server"
 .SH NAME
 dnsbulktest \- A debugging tool for intermittent resolver failures
 .SH SYNOPSIS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-4.9.4/docs/dnsgram.1 
new/pdns-4.9.8/docs/dnsgram.1
--- old/pdns-4.9.4/docs/dnsgram.1       2025-02-06 16:19:08.000000000 +0100
+++ new/pdns-4.9.8/docs/dnsgram.1       2025-08-07 10:49:28.000000000 +0200
@@ -27,7 +27,7 @@
 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
 .in \\n[rst2man-indent\\n[rst2man-indent-level]]u
 ..
-.TH "DNSGRAM" "1" "Feb 06, 2025" "" "PowerDNS Authoritative Server"
+.TH "DNSGRAM" "1" "Aug 07, 2025" "" "PowerDNS Authoritative Server"
 .SH NAME
 dnsgram \- A debugging tool for intermittent resolver failures
 .SH SYNOPSIS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-4.9.4/docs/dnspcap2calidns.1 
new/pdns-4.9.8/docs/dnspcap2calidns.1
--- old/pdns-4.9.4/docs/dnspcap2calidns.1       2025-02-06 16:19:08.000000000 
+0100
+++ new/pdns-4.9.8/docs/dnspcap2calidns.1       2025-08-07 10:49:28.000000000 
+0200
@@ -27,7 +27,7 @@
 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
 .in \\n[rst2man-indent\\n[rst2man-indent-level]]u
 ..
-.TH "DNSPCAP2CALIDNS" "1" "Feb 06, 2025" "" "PowerDNS Authoritative Server"
+.TH "DNSPCAP2CALIDNS" "1" "Aug 07, 2025" "" "PowerDNS Authoritative Server"
 .SH NAME
 dnspcap2calidns \- A tool to convert PCAPs of DNS traffic to calidns input
 .SH SYNOPSIS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-4.9.4/docs/dnspcap2protobuf.1 
new/pdns-4.9.8/docs/dnspcap2protobuf.1
--- old/pdns-4.9.4/docs/dnspcap2protobuf.1      2025-02-06 16:19:08.000000000 
+0100
+++ new/pdns-4.9.8/docs/dnspcap2protobuf.1      2025-08-07 10:49:28.000000000 
+0200
@@ -27,7 +27,7 @@
 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
 .in \\n[rst2man-indent\\n[rst2man-indent-level]]u
 ..
-.TH "DNSPCAP2PROTOBUF" "1" "Feb 06, 2025" "" "PowerDNS Authoritative Server"
+.TH "DNSPCAP2PROTOBUF" "1" "Aug 07, 2025" "" "PowerDNS Authoritative Server"
 .SH NAME
 dnspcap2protobuf \- A tool to convert PCAPs of DNS traffic to PowerDNS Protobuf
 .SH SYNOPSIS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-4.9.4/docs/dnsreplay.1 
new/pdns-4.9.8/docs/dnsreplay.1
--- old/pdns-4.9.4/docs/dnsreplay.1     2025-02-06 16:19:08.000000000 +0100
+++ new/pdns-4.9.8/docs/dnsreplay.1     2025-08-07 10:49:28.000000000 +0200
@@ -27,7 +27,7 @@
 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
 .in \\n[rst2man-indent\\n[rst2man-indent-level]]u
 ..
-.TH "DNSREPLAY" "1" "Feb 06, 2025" "" "PowerDNS Authoritative Server"
+.TH "DNSREPLAY" "1" "Aug 07, 2025" "" "PowerDNS Authoritative Server"
 .SH NAME
 dnsreplay \- A PowerDNS nameserver debugging tool
 .SH SYNOPSIS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-4.9.4/docs/dnsscan.1 
new/pdns-4.9.8/docs/dnsscan.1
--- old/pdns-4.9.4/docs/dnsscan.1       2025-02-06 16:19:08.000000000 +0100
+++ new/pdns-4.9.8/docs/dnsscan.1       2025-08-07 10:49:28.000000000 +0200
@@ -27,7 +27,7 @@
 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
 .in \\n[rst2man-indent\\n[rst2man-indent-level]]u
 ..
-.TH "DNSSCAN" "1" "Feb 06, 2025" "" "PowerDNS Authoritative Server"
+.TH "DNSSCAN" "1" "Aug 07, 2025" "" "PowerDNS Authoritative Server"
 .SH NAME
 dnsscan \- List the amount of queries per qtype in a pcap
 .SH SYNOPSIS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-4.9.4/docs/dnsscope.1 
new/pdns-4.9.8/docs/dnsscope.1
--- old/pdns-4.9.4/docs/dnsscope.1      2025-02-06 16:19:08.000000000 +0100
+++ new/pdns-4.9.8/docs/dnsscope.1      2025-08-07 10:49:28.000000000 +0200
@@ -27,7 +27,7 @@
 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
 .in \\n[rst2man-indent\\n[rst2man-indent-level]]u
 ..
-.TH "DNSSCOPE" "1" "Feb 06, 2025" "" "PowerDNS Authoritative Server"
+.TH "DNSSCOPE" "1" "Aug 07, 2025" "" "PowerDNS Authoritative Server"
 .SH NAME
 dnsscope \- A PowerDNS nameserver debugging tool
 .SH SYNOPSIS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-4.9.4/docs/dnstcpbench.1 
new/pdns-4.9.8/docs/dnstcpbench.1
--- old/pdns-4.9.4/docs/dnstcpbench.1   2025-02-06 16:19:08.000000000 +0100
+++ new/pdns-4.9.8/docs/dnstcpbench.1   2025-08-07 10:49:28.000000000 +0200
@@ -27,7 +27,7 @@
 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
 .in \\n[rst2man-indent\\n[rst2man-indent-level]]u
 ..
-.TH "DNSTCPBENCH" "1" "Feb 06, 2025" "" "PowerDNS Authoritative Server"
+.TH "DNSTCPBENCH" "1" "Aug 07, 2025" "" "PowerDNS Authoritative Server"
 .SH NAME
 dnstcpbench \- tool to perform TCP benchmarking of nameservers
 .SH SYNOPSIS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-4.9.4/docs/dnswasher.1 
new/pdns-4.9.8/docs/dnswasher.1
--- old/pdns-4.9.4/docs/dnswasher.1     2025-02-06 16:19:08.000000000 +0100
+++ new/pdns-4.9.8/docs/dnswasher.1     2025-08-07 10:49:28.000000000 +0200
@@ -27,7 +27,7 @@
 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
 .in \\n[rst2man-indent\\n[rst2man-indent-level]]u
 ..
-.TH "DNSWASHER" "1" "Feb 06, 2025" "" "PowerDNS Authoritative Server"
+.TH "DNSWASHER" "1" "Aug 07, 2025" "" "PowerDNS Authoritative Server"
 .SH NAME
 dnswasher \- A PowerDNS nameserver debugging tool
 .SH SYNOPSIS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-4.9.4/docs/dumresp.1 
new/pdns-4.9.8/docs/dumresp.1
--- old/pdns-4.9.4/docs/dumresp.1       2025-02-06 16:19:08.000000000 +0100
+++ new/pdns-4.9.8/docs/dumresp.1       2025-08-07 10:49:28.000000000 +0200
@@ -27,7 +27,7 @@
 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
 .in \\n[rst2man-indent\\n[rst2man-indent-level]]u
 ..
-.TH "DUMRESP" "1" "Feb 06, 2025" "" "PowerDNS Authoritative Server"
+.TH "DUMRESP" "1" "Aug 07, 2025" "" "PowerDNS Authoritative Server"
 .SH NAME
 dumresp \- A dumb DNS responder
 .SH SYNOPSIS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-4.9.4/docs/ixfrdist.1 
new/pdns-4.9.8/docs/ixfrdist.1
--- old/pdns-4.9.4/docs/ixfrdist.1      2025-02-06 16:19:08.000000000 +0100
+++ new/pdns-4.9.8/docs/ixfrdist.1      2025-08-07 10:49:28.000000000 +0200
@@ -27,7 +27,7 @@
 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
 .in \\n[rst2man-indent\\n[rst2man-indent-level]]u
 ..
-.TH "IXFRDIST" "1" "Feb 06, 2025" "" "PowerDNS Authoritative Server"
+.TH "IXFRDIST" "1" "Aug 07, 2025" "" "PowerDNS Authoritative Server"
 .SH NAME
 ixfrdist \- An IXFR/AXFR-only server that re-distributes zones
 .SH SYNOPSIS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-4.9.4/docs/ixfrdist.yml.5 
new/pdns-4.9.8/docs/ixfrdist.yml.5
--- old/pdns-4.9.4/docs/ixfrdist.yml.5  2025-02-06 16:19:08.000000000 +0100
+++ new/pdns-4.9.8/docs/ixfrdist.yml.5  2025-08-07 10:49:28.000000000 +0200
@@ -27,7 +27,7 @@
 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
 .in \\n[rst2man-indent\\n[rst2man-indent-level]]u
 ..
-.TH "IXFRDIST.YML" "5" "Feb 06, 2025" "" "PowerDNS Authoritative Server"
+.TH "IXFRDIST.YML" "5" "Aug 07, 2025" "" "PowerDNS Authoritative Server"
 .SH NAME
 ixfrdist.yml \- The ixfrdist configuration file
 .SH SYNOPSIS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-4.9.4/docs/ixplore.1 
new/pdns-4.9.8/docs/ixplore.1
--- old/pdns-4.9.4/docs/ixplore.1       2025-02-06 16:19:08.000000000 +0100
+++ new/pdns-4.9.8/docs/ixplore.1       2025-08-07 10:49:28.000000000 +0200
@@ -27,7 +27,7 @@
 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
 .in \\n[rst2man-indent\\n[rst2man-indent-level]]u
 ..
-.TH "IXPLORE" "1" "Feb 06, 2025" "" "PowerDNS Authoritative Server"
+.TH "IXPLORE" "1" "Aug 07, 2025" "" "PowerDNS Authoritative Server"
 .SH NAME
 ixplore \- A tool that provides insights into IXFRs
 .SH SYNOPSIS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-4.9.4/docs/nproxy.1 new/pdns-4.9.8/docs/nproxy.1
--- old/pdns-4.9.4/docs/nproxy.1        2025-02-06 16:19:08.000000000 +0100
+++ new/pdns-4.9.8/docs/nproxy.1        2025-08-07 10:49:28.000000000 +0200
@@ -27,7 +27,7 @@
 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
 .in \\n[rst2man-indent\\n[rst2man-indent-level]]u
 ..
-.TH "NPROXY" "1" "Feb 06, 2025" "" "PowerDNS Authoritative Server"
+.TH "NPROXY" "1" "Aug 07, 2025" "" "PowerDNS Authoritative Server"
 .SH NAME
 nproxy \- DNS notification proxy
 .SH SYNOPSIS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-4.9.4/docs/nsec3dig.1 
new/pdns-4.9.8/docs/nsec3dig.1
--- old/pdns-4.9.4/docs/nsec3dig.1      2025-02-06 16:19:08.000000000 +0100
+++ new/pdns-4.9.8/docs/nsec3dig.1      2025-08-07 10:49:28.000000000 +0200
@@ -27,7 +27,7 @@
 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
 .in \\n[rst2man-indent\\n[rst2man-indent-level]]u
 ..
-.TH "NSEC3DIG" "1" "Feb 06, 2025" "" "PowerDNS Authoritative Server"
+.TH "NSEC3DIG" "1" "Aug 07, 2025" "" "PowerDNS Authoritative Server"
 .SH NAME
 nsec3dig \- Show and validate NSEC3 proofs
 .SH SYNOPSIS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-4.9.4/docs/pdns_control.1 
new/pdns-4.9.8/docs/pdns_control.1
--- old/pdns-4.9.4/docs/pdns_control.1  2025-02-06 16:19:08.000000000 +0100
+++ new/pdns-4.9.8/docs/pdns_control.1  2025-08-07 10:49:28.000000000 +0200
@@ -27,7 +27,7 @@
 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
 .in \\n[rst2man-indent\\n[rst2man-indent-level]]u
 ..
-.TH "PDNS_CONTROL" "1" "Feb 06, 2025" "" "PowerDNS Authoritative Server"
+.TH "PDNS_CONTROL" "1" "Aug 07, 2025" "" "PowerDNS Authoritative Server"
 .SH NAME
 pdns_control \- Control the PowerDNS nameserver
 .SH SYNOPSIS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-4.9.4/docs/pdns_notify.1 
new/pdns-4.9.8/docs/pdns_notify.1
--- old/pdns-4.9.4/docs/pdns_notify.1   2025-02-06 16:19:08.000000000 +0100
+++ new/pdns-4.9.8/docs/pdns_notify.1   2025-08-07 10:49:28.000000000 +0200
@@ -27,7 +27,7 @@
 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
 .in \\n[rst2man-indent\\n[rst2man-indent-level]]u
 ..
-.TH "PDNS_NOTIFY" "1" "Feb 06, 2025" "" "PowerDNS Authoritative Server"
+.TH "PDNS_NOTIFY" "1" "Aug 07, 2025" "" "PowerDNS Authoritative Server"
 .SH NAME
 pdns_notify \- A simple DNS NOTIFY sender
 .SH SYNOPSIS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-4.9.4/docs/pdns_server.1 
new/pdns-4.9.8/docs/pdns_server.1
--- old/pdns-4.9.4/docs/pdns_server.1   2025-02-06 16:19:08.000000000 +0100
+++ new/pdns-4.9.8/docs/pdns_server.1   2025-08-07 10:49:28.000000000 +0200
@@ -27,7 +27,7 @@
 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
 .in \\n[rst2man-indent\\n[rst2man-indent-level]]u
 ..
-.TH "PDNS_SERVER" "1" "Feb 06, 2025" "" "PowerDNS Authoritative Server"
+.TH "PDNS_SERVER" "1" "Aug 07, 2025" "" "PowerDNS Authoritative Server"
 .SH NAME
 pdns_server \- The PowerDNS Authoritative Nameserver
 .SH SYNOPSIS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-4.9.4/docs/pdnsutil.1 
new/pdns-4.9.8/docs/pdnsutil.1
--- old/pdns-4.9.4/docs/pdnsutil.1      2025-02-06 16:19:08.000000000 +0100
+++ new/pdns-4.9.8/docs/pdnsutil.1      2025-08-07 10:49:28.000000000 +0200
@@ -27,7 +27,7 @@
 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
 .in \\n[rst2man-indent\\n[rst2man-indent-level]]u
 ..
-.TH "PDNSUTIL" "1" "Feb 06, 2025" "" "PowerDNS Authoritative Server"
+.TH "PDNSUTIL" "1" "Aug 07, 2025" "" "PowerDNS Authoritative Server"
 .SH NAME
 pdnsutil \- PowerDNS record and DNSSEC command and control
 .SH SYNOPSIS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-4.9.4/docs/saxfr.1 new/pdns-4.9.8/docs/saxfr.1
--- old/pdns-4.9.4/docs/saxfr.1 2025-02-06 16:19:08.000000000 +0100
+++ new/pdns-4.9.8/docs/saxfr.1 2025-08-07 10:49:28.000000000 +0200
@@ -27,7 +27,7 @@
 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
 .in \\n[rst2man-indent\\n[rst2man-indent-level]]u
 ..
-.TH "SAXFR" "1" "Feb 06, 2025" "" "PowerDNS Authoritative Server"
+.TH "SAXFR" "1" "Aug 07, 2025" "" "PowerDNS Authoritative Server"
 .SH NAME
 saxfr \- Perform AXFRs and show information about it
 .SH SYNOPSIS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-4.9.4/docs/sdig.1 new/pdns-4.9.8/docs/sdig.1
--- old/pdns-4.9.4/docs/sdig.1  2025-02-06 16:19:08.000000000 +0100
+++ new/pdns-4.9.8/docs/sdig.1  2025-08-07 10:49:28.000000000 +0200
@@ -27,7 +27,7 @@
 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
 .in \\n[rst2man-indent\\n[rst2man-indent-level]]u
 ..
-.TH "SDIG" "1" "Feb 06, 2025" "" "PowerDNS Authoritative Server"
+.TH "SDIG" "1" "Aug 07, 2025" "" "PowerDNS Authoritative Server"
 .SH NAME
 sdig \- Perform a DNS query and show the results
 .SH SYNOPSIS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-4.9.4/docs/zone2json.1 
new/pdns-4.9.8/docs/zone2json.1
--- old/pdns-4.9.4/docs/zone2json.1     2025-02-06 16:19:08.000000000 +0100
+++ new/pdns-4.9.8/docs/zone2json.1     2025-08-07 10:49:28.000000000 +0200
@@ -27,7 +27,7 @@
 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
 .in \\n[rst2man-indent\\n[rst2man-indent-level]]u
 ..
-.TH "ZONE2JSON" "1" "Feb 06, 2025" "" "PowerDNS Authoritative Server"
+.TH "ZONE2JSON" "1" "Aug 07, 2025" "" "PowerDNS Authoritative Server"
 .SH NAME
 zone2json \- convert BIND zones to JSON
 .SH SYNOPSIS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-4.9.4/docs/zone2ldap.1 
new/pdns-4.9.8/docs/zone2ldap.1
--- old/pdns-4.9.4/docs/zone2ldap.1     2025-02-06 16:19:08.000000000 +0100
+++ new/pdns-4.9.8/docs/zone2ldap.1     2025-08-07 10:49:28.000000000 +0200
@@ -27,7 +27,7 @@
 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
 .in \\n[rst2man-indent\\n[rst2man-indent-level]]u
 ..
-.TH "ZONE2LDAP" "1" "Feb 06, 2025" "" "PowerDNS Authoritative Server"
+.TH "ZONE2LDAP" "1" "Aug 07, 2025" "" "PowerDNS Authoritative Server"
 .SH NAME
 zone2ldap \- convert zonefiles to ldif
 .SH SYNOPSIS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-4.9.4/docs/zone2sql.1 
new/pdns-4.9.8/docs/zone2sql.1
--- old/pdns-4.9.4/docs/zone2sql.1      2025-02-06 16:19:08.000000000 +0100
+++ new/pdns-4.9.8/docs/zone2sql.1      2025-08-07 10:49:28.000000000 +0200
@@ -27,7 +27,7 @@
 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
 .in \\n[rst2man-indent\\n[rst2man-indent-level]]u
 ..
-.TH "ZONE2SQL" "1" "Feb 06, 2025" "" "PowerDNS Authoritative Server"
+.TH "ZONE2SQL" "1" "Aug 07, 2025" "" "PowerDNS Authoritative Server"
 .SH NAME
 zone2sql \- convert BIND zones to SQL
 .SH SYNOPSIS
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-4.9.4/ext/lmdb-safe/lmdb-safe.hh 
new/pdns-4.9.8/ext/lmdb-safe/lmdb-safe.hh
--- old/pdns-4.9.4/ext/lmdb-safe/lmdb-safe.hh   2025-02-06 16:17:38.000000000 
+0100
+++ new/pdns-4.9.8/ext/lmdb-safe/lmdb-safe.hh   2025-08-07 10:48:01.000000000 
+0200
@@ -12,6 +12,8 @@
 #include <mutex>
 #include <vector>
 #include <algorithm>
+#include <string>
+#include <string_view>
 
 #include "config.h"
 
@@ -24,6 +26,13 @@
 #endif
 
 using std::string_view;
+using std::string;
+
+#if BOOST_VERSION >= 106100
+#define StringView string_view
+#else
+#define StringView string
+#endif
 
 /* open issues:
  *
@@ -98,7 +107,7 @@
   std::map<std::thread::id, int> d_ROtransactionsOut;
 };
 
-std::shared_ptr<MDBEnv> getMDBEnv(const char* fname, int flags, int mode, 
uint64_t mapsizeMB=(sizeof(void *)==4) ? 100 : 16000);
+std::shared_ptr<MDBEnv> getMDBEnv(const char* fname, int flags, int mode, 
uint64_t mapsizeMB);
 
 #ifndef DNSDIST
 
@@ -300,6 +309,9 @@
     return ret;
   }
 
+  template <class T>
+  T get() const;
+
   operator MDB_val&()
   {
     return d_mdbval;
@@ -312,6 +324,12 @@
 #endif
 };
 
+template <>
+inline std::string MDBInVal::get<std::string>() const
+{
+  return {static_cast<char*>(d_mdbval.mv_data), d_mdbval.mv_size};
+}
+
 class MDBROCursor;
 
 class MDBROTransactionImpl
@@ -415,6 +433,7 @@
 private:
   std::vector<T*> *d_registry;
   MDB_cursor* d_cursor{nullptr};
+  std::string d_prefix{""};
 public:
   MDB_txn* d_txn{nullptr}; // ew, public
   uint64_t d_txtime{0};
@@ -523,6 +542,9 @@
 
     while (true) {
       auto sval = data.getNoStripHeader<std::string_view>();
+      if (d_prefix.length() > 0 && 
key.getNoStripHeader<StringView>().rfind(d_prefix, 0) != 0) {
+        return MDB_NOTFOUND;
+      }
 
       if (!LMDBLS::LSisDeleted(sval)) {
         // done!
@@ -573,6 +595,7 @@
 public:
   int get(MDBOutVal& key, MDBOutVal& data, MDB_cursor_op op)
   {
+    d_prefix.clear();
     int rc = mdb_cursor_get(d_cursor, &key.d_mdbval, &data.d_mdbval, op);
     if(rc && rc != MDB_NOTFOUND)
        throw std::runtime_error("Unable to get from cursor: " + 
std::string(mdb_strerror(rc)));
@@ -581,6 +604,7 @@
 
   int find(const MDBInVal& in, MDBOutVal& key, MDBOutVal& data)
   {
+    d_prefix.clear();
     key.d_mdbval = in.d_mdbval;
     int rc=mdb_cursor_get(d_cursor, const_cast<MDB_val*>(&key.d_mdbval), 
&data.d_mdbval, MDB_SET);
     if(rc && rc != MDB_NOTFOUND)
@@ -588,8 +612,20 @@
     return skipDeleted(key, data, MDB_SET, rc);
   }
 
+  int prefix(const MDBInVal& in, MDBOutVal& key, MDBOutVal& data)
+  {
+    d_prefix = in.get<string>();
+    return _lower_bound(in, key, data);
+  }
+
   int lower_bound(const MDBInVal& in, MDBOutVal& key, MDBOutVal& data)
   {
+    d_prefix.clear();
+    return _lower_bound(in, key, data);
+  }
+
+  int _lower_bound(const MDBInVal& in, MDBOutVal& key, MDBOutVal& data) // 
used by prefix() and lower_bound()
+  {
     key.d_mdbval = in.d_mdbval;
 
     int rc = mdb_cursor_get(d_cursor, const_cast<MDB_val*>(&key.d_mdbval), 
&data.d_mdbval, MDB_SET_RANGE);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-4.9.4/ext/lmdb-safe/lmdb-typed.hh 
new/pdns-4.9.8/ext/lmdb-safe/lmdb-typed.hh
--- old/pdns-4.9.4/ext/lmdb-safe/lmdb-typed.hh  2025-02-06 16:17:38.000000000 
+0100
+++ new/pdns-4.9.8/ext/lmdb-safe/lmdb-typed.hh  2025-08-07 10:48:01.000000000 
+0200
@@ -284,14 +284,19 @@
     // }
 
     //! Get item with id, from main table directly
-    bool get(uint32_t id, T& t)
+    int get2(uint32_t itemId, T& value)
     {
-      MDBOutVal data;
-      if((*d_parent.d_txn)->get(d_parent.d_parent->d_main, id, data))
-        return false;
-
-      serFromString(data.get<std::string>(), t);
-      return true;
+      MDBOutVal data{};
+      int rc;
+      rc = (*d_parent.d_txn)->get(d_parent.d_parent->d_main, itemId, data);
+      if (rc == 0) {
+        serFromString(data.get<std::string>(), value);
+      }
+      return rc;
+    }
+    bool get(uint32_t itemId, T& value)
+    {
+      return get2(itemId, value) == 0;
     }
 
     //! Get item through index N, then via the main database
@@ -309,17 +314,24 @@
       // because we know we only want one item, pass onlyOldest=true to 
consistently get the same one out of a set of duplicates
       get_multi<N>(key, ids, true);
 
-      if (ids.size() == 0) {
+      switch (ids.size()) {
+      case 0:
         return 0;
-      }
-
-      if (ids.size() == 1) {
-        if (get(ids[0], out)) {
+      case 1: {
+        auto rc = get2(ids[0], out);
+        if (rc == 0) {
           return ids[0];
         }
+        if (rc == MDB_NOTFOUND) {
+          /* element not present, or has been marked deleted */
+          return 0;
+        }
+        throw std::runtime_error("in index get, failed (" + std::to_string(rc) 
+ ")");
+        break;
+      }
+      default:
+        throw std::runtime_error("in index get, found more than one item");
       }
-
-      throw std::runtime_error("in index get, found more than one item");
     }
 
     // //! Cardinality of index N
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-4.9.4/modules/gmysqlbackend/smysql.cc 
new/pdns-4.9.8/modules/gmysqlbackend/smysql.cc
--- old/pdns-4.9.4/modules/gmysqlbackend/smysql.cc      2025-02-06 
16:17:38.000000000 +0100
+++ new/pdns-4.9.8/modules/gmysqlbackend/smysql.cc      2025-08-07 
10:48:01.000000000 +0200
@@ -116,7 +116,12 @@
       releaseStatement();
       throw SSqlException("Attempt to bind more parameters than query has: " + 
d_query);
     }
-    d_req_bind[d_paridx].buffer_type = MYSQL_TYPE_LONG;
+    if constexpr (sizeof(long) == 4) {
+      d_req_bind[d_paridx].buffer_type = MYSQL_TYPE_LONG; // 
NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
+    }
+    else {
+      d_req_bind[d_paridx].buffer_type = MYSQL_TYPE_LONGLONG; // 
NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
+    }
     d_req_bind[d_paridx].buffer = new long[1];
     *((long*)d_req_bind[d_paridx].buffer) = value;
     d_paridx++;
@@ -129,7 +134,12 @@
       releaseStatement();
       throw SSqlException("Attempt to bind more parameters than query has: " + 
d_query);
     }
-    d_req_bind[d_paridx].buffer_type = MYSQL_TYPE_LONG;
+    if constexpr (sizeof(long) == 4) {
+      d_req_bind[d_paridx].buffer_type = MYSQL_TYPE_LONG; // 
NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
+    }
+    else {
+      d_req_bind[d_paridx].buffer_type = MYSQL_TYPE_LONGLONG; // 
NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
+    }
     d_req_bind[d_paridx].buffer = new unsigned long[1];
     d_req_bind[d_paridx].is_unsigned = 1;
     *((unsigned long*)d_req_bind[d_paridx].buffer) = value;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-4.9.4/modules/lmdbbackend/lmdbbackend.cc 
new/pdns-4.9.8/modules/lmdbbackend/lmdbbackend.cc
--- old/pdns-4.9.4/modules/lmdbbackend/lmdbbackend.cc   2025-02-06 
16:17:38.000000000 +0100
+++ new/pdns-4.9.8/modules/lmdbbackend/lmdbbackend.cc   2025-08-07 
10:48:01.000000000 +0200
@@ -656,8 +656,6 @@
 
   string syncMode = toLower(getArg("sync-mode"));
 
-  d_random_ids = mustDo("random-ids");
-
   if (syncMode == "nosync")
     d_asyncFlag = MDB_NOSYNC;
   else if (syncMode == "nometasync")
@@ -667,17 +665,14 @@
   else
     throw std::runtime_error("Unknown sync mode " + syncMode + " requested for 
LMDB backend");
 
-  uint64_t mapSize = 0;
+  d_mapsize = 0;
   try {
-    mapSize = std::stoll(getArg("map-size"));
+    d_mapsize = std::stoll(getArg("map-size"));
   }
   catch (const std::exception& e) {
     throw std::runtime_error(std::string("Unable to parse the 'map-size' LMDB 
value: ") + e.what());
   }
 
-  LMDBLS::s_flag_deleted = mustDo("flag-deleted");
-  d_handle_dups = false;
-
   if (mustDo("lightning-stream")) {
     d_random_ids = true;
     d_handle_dups = true;
@@ -687,6 +682,11 @@
       throw std::runtime_error(std::string("running with Lightning Stream 
support requires shards=1"));
     }
   }
+  else {
+    d_random_ids = mustDo("random-ids");
+    d_handle_dups = false;
+    LMDBLS::s_flag_deleted = mustDo("flag-deleted");
+  }
 
   bool opened = false;
 
@@ -723,7 +723,7 @@
         throw std::runtime_error("Somehow, we are not at schema version 5. 
Giving up");
       }
 
-      d_tdomains = 
std::make_shared<tdomains_t>(getMDBEnv(getArg("filename").c_str(), MDB_NOSUBDIR 
| d_asyncFlag, 0600, mapSize), "domains_v5");
+      d_tdomains = 
std::make_shared<tdomains_t>(getMDBEnv(getArg("filename").c_str(), MDB_NOSUBDIR 
| d_asyncFlag, 0600, d_mapsize), "domains_v5");
       d_tmeta = std::make_shared<tmeta_t>(d_tdomains->getEnv(), "metadata_v5");
       d_tkdb = std::make_shared<tkdb_t>(d_tdomains->getEnv(), "keydata_v5");
       d_ttsig = std::make_shared<ttsig_t>(d_tdomains->getEnv(), "tsig_v5");
@@ -770,7 +770,7 @@
   }
 
   if (!opened) {
-    d_tdomains = 
std::make_shared<tdomains_t>(getMDBEnv(getArg("filename").c_str(), MDB_NOSUBDIR 
| d_asyncFlag, 0600, mapSize), "domains_v5");
+    d_tdomains = 
std::make_shared<tdomains_t>(getMDBEnv(getArg("filename").c_str(), MDB_NOSUBDIR 
| d_asyncFlag, 0600, d_mapsize), "domains_v5");
     d_tmeta = std::make_shared<tmeta_t>(d_tdomains->getEnv(), "metadata_v5");
     d_tkdb = std::make_shared<tkdb_t>(d_tdomains->getEnv(), "keydata_v5");
     d_ttsig = std::make_shared<ttsig_t>(d_tdomains->getEnv(), "tsig_v5");
@@ -1211,7 +1211,7 @@
   auto& shard = d_trecords[id % s_shards];
   if (!shard.env) {
     shard.env = getMDBEnv((getArg("filename") + "-" + std::to_string(id % 
s_shards)).c_str(),
-                          MDB_NOSUBDIR | d_asyncFlag, 0600);
+                          MDB_NOSUBDIR | d_asyncFlag, 0600, d_mapsize);
     shard.dbi = shard.env->openDB("records_v5", MDB_CREATE);
   }
   auto ret = 
std::make_shared<RecordsRWTransaction>(shard.env->getRWTransaction());
@@ -1228,7 +1228,7 @@
       throw DBException("attempting to start nested transaction without open 
parent env");
     }
     shard.env = getMDBEnv((getArg("filename") + "-" + std::to_string(id % 
s_shards)).c_str(),
-                          MDB_NOSUBDIR | d_asyncFlag, 0600);
+                          MDB_NOSUBDIR | d_asyncFlag, 0600, d_mapsize);
     shard.dbi = shard.env->openDB("records_v5", MDB_CREATE);
   }
 
@@ -1405,10 +1405,7 @@
   d_matchkey = co(di.id);
 
   MDBOutVal key, val;
-  auto a = d_getcursor->lower_bound(d_matchkey, key, val);
-  auto b0 = key.getNoStripHeader<StringView>();
-  auto b = b0.rfind(d_matchkey, 0);
-  if (a || b != 0) {
+  if (d_getcursor->prefix(d_matchkey, key, val) != 0) {
     d_getcursor.reset();
   }
 
@@ -1470,7 +1467,7 @@
     d_matchkey = co(zoneId, relqname, type.getCode());
   }
 
-  if (d_getcursor->lower_bound(d_matchkey, key, val) || 
key.getNoStripHeader<StringView>().rfind(d_matchkey, 0) != 0) {
+  if (d_getcursor->prefix(d_matchkey, key, val) != 0) {
     d_getcursor.reset();
     if (d_dolog) {
       g_log << Logger::Warning << "Query " << ((long)(void*)this) << ": " << 
d_dtime.udiffNoReset() << " us to execute (found nothing)" << endl;
@@ -1508,7 +1505,7 @@
 
       if (zr.dr.d_type == QType::NSEC3) {
         // Hit a magic NSEC3 skipping
-        if (d_getcursor->next(d_currentKey, d_currentVal) || 
d_currentKey.getNoStripHeader<StringView>().rfind(d_matchkey, 0) != 0) {
+        if (d_getcursor->next(d_currentKey, d_currentVal) != 0) {
           // cerr<<"resetting d_getcursor 1"<<endl;
           d_getcursor.reset();
         }
@@ -1516,6 +1513,7 @@
       }
 
       serFromString(d_currentVal.get<string_view>(), d_currentrrset);
+      d_currentrrsettime = 
static_cast<time_t>(LMDBLS::LSgetTimestamp(d_currentVal.getNoStripHeader<string_view>())
 / (1000UL * 1000UL * 1000UL));
       d_currentrrsetpos = 0;
     }
     else {
@@ -1536,7 +1534,7 @@
 
       if (d_currentrrsetpos >= d_currentrrset.size()) {
         d_currentrrset.clear(); // will invalidate lrr
-        if (d_getcursor->next(d_currentKey, d_currentVal) || 
d_currentKey.getNoStripHeader<StringView>().rfind(d_matchkey, 0) != 0) {
+        if (d_getcursor->next(d_currentKey, d_currentVal) != 0) {
           // cerr<<"resetting d_getcursor 2"<<endl;
           d_getcursor.reset();
         }
@@ -1570,6 +1568,7 @@
   rr.domain_id = zr.domain_id;
   rr.auth = zr.auth;
   rr.disabled = zr.disabled;
+  rr.last_modified = d_currentrrsettime;
 
   return true;
 }
@@ -2423,7 +2422,7 @@
 
   auto cursor = txn->txn->getCursor(txn->db->dbi);
   MDBOutVal key, val;
-  if (cursor.lower_bound(matchkey, key, val)) {
+  if (cursor.prefix(matchkey, key, val) != 0) {
     // cout << "Could not find anything"<<endl;
     return false;
   }
@@ -2431,7 +2430,7 @@
   bool hasOrderName = !ordername.empty();
   bool needNSEC3 = hasOrderName;
 
-  for (; key.getNoStripHeader<StringView>().rfind(matchkey, 0) == 0;) {
+  do {
     vector<LMDBResourceRecord> lrrs;
 
     if (co.getQType(key.getNoStripHeader<StringView>()) != QType::NSEC3) {
@@ -2456,9 +2455,7 @@
       }
     }
 
-    if (cursor.next(key, val))
-      break;
-  }
+  } while (cursor.next(key, val) == 0);
 
   bool del = false;
   LMDBResourceRecord lrr;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-4.9.4/modules/lmdbbackend/lmdbbackend.hh 
new/pdns-4.9.8/modules/lmdbbackend/lmdbbackend.hh
--- old/pdns-4.9.4/modules/lmdbbackend/lmdbbackend.hh   2025-02-06 
16:17:38.000000000 +0100
+++ new/pdns-4.9.8/modules/lmdbbackend/lmdbbackend.hh   2025-08-07 
10:48:01.000000000 +0200
@@ -323,6 +323,7 @@
 
   vector<LMDBResourceRecord> d_currentrrset;
   size_t d_currentrrsetpos;
+  time_t d_currentrrsettime;
   MDBOutVal d_currentKey;
   MDBOutVal d_currentVal;
   bool d_includedisabled;
@@ -333,4 +334,5 @@
   bool d_random_ids;
   bool d_handle_dups;
   DTime d_dtime; // used only for logging
+  uint64_t d_mapsize;
 };
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-4.9.4/pdns/api-swagger.json 
new/pdns-4.9.8/pdns/api-swagger.json
--- old/pdns-4.9.4/pdns/api-swagger.json        2025-02-06 16:18:33.000000000 
+0100
+++ new/pdns-4.9.8/pdns/api-swagger.json        2025-08-07 10:48:54.000000000 
+0200
@@ -2350,6 +2350,10 @@
         "disabled": {
           "type": "boolean",
           "description": "Whether or not this record is disabled. When unset, 
the record is not disabled"
+        },
+        "modified_at": {
+          "type": "integer",
+          "description": "Timestamp of the last change to the record"
         }
       }
     },
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-4.9.4/pdns/api-swagger.yaml 
new/pdns-4.9.8/pdns/api-swagger.yaml
--- old/pdns-4.9.4/pdns/api-swagger.yaml        2025-02-06 16:18:23.000000000 
+0100
+++ new/pdns-4.9.8/pdns/api-swagger.yaml        2025-08-07 10:48:45.000000000 
+0200
@@ -1110,6 +1110,9 @@
       disabled:
         type: boolean
         description: 'Whether or not this record is disabled. When unset, the 
record is not disabled'
+      modified_at:
+        type: integer
+        description: 'Timestamp of the last change to the record'
 
   Comment:
     title: Comment
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-4.9.4/pdns/credentials.hh 
new/pdns-4.9.8/pdns/credentials.hh
--- old/pdns-4.9.4/pdns/credentials.hh  2025-02-06 16:17:38.000000000 +0100
+++ new/pdns-4.9.8/pdns/credentials.hh  2025-08-07 10:48:01.000000000 +0200
@@ -21,7 +21,7 @@
  */
 #pragma once
 
-#include <memory>
+#include <cstdint>
 #include <string>
 
 class SensitiveData
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-4.9.4/pdns/dns.hh new/pdns-4.9.8/pdns/dns.hh
--- old/pdns-4.9.4/pdns/dns.hh  2025-02-06 16:17:38.000000000 +0100
+++ new/pdns-4.9.8/pdns/dns.hh  2025-08-07 10:48:01.000000000 +0200
@@ -77,7 +77,7 @@
 
   // Aligned on 8-byte boundaries on systems where time_t is 8 bytes and int
   // is 4 bytes, aka modern linux on x86_64
-  time_t last_modified{}; //!< For autocalculating SOA serial numbers - the 
backend needs to fill this in
+  time_t last_modified{}; //!< Timestamp of last update, if known by the 
backend
 
   uint32_t ttl{}; //!< Time To Live of this record
   uint32_t signttl{}; //!< If non-zero, use this TTL as original TTL in the 
RRSIG
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-4.9.4/pdns/dnssecinfra.cc 
new/pdns-4.9.8/pdns/dnssecinfra.cc
--- old/pdns-4.9.4/pdns/dnssecinfra.cc  2025-02-06 16:17:38.000000000 +0100
+++ new/pdns-4.9.8/pdns/dnssecinfra.cc  2025-08-07 10:48:02.000000000 +0200
@@ -782,7 +782,7 @@
   DNSPacketWriter dw(signVect, DNSName(), 0);
   auto pos=signVect.size();
   if(!timersonly) {
-    dw.xfrName(tsigKeyName, false);
+    dw.xfrName(tsigKeyName.makeLowerCase(), false);
     dw.xfr16BitInt(QClass::ANY); // class
     dw.xfr32BitInt(0);    // TTL
     dw.xfrName(trc.d_algoName.makeLowerCase(), false);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-4.9.4/pdns/lua-record.cc 
new/pdns-4.9.8/pdns/lua-record.cc
--- old/pdns-4.9.4/pdns/lua-record.cc   2025-02-06 16:17:38.000000000 +0100
+++ new/pdns-4.9.8/pdns/lua-record.cc   2025-08-07 10:48:02.000000000 +0200
@@ -915,81 +915,87 @@
       return std::string("error");
     });
   lua.writeFunction("createForward", []() {
-      static string allZerosIP("0.0.0.0");
-      DNSName rel=s_lua_record_ctx->qname.makeRelative(s_lua_record_ctx->zone);
-      // parts is something like ["1", "2", "3", "4", "static"] or
-      // ["1", "2", "3", "4"] or ["ip40414243", "ip-addresses", ...]
-      auto parts = rel.getRawLabels();
-      // Yes, this still breaks if an 1-2-3-4.XXXX is nested too deeply...
-      if(parts.size()>=4) {
-        try {
-          ComboAddress ca(parts[0]+"."+parts[1]+"."+parts[2]+"."+parts[3]);
-          return ca.toString();
-        } catch (const PDNSException &e) {
-          return allZerosIP;
-        }
-      } else if (!parts.empty()) {
-        auto& input = parts.at(0);
-
-        // allow a word without - in front, as long as it does not contain 
anything that could be a number
-        size_t nonhexprefix = strcspn(input.c_str(), "0123456789abcdefABCDEF");
-        if (nonhexprefix > 0) {
-          input = input.substr(nonhexprefix);
-        }
-
-        // either hex string, or 12-13-14-15
-        vector<string> ip_parts;
-
-        stringtok(ip_parts, input, "-");
-        unsigned int x1, x2, x3, x4;
-        if (ip_parts.size() >= 4) {
-          // 1-2-3-4 with any prefix (e.g. ip-foo-bar-1-2-3-4)
-          string ret;
-          for (size_t index=4; index > 0; index--) {
-            auto octet = ip_parts[ip_parts.size() - index];
-            try {
-              auto octetVal = std::stol(octet);
+      static string allZerosIP{"0.0.0.0"};
+      try {
+        DNSName 
rel{s_lua_record_ctx->qname.makeRelative(s_lua_record_ctx->zone)};
+
+        // parts is something like ["1", "2", "3", "4", "static"] or
+        // ["1", "2", "3", "4"] or ["ip40414243", "ip-addresses", ...]
+        auto parts = rel.getRawLabels();
+        // Yes, this still breaks if an 1-2-3-4.XXXX is nested too deeply...
+        if (parts.size() >= 4) {
+          ComboAddress 
address(parts[0]+"."+parts[1]+"."+parts[2]+"."+parts[3]);
+          return address.toString();
+        }
+       if (!parts.empty()) {
+          auto& input = parts.at(0);
+
+          // allow a word without - in front, as long as it does not contain 
anything that could be a number
+          size_t nonhexprefix = strcspn(input.c_str(), 
"0123456789abcdefABCDEF");
+          if (nonhexprefix > 0) {
+            input = input.substr(nonhexprefix);
+          }
+
+          // either hex string, or 12-13-14-15
+          vector<string> ip_parts;
+
+          stringtok(ip_parts, input, "-");
+          if (ip_parts.size() >= 4) {
+            // 1-2-3-4 with any prefix (e.g. ip-foo-bar-1-2-3-4)
+            string ret;
+            for (size_t index=4; index > 0; index--) {
+              auto octet = ip_parts.at(ip_parts.size() - index);
+              auto octetVal = std::stol(octet); // may throw
               if (octetVal >= 0 && octetVal <= 255) {
-                ret += ip_parts.at(ip_parts.size() - index) + ".";
+                ret += octet + ".";
               } else {
                 return allZerosIP;
               }
-            } catch (const std::exception &e) {
-              return allZerosIP;
             }
+            ret.resize(ret.size() - 1); // remove trailing dot after last octet
+            return ret;
           }
-          ret.resize(ret.size() - 1); // remove trailing dot after last octet
-          return ret;
-        }
-        if(input.length() >= 8) {
-          auto last8 = input.substr(input.length()-8);
-          if(sscanf(last8.c_str(), "%02x%02x%02x%02x", &x1, &x2, &x3, &x4)==4) 
{
-            return std::to_string(x1) + "." + std::to_string(x2) + "." + 
std::to_string(x3) + "." + std::to_string(x4);
+          if (input.length() >= 8) {
+            auto last8 = input.substr(input.length()-8);
+            unsigned int part1{0};
+            unsigned int part2{0};
+            unsigned int part3{0};
+            unsigned int part4{0};
+            if (sscanf(last8.c_str(), "%02x%02x%02x%02x", &part1, &part2, 
&part3, &part4) == 4) {
+              ComboAddress address(std::to_string(part1) + "." + 
std::to_string(part2) + "." + std::to_string(part3) + "." + 
std::to_string(part4));
+              return address.toString();
+            }
           }
         }
+        return allZerosIP;
+      } catch (const PDNSException &e) {
+        return allZerosIP;
       }
-      return allZerosIP;
     });
 
   lua.writeFunction("createForward6", []() {
-      DNSName rel=s_lua_record_ctx->qname.makeRelative(s_lua_record_ctx->zone);
-      auto parts = rel.getRawLabels();
-      if(parts.size()==8) {
-        string tot;
-        for(int i=0; i<8; ++i) {
-          if(i)
-            tot.append(1,':');
-          tot+=parts[i];
+      static string allZerosIP{"::"};
+      try {
+        DNSName 
rel{s_lua_record_ctx->qname.makeRelative(s_lua_record_ctx->zone)};
+
+        auto parts = rel.getRawLabels();
+        if (parts.size() == 8) {
+          string tot;
+          for (int chunk = 0; chunk < 8; ++chunk) {
+            if (chunk != 0) {
+              tot.append(1, ':');
+             }
+            tot += parts.at(chunk);
+          }
+          ComboAddress address(tot);
+          return address.toString();
         }
-        ComboAddress ca(tot);
-        return ca.toString();
-      }
-      else if(parts.size()==1) {
-        if (parts[0].find('-') != std::string::npos) {
-          boost::replace_all(parts[0],"-",":");
-          ComboAddress ca(parts[0]);
-          return ca.toString();
-        } else {
+        if (parts.size() == 1) {
+          if (parts[0].find('-') != std::string::npos) {
+            std::replace(parts[0].begin(), parts[0].end(), '-', ':');
+            ComboAddress address(parts[0]);
+            return address.toString();
+          }
           if (parts[0].size() >= 32) {
             auto ippart = parts[0].substr(parts[0].size()-32);
             auto fulladdress =
@@ -1002,57 +1008,63 @@
               ippart.substr(24, 4) + ":" +
               ippart.substr(28, 4);
 
-            ComboAddress ca(fulladdress);
-            return ca.toString();
+            ComboAddress address(fulladdress);
+            return address.toString();
           }
         }
+        return allZerosIP;
+      } catch (const PDNSException &e) {
+        return allZerosIP;
       }
-
-      return std::string("::");
     });
-  lua.writeFunction("createReverse6", [](string format, 
boost::optional<std::unordered_map<string,string>> e){
+  lua.writeFunction("createReverse6", [](const string &format, 
boost::optional<std::unordered_map<string,string>> excp){
       vector<ComboAddress> candidates;
 
       try {
         auto labels= s_lua_record_ctx->qname.getRawLabels();
-        if(labels.size()<32)
+        if (labels.size()<32) {
           return std::string("unknown");
+       }
         boost::format fmt(format);
         fmt.exceptions( boost::io::all_error_bits ^ ( 
boost::io::too_many_args_bit | boost::io::too_few_args_bit )  );
 
 
         string together;
         vector<string> quads;
-        for(int i=0; i<8; ++i) {
-          if(i)
-            together+=":";
+        for (int chunk = 0; chunk < 8; ++chunk) {
+          if (chunk != 0) {
+            together += ":";
+         }
           string lquad;
-          for(int j=0; j <4; ++j) {
-            lquad.append(1, labels[31-i*4-j][0]);
-            together += labels[31-i*4-j][0];
+          for (int quartet = 0; quartet < 4; ++quartet) {
+            lquad.append(1, labels[31 - chunk * 4 - quartet][0]);
+            together += labels[31 - chunk * 4 - quartet][0];
           }
           quads.push_back(lquad);
         }
-        ComboAddress ip6(together,0);
+       ComboAddress ip6(together,0);
 
-        if(e) {
-          auto& addrs=*e;
+       if (excp) {
+          auto& addrs=*excp;
           for(const auto& addr: addrs) {
             // this makes sure we catch all forms of the address
-            if(ComboAddress(addr.first,0)==ip6)
+            if (ComboAddress(addr.first, 0) == ip6) {
               return addr.second;
+           }
           }
         }
 
         string dashed=ip6.toString();
         boost::replace_all(dashed, ":", "-");
 
-        for(int i=31; i>=0; --i)
-          fmt % labels[i];
+        for (int byte = 31; byte >= 0; --byte) {
+          fmt % labels[byte];
+       }
         fmt % dashed;
 
-        for(const auto& lquad : quads)
+        for(const auto& lquad : quads) {
           fmt % lquad;
+       }
 
         return fmt.str();
       }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-4.9.4/pdns/test-tsig.cc 
new/pdns-4.9.8/pdns/test-tsig.cc
--- old/pdns-4.9.4/pdns/test-tsig.cc    2025-02-06 16:17:38.000000000 +0100
+++ new/pdns-4.9.8/pdns/test-tsig.cc    2025-08-07 10:48:02.000000000 +0200
@@ -141,6 +141,17 @@
   checkTSIG(tsigName, tsigAlgo.makeLowerCase(), tsigSecret, packet);
 }
 
+BOOST_AUTO_TEST_CASE(test_TSIG_different_case_name) {
+  DNSName tsigName("tsig.Name");
+  DNSName tsigAlgo("HMAC-MD5.SIG-ALG.REG.INT");
+  DNSName qname("test.valid.tsig");
+  string tsigSecret("verysecret");
+
+  vector<uint8_t> packet = generateTSIGQuery(qname, tsigName, tsigAlgo, 
tsigSecret);
+
+  checkTSIG(tsigName.makeLowerCase(), tsigAlgo.makeLowerCase(), tsigSecret, 
packet);
+}
+
 BOOST_AUTO_TEST_CASE(test_TSIG_different_name_same_algo) {
   DNSName tsigName("tsig.name");
   DNSName tsigAlgo("HMAC-MD5.SIG-ALG.REG.INT");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pdns-4.9.4/pdns/ws-auth.cc 
new/pdns-4.9.8/pdns/ws-auth.cc
--- old/pdns-4.9.4/pdns/ws-auth.cc      2025-02-06 16:17:38.000000000 +0100
+++ new/pdns-4.9.8/pdns/ws-auth.cc      2025-08-07 10:48:02.000000000 +0200
@@ -523,9 +523,13 @@
 
       while (rit != records.end() && rit->qname == current_qname && rit->qtype 
== current_qtype) {
         ttl = min(ttl, rit->ttl);
-        rrset_records.push_back(Json::object{
+        auto object = Json::object{
           {"disabled", rit->disabled},
-          {"content", makeApiRecordContent(rit->qtype, rit->content)}});
+          {"content", makeApiRecordContent(rit->qtype, rit->content)}};
+        if (rit->last_modified != 0) {
+          object["modified_at"] = (double)rit->last_modified;
+        }
+        rrset_records.push_back(object);
         rit++;
       }
       while (cit != comments.end() && cit->qname == current_qname && 
cit->qtype == current_qtype) {
@@ -2578,6 +2582,9 @@
         {"ttl", (double)resourceRecord.ttl},
         {"disabled", resourceRecord.disabled},
         {"content", makeApiRecordContent(resourceRecord.qtype, 
resourceRecord.content)}};
+      if (resourceRecord.last_modified != 0) {
+        object["modified_at"] = (double)resourceRecord.last_modified;
+      }
 
       val = zoneIdZone.find(resourceRecord.domain_id);
       if (val != zoneIdZone.end()) {

Reply via email to