Permalink
Browse files

implement Lua pre-query filter, executed before we ask a question to …

…an authoritative server from the recursor, plus add sample script for ezdns
  • Loading branch information...
1 parent 77b9f5f commit 3457a2a0ec41d3b3aff7640f30008788e1228a6e @ahupowerdns ahupowerdns committed Dec 28, 2014
Showing with 47 additions and 9 deletions.
  1. +9 −2 pdns/lua-recursor.cc
  2. +1 −0 pdns/lua-recursor.hh
  3. +3 −0 pdns/pdns_recursor.cc
  4. +11 −1 pdns/powerdns-example-script.lua
  5. +2 −0 pdns/rec_channel.hh
  6. +13 −4 pdns/syncres.cc
  7. +8 −2 pdns/syncres.hh
View
@@ -155,14 +155,20 @@ 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)
{
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);
@@ -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);
@@ -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;
@@ -157,4 +157,14 @@ function hidettl ( remoteip, domain, qtype, records, origrcode )
val.ttl=0
end
return origrcode, records
-end
+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
View
@@ -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
View
@@ -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);
View
@@ -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;

0 comments on commit 3457a2a

Please sign in to comment.