Skip to content

Commit

Permalink
rec: make sure RPZs serial and its soa serial are consistent
Browse files Browse the repository at this point in the history
Also give a better error message when our serial is higher than the auth one

Fixes #14857
  • Loading branch information
omoerbeek committed Nov 21, 2024
1 parent b476fe1 commit 66f7b4b
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 2 deletions.
4 changes: 4 additions & 0 deletions pdns/ixfr.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
4 changes: 4 additions & 0 deletions pdns/recursordist/filterpo.hh
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,10 @@ public:
{
return d_serial;
}
[[nodiscard]] const DNSRecord& getSOA() const
{
return d_zoneData->d_soa;
}

[[nodiscard]] size_t size() const
{
Expand Down
20 changes: 18 additions & 2 deletions pdns/recursordist/rpzloader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
}
}
Expand All @@ -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,
Expand Down

0 comments on commit 66f7b4b

Please sign in to comment.