]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Split query/response actions
authorRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 21 Mar 2016 17:42:22 +0000 (18:42 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 21 Mar 2016 17:42:22 +0000 (18:42 +0100)
pdns/dnsdist-lua.cc
pdns/dnsdist-lua2.cc
pdns/dnsdist-tcp.cc
pdns/dnsdist.cc
pdns/dnsdist.hh
pdns/dnsrulactions.hh

index 12d51580e5b71d69e667a1e02b24e9164683fbf4..0ab42a439a8605af1c1978555c4e98078c8a1fa6 100644 (file)
@@ -134,6 +134,10 @@ vector<std::function<void(void)>> setupLua(bool client, const std::string& confi
       {"Delay", (int)DNSAction::Action::Delay}}
     );
 
+    g_lua.writeVariable("DNSResponseAction", std::unordered_map<string,int>{
+      {"None",(int)DNSResponseAction::Action::None}}
+    );
+
   vector<pair<string, int> > dd;
   for(const auto& n : QType::names)
     dd.push_back({n.first, n.second});
@@ -1321,7 +1325,7 @@ vector<std::function<void(void)>> setupLua(bool client, const std::string& confi
 
   g_lua.writeFunction("setECSOverride", [](bool override) { g_ECSOverride=override; });
 
-  g_lua.writeFunction("addResponseAction", [](luadnsrule_t var, std::shared_ptr<DNSAction> ea) {
+  g_lua.writeFunction("addResponseAction", [](luadnsrule_t var, std::shared_ptr<DNSResponseAction> ea) {
       setLuaSideEffect();
       auto rule=makeRule(var);
       g_resprulactions.modify([rule, ea](decltype(g_resprulactions)::value_type& rulactions){
index 962438860000ff85af80d0e009b37435008a481b..91553f246aac9b6a67887b46ed6f0c1dce78c856 100644 (file)
@@ -578,7 +578,7 @@ void moreLua(bool client)
         return std::shared_ptr<DNSAction>(new RemoteLogAction(logger));
       });
     g_lua.writeFunction("RemoteLogResponseAction", [](std::shared_ptr<RemoteLogger> logger) {
-        return std::shared_ptr<DNSAction>(new RemoteLogResponseAction(logger));
+        return std::shared_ptr<DNSResponseAction>(new RemoteLogResponseAction(logger));
       });
     g_lua.writeFunction("newRemoteLogger", [client](const std::string& remote) {
         return std::make_shared<RemoteLogger>(ComboAddress(remote));
index 432542de212118299d7c160c588c54f30553682c..a6cca5dfbe95bc64de438d78abb8499b968fcba2 100644 (file)
@@ -265,7 +265,7 @@ void* tcpClientThread(int pipefd)
        struct timespec now;
        clock_gettime(CLOCK_MONOTONIC, &now);
 
-       if (!processQuery(localDynBlockNMG, localRulactions, blockFilter, dq, ci.remote, poolname, &delayMsec, now)) {
+       if (!processQuery(localDynBlockNMG, localRulactions, blockFilter, dq, poolname, &delayMsec, now)) {
          goto drop;
        }
 
@@ -412,16 +412,12 @@ void* tcpClientThread(int pipefd)
           break;
         }
 
-        DNSQuestion dr(&rqname, rqtype, rqclass, &ci.cs->local, &ci.remote, dh, responseSize, responseLen, true);
+        DNSQuestion dr(&qname, qtype, qclass, &ci.cs->local, &ci.remote, dh, responseSize, responseLen, true);
 #ifdef HAVE_PROTOBUF
         dr.uniqueId = dq.uniqueId;
 #endif
-        for(const auto& lr : *localRespRulactions) {
-          if(lr.first->matches(&dr)) {
-            lr.first->d_matches++;
-            /* for now we only support actions returning None */
-            (*lr.second)(&dr, &ruleresult);
-          }
+        if (!processResponse(localRespRulactions, dr)) {
+          break;
         }
 
        if (packetCache && !dq.skipCache) {
index 773a79d055345e797d1689c4f45ebcb41db562f1..9883b12a94d38fa0cd52c1e8494a7918f541a94c 100644 (file)
@@ -108,7 +108,7 @@ GlobalStateHolder<pools_t> g_pools;
    If all downstreams are over QPS, we pick the fastest server */
 
 GlobalStateHolder<vector<pair<std::shared_ptr<DNSRule>, std::shared_ptr<DNSAction> > > > g_rulactions;
-GlobalStateHolder<vector<pair<std::shared_ptr<DNSRule>, std::shared_ptr<DNSAction> > > > g_resprulactions;
+GlobalStateHolder<vector<pair<std::shared_ptr<DNSRule>, std::shared_ptr<DNSResponseAction> > > > g_resprulactions;
 Rings g_rings;
 
 GlobalStateHolder<servers_t> g_dstates;
@@ -341,17 +341,12 @@ void* responderThread(std::shared_ptr<DownstreamState> state)
     dh->id = ids->origID;
 
     uint16_t addRoom = 0;
-    DNSQuestion dq(&ids->qname, ids->qtype, ids->qclass, &ids->origDest, &ids->origRemote, dh, sizeof(packet), responseLen, false);
+    DNSQuestion dr(&ids->qname, ids->qtype, ids->qclass, &ids->origDest, &ids->origRemote, dh, sizeof(packet), responseLen, false);
 #ifdef HAVE_PROTOBUF
-    dq.uniqueId = ids->uniqueId;
+    dr.uniqueId = ids->uniqueId;
 #endif
-    string ruleresult;
-    for(const auto& lr : *localRespRulactions) {
-      if(lr.first->matches(&dq)) {
-        lr.first->d_matches++;
-        /* for now we only support actions returning None */
-        (*lr.second)(&dq, &ruleresult);
-      }
+    if (!processResponse(localRespRulactions, dr)) {
+      break;
     }
 
 #ifdef HAVE_DNSCRYPT
@@ -665,16 +660,16 @@ void spoofResponseFromString(DNSQuestion& dq, const string& spoofContent)
   }
 }
 
-bool processQuery(LocalStateHolder<NetmaskTree<DynBlock> >& localDynBlock, LocalStateHolder<vector<pair<std::shared_ptr<DNSRule>, std::shared_ptr<DNSAction> > > >& localRulactions, blockfilter_t blockFilter, DNSQuestion& dq, const ComboAddress& remote, string& poolname, int* delayMsec, const struct timespec& now)
+bool processQuery(LocalStateHolder<NetmaskTree<DynBlock> >& localDynBlock, LocalStateHolder<vector<pair<std::shared_ptr<DNSRule>, std::shared_ptr<DNSAction> > > >& localRulactions, blockfilter_t blockFilter, DNSQuestion& dq, string& poolname, int* delayMsec, const struct timespec& now)
 {
   {
     WriteLock wl(&g_rings.queryLock);
-    g_rings.queryRing.push_back({now,remote,*dq.qname,dq.len,dq.qtype,*dq.dh});
+    g_rings.queryRing.push_back({now,*dq.remote,*dq.qname,dq.len,dq.qtype,*dq.dh});
   }
 
-  if(auto got=localDynBlock->lookup(remote)) {
+  if(auto got=localDynBlock->lookup(*dq.remote)) {
     if(now < got->second.until) {
-      vinfolog("Query from %s dropped because of dynamic block", remote.toStringWithPort());
+      vinfolog("Query from %s dropped because of dynamic block", dq.remote->toStringWithPort());
       g_stats.dynBlocked++;
       got->second.blocks++;
       return false;
@@ -735,6 +730,20 @@ bool processQuery(LocalStateHolder<NetmaskTree<DynBlock> >& localDynBlock, Local
   return true;
 }
 
+bool processResponse(LocalStateHolder<vector<pair<std::shared_ptr<DNSRule>, std::shared_ptr<DNSResponseAction> > > >& localRespRulactions, DNSQuestion& dr)
+{
+  std::string ruleresult;
+  for(const auto& lr : *localRespRulactions) {
+    if(lr.first->matches(&dr)) {
+      lr.first->d_matches++;
+      /* for now we only support actions returning None */
+      (*lr.second)(&dr, &ruleresult);
+    }
+  }
+
+  return true;
+}
+
 static ssize_t udpClientSendRequestToBackend(DownstreamState* ss, const int sd, const char* request, const size_t requestLen)
 {
   if (ss->sourceItf == 0) {
@@ -867,7 +876,7 @@ try
       struct timespec now;
       clock_gettime(CLOCK_MONOTONIC, &now);
 
-      if (!processQuery(localDynBlock, localRulactions, blockFilter, dq, remote, poolname, &delayMsec, now))
+      if (!processQuery(localDynBlock, localRulactions, blockFilter, dq, poolname, &delayMsec, now))
       {
         continue;
       }
index 6e2e735d17b609879fc7897a4a62cdadf23dd1c7..6e92f515164c66d2ee5ce1d9597270d61273643a 100644 (file)
@@ -425,6 +425,14 @@ public:
   virtual string toString() const = 0;
 };
 
+class DNSResponseAction
+{
+public:
+  enum class Action { None };
+  virtual Action operator()(DNSQuestion*, string* ruleresult) const =0;
+  virtual string toString() const = 0;
+};
+
 using NumberedServerVector = NumberedVector<shared_ptr<DownstreamState>>;
 typedef std::function<shared_ptr<DownstreamState>(const NumberedServerVector& servers, const DNSQuestion*)> policyfunc_t;
 
@@ -462,7 +470,7 @@ extern GlobalStateHolder<ServerPolicy> g_policy;
 extern GlobalStateHolder<servers_t> g_dstates;
 extern GlobalStateHolder<pools_t> g_pools;
 extern GlobalStateHolder<vector<pair<std::shared_ptr<DNSRule>, std::shared_ptr<DNSAction> > > > g_rulactions;
-extern GlobalStateHolder<vector<pair<std::shared_ptr<DNSRule>, std::shared_ptr<DNSAction> > > > g_resprulactions;
+extern GlobalStateHolder<vector<pair<std::shared_ptr<DNSRule>, std::shared_ptr<DNSResponseAction> > > > g_resprulactions;
 extern GlobalStateHolder<NetmaskGroup> g_ACL;
 
 extern ComboAddress g_serverControl; // not changed during runtime
@@ -520,7 +528,8 @@ bool getLuaNoSideEffect(); // set if there were only explicit declarations of _n
 void resetLuaSideEffect(); // reset to indeterminate state
 
 bool responseContentMatches(const char* response, const uint16_t responseLen, const DNSName& qname, const uint16_t qtype, const uint16_t qclass, const ComboAddress& remote);
-bool processQuery(LocalStateHolder<NetmaskTree<DynBlock> >& localDynBlock, LocalStateHolder<vector<pair<std::shared_ptr<DNSRule>, std::shared_ptr<DNSAction> > > >& localRulactions, blockfilter_t blockFilter, DNSQuestion& dq, const ComboAddress& remote, string& poolname, int* delayMsec, const struct timespec& now);
+bool processQuery(LocalStateHolder<NetmaskTree<DynBlock> >& localDynBlock, LocalStateHolder<vector<pair<std::shared_ptr<DNSRule>, std::shared_ptr<DNSAction> > > >& localRulactions, blockfilter_t blockFilter, DNSQuestion& dq, string& poolname, int* delayMsec, const struct timespec& now);
+bool processResponse(LocalStateHolder<vector<pair<std::shared_ptr<DNSRule>, std::shared_ptr<DNSResponseAction> > > >& localRespRulactions, DNSQuestion& dq);
 bool fixUpResponse(char** response, uint16_t* responseLen, size_t* responseSize, const DNSName& qname, uint16_t origFlags, bool ednsAdded, std::vector<uint8_t>& rewrittenResponse, uint16_t addRoom);
 void restoreFlags(struct dnsheader* dh, uint16_t origFlags);
 
index 63cacd33b9f5a1bf9e85f57192afd0189d70bca3..6f15664bbd5d0df5feb5be88808c61adf013c261 100644 (file)
@@ -731,13 +731,13 @@ private:
   std::shared_ptr<RemoteLogger> d_logger;
 };
 
-class RemoteLogResponseAction : public DNSAction, public boost::noncopyable
+class RemoteLogResponseAction : public DNSResponseAction, public boost::noncopyable
 {
 public:
   RemoteLogResponseAction(std::shared_ptr<RemoteLogger> logger): d_logger(logger)
   {
   }
-  DNSAction::Action operator()(DNSQuestion* dq, string* ruleresult) const override
+  DNSResponseAction::Action operator()(DNSQuestion* dq, string* ruleresult) const override
   {
     d_logger->logResponse(*dq);
     return Action::None;