]> granicus.if.org Git - pdns/commitdiff
rec: Allow returning the `DNSQuestion`'s `data` table from `gettag()`
authorRemi Gacogne <remi.gacogne@powerdns.com>
Tue, 7 Feb 2017 14:26:24 +0000 (15:26 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Tue, 7 Feb 2017 14:54:02 +0000 (15:54 +0100)
Allow `gettag()` to optionally return a table whose keys and values
are strings, to fill up the `DNSQuestion`'s `data` table.

docs/markdown/recursor/scripting.md
pdns/lua-recursor4.cc
pdns/lua-recursor4.hh
pdns/pdns_recursor.cc

index 086f7f1c124bbb8dc6ff80085908c0d2c6f5eee6..b9a1c0787833a0d2d99446948bf49ca849641478 100644 (file)
@@ -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
index 850a97d17995c0a6f03ca276106195b0f4bfed41..254d2220c2f38a498e1b1ef2fc255e934ae5271f 100644 (file)
@@ -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<std::string>* policyTags)
+int RecursorLua4::gettag(const ComboAddress& remote, const Netmask& ednssubnet, const ComboAddress& local, const DNSName& qname, uint16_t qtype, std::vector<std::string>* policyTags, std::unordered_map<string,string>& 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<std::string>* policyTags)
+int RecursorLua4::gettag(const ComboAddress& remote, const Netmask& ednssubnet, const ComboAddress& local, const DNSName& qname, uint16_t qtype, std::vector<std::string>* policyTags, std::unordered_map<string,string>& 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;
index 1502b6db435919b780c13f62b7f3843d24bff25d..efc7ac5997fb6ffb79098b2b3e5c342ab049b0ee 100644 (file)
@@ -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<std::string>* policyTags);
+  int gettag(const ComboAddress& remote, const Netmask& ednssubnet, const ComboAddress& local, const DNSName& qname, uint16_t qtype, std::vector<std::string>* policyTags, std::unordered_map<string,string>& data);
 
   bool prerpz(DNSQuestion& dq, int& ret);
   bool preresolve(DNSQuestion& dq, int& ret);
@@ -116,7 +116,7 @@ public:
             d_postresolve);
   }
 
-  typedef std::function<std::tuple<int,boost::optional<std::unordered_map<int,string> > >(ComboAddress, Netmask, ComboAddress, DNSName, uint16_t)> gettag_t;
+  typedef std::function<std::tuple<int,boost::optional<std::unordered_map<int,string> >,boost::optional<std::unordered_map<string,string> > >(ComboAddress, Netmask, ComboAddress, DNSName, uint16_t)> gettag_t;
   gettag_t d_gettag; // public so you can query if we have this hooked
 
 private:
index 7be428fa9af677fe232e0ca807aa1168a77bd531..89496f50bae4c246ea51baca1ae69aac81c59830 100644 (file)
@@ -204,6 +204,7 @@ struct DNSComboWriter {
   shared_ptr<TCPConnection> d_tcpConnection;
   vector<pair<uint16_t, string> > d_ednsOpts;
   std::vector<std::string> d_policyTags;
+  std::unordered_map<string,string> 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<std::string> policyTags;
+  std::unordered_map<string,string> 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;