]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Count hits in the StatNode 12626/head
authorRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 3 Mar 2023 17:00:08 +0000 (18:00 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Tue, 7 Mar 2023 18:14:47 +0000 (19:14 +0100)
pdns/dnsdist-lua-inspection.cc
pdns/dnsdistdist/dnsdist-dynblocks.cc
pdns/dnsdistdist/dnsdist-lua-inspection-ffi.cc
pdns/dnsdistdist/dnsdist-lua-inspection-ffi.hh
pdns/dnsscope.cc
pdns/statnode.cc
pdns/statnode.hh

index ccc4a997cb82249f26e5c689f35ba5593afc1374..86b3e0b5918c324128aa1cd99a2ff2c818ff50d7 100644 (file)
@@ -114,7 +114,7 @@ static counts_t filterScore(const counts_t& counts,
   return ret;
 }
 
-typedef std::function<void(const StatNode&, const StatNode::Stat&, const StatNode::Stat&)> statvisitor_t;
+using statvisitor_t = std::function<void(const StatNode&, const StatNode::Stat&, const StatNode::Stat&)>;
 
 static void statNodeRespRing(statvisitor_t visitor, uint64_t seconds)
 {
@@ -128,13 +128,20 @@ static void statNodeRespRing(statvisitor_t visitor, uint64_t seconds)
     auto rl = shard->respRing.lock();
 
     for(const auto& c : *rl) {
-      if (now < c.when)
+      if (now < c.when){
         continue;
+      }
 
-      if (seconds && c.when < cutoff)
+      if (seconds && c.when < cutoff) {
         continue;
+      }
+
+      bool hit = c.ds.sin4.sin_family == 0;
+      if (!hit && c.ds.isIPv4() && c.ds.sin4.sin_addr.s_addr == 0 && c.ds.sin4.sin_port == 0) {
+        hit = true;
+      }
 
-      root.submit(c.name, ((c.dh.rcode == 0 && c.usec == std::numeric_limits<unsigned int>::max()) ? -1 : c.dh.rcode), c.size, boost::none);
+      root.submit(c.name, ((c.dh.rcode == 0 && c.usec == std::numeric_limits<unsigned int>::max()) ? -1 : c.dh.rcode), c.size, hit, boost::none);
     }
   }
 
@@ -785,6 +792,7 @@ void setupLuaInspection(LuaContext& luaCtx)
   luaCtx.registerMember("noerrors", &StatNode::Stat::noerrors);
   luaCtx.registerMember("drops", &StatNode::Stat::drops);
   luaCtx.registerMember("bytes", &StatNode::Stat::bytes);
+  luaCtx.registerMember("hits", &StatNode::Stat::hits);
 
   luaCtx.writeFunction("statNodeRespRing", [](statvisitor_t visitor, boost::optional<uint64_t> seconds) {
       statNodeRespRing(visitor, seconds ? *seconds : 0U);
index d6d84c0b9935f4dc449276e51361a4201f2384ca..ae9896ed273d6339ff59a56e63e149ca6e4683a8 100644 (file)
@@ -416,7 +416,12 @@ void DynBlockRulesGroup::processResponseRules(counts_t& counts, StatNode& root,
       }
 
       if (suffixMatchRuleMatches) {
-        root.submit(c.name, ((c.dh.rcode == 0 && c.usec == std::numeric_limits<unsigned int>::max()) ? -1 : c.dh.rcode), c.size, boost::none);
+        bool hit = c.ds.sin4.sin_family == 0;
+        if (!hit && c.ds.isIPv4() && c.ds.sin4.sin_addr.s_addr == 0 && c.ds.sin4.sin_port == 0) {
+          hit = true;
+        }
+
+        root.submit(c.name, ((c.dh.rcode == 0 && c.usec == std::numeric_limits<unsigned int>::max()) ? -1 : c.dh.rcode), c.size, hit, boost::none);
       }
     }
   }
index 4c50e4bf15f7c61eddb16715f60bbc52ed47048b..0187ebcb4e74660c678f456004911537d386b575 100644 (file)
@@ -54,6 +54,11 @@ uint64_t dnsdist_ffi_stat_node_get_bytes(const dnsdist_ffi_stat_node_t* node)
   return node->self.bytes;
 }
 
+uint64_t dnsdist_ffi_stat_node_get_hits(const dnsdist_ffi_stat_node_t* node)
+{
+  return node->self.hits;
+}
+
 unsigned int dnsdist_ffi_stat_node_get_labels_count(const dnsdist_ffi_stat_node_t* node)
 {
   return node->node.labelsCount;
@@ -101,6 +106,11 @@ uint64_t dnsdist_ffi_stat_node_get_children_bytes_count(const dnsdist_ffi_stat_n
   return node->children.bytes;
 }
 
+uint64_t dnsdist_ffi_stat_node_get_children_hits(const dnsdist_ffi_stat_node_t* node)
+{
+  return node->children.hits;
+}
+
 void dnsdist_ffi_state_node_set_reason(dnsdist_ffi_stat_node_t* node, const char* reason, size_t reasonSize)
 {
   node->reason = std::string(reason, reasonSize);
index 05f087f649d4f31126b0b48aefe965ebcc26a800..f45a180dc6767d4dac77020627c0dd462a57336f 100644 (file)
@@ -29,6 +29,7 @@ extern "C" {
   uint64_t dnsdist_ffi_stat_node_get_servfails_count(const dnsdist_ffi_stat_node_t* node) __attribute__ ((visibility ("default")));
   uint64_t dnsdist_ffi_stat_node_get_drops_count(const dnsdist_ffi_stat_node_t* node) __attribute__ ((visibility ("default")));
   uint64_t dnsdist_ffi_stat_node_get_bytes(const dnsdist_ffi_stat_node_t* node) __attribute__ ((visibility ("default")));
+  uint64_t dnsdist_ffi_stat_node_get_hits(const dnsdist_ffi_stat_node_t* node) __attribute__ ((visibility ("default")));
   unsigned int dnsdist_ffi_stat_node_get_labels_count(const dnsdist_ffi_stat_node_t* node) __attribute__ ((visibility ("default")));
   void dnsdist_ffi_stat_node_get_full_name_raw(const dnsdist_ffi_stat_node_t* node, const char** name, size_t* nameSize) __attribute__ ((visibility ("default")));
 
@@ -40,6 +41,7 @@ extern "C" {
   uint64_t dnsdist_ffi_stat_node_get_children_servfails_count(const dnsdist_ffi_stat_node_t* node) __attribute__ ((visibility ("default")));
   uint64_t dnsdist_ffi_stat_node_get_children_drops_count(const dnsdist_ffi_stat_node_t* node) __attribute__ ((visibility ("default")));
   uint64_t dnsdist_ffi_stat_node_get_children_bytes_count(const dnsdist_ffi_stat_node_t* node) __attribute__ ((visibility ("default")));
+  uint64_t dnsdist_ffi_stat_node_get_children_hits(const dnsdist_ffi_stat_node_t* node) __attribute__ ((visibility ("default")));
 
   void dnsdist_ffi_state_node_set_reason(dnsdist_ffi_stat_node_t* node, const char* reason, size_t reasonSize) __attribute__ ((visibility ("default")));
 }
index 2f858813a4e49a63daa1a8b139886a2ac9e1356c..10dc10acc01196babe0dc410b92df5081164e866 100644 (file)
@@ -358,7 +358,7 @@ try
              rem.sin4.sin_port=0;
 
              if(doServFailTree)
-               root.submit(qname, header.rcode, pr.d_len, rem);
+               root.submit(qname, header.rcode, pr.d_len, false, rem);
            }
 
            if(!qd.d_qcount || qd.d_qcount == qd.d_answercount) {
index e4c8f9edb50f669f79d6d6b25cf2cb2c77eac3cf..a2b493496edbe8a51b716f0014b254c0372a6b74 100644 (file)
@@ -13,6 +13,7 @@ StatNode::Stat StatNode::print(unsigned int depth, Stat newstat, bool silent) co
   childstat.servfails += s.servfails;
   childstat.drops += s.drops;
   childstat.bytes += s.bytes;
+  childstat.hits += s.hits;
 
   if(children.size()>1024 && !silent) {
     cout<<string(depth, ' ')<<name<<": too many to print"<<endl;
@@ -26,7 +27,8 @@ StatNode::Stat StatNode::print(unsigned int depth, Stat newstat, bool silent) co
       childstat.nxdomains<<" nxdomains, "<< 
       childstat.servfails<<" servfails, "<< 
       childstat.drops<<" drops, "<<
-      childstat.bytes<<" bytes"<<endl;
+      childstat.bytes<<" bytes, "<<
+      childstat.hits<<" hits"<<endl;
 
   newstat+=childstat;
 
@@ -48,7 +50,7 @@ void StatNode::visit(visitor_t visitor, Stat &newstat, unsigned int depth) const
 }
 
 
-void StatNode::submit(const DNSName& domain, int rcode, unsigned int bytes, boost::optional<const ComboAddress&> remote)
+void StatNode::submit(const DNSName& domain, int rcode, unsigned int bytes, bool hit, boost::optional<const ComboAddress&> remote)
 {
   //  cerr<<"FIRST submit called on '"<<domain<<"'"<<endl;
   std::vector<string> tmp = domain.getRawLabels();
@@ -57,7 +59,7 @@ void StatNode::submit(const DNSName& domain, int rcode, unsigned int bytes, boos
   }
 
   auto last = tmp.end() - 1;
-  children[*last].submit(last, tmp.begin(), "", rcode, bytes, remote, 1);
+  children[*last].submit(last, tmp.begin(), "", rcode, bytes, remote, 1, hit);
 }
 
 /* www.powerdns.com. -> 
@@ -67,7 +69,7 @@ void StatNode::submit(const DNSName& domain, int rcode, unsigned int bytes, boos
    www.powerdns.com. 
 */
 
-void StatNode::submit(std::vector<string>::const_iterator end, std::vector<string>::const_iterator begin, const std::string& domain, int rcode, unsigned int bytes, boost::optional<const ComboAddress&> remote, unsigned int count)
+void StatNode::submit(std::vector<string>::const_iterator end, std::vector<string>::const_iterator begin, const std::string& domain, int rcode, unsigned int bytes, boost::optional<const ComboAddress&> remote, unsigned int count, bool hit)
 {
   //  cerr<<"Submit called for domain='"<<domain<<"': ";
   //  for(const std::string& n :  labels) 
@@ -96,18 +98,26 @@ void StatNode::submit(std::vector<string>::const_iterator end, std::vector<strin
     //    cerr<<"Hit the end, set our fullname to '"<<fullname<<"'"<<endl<<endl;
     s.queries++;
     s.bytes += bytes;
-    if(rcode<0)
+    if (rcode < 0) {
       s.drops++;
-    else if(rcode==0)
+    }
+    else if (rcode == RCode::NoError) {
       s.noerrors++;
-    else if(rcode==2)
+    }
+    else if (rcode == RCode::ServFail) {
       s.servfails++;
-    else if(rcode==3)
+    }
+    else if (rcode == RCode::NXDomain) {
       s.nxdomains++;
+    }
 
     if (remote) {
       s.remotes[*remote]++;
     }
+
+    if (hit) {
+      ++s.hits;
+    }
   }
   else {
     if (fullname.empty()) {
@@ -122,6 +132,6 @@ void StatNode::submit(std::vector<string>::const_iterator end, std::vector<strin
     }
     //    cerr<<"Not yet end, set our fullname to '"<<fullname<<"', recursing"<<endl;
     --end;
-    children[*end].submit(end, begin, fullname, rcode, bytes, remote, count+1);
+    children[*end].submit(end, begin, fullname, rcode, bytes, remote, count+1, hit);
   }
 }
index 88b4a210aa7d1a63eb7fd7ee57208cc1e6da0a42..4f9590507e21bf0e13c2cf3bf97e8464454c575f 100644 (file)
@@ -30,45 +30,53 @@ public:
 
   struct Stat
   {
-    Stat(): queries(0), noerrors(0), nxdomains(0), servfails(0), drops(0), bytes(0)
+    Stat()
     {
     }
-    uint64_t queries, noerrors, nxdomains, servfails, drops, bytes;
+
+    uint64_t queries{0};
+    uint64_t noerrors{0};
+    uint64_t nxdomains{0};
+    uint64_t servfails{0};
+    uint64_t drops{0};
+    uint64_t bytes{0};
+    uint64_t hits{0};
+    using remotes_t = std::map<ComboAddress,int,ComboAddress::addressOnlyLessThan>;
+    remotes_t remotes;
 
     Stat& operator+=(const Stat& rhs) {
-      queries+=rhs.queries;
-      noerrors+=rhs.noerrors;
-      nxdomains+=rhs.nxdomains;
-      servfails+=rhs.servfails;
-      drops+=rhs.drops;
-      bytes+=rhs.bytes;
+      queries += rhs.queries;
+      noerrors += rhs.noerrors;
+      nxdomains += rhs.nxdomains;
+      servfails += rhs.servfails;
+      drops += rhs.drops;
+      bytes += rhs.bytes;
+      hits += rhs.hits;
 
-      for(const remotes_t::value_type& rem : rhs.remotes) {
-        remotes[rem.first]+=rem.second;
+      for (const remotes_t::value_type& rem : rhs.remotes) {
+        remotes[rem.first] += rem.second;
       }
       return *this;
     }
-    typedef std::map<ComboAddress,int,ComboAddress::addressOnlyLessThan> remotes_t;
-    remotes_t remotes;
   };
 
+  using visitor_t = std::function<void(const StatNode*, const Stat& selfstat, const Stat& childstat)>;
+  using children_t = std::map<std::string, StatNode, CIStringCompare>;
+
   Stat s;
   std::string name;
   std::string fullname;
   uint8_t labelsCount{0};
 
-  void submit(const DNSName& domain, int rcode, unsigned int bytes, boost::optional<const ComboAddress&> remote);
-
+  void submit(const DNSName& domain, int rcode, unsigned int bytes, bool hit, boost::optional<const ComboAddress&> remote);
   Stat print(unsigned int depth=0, Stat newstat=Stat(), bool silent=false) const;
-  typedef std::function<void(const StatNode*, const Stat& selfstat, const Stat& childstat)> visitor_t;
   void visit(visitor_t visitor, Stat& newstat, unsigned int depth=0) const;
   bool empty() const
   {
     return children.empty() && s.remotes.empty();
   }
-  typedef std::map<std::string,StatNode, CIStringCompare> children_t;
   children_t children;
 
 private:
-  void submit(std::vector<string>::const_iterator end, std::vector<string>::const_iterator begin, const std::string& domain, int rcode, unsigned int bytes, boost::optional<const ComboAddress&> remote, unsigned int count);
+  void submit(std::vector<string>::const_iterator end, std::vector<string>::const_iterator begin, const std::string& domain, int rcode, unsigned int bytes, boost::optional<const ComboAddress&> remote, unsigned int count, bool hit);
 };