]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
implement & hookup the lua hooks
authorBert Hubert <bert.hubert@netherlabs.nl>
Thu, 12 Jun 2008 18:39:32 +0000 (18:39 +0000)
committerBert Hubert <bert.hubert@netherlabs.nl>
Thu, 12 Jun 2008 18:39:32 +0000 (18:39 +0000)
git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@1196 d19b8d6e-7fed-0310-83ef-9ca221ded41b

pdns/Makefile-recursor
pdns/lua-pdns-recursor.cc
pdns/pdns_recursor.cc
pdns/rec_channel_rec.cc
pdns/syncres.hh

index c6b4b555df9e66207f328681063e1cef83277b21..ce0b7ebe1c316fdac901ca121276e66cde9cdec5 100644 (file)
@@ -14,8 +14,7 @@ PDNS_RECURSOR_OBJECTS=syncres.o  misc.o unix_utility.o qtype.o logger.o  \
 arguments.o lwres.o pdns_recursor.o recursor_cache.o dnsparser.o \
 dnswriter.o dnsrecords.o rcpgenerator.o base64.o zoneparser-tng.o \
 rec_channel.o rec_channel_rec.o malloc.o selectmplexer.o sillyrecords.o \
-dns_random.o aescrypt.o aeskey.o aes_modes.o aestab.o
-
+dns_random.o aescrypt.o aeskey.o aes_modes.o aestab.o lua-pdns-recursor.o
 
 REC_CONTROL_OBJECTS=rec_channel.o rec_control.o arguments.o 
 
@@ -25,15 +24,23 @@ all: message pdns_recursor rec_control
 # OS specific instructions
 -include sysdeps/$(shell uname).inc
 
+ifeq ($(LUA), 1)
+       LUALIBS=-llua5.1
+       CXXFLAGS+=-I/usr/include/lua5.1 -DPDNS_ENABLE_LUA
+endif
+
+
 ifeq ($(STATIC),semi)
-        STATICFLAGS=-Wl,-Bstatic -lstdc++ -lgcc -Wl,-Bdynamic -static-libgcc -lm -lc
+        STATICFLAGS=-Wl,-Bstatic -lstdc++ $(LUALIBS) -lgcc -Wl,-Bdynamic -static-libgcc -lm -lc
         LINKCC=$(CC)
-endif
-ifeq ($(STATIC),full)
-        STATICFLAGS=-lstdc++ -lm -static
+elseifeq ($(STATIC),full)
+        STATICFLAGS=-lstdc++ -lm $(LUALIBS) -static 
         LINKCC=$(CC)
+else
+       LDFLAGS += $(LUALIBS)
 endif
 
+
 LDFLAGS += $(PROFILEFLAGS) $(STATICFLAGS)
 
 message: 
index f6278df71d43a718323af25d48766f94c232de6a..8ccceb299798558e1dff1774676e50d419675470 100644 (file)
@@ -1,4 +1,39 @@
 #include "lua-pdns-recursor.hh"
+
+#ifdef PDNS_ENABLE_LUA
+#define PDNS_DO_LUA
+#endif
+
+#ifdef LIBDIR
+#define PDNS_DO_LUA
+#endif
+
+#if !defined(PDNS_DO_LUA) && !defined(LIBDIR)
+
+// stub implementation
+
+PowerDNSLua::PowerDNSLua(const std::string& fname)
+{
+  throw runtime_error("Lua support disabled");
+}
+
+bool PowerDNSLua::nxdomain(const ComboAddress& remote, const string& query, const QType& qtype, vector<DNSResourceRecord>& ret, int& res)
+{
+  return false;
+}
+
+bool PowerDNSLua::prequery(const ComboAddress& remote, const string& query, const QType& qtype, vector<DNSResourceRecord>& ret, int& res)
+{
+  return false;
+}
+
+PowerDNSLua::~PowerDNSLua()
+{
+
+}
+
+#else
+
 extern "C" {
 #undef L
 /* Include the Lua API header files. */
@@ -35,6 +70,8 @@ PowerDNSLua::PowerDNSLua(const std::string& fname)
 {
   d_lua = lua_open();
   luaopen_base(d_lua);
+  luaopen_string(d_lua);
+
   lua_settop(d_lua, 0);
   if(luaL_dofile(d_lua,  fname.c_str())) 
     throw runtime_error(string("Error loading LUA file '")+fname+"': "+ string(lua_isstring(d_lua, -1) ? lua_tostring(d_lua, -1) : "unknown error"));
@@ -95,12 +132,18 @@ bool PowerDNSLua::passthrough(const string& func, const ComboAddress& remote, co
     
     rr.qtype = QType((int)(lua_tonumber(d_lua, -1)));
     lua_pop(d_lua, 1);
-    
-    lua_pushnumber(d_lua, 2); // 4 is now '1'
+    lua_pushnumber(d_lua, 2); // 4 is now '2'
     lua_gettable(d_lua, 3);  // replace by the second entry of our table we hope
-    
     rr.content= lua_tostring(d_lua,  -1);
-    lua_pop(d_lua, 2); // content + table
+    lua_pop(d_lua, 1); // content 
+
+    lua_pushnumber(d_lua, 3); // 4 is now '3'
+    lua_gettable(d_lua, 3);  // replace by the second entry of our table we hope
+    rr.ttl = (uint32_t)lua_tonumber(d_lua,  -1);
+    lua_pop(d_lua, 1); // content 
+    
+
+    lua_pop(d_lua, 1); // table
 
     //    cerr<<"Adding content '"<<rr.content<<"'\n";
     ret.push_back(rr);
@@ -118,16 +161,6 @@ bool PowerDNSLua::passthrough(const string& func, const ComboAddress& remote, co
 
 PowerDNSLua::~PowerDNSLua()
 {
-  cerr<<"Destructor called"<<endl;
-  /* Remember to destroy the Lua State */
   lua_close(d_lua);
-  cerr<<"Done destroying"<<endl;
-}
-
-/*
-int main()
-{
-  PowerDNSLua pdl;
-  pdl.nxdomain(ComboAddress("127.0.0.1"), "ds9a.nl", QType(QType::A));
 }
-*/
+#endif
index 5554465211ad141c8ed7847600da43f48e71a0b5..f14dfb8e7324aaba679aec66dffd80b2eecd0a3f 100644 (file)
@@ -57,6 +57,7 @@
 #include "iputils.hh"
 #include "mplexer.hh"
 #include "config.h"
+#include "lua-pdns-recursor.hh"
 
 #ifndef RECURSOR
 #include "statbag.hh"
@@ -66,6 +67,7 @@ StatBag S;
 FDMultiplexer* g_fdm;
 unsigned int g_maxTCPPerClient;
 bool g_logCommonErrors;
+shared_ptr<PowerDNSLua> g_pdl;
 using namespace boost;
 
 #ifdef __FreeBSD__           // see cvstrac ticket #26
@@ -534,7 +536,14 @@ void startDoResolve(void *p)
     if(!dc->d_mdp.d_header.rd)
       sr.setCacheOnly();
 
-    int res=sr.beginResolve(dc->d_mdp.d_qname, QType(dc->d_mdp.d_qtype), dc->d_mdp.d_qclass, ret);
+    int res;
+
+    if(!g_pdl.get() || !g_pdl->prequery(dc->d_remote, dc->d_mdp.d_qname, QType(dc->d_mdp.d_qtype), ret, res)) 
+       res = sr.beginResolve(dc->d_mdp.d_qname, QType(dc->d_mdp.d_qtype), dc->d_mdp.d_qclass, ret);
+
+    if(g_pdl.get() && (res < 0 || res == RCode::NXDomain || res == RCode::ServFail)) {
+      g_pdl->nxdomain(dc->d_remote, dc->d_mdp.d_qname, QType(dc->d_mdp.d_qtype), ret, res);
+    }
 
     if(res<0) {
       pw.getHeader()->rcode=RCode::ServFail;
@@ -1610,6 +1619,35 @@ void parseAuthAndForwards()
   }
 }
 
+string doReloadLuaScript(vector<string>::const_iterator begin, vector<string>::const_iterator end)
+{
+  string fname=::arg()["lua-dns-script"];
+  try {
+    if(begin==end) {
+      if(!fname.empty()) 
+       g_pdl = shared_ptr<PowerDNSLua>(new PowerDNSLua(fname));
+      else
+       throw runtime_error("Asked to relead lua scripts, but no name passed and no default ('lua-dns-script') defined");
+    }
+    else {
+      fname=*begin;
+      if(fname.empty()) {
+       g_pdl.reset();
+       L<<Logger::Error<<"Unloaded current lua script"<<endl;
+       return "unloaded current lua script\n";
+      }
+      else
+       g_pdl = shared_ptr<PowerDNSLua>(new PowerDNSLua(fname));
+    }
+  }
+  catch(exception& e) {
+    L<<Logger::Error<<"Retaining current script, error from '"<<fname<<"': "<< e.what() <<endl;
+    return string("Retaining current script, error from '"+fname+"': "+string(e.what())+"\n");
+  }
+  L<<Logger::Warning<<"(Re)loaded lua script from '"<<fname<<"'"<<endl;
+  return "ok - loaded script from '"+fname+"'\n";
+}
+
 void seedRandom(const string& source);
 
 int serviceMain(int argc, char*argv[])
@@ -1718,6 +1756,19 @@ int serviceMain(int argc, char*argv[])
   }
   
   parseAuthAndForwards();
+
+  try {
+    if(!::arg()["lua-dns-script"].empty()) {
+      g_pdl = shared_ptr<PowerDNSLua>(new PowerDNSLua(::arg()["lua-dns-script"]));
+      L<<Logger::Warning<<"Loaded 'lua' script from '"<<::arg()["lua-dns-script"]<<"'"<<endl;
+    }
+    
+  }
+  catch(exception &e) {
+    L<<Logger::Error<<"Failed to load 'lua' script from '"<<::arg()["lua-dns-script"]<<"': "<<e.what()<<endl;
+    exit(99);
+  }
+
   
   g_stats.remotes.resize(::arg().asNum("remotes-ringbuffer-entries"));
   if(!g_stats.remotes.empty())
@@ -1886,6 +1937,7 @@ int main(int argc, char **argv)
   //  HTimer mtimer("main");
   //  mtimer.start();
 
+
   g_stats.startupTime=time(0);
   reportBasicTypes();
 
@@ -1952,6 +2004,7 @@ int main(int argc, char **argv)
     ::arg().set("export-etc-hosts", "If we should serve up contents from /etc/hosts")="off";
     ::arg().set("serve-rfc1918", "If we should be authoritative for RFC 1918 private IP space")="";
     ::arg().set("auth-can-lower-ttl", "If we follow RFC 2181 to the letter, an authoritative server can lower the TTL of NS records")="off";
+    ::arg().set("lua-dns-script", "Filename containing an optional 'lua' script that will be used to modify dns answers")="";
     ::arg().setSwitch( "ignore-rd-bit", "Assume each packet requires recursion, for compatability" )= "off"; 
 
     ::arg().setCmd("help","Provide a helpful message");
index 58eb3cfa82abdcd91932a57e3cd5d58013c72c78..5b5ea02b51c5ca51650f2b35b1440766f19c38bd 100644 (file)
@@ -298,6 +298,16 @@ string RecursorControlParser::getAnswer(const string& question, RecursorControlP
   if(cmd=="wipe-cache") 
     return doWipeCache(begin, end);
 
+  if(cmd=="reload-lua-script") 
+    return doReloadLuaScript(begin, end);
+
+  if(cmd=="unload-lua-script") {
+    vector<string> empty;
+    empty.push_back(string());
+    return doReloadLuaScript(empty.begin(), empty.end());
+  }
+
+
   if(cmd=="top-remotes")
     return doTopRemotes();
 
index 7d455136dc7fd628d510965165c06fb32b87e42a..81d746e16e961707d29751c164bd5048dac93506 100644 (file)
@@ -501,6 +501,8 @@ struct RecursorStats
   }
 };
 
+string doReloadLuaScript(vector<string>::const_iterator begin, vector<string>::const_iterator end);
+
 extern RecursorStats g_stats;