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?

Cheers

> 
> 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