]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
implement 'weak' geobackend dependency, abstract out functionality
authorbert hubert <bert.hubert@netherlabs.nl>
Sat, 9 Dec 2017 22:43:17 +0000 (23:43 +0100)
committerbert hubert <bert.hubert@netherlabs.nl>
Sat, 9 Dec 2017 22:43:17 +0000 (23:43 +0100)
modules/geoipbackend/geoipbackend.cc
modules/geoipbackend/geoipbackend.hh
pdns/lua-record.cc

index 7bbdd4236428cdfe92356ee413bf890bd64df40a..ab299da01e4f71e8d4509d240d292085a06ba825 100644 (file)
@@ -1098,6 +1098,27 @@ bool GeoIPBackend::hasDNSSECkey(const DNSName& name) {
   return false;
 }
 
+string getGeo(const std::string& ip, GeoIPBackend::GeoIPQueryAttribute qa)
+{
+  try {
+    GeoIPBackend gib;
+    GeoIPLookup gl;
+    string res=gib.queryGeoIP(ip, false, qa, &gl);
+    //    cout<<"Result for "<<ip<<" lookup: "<<res<<endl;
+    if(qa==GeoIPBackend::ASn && boost::starts_with(res, "as"))
+      return res.substr(2);
+    return res;
+  }
+  catch(std::exception& e) {
+    cout<<"Error: "<<e.what()<<endl;
+  }
+  catch(PDNSException& e) {
+    cout<<"Error: "<<e.reason<<endl;
+  }
+  return "";
+}
+
+
 class GeoIPFactory : public BackendFactory{
 public:
   GeoIPFactory() : BackendFactory("geoip") {}
index 02a66a4e80f7af1f3cee3aa26d7cdec005fca17e..d963a798e2ac8d4bd6827f68536661dff835d377 100644 (file)
@@ -112,4 +112,6 @@ private:
   vector<DNSResourceRecord> d_result;
 };
 
+std::string getGeo(const std::string& ip, GeoIPBackend::GeoIPQueryAttribute qa);
+
 #endif /* PDNS_GEOIPBACKEND_HH */
index 4b22e1930c482f93c71d7b18ff3d25ac7beb0a71..f7fff7d107a4737f5dea07f0f517269c901921fe 100644 (file)
@@ -191,26 +191,28 @@ bool doCompare(const T& var, const std::string& res, const C& cmp)
   return false;
 }
 }
-static string getGeo(const std::string& ip, GeoIPBackend::GeoIPQueryAttribute qa)
+
+
+std::string getGeo(const std::string& ip, GeoIPBackend::GeoIPQueryAttribute qa) __attribute__((weak));
+
+std::string getGeo(const std::string& ip, GeoIPBackend::GeoIPQueryAttribute qa)
 {
-  try {
-    GeoIPBackend gib;
-    GeoIPLookup gl;
-    string res=gib.queryGeoIP(ip, false, qa, &gl);
-    //    cout<<"Result for "<<ip<<" lookup: "<<res<<endl;
-    if(qa==GeoIPBackend::ASn && boost::starts_with(res, "as"))
-      return res.substr(2);
-    return res;
-  }
-  catch(std::exception& e) {
-    cout<<"Error: "<<e.what()<<endl;
-  }
-  catch(PDNSException& e) {
-    cout<<"Error: "<<e.reason<<endl;
-  }
-  return "";
+  cerr<<"Weak variant called"<<endl;
+  return "unknown";
 }
 
+static ComboAddress pickrandom(vector<ComboAddress>& ips)
+{
+  return ips[random() % ips.size()];
+}
+
+static ComboAddress hashed(const ComboAddress& who, vector<ComboAddress>& ips)
+{
+  ComboAddress::addressOnlyHash aoh;
+  return ips[aoh(who) % ips.size()];
+}
+
+
 static ComboAddress wrandom(vector<pair<int,ComboAddress> >& wips)
 {
   int sum=0;
@@ -376,7 +378,7 @@ std::vector<shared_ptr<DNSRecordContent>> luaSynth(const std::string& code, cons
     });
   
   
-  lua.writeFunction("ifportup", [&bestwho](int port, const vector<pair<int, string> >& ips, const std::unordered_map<string,string>& options) {
+  lua.writeFunction("ifportup", [&bestwho](int port, const vector<pair<int, string> >& ips, const boost::optional<std::unordered_map<string,string>> options) {
       vector<ComboAddress> candidates;
       for(const auto& i : ips) {
         ComboAddress rem(i.second, port);
@@ -390,7 +392,22 @@ std::vector<shared_ptr<DNSRecordContent>> luaSynth(const std::string& code, cons
           ret.push_back(i.second);
       }
       else {
-        auto res=closest(bestwho, candidates);
+        ComboAddress res;
+        string selector="random";
+        if(options) {
+          if(options->count("selector"))
+            selector=options->find("selector")->second;
+        }
+        if(selector=="random")
+          res=pickrandom(candidates);
+        else if(selector=="closest")
+          res=closest(bestwho, candidates);
+        else if(selector=="hashed")
+          res=hashed(bestwho, candidates);
+        else {
+          L<<Logger::Warning<<"LUA Record ifportup called with unknown selector '"<<selector<<"'"<<endl;
+          res=pickrandom(candidates);
+        }
         ret.push_back(res.toString());
       }
       return ret;