]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Factor code responsible for filling DomainInfo. NFC yet.
authorMiod Vallat <miod.vallat@powerdns.com>
Mon, 15 Sep 2025 10:09:00 +0000 (12:09 +0200)
committerMiod Vallat <miod.vallat@powerdns.com>
Mon, 22 Sep 2025 12:05:52 +0000 (14:05 +0200)
Signed-off-by: Miod Vallat <miod.vallat@powerdns.com>
(cherry picked from commit 7c5d7af8ba785c99021a78b229f89ea6ad652170)

modules/lmdbbackend/lmdbbackend.cc
modules/lmdbbackend/lmdbbackend.hh

index ec014ffb283f2de3381739ccdb25cbf463c8ecf5..07441464c1b5f6b22ed1bdc80a72b32decccca07 100644 (file)
@@ -1002,6 +1002,27 @@ void LMDBBackend::deleteDomainRecords(RecordsRWTransaction& txn, uint32_t domain
   }
 }
 
+bool LMDBBackend::findDomain(const DNSName& domain, DomainInfo& info)
+{
+  auto rotxn = d_tdomains->getROTransaction();
+  auto domain_id = rotxn.get<0>(domain, info);
+  if (domain_id == 0) {
+    return false;
+  }
+  info.id = static_cast<uint32_t>(domain_id);
+  return true;
+}
+
+bool LMDBBackend::findDomain(uint32_t domainid, DomainInfo& info)
+{
+  auto rotxn = d_tdomains->getROTransaction();
+  if (!rotxn.get(domainid, info)) {
+    return false;
+  }
+  info.id = domainid;
+  return true;
+}
+
 /* Here's the complicated story. Other backends have just one transaction, which is either
    on or not.
 
@@ -1019,12 +1040,11 @@ bool LMDBBackend::startTransaction(const DNSName& domain, int domain_id)
   // cout <<"startTransaction("<<domain<<", "<<domain_id<<")"<<endl;
   int real_id = domain_id;
   if (real_id < 0) {
-    auto rotxn = d_tdomains->getROTransaction();
-    DomainInfo di;
-    real_id = rotxn.get<0>(domain, di);
-    // cout<<"real_id = "<<real_id << endl;
-    if (!real_id)
+    DomainInfo info;
+    if (!findDomain(domain, info)) {
       return false;
+    }
+    real_id = static_cast<int>(info.id);
   }
   if (d_rwtxn) {
     throw DBException("Attempt to start a transaction while one was open already");
@@ -1167,15 +1187,15 @@ bool LMDBBackend::replaceRRSet(uint32_t domain_id, const DNSName& qname, const Q
     needCommit = true;
   }
 
-  DomainInfo di;
-  if (!d_tdomains->getROTransaction().get(domain_id, di)) {
+  DomainInfo info;
+  if (!findDomain(domain_id, info)) {
     return false;
   }
 
   compoundOrdername co;
   auto cursor = txn->txn->getCursor(txn->db->dbi);
   MDBOutVal key, val;
-  string match = co(domain_id, qname.makeRelative(di.zone), qt.getCode());
+  string match = co(domain_id, qname.makeRelative(info.zone), qt.getCode());
   if (!cursor.find(match, key, val)) {
     cursor.del();
   }
@@ -1185,7 +1205,7 @@ bool LMDBBackend::replaceRRSet(uint32_t domain_id, const DNSName& qname, const Q
     for (const auto& rr : rrset) {
       LMDBResourceRecord lrr(rr);
       lrr.content = serializeContent(lrr.qtype.getCode(), lrr.qname, lrr.content);
-      lrr.qname.makeUsRelative(di.zone);
+      lrr.qname.makeUsRelative(info.zone);
 
       adjustedRRSet.emplace_back(lrr);
     }
@@ -1324,10 +1344,10 @@ bool LMDBBackend::deleteDomain(const DNSName& domain)
 
   if (!d_handle_dups) {
     // get domain id
-    auto txn = d_tdomains->getROTransaction();
-
-    DomainInfo di;
-    idvec.push_back(txn.get<0>(domain, di));
+    DomainInfo info;
+    if (findDomain(domain, info)) {
+      idvec.push_back(info.id);
+    }
   }
   else {
     // this transaction used to be RO.
@@ -1386,23 +1406,18 @@ bool LMDBBackend::list(const DNSName& target, int /* id */, bool include_disable
 {
   d_includedisabled = include_disabled;
 
-  DomainInfo di;
-  {
-    auto dtxn = d_tdomains->getROTransaction();
-    if ((di.id = dtxn.get<0>(target, di))) {
-      // cerr << "Found domain " << target << " on domain_id " << di.id << ", list requested " << id << endl;
-    }
-    else {
-      // cerr << "Did not find " << target << endl;
-      return false;
-    }
+  DomainInfo info;
+  if (!findDomain(target, info)) {
+    // cerr << "Did not find " << target << endl;
+    return false;
   }
+  // cerr << "Found domain " << target << " on domain_id " << info.id << ", list requested " << id << endl;
 
-  d_rotxn = getRecordsROTransaction(di.id, d_rwtxn);
+  d_rotxn = getRecordsROTransaction(info.id, d_rwtxn);
   d_getcursor = std::make_shared<MDBROCursor>(d_rotxn->txn->getCursor(d_rotxn->db->dbi));
 
   compoundOrdername co;
-  d_matchkey = co(di.id);
+  d_matchkey = co(info.id);
 
   MDBOutVal key, val;
   if (d_getcursor->prefix(d_matchkey, key, val) != 0) {
@@ -1428,26 +1443,26 @@ void LMDBBackend::lookup(const QType& type, const DNSName& qdomain, int zoneId,
   d_includedisabled = false;
 
   DNSName hunt(qdomain);
-  DomainInfo di;
+  DomainInfo info;
   if (zoneId < 0) {
-    auto rotxn = d_tdomains->getROTransaction();
-
     do {
-      zoneId = rotxn.get<0>(hunt, di);
-    } while (!zoneId && type != QType::SOA && hunt.chopOff());
-    if (zoneId <= 0) {
+      if (findDomain(hunt, info)) {
+        break;
+      }
+    } while (type != QType::SOA && hunt.chopOff());
+    if (info.id <= 0) {
       //      cout << "Did not find zone for "<< qdomain<<endl;
       d_getcursor.reset();
       return;
     }
   }
   else {
-    if (!d_tdomains->getROTransaction().get(zoneId, di)) {
+    if (!findDomain(zoneId, info)) {
       // cout<<"Could not find a zone with id "<<zoneId<<endl;
       d_getcursor.reset();
       return;
     }
-    hunt = di.zone;
+    hunt = info.zone;
   }
 
   DNSName relqname = qdomain.makeRelative(hunt);
@@ -1455,16 +1470,16 @@ void LMDBBackend::lookup(const QType& type, const DNSName& qdomain, int zoneId,
     return;
   }
   // cout<<"get will look for "<<relqname<< " in zone "<<hunt<<" with id "<<zoneId<<" and type "<<type.toString()<<endl;
-  d_rotxn = getRecordsROTransaction(zoneId, d_rwtxn);
+  d_rotxn = getRecordsROTransaction(info.id, d_rwtxn);
 
   compoundOrdername co;
   d_getcursor = std::make_shared<MDBROCursor>(d_rotxn->txn->getCursor(d_rotxn->db->dbi));
   MDBOutVal key, val;
   if (type.getCode() == QType::ANY) {
-    d_matchkey = co(zoneId, relqname);
+    d_matchkey = co(info.id, relqname);
   }
   else {
-    d_matchkey = co(zoneId, relqname, type.getCode());
+    d_matchkey = co(info.id, relqname, type.getCode());
   }
 
   if (d_getcursor->prefix(d_matchkey, key, val) != 0) {
@@ -1595,27 +1610,10 @@ bool LMDBBackend::getSerial(DomainInfo& di)
 
 bool LMDBBackend::getDomainInfo(const DNSName& domain, DomainInfo& di, bool getserial)
 {
-  {
-    auto txn = d_tdomains->getROTransaction();
-    // auto range = txn.prefix_range<0>(domain);
-
-    // bool found = false;
-
-    // for (auto& iter = range.first ; iter != range.second; ++iter) {
-    //   found = true;
-    //   di.id = iter.getID();
-    //   di.backend = this;
-    // }
-
-    // if (!found) {
-    //   return false;
-    // }
-    if (!(di.id = txn.get<0>(domain, di))) {
-      return false;
-    }
-
-    di.backend = this;
+  if (!findDomain(domain, di)) {
+    return false;
   }
+  di.backend = this;
 
   if (getserial) {
     getSerial(di);
@@ -1626,31 +1624,26 @@ bool LMDBBackend::getDomainInfo(const DNSName& domain, DomainInfo& di, bool gets
 
 int LMDBBackend::genChangeDomain(const DNSName& domain, const std::function<void(DomainInfo&)>& func)
 {
+  DomainInfo info;
+  if (!findDomain(domain, info)) {
+    return static_cast<int>(false);
+  }
+  func(info);
   auto txn = d_tdomains->getRWTransaction();
-
-  DomainInfo di;
-
-  auto id = txn.get<0>(domain, di);
-  func(di);
-  txn.put(di, id);
-
+  txn.put(info, info.id);
   txn.commit();
   return true;
 }
 
 int LMDBBackend::genChangeDomain(uint32_t id, const std::function<void(DomainInfo&)>& func)
 {
-  DomainInfo di;
-
+  DomainInfo info;
+  if (!findDomain(id, info)) {
+    return static_cast<int>(false);
+  }
+  func(info);
   auto txn = d_tdomains->getRWTransaction();
-
-  if (!txn.get(id, di))
-    return false;
-
-  func(di);
-
-  txn.put(di, id);
-
+  txn.put(info, id);
   txn.commit();
   return true;
 }
@@ -1678,20 +1671,20 @@ bool LMDBBackend::setPrimaries(const DNSName& domain, const vector<ComboAddress>
 
 bool LMDBBackend::createDomain(const DNSName& domain, const DomainInfo::DomainKind kind, const vector<ComboAddress>& primaries, const string& account)
 {
-  DomainInfo di;
+  DomainInfo info;
 
+  if (findDomain(domain, info)) {
+    throw DBException("Domain '" + domain.toLogString() + "' exists already");
+  }
   {
     auto txn = d_tdomains->getRWTransaction();
-    if (txn.get<0>(domain, di)) {
-      throw DBException("Domain '" + domain.toLogString() + "' exists already");
-    }
 
-    di.zone = domain;
-    di.kind = kind;
-    di.primaries = primaries;
-    di.account = account;
+    info.zone = domain;
+    info.kind = kind;
+    info.primaries = primaries;
+    info.account = account;
 
-    txn.put(di, 0, d_random_ids);
+    txn.put(info, 0, d_random_ids);
     txn.commit();
   }
 
@@ -1716,18 +1709,13 @@ void LMDBBackend::getAllDomainsFiltered(vector<DomainInfo>* domains, const std::
     }
 
     for (const auto& zone : dups) {
-      DomainInfo di;
-
+      DomainInfo info;
       // this get grabs the oldest item if there are duplicates
-      di.id = txn.get<0>(zone, di);
-
-      if (di.id == 0) {
-        // .get actually found nothing for us
+      if (!findDomain(zone, info)) {
         continue;
       }
-
-      di.backend = this;
-      zonemap[di.zone] = di;
+      info.backend = this;
+      zonemap[info.zone] = info;
     }
 
     for (auto& [k, v] : zonemap) {
@@ -1838,8 +1826,8 @@ void LMDBBackend::getUpdatedPrimaries(vector<DomainInfo>& updatedDomains, std::u
 
 void LMDBBackend::setNotified(uint32_t domain_id, uint32_t serial)
 {
-  genChangeDomain(domain_id, [serial](DomainInfo& di) {
-    di.notified_serial = serial;
+  genChangeDomain(domain_id, [serial](DomainInfo& info) {
+    info.notified_serial = serial;
   });
 }
 
@@ -2052,16 +2040,17 @@ bool LMDBBackend::unpublishDomainKey(const DNSName& name, unsigned int id)
   return true;
 }
 
+// NOLINTNEXTLINE(readability-function-cognitive-complexity)
 bool LMDBBackend::getBeforeAndAfterNamesAbsolute(uint32_t id, const DNSName& qname, DNSName& unhashed, DNSName& before, DNSName& after)
 {
   //  cout << __PRETTY_FUNCTION__<< ": "<<id <<", "<<qname << " " << unhashed<<endl;
 
-  DomainInfo di;
-  if (!d_tdomains->getROTransaction().get(id, di)) {
+  DomainInfo info;
+  if (!findDomain(id, info)) {
     // domain does not exist, tough luck
     return false;
   }
-  // cout <<"Zone: "<<di.zone<<endl;
+  // cout <<"Zone: "<<info.zone<<endl;
 
   compoundOrdername co;
   auto txn = getRecordsROTransaction(id);
@@ -2095,7 +2084,7 @@ bool LMDBBackend::getBeforeAndAfterNamesAbsolute(uint32_t id, const DNSName& qna
       }
     }
     before = co.getQName(key.getNoStripHeader<StringView>());
-    unhashed = DNSName(lrr.content.c_str(), lrr.content.size(), 0, false) + di.zone;
+    unhashed = DNSName(lrr.content.c_str(), lrr.content.size(), 0, false) + info.zone;
 
     // now to find after .. at the beginning of the zone
     if (cursor.lower_bound(co(id), key, val)) {
@@ -2193,7 +2182,7 @@ bool LMDBBackend::getBeforeAndAfterNamesAbsolute(uint32_t id, const DNSName& qna
           }
         }
         before = co.getQName(key.getNoStripHeader<StringView>());
-        unhashed = DNSName(lrr.content.c_str(), lrr.content.size(), 0, false) + di.zone;
+        unhashed = DNSName(lrr.content.c_str(), lrr.content.size(), 0, false) + info.zone;
         // cout <<"Should still find 'after'!"<<endl;
         // for 'after', we need to find the first hash of this zone
 
@@ -2223,7 +2212,7 @@ bool LMDBBackend::getBeforeAndAfterNamesAbsolute(uint32_t id, const DNSName& qna
       ++count;
     }
     before = co.getQName(key.getNoStripHeader<StringView>());
-    unhashed = DNSName(lrr.content.c_str(), lrr.content.size(), 0, false) + di.zone;
+    unhashed = DNSName(lrr.content.c_str(), lrr.content.size(), 0, false) + info.zone;
     // cout<<"Went backwards, found "<<before<<endl;
     // return us to starting point
     while (count--)
@@ -2409,13 +2398,13 @@ bool LMDBBackend::updateDNSSECOrderNameAndAuth(uint32_t domain_id, const DNSName
     needCommit = true;
   }
 
-  DomainInfo di;
-  if (!d_tdomains->getROTransaction().get(domain_id, di)) {
+  DomainInfo info;
+  if (!findDomain(domain_id, info)) {
     //    cout<<"Could not find domain_id "<<domain_id <<endl;
     return false;
   }
 
-  DNSName rel = qname.makeRelative(di.zone);
+  DNSName rel = qname.makeRelative(info.zone);
 
   compoundOrdername co;
   string matchkey = co(domain_id, rel);
@@ -2518,21 +2507,21 @@ bool LMDBBackend::updateEmptyNonTerminals(uint32_t domain_id, set<DNSName>& inse
     needCommit = true;
   }
 
+  DomainInfo info;
+  if (!findDomain(domain_id, info)) {
+    // cout <<"No such domain with id "<<domain_id<<endl;
+    return false;
+  }
+
   // if remove is set, all ENTs should be removed & nothing else should be done
   if (remove) {
     deleteDomainRecords(*txn, domain_id, 0);
   }
   else {
-    DomainInfo di;
-    auto rotxn = d_tdomains->getROTransaction();
-    if (!rotxn.get(domain_id, di)) {
-      // cout <<"No such domain with id "<<domain_id<<endl;
-      return false;
-    }
     compoundOrdername co;
     for (const auto& n : insert) {
       LMDBResourceRecord lrr;
-      lrr.qname = n.makeRelative(di.zone);
+      lrr.qname = n.makeRelative(info.zone);
       lrr.ttl = 0;
       lrr.auth = true;
 
@@ -2544,7 +2533,7 @@ bool LMDBBackend::updateEmptyNonTerminals(uint32_t domain_id, set<DNSName>& inse
     }
     for (auto n : erase) {
       // cout <<" -"<<n<<endl;
-      n.makeUsRelative(di.zone);
+      n.makeUsRelative(info.zone);
       txn->txn->del(txn->db->dbi, co(domain_id, n, 0));
     }
   }
index f5c7123d54c16a7d402d444095e7f0a69a65ce40..71cf8e2bbd01f7963c465e99dcc9e159f373c134 100644 (file)
@@ -310,6 +310,9 @@ private:
   int genChangeDomain(uint32_t id, const std::function<void(DomainInfo&)>& func);
   void deleteDomainRecords(RecordsRWTransaction& txn, uint32_t domain_id, uint16_t qtype = QType::ANY);
 
+  bool findDomain(const DNSName& domain, DomainInfo& info);
+  bool findDomain(uint32_t domainid, DomainInfo& info);
+
   void getAllDomainsFiltered(vector<DomainInfo>* domains, const std::function<bool(DomainInfo&)>& allow);
 
   bool getSerial(DomainInfo& di);