]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
implement Lua pre-query filter, executed before we ask a question to an authoritative...
authorbert hubert <bert.hubert@netherlabs.nl>
Sun, 28 Dec 2014 14:26:36 +0000 (15:26 +0100)
committerbert hubert <bert.hubert@netherlabs.nl>
Sun, 28 Dec 2014 14:26:36 +0000 (15:26 +0100)
pdns/lua-recursor.cc
pdns/lua-recursor.hh
pdns/pdns_recursor.cc
pdns/powerdns-example-script.lua
pdns/rec_channel.hh
pdns/syncres.cc
pdns/syncres.hh

index 4ac6bdd99b1d0ead334a9d07f2645913b3d81ddd..ee06b98284ce41fe0d4a767207ba8b85faae8c36 100644 (file)
@@ -155,6 +155,12 @@ bool RecursorLua::postresolve(const ComboAddress& remote, const ComboAddress& lo
   return passthrough("postresolve", remote, local, query, qtype, ret, res, variable);
 }
 
+bool RecursorLua::prequery(const ComboAddress& remote, const ComboAddress& local,const string& query, const QType& qtype, vector<DNSResourceRecord>& ret, int& res)
+{
+  return passthrough("prequery", remote, local, query, qtype, ret, res, 0);
+}
+
+
 
 bool RecursorLua::passthrough(const string& func, const ComboAddress& remote, const ComboAddress& local, const string& query, const QType& qtype, vector<DNSResourceRecord>& ret, 
   int& res, bool* variable)
@@ -162,7 +168,7 @@ bool RecursorLua::passthrough(const string& func, const ComboAddress& remote, co
   d_variable = false;
   lua_getglobal(d_lua,  func.c_str());
   if(!lua_isfunction(d_lua, -1)) {
-    //  cerr<<"No such function '"<<func<<"'\n";
+    //    cerr<<"No such function '"<<func<<"'\n";
     lua_pop(d_lua, 1);
     return false;
   }
@@ -191,7 +197,8 @@ bool RecursorLua::passthrough(const string& func, const ComboAddress& remote, co
     return false;
   }
 
-  *variable |= d_variable;
+  if(variable)
+    *variable |= d_variable;
     
   if(!lua_isnumber(d_lua, 1)) {
     string tocall = lua_tostring(d_lua,1);
index 62eaead2aa75c62ed848594c7b0d5a3a1829968a..9dee98816cd3835cae05c6feb0056a409a16f053 100644 (file)
@@ -13,6 +13,7 @@ public:
   bool nxdomain(const ComboAddress& remote, const ComboAddress& local, const string& query, const QType& qtype, vector<DNSResourceRecord>& res, int& ret, bool* variable);
   bool nodata(const ComboAddress& remote, const ComboAddress& local, const string& query, const QType& qtype, vector<DNSResourceRecord>& res, int& ret, bool* variable);
   bool postresolve(const ComboAddress& remote, const ComboAddress& local, const string& query, const QType& qtype, vector<DNSResourceRecord>& res, int& ret, bool* variable);
+  bool prequery(const ComboAddress& requestor, const ComboAddress& ns, const string& query, const QType& qtype, vector<DNSResourceRecord>& res, int& ret);
 
 private:
   bool passthrough(const string& func, const ComboAddress& remote,const ComboAddress& local, const string& query, const QType& qtype, vector<DNSResourceRecord>& ret, int& res, bool* variable);
index 158c7b8c6799d67cdcd1c6cd129251996d26a1c9..c54c927370f1969ea1138ea7f7313be22856eb2d 100644 (file)
@@ -542,6 +542,9 @@ void startDoResolve(void *p)
     uint32_t minTTL=std::numeric_limits<uint32_t>::max();
 
     SyncRes sr(dc->d_now);
+    if(t_pdl) {
+      sr.setLuaEngine(*t_pdl);
+    }
     bool tracedQuery=false; // we could consider letting Lua know about this too
     bool variableAnswer = false;
 
index 7d49fd106305b0d39235bd0c54005026a35ee509..145835745e79c27c7e7f1ae1384d1de12479e865 100644 (file)
@@ -157,4 +157,14 @@ function hidettl ( remoteip, domain, qtype, records, origrcode )
                val.ttl=0
        end
        return origrcode, records
-end
\ No newline at end of file
+end
+
+function prequery(remoteip, domain, qtype)
+       print("pdns wants to ask "..remoteip.." about "..domain.." "..qtype)
+       if(remoteip=="192.121.121.14")
+       then
+               return -3,{}
+       else
+               return -1,{}
+       end
+end
index cd8bae6e1104cc9f8723afd0bdf1ad078c87fad0..144e6564c070027aa131f2f3f5eede75f459c7b8 100644 (file)
@@ -2,6 +2,7 @@
 #define PDNS_REC_CHANNEL
 #include <string>
 #include <map>
+#include <vector>
 #include <inttypes.h>
 #include <sys/un.h>
 #include <pthread.h>
@@ -42,4 +43,5 @@ private:
 std::map<std::string, std::string> getAllStatsMap();
 extern pthread_mutex_t g_carbon_config_lock;
 void sortPublicSuffixList();
+std::vector<std::pair<std::string, uint16_t> >* pleaseGetQueryRing();
 #endif 
index dab3a5bb99f474b376755100e221cc4526cc6ac0..c351534b86c704aabf129fa80c8a2226440de53c 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <boost/algorithm/string.hpp>
 #include <boost/foreach.hpp>
+#include "lua-recursor.hh"
 #include "utility.hh"
 #include "syncres.hh"
 #include <iostream>
@@ -72,8 +73,8 @@ bool SyncRes::s_noEDNSPing;
 bool SyncRes::s_noEDNS;
 
 SyncRes::SyncRes(const struct timeval& now) :  d_outqueries(0), d_tcpoutqueries(0), d_throttledqueries(0), d_timeouts(0), d_unreachables(0),
-                                                 d_now(now),
-                                                 d_cacheonly(false), d_nocache(false),   d_doEDNS0(false), d_lm(s_lm)
+                                              d_now(now),
+                                              d_cacheonly(false), d_nocache(false),   d_doEDNS0(false), d_lm(s_lm)
                                                  
 { 
   if(!t_sstorage) {
@@ -932,9 +933,17 @@ int SyncRes::doResolveAt(set<string, CIStringCompare> nameservers, string auth,
               s_tcpoutqueries++; d_tcpoutqueries++;
             }
             
-            resolveret=asyncresolveWrapper(*remoteIP, qname,  qtype.getCode(), 
+           if(d_pdl && d_pdl->prequery(*remoteIP, *remoteIP, qname, qtype, lwr.d_result, resolveret)) {
+             LOG(prefix<<qname<<": query handled by Lua"<<endl);
+           }
+           else 
+             resolveret=asyncresolveWrapper(*remoteIP, qname,  qtype.getCode(), 
                                            doTCP, sendRDQuery, &d_now, &lwr);    // <- we go out on the wire!
-              
+
+            if(resolveret==-3)
+             throw ImmediateServFailException("Query killed by policy");
+
+
            if(resolveret != 1) {
               if(resolveret==0) {
                 LOG(prefix<<qname<<": timeout resolving after "<<lwr.d_usec/1000.0<<"msec "<< (doTCP ? "over TCP" : "")<<endl);
index c1df0d1c60eba71cc6c987a03d26382452ff8d69..0ebbb7d069cb66998be3a386251dedb096bc9ea6 100644 (file)
@@ -23,7 +23,7 @@
 #include "iputils.hh"
 
 void primeHints(void);
-
+class RecursorLua;
 struct NegCacheEntry
 {
   string d_name;
@@ -278,6 +278,12 @@ public:
     return d_trace.str();
   }
 
+  void setLuaEngine(shared_ptr<RecursorLua> pdl)
+  {
+    d_pdl = pdl;
+  }
+
+
   int asyncresolveWrapper(const ComboAddress& ip, const string& domain, int type, bool doTCP, bool sendRDQuery, struct timeval* now, LWResult* res);
   
   static void doEDNSDumpAndClose(int fd);
@@ -444,9 +450,9 @@ private:
   inline vector<string> shuffleInSpeedOrder(set<string, CIStringCompare> &nameservers, const string &prefix);
   bool moreSpecificThan(const string& a, const string &b);
   vector<ComboAddress> getAddrs(const string &qname, int depth, set<GetBestNSAnswer>& beenthere);
-
 private:
   ostringstream d_trace;
+  shared_ptr<RecursorLua> d_pdl;
   string d_prefix;
   bool d_cacheonly;
   bool d_nocache;