]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Small refactoring of GeoIPBackend::loadDomain 13321/head
authorFred Morcos <fred.morcos@open-xchange.com>
Thu, 12 Oct 2023 14:32:24 +0000 (16:32 +0200)
committerFred Morcos <fred.morcos@open-xchange.com>
Thu, 12 Oct 2023 14:45:31 +0000 (16:45 +0200)
modules/geoipbackend/geoipbackend.cc
modules/geoipbackend/geoipbackend.hh

index 5341e1d8549a478d922a00a24e7893f95271b37e..2d0523158b38c049403d98d346513c9e015e5f78 100644 (file)
@@ -33,6 +33,7 @@
 #include <boost/format.hpp>
 #include <fstream>
 #include <filesystem>
+#include <utility>
 #include <yaml-cpp/yaml.h>
 
 ReadWriteLock GeoIPBackend::s_state_lock;
@@ -124,6 +125,94 @@ static bool validateMappingLookupFormats(const vector<string>& formats)
   return true;
 }
 
+static vector<GeoIPDNSResourceRecord> makeDNSResourceRecord(GeoIPDomain& dom, DNSName name)
+{
+  GeoIPDNSResourceRecord resourceRecord;
+  resourceRecord.domain_id = static_cast<int>(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<GeoIPDNSResourceRecord> 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<string>()};
+    NetmaskTree<vector<string>> 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<string> value;
+        if (net->second.IsSequence()) {
+          value = net->second.as<vector<string>>();
+        }
+        else {
+          value.push_back(net->second.as<string>());
+        }
+        if (net->first.as<string>() == "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<string>()};
+          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<string> value;
+      if (service->second.IsSequence()) {
+        value = service->second.as<vector<string>>();
+      }
+      else {
+        value.push_back(service->second.as<string>());
+      }
+      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<vector<string>>();
+      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<map<std::string, std::string>>();
+    }
+    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<string>()};
-      NetmaskTree<vector<string>> 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<string> value;
-          if (net->second.IsSequence()) {
-            value = net->second.as<vector<string>>();
-          }
-          else {
-            value.push_back(net->second.as<string>());
-          }
-          if (net->first.as<string>() == "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<string>()};
-            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<string> value;
-        if (service->second.IsSequence()) {
-          value = service->second.as<vector<string>>();
-        }
-        else {
-          value.push_back(service->second.as<string>());
-        }
-        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<vector<string>>();
-        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<map<std::string, std::string>>();
-      }
-      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<GeoIPDNSResourceRecord> rrs;
-          resourceRecord.domain_id = static_cast<int>(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<GeoIPDNSResourceRecord> rrs;
-          resourceRecord.domain_id = static_cast<int>(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);
         }
       }
index a2d3c7b994ad6de64ff2d084d07e5fd230bd2b53..6185b2d9bd80bfacf9b2a9346e4d17a57a4c318e 100644 (file)
@@ -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<GeoIPDomain>& domains);
   vector<DNSResourceRecord> d_result;