Cointrol: tags -1 - moreinfo

(I hope untagging is the right thing to do)


* Sebastian Ramacher <sramac...@debian.org> [250708 08:02]:
Control: tags -1 moreinfo

On 2025-07-07 18:01:12 +0200, Chris Hofstädtler wrote:
Package: release.debian.org
Severity: normal
X-Debbugs-Cc: p...@packages.debian.org
Control: affects -1 + src:pdns
User: release.debian....@packages.debian.org
Usertags: unblock

Please unblock package pdns

pdns 4.9.7 is an upstream bugfix release in the 4.9 series.
Previously we had 4.9.4; upstream released 4.9.5 (after the freeze
started) and 4.9.7 (today) - 4.9.6 was skipped.

Is there a summary of the changes from 4.9.4 to 4.9.7 somewhere? Or
could you provide a short summary of those changes?

Yes:

https://doc.powerdns.com/authoritative/changelog/4.9.html

4.9.5:

Improvements
- Faster LMDB list/lookup/get operations

Bug Fixes
- Correctly handle marked-as-deleted elements in LMDB read-only queries
- Fix MySQL operation on 64-bit big-endian platforms
  [zeha: this is our previously applied patch]
- Fix incorrect behaviour of Lua createForward and createForward6 functions leading to possible SERVFAIL answers, when processing certain data.

4.9.6:
not released

4.9.7:

Bug Fixes
- compilation fix: Include cstdint to get uint64_t
- auth docker: avoid crash on –version caused by doubly loaded modules
  [zeha: does not affect the release tarball]
- TSIG payload: use canonical (lowercase) name format
- LMDB: honour map-size for all files
- Close race window during which LMDB lightning stream flag values might be 
incorrect


Hope this helps,
Chris


I'd like to take the latest upstream release into unstable and
testing. Have not uploaded it yet.

[ Reason ]
Accepting the upstream bugfix release will hopefully make applying
future security fixes easier, or we can just use a future bugfix
release for them.

4.9.5 includes the patch we applied to 4.9.4 to fix tests on s390x.

[ Impact ]
If we stay on 4.9.4, the diff for security fixes will be larger and
thus harder.
We'll also miss out on upstream bug- and performance-fixes to the LMDB
backend, better exception handling in Lua functions leading to
SERVFAILs, an interop fix for TSIG and a compile fix for newer gcc.

[ Tests ]
In Debian we only have smoke tests, however they did find the s390x
mysql issue in the past. Upstream has a big test suite they run for
releases.

[ Risks ]
Not sure. The diff seems right to me for the fixes upstream
described.

[ Checklist ]
  [x] all changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [x] attach debdiff against the package in testing

[ Other info ]

The attached debdiff was produced using:
  debdiff pdns_4.9.4-2.dsc pdns_4.9.7-1.dsc | filterdiff -x '*.1' > 
pdns_4.9.7-1.filtered.debdiff
to exclude the date changes to the xxx.1 manpages.

unblock pdns/4.9.7-1

diff -Nru pdns-4.9.4/configure pdns-4.9.7/configure
--- pdns-4.9.4/configure        2025-02-06 16:18:00.000000000 +0100
+++ pdns-4.9.7/configure        2025-07-07 09:42:38.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.7.
 #
 #
 # 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.7'
+PACKAGE_STRING='pdns 4.9.7'
 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.7 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.7:";;
    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.7
 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.7, 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.7'


 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.7, 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.7
 configured by $0, generated by GNU Autoconf 2.71,
   with options \\"\$ac_cs_config\\"

diff -Nru pdns-4.9.4/configure.ac pdns-4.9.7/configure.ac
--- pdns-4.9.4/configure.ac     2025-02-06 16:17:52.000000000 +0100
+++ pdns-4.9.7/configure.ac     2025-07-07 09:42:29.000000000 +0200
@@ -1,6 +1,6 @@
 AC_PREREQ([2.69])

-AC_INIT([pdns], [4.9.4])
+AC_INIT([pdns], [4.9.7])
 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 -Nru pdns-4.9.4/debian/changelog pdns-4.9.7/debian/changelog
--- pdns-4.9.4/debian/changelog 2025-03-21 13:09:53.000000000 +0100
+++ pdns-4.9.7/debian/changelog 2025-07-07 12:15:52.000000000 +0200
@@ -1,3 +1,10 @@
+pdns (4.9.7-1) unstable; urgency=medium
+
+  * New upstream version 4.9.7
+  * Drop upstream-applied patch
+
+ -- Chris Hofstaedtler <z...@debian.org>  Mon, 07 Jul 2025 12:15:52 +0200
+
 pdns (4.9.4-2) unstable; urgency=medium

   * Add upstream-pending patch to fix mysqlbackend on s390x
diff -Nru pdns-4.9.4/debian/patches/series pdns-4.9.7/debian/patches/series
--- pdns-4.9.4/debian/patches/series    2025-03-21 13:09:34.000000000 +0100
+++ pdns-4.9.7/debian/patches/series    2025-07-07 12:15:39.000000000 +0200
@@ -1 +0,0 @@
-upstream/0001-mysql-use-MYSQL_TYPE_LONGLONG-on-64bit-platforms.patch
diff -Nru 
pdns-4.9.4/debian/patches/upstream/0001-mysql-use-MYSQL_TYPE_LONGLONG-on-64bit-platforms.patch
 
pdns-4.9.7/debian/patches/upstream/0001-mysql-use-MYSQL_TYPE_LONGLONG-on-64bit-platforms.patch
--- 
pdns-4.9.4/debian/patches/upstream/0001-mysql-use-MYSQL_TYPE_LONGLONG-on-64bit-platforms.patch
      2025-03-21 13:09:34.000000000 +0100
+++ 
pdns-4.9.7/debian/patches/upstream/0001-mysql-use-MYSQL_TYPE_LONGLONG-on-64bit-platforms.patch
      1970-01-01 01:00:00.000000000 +0100
@@ -1,43 +0,0 @@
-From: Chris Hofstaedtler <chris.hofstaedt...@deduktiva.com>
-Date: Fri, 21 Mar 2025 12:54:21 +0100
-Subject: mysql: use MYSQL_TYPE_LONGLONG on 64bit platforms
-
-Found on s390x.
-
-https://github.com/PowerDNS/pdns/pull/15340/
----
- modules/gmysqlbackend/smysql.cc | 14 ++++++++++++--
- 1 file changed, 12 insertions(+), 2 deletions(-)
-
-diff --git a/modules/gmysqlbackend/smysql.cc b/modules/gmysqlbackend/smysql.cc
-index efcbffd..4cc7856 100644
---- a/modules/gmysqlbackend/smysql.cc
-+++ b/modules/gmysqlbackend/smysql.cc
-@@ -116,7 +116,12 @@ public:
-       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;
-+    }
-+    else {
-+      d_req_bind[d_paridx].buffer_type = MYSQL_TYPE_LONGLONG;
-+    }
-     d_req_bind[d_paridx].buffer = new long[1];
-     *((long*)d_req_bind[d_paridx].buffer) = value;
-     d_paridx++;
-@@ -129,7 +134,12 @@ public:
-       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;
-+    }
-+    else {
-+      d_req_bind[d_paridx].buffer_type = MYSQL_TYPE_LONGLONG;
-+    }
-     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 -Nru pdns-4.9.4/docs/ixfrdist.yml.5 pdns-4.9.7/docs/ixfrdist.yml.5
--- pdns-4.9.4/docs/ixfrdist.yml.5      2025-02-06 16:19:08.000000000 +0100
+++ pdns-4.9.7/docs/ixfrdist.yml.5      2025-07-07 09:43:48.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" "Jul 07, 2025" "" "PowerDNS Authoritative Server"
 .SH NAME
 ixfrdist.yml \- The ixfrdist configuration file
 .SH SYNOPSIS
diff -Nru pdns-4.9.4/ext/lmdb-safe/lmdb-safe.hh 
pdns-4.9.7/ext/lmdb-safe/lmdb-safe.hh
--- pdns-4.9.4/ext/lmdb-safe/lmdb-safe.hh       2025-02-06 16:17:38.000000000 
+0100
+++ pdns-4.9.7/ext/lmdb-safe/lmdb-safe.hh       2025-07-07 09:42:15.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 -Nru pdns-4.9.4/ext/lmdb-safe/lmdb-typed.hh 
pdns-4.9.7/ext/lmdb-safe/lmdb-typed.hh
--- pdns-4.9.4/ext/lmdb-safe/lmdb-typed.hh      2025-02-06 16:17:38.000000000 
+0100
+++ pdns-4.9.7/ext/lmdb-safe/lmdb-typed.hh      2025-07-07 09:42:15.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 -Nru pdns-4.9.4/modules/gmysqlbackend/smysql.cc 
pdns-4.9.7/modules/gmysqlbackend/smysql.cc
--- pdns-4.9.4/modules/gmysqlbackend/smysql.cc  2025-02-06 16:17:38.000000000 
+0100
+++ pdns-4.9.7/modules/gmysqlbackend/smysql.cc  2025-07-07 09:42:15.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 -Nru pdns-4.9.4/modules/lmdbbackend/lmdbbackend.cc 
pdns-4.9.7/modules/lmdbbackend/lmdbbackend.cc
--- pdns-4.9.4/modules/lmdbbackend/lmdbbackend.cc       2025-02-06 
16:17:38.000000000 +0100
+++ pdns-4.9.7/modules/lmdbbackend/lmdbbackend.cc       2025-07-07 
09:42:15.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();
         }
@@ -1536,7 +1533,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();
         }
@@ -2423,7 +2420,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 +2428,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 +2453,7 @@
       }
     }

-    if (cursor.next(key, val))
-      break;
-  }
+  } while (cursor.next(key, val) == 0);

   bool del = false;
   LMDBResourceRecord lrr;
diff -Nru pdns-4.9.4/modules/lmdbbackend/lmdbbackend.hh 
pdns-4.9.7/modules/lmdbbackend/lmdbbackend.hh
--- pdns-4.9.4/modules/lmdbbackend/lmdbbackend.hh       2025-02-06 
16:17:38.000000000 +0100
+++ pdns-4.9.7/modules/lmdbbackend/lmdbbackend.hh       2025-07-07 
09:42:15.000000000 +0200
@@ -333,4 +333,5 @@
   bool d_random_ids;
   bool d_handle_dups;
   DTime d_dtime; // used only for logging
+  uint64_t d_mapsize;
 };
diff -Nru pdns-4.9.4/pdns/credentials.hh pdns-4.9.7/pdns/credentials.hh
--- pdns-4.9.4/pdns/credentials.hh      2025-02-06 16:17:38.000000000 +0100
+++ pdns-4.9.7/pdns/credentials.hh      2025-07-07 09:42:15.000000000 +0200
@@ -21,7 +21,7 @@
  */
 #pragma once

-#include <memory>
+#include <cstdint>
 #include <string>

 class SensitiveData
diff -Nru pdns-4.9.4/pdns/dnssecinfra.cc pdns-4.9.7/pdns/dnssecinfra.cc
--- pdns-4.9.4/pdns/dnssecinfra.cc      2025-02-06 16:17:38.000000000 +0100
+++ pdns-4.9.7/pdns/dnssecinfra.cc      2025-07-07 09:42:15.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 -Nru pdns-4.9.4/pdns/lua-record.cc pdns-4.9.7/pdns/lua-record.cc
--- pdns-4.9.4/pdns/lua-record.cc       2025-02-06 16:17:38.000000000 +0100
+++ pdns-4.9.7/pdns/lua-record.cc       2025-07-07 09:42:15.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 -Nru pdns-4.9.4/pdns/test-tsig.cc pdns-4.9.7/pdns/test-tsig.cc
--- pdns-4.9.4/pdns/test-tsig.cc        2025-02-06 16:17:38.000000000 +0100
+++ pdns-4.9.7/pdns/test-tsig.cc        2025-07-07 09:42:15.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");


--
Sebastian Ramacher

Reply via email to