From: Otto Moerbeek Date: Thu, 21 Nov 2024 09:27:29 +0000 (+0100) Subject: rec: make sure RPZs serial and its soa serial are consistent X-Git-Tag: rec-5.2.0-beta1~7^2~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=66f7b4bc2500cf4fa0e3826b023e24a209be290a;p=thirdparty%2Fpdns.git rec: make sure RPZs serial and its soa serial are consistent Also give a better error message when our serial is higher than the auth one Fixes #14857 --- diff --git a/pdns/ixfr.cc b/pdns/ixfr.cc index 09d5d9a9f2..93404f15d7 100644 --- a/pdns/ixfr.cc +++ b/pdns/ixfr.cc @@ -272,6 +272,10 @@ vector, vector>> getIXFRDeltas(const ComboAddr // we are up to date return ret; } + if(soaRecord->d_st.serial < getRR(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(oursr)->d_st.serial) + " theirs " + std::to_string(soaRecord->d_st.serial)); + } primarySOA = std::move(soaRecord); ++primarySOACount; } else if (r.d_type == QType::SOA) { diff --git a/pdns/recursordist/filterpo.hh b/pdns/recursordist/filterpo.hh index fbd14c1d76..1daea4b99e 100644 --- a/pdns/recursordist/filterpo.hh +++ b/pdns/recursordist/filterpo.hh @@ -374,6 +374,10 @@ public: { return d_serial; } + [[nodiscard]] const DNSRecord& getSOA() const + { + return d_zoneData->d_soa; + } [[nodiscard]] size_t size() const { diff --git a/pdns/recursordist/rpzloader.cc b/pdns/recursordist/rpzloader.cc index 09792e92ee..6af30447dc 100644 --- a/pdns/recursordist/rpzloader.cc +++ b/pdns/recursordist/rpzloader.cc @@ -382,6 +382,19 @@ std::shared_ptr loadRPZFromFile(const std::string& fname static bool dumpZoneToDisk(Logr::log_t logger, const std::shared_ptr& 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(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(resourceRecord); - if (tempSR) { + if (auto tempSR = getRR(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,