From: Otto Moerbeek Date: Wed, 2 Oct 2024 15:19:21 +0000 (+0200) Subject: Add group processing X-Git-Tag: rec-5.2.0-alpha1~7^2~16 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c75e25a09a56b98e3993929fe9d764af4d234d57;p=thirdparty%2Fpdns.git Add group processing --- diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index 8d146c5809..974414a3a9 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -3566,7 +3566,6 @@ static void activateForwardingCatalogZones(LuaConfigItems& lci) } } - void activateLuaConfig(LuaConfigItems& lci) { if (!lci.trustAnchorFileInfo.fname.empty()) { @@ -3583,4 +3582,3 @@ void activateLuaConfig(LuaConfigItems& lci) activateForwardingCatalogZones(lci); g_luaconfs.setState(lci); } - diff --git a/pdns/recursordist/rec-xfr.cc b/pdns/recursordist/rec-xfr.cc index e8a5e6518b..a7b07cff3d 100644 --- a/pdns/recursordist/rec-xfr.cc +++ b/pdns/recursordist/rec-xfr.cc @@ -29,14 +29,12 @@ #include "axfr-retriever.hh" #include "ixfr.hh" #include "dnsrecords.hh" -#include "settings/cxxsettings.hh" -#include "rec-main.hh" -#include "syncres.hh" static const DNSName cZones("zones"); static const DNSName cVersion("version"); -// TODO: cleanup files if not in catalogzones +// TODO: cleanup files if not in catalogzones? +// TODO: notify to catzone (works but for #14506) void CatalogZone::add(const DNSRecord& record, Logr::log_t logger) { @@ -54,7 +52,7 @@ void CatalogZone::add(const DNSRecord& record, Logr::log_t logger) return; } const auto& key = record.d_name; - logger->info(Logr::Debug, "Adding cat zone entry", "name", Logging::Loggable(key), "qtype", Logging::Loggable(record.d_type)); + logger->info(Logr::Debug, "Adding cat zone entry", "name", Logging::Loggable(key), "qtype", Logging::Loggable(QType(record.d_type))); d_records.emplace(std::make_pair(key, record.d_type), record); } @@ -74,38 +72,59 @@ void CatalogZone::remove(const DNSRecord& record, Logr::log_t logger) return; } const auto& key = record.d_name; - logger->info(Logr::Debug, "Removing cat zone entry", "name", Logging::Loggable(key), "qtype", Logging::Loggable(record.d_type)); + logger->info(Logr::Debug, "Removing cat zone entry", "name", Logging::Loggable(key), "qtype", Logging::Loggable(QType(record.d_type))); d_records.erase(std::make_pair(key, record.d_type)); } void CatalogZone::registerForwarders(const FWCatz& params, Logr::log_t logger) { - auto defsIter = params.d_defaults.find(""); - pdns::rust::settings::rec::FCZDefault defaults = defsIter->second; - // defaults.name = "default"; - // defaults.forwarders = {"1.2.3.4", "4.5.6.7"}; - // defaults.recurse = false; - // defaults.notify_allowed = false; - const string zonesFile = ::arg()["api-config-dir"] + "/catzone." + d_name.toString(); ::rust::Vec<::pdns::rust::settings::rec::ForwardZone> forwards; + for (const auto& record : d_records) { if (record.first.second != QType::PTR) { continue; } if (const auto ptr = getRR(record.second)) { + auto defsIter = params.d_defaults.find(""); + const auto& name = record.first.first; + auto groupKey = name; + groupKey.prependRawLabel("group"); + // Look for group records matching the member + auto range = d_records.equal_range(std::make_pair(groupKey, QType::TXT)); + for (auto groupIter = range.first; groupIter != range.second; ++groupIter) { + if (const auto txt = getRR(groupIter->second); txt != nullptr) { + auto groupName = txt->d_text; + groupName = unquotify(groupName); + auto iter = params.d_defaults.find(groupName); + if (iter == params.d_defaults.end()) { + logger->info(Logr::Debug, "No match for group in YAML config", "name", Logging::Loggable(name), "groupName", Logging::Loggable(groupName)); + continue; + } + logger->info(Logr::Debug, "Match for group in YAML config", "name", Logging::Loggable(name), "groupName", Logging::Loggable(groupName)); + defsIter = iter; + break; + } + } + if (defsIter == params.d_defaults.end()) { + logger->info(Logr::Error, "No match for group in YAML config", "name", Logging::Loggable(name)); + continue; + } auto target = ptr->getContent(); pdns::rust::settings::rec::ForwardZone forward; forward.zone = target.toString(); - forward.recurse = defaults.recurse; - forward.notify_allowed = defaults.notify_allowed; - for (const auto& value : defaults.forwarders) { + forward.recurse = defsIter->second.recurse; + forward.notify_allowed = defsIter->second.notify_allowed; + for (const auto& value : defsIter->second.forwarders) { forward.forwarders.emplace_back(value); } - forward.validate(""); + forward.validate("catz"); forwards.emplace_back(std::move(forward)); } } + + // Simple approach: just replace everything. Keeping track of changes to members is a bit involved as the + // members themselves can change, be added ot deleted, but also the group records. pdns::rust::settings::rec::api_delete_zones(zonesFile); pdns::rust::settings::rec::api_add_forward_zones(zonesFile, forwards); reloadZoneConfiguration(true); @@ -145,7 +164,7 @@ bool CatalogZone::dupsCheck() const invalid = true; continue; } - if (!values.insert(ptr->getContent()).second) { + if (!values.emplace(ptr->getContent()).second) { invalid = true; break; } @@ -222,7 +241,7 @@ void ZoneXFR::preloadZoneFile(const DNSName& zoneName, std::shared_ptr(*oldZone); for (const auto& primary : d_params.primaries) { try { - d_params.soaRecordContent = loadZoneFromServer(logger, primary, zoneName, newZone, d_params.tsigtriplet, d_params.maxReceivedMBytes, d_params.localAddress, d_params.xfrTimeout); + d_params.soaRecordContent = loadZoneFromServer(logger, primary, zoneName, newZone, d_params.tsigtriplet, d_params.maxReceivedMBytes, d_params.localAddress, d_params.xfrTimeout); newZone->setSerial(d_params.soaRecordContent->d_st.serial); newZone->setRefresh(d_params.soaRecordContent->d_st.refresh); refresh = std::max(d_params.refreshFromConf != 0 ? d_params.refreshFromConf : newZone->getRefresh(), 1U); @@ -251,7 +270,7 @@ void ZoneXFR::preloadZoneFile(const DNSName& zoneName, std::shared_ptr& oldZone, uint32_t& refresh, bool& skipRefreshDelay, uint64_t configGeneration, ZoneWaiter& waiter, Logr::log_t logger) @@ -399,12 +417,12 @@ bool ZoneXFR::zoneTrackerIteration(const DNSName& zoneName, std::shared_ptrversionCheck()) { - throw PDNSException("no valid version record in catalog zone"); - } - if (!newZone->dupsCheck()) { - throw PDNSException("duplicate PTR values in catalog zone"); - } + if (!newZone->versionCheck()) { + throw PDNSException("no valid version record in catalog zone"); + } + if (!newZone->dupsCheck()) { + throw PDNSException("duplicate PTR values in catalog zone"); + } /* only update sr now that all changes have been converted */ if (currentSR) { @@ -443,9 +461,9 @@ bool ZoneXFR::zoneTrackerIteration(const DNSName& zoneName, std::shared_ptrwithName("catixfr"); + auto logger = g_slog->withName("fwcatzixfr"); 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 */ @@ -476,4 +494,3 @@ void ZoneXFR::zoneXFRTracker(ZoneXFRParams params, uint64_t configGeneration) // clearZoneTracker(zoneName); } - diff --git a/pdns/recursordist/rec-xfr.hh b/pdns/recursordist/rec-xfr.hh index 3e77806497..5923527e4f 100644 --- a/pdns/recursordist/rec-xfr.hh +++ b/pdns/recursordist/rec-xfr.hh @@ -23,6 +23,7 @@ #include "config.h" +#include #include #include #include @@ -77,13 +78,13 @@ public: } void reserve([[maybe_unused]] size_t size) { - //d_records.reserve(size); + // d_records.reserve(size); } void clear() { d_records.clear(); } - void newStats([[maybe_unused]] uint32_t serial, [[maybe_unused]]bool fullTransfer) + void newStats([[maybe_unused]] uint32_t serial, [[maybe_unused]] bool fullTransfer) { // XXX stats } @@ -91,7 +92,7 @@ public: { // XXX stats } - void add(const DNSRecord& record, Logr::log_t logger); + void add(const DNSRecord& record, Logr::log_t logger); void remove(const DNSRecord& record, Logr::log_t logger); void registerForwarders(const FWCatz& params, Logr::log_t logger); [[nodiscard]] bool versionCheck() const; @@ -111,7 +112,7 @@ struct FWCatz std::shared_ptr d_catz; }; -struct ZoneXFR +class ZoneXFR { public: // A struct that holds the condition var and related stuff to allow notifies to be sent to the tread owning @@ -131,7 +132,7 @@ public: static void clearZoneTracker(const DNSName& zoneName); static void zoneXFRTracker(ZoneXFRParams params, uint64_t configGeneration); - ZoneXFR(ZoneXFRParams params) : + ZoneXFR(ZoneXFRParams params) : d_params(std::move(params)) {} @@ -146,3 +147,4 @@ private: static LockGuarded> condVars; }; +std::string reloadZoneConfiguration(bool yaml); diff --git a/pdns/recursordist/rpzloader.cc b/pdns/recursordist/rpzloader.cc index 46fcffb0c0..db554df57f 100644 --- a/pdns/recursordist/rpzloader.cc +++ b/pdns/recursordist/rpzloader.cc @@ -434,7 +434,6 @@ static bool dumpZoneToDisk(Logr::log_t logger, const std::shared_ptr& oldZone, uint32_t& refresh, const string& polName, uint64_t configGeneration, ZoneXFR::ZoneWaiter& rpzwaiter, Logr::log_t logger) { while (!params.zoneXFRParams.soaRecordContent) { diff --git a/pdns/recursordist/syncres.hh b/pdns/recursordist/syncres.hh index 02d8ef722f..6b31b300a2 100644 --- a/pdns/recursordist/syncres.hh +++ b/pdns/recursordist/syncres.hh @@ -936,7 +936,6 @@ extern uint16_t g_outgoingEDNSBufsize; extern std::atomic g_maxCacheEntries, g_maxPacketCacheEntries; extern bool g_lowercaseOutgoing; -std::string reloadZoneConfiguration(bool yaml); using pipefunc_t = std::function; void broadcastFunction(const pipefunc_t& func); void distributeAsyncFunction(const std::string& packet, const pipefunc_t& func);