]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
lmdb createDomain: provide initial ID seed
authorPeter van Dijk <peter.van.dijk@powerdns.com>
Thu, 19 Jun 2025 19:15:04 +0000 (21:15 +0200)
committerPeter van Dijk <peter.van.dijk@powerdns.com>
Fri, 20 Jun 2025 09:50:41 +0000 (11:50 +0200)
ext/lmdb-safe/lmdb-typed.cc
ext/lmdb-safe/lmdb-typed.hh
modules/lmdbbackend/lmdbbackend.cc
regression-tests/tests/pdnsutil-zone-handling/command
regression-tests/tests/pdnsutil-zone-handling/expected_result.lmdb [new file with mode: 0644]

index ff63ea8f2c8f80eb2a364159358d5b9e450c5d97..3d40bad7826930f3b5c1849ce9387e2543a7a18c 100644 (file)
@@ -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<signed int>::max()) + 1;
+    if (seed == 0 || attempts > 0) {
+      newID = dns_random(std::numeric_limits<signed int>::max()) + 1;
+    }
     if (cursor.find(MDBInVal(newID), key, content) != 0) {
       return newID;
     }
index 4cdcb4efaffd3313db722d2f1979b380980c32c0..355d4ecc0474f4cd890bdd2000b806722cb0aa2a 100644 (file)
@@ -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;
index 77e498dfffbc4e8d1468eab19b31e9020db7cc05..55f698b3b4fa846193df668a839ed1656d6f8fe9 100644 (file)
@@ -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();
   }
 
index 8cc389df7893ec24734aa965d40ebd6a40fda55b..9aa474e6e6d3a60813b6d2cce8d0a033872663eb 100755 (executable)
@@ -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 (file)
index 0000000..61792a2
--- /dev/null
@@ -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'.