From: bert hubert Date: Fri, 22 Jan 2016 10:32:38 +0000 (+0100) Subject: fix up asynchronous querying X-Git-Tag: dnsdist-1.0.0-alpha2~37^2~1 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6b8b26c80c96d9bfec0091b44f1ba11c6639e58a;p=pdns fix up asynchronous querying --- diff --git a/pdns/kv-example-script.lua b/pdns/kv-example-script.lua index bbfcf60d2..ae39cddb9 100644 --- a/pdns/kv-example-script.lua +++ b/pdns/kv-example-script.lua @@ -4,43 +4,53 @@ This implements a two-step domain filtering solution where the status of an IP a and a domain name need to be looked up. To do so, we use the udpQuestionResponse answers which generically allows us to do asynchronous lookups via UDP. -Such lookups can be slow, they won't block PowerDNS while we wait for them. +Such lookups can be slow, but they won't block PowerDNS while we wait for them. -To benefit from this hook, return: "udpQueryResponse", UDP-server, data -from preresolve (or other hooks). -The 'data' third return value should be a table with the query in there, plus the callback -that needs to be called once the data is in. - -We'll add more parameters, like 'timeout' and perhaps 'protocol' as we improve this feature -over time. +To benefit from this hook, +.. To test, use the 'kvresp' example program provided. --]] -function preresolve ( remoteip, domain, qtype ) - print ("preresolve handler called for: "..remoteip.. ", local: ".. getlocaladdress()..", ".. domain..", ".. qtype) - return "udpQueryResponse", "127.0.0.1:5555", {query="IP "..remoteip, callback="getipdetails"} +function preresolve (dq) + print ("prereesolve handler called for: "..dq.remoteaddr:toString().. ", local: ".. dq.localaddr:toString()..", ".. dq.qname:toString()..", ".. dq.qtype) + dq.followupFunction="udpQueryResponse" + dq.udpCallback="gotipdetails" + dq.udpQueryDest=newCA("127.0.0.1:5555") + dq.udpQuery = "IP "..dq.remoteaddr:toString() + dq.variable = true; + return true; end -function getipdetails(remoteip, domain, qtype, data) - print("In getipdetails, got ".. data.response.. " from '"..remoteip.."', for '"..remoteip.."'") - data.ipstatus=data.response - data.query="DOMAIN "..domain - data.callback="getdomaindetails" - return "udpQueryResponse", "127.0.0.1:5555", data +function gotipdetails(dq) + print("gotipdetails called, got: "..dq.udpAnswer) + if(dq.udpAnswer ~= "1") + then + print("IP address wants no filtering, not looking up this domain") + dq.followupFunction="" + return false + end + local data={} + data["ipdetails"]= dq.udpAnswer + dq.data=data + dq.udpQuery="DOMAIN "..dq.qname:toString() + dq.udpCallback="gotdomaindetails" + print("returning true in gotipdetails") + return true end -function getdomaindetails(remoteip, domain, qtype, data) - print("In getipdetails, got ".. data.response.. " from '"..remoteip.."', for '"..domain.."'") - print("So status of domain is "..data.response.." and status of IP is "..data.ipstatus) - if(data.ipstatus=="1" and data.response=="1") - then +function gotdomaindetails(dq) + dq.followupFunction="" + print("So status of domain is "..dq.udpAnswer.." and status of IP is "..dq.data.ipdetails) + if(dq.data.ipdetails=="1" and dq.udpAnswer=="1") + then print("IP wants filtering and domain is of the filtered kind") - return 0,{{qtype=pdns.CNAME, content="www.blocked.com", ttl=3602}, - {qname="www.webserver.com", qtype=pdns.A, content="1.2.3.4", ttl=3602}} - else - return pdns.PASS, {} - end + dq:addAnswer(pdns.CNAME, "blocked.powerdns.com") + return true + else + print("Returning false (normal resolution should proceed)") + return false + end end diff --git a/pdns/lua-recursor4.cc b/pdns/lua-recursor4.cc index 745b57b21..fc87af208 100644 --- a/pdns/lua-recursor4.cc +++ b/pdns/lua-recursor4.cc @@ -247,6 +247,11 @@ RecursorLua4::RecursorLua4(const std::string& fname) d_lw->registerMember("followupFunction", &DNSQuestion::followupFunction); d_lw->registerMember("followupPrefix", &DNSQuestion::followupPrefix); d_lw->registerMember("followupName", &DNSQuestion::followupName); + d_lw->registerMember("data", &DNSQuestion::data); + d_lw->registerMember("udpQuery", &DNSQuestion::udpQuery); + d_lw->registerMember("udpAnswer", &DNSQuestion::udpAnswer); + d_lw->registerMember("udpQueryDest", &DNSQuestion::udpQueryDest); + d_lw->registerMember("udpCallback", &DNSQuestion::udpCallback); d_lw->registerMember("name", &DNSRecord::d_name); d_lw->registerMember("type", &DNSRecord::d_type); d_lw->registerMember("ttl", &DNSRecord::d_ttl); @@ -403,6 +408,8 @@ bool RecursorLua4::genhook(luacall_t& func, const ComboAddress& remote,const Com theL()< string GenUDPQueryResponse(const ComboAddress& dest, const string& query); class LuaContext; @@ -47,6 +48,8 @@ private: string udpAnswer; string udpCallback; + std::unordered_map data; + DNSName followupName; };