From: Remi Gacogne Date: Fri, 3 Mar 2023 17:00:08 +0000 (+0100) Subject: dnsdist: Count hits in the StatNode X-Git-Tag: dnsdist-1.8.0-rc3~2^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fpull%2F12626%2Fhead;p=thirdparty%2Fpdns.git dnsdist: Count hits in the StatNode --- diff --git a/pdns/dnsdist-lua-inspection.cc b/pdns/dnsdist-lua-inspection.cc index ccc4a997cb..86b3e0b591 100644 --- a/pdns/dnsdist-lua-inspection.cc +++ b/pdns/dnsdist-lua-inspection.cc @@ -114,7 +114,7 @@ static counts_t filterScore(const counts_t& counts, return ret; } -typedef std::function statvisitor_t; +using statvisitor_t = std::function; 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::max()) ? -1 : c.dh.rcode), c.size, boost::none); + root.submit(c.name, ((c.dh.rcode == 0 && c.usec == std::numeric_limits::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 seconds) { statNodeRespRing(visitor, seconds ? *seconds : 0U); diff --git a/pdns/dnsdistdist/dnsdist-dynblocks.cc b/pdns/dnsdistdist/dnsdist-dynblocks.cc index d6d84c0b99..ae9896ed27 100644 --- a/pdns/dnsdistdist/dnsdist-dynblocks.cc +++ b/pdns/dnsdistdist/dnsdist-dynblocks.cc @@ -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::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::max()) ? -1 : c.dh.rcode), c.size, hit, boost::none); } } } diff --git a/pdns/dnsdistdist/dnsdist-lua-inspection-ffi.cc b/pdns/dnsdistdist/dnsdist-lua-inspection-ffi.cc index 4c50e4bf15..0187ebcb4e 100644 --- a/pdns/dnsdistdist/dnsdist-lua-inspection-ffi.cc +++ b/pdns/dnsdistdist/dnsdist-lua-inspection-ffi.cc @@ -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); diff --git a/pdns/dnsdistdist/dnsdist-lua-inspection-ffi.hh b/pdns/dnsdistdist/dnsdist-lua-inspection-ffi.hh index 05f087f649..f45a180dc6 100644 --- a/pdns/dnsdistdist/dnsdist-lua-inspection-ffi.hh +++ b/pdns/dnsdistdist/dnsdist-lua-inspection-ffi.hh @@ -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"))); } diff --git a/pdns/dnsscope.cc b/pdns/dnsscope.cc index 2f858813a4..10dc10acc0 100644 --- a/pdns/dnsscope.cc +++ b/pdns/dnsscope.cc @@ -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) { diff --git a/pdns/statnode.cc b/pdns/statnode.cc index e4c8f9edb5..a2b493496e 100644 --- a/pdns/statnode.cc +++ b/pdns/statnode.cc @@ -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< remote) +void StatNode::submit(const DNSName& domain, int rcode, unsigned int bytes, bool hit, boost::optional remote) { // cerr<<"FIRST submit called on '"< 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::const_iterator end, std::vector::const_iterator begin, const std::string& domain, int rcode, unsigned int bytes, boost::optional remote, unsigned int count) +void StatNode::submit(std::vector::const_iterator end, std::vector::const_iterator begin, const std::string& domain, int rcode, unsigned int bytes, boost::optional remote, unsigned int count, bool hit) { // cerr<<"Submit called for domain='"<::const_iterator end, std::vector::const_iterator end, std::vector; + 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 remotes_t; - remotes_t remotes; }; + using visitor_t = std::function; + using children_t = std::map; + Stat s; std::string name; std::string fullname; uint8_t labelsCount{0}; - void submit(const DNSName& domain, int rcode, unsigned int bytes, boost::optional remote); - + void submit(const DNSName& domain, int rcode, unsigned int bytes, bool hit, boost::optional remote); Stat print(unsigned int depth=0, Stat newstat=Stat(), bool silent=false) const; - typedef std::function 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 children_t; children_t children; private: - void submit(std::vector::const_iterator end, std::vector::const_iterator begin, const std::string& domain, int rcode, unsigned int bytes, boost::optional remote, unsigned int count); + void submit(std::vector::const_iterator end, std::vector::const_iterator begin, const std::string& domain, int rcode, unsigned int bytes, boost::optional remote, unsigned int count, bool hit); };