From: Peter van Dijk Date: Thu, 19 Jun 2025 19:15:04 +0000 (+0200) Subject: lmdb createDomain: provide initial ID seed X-Git-Tag: dnsdist-2.1.0-alpha0~6^2~10 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=03c5499bf1f5d56e3ef82aab095ece4a135383d4;p=thirdparty%2Fpdns.git lmdb createDomain: provide initial ID seed --- diff --git a/ext/lmdb-safe/lmdb-typed.cc b/ext/lmdb-safe/lmdb-typed.cc index ff63ea8f2c..3d40bad782 100644 --- a/ext/lmdb-safe/lmdb-typed.cc +++ b/ext/lmdb-safe/lmdb-typed.cc @@ -13,10 +13,10 @@ uint32_t MDBGetMaxID(MDBRWTransaction& txn, MDBDbi& dbi) return maxid; } -uint32_t MDBGetRandomID(MDBRWTransaction& txn, MDBDbi& dbi) +uint32_t MDBGetRandomID(MDBRWTransaction& txn, MDBDbi& dbi, uint32_t seed) { auto cursor = txn->getRWCursor(dbi); - uint32_t newID = 0; + uint32_t newID = seed & ~(1 << 31); for (int attempts = 0; attempts < 20; attempts++) { MDBOutVal key{}; MDBOutVal content{}; @@ -24,7 +24,9 @@ uint32_t MDBGetRandomID(MDBRWTransaction& txn, MDBDbi& dbi) // dns_random generates a random number in [0..signed_int_max-1]. We add 1 to avoid 0 // and allow type_max. 0 is avoided because the put() interface uses it to mean // "please allocate a number for me". - newID = dns_random(std::numeric_limits::max()) + 1; + if (seed == 0 || attempts > 0) { + newID = dns_random(std::numeric_limits::max()) + 1; + } if (cursor.find(MDBInVal(newID), key, content) != 0) { return newID; } diff --git a/ext/lmdb-safe/lmdb-typed.hh b/ext/lmdb-safe/lmdb-typed.hh index 4cdcb4efaf..355d4ecc04 100644 --- a/ext/lmdb-safe/lmdb-typed.hh +++ b/ext/lmdb-safe/lmdb-typed.hh @@ -41,7 +41,7 @@ uint32_t MDBGetMaxID(MDBRWTransaction& txn, MDBDbi& dbi); * Return a randomly generated ID that is unique and not zero. May throw if the database * is very full. */ -uint32_t MDBGetRandomID(MDBRWTransaction& txn, MDBDbi& dbi); +uint32_t MDBGetRandomID(MDBRWTransaction& txn, MDBDbi& dbi, uint32_t seed=0); /** * This is our serialization interface. It can be specialized for other types. @@ -765,12 +765,12 @@ public: } // insert something, with possibly a specific id - uint32_t put(const T& value, uint32_t itemId, bool random_ids=false) + uint32_t put(const T& value, uint32_t itemId, bool random_ids=false, uint32_t seed=0) { int flags = 0; if(itemId == 0) { if(random_ids) { - itemId = MDBGetRandomID(*d_txn, d_parent->d_main); + itemId = MDBGetRandomID(*d_txn, d_parent->d_main, seed); } else { itemId = MDBGetMaxID(*d_txn, d_parent->d_main) + 1; diff --git a/modules/lmdbbackend/lmdbbackend.cc b/modules/lmdbbackend/lmdbbackend.cc index 77e498dfff..55f698b3b4 100644 --- a/modules/lmdbbackend/lmdbbackend.cc +++ b/modules/lmdbbackend/lmdbbackend.cc @@ -1954,7 +1954,7 @@ bool LMDBBackend::createDomain(const ZoneName& domain, const DomainInfo::DomainK di.primaries = primaries; di.account = account; - txn.put(di, 0, d_random_ids); + txn.put(di, 0, d_random_ids, domain.hash()); txn.commit(); } diff --git a/regression-tests/tests/pdnsutil-zone-handling/command b/regression-tests/tests/pdnsutil-zone-handling/command index 8cc389df78..9aa474e6e6 100755 --- a/regression-tests/tests/pdnsutil-zone-handling/command +++ b/regression-tests/tests/pdnsutil-zone-handling/command @@ -34,6 +34,9 @@ pdnsutil_wrapper rrset delete ${ZONE} no ANY # Display zone contents for final verification pdnsutil_wrapper zone list ${ZONE} | LC_ALL=C sort +# Only for LMDB, check predictable zone ID +[ $backend = lmdb ] && pdnsutil_wrapper -v zone show ${ZONE} + # Delete this non-standard zone, so that the result of the zone-variants # test do not vary if this particular test is skipped. pdnsutil_wrapper zone delete ${ZONE} > /dev/null diff --git a/regression-tests/tests/pdnsutil-zone-handling/expected_result.lmdb b/regression-tests/tests/pdnsutil-zone-handling/expected_result.lmdb new file mode 100644 index 0000000000..61792a2e9f --- /dev/null +++ b/regression-tests/tests/pdnsutil-zone-handling/expected_result.lmdb @@ -0,0 +1,26 @@ +New rrset: +cname.bug.less. 3600 IN CNAME host +New rrset: +host.bug.less. 3600 IN A 127.0.0.1 +Ignoring duplicate record content "127.0.0.2" +New rrset: +host2.bug.less. 3600 IN A 127.0.0.2 +Attempting to add record to cname.bug.less which already has a CNAME record +Attempting to add CNAME to host.bug.less which already has existing records +New rrset: +host2.bug.less. 3600 IN A 127.0.0.2 +host2.bug.less. 3600 IN A 127.0.0.3 +New rrset: +no.bug.less. 3600 IN A 1.2.3.4 +New rrset: +no.bug.less. 3600 IN TXT "insert your favorite zen quote here" +$ORIGIN . +bug.less 3600 IN SOA a.misconfigured.dns.server.invalid hostmaster.bug.less 0 10800 3600 604800 3600 +cname.bug.less 3600 IN CNAME host. +host.bug.less 3600 IN A 127.0.0.1 +host2.bug.less 3600 IN A 127.0.0.2 +host2.bug.less 3600 IN A 127.0.0.3 +This is a Native zone (936255546) +Zone is not actively secured +Metadata items: None +No keys for zone 'bug.less'.