From: Fred Morcos Date: Thu, 12 Oct 2023 14:32:24 +0000 (+0200) Subject: Small refactoring of GeoIPBackend::loadDomain X-Git-Tag: rec-5.0.0-alpha2~10^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=195e117563293375e52616fc3a3aeae316def566;p=thirdparty%2Fpdns.git Small refactoring of GeoIPBackend::loadDomain --- diff --git a/modules/geoipbackend/geoipbackend.cc b/modules/geoipbackend/geoipbackend.cc index 5341e1d854..2d0523158b 100644 --- a/modules/geoipbackend/geoipbackend.cc +++ b/modules/geoipbackend/geoipbackend.cc @@ -33,6 +33,7 @@ #include #include #include +#include #include ReadWriteLock GeoIPBackend::s_state_lock; @@ -124,6 +125,94 @@ static bool validateMappingLookupFormats(const vector& formats) return true; } +static vector makeDNSResourceRecord(GeoIPDomain& dom, DNSName name) +{ + GeoIPDNSResourceRecord resourceRecord; + resourceRecord.domain_id = static_cast(dom.id); + resourceRecord.ttl = dom.ttl; + resourceRecord.qname = std::move(name); + resourceRecord.qtype = QType(0); // empty non terminal + resourceRecord.content = ""; + resourceRecord.auth = true; + resourceRecord.weight = 100; + resourceRecord.has_weight = false; + vector rrs; + rrs.push_back(resourceRecord); + return rrs; +} + +void GeoIPBackend::setupNetmasks(const YAML::Node& domain, GeoIPDomain& dom) +{ + for (auto service = domain["services"].begin(); service != domain["services"].end(); service++) { + unsigned int netmask4 = 0; + unsigned int netmask6 = 0; + DNSName serviceName{service->first.as()}; + NetmaskTree> netmaskTree; + + // if it's an another map, we need to iterate it again, otherwise we just add two root entries. + if (service->second.IsMap()) { + for (auto net = service->second.begin(); net != service->second.end(); net++) { + vector value; + if (net->second.IsSequence()) { + value = net->second.as>(); + } + else { + value.push_back(net->second.as()); + } + if (net->first.as() == "default") { + netmaskTree.insert(Netmask("0.0.0.0/0")).second.assign(value.begin(), value.end()); + netmaskTree.insert(Netmask("::/0")).second.swap(value); + } + else { + Netmask netmask{net->first.as()}; + netmaskTree.insert(netmask).second.swap(value); + if (netmask.isIPv6() && netmask6 < netmask.getBits()) { + netmask6 = netmask.getBits(); + } + if (!netmask.isIPv6() && netmask4 < netmask.getBits()) { + netmask4 = netmask.getBits(); + } + } + } + } + else { + vector value; + if (service->second.IsSequence()) { + value = service->second.as>(); + } + else { + value.push_back(service->second.as()); + } + netmaskTree.insert(Netmask("0.0.0.0/0")).second.assign(value.begin(), value.end()); + netmaskTree.insert(Netmask("::/0")).second.swap(value); + } + + // Allow per domain override of mapping_lookup_formats and custom_mapping. + // If not defined, the global values will be used. + if (YAML::Node formats = domain["mapping_lookup_formats"]) { + auto mapping_lookup_formats = formats.as>(); + if (!validateMappingLookupFormats(mapping_lookup_formats)) { + throw PDNSException(string("%mp is not allowed in mapping lookup formats of domain ") + dom.domain.toLogString()); + } + + dom.mapping_lookup_formats = mapping_lookup_formats; + } + else { + dom.mapping_lookup_formats = d_global_mapping_lookup_formats; + } + if (YAML::Node mapping = domain["custom_mapping"]) { + dom.custom_mapping = mapping.as>(); + } + else { + dom.custom_mapping = d_global_custom_mapping; + } + + dom.services[serviceName].netmask4 = netmask4; + dom.services[serviceName].netmask6 = netmask6; + dom.services[serviceName].masks.swap(netmaskTree); + } +} + bool GeoIPBackend::loadDomain(const YAML::Node& domain, std::uint32_t domainID, GeoIPDomain& dom) { try { @@ -188,74 +277,7 @@ bool GeoIPBackend::loadDomain(const YAML::Node& domain, std::uint32_t domainID, std::swap(dom.records[qname], rrs); } - for (auto service = domain["services"].begin(); service != domain["services"].end(); service++) { - unsigned int netmask4 = 0; - unsigned int netmask6 = 0; - DNSName srvName{service->first.as()}; - NetmaskTree> nmt; - - // if it's an another map, we need to iterate it again, otherwise we just add two root entries. - if (service->second.IsMap()) { - for (auto net = service->second.begin(); net != service->second.end(); net++) { - vector value; - if (net->second.IsSequence()) { - value = net->second.as>(); - } - else { - value.push_back(net->second.as()); - } - if (net->first.as() == "default") { - nmt.insert(Netmask("0.0.0.0/0")).second.assign(value.begin(), value.end()); - nmt.insert(Netmask("::/0")).second.swap(value); - } - else { - Netmask netmask{net->first.as()}; - nmt.insert(netmask).second.swap(value); - if (netmask.isIPv6() && netmask6 < netmask.getBits()) { - netmask6 = netmask.getBits(); - } - if (!netmask.isIPv6() && netmask4 < netmask.getBits()) { - netmask4 = netmask.getBits(); - } - } - } - } - else { - vector value; - if (service->second.IsSequence()) { - value = service->second.as>(); - } - else { - value.push_back(service->second.as()); - } - nmt.insert(Netmask("0.0.0.0/0")).second.assign(value.begin(), value.end()); - nmt.insert(Netmask("::/0")).second.swap(value); - } - - // Allow per domain override of mapping_lookup_formats and custom_mapping. - // If not defined, the global values will be used. - if (YAML::Node formats = domain["mapping_lookup_formats"]) { - auto mapping_lookup_formats = formats.as>(); - if (!validateMappingLookupFormats(mapping_lookup_formats)) { - throw PDNSException(string("%mp is not allowed in mapping lookup formats of domain ") + dom.domain.toLogString()); - } - - dom.mapping_lookup_formats = mapping_lookup_formats; - } - else { - dom.mapping_lookup_formats = d_global_mapping_lookup_formats; - } - if (YAML::Node mapping = domain["custom_mapping"]) { - dom.custom_mapping = mapping.as>(); - } - else { - dom.custom_mapping = d_global_custom_mapping; - } - - dom.services[srvName].netmask4 = netmask4; - dom.services[srvName].netmask6 = netmask6; - dom.services[srvName].masks.swap(nmt); - } + setupNetmasks(domain, dom); // rectify the zone, first static records for (auto& item : dom.records) { @@ -263,17 +285,7 @@ bool GeoIPBackend::loadDomain(const YAML::Node& domain, std::uint32_t domainID, DNSName name = item.first; while (name.chopOff() && name.isPartOf(dom.domain)) { if (dom.records.find(name) == dom.records.end() && (dom.services.count(name) == 0U)) { // don't ENT out a service! - GeoIPDNSResourceRecord resourceRecord; - vector rrs; - resourceRecord.domain_id = static_cast(dom.id); - resourceRecord.ttl = dom.ttl; - resourceRecord.qname = name; - resourceRecord.qtype = QType(0); // empty non terminal - resourceRecord.content = ""; - resourceRecord.auth = true; - resourceRecord.weight = 100; - resourceRecord.has_weight = false; - rrs.push_back(resourceRecord); + auto rrs = makeDNSResourceRecord(dom, name); std::swap(dom.records[name], rrs); } } @@ -285,17 +297,7 @@ bool GeoIPBackend::loadDomain(const YAML::Node& domain, std::uint32_t domainID, DNSName name = item.first; while (name.chopOff() && name.isPartOf(dom.domain)) { if (dom.records.find(name) == dom.records.end()) { - GeoIPDNSResourceRecord resourceRecord; - vector rrs; - resourceRecord.domain_id = static_cast(dom.id); - resourceRecord.ttl = dom.ttl; - resourceRecord.qname = name; - resourceRecord.qtype = QType(0); - resourceRecord.content = ""; - resourceRecord.auth = true; - resourceRecord.weight = 100; - resourceRecord.has_weight = false; - rrs.push_back(resourceRecord); + auto rrs = makeDNSResourceRecord(dom, name); std::swap(dom.records[name], rrs); } } diff --git a/modules/geoipbackend/geoipbackend.hh b/modules/geoipbackend/geoipbackend.hh index a2d3c7b994..6185b2d9bd 100644 --- a/modules/geoipbackend/geoipbackend.hh +++ b/modules/geoipbackend/geoipbackend.hh @@ -83,6 +83,7 @@ private: bool d_dnssec{}; bool hasDNSSECkey(const DNSName& name); bool lookup_static(const GeoIPDomain& dom, const DNSName& search, const QType& qtype, const DNSName& qdomain, const Netmask& addr, GeoIPNetmask& gl); + void setupNetmasks(const YAML::Node& domain, GeoIPDomain& dom); bool loadDomain(const YAML::Node& domain, std::uint32_t domainID, GeoIPDomain& dom); void loadDomainsFromDirectory(const std::string& dir, vector& domains); vector d_result;