From 667f6c7cef3b275639388e2adf2c78e0da00a3ce Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 25 May 2016 16:41:00 +0200 Subject: [PATCH] rec: Manage the applied policy and tags from pre/post resolve hooks This adds a `appliedPolicy` string member to the dq object, along with new methods: * `addPolicyTag(string)` * `setPolicyTags(table of strings)` * `getPolicyTags()` A new repeated (ie, {0,n}) `tags` is added to our protobuf responses. --- pdns/dnsmessage.proto | 1 + pdns/lua-recursor4.cc | 39 +++++++++++++++++++++++++++++++-------- pdns/lua-recursor4.hh | 9 ++++++--- pdns/pdns_recursor.cc | 10 ++++++++-- 4 files changed, 46 insertions(+), 13 deletions(-) diff --git a/pdns/dnsmessage.proto b/pdns/dnsmessage.proto index a5edca63b..10c514c16 100644 --- a/pdns/dnsmessage.proto +++ b/pdns/dnsmessage.proto @@ -42,6 +42,7 @@ message PBDNSMessage { optional uint32 rcode = 1; repeated DNSRR rrs = 2; optional string appliedPolicy = 3; + repeated string tags = 4; } optional DNSResponse response = 13; diff --git a/pdns/lua-recursor4.cc b/pdns/lua-recursor4.cc index 476326bca..1f48e4997 100644 --- a/pdns/lua-recursor4.cc +++ b/pdns/lua-recursor4.cc @@ -316,6 +316,7 @@ RecursorLua4::RecursorLua4(const std::string& fname) d_lw->registerMember("udpAnswer", &DNSQuestion::udpAnswer); d_lw->registerMember("udpQueryDest", &DNSQuestion::udpQueryDest); d_lw->registerMember("udpCallback", &DNSQuestion::udpCallback); + d_lw->registerMember("appliedPolicy", &DNSQuestion::appliedPolicy); d_lw->registerFunction("getEDNSOptions", &DNSQuestion::getEDNSOptions); d_lw->registerFunction("getEDNSOption", &DNSQuestion::getEDNSOption); d_lw->registerFunction("getEDNSSubnet", &DNSQuestion::getEDNSSubnet); @@ -342,6 +343,22 @@ RecursorLua4::RecursorLua4(const std::string& fname) d_lw->registerFunction("getRecords", &DNSQuestion::getRecords); d_lw->registerFunction("setRecords", &DNSQuestion::setRecords); + d_lw->registerFunction("addPolicyTag", [](DNSQuestion& dq, const std::string& tag) { dq.policyTags.push_back(tag); }); + d_lw->registerFunction >&)>("setPolicyTags", [](DNSQuestion& dq, const std::vector >& tags) { + dq.policyTags.clear(); + for (const auto& tag : tags) { + dq.policyTags.push_back(tag.second); + } + }); + d_lw->registerFunction >(DNSQuestion::*)()>("getPolicyTags", [](const DNSQuestion& dq) { + std::vector > ret; + int count = 1; + for (const auto& tag : dq.policyTags) { + ret.push_back({count++, tag}); + } + return ret; + }); + d_lw->writeFunction("newDS", []() { return SuffixMatchNode(); }); d_lw->registerFunction > >)>("add", [](SuffixMatchNode&smn, const boost::variant > >& in) @@ -431,29 +448,29 @@ RecursorLua4::RecursorLua4(const std::string& fname) d_gettag = d_lw->readVariable>("gettag").get_value_or(0); } -bool RecursorLua4::preresolve(const ComboAddress& remote,const ComboAddress& local, const DNSName& query, const QType& qtype, vector& res, const vector >* ednsOpts, unsigned int tag, int& ret, bool* variable) +bool RecursorLua4::preresolve(const ComboAddress& remote,const ComboAddress& local, const DNSName& query, const QType& qtype, vector& res, const vector >* ednsOpts, unsigned int tag, std::string* appliedPolicy, std::vector* policyTags, int& ret, bool* variable) { - return genhook(d_preresolve, remote, local, query, qtype, res, ednsOpts, tag, ret, variable); + return genhook(d_preresolve, remote, local, query, qtype, res, ednsOpts, tag, appliedPolicy, policyTags, ret, variable); } bool RecursorLua4::nxdomain(const ComboAddress& remote,const ComboAddress& local, const DNSName& query, const QType& qtype, vector& res, int& ret, bool* variable) { - return genhook(d_nxdomain, remote, local, query, qtype, res, 0, 0, ret, variable); + return genhook(d_nxdomain, remote, local, query, qtype, res, 0, 0, nullptr, nullptr, ret, variable); } bool RecursorLua4::nodata(const ComboAddress& remote,const ComboAddress& local, const DNSName& query, const QType& qtype, vector& res, int& ret, bool* variable) { - return genhook(d_nodata, remote, local, query, qtype, res, 0, 0, ret, variable); + return genhook(d_nodata, remote, local, query, qtype, res, 0, 0, nullptr, nullptr, ret, variable); } -bool RecursorLua4::postresolve(const ComboAddress& remote,const ComboAddress& local, const DNSName& query, const QType& qtype, vector& res, int& ret, bool* variable) +bool RecursorLua4::postresolve(const ComboAddress& remote,const ComboAddress& local, const DNSName& query, const QType& qtype, vector& res, std::string* appliedPolicy, std::vector* policyTags, int& ret, bool* variable) { - return genhook(d_postresolve, remote, local, query, qtype, res, 0, 0, ret, variable); + return genhook(d_postresolve, remote, local, query, qtype, res, 0, 0, appliedPolicy, policyTags, ret, variable); } bool RecursorLua4::preoutquery(const ComboAddress& ns, const ComboAddress& requestor, const DNSName& query, const QType& qtype, vector& res, int& ret) { - return genhook(d_preoutquery, ns, requestor, query, qtype, res, 0, 0, ret, 0); + return genhook(d_preoutquery, ns, requestor, query, qtype, res, 0, 0, nullptr, nullptr, ret, 0); } bool RecursorLua4::ipfilter(const ComboAddress& remote, const ComboAddress& local, const struct dnsheader& dh) @@ -470,7 +487,7 @@ int RecursorLua4::gettag(const ComboAddress& remote, const Netmask& ednssubnet, return 0; } -bool RecursorLua4::genhook(luacall_t& func, const ComboAddress& remote,const ComboAddress& local, const DNSName& query, const QType& qtype, vector& res, const vector >* ednsOpts, unsigned int tag, int& ret, bool* variable) +bool RecursorLua4::genhook(luacall_t& func, const ComboAddress& remote,const ComboAddress& local, const DNSName& query, const QType& qtype, vector& res, const vector >* ednsOpts, unsigned int tag, std::string* appliedPolicy, std::vector* policyTags, int& ret, bool* variable) { if(!func) return false; @@ -516,6 +533,12 @@ loop:; } } res=dq->records; + if (appliedPolicy) { + *appliedPolicy=dq->appliedPolicy; + } + if (policyTags) { + *policyTags = dq->policyTags; + } } diff --git a/pdns/lua-recursor4.hh b/pdns/lua-recursor4.hh index 31d9df58f..377015a5d 100644 --- a/pdns/lua-recursor4.hh +++ b/pdns/lua-recursor4.hh @@ -16,10 +16,10 @@ private: public: explicit RecursorLua4(const std::string& fname); ~RecursorLua4(); // this is so unique_ptr works with an incomplete type - bool preresolve(const ComboAddress& remote,const ComboAddress& local, const DNSName& query, const QType& qtype, vector& res, const vector >* ednsOpts, unsigned int tag, int& ret, bool* variable); + bool preresolve(const ComboAddress& remote,const ComboAddress& local, const DNSName& query, const QType& qtype, vector& res, const vector >* ednsOpts, unsigned int tag, std::string* appliedPolicy, std::vector* policyTags, int& ret, bool* variable); bool nxdomain(const ComboAddress& remote, const ComboAddress& local, const DNSName& query, const QType& qtype, vector& res, int& ret, bool* variable); bool nodata(const ComboAddress& remote, const ComboAddress& local, const DNSName& query, const QType& qtype, vector& res, int& ret, bool* variable); - bool postresolve(const ComboAddress& remote, const ComboAddress& local, const DNSName& query, const QType& qtype, vector& res, int& ret, bool* variable); + bool postresolve(const ComboAddress& remote, const ComboAddress& local, const DNSName& query, const QType& qtype, vector& res, std::string* appliedPolicy, std::vector* policyTags, int& ret, bool* variable); bool preoutquery(const ComboAddress& ns, const ComboAddress& requestor, const DNSName& query, const QType& qtype, vector& res, int& ret); bool ipfilter(const ComboAddress& remote, const ComboAddress& local, const struct dnsheader&); @@ -59,11 +59,14 @@ private: std::unordered_map data; const std::vector>* ednsOptions; DNSName followupName; + + string appliedPolicy; + std::vector policyTags; }; typedef std::function)> luacall_t; luacall_t d_preresolve, d_nxdomain, d_nodata, d_postresolve, d_preoutquery, d_postoutquery; - bool genhook(luacall_t& func, const ComboAddress& remote,const ComboAddress& local, const DNSName& query, const QType& qtype, vector& res, const vector >* ednsOpts, unsigned int tag, int& ret, bool* variable); + bool genhook(luacall_t& func, const ComboAddress& remote,const ComboAddress& local, const DNSName& query, const QType& qtype, vector& res, const vector >* ednsOpts, unsigned int tag, std::string* appliedPolicy, std::vector* policyTags, int& ret, bool* variable); typedef std::function ipfilter_t; ipfilter_t d_ipfilter; }; diff --git a/pdns/pdns_recursor.cc b/pdns/pdns_recursor.cc index 84a4b7a0f..37dcdc1a4 100644 --- a/pdns/pdns_recursor.cc +++ b/pdns/pdns_recursor.cc @@ -706,6 +706,7 @@ void startDoResolve(void *p) auto luaconfsLocal = g_luaconfs.getLocal(); std::string appliedPolicy; + std::vector policyTags; #ifdef HAVE_PROTOBUF PBDNSMessage_DNSResponse protobufResponse; if(luaconfsLocal->protobufServer) { @@ -830,7 +831,7 @@ void startDoResolve(void *p) } - if(!t_pdl->get() || !(*t_pdl)->preresolve(dc->d_remote, dc->d_local, dc->d_mdp.d_qname, QType(dc->d_mdp.d_qtype), ret, dc->d_ednsOpts.empty() ? 0 : &dc->d_ednsOpts, dc->d_tag, res, &variableAnswer)) { + if(!t_pdl->get() || !(*t_pdl)->preresolve(dc->d_remote, dc->d_local, dc->d_mdp.d_qname, QType(dc->d_mdp.d_qtype), ret, dc->d_ednsOpts.empty() ? 0 : &dc->d_ednsOpts, dc->d_tag, &appliedPolicy, &policyTags, res, &variableAnswer)) { try { res = sr.beginResolve(dc->d_mdp.d_qname, QType(dc->d_mdp.d_qtype), dc->d_mdp.d_qclass, ret); } @@ -898,7 +899,7 @@ void startDoResolve(void *p) (*t_pdl)->nxdomain(dc->d_remote, dc->d_local, dc->d_mdp.d_qname, QType(dc->d_mdp.d_qtype), ret, res, &variableAnswer); - (*t_pdl)->postresolve(dc->d_remote, dc->d_local, dc->d_mdp.d_qname, QType(dc->d_mdp.d_qtype), ret, res, &variableAnswer); + (*t_pdl)->postresolve(dc->d_remote, dc->d_local, dc->d_mdp.d_qname, QType(dc->d_mdp.d_qtype), ret, &appliedPolicy, &policyTags, res, &variableAnswer); } } @@ -1038,6 +1039,11 @@ void startDoResolve(void *p) if (!appliedPolicy.empty()) { protobufResponse.set_appliedpolicy(appliedPolicy); } + if (!policyTags.empty()) { + for(const auto tag : policyTags) { + protobufResponse.add_tags(tag); + } + } protobufLogResponse(luaconfsLocal->protobufServer, dc, packet.size(), protobufResponse); } #endif -- 2.40.0