]> granicus.if.org Git - pdns/commitdiff
fix lua5.0 compatability for the enterprisetards, plus spiff up the lua bridge to...
authorBert Hubert <bert.hubert@netherlabs.nl>
Sat, 14 Jun 2008 12:23:11 +0000 (12:23 +0000)
committerBert Hubert <bert.hubert@netherlabs.nl>
Sat, 14 Jun 2008 12:23:11 +0000 (12:23 +0000)
'place' of answers and the rcode, plus optional ability to override the qname

git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@1198 d19b8d6e-7fed-0310-83ef-9ca221ded41b

pdns/Makefile-recursor
pdns/lua-pdns-recursor.cc
pdns/lua-pdns-recursor.hh
pdns/pdns_recursor.cc
pdns/powerdns-example-script.lua

index c9d086859dd7b54a8be2e8ca83dcb92524be012c..7fed2415ea5e63628a712daff7518c32a2b4511c 100644 (file)
@@ -8,8 +8,13 @@ CFLAGS:=$(CFLAGS) -Wall $(OPTFLAGS) $(PROFILEFLAGS)
 LINKCC=$(CXX)
 CC?=gcc
 
-LUA_CPPFLAGS_CONFIG ?= -I/usr/include/lua5.1
-LUA_LIBS_CONFIG ?= -llua5.1
+# Lua 5.1 settings
+#LUA_CPPFLAGS_CONFIG ?= -I/usr/include/lua5.1
+#LUA_LIBS_CONFIG ?= -llua5.1
+
+# Lua 5.0 settings
+LUA_CPPFLAGS_CONFIG=-I/usr/include/lua50 
+LUA_LIBS_CONFIG=-llua50 -llualib50
 
 # static dependencies
 
index a6ceef5e82cd7c8bbb3cfe39dd88b9cd98c5064e..4109209986227db4e79b6dbf9510164a54fb6b1d 100644 (file)
@@ -65,7 +65,11 @@ PowerDNSLua::PowerDNSLua(const std::string& fname)
   luaopen_string(d_lua);
 
   lua_settop(d_lua, 0);
+#ifndef LUA_VERSION_NUM
+  if(lua_dofile(d_lua,  fname.c_str())) 
+#else
   if(luaL_dofile(d_lua,  fname.c_str())) 
+#endif
     throw runtime_error(string("Error loading LUA file '")+fname+"': "+ string(lua_isstring(d_lua, -1) ? lua_tostring(d_lua, -1) : "unknown error"));
   
   lua_pushcfunction(d_lua, netmaskMatchLua);
@@ -82,6 +86,36 @@ bool PowerDNSLua::prequery(const ComboAddress& remote, const string& query, cons
   return passthrough("prequery", remote, query, qtype, ret, res);
 }
 
+bool PowerDNSLua::getFromTable(const std::string& key, std::string& value)
+{
+  lua_pushstring(d_lua, key.c_str()); // 4 is now '1'
+  lua_gettable(d_lua, -2);  // replace by the first entry of our table we hope
+
+  bool ret=false;
+  if(!lua_isnil(d_lua, -1)) {
+    value = lua_tostring(d_lua, -1);
+    ret=true;
+  }
+  lua_pop(d_lua, 1);
+  return ret;
+}
+
+
+bool PowerDNSLua::getFromTable(const std::string& key, uint32_t& value)
+{
+  lua_pushstring(d_lua, key.c_str()); // 4 is now '1'
+  lua_gettable(d_lua, -2);  // replace by the first entry of our table we hope
+
+  bool ret=false;
+  if(!lua_isnil(d_lua, -1)) {
+    value = lua_tonumber(d_lua, -1);
+    ret=true;
+  }
+  lua_pop(d_lua, 1);
+  return ret;
+}
+
+
 bool PowerDNSLua::passthrough(const string& func, const ComboAddress& remote, const string& query, const QType& qtype, vector<DNSResourceRecord>& ret, int& res)
 {
   lua_getglobal(d_lua,  func.c_str());
@@ -96,11 +130,14 @@ bool PowerDNSLua::passthrough(const string& func, const ComboAddress& remote, co
   lua_pushnumber(d_lua,  qtype.getCode() );
 
   lua_call(d_lua,  3, 2);
-  if(!lua_toboolean(d_lua, 1)) {
+  res = lua_tonumber(d_lua, 1); // new rcode
+  if(res < 0) {
     //    cerr << "handler did not handle"<<endl;
     lua_pop(d_lua, 2);
     return false;
   }
+  else
+    cerr<<"res = "<<res<<endl;
 
   /* get the result */
   DNSResourceRecord rr;
@@ -110,31 +147,31 @@ bool PowerDNSLua::passthrough(const string& func, const ComboAddress& remote, co
 
   ret.clear();
 
-  //  cerr<<"Think there are "<<lua_objlen(d_lua, 2)<<" records\n";
+  /*           1       2   3   4   */
+  /* stack:  boolean table key row */
 
-  /*           1       2   */
-  /* stack:  boolean table */
+  lua_pushnil(d_lua);  /* first key */
+  while (lua_next(d_lua, 2) != 0) {
 
-  for(unsigned int n = 0 ; n <= lua_objlen(d_lua, 2); ++n) {
-    lua_pushnumber(d_lua, n); // becomes 3
-    lua_gettable(d_lua, 2);  // 3 gone, replaced by table[0] - which is again a table
+    uint32_t tmpnum;
+    if(!getFromTable("qtype", tmpnum)) 
+      rr.qtype=QType::A;
+    else
+      rr.qtype=tmpnum;
 
-    lua_pushnumber(d_lua, 1); // 4 is now '1'
-    lua_gettable(d_lua, 3);  // replace by the first entry of our table we hope
-    
-    rr.qtype = QType((int)(lua_tonumber(d_lua, -1)));
-    lua_pop(d_lua, 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, 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 
-    
+    getFromTable("content", rr.content);
+    if(!getFromTable("ttl", rr.ttl))
+      rr.ttl=3600;
 
+    if(!getFromTable("qname", rr.qname))
+      rr.qname = query;
+
+    if(!getFromTable("place", tmpnum))
+      rr.d_place = DNSResourceRecord::ANSWER;
+    else
+      rr.d_place = (DNSResourceRecord::Place) tmpnum;
+
+    /* removes 'value'; keeps 'key' for next iteration */
     lua_pop(d_lua, 1); // table
 
     //    cerr<<"Adding content '"<<rr.content<<"'\n";
@@ -143,11 +180,6 @@ bool PowerDNSLua::passthrough(const string& func, const ComboAddress& remote, co
 
   lua_pop(d_lua, 2);
 
-  //  printf("\nBack to C again: %s, type %d\n\n", rr.content.c_str(), rr.qtype.getCode());
-
-  res=0;
-
-
   return true;
 }
 
index b60824958e538bd3810d293d82793d9b4ab95817..4b2309ad5bafd9c7cfb50258d242fcf331fe0f63 100644 (file)
@@ -16,6 +16,8 @@ public:
 private:
   lua_State* d_lua;
   bool passthrough(const string& func, const ComboAddress& remote, const string& query, const QType& qtype, vector<DNSResourceRecord>& ret, int& res);
+  bool getFromTable(const std::string& key, std::string& value);
+  bool getFromTable(const std::string& key, uint32_t& value);
   bool d_failed;
 };
 
index 1d4bd7824930381bd5a9f52a2c1d3c7d1f8983d0..e8f26042b3292a444214cf6c7fc8444db7dc52fb 100644 (file)
@@ -317,9 +317,9 @@ int asendto(const char *data, int len, int flags,
 
   for(; chain.first != chain.second; chain.first++) {
     if(chain.first->key.fd > -1) { // don't chain onto existing chained waiter!
-      //      cerr<<"Orig: "<<pident.domain<<", "<<pident.remote.toString()<<", id="<<id<<endl;
-      // cerr<<"Had hit: "<< chain.first->key.domain<<", "<<chain.first->key.remote.toString()<<", id="<<chain.first->key.id
-      // <<", count="<<chain.first->key.chain.size()<<", origfd: "<<chain.first->key.fd<<endl;
+      cerr<<"Orig: "<<pident.domain<<", "<<pident.remote.toString()<<", id="<<id<<endl;
+      cerr<<"Had hit: "<< chain.first->key.domain<<", "<<chain.first->key.remote.toString()<<", id="<<chain.first->key.id
+         <<", count="<<chain.first->key.chain.size()<<", origfd: "<<chain.first->key.fd<<endl;
       
       chain.first->key.chain.insert(id); // we can chain
       *fd=-1;                            // gets used in waitEvent / sendEvent later on
@@ -538,11 +538,12 @@ void startDoResolve(void *p)
 
     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)) 
+    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(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) {
@@ -1243,15 +1244,18 @@ void handleTCPClientWritable(int fd, FDMultiplexer::funcparam_t& var)
 // resend event to everybody chained onto it
 void doResends(MT_t::waiters_t::iterator& iter, PacketID resend, const string& content)
 {
+
   if(iter->key.chain.empty())
     return;
 
+  cerr<<"doResends called!\n";
   for(PacketID::chain_t::iterator i=iter->key.chain.begin(); i != iter->key.chain.end() ; ++i) {
     resend.fd=-1;
     resend.id=*i;
+    cerr<<"\tResending "<<content.size()<<" bytes for fd="<<resend.fd<<" and id="<<resend.id<<endl;
+
     MT->sendEvent(resend, &content);
     g_stats.chainResends++;
-    //    cerr<<"\tResending "<<content.size()<<" bytes for fd="<<resend.fd<<" and id="<<resend.id<<": "<< res <<endl;
   }
 }
 
@@ -1868,6 +1872,7 @@ int serviceMain(int argc, char*argv[])
 
     Utility::gettimeofday(&g_now, 0);
     g_fdm->run(&g_now);
+    Utility::gettimeofday(&g_now, 0);
 
     if(listenOnTCP) {
       if(TCPConnection::s_currentConnections > maxTcpClients) {  // shutdown
index 8f709b95a7caaf84028838765444484048c0b214..dcbe5f4560f72e911e2962dff34d71c589d7c2ce 100644 (file)
@@ -2,17 +2,21 @@ function prequery ( ip, domain, qtype )
        print ("prequery handler called for: ", ip, domain, qtype)
        ret = {}
        
-       ret[0]= {1, "9.8.7.6", 3601};
-       ret[1]= {1, "10.11.12.13", 3601};
-       ret[2]= {1, "11.12.13.14", 3601};
-
+--     ret[1]= {1, "10.11.12.13", 3601};
+--     ret[2]= {1, "11.12.13.14", 3601};
        if domain == "www.ds9c.nl." 
        then
+               ret[0]= {qtype=1, content="9.8.7.6", ttl=3601}
+               ret[1]= {qtype=1, content="1.2.3.4", ttl=3601}
                print "dealing!"
-               return 1, ret
+               return 0, ret
+       elseif domain == "www.baddomain.com."
+       then
+               print "dealing - nx"
+               return 3, ret
        else
                print "not dealing!"
-               return false, ret
+               return -1, ret
        end
 end
 
@@ -20,16 +24,18 @@ function nxdomain ( ip, domain, qtype )
        print ("nxhandler called for: ", ip, domain, qtype)
        ret={}
        if qtype ~= 1 then return false, ret end  --  only A records
-       if not string.match(domain, "^www.") then return false, ret end  -- only things that start with www.
+--     if not string.match(domain, "^www.") then return false, ret end  -- only things that start with www.
        
        if matchnetmask(ip, "127.0.0.1/8")
        then 
                print "dealing"
-               ret[0]={1, "127.1.2.3", 3602}
-               ret[1]={15, "25 ds9a.nl", 3602}
-               return 1, ret
+               ret[0]={qtype="5", content="www.webserver.com", ttl=3602}
+               ret[1]={qname="www.webserver.com", qtype="1", content="1.2.3.4", ttl=3602}
+               ret[2]={qname="webserver.com", qtype="2", content="ns1.webserver.com", place=2}
+--             ret[1]={15, "25 ds9a.nl", 3602}
+               return 0, ret
        else
                print "not dealing"
-               return false, ret
+               return -1, ret
        end
 end