From: Otto Moerbeek Date: Tue, 5 Mar 2024 15:12:54 +0000 (+0100) Subject: rec: tidy rpzloader.?? X-Git-Tag: dnsdist-1.10.0-alpha0~15^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fpull%2F13861%2Fhead;p=thirdparty%2Fpdns.git rec: tidy rpzloader.?? --- diff --git a/pdns/recursordist/rpzloader.cc b/pdns/recursordist/rpzloader.cc index ef04c8baf9..fcf04fd183 100644 --- a/pdns/recursordist/rpzloader.cc +++ b/pdns/recursordist/rpzloader.cc @@ -43,65 +43,73 @@ Netmask makeNetmaskFromRPZ(const DNSName& name) * $NETMASK.zz (::/$NETMASK) * Terrible right? */ - if (parts.size() < 2 || parts.size() > 9) + if (parts.size() < 2 || parts.size() > 9) { throw PDNSException("Invalid IP address in RPZ: " + name.toLogString()); + } bool isV6 = (stoi(parts[0]) > 32); bool hadZZ = false; for (auto& part : parts) { // Check if we have an IPv4 octet - for (auto c : part) - if (!isdigit(c)) + for (auto labelLetter : part) { + if (isdigit(labelLetter) == 0) { isV6 = true; - + } + } if (pdns_iequals(part, "zz")) { - if (hadZZ) + if (hadZZ) { throw PDNSException("more than one 'zz' label found in RPZ name" + name.toLogString()); + } part = ""; isV6 = true; hadZZ = true; } } - if (isV6 && parts.size() < 9 && !hadZZ) + if (isV6 && parts.size() < 9 && !hadZZ) { throw PDNSException("No 'zz' label found in an IPv6 RPZ name shorter than 9 elements: " + name.toLogString()); + } - if (parts.size() == 5 && !isV6) - return Netmask(parts[4] + "." + parts[3] + "." + parts[2] + "." + parts[1] + "/" + parts[0]); - - string v6; + if (parts.size() == 5 && !isV6) { + return parts[4] + "." + parts[3] + "." + parts[2] + "." + parts[1] + "/" + parts[0]; + } + string v6Address; - if (parts[parts.size() - 1] == "") { - v6 += ":"; + if (parts[parts.size() - 1].empty()) { + v6Address += ":"; } for (uint8_t i = parts.size() - 1; i > 0; i--) { - v6 += parts[i]; - if (i > 1 || (i == 1 && parts[i] == "")) { - v6 += ":"; + v6Address += parts[i]; + if (i > 1 || (i == 1 && parts[i].empty())) { + v6Address += ":"; } } - v6 += "/" + parts[0]; + v6Address += "/" + parts[0]; - return Netmask(v6); + return v6Address; } -static void RPZRecordToPolicy(const DNSRecord& dr, std::shared_ptr zone, bool addOrRemove, const boost::optional& defpol, bool defpolOverrideLocal, uint32_t maxTTL, Logr::log_t log) +static void RPZRecordToPolicy(const DNSRecord& dnsRecord, const std::shared_ptr& zone, bool addOrRemove, const boost::optional& defpol, bool defpolOverrideLocal, uint32_t maxTTL, Logr::log_t log) { - static const DNSName drop("rpz-drop."), truncate("rpz-tcp-only."), noaction("rpz-passthru."); - static const DNSName rpzClientIP("rpz-client-ip"), rpzIP("rpz-ip"), - rpzNSDname("rpz-nsdname"), rpzNSIP("rpz-nsip."); + static const DNSName drop("rpz-drop."); + static const DNSName truncate("rpz-tcp-only."); + static const DNSName noaction("rpz-passthru."); + static const DNSName rpzClientIP("rpz-client-ip"); + static const DNSName rpzIP("rpz-ip"); + static const DNSName rpzNSDname("rpz-nsdname"); + static const DNSName rpzNSIP("rpz-nsip."); static const std::string rpzPrefix("rpz-"); DNSFilterEngine::Policy pol; bool defpolApplied = false; - if (dr.d_class != QClass::IN) { + if (dnsRecord.d_class != QClass::IN) { return; } - if (dr.d_type == QType::CNAME) { - auto crc = getRR(dr); + if (dnsRecord.d_type == QType::CNAME) { + auto crc = getRR(dnsRecord); if (!crc) { return; } @@ -140,8 +148,8 @@ static void RPZRecordToPolicy(const DNSRecord& dr, std::shared_ptrinfo(Logr::Info, "Discarding unsupported RPZ entry", "target", Logging::Loggable(crcTarget), "name", Logging::Loggable(dr.d_name))); + SLOG(g_log << Logger::Info << "Discarding unsupported RPZ entry " << crcTarget << " for " << dnsRecord.d_name << endl, + log->info(Logr::Info, "Discarding unsupported RPZ entry", "target", Logging::Loggable(crcTarget), "name", Logging::Loggable(dnsRecord.d_name))); return; } else { @@ -149,7 +157,7 @@ static void RPZRecordToPolicy(const DNSRecord& dr, std::shared_ptr(); } - pol.d_custom->emplace_back(dr.getContent()); + pol.d_custom->emplace_back(dnsRecord.getContent()); // cerr<<"Wants custom "<(); } - pol.d_custom->emplace_back(dr.getContent()); + pol.d_custom->emplace_back(dnsRecord.getContent()); // cerr<<"Wants custom "<getZoneRepresentation()<<" for "<d_ttl < 0) { - pol.d_ttl = static_cast(std::min(maxTTL, dr.d_ttl)); + pol.d_ttl = static_cast(std::min(maxTTL, dnsRecord.d_ttl)); } else { pol.d_ttl = static_cast(std::min(maxTTL, static_cast(pol.d_ttl))); @@ -177,104 +185,113 @@ static void RPZRecordToPolicy(const DNSRecord& dr, std::shared_ptraddNSTrigger(filt, std::move(pol), defpolApplied); - else - zone->rmNSTrigger(filt, std::move(pol)); - } - else if (dr.d_name.isPartOf(rpzClientIP)) { - DNSName filt = dr.d_name.makeRelative(rpzClientIP); - auto nm = makeNetmaskFromRPZ(filt); - if (addOrRemove) - zone->addClientTrigger(nm, std::move(pol), defpolApplied); - else - zone->rmClientTrigger(nm, std::move(pol)); - } - else if (dr.d_name.isPartOf(rpzIP)) { + } + else { + zone->rmNSTrigger(filt, pol); + } + } + else if (dnsRecord.d_name.isPartOf(rpzClientIP)) { + DNSName filt = dnsRecord.d_name.makeRelative(rpzClientIP); + auto netmask = makeNetmaskFromRPZ(filt); + if (addOrRemove) { + zone->addClientTrigger(netmask, std::move(pol), defpolApplied); + } + else { + zone->rmClientTrigger(netmask, pol); + } + } + else if (dnsRecord.d_name.isPartOf(rpzIP)) { // cerr<<"Should apply answer content IP policy: "<addResponseTrigger(nm, std::move(pol), defpolApplied); - else - zone->rmResponseTrigger(nm, std::move(pol)); - } - else if (dr.d_name.isPartOf(rpzNSIP)) { - DNSName filt = dr.d_name.makeRelative(rpzNSIP); - auto nm = makeNetmaskFromRPZ(filt); - if (addOrRemove) - zone->addNSIPTrigger(nm, std::move(pol), defpolApplied); - else - zone->rmNSIPTrigger(nm, std::move(pol)); + DNSName filt = dnsRecord.d_name.makeRelative(rpzIP); + auto netmask = makeNetmaskFromRPZ(filt); + if (addOrRemove) { + zone->addResponseTrigger(netmask, std::move(pol), defpolApplied); + } + else { + zone->rmResponseTrigger(netmask, pol); + } + } + else if (dnsRecord.d_name.isPartOf(rpzNSIP)) { + DNSName filt = dnsRecord.d_name.makeRelative(rpzNSIP); + auto netmask = makeNetmaskFromRPZ(filt); + if (addOrRemove) { + zone->addNSIPTrigger(netmask, std::move(pol), defpolApplied); + } + else { + zone->rmNSIPTrigger(netmask, pol); + } } else { if (addOrRemove) { /* if we did override the existing policy with the default policy, we might turn two A or AAAA into a CNAME, which would trigger an exception. Let's just ignore it. */ - zone->addQNameTrigger(dr.d_name, std::move(pol), defpolApplied); + zone->addQNameTrigger(dnsRecord.d_name, std::move(pol), defpolApplied); } else { - zone->rmQNameTrigger(dr.d_name, std::move(pol)); + zone->rmQNameTrigger(dnsRecord.d_name, pol); } } } -static shared_ptr loadRPZFromServer(Logr::log_t plogger, const ComboAddress& primary, const DNSName& zoneName, std::shared_ptr zone, const boost::optional& defpol, bool defpolOverrideLocal, uint32_t maxTTL, const TSIGTriplet& tt, size_t maxReceivedBytes, const ComboAddress& localAddress, uint16_t axfrTimeout) +static shared_ptr loadRPZFromServer(Logr::log_t plogger, const ComboAddress& primary, const DNSName& zoneName, const std::shared_ptr& zone, const boost::optional& defpol, bool defpolOverrideLocal, uint32_t maxTTL, const TSIGTriplet& tsigTriplet, size_t maxReceivedBytes, const ComboAddress& localAddress, uint16_t axfrTimeout) { auto logger = plogger->withValues("primary", Logging::Loggable(primary)); SLOG(g_log << Logger::Warning << "Loading RPZ zone '" << zoneName << "' from " << primary.toStringWithPort() << endl, logger->info(Logr::Info, "Loading RPZ from nameserver")); - if (!tt.name.empty()) { - SLOG(g_log << Logger::Warning << "With TSIG key '" << tt.name << "' of algorithm '" << tt.algo << "'" << endl, - logger->info(Logr::Info, "Using TSIG key for authentication", "tsig_key_name", Logging::Loggable(tt.name), "tsig_key_algorithm", Logging::Loggable(tt.algo))); + if (!tsigTriplet.name.empty()) { + SLOG(g_log << Logger::Warning << "With TSIG key '" << tsigTriplet.name << "' of algorithm '" << tsigTriplet.algo << "'" << endl, + logger->info(Logr::Info, "Using TSIG key for authentication", "tsig_key_name", Logging::Loggable(tsigTriplet.name), "tsig_key_algorithm", Logging::Loggable(tsigTriplet.algo))); } ComboAddress local(localAddress); - if (local == ComboAddress()) + if (local == ComboAddress()) { local = pdns::getQueryLocalAddress(primary.sin4.sin_family, 0); + } - AXFRRetriever axfr(primary, zoneName, tt, &local, maxReceivedBytes, axfrTimeout); + AXFRRetriever axfr(primary, zoneName, tsigTriplet, &local, maxReceivedBytes, axfrTimeout); unsigned int nrecords = 0; Resolver::res_t nop; vector chunk; time_t last = 0; time_t axfrStart = time(nullptr); time_t axfrNow = time(nullptr); - shared_ptr sr; + shared_ptr soaRecordContent; // coverity[store_truncates_time_t] - while (axfr.getChunk(nop, &chunk, (axfrStart + axfrTimeout - axfrNow))) { - for (auto& dr : chunk) { - if (dr.d_type == QType::NS || dr.d_type == QType::TSIG) { + while (axfr.getChunk(nop, &chunk, (axfrStart + axfrTimeout - axfrNow)) != 0) { + for (auto& dnsRecord : chunk) { + if (dnsRecord.d_type == QType::NS || dnsRecord.d_type == QType::TSIG) { continue; } - dr.d_name.makeUsRelative(zoneName); - if (dr.d_type == QType::SOA) { - sr = getRR(dr); - zone->setSOA(dr); + dnsRecord.d_name.makeUsRelative(zoneName); + if (dnsRecord.d_type == QType::SOA) { + soaRecordContent = getRR(dnsRecord); + zone->setSOA(dnsRecord); continue; } - RPZRecordToPolicy(dr, zone, true, defpol, defpolOverrideLocal, maxTTL, logger); + RPZRecordToPolicy(dnsRecord, zone, true, defpol, defpolOverrideLocal, maxTTL, logger); nrecords++; } axfrNow = time(nullptr); if (axfrNow < axfrStart || axfrNow - axfrStart > axfrTimeout) { throw PDNSException("Total AXFR time exceeded!"); } - if (last != time(0)) { + if (last != time(nullptr)) { SLOG(g_log << Logger::Info << "Loaded & indexed " << nrecords << " policy records so far for RPZ zone '" << zoneName << "'" << endl, logger->info(Logr::Info, "RPZ load in progress", "nrecords", Logging::Loggable(nrecords))); - last = time(0); + last = time(nullptr); } } - SLOG(g_log << Logger::Info << "Done: " << nrecords << " policy records active, SOA: " << sr->getZoneRepresentation() << endl, - logger->info(Logr::Info, "RPZ load completed", "nrecords", Logging::Loggable(nrecords), "soa", Logging::Loggable(sr->getZoneRepresentation()))); - return sr; + SLOG(g_log << Logger::Info << "Done: " << nrecords << " policy records active, SOA: " << soaRecordContent->getZoneRepresentation() << endl, + logger->info(Logr::Info, "RPZ load completed", "nrecords", Logging::Loggable(nrecords), "soa", Logging::Loggable(soaRecordContent->getZoneRepresentation()))); + return soaRecordContent; } static LockGuarded>> s_rpzStats; @@ -282,20 +299,21 @@ static LockGuarded>> s_rpzS shared_ptr getRPZZoneStats(const std::string& zone) { auto stats = s_rpzStats.lock(); - auto it = stats->find(zone); - if (it == stats->end()) { + auto statsIt = stats->find(zone); + if (statsIt == stats->end()) { auto stat = std::make_shared(); (*stats)[zone] = stat; return stat; } - return it->second; + return statsIt->second; } static void incRPZFailedTransfers(const std::string& zone) { auto stats = getRPZZoneStats(zone); - if (stats != nullptr) + if (stats != nullptr) { stats->d_failedTransfers++; + } } static void setRPZZoneNewState(const std::string& zone, uint32_t serial, uint64_t numberOfRecords, bool fromFile, bool wasAXFR) @@ -316,9 +334,9 @@ static void setRPZZoneNewState(const std::string& zone, uint32_t serial, uint64_ } // this function is silent - you do the logging -std::shared_ptr loadRPZFromFile(const std::string& fname, std::shared_ptr zone, const boost::optional& defpol, bool defpolOverrideLocal, uint32_t maxTTL) +std::shared_ptr loadRPZFromFile(const std::string& fname, const std::shared_ptr& zone, const boost::optional& defpol, bool defpolOverrideLocal, uint32_t maxTTL) { - shared_ptr sr = nullptr; + shared_ptr soaRecordContent = nullptr; ZoneParserTNG zpt(fname); zpt.setMaxGenerateSteps(::arg().asNum("max-generate-steps")); zpt.setMaxIncludes(::arg().asNum("max-include-depth")); @@ -328,21 +346,22 @@ std::shared_ptr loadRPZFromFile(const std::string& fname auto log = g_slog->withName("rpz")->withValues("file", Logging::Loggable(fname), "zone", Logging::Loggable(zone->getName())); while (zpt.get(drr)) { try { - if (drr.qtype.getCode() == QType::CNAME && drr.content.empty()) + if (drr.qtype.getCode() == QType::CNAME && drr.content.empty()) { drr.content = "."; - DNSRecord dr(drr); - if (dr.d_type == QType::SOA) { - sr = getRR(dr); - domain = dr.d_name; + } + DNSRecord dnsRecord(drr); + if (dnsRecord.d_type == QType::SOA) { + soaRecordContent = getRR(dnsRecord); + domain = dnsRecord.d_name; zone->setDomain(domain); - soaRecord = std::move(dr); + soaRecord = std::move(dnsRecord); } - else if (dr.d_type == QType::NS) { + else if (dnsRecord.d_type == QType::NS) { continue; } else { - dr.d_name = dr.d_name.makeRelative(domain); - RPZRecordToPolicy(dr, zone, true, defpol, defpolOverrideLocal, maxTTL, log); + dnsRecord.d_name = dnsRecord.d_name.makeRelative(domain); + RPZRecordToPolicy(dnsRecord, zone, true, defpol, defpolOverrideLocal, maxTTL, log); } } catch (const PDNSException& pe) { @@ -350,36 +369,36 @@ std::shared_ptr loadRPZFromFile(const std::string& fname } } - if (sr != nullptr) { - zone->setRefresh(sr->d_st.refresh); + if (soaRecordContent != nullptr) { + zone->setRefresh(soaRecordContent->d_st.refresh); zone->setSOA(std::move(soaRecord)); - setRPZZoneNewState(zone->getName(), sr->d_st.serial, zone->size(), true, false); + setRPZZoneNewState(zone->getName(), soaRecordContent->d_st.serial, zone->size(), true, false); } - return sr; + return soaRecordContent; } static bool dumpZoneToDisk(Logr::log_t logger, const DNSName& zoneName, const std::shared_ptr& newZone, const std::string& dumpZoneFileName) { logger->info(Logr::Debug, "Dumping zone to disk", "destination_file", Logging::Loggable(dumpZoneFileName)); std::string temp = dumpZoneFileName + "XXXXXX"; - int fd = mkstemp(&temp.at(0)); - if (fd < 0) { + int fileDesc = mkstemp(&temp.at(0)); + if (fileDesc < 0) { SLOG(g_log << Logger::Warning << "Unable to open a file to dump the content of the RPZ zone " << zoneName << endl, logger->error(Logr::Error, errno, "Unable to create temporary file")); return false; } - auto fp = std::unique_ptr(fdopen(fd, "w+"), fclose); - if (!fp) { + auto filePtr = std::unique_ptr(fdopen(fileDesc, "w+"), fclose); + if (!filePtr) { int err = errno; - close(fd); + close(fileDesc); SLOG(g_log << Logger::Warning << "Unable to open a file pointer to dump the content of the RPZ zone " << zoneName << endl, logger->error(Logr::Error, err, "Unable to open file pointer")); return false; } try { - newZone->dump(fp.get()); + newZone->dump(filePtr.get()); } catch (const std::exception& e) { SLOG(g_log << Logger::Warning << "Error while dumping the content of the RPZ zone " << zoneName << ": " << e.what() << endl, @@ -387,19 +406,19 @@ static bool dumpZoneToDisk(Logr::log_t logger, const DNSName& zoneName, const st return false; } - if (fflush(fp.get()) != 0) { + if (fflush(filePtr.get()) != 0) { SLOG(g_log << Logger::Warning << "Error while flushing the content of the RPZ zone " << zoneName << " to the dump file: " << stringerror() << endl, logger->error(Logr::Warning, errno, "Error while flushing the content of the RPZ")); return false; } - if (fsync(fileno(fp.get())) != 0) { + if (fsync(fileno(filePtr.get())) != 0) { SLOG(g_log << Logger::Warning << "Error while syncing the content of the RPZ zone " << zoneName << " to the dump file: " << stringerror() << endl, logger->error(Logr::Error, errno, "Error while syncing the content of the RPZ")); return false; } - if (fclose(fp.release()) != 0) { + if (fclose(filePtr.release()) != 0) { SLOG(g_log << Logger::Warning << "Error while writing the content of the RPZ zone " << zoneName << " to the dump file: " << stringerror() << endl, logger->error(Logr::Error, errno, "Error while writing the content of the RPZ")); return false; diff --git a/pdns/recursordist/rpzloader.hh b/pdns/recursordist/rpzloader.hh index 2933d9a1d0..57fddce8af 100644 --- a/pdns/recursordist/rpzloader.hh +++ b/pdns/recursordist/rpzloader.hh @@ -43,7 +43,7 @@ struct RPZTrackerParams std::string dumpZoneFileName; }; -std::shared_ptr loadRPZFromFile(const std::string& fname, std::shared_ptr zone, const boost::optional& defpol, bool defpolOverrideLocal, uint32_t maxTTL); +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);