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