]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
initial Lua support
authorBert Hubert <bert.hubert@netherlabs.nl>
Thu, 12 Jun 2008 13:06:06 +0000 (13:06 +0000)
committerBert Hubert <bert.hubert@netherlabs.nl>
Thu, 12 Jun 2008 13:06:06 +0000 (13:06 +0000)
git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@1191 d19b8d6e-7fed-0310-83ef-9ca221ded41b

pdns/lua-pdns-recursor.cc [new file with mode: 0644]
pdns/lua-pdns-recursor.hh [new file with mode: 0644]

diff --git a/pdns/lua-pdns-recursor.cc b/pdns/lua-pdns-recursor.cc
new file mode 100644 (file)
index 0000000..f1bc297
--- /dev/null
@@ -0,0 +1,142 @@
+#include "lua-pdns-recursor.hh"
+extern "C" {
+#undef L
+/* Include the Lua API header files. */
+#include <lua.h>
+#include <lauxlib.h>
+#include <lualib.h>
+}
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string>
+#include <vector>
+
+using namespace std;
+
+extern "C" int netmaskMatchLua(lua_State *lua)
+{
+  bool result=false;
+  if(lua_gettop(lua) == 2) {
+    string ip=lua_tostring(lua, 1);
+    string netmask=lua_tostring(lua, 2);
+
+    Netmask nm(netmask);
+    ComboAddress ca(ip);
+    
+    result = nm.match(ip);
+  }
+  lua_pushboolean(lua, result);
+  return 1;
+}
+
+PowerDNSLua::PowerDNSLua()
+{
+  d_lua = lua_open();
+  luaopen_base(d_lua);
+  lua_settop(d_lua, 0);
+  if(luaL_dofile(d_lua,  "./script.lua")) {
+    cerr<<"Error loading LUA file: ";
+    if (lua_isstring(d_lua, -1)) 
+      cerr<<lua_tostring(d_lua, -1);
+    cerr<<endl;
+
+    d_failed=true;
+  }
+  lua_pushcfunction(d_lua, netmaskMatchLua);
+  lua_setglobal(d_lua, "matchnetmask");
+  d_failed=false;
+}
+
+bool PowerDNSLua::nxdomain(const ComboAddress& remote, const string& query, const QType& qtype, vector<DNSResourceRecord>& ret, int& res)
+{
+  return passthrough("nxdomain", remote, query, qtype, ret, res);
+}
+
+bool PowerDNSLua::prequery(const ComboAddress& remote, const string& query, const QType& qtype, vector<DNSResourceRecord>& ret, int& res)
+{
+  return passthrough("prequery", remote, query, qtype, ret, res);
+}
+
+bool PowerDNSLua::passthrough(const string& func, const ComboAddress& remote, const string& query, const QType& qtype, vector<DNSResourceRecord>& ret, int& res)
+{
+  if(d_failed)
+    return false;
+
+  /* the function name */
+  lua_getglobal(d_lua,  func.c_str());
+  if(!lua_isfunction(d_lua, -1)) {
+    cerr<<"No such function '"<<func<<"'\n";
+    lua_pop(d_lua, 1);
+    return false;
+  }
+  /* the first argument */
+  lua_pushstring(d_lua,  remote.toString().c_str() );
+  lua_pushstring(d_lua,  query.c_str() );
+  lua_pushnumber(d_lua,  qtype.getCode() );
+
+  lua_call(d_lua,  3, 2);
+  if(!lua_toboolean(d_lua, 1)) {
+    //    cerr << "handler did not handle"<<endl;
+    lua_pop(d_lua, 2);
+    return false;
+  }
+
+  /* get the result */
+  DNSResourceRecord rr;
+  rr.qname = query;
+  rr.d_place = DNSResourceRecord::ANSWER;
+  rr.ttl = 3600;
+
+  ret.clear();
+
+  //  cerr<<"Think there are "<<lua_objlen(d_lua, 2)<<" records\n";
+
+  /*           1       2   */
+  /* stack:  boolean table */
+
+  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
+
+    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 '1'
+    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
+
+    //    cerr<<"Adding content '"<<rr.content<<"'\n";
+    ret.push_back(rr);
+  }
+
+  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;
+}
+
+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));
+}
+*/
diff --git a/pdns/lua-pdns-recursor.hh b/pdns/lua-pdns-recursor.hh
new file mode 100644 (file)
index 0000000..99c9579
--- /dev/null
@@ -0,0 +1,22 @@
+#ifndef PDNS_LUA_PDNS_RECURSOR_HH
+#define PDNS_LUA_PDNS_RECURSOR_HH
+#include "dns.hh"
+#include "iputils.hh"
+
+struct lua_State;
+
+class PowerDNSLua
+{
+public:
+  PowerDNSLua();
+  ~PowerDNSLua();
+  void reload();
+  bool prequery(const ComboAddress& remote, const string& query, const QType& qtype, vector<DNSResourceRecord>& res, int& ret);
+  bool nxdomain(const ComboAddress& remote, const string& query, const QType& qtype, vector<DNSResourceRecord>& res, int& ret);
+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 d_failed;
+};
+
+#endif