From: Remi Gacogne Date: Tue, 7 Feb 2017 14:26:24 +0000 (+0100) Subject: rec: Allow returning the `DNSQuestion`'s `data` table from `gettag()` X-Git-Tag: rec-4.1.0-alpha1~268^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fpull%2F4982%2Fhead;p=thirdparty%2Fpdns.git rec: Allow returning the `DNSQuestion`'s `data` table from `gettag()` Allow `gettag()` to optionally return a table whose keys and values are strings, to fill up the `DNSQuestion`'s `data` table. --- diff --git a/docs/markdown/recursor/scripting.md b/docs/markdown/recursor/scripting.md index 086f7f1c12..b9a1c07878 100644 --- a/docs/markdown/recursor/scripting.md +++ b/docs/markdown/recursor/scripting.md @@ -154,11 +154,13 @@ would require packet parsing, which is what we are trying to prevent with `ipfil ### `function gettag(remote, ednssubnet, local, qname, qtype)` The `gettag` function is invoked when the Recursor attempts to discover in which packetcache an answer is available. + This function must return an integer, which is the tag number of the packetcache. In addition to this integer, this function can return a table of policy tags. - The resulting tag number can be accessed via `dq.tag` in the `preresolve` hook, and the policy tags via `dq:getPolicyTags()` in every hook. +Starting with 4.1.0, it can also return a table whose keys and values are strings +to fill the upcoming `DNSQuestion`'s `data` table. The tagged packetcache can e.g. be used to answer queries from cache that have e.g. been filtered for certain IPs (this logic should be implemented in the diff --git a/pdns/lua-recursor4.cc b/pdns/lua-recursor4.cc index 850a97d179..254d2220c2 100644 --- a/pdns/lua-recursor4.cc +++ b/pdns/lua-recursor4.cc @@ -71,7 +71,7 @@ bool RecursorLua4::ipfilter(const ComboAddress& remote, const ComboAddress& loca return false; } -int RecursorLua4::gettag(const ComboAddress& remote, const Netmask& ednssubnet, const ComboAddress& local, const DNSName& qname, uint16_t qtype, std::vector* policyTags) +int RecursorLua4::gettag(const ComboAddress& remote, const Netmask& ednssubnet, const ComboAddress& local, const DNSName& qname, uint16_t qtype, std::vector* policyTags, std::unordered_map& data) { return 0; } @@ -628,7 +628,7 @@ bool RecursorLua4::ipfilter(const ComboAddress& remote, const ComboAddress& loca return false; // don't block } -int RecursorLua4::gettag(const ComboAddress& remote, const Netmask& ednssubnet, const ComboAddress& local, const DNSName& qname, uint16_t qtype, std::vector* policyTags) +int RecursorLua4::gettag(const ComboAddress& remote, const Netmask& ednssubnet, const ComboAddress& local, const DNSName& qname, uint16_t qtype, std::vector* policyTags, std::unordered_map& data) { if(d_gettag) { auto ret = d_gettag(remote, ednssubnet, local, qname, qtype); @@ -641,6 +641,10 @@ int RecursorLua4::gettag(const ComboAddress& remote, const Netmask& ednssubnet, } } } + const auto& dataret = std::get<2>(ret); + if (dataret) { + data = *dataret; + } return std::get<0>(ret); } return 0; diff --git a/pdns/lua-recursor4.hh b/pdns/lua-recursor4.hh index 1502b6db43..efc7ac5997 100644 --- a/pdns/lua-recursor4.hh +++ b/pdns/lua-recursor4.hh @@ -96,7 +96,7 @@ public: #endif }; - int gettag(const ComboAddress& remote, const Netmask& ednssubnet, const ComboAddress& local, const DNSName& qname, uint16_t qtype, std::vector* policyTags); + int gettag(const ComboAddress& remote, const Netmask& ednssubnet, const ComboAddress& local, const DNSName& qname, uint16_t qtype, std::vector* policyTags, std::unordered_map& data); bool prerpz(DNSQuestion& dq, int& ret); bool preresolve(DNSQuestion& dq, int& ret); @@ -116,7 +116,7 @@ public: d_postresolve); } - typedef std::function > >(ComboAddress, Netmask, ComboAddress, DNSName, uint16_t)> gettag_t; + typedef std::function >,boost::optional > >(ComboAddress, Netmask, ComboAddress, DNSName, uint16_t)> gettag_t; gettag_t d_gettag; // public so you can query if we have this hooked private: diff --git a/pdns/pdns_recursor.cc b/pdns/pdns_recursor.cc index 7be428fa9a..89496f50ba 100644 --- a/pdns/pdns_recursor.cc +++ b/pdns/pdns_recursor.cc @@ -204,6 +204,7 @@ struct DNSComboWriter { shared_ptr d_tcpConnection; vector > d_ednsOpts; std::vector d_policyTags; + std::unordered_map d_data; }; @@ -772,6 +773,7 @@ void startDoResolve(void *p) dq.appliedPolicy = &appliedPolicy; dq.currentRecords = &ret; dq.dh = &dc->d_mdp.d_header; + dq.data = dc->d_data; if(dc->d_mdp.d_qtype==QType::ANY && !dc->d_tcp && g_anyToTcp) { pw.getHeader()->tc = 1; @@ -1386,7 +1388,7 @@ void handleRunningTCPQuestion(int fd, FDMultiplexer::funcparam_t& var) if(t_pdl->get() && (*t_pdl)->d_gettag) { try { - dc->d_tag = (*t_pdl)->gettag(conn->d_remote, ednssubnet, dest, qname, qtype, &dc->d_policyTags); + dc->d_tag = (*t_pdl)->gettag(conn->d_remote, ednssubnet, dest, qname, qtype, &dc->d_policyTags, dc->d_data); } catch(std::exception& e) { if(g_logCommonErrors) @@ -1518,6 +1520,7 @@ string* doProcessUDPQuestion(const std::string& question, const ComboAddress& fr unsigned int ctag=0; bool needECS = false; std::vector policyTags; + std::unordered_map data; #ifdef HAVE_PROTOBUF boost::uuids::uuid uniqueId; auto luaconfsLocal = g_luaconfs.getLocal(); @@ -1552,7 +1555,7 @@ string* doProcessUDPQuestion(const std::string& question, const ComboAddress& fr if(t_pdl->get() && (*t_pdl)->d_gettag) { try { - ctag=(*t_pdl)->gettag(fromaddr, ednssubnet, destaddr, qname, qtype, &policyTags); + ctag=(*t_pdl)->gettag(fromaddr, ednssubnet, destaddr, qname, qtype, &policyTags, data); } catch(std::exception& e) { if(g_logCommonErrors) @@ -1646,6 +1649,7 @@ string* doProcessUDPQuestion(const std::string& question, const ComboAddress& fr dc->setLocal(destaddr); dc->d_tcp=false; dc->d_policyTags = policyTags; + dc->d_data = data; #ifdef HAVE_PROTOBUF if (luaconfsLocal->protobufServer || luaconfsLocal->outgoingProtobufServer) { dc->d_uuid = uniqueId;