]> granicus.if.org Git - pdns/commitdiff
fix up lua 5.0 support for libraries, add error handling for lua runtime errors,...
authorBert Hubert <bert.hubert@netherlabs.nl>
Sat, 14 Jun 2008 19:55:57 +0000 (19:55 +0000)
committerBert Hubert <bert.hubert@netherlabs.nl>
Sat, 14 Jun 2008 19:55:57 +0000 (19:55 +0000)
git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@1199 d19b8d6e-7fed-0310-83ef-9ca221ded41b

pdns/Makefile-recursor
pdns/docs/pdns.sgml
pdns/lua-pdns-recursor.cc

index 7fed2415ea5e63628a712daff7518c32a2b4511c..6a1597e3e0b0a6aaf2ec1edecf3b8704847fe78d 100644 (file)
@@ -9,12 +9,12 @@ LINKCC=$(CXX)
 CC?=gcc
 
 # Lua 5.1 settings
-#LUA_CPPFLAGS_CONFIG ?= -I/usr/include/lua5.1
-#LUA_LIBS_CONFIG ?= -llua5.1
+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
+#LUA_CPPFLAGS_CONFIG=-I/usr/include/lua50 
+#LUA_LIBS_CONFIG=-llua50 -llualib50
 
 # static dependencies
 
index 4bd8d604bbf58a8a504036107ce883d3b2b62849..e90d3245b604f712c0d73409a8a09cbdd0fe5263 100644 (file)
@@ -8203,8 +8203,8 @@ Feb 10 14:16:03 stats: 125784 questions, 13971 cache entries, 309 negative entri
          have taken over the request, or want to let normal proceedings take their course.
        </para>
        <para>
-         If a function has taken over a request, it should return 'true', and specify a table with records to be put in the answer section of a packet. 
-         Returning 'false' and an empty table signifies that the function chose not to intervene.
+         If a function has taken over a request, it should return an rcode (usually 0), and specify a table with records to be put in the answer section of a packet. 
+         Returning -1 and an empty table signifies that the function chose not to intervene.
        </para>
        <para>
          A minimal sample script:
@@ -8215,16 +8215,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 matchnetmask(ip, "192.168.0.0/16")  then return false, ret -- only interfere with local queries
-
-  ret[0]={1, "127.1.2.3", 3600}    -- add IN A 127.1.2.3
-  ret[1]={1  "127.3.2.1", 3600}    -- add IN A 127.3.2.1
-  return true, ret                 -- return true, plus records
+  if qtype ~= 1 then return -1, ret end  --  only A records
+  if not string.gmatch(domain, "^www.") then return -1, ret end  -- only things that start with www.
+  if not matchnetmask(ip, "10.0.0.0/8")  then return -1, ret end -- only interfere with local queries
+  ret[0]={qtype=1, content="127.1.2.3"}    -- add IN A 127.1.2.3
+  ret[1]={qtype=1, content="127.3.2.1"}    -- add IN A 127.3.2.1
+  return 0, ret                 -- return true, plus records
 end
          </screen>
        </para>
+       <para>
+         For Lua 5.0, use <function>string.find</function> instead of <function>string.gmatch</function>.
+       </para>
        <para>
          <warning>
            <para>
@@ -8238,6 +8240,58 @@ end
          The exception is that, unlike in the datbase, there is no 'prio' field, which means that an MX record with priority 25 pointing to 'smtp.mailserver.com' would be encoded as
          '25 smtp.mailserver.com.'.
        </para>
+       <para>
+         Useful return 'rcodes' include 0 for "no error" and 3 for "NXDOMAIN".
+       </para>
+       <para>
+         Useful fields that can be set in the return table include:
+         <variablelist>
+           <varlistentry>
+             <term>content</term>
+             <listitem>
+               <para>
+                 Content of the record, as specified above in 'zone file format'. No default, mandatory field.
+               </para>
+             </listitem>
+           </varlistentry>
+           <varlistentry>
+             <term>place</term>
+             <listitem>
+               <para>
+                 Place of this record. Defaults to 1, indicating 'Answer' section. Can also be 2, for Authority of 3 for Additional.
+                 When using this rare feature, always emit records with 'Place' in ascending order. This field is usually not needed.
+               </para>
+             </listitem>
+           </varlistentry>
+
+           <varlistentry>
+             <term>qname</term>
+             <listitem>
+               <para>
+                 qname of the answer, the 'name' of the record. Defaults to the name of the query, which is almost always correct except when
+                 specifying additional records or rolling out a CNAME chain.
+               </para>
+             </listitem>
+           </varlistentry>
+           <varlistentry>
+             <term>qtype</term>
+             <listitem>
+               <para>
+                 Currently the numerical qtype of the answer, defaulting to '1' which is an A record. '2' is an NS record, '5' a CNAME and '15' an MX record.
+               </para>
+             </listitem>
+           </varlistentry>
+           <varlistentry>
+             <term>ttl</term>
+             <listitem>
+               <para>
+                 Time to live of a record. Defaults to 3600. Be sure not to specify differing TTLs within answers with an identical qname. While this
+                 can be encoded in DNS, results may be undesired.
+               </para>
+             </listitem>
+           </varlistentry>
+         </variablelist>
+       </para>
       </sect2>
     </sect1>
     <sect1 id="recursor-design-and-engineering">
index 4109209986227db4e79b6dbf9510164a54fb6b1d..0be22a8a3453af5b84ae2dfff0476fa53ce24479 100644 (file)
@@ -61,16 +61,19 @@ extern "C" int netmaskMatchLua(lua_State *lua)
 PowerDNSLua::PowerDNSLua(const std::string& fname)
 {
   d_lua = lua_open();
+
+#ifndef LUA_VERSION_NUM
   luaopen_base(d_lua);
   luaopen_string(d_lua);
 
-  lua_settop(d_lua, 0);
-#ifndef LUA_VERSION_NUM
   if(lua_dofile(d_lua,  fname.c_str())) 
 #else
+  luaL_openlibs(d_lua);
   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_settop(d_lua, 0);
   
   lua_pushcfunction(d_lua, netmaskMatchLua);
   lua_setglobal(d_lua, "matchnetmask");
@@ -108,7 +111,7 @@ bool PowerDNSLua::getFromTable(const std::string& key, uint32_t& value)
 
   bool ret=false;
   if(!lua_isnil(d_lua, -1)) {
-    value = lua_tonumber(d_lua, -1);
+    value = (uint32_t)lua_tonumber(d_lua, -1);
     ret=true;
   }
   lua_pop(d_lua, 1);
@@ -129,15 +132,18 @@ bool PowerDNSLua::passthrough(const string& func, const ComboAddress& remote, co
   lua_pushstring(d_lua,  query.c_str() );
   lua_pushnumber(d_lua,  qtype.getCode() );
 
-  lua_call(d_lua,  3, 2);
-  res = lua_tonumber(d_lua, 1); // new rcode
+  if(lua_pcall(d_lua,  3, 2, 0)) { // error 
+    string error=string("lua error: ")+lua_tostring(d_lua, -1);
+    lua_pop(d_lua, 1);
+    throw runtime_error(error);
+    return false;
+  }
+  res = (int)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;