From: Otto Moerbeek Date: Fri, 27 Sep 2024 12:11:44 +0000 (+0200) Subject: Refactor XFR parameters of RPZParams out X-Git-Tag: rec-5.2.0-alpha1~7^2~20 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a344d15f25906914c964a17fd813540018911e80;p=thirdparty%2Fpdns.git Refactor XFR parameters of RPZParams out --- diff --git a/pdns/recursordist/Makefile.am b/pdns/recursordist/Makefile.am index fe71369ee7..6f90adc1d5 100644 --- a/pdns/recursordist/Makefile.am +++ b/pdns/recursordist/Makefile.am @@ -198,6 +198,7 @@ pdns_recursor_SOURCES = \ rec-tcounters.cc rec-tcounters.hh \ rec-tcp.cc \ rec-tcpout.cc rec-tcpout.hh \ + rec-xfr.cc rec-xfr.hh \ rec-zonetocache.cc rec-zonetocache.hh \ rec_channel.cc rec_channel.hh rec_metrics.hh \ rec_channel_rec.cc \ @@ -330,6 +331,7 @@ testrunner_SOURCES = \ rec-system-resolve.hh rec-system-resolve.cc \ rec-taskqueue.cc rec-taskqueue.hh \ rec-tcounters.cc rec-tcounters.hh \ + rec-xfr.cc rec-xfr.hh \ rec-zonetocache.cc rec-zonetocache.hh \ recpacketcache.cc recpacketcache.hh \ recursor_cache.cc recursor_cache.hh \ diff --git a/pdns/recursordist/pdns_recursor.cc b/pdns/recursordist/pdns_recursor.cc index 9bd39a7f54..251b06c87e 100644 --- a/pdns/recursordist/pdns_recursor.cc +++ b/pdns/recursordist/pdns_recursor.cc @@ -2393,7 +2393,7 @@ static string* doProcessUDPQuestion(const std::string& question, const ComboAddr SLOG(g_log << Logger::Notice << RecThreadInfo::id() << " got NOTIFY for " << qname.toLogString() << " from " << source.toStringWithPort() << (source != fromaddr ? " (via " + fromaddr.toStringWithPort() + ")" : "") << endl, g_slogudpin->info(Logr::Notice, "Got NOTIFY", "source", Logging::Loggable(source), "remote", Logging::Loggable(fromaddr), "qname", Logging::Loggable(qname))); } - if (!notifyRPZTracker(qname)) { + if (!notifyZoneTracker(qname)) { // It wasn't an RPZ requestWipeCaches(qname); } diff --git a/pdns/recursordist/rec-lua-conf.cc b/pdns/recursordist/rec-lua-conf.cc index bd838f846f..ba915adeb9 100644 --- a/pdns/recursordist/rec-lua-conf.cc +++ b/pdns/recursordist/rec-lua-conf.cc @@ -132,7 +132,7 @@ static void parseRPZParameters(const rpzOptions_t& have, RPZTrackerParams& param params.maxTTL = boost::get(have.at("maxTTL")); } if (have.count("zoneSizeHint") != 0) { - params.zoneSizeHint = static_cast(boost::get(have.at("zoneSizeHint"))); + params.zoneXFRParams.zoneSizeHint = static_cast(boost::get(have.at("zoneSizeHint"))); } if (have.count("tags") != 0) { const auto& tagsTable = boost::get>>(have.at("tags")); @@ -273,16 +273,16 @@ static void parseFrameStreamOptions(const boost::optional& static void rpzPrimary(LuaConfigItems& lci, const boost::variant>>& primaries_, const string& zoneName, const boost::optional& options) { RPZTrackerParams params; - params.name = zoneName; + params.zoneXFRParams.name = zoneName; params.polName = zoneName; std::shared_ptr zone = std::make_shared(); if (primaries_.type() == typeid(string)) { - params.primaries.emplace_back(boost::get(primaries_), 53); + params.zoneXFRParams.primaries.emplace_back(boost::get(primaries_), 53); } else { for (const auto& primary : boost::get>>(primaries_)) { - params.primaries.emplace_back(primary.second, 53); + params.zoneXFRParams.primaries.emplace_back(primary.second, 53); } } @@ -292,9 +292,9 @@ static void rpzPrimary(LuaConfigItems& lci, const boost::variant(have.at("tsigname")))); - params.tsigtriplet.algo = DNSName(toLower(boost::get(have.at("tsigalgo")))); - if (B64Decode(boost::get(have.at("tsigsecret")), params.tsigtriplet.secret) != 0) { + params.zoneXFRParams.tsigtriplet.name = DNSName(toLower(boost::get(have.at("tsigname")))); + params.zoneXFRParams.tsigtriplet.algo = DNSName(toLower(boost::get(have.at("tsigalgo")))); + if (B64Decode(boost::get(have.at("tsigsecret")), params.zoneXFRParams.tsigtriplet.secret) != 0) { throw std::runtime_error("TSIG secret is not valid Base-64 encoded"); } } @@ -307,15 +307,15 @@ static void rpzPrimary(LuaConfigItems& lci, const boost::variant(boost::get(have.at("maxReceivedMBytes"))); + params.zoneXFRParams.maxReceivedMBytes = static_cast(boost::get(have.at("maxReceivedMBytes"))); } if (have.count("localAddress") != 0) { - params.localAddress = ComboAddress(boost::get(have.at("localAddress"))); + params.zoneXFRParams.localAddress = ComboAddress(boost::get(have.at("localAddress"))); } if (have.count("axfrTimeout") != 0) { - params.xfrTimeout = static_cast(boost::get(have.at("axfrTimeout"))); + params.zoneXFRParams.xfrTimeout = static_cast(boost::get(have.at("axfrTimeout"))); } if (have.count("seedFile") != 0) { @@ -327,11 +327,11 @@ static void rpzPrimary(LuaConfigItems& lci, const boost::variantwriteFunction("rpzFile", [&lci](const string& filename, boost::optional options) { RPZTrackerParams params; - params.name = filename; + params.zoneXFRParams.name = filename; params.polName = "rpzFile"; if (options) { parseRPZParameters(*options, params); diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index ab33fbc447..f20c17736e 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -2875,7 +2875,7 @@ static void recursorThread() checkFrameStreamExport(luaconfsLocal, luaconfsLocal->nodFrameStreamExportConfig, t_nodFrameStreamServersInfo); #endif for (const auto& rpz : luaconfsLocal->rpzs) { - string name = rpz.polName.empty() ? (rpz.primaries.empty() ? "rpzFile" : rpz.name) : rpz.polName; + string name = rpz.polName.empty() ? (rpz.zoneXFRParams.primaries.empty() ? "rpzFile" : rpz.zoneXFRParams.name) : rpz.polName; t_Counters.at(rec::PolicyNameHits::policyName).counts[name] = 0; } } @@ -3405,7 +3405,7 @@ struct WipeCacheResult wipeCaches(const DNSName& canon, bool subtree, uint16_t q void startLuaConfigDelayedThreads(const vector& rpzs, uint64_t generation) { for (const auto& rpzPrimary : rpzs) { - if (rpzPrimary.primaries.empty()) { + if (rpzPrimary.zoneXFRParams.primaries.empty()) { continue; } try { @@ -3437,13 +3437,13 @@ static void* pleaseInitPolCounts(const string& name) static bool activateRPZFile(const RPZTrackerParams& params, LuaConfigItems& lci, shared_ptr& zone) { - auto log = lci.d_slog->withValues("file", Logging::Loggable(params.name)); + auto log = lci.d_slog->withValues("file", Logging::Loggable(params.zoneXFRParams.name)); zone->setName(params.polName.empty() ? "rpzFile" : params.polName); try { SLOG(g_log << Logger::Warning << "Loading RPZ from file '" << params.name << "'" << endl, log->info(Logr::Info, "Loading RPZ from file")); - loadRPZFromFile(params.name, zone, params.defpol, params.defpolOverrideLocal, params.maxTTL); + loadRPZFromFile(params.zoneXFRParams.name, zone, params.defpol, params.defpolOverrideLocal, params.maxTTL); SLOG(g_log << Logger::Warning << "Done loading RPZ from file '" << params.name << "'" << endl, log->info(Logr::Info, "Done loading RPZ from file")); } @@ -3458,20 +3458,20 @@ static bool activateRPZFile(const RPZTrackerParams& params, LuaConfigItems& lci, static void activateRPZPrimary(RPZTrackerParams& params, LuaConfigItems& lci, shared_ptr& zone, const DNSName& domain) { - auto log = lci.d_slog->withValues("seedfile", Logging::Loggable(params.seedFileName), "zone", Logging::Loggable(params.name)); + auto log = lci.d_slog->withValues("seedfile", Logging::Loggable(params.seedFileName), "zone", Logging::Loggable(params.zoneXFRParams.name)); if (!params.seedFileName.empty()) { SLOG(g_log << Logger::Info << "Pre-loading RPZ zone " << params.name << " from seed file '" << params.seedFileName << "'" << endl, log->info(Logr::Info, "Pre-loading RPZ zone from seed file")); try { - params.soaRecordContent = loadRPZFromFile(params.seedFileName, zone, params.defpol, params.defpolOverrideLocal, params.maxTTL); + params.zoneXFRParams.soaRecordContent = loadRPZFromFile(params.seedFileName, zone, params.defpol, params.defpolOverrideLocal, params.maxTTL); if (zone->getDomain() != domain) { - throw PDNSException("The RPZ zone " + params.name + " loaded from the seed file (" + zone->getDomain().toString() + ") does not match the one passed in parameter (" + domain.toString() + ")"); + throw PDNSException("The RPZ zone " + params.zoneXFRParams.name + " loaded from the seed file (" + zone->getDomain().toString() + ") does not match the one passed in parameter (" + domain.toString() + ")"); } - if (params.soaRecordContent == nullptr) { - throw PDNSException("The RPZ zone " + params.name + " loaded from the seed file (" + zone->getDomain().toString() + ") has no SOA record"); + if (params.zoneXFRParams.soaRecordContent == nullptr) { + throw PDNSException("The RPZ zone " + params.zoneXFRParams.name + " loaded from the seed file (" + zone->getDomain().toString() + ") has no SOA record"); } } catch (const PDNSException& e) { @@ -3491,8 +3491,8 @@ static void activateRPZs(LuaConfigItems& lci) { for (auto& params : lci.rpzs) { auto zone = std::make_shared(); - if (params.zoneSizeHint != 0) { - zone->reserve(params.zoneSizeHint); + if (params.zoneXFRParams.zoneSizeHint != 0) { + zone->reserve(params.zoneXFRParams.zoneSizeHint); } if (!params.tags.empty()) { std::unordered_set tags; @@ -3511,15 +3511,15 @@ static void activateRPZs(LuaConfigItems& lci) zone->setIncludeSOA(params.includeSOA); zone->setIgnoreDuplicates(params.ignoreDuplicates); - if (params.primaries.empty()) { + if (params.zoneXFRParams.primaries.empty()) { if (activateRPZFile(params, lci, zone)) { lci.dfe.addZone(zone); } } else { - DNSName domain(params.name); + DNSName domain(params.zoneXFRParams.name); zone->setDomain(domain); - zone->setName(params.polName.empty() ? params.name : params.polName); + zone->setName(params.polName.empty() ? params.zoneXFRParams.name : params.polName); params.zoneIdx = lci.dfe.addZone(zone); activateRPZPrimary(params, lci, zone, domain); } diff --git a/pdns/recursordist/rec-xfr.cc b/pdns/recursordist/rec-xfr.cc new file mode 100644 index 0000000000..6ef1435df5 --- /dev/null +++ b/pdns/recursordist/rec-xfr.cc @@ -0,0 +1,66 @@ +/* + * This file is part of PowerDNS or dnsdist. + * Copyright -- PowerDNS.COM B.V. and its contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * In addition, for the avoidance of any doubt, permission is granted to + * link this program with OpenSSL and to (re)distribute the binaries + * produced as the result of such linking. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "rec-xfr.hh" +#include "lock.hh" + +// As there can be multiple threads doing updates (due to config reloads), we use a multimap. +// The value contains the actual thread id that owns the struct. + +static LockGuarded> condVars; + +// Notify all threads tracking the RPZ name +bool notifyZoneTracker(const DNSName& name) +{ + auto lock = condVars.lock(); + auto [start, end] = lock->equal_range(name); + if (start == end) { + // Did not find any thread tracking that name + return false; + } + while (start != end) { + start->second.stop = true; + start->second.condVar.notify_one(); + ++start; + } + return true; +} + +void insertZoneTracker(const DNSName& zoneName, ZoneWaiter& waiter) +{ + auto lock = condVars.lock(); + lock->emplace(zoneName, waiter); +} + +void clearZoneTracker(const DNSName& zoneName) +{ + // Zap our (and only our) ZoneWaiter struct out of the multimap + auto lock = condVars.lock(); + auto [start, end] = lock->equal_range(zoneName); + while (start != end) { + if (start->second.id == std::this_thread::get_id()) { + lock->erase(start); + break; + } + ++start; + } +} diff --git a/pdns/recursordist/rec-xfr.hh b/pdns/recursordist/rec-xfr.hh new file mode 100644 index 0000000000..739ef96b17 --- /dev/null +++ b/pdns/recursordist/rec-xfr.hh @@ -0,0 +1,61 @@ +/* + * This file is part of PowerDNS or dnsdist. + * Copyright -- PowerDNS.COM B.V. and its contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * In addition, for the avoidance of any doubt, permission is granted to + * link this program with OpenSSL and to (re)distribute the binaries + * produced as the result of such linking. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#pragma once + +#include "config.h" + +#include +#include + +#include "iputils.hh" + +class DNSName; +class SOARecordContent; + +// Please make sure that the struct below only contains value types since they are used as parameters in a thread ct +struct ZoneXFRParams +{ + std::string name; + std::vector primaries; + ComboAddress localAddress; + std::shared_ptr soaRecordContent; + TSIGTriplet tsigtriplet; + size_t maxReceivedMBytes{0}; + size_t zoneSizeHint{0}; + uint16_t xfrTimeout{20}; +}; + +// A struct that holds the condition var and related stuff to allow notifies to be sent to the tread owning +// the struct. +struct ZoneWaiter +{ + ZoneWaiter(std::thread::id arg) : + id(arg) {} + std::thread::id id; + std::mutex mutex; + std::condition_variable condVar; + std::atomic stop{false}; +}; + +bool notifyZoneTracker(const DNSName& name); +void insertZoneTracker(const DNSName& zoneName, ZoneWaiter& waiter); +void clearZoneTracker(const DNSName& zoneName); diff --git a/pdns/recursordist/rpzloader.cc b/pdns/recursordist/rpzloader.cc index a7471d64ca..42d38a9de1 100644 --- a/pdns/recursordist/rpzloader.cc +++ b/pdns/recursordist/rpzloader.cc @@ -24,10 +24,8 @@ #include "dnsparser.hh" #include "dnsrecords.hh" #include "ixfr.hh" -#include "syncres.hh" #include "axfr-retriever.hh" #include "lock.hh" -#include "logger.hh" #include "logging.hh" #include "rec-lua-conf.hh" #include "rpzloader.hh" @@ -436,32 +434,21 @@ static bool dumpZoneToDisk(Logr::log_t logger, const std::shared_ptr stop{false}; -}; - -static void preloadRPZFIle(RPZTrackerParams& params, const DNSName& zoneName, std::shared_ptr& oldZone, uint32_t& refresh, const string& polName, uint64_t configGeneration, RPZWaiter& rpzwaiter, Logr::log_t logger) + +static void preloadRPZFIle(RPZTrackerParams& params, const DNSName& zoneName, std::shared_ptr& oldZone, uint32_t& refresh, const string& polName, uint64_t configGeneration, ZoneWaiter& rpzwaiter, Logr::log_t logger) { - while (!params.soaRecordContent) { + while (!params.zoneXFRParams.soaRecordContent) { /* if we received an empty sr, the zone was not really preloaded */ /* full copy, as promised */ std::shared_ptr newZone = std::make_shared(*oldZone); - for (const auto& primary : params.primaries) { + for (const auto& primary : params.zoneXFRParams.primaries) { try { - params.soaRecordContent = loadRPZFromServer(logger, primary, zoneName, newZone, params.defpol, params.defpolOverrideLocal, params.maxTTL, params.tsigtriplet, params.maxReceivedMBytes, params.localAddress, params.xfrTimeout); - newZone->setSerial(params.soaRecordContent->d_st.serial); - newZone->setRefresh(params.soaRecordContent->d_st.refresh); + params.zoneXFRParams.soaRecordContent = loadRPZFromServer(logger, primary, zoneName, newZone, params.defpol, params.defpolOverrideLocal, params.maxTTL, params.zoneXFRParams.tsigtriplet, params.zoneXFRParams.maxReceivedMBytes, params.zoneXFRParams.localAddress, params.zoneXFRParams.xfrTimeout); + newZone->setSerial(params.zoneXFRParams.soaRecordContent->d_st.serial); + newZone->setRefresh(params.zoneXFRParams.soaRecordContent->d_st.refresh); refresh = std::max(params.refreshFromConf != 0 ? params.refreshFromConf : newZone->getRefresh(), 1U); - setRPZZoneNewState(polName, params.soaRecordContent->d_st.serial, newZone->size(), false, true); + setRPZZoneNewState(polName, params.zoneXFRParams.soaRecordContent->d_st.serial, newZone->size(), false, true); g_luaconfs.modify([zoneIdx = params.zoneIdx, &newZone](LuaConfigItems& lci) { lci.dfe.setZone(zoneIdx, newZone); @@ -487,7 +474,7 @@ static void preloadRPZFIle(RPZTrackerParams& params, const DNSName& zoneName, st } // Release newZone before (long) sleep to reduce memory usage newZone = nullptr; - if (!params.soaRecordContent) { + if (!params.zoneXFRParams.soaRecordContent) { std::unique_lock lock(rpzwaiter.mutex); rpzwaiter.condVar.wait_for(lock, std::chrono::seconds(refresh), [&stop = rpzwaiter.stop] { return stop.load(); }); @@ -504,12 +491,12 @@ static void preloadRPZFIle(RPZTrackerParams& params, const DNSName& zoneName, st } } -static bool RPZTrackerIteration(RPZTrackerParams& params, const DNSName& zoneName, std::shared_ptr& oldZone, uint32_t& refresh, const string& polName, bool& skipRefreshDelay, uint64_t configGeneration, RPZWaiter& rpzwaiter, Logr::log_t logger) +static bool RPZTrackerIteration(RPZTrackerParams& params, const DNSName& zoneName, std::shared_ptr& oldZone, uint32_t& refresh, const string& polName, bool& skipRefreshDelay, uint64_t configGeneration, ZoneWaiter& rpzwaiter, Logr::log_t logger) { // Don't hold on to oldZone, it well be re-assigned after sleep in the try block oldZone = nullptr; DNSRecord dnsRecord; - dnsRecord.setContent(params.soaRecordContent); + dnsRecord.setContent(params.zoneXFRParams.soaRecordContent); if (skipRefreshDelay) { skipRefreshDelay = false; @@ -542,19 +529,19 @@ static bool RPZTrackerIteration(RPZTrackerParams& params, const DNSName& zoneNam } vector, vector>> deltas; - for (const auto& primary : params.primaries) { + for (const auto& primary : params.zoneXFRParams.primaries) { auto soa = getRR(dnsRecord); auto serial = soa ? soa->d_st.serial : 0; SLOG(g_log << Logger::Info << "Getting IXFR deltas for " << zoneName << " from " << primary.toStringWithPort() << ", our serial: " << serial << endl, logger->info(Logr::Info, "Getting IXFR deltas", "address", Logging::Loggable(primary), "ourserial", Logging::Loggable(serial))); - ComboAddress local(params.localAddress); + ComboAddress local(params.zoneXFRParams.localAddress); if (local == ComboAddress()) { local = pdns::getQueryLocalAddress(primary.sin4.sin_family, 0); } try { - deltas = getIXFRDeltas(primary, zoneName, dnsRecord, params.xfrTimeout, true, params.tsigtriplet, &local, params.maxReceivedMBytes); + deltas = getIXFRDeltas(primary, zoneName, dnsRecord, params.zoneXFRParams.xfrTimeout, true, params.zoneXFRParams.tsigtriplet, &local, params.zoneXFRParams.maxReceivedMBytes); /* no need to try another primary */ break; @@ -589,7 +576,7 @@ static bool RPZTrackerIteration(RPZTrackerParams& params, const DNSName& zoneNam /* we need to make a _full copy_ of the zone we are going to work on */ std::shared_ptr newZone = std::make_shared(*oldZone); /* initialize the current serial to the last one */ - std::shared_ptr currentSR = params.soaRecordContent; + std::shared_ptr currentSR = params.zoneXFRParams.soaRecordContent; int totremove = 0; int totadd = 0; @@ -648,13 +635,13 @@ static bool RPZTrackerIteration(RPZTrackerParams& params, const DNSName& zoneNam /* only update sr now that all changes have been converted */ if (currentSR) { - params.soaRecordContent = std::move(currentSR); + 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, - logger->info(Logr::Info, "RPZ mutations", "removals", Logging::Loggable(totremove), "additions", Logging::Loggable(totadd), "newserial", Logging::Loggable(params.soaRecordContent->d_st.serial))); - newZone->setSerial(params.soaRecordContent->d_st.serial); - newZone->setRefresh(params.soaRecordContent->d_st.refresh); - setRPZZoneNewState(polName, params.soaRecordContent->d_st.serial, newZone->size(), false, fullUpdate); + logger->info(Logr::Info, "RPZ mutations", "removals", Logging::Loggable(totremove), "additions", Logging::Loggable(totadd), "newserial", Logging::Loggable(params.zoneXFRParams.soaRecordContent->d_st.serial))); + newZone->setSerial(params.zoneXFRParams.soaRecordContent->d_st.serial); + newZone->setRefresh(params.zoneXFRParams.soaRecordContent->d_st.refresh); + setRPZZoneNewState(polName, params.zoneXFRParams.soaRecordContent->d_st.serial, newZone->size(), false, fullUpdate); /* we need to replace the existing zone with the new one, but we don't want to touch anything else, especially other zones, @@ -685,35 +672,13 @@ static bool RPZTrackerIteration(RPZTrackerParams& params, const DNSName& zoneNam return true; } -// As there can be multiple threads doing updates (due to config reloads), we use a multimap. -// The value contains the actual thread id that owns the struct. - -static LockGuarded> condVars; - -// Notify all threads tracking the RPZ name -bool notifyRPZTracker(const DNSName& name) -{ - auto lock = condVars.lock(); - auto [start, end] = lock->equal_range(name); - if (start == end) { - // Did not find any thread tracking that RPZ name - return false; - } - while (start != end) { - start->second.stop = true; - start->second.condVar.notify_one(); - ++start; - } - return true; -} - // coverity[pass_by_value] params is intended to be a copy, as this is the main function of a thread void RPZIXFRTracker(RPZTrackerParams params, uint64_t configGeneration) { setThreadName("rec/rpzixfr"); - bool isPreloaded = params.soaRecordContent != nullptr; + bool isPreloaded = params.zoneXFRParams.soaRecordContent != nullptr; auto logger = g_slog->withName("rpz"); - RPZWaiter waiter(std::this_thread::get_id()); + ZoneWaiter waiter(std::this_thread::get_id()); /* we can _never_ modify this zone directly, we need to do a full copy then replace the existing zone */ std::shared_ptr oldZone = g_luaconfs.getLocal()->dfe.getZone(params.zoneIdx); @@ -731,10 +696,8 @@ void RPZIXFRTracker(RPZTrackerParams params, uint64_t configGeneration) // Now that we know the name, set it in the logger logger = logger->withValues("zone", Logging::Loggable(zoneName)); - { - auto lock = condVars.lock(); - lock->emplace(zoneName, waiter); - } + insertZoneTracker(zoneName, waiter); + preloadRPZFIle(params, zoneName, oldZone, refresh, polName, configGeneration, waiter, logger); bool skipRefreshDelay = isPreloaded; @@ -743,14 +706,5 @@ void RPZIXFRTracker(RPZTrackerParams params, uint64_t configGeneration) // empty } - // Zap our (and only our) RPZWaiter struct out of the multimap - auto lock = condVars.lock(); - auto [start, end] = lock->equal_range(zoneName); - while (start != end) { - if (start->second.id == std::this_thread::get_id()) { - lock->erase(start); - break; - } - ++start; - } + clearZoneTracker(zoneName); } diff --git a/pdns/recursordist/rpzloader.hh b/pdns/recursordist/rpzloader.hh index 8b2252f14c..0872ff6a27 100644 --- a/pdns/recursordist/rpzloader.hh +++ b/pdns/recursordist/rpzloader.hh @@ -20,6 +20,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #pragma once +#include "rec-xfr.hh" #include "filterpo.hh" #include #include "dnsrecords.hh" @@ -29,23 +30,16 @@ extern bool g_logRPZChanges; // Please make sure that the struct below only contains value types since they are used as parameters in a thread ct struct RPZTrackerParams { - std::string name; - std::vector primaries; + ZoneXFRParams zoneXFRParams; boost::optional defpol; std::string defcontent; bool defpolOverrideLocal{true}; uint32_t maxTTL = std::numeric_limits::max(); size_t zoneIdx{0}; - TSIGTriplet tsigtriplet; - size_t maxReceivedMBytes{0}; - ComboAddress localAddress; - uint16_t xfrTimeout{20}; uint32_t refreshFromConf{0}; - std::shared_ptr soaRecordContent; std::string seedFileName; std::string dumpZoneFileName; std::string polName; - size_t zoneSizeHint{0}; std::set tags; uint32_t extendedErrorCode{std::numeric_limits::max()}; std::string extendedErrorExtra; @@ -55,7 +49,6 @@ struct RPZTrackerParams std::shared_ptr loadRPZFromFile(const std::string& fname, const std::shared_ptr& zone, const boost::optional& defpol, bool defpolOverrideLocal, uint32_t maxTTL); void RPZIXFRTracker(RPZTrackerParams params, uint64_t configGeneration); -bool notifyRPZTracker(const DNSName& name); struct rpzStats { diff --git a/pdns/recursordist/settings/cxxsupport.cc b/pdns/recursordist/settings/cxxsupport.cc index f8345b4918..fcaf9f6ec1 100644 --- a/pdns/recursordist/settings/cxxsupport.cc +++ b/pdns/recursordist/settings/cxxsupport.cc @@ -870,10 +870,10 @@ void fromLuaToRust(const vector& rpzs, pdns::rust::settings::r .seedFile = "", }; - for (const auto& address : rpz.primaries) { + for (const auto& address : rpz.zoneXFRParams.primaries) { rustrpz.addresses.emplace_back(address.toStringWithPort()); } - rustrpz.name = rpz.name; + rustrpz.name = rpz.zoneXFRParams.name; rustrpz.defcontent = rpz.defcontent; if (rpz.defpol) { rustrpz.defpol = cvt(rpz.defpol->d_kind); @@ -890,14 +890,14 @@ void fromLuaToRust(const vector& rpzs, pdns::rust::settings::r rustrpz.tags.emplace_back(tag); } rustrpz.overridesGettag = rpz.defpolOverrideLocal; - rustrpz.zoneSizeHint = rpz.zoneSizeHint; - assign(rustrpz.tsig, rpz.tsigtriplet); + rustrpz.zoneSizeHint = rpz.zoneXFRParams.zoneSizeHint; + assign(rustrpz.tsig, rpz.zoneXFRParams.tsigtriplet); rustrpz.refresh = rpz.refreshFromConf; - rustrpz.maxReceivedMBytes = rpz.maxReceivedMBytes; - if (rpz.localAddress != ComboAddress()) { - rustrpz.localAddress = rpz.localAddress.toString(); + rustrpz.maxReceivedMBytes = rpz.zoneXFRParams.maxReceivedMBytes; + if (rpz.zoneXFRParams.localAddress != ComboAddress()) { + rustrpz.localAddress = rpz.zoneXFRParams.localAddress.toString(); } - rustrpz.axfrTimeout = rpz.xfrTimeout; + rustrpz.axfrTimeout = rpz.zoneXFRParams.xfrTimeout; rustrpz.dumpFile = rpz.dumpZoneFileName; rustrpz.seedFile = rpz.seedFileName; @@ -1181,9 +1181,9 @@ void fromRustToLuaConfig(const rust::Vec& rpzs, RPZTrackerParams params; for (const auto& address : rpz.addresses) { ComboAddress combo = ComboAddress(std::string(address), 53); - params.primaries.emplace_back(combo.toStringWithPort()); + params.zoneXFRParams.primaries.emplace_back(combo.toStringWithPort()); } - params.name = std::string(rpz.name); + params.zoneXFRParams.name = std::string(rpz.name); params.polName = std::string(rpz.policyName); if (!rpz.defpol.empty()) { @@ -1217,14 +1217,14 @@ void fromRustToLuaConfig(const rust::Vec& rpzs, params.tags.emplace(std::string(tag)); } params.defpolOverrideLocal = rpz.overridesGettag; - params.zoneSizeHint = rpz.zoneSizeHint; - assign(params.tsigtriplet, rpz.tsig); + params.zoneXFRParams.zoneSizeHint = rpz.zoneSizeHint; + assign(params.zoneXFRParams.tsigtriplet, rpz.tsig); params.refreshFromConf = rpz.refresh; - params.maxReceivedMBytes = rpz.maxReceivedMBytes; + params.zoneXFRParams.maxReceivedMBytes = rpz.maxReceivedMBytes; if (!rpz.localAddress.empty()) { - params.localAddress = ComboAddress(std::string(rpz.localAddress)); + params.zoneXFRParams.localAddress = ComboAddress(std::string(rpz.localAddress)); } - params.xfrTimeout = rpz.axfrTimeout; + params.zoneXFRParams.xfrTimeout = rpz.axfrTimeout; params.dumpZoneFileName = std::string(rpz.dumpFile); params.seedFileName = std::string(rpz.seedFile); luaConfig.rpzs.emplace_back(params);