]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
rec: Pass a `DNSQuestion` object to Lua hooks 4564/head
authorRemi Gacogne <remi.gacogne@powerdns.com>
Thu, 13 Oct 2016 12:17:39 +0000 (14:17 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Thu, 13 Oct 2016 12:17:39 +0000 (14:17 +0200)
The main motivation is to get rid of the huge number of parameters
passed to our Lua hooks, and to make it easy to access new values
from every hook. It also prevents copying the `DNSName` and
`ComboAddress` for every Lua hook.
I'm still wondering whether we actually need to make `dq` a shared
pointer, or if we couldn't just allocate it on the stack.

pdns/lua-recursor4.cc
pdns/lua-recursor4.hh
pdns/pdns_recursor.cc

index f4d29ff793a6e40cdebaeb7dcc63f54fe494d49c..461a8bf7d4c909285c5b35ca61cea3483bcd9e39 100644 (file)
@@ -36,32 +36,32 @@ RecursorLua4::RecursorLua4(const std::string &fname)
   throw std::runtime_error("Attempt to load a Lua script in a PowerDNS binary without Lua support");
 }
 
-bool RecursorLua4::nxdomain(const ComboAddress& remote,const ComboAddress& local, const DNSName& query, const QType& qtype, bool isTcp, vector<DNSRecord>& ret, int& res, bool* variable)
+bool RecursorLua4::nxdomain(std::shared_ptr<DNSQuestion> dq, int& res)
 {
   return false;
 }
 
-bool RecursorLua4::nodata(const ComboAddress& remote,const ComboAddress& local, const DNSName& query, const QType& qtype, bool isTcp, vector<DNSRecord>& ret, int& res, bool* variable)
+bool RecursorLua4::nodata(std::shared_ptr<DNSQuestion> dq, int& res)
 {
   return false;
 }
 
-bool RecursorLua4::postresolve(const ComboAddress& remote,const ComboAddress& local, const DNSName& query, const QType& qtype, bool isTcp, vector<DNSRecord>& ret, DNSFilterEngine::Policy* appliedPolicy, std::vector<std::string>* policyTags, int& res, bool* variable)
+bool RecursorLua4::postresolve(std::shared_ptr<DNSQuestion> dq, int& res)
 {
   return false;
 }
 
-bool RecursorLua4::prerpz(const ComboAddress& remote,const ComboAddress& local, const DNSName& query, const QType& qtype, bool isTcp, vector<DNSRecord>& res, const vector<pair<uint16_t,string> >* ednsOpts, unsigned int tag, int& ret, bool* wantsRPZ, std::unordered_map<std::string,bool>* discardedPolicies)
+bool RecursorLua4::prerpz(std::shared_ptr<DNSQuestion> dq, int& ret)
 {
   return false;
 }
 
-bool RecursorLua4::preresolve(const ComboAddress& remote, const ComboAddress& local, const DNSName& query, const QType& qtype, bool isTcp, vector<DNSRecord>& ret, const vector<pair<uint16_t,string> >* ednsOpts, unsigned int tag, DNSFilterEngine::Policy* appliedPolicy, std::vector<std::string>* policyTags, int& res, bool* variable, bool* wantsRPZ)
+bool RecursorLua4::preresolve(std::shared_ptr<DNSQuestion> dq, int& res)
 {
   return false;
 }
 
-bool RecursorLua4::preoutquery(const ComboAddress& remote, const ComboAddress& local,const DNSName& query, const QType& qtype, bool isTcp, vector<DNSRecord>& ret, int& res)
+bool RecursorLua4::preoutquery(const ComboAddress& ns, const ComboAddress& requestor, const DNSName& query, const QType& qtype, bool isTcp, vector<DNSRecord>& res, int& ret)
 {
   return false;
 }
@@ -159,7 +159,7 @@ static int getFakePTRRecords(const DNSName& qname, const std::string& prefix, ve
 
 }
 
-vector<pair<uint16_t, string> > RecursorLua4::DNSQuestion::getEDNSOptions()
+vector<pair<uint16_t, string> > RecursorLua4::DNSQuestion::getEDNSOptions() const
 {
   if(ednsOptions)
     return *ednsOptions;
@@ -167,7 +167,7 @@ vector<pair<uint16_t, string> > RecursorLua4::DNSQuestion::getEDNSOptions()
     return vector<pair<uint16_t,string>>();
 }
 
-boost::optional<string>  RecursorLua4::DNSQuestion::getEDNSOption(uint16_t code)
+boost::optional<string>  RecursorLua4::DNSQuestion::getEDNSOption(uint16_t code) const
 {
   if(ednsOptions)
     for(const auto& o : *ednsOptions)
@@ -177,7 +177,7 @@ boost::optional<string>  RecursorLua4::DNSQuestion::getEDNSOption(uint16_t code)
   return boost::optional<string>();
 }
 
-boost::optional<Netmask>  RecursorLua4::DNSQuestion::getEDNSSubnet()
+boost::optional<Netmask>  RecursorLua4::DNSQuestion::getEDNSSubnet() const
 {
 
   if(ednsOptions) {
@@ -195,7 +195,7 @@ boost::optional<Netmask>  RecursorLua4::DNSQuestion::getEDNSSubnet()
 }
 
 
-vector<pair<int, DNSRecord> > RecursorLua4::DNSQuestion::getRecords()
+vector<pair<int, DNSRecord> > RecursorLua4::DNSQuestion::getRecords() const
 {
   vector<pair<int, DNSRecord> > ret;
   int num=1;
@@ -355,14 +355,18 @@ RecursorLua4::RecursorLua4(const std::string& fname)
   d_lw->registerFunction<string(DNSName::*)()>("toString", [](const DNSName&dn ) { return dn.toString(); });
   d_lw->registerFunction<string(DNSName::*)()>("toStringNoDot", [](const DNSName&dn ) { return dn.toStringNoDot(); });
   d_lw->registerFunction<bool(DNSName::*)()>("chopOff", [](DNSName&dn ) { return dn.chopOff(); });
-  d_lw->registerMember("qname", &DNSQuestion::qname);
-  d_lw->registerMember("qtype", &DNSQuestion::qtype);
-  d_lw->registerMember("isTcp", &DNSQuestion::isTcp);
-  d_lw->registerMember("localaddr", &DNSQuestion::local);
-  d_lw->registerMember("remoteaddr", &DNSQuestion::remote);
+
+  d_lw->registerMember<const DNSName (DNSQuestion::*)>("qname", [](const DNSQuestion& dq) -> const DNSName& { return dq.qname; }, [](DNSQuestion& dq, const DNSName& newName) { (void) newName; });
+  d_lw->registerMember<uint16_t (DNSQuestion::*)>("qtype", [](const DNSQuestion& dq) -> uint16_t { return dq.qtype; }, [](DNSQuestion& dq, uint16_t newType) { (void) newType; });
+  d_lw->registerMember<bool (DNSQuestion::*)>("isTcp", [](const DNSQuestion& dq) -> bool { return dq.isTcp; }, [](DNSQuestion& dq, bool newTcp) { (void) newTcp; });
+  d_lw->registerMember<const ComboAddress (DNSQuestion::*)>("localaddr", [](const DNSQuestion& dq) -> const ComboAddress& { return dq.local; }, [](DNSQuestion& dq, const ComboAddress& newLocal) { (void) newLocal; });
+  d_lw->registerMember<const ComboAddress (DNSQuestion::*)>("remoteaddr", [](const DNSQuestion& dq) -> const ComboAddress& { return dq.remote; }, [](DNSQuestion& dq, const ComboAddress& newRemote) { (void) newRemote; });
+
+  d_lw->registerMember<bool (DNSQuestion::*)>("variable", [](const DNSQuestion& dq) -> bool { return dq.variable; }, [](DNSQuestion& dq, bool newVariable) { dq.variable = newVariable; });
+  d_lw->registerMember<bool (DNSQuestion::*)>("wantsRPZ", [](const DNSQuestion& dq) -> bool { return dq.wantsRPZ; }, [](DNSQuestion& dq, bool newWantsRPZ) { dq.wantsRPZ = newWantsRPZ; });
+
   d_lw->registerMember("rcode", &DNSQuestion::rcode);
   d_lw->registerMember("tag", &DNSQuestion::tag);
-  d_lw->registerMember("variable", &DNSQuestion::variable);
   d_lw->registerMember("followupFunction", &DNSQuestion::followupFunction);
   d_lw->registerMember("followupPrefix", &DNSQuestion::followupPrefix);
   d_lw->registerMember("followupName", &DNSQuestion::followupName);
@@ -371,7 +375,6 @@ 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("wantsRPZ", &DNSQuestion::wantsRPZ);
   d_lw->registerMember("appliedPolicy", &DNSQuestion::appliedPolicy);
   d_lw->registerMember<DNSFilterEngine::Policy, std::string>("policyName",
     [](const DNSFilterEngine::Policy& pol) -> std::string {
@@ -551,34 +554,39 @@ RecursorLua4::RecursorLua4(const std::string& fname)
   d_gettag = d_lw->readVariable<boost::optional<gettag_t>>("gettag").get_value_or(0);
 }
 
-bool RecursorLua4::prerpz(const ComboAddress& remote,const ComboAddress& local, const DNSName& query, const QType& qtype, bool isTcp, vector<DNSRecord>& res, const vector<pair<uint16_t,string> >* ednsOpts, unsigned int tag, int& ret, bool* wantsRPZ, std::unordered_map<std::string,bool>* discardedPolicies)
+bool RecursorLua4::prerpz(std::shared_ptr<DNSQuestion> dq, int& ret)
 {
-  return genhook(d_prerpz, remote, local, query, qtype, isTcp, res, ednsOpts, tag, nullptr, nullptr, ret, nullptr, wantsRPZ, discardedPolicies);
+  return genhook(d_prerpz, dq, ret);
 }
 
-bool RecursorLua4::preresolve(const ComboAddress& remote,const ComboAddress& local, const DNSName& query, const QType& qtype, bool isTcp, vector<DNSRecord>& res, const vector<pair<uint16_t,string> >* ednsOpts, unsigned int tag, DNSFilterEngine::Policy* appliedPolicy, std::vector<std::string>* policyTags, int& ret, bool* variable, bool* wantsRPZ)
+bool RecursorLua4::preresolve(std::shared_ptr<DNSQuestion> dq, int& ret)
 {
-  return genhook(d_preresolve, remote, local, query, qtype, isTcp, res, ednsOpts, tag, appliedPolicy, policyTags, ret, variable, wantsRPZ, nullptr);
+  return genhook(d_preresolve, dq, ret);
 }
 
-bool RecursorLua4::nxdomain(const ComboAddress& remote,const ComboAddress& local, const DNSName& query, const QType& qtype, bool isTcp, vector<DNSRecord>& res, int& ret, bool* variable)
+bool RecursorLua4::nxdomain(std::shared_ptr<DNSQuestion> dq, int& ret)
 {
-  return genhook(d_nxdomain, remote, local, query, qtype, isTcp, res, 0, 0, nullptr, nullptr, ret, variable, 0, nullptr);
+  return genhook(d_nxdomain, dq, ret);
 }
 
-bool RecursorLua4::nodata(const ComboAddress& remote,const ComboAddress& local, const DNSName& query, const QType& qtype, bool isTcp, vector<DNSRecord>& res, int& ret, bool* variable)
+bool RecursorLua4::nodata(std::shared_ptr<DNSQuestion> dq, int& ret)
 {
-  return genhook(d_nodata, remote, local, query, qtype, isTcp, res, 0, 0, nullptr, nullptr, ret, variable, 0, nullptr);
+  return genhook(d_nodata, dq, ret);
 }
 
-bool RecursorLua4::postresolve(const ComboAddress& remote,const ComboAddress& local, const DNSName& query, const QType& qtype, bool isTcp, vector<DNSRecord>& res, DNSFilterEngine::Policy* appliedPolicy, std::vector<std::string>* policyTags, int& ret, bool* variable)
+bool RecursorLua4::postresolve(std::shared_ptr<DNSQuestion> dq, int& ret)
 {
-  return genhook(d_postresolve, remote, local, query, qtype, isTcp, res, 0, 0, appliedPolicy, policyTags, ret, variable, 0, nullptr);
+  return genhook(d_postresolve, dq, ret);
 }
 
 bool RecursorLua4::preoutquery(const ComboAddress& ns, const ComboAddress& requestor, const DNSName& query, const QType& qtype, bool isTcp, vector<DNSRecord>& res, int& ret)
 {
-  return genhook(d_preoutquery, ns, requestor, query, qtype, isTcp, res, 0, 0, nullptr, nullptr, ret, 0, 0, nullptr);
+  bool variableAnswer = false;
+  bool wantsRPZ = false;
+  auto dq = std::make_shared<RecursorLua4::DNSQuestion>(requestor, ns, query, qtype.getCode(), isTcp, variableAnswer, wantsRPZ);
+  dq->currentRecords = &res;
+
+  return genhook(d_preoutquery, dq, ret);
 }
 
 bool RecursorLua4::ipfilter(const ComboAddress& remote, const ComboAddress& local, const struct dnsheader& dh)
@@ -606,28 +614,26 @@ 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, bool isTcp, vector<DNSRecord>& res, const vector<pair<uint16_t,string> >* ednsOpts, unsigned int tag, DNSFilterEngine::Policy* appliedPolicy, std::vector<std::string>* policyTags, int& ret, bool* variable, bool* wantsRPZ, std::unordered_map<std::string,bool>* discardedPolicies)
+bool RecursorLua4::genhook(luacall_t& func, std::shared_ptr<DNSQuestion> dq, int& ret)
 {
   if(!func)
     return false;
 
-  auto dq = std::make_shared<DNSQuestion>();
-  dq->qname = query;
-  dq->qtype = qtype.getCode();
-  dq->local=local;
-  dq->remote=remote;
-  dq->records = res;
-  dq->tag = tag;
-  dq->ednsOptions = ednsOpts;
-  dq->isTcp = isTcp;
+  if (dq->currentRecords) {
+    dq->records = *dq->currentRecords;
+  } else {
+    dq->records.clear();
+  }
+
+  dq->followupFunction.clear();
+  dq->followupPrefix.clear();
+  dq->followupName.clear();
+  dq->udpQuery.clear();
+  dq->udpAnswer.clear();
+  dq->udpCallback.clear();
+
   dq->rcode = ret;
-  dq->policyTags = policyTags;
-  dq->appliedPolicy = appliedPolicy;
-  if(wantsRPZ) dq->wantsRPZ = *wantsRPZ;
-  if(discardedPolicies) dq->discardedPolicies = discardedPolicies;
   bool handled=func(dq);
-  if(variable) *variable |= dq->variable; // could still be set to indicate this *name* is variable, even if not 'handled'
-  if(wantsRPZ) *wantsRPZ = dq->wantsRPZ; // Even if we did not handle the query, RPZ could be disabled
 
   if(handled) {
 loop:;
@@ -635,7 +641,7 @@ loop:;
     
     if(!dq->followupFunction.empty()) {
       if(dq->followupFunction=="followCNAMERecords") {
-        ret = followCNAMERecords(dq->records, qtype);
+        ret = followCNAMERecords(dq->records, QType(dq->qtype));
       }
       else if(dq->followupFunction=="getFakeAAAARecords") {
         ret=getFakeAAAARecords(dq->followupName, dq->followupPrefix, dq->records);
@@ -650,18 +656,18 @@ loop:;
           theL()<<Logger::Error<<"Attempted callback for Lua UDP Query/Response which could not be found"<<endl;
           return false;
         }
-        bool res=func(dq);
-        if(variable) *variable |= dq->variable; // could still be set to indicate this *name* is variable
-        if(!res) {
+        bool result=func(dq);
+        if(!result) {
           return false;
         }
         goto loop;
       }
     }
-    res=dq->records;
+    if (dq->currentRecords) {
+      *dq->currentRecords = dq->records;
+    }
   }
 
-
   // see if they added followup work for us too
   return handled;
 }
index a684ee0ae3563d73d9d4aced21672a31367a1673..c88e33c5c522e0ae073462663b85b00bfc453338 100644 (file)
@@ -44,38 +44,38 @@ private:
 public:
   explicit RecursorLua4(const std::string& fname);
   ~RecursorLua4(); // this is so unique_ptr works with an incomplete type
-  bool prerpz(const ComboAddress& remote,const ComboAddress& local, const DNSName& query, const QType& qtype, bool isTcp, vector<DNSRecord>& res, const vector<pair<uint16_t,string> >* ednsOpts, unsigned int tag, int& ret, bool* wantsRPZ, std::unordered_map<std::string,bool>* discardedPolicies);
-  bool preresolve(const ComboAddress& remote,const ComboAddress& local, const DNSName& query, const QType& qtype, bool isTcp, vector<DNSRecord>& res, const vector<pair<uint16_t,string> >* ednsOpts, unsigned int tag, DNSFilterEngine::Policy* appliedPolicy, std::vector<std::string>* policyTags, int& ret, bool* variable, bool* wantsRPZ);
-  bool nxdomain(const ComboAddress& remote, const ComboAddress& local, const DNSName& query, const QType& qtype, bool isTcp, vector<DNSRecord>& res, int& ret, bool* variable);
-  bool nodata(const ComboAddress& remote, const ComboAddress& local, const DNSName& query, const QType& qtype, bool isTcp, vector<DNSRecord>& res, int& ret, bool* variable);
-  bool postresolve(const ComboAddress& remote, const ComboAddress& local, const DNSName& query, const QType& qtype, bool isTcp, vector<DNSRecord>& res, DNSFilterEngine::Policy* appliedPolicy, std::vector<std::string>* policyTags, int& ret, bool* variable);
 
-  bool preoutquery(const ComboAddress& ns, const ComboAddress& requestor, const DNSName& query, const QType& qtype, bool isTcp, vector<DNSRecord>& res, int& ret);
-  bool ipfilter(const ComboAddress& remote, const ComboAddress& local, const struct dnsheader&);
-
-  int gettag(const ComboAddress& remote, const Netmask& ednssubnet, const ComboAddress& local, const DNSName& query, uint16_t qtype, std::vector<std::string>* policyTags);
-
-  typedef std::function<std::tuple<int,boost::optional<std::unordered_map<int,string> > >(ComboAddress, Netmask, ComboAddress, DNSName, uint16_t)> gettag_t;
-  gettag_t d_gettag; // public so you can query if we have this hooked
-
-private:
   struct DNSQuestion
   {
-    DNSName qname;
-    uint16_t qtype;
-    ComboAddress local, remote;
-    int rcode{0};
-    // struct dnsheader, packet length would be great
+    DNSQuestion(const ComboAddress& rem, const ComboAddress& loc, const DNSName& query, uint16_t type, bool tcp, bool& variable_, bool& wantsRPZ_): qname(query), qtype(type), local(loc), remote(rem), isTcp(tcp), variable(variable_), wantsRPZ(wantsRPZ_)
+    {
+    }
+    const DNSName& qname;
+    const uint16_t qtype;
+    const ComboAddress& local;
+    const ComboAddress& remote;
+    const bool isTcp;
+    const std::vector<pair<uint16_t, string>>* ednsOptions{nullptr};
+    vector<DNSRecord>* currentRecords{nullptr};
+    DNSFilterEngine::Policy* appliedPolicy{nullptr};
+    std::vector<std::string>* policyTags{nullptr};
+    std::unordered_map<std::string,bool>* discardedPolicies{nullptr};
+    bool& variable;
+    bool& wantsRPZ;
     int tag{0};
-    vector<DNSRecord> records;
+
+#ifdef HAVE_LUA
     void addAnswer(uint16_t type, const std::string& content, boost::optional<int> ttl, boost::optional<string> name);
     void addRecord(uint16_t type, const std::string& content, DNSResourceRecord::Place place, boost::optional<int> ttl, boost::optional<string> name);
-    vector<pair<int,DNSRecord> > getRecords();
-    vector<pair<uint16_t, string> > getEDNSOptions();
-    boost::optional<string> getEDNSOption(uint16_t code);
-    boost::optional<Netmask> getEDNSSubnet();
+    vector<pair<int,DNSRecord> > getRecords() const;
+    vector<pair<uint16_t, string> > getEDNSOptions() const;
+    boost::optional<string> getEDNSOption(uint16_t code) const;
+    boost::optional<Netmask> getEDNSSubnet() const;
     void setRecords(const vector<pair<int,DNSRecord> >& records);
-    bool variable{false};
+
+    int rcode{0};
+    // struct dnsheader, packet length would be great
+    vector<DNSRecord> records;
     
     string followupFunction;
     string followupPrefix;
@@ -86,19 +86,37 @@ private:
     string udpCallback;
     
     std::unordered_map<string,string> data;
-    const std::vector<pair<uint16_t, string>>* ednsOptions;
     DNSName followupName;
-
-    DNSFilterEngine::Policy* appliedPolicy;
-    std::vector<std::string>* policyTags;
-    std::unordered_map<std::string,bool>* discardedPolicies;
-    bool isTcp;
-    bool wantsRPZ{true};
+#endif
   };
 
+  int gettag(const ComboAddress& remote, const Netmask& ednssubnet, const ComboAddress& local, const DNSName& qname, uint16_t qtype, std::vector<std::string>* policyTags);
+
+  bool prerpz(std::shared_ptr<DNSQuestion> dq, int& ret);
+  bool preresolve(std::shared_ptr<DNSQuestion> dq, int& ret);
+  bool nxdomain(std::shared_ptr<DNSQuestion> dq, int& ret);
+  bool nodata(std::shared_ptr<DNSQuestion> dq, int& ret);
+  bool postresolve(std::shared_ptr<DNSQuestion> dq, int& ret);
+
+  bool preoutquery(const ComboAddress& ns, const ComboAddress& requestor, const DNSName& query, const QType& qtype, bool isTcp, vector<DNSRecord>& res, int& ret);
+  bool ipfilter(const ComboAddress& remote, const ComboAddress& local, const struct dnsheader&);
+
+  bool needDQ() const
+  {
+    return (d_prerpz ||
+            d_preresolve ||
+            d_nxdomain ||
+            d_nodata ||
+            d_postresolve);
+  }
+
+  typedef std::function<std::tuple<int,boost::optional<std::unordered_map<int,string> > >(ComboAddress, Netmask, ComboAddress, DNSName, uint16_t)> gettag_t;
+  gettag_t d_gettag; // public so you can query if we have this hooked
+
+private:
   typedef std::function<bool(std::shared_ptr<DNSQuestion>)> luacall_t;
   luacall_t d_prerpz, 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, bool isTcp, vector<DNSRecord>& res,  const vector<pair<uint16_t,string> >* ednsOpts, unsigned int tag, DNSFilterEngine::Policy* appliedPolicy, std::vector<std::string>* policyTags, int& ret, bool* variable, bool* wantsRPZ, std::unordered_map<std::string,bool>* discardedPolicies);
+  bool genhook(luacall_t& func, std::shared_ptr<DNSQuestion> dq, int& ret);
   typedef std::function<bool(ComboAddress,ComboAddress, struct dnsheader)> ipfilter_t;
   ipfilter_t d_ipfilter;
 };
index c719bfe6466af099058e6fc7990a4256932264e8..75dc2539d5ee111d92bc4626eaf79dd2ab778da9 100644 (file)
@@ -712,6 +712,17 @@ void startDoResolve(void *p)
     int res;
     DNSFilterEngine::Policy appliedPolicy;
     DNSRecord spoofed;
+    std::shared_ptr<RecursorLua4::DNSQuestion> dq = nullptr;
+    if (t_pdl->get() && (*t_pdl)->needDQ()) {
+      dq = std::make_shared<RecursorLua4::DNSQuestion>(dc->d_remote, dc->d_local, dc->d_mdp.d_qname, dc->d_mdp.d_qtype, dc->d_tcp, variableAnswer, wantsRPZ);
+      dq->ednsOptions = &dc->d_ednsOpts;
+      dq->tag = dc->d_tag;
+      dq->discardedPolicies = &sr.d_discardedPolicies;
+      dq->policyTags = &dc->d_policyTags;
+      dq->appliedPolicy = &appliedPolicy;
+      dq->currentRecords = &ret;
+    }
+
     if(dc->d_mdp.d_qtype==QType::ANY && !dc->d_tcp && g_anyToTcp) {
       pw.getHeader()->tc = 1;
       res = 0;
@@ -741,7 +752,7 @@ void startDoResolve(void *p)
       sr.setCacheOnly();
 
     if (t_pdl->get()) {
-      (*t_pdl)->prerpz(dc->d_remote, dc->d_local, dc->d_mdp.d_qname, QType(dc->d_mdp.d_qtype), dc->d_tcp, ret, dc->d_ednsOpts.empty() ? 0 : &dc->d_ednsOpts, dc->d_tag, res, &wantsRPZ, &sr.d_discardedPolicies);
+      (*t_pdl)->prerpz(dq, res);
     }
 
     // Check if the query has a policy attached to it
@@ -750,7 +761,7 @@ void startDoResolve(void *p)
     }
 
     // if there is a RecursorLua active, and it 'took' the query in preResolve, we don't launch beginResolve
-    if(!t_pdl->get() || !(*t_pdl)->preresolve(dc->d_remote, dc->d_local, dc->d_mdp.d_qname, QType(dc->d_mdp.d_qtype), dc->d_tcp, ret, dc->d_ednsOpts.empty() ? 0 : &dc->d_ednsOpts, dc->d_tag, &appliedPolicy, &dc->d_policyTags, res, &variableAnswer, &wantsRPZ)) {
+    if(!t_pdl->get() || !(*t_pdl)->preresolve(dq, res)) {
 
       sr.d_wantsRPZ = wantsRPZ;
       if(wantsRPZ) {
@@ -859,14 +870,14 @@ void startDoResolve(void *p)
                 for(; i!= ret.cend(); ++i)
                   if(i->d_type == dc->d_mdp.d_qtype && i->d_place == DNSResourceRecord::ANSWER)
                           break;
-                if(i == ret.cend() && (*t_pdl)->nodata(dc->d_remote, dc->d_local, dc->d_mdp.d_qname, QType(dc->d_mdp.d_qtype), dc->d_tcp, ret, res, &variableAnswer))
+                if(i == ret.cend() && (*t_pdl)->nodata(dq, res))
                   shouldNotValidate = true;
 
        }
-       else if(res == RCode::NXDomain && (*t_pdl)->nxdomain(dc->d_remote, dc->d_local, dc->d_mdp.d_qname, QType(dc->d_mdp.d_qtype), dc->d_tcp, ret, res, &variableAnswer))
+       else if(res == RCode::NXDomain && (*t_pdl)->nxdomain(dq, res))
           shouldNotValidate = true;
 
-       if((*t_pdl)->postresolve(dc->d_remote, dc->d_local, dc->d_mdp.d_qname, QType(dc->d_mdp.d_qtype), dc->d_tcp, ret, &appliedPolicy, &dc->d_policyTags, res, &variableAnswer))
+       if((*t_pdl)->postresolve(dq, res))
           shouldNotValidate = true;
       }