From 67eeef8a133bec92f90650ee9ac927ca216615df Mon Sep 17 00:00:00 2001 From: Bert Hubert Date: Sat, 14 Jun 2008 21:11:33 +0000 Subject: [PATCH] prequery -> preresolve, make records arrive in the correct order, make nxdomain only act on nxdomain, improve example script git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@1200 d19b8d6e-7fed-0310-83ef-9ca221ded41b --- pdns/docs/pdns.sgml | 32 +++++++++++++++++---------- pdns/lua-pdns-recursor.cc | 22 ++++++++++++------ pdns/lua-pdns-recursor.hh | 2 +- pdns/pdns_recursor.cc | 7 +++--- pdns/powerdns-example-script.lua | 38 ++++++++++++++++++-------------- 5 files changed, 62 insertions(+), 39 deletions(-) diff --git a/pdns/docs/pdns.sgml b/pdns/docs/pdns.sgml index e90d3245b..4ac648f81 100644 --- a/pdns/docs/pdns.sgml +++ b/pdns/docs/pdns.sgml @@ -8167,8 +8167,9 @@ Feb 10 14:16:03 stats: 125784 questions, 13971 cache entries, 309 negative entri Configuring Lua scripts - In order to load scripts, the PowerDNS Recursor must have 'lua' support built in. The packages distributed from the PowerDNS website have this language - enabled, other distributions may differ. + In order to load scripts, the PowerDNS Recursor must have Lua support built in. The packages distributed from the PowerDNS website have this language + enabled, other distributions may differ. To compile with Lua support, use: LUA=1 make or LUA=1 gmake + as the case may be. Paths to the Lua include files and binaries may be found near the top of the Makefile. If lua support is available, a script can be configured either via the configuration file, or at runtime via the rec_control tool. @@ -8187,11 +8188,11 @@ Feb 10 14:16:03 stats: 125784 questions, 13971 cache entries, 309 negative entri Writing Lua PowerDNS Recursor scripts - Once a script is loaded, PowerDNS looks for two functions: prequery and nxdomain. Either or both of these + Once a script is loaded, PowerDNS looks for two functions: preresolve and nxdomain. Either or both of these can be absent, in which case the corresponding functionality is disabled. - prequery is called before any DNS resolution is attempted, and if this function indicates it, it can supply a direct answer to the + preresolve is called before any DNS resolution is attempted, and if this function indicates it, it can supply a direct answer to the DNS query, overriding the internet. This is useful to combat botnets, or to disable domains unacceptable to an organization for whatever reason. @@ -8216,17 +8217,14 @@ function nxdomain ( ip, domain, qtype ) ret={} 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 string.find(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 + ret[1]={qtype=1, content="127.1.2.3"} -- add IN A 127.1.2.3 + ret[2]={qtype=1, content="127.3.2.1"} -- add IN A 127.3.2.1 + return 0, ret -- return no error, plus records end - - For Lua 5.0, use string.find instead of string.gmatch. - @@ -8286,12 +8284,22 @@ end 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. + will be encoded in DNS, actual results may be undesired. + + + + The result table must have indexes that start at 1! Otherwise the first or confusingly the last entry of the table will + be ignored. A useful technique is to return data using: + return 0, {{qtype=1, content="1.2.3.4"}, {qtype=1, content="4.3.2.1"}} as this will get the numbering + right automatically. + + + diff --git a/pdns/lua-pdns-recursor.cc b/pdns/lua-pdns-recursor.cc index 0be22a8a3..74fb4416a 100644 --- a/pdns/lua-pdns-recursor.cc +++ b/pdns/lua-pdns-recursor.cc @@ -84,9 +84,9 @@ bool PowerDNSLua::nxdomain(const ComboAddress& remote, const string& query, cons return passthrough("nxdomain", remote, query, qtype, ret, res); } -bool PowerDNSLua::prequery(const ComboAddress& remote, const string& query, const QType& qtype, vector& ret, int& res) +bool PowerDNSLua::preresolve(const ComboAddress& remote, const string& query, const QType& qtype, vector& ret, int& res) { - return passthrough("prequery", remote, query, qtype, ret, res); + return passthrough("preresolve", remote, query, qtype, ret, res); } bool PowerDNSLua::getFromTable(const std::string& key, std::string& value) @@ -138,12 +138,13 @@ bool PowerDNSLua::passthrough(const string& func, const ComboAddress& remote, co throw runtime_error(error); return false; } - res = (int)lua_tonumber(d_lua, 1); // new rcode - if(res < 0) { + int newres = (int)lua_tonumber(d_lua, 1); // new rcode + if(newres < 0) { // cerr << "handler did not handle"<& res, int& ret); + bool preresolve(const ComboAddress& remote, const string& query, const QType& qtype, vector& res, int& ret); bool nxdomain(const ComboAddress& remote, const string& query, const QType& qtype, vector& res, int& ret); private: lua_State* d_lua; diff --git a/pdns/pdns_recursor.cc b/pdns/pdns_recursor.cc index e8f26042b..95122e14f 100644 --- a/pdns/pdns_recursor.cc +++ b/pdns/pdns_recursor.cc @@ -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->preresolve(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()) { + if(res == RCode::NXDomain) + g_pdl->nxdomain(dc->d_remote, dc->d_mdp.d_qname, QType(dc->d_mdp.d_qtype), ret, res); } } diff --git a/pdns/powerdns-example-script.lua b/pdns/powerdns-example-script.lua index dcbe5f456..1a60065eb 100644 --- a/pdns/powerdns-example-script.lua +++ b/pdns/powerdns-example-script.lua @@ -1,37 +1,43 @@ -function prequery ( ip, domain, qtype ) +function preresolve ( ip, domain, qtype ) print ("prequery handler called for: ", ip, domain, qtype) - ret = {} - --- 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} + ret={} + ret[1]= {qtype=1, content="9.8.7.6", ttl=3601} + ret[2]= {qtype=1, content="1.2.3.4", ttl=3601} print "dealing!" return 0, ret elseif domain == "www.baddomain.com." then - print "dealing - nx" - return 3, ret + print "dealing - faking nx" + return 3, {} + elseif domain == "echo." + then + print "dealing with echo!" + return 0, {{qtype=1, content=ip}} + elseif domain == "echo6." + then + print "dealing with echo6!" + return 0, {{qtype=28, content=ip}} else print "not dealing!" - return -1, ret + return -1, {} end end 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 qtype ~= 1 then return -1, {} end -- only A records + if not string.find(domain, "^www.") then return -1, {} end -- only things that start with www. if matchnetmask(ip, "127.0.0.1/8") then print "dealing" - 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={} + ret[1]={qtype="5", content="www.webserver.com", ttl=3602} + ret[2]={qname="www.webserver.com", qtype="1", content="1.2.3.4", ttl=3602} + ret[3]={qname="webserver.com", qtype="2", content="ns1.webserver.com", place=2} -- ret[1]={15, "25 ds9a.nl", 3602} return 0, ret else -- 2.40.0