]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
rec: make sure RPZs serial and its soa serial are consistent
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Thu, 21 Nov 2024 09:27:29 +0000 (10:27 +0100)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Thu, 21 Nov 2024 09:27:29 +0000 (10:27 +0100)
Also give a better error message when our serial is higher than the auth one

Fixes #14857

pdns/ixfr.cc
pdns/recursordist/filterpo.hh
pdns/recursordist/rpzloader.cc

index 09d5d9a9f21585aa91506daa38e20b4bd2fa62a9..93404f15d76af7f1f418a5d34b7747b180352235 100644 (file)
@@ -272,6 +272,10 @@ vector<pair<vector<DNSRecord>, vector<DNSRecord>>> getIXFRDeltas(const ComboAddr
           // we are up to date
           return ret;
         }
+        if(soaRecord->d_st.serial < getRR<SOARecordContent>(oursr)->d_st.serial) {
+          // we have a higher SOA than the auth? Should not happen, but what can we do?
+          throw std::runtime_error("Our serial is higher than remote one for zone '" + zone.toLogString() + "' from primary '" + primary.toStringWithPort() + "': ours " + std::to_string(getRR<SOARecordContent>(oursr)->d_st.serial) + " theirs " + std::to_string(soaRecord->d_st.serial));
+        }
         primarySOA = std::move(soaRecord);
         ++primarySOACount;
       } else if (r.d_type == QType::SOA) {
index fbd14c1d76d0328e63c65870f3e36e7cda606eb3..1daea4b99ee300f78d46fbbc19ee1354f62b9c6e 100644 (file)
@@ -374,6 +374,10 @@ public:
     {
       return d_serial;
     }
+    [[nodiscard]] const DNSRecord& getSOA() const
+    {
+      return d_zoneData->d_soa;
+    }
 
     [[nodiscard]] size_t size() const
     {
index 09792e92ee63c324db390600da69bede1b5b1943..6af30447dcec1496180d4fd164f24f8466ed8da1 100644 (file)
@@ -382,6 +382,19 @@ std::shared_ptr<const SOARecordContent> loadRPZFromFile(const std::string& fname
 static bool dumpZoneToDisk(Logr::log_t logger, const std::shared_ptr<DNSFilterEngine::Zone>& newZone, const std::string& dumpZoneFileName)
 {
   logger->info(Logr::Debug, "Dumping zone to disk", "destination_file", Logging::Loggable(dumpZoneFileName));
+  DNSRecord soa = newZone->getSOA();
+  uint32_t serial = 0;
+  DNSName zone;
+  if (auto soaContent = getRR<SOARecordContent>(soa)) {
+    serial = soaContent->d_st.serial;
+  }
+  if (newZone->getSerial() != serial) {
+    logger->info(Logr::Error, "Inconsistency of internal serial and SOA serial", "serial", Logging::Loggable(newZone->getSerial()), "soaserial", Logging::Loggable(serial));
+  }
+
+  if (newZone->getDomain() != soa.d_name) {
+    logger->info(Logr::Error, "Inconsistency of internal name and SOA name", "zone", Logging::Loggable(newZone->getDomain()), "soaname", Logging::Loggable(soa.d_name));
+  }
   std::string temp = dumpZoneFileName + "XXXXXX";
   int fileDesc = mkstemp(&temp.at(0));
   if (fileDesc < 0) {
@@ -621,8 +634,10 @@ static bool RPZTrackerIteration(RPZTrackerParams& params, const DNSName& zoneNam
           continue;
         }
         if (resourceRecord.d_type == QType::SOA) {
-          auto tempSR = getRR<SOARecordContent>(resourceRecord);
-          if (tempSR) {
+          if (auto tempSR = getRR<SOARecordContent>(resourceRecord)) {
+            dnsRecord = resourceRecord;
+            // IXFR leaves us a relative name, fix that
+            dnsRecord.d_name = newZone->getDomain();
             currentSR = std::move(tempSR);
           }
         }
@@ -637,6 +652,7 @@ static bool RPZTrackerIteration(RPZTrackerParams& params, const DNSName& zoneNam
 
     /* only update sr now that all changes have been converted */
     if (currentSR) {
+      newZone->setSOA(dnsRecord);
       params.zoneXFRParams.soaRecordContent = std::move(currentSR);
     }
     SLOG(g_log << Logger::Info << "Had " << totremove << " RPZ removal" << addS(totremove) << ", " << totadd << " addition" << addS(totadd) << " for " << zoneName << " New serial: " << params.soaRecordContent->d_st.serial << endl,