Permalink
Browse files

Merge remote-tracking branch 'origin/cnamefollow'

  • Loading branch information...
2 parents 23b7fa1 + e1c8b82 commit 21e7976ac46f990c67d56eee1432b0245602312a @ahupowerdns ahupowerdns committed May 27, 2014
Showing with 86 additions and 15 deletions.
  1. +33 −4 pdns/lua-pdns.cc
  2. +1 −0 pdns/lua-pdns.hh
  3. +46 −11 pdns/lua-recursor.cc
  4. +6 −0 pdns/powerdns-example-script.lua
View
@@ -161,6 +161,7 @@ int getLuaTableLength(lua_State* lua, int depth)
#endif
}
+// expects a table at offset 2, and, importantly DOES NOT POP IT from the stack - only the contents
void popResourceRecordsTable(lua_State *lua, const string &query, vector<DNSResourceRecord>& ret)
{
/* get the result */
@@ -169,10 +170,7 @@ void popResourceRecordsTable(lua_State *lua, const string &query, vector<DNSReso
rr.d_place = DNSResourceRecord::ANSWER;
rr.ttl = 3600;
-// cerr<<"Lua stacksize "<<lua_gettop(lua)<<endl;
-
int tableLen = getLuaTableLength(lua, 2);
-// cerr<<"Got back "<<tableLen<< " answers from Lua"<<endl;
for(int n=1; n < tableLen + 1; ++n) {
lua_pushnumber(lua, n);
@@ -278,7 +276,6 @@ int logLua(lua_State *lua)
PowerDNSLua::PowerDNSLua(const std::string& fname)
{
-
d_lua = luaL_newstate();
lua_pushcfunction(d_lua, netmaskMatchLua);
@@ -353,4 +350,36 @@ PowerDNSLua::~PowerDNSLua()
{
lua_close(d_lua);
}
+
+#if 0
+void luaStackDump (lua_State *L) {
+ int i;
+ int top = lua_gettop(L);
+ for (i = 1; i <= top; i++) { /* repeat for each level */
+ int t = lua_type(L, i);
+ switch (t) {
+
+ case LUA_TSTRING: /* strings */
+ printf("`%s'", lua_tostring(L, i));
+ break;
+
+ case LUA_TBOOLEAN: /* booleans */
+ printf(lua_toboolean(L, i) ? "true" : "false");
+ break;
+
+ case LUA_TNUMBER: /* numbers */
+ printf("%g", lua_tonumber(L, i));
+ break;
+
+ default: /* other values */
+ printf("%s", lua_typename(L, t));
+ break;
+
+ }
+ printf(" "); /* put a separator */
+ }
+ printf("\n"); /* end the listing */
+}
+#endif
+
#endif
View
@@ -36,4 +36,5 @@ void pushResourceRecordsTable(lua_State* lua, const vector<DNSResourceRecord>& r
void popResourceRecordsTable(lua_State *lua, const string &query, vector<DNSResourceRecord>& ret);
void pushSyslogSecurityLevelTable(lua_State *lua);
int getLuaTableLength(lua_State* lua, int depth);
+void luaStackDump (lua_State *L);
#endif
View
@@ -58,6 +58,32 @@ RecursorLua::RecursorLua(const std::string &fname)
// empty
}
+int followCNAMERecords(vector<DNSResourceRecord>& ret, const QType& qtype)
+{
+ vector<DNSResourceRecord> resolved;
+ string target;
+ BOOST_FOREACH(DNSResourceRecord& rr, ret) {
+ if(rr.qtype.getCode() == QType::CNAME) {
+ target=rr.content;
+ break;
+ }
+ }
+ if(target.empty())
+ return 0;
+
+ if(target[target.size()-1]!='.')
+ target.append(1, '.');
+
+ int rcode=directResolve(target, qtype, 1, resolved); // 1 == class
+
+ BOOST_FOREACH(const DNSResourceRecord& rr, resolved)
+ {
+ ret.push_back(rr);
+ }
+ return rcode;
+
+}
+
int getFakeAAAARecords(const std::string& qname, const std::string& prefix, vector<DNSResourceRecord>& ret)
{
int rcode=directResolve(qname, QType(QType::A), 1, ret);
@@ -158,26 +184,37 @@ bool RecursorLua::passthrough(const string& func, const ComboAddress& remote, co
extraParameter+=2;
}
- if(lua_pcall(d_lua, 3 + extraParameter, 3, 0)) {
+ if(lua_pcall(d_lua, 3 + extraParameter, 3, 0)) { // NOTE! Means we always get 3 stack entries back!
string error=string("lua error in '"+func+"' while processing query for '"+query+"|"+qtype.getName()+": ")+lua_tostring(d_lua, -1);
lua_pop(d_lua, 1);
throw runtime_error(error);
return false;
}
-
+
*variable |= d_variable;
if(!lua_isnumber(d_lua, 1)) {
string tocall = lua_tostring(d_lua,1);
- string luaqname = lua_tostring(d_lua,2);
- string luaprefix = lua_tostring(d_lua, 3);
- lua_pop(d_lua, 3);
- // cerr<<"should call '"<<tocall<<"' to finish off"<<endl;
+ lua_remove(d_lua, 1); // the name
ret.clear();
- if(tocall == "getFakeAAAARecords")
+ if(tocall == "getFakeAAAARecords") {
+ string luaprefix = lua_tostring(d_lua, 2);
+ string luaqname = lua_tostring(d_lua,1);
+ lua_pop(d_lua, 2);
res = getFakeAAAARecords(luaqname, luaprefix, ret);
- else if(tocall == "getFakePTRRecords")
+ }
+ else if(tocall == "getFakePTRRecords") {
+ string luaprefix = lua_tostring(d_lua, 2);
+ string luaqname = lua_tostring(d_lua,1);
+ lua_pop(d_lua, 2);
res = getFakePTRRecords(luaqname, luaprefix, ret);
+ }
+ else if(tocall == "followCNAMERecords") {
+ popResourceRecordsTable(d_lua, query, ret);
+ lua_pop(d_lua, 2);
+ res = followCNAMERecords(ret, qtype);
+ }
+
return true;
// returned a followup
}
@@ -195,10 +232,8 @@ bool RecursorLua::passthrough(const string& func, const ComboAddress& remote, co
/* 1 2 3 4 */
/* stack: boolean table key row */
- popResourceRecordsTable(d_lua, query, ret);
-
+ popResourceRecordsTable(d_lua, query, ret); // doesn't actually pop the table itself!
lua_pop(d_lua, 3);
-
return true;
}
@@ -14,6 +14,12 @@ function preresolve ( remoteip, domain, qtype )
return "getFakePTRRecords", domain, "fe80::21b::77ff:0:0"
end
+ if domain == "www.followme.com."
+ then
+ print ("Need to CNAME www.followme.com to www.powerdns.com")
+ return "followCNAMERecords", 0, {{qtype=pdns.CNAME, content="www.powerdns.com"}}
+ end
+
if domain == "www.donotanswer.org."
then
print("we won't answer a query for donotanswer.org")

0 comments on commit 21e7976

Please sign in to comment.