]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Use `DNSName` in `StatNode` to avoid encoding issues
authorRemi Gacogne <remi.gacogne@powerdns.com>
Thu, 26 Mar 2026 14:16:40 +0000 (15:16 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Thu, 26 Mar 2026 14:16:40 +0000 (15:16 +0100)
Signed-off-by: Remi Gacogne <remi.gacogne@powerdns.com>
pdns/dnsdistdist/dnsdist-dynblocks.hh
pdns/dnsdistdist/dnsdist-lua-inspection-ffi.cc
pdns/dnsdistdist/dnsdist-lua-inspection.cc
pdns/statnode.cc
pdns/statnode.hh

index f55677ce810019a91021429bf22ce9e1c4844e9e..ffc6a4202ad72f5d9935d1776ba244e516c43596 100644 (file)
@@ -65,6 +65,7 @@ struct dnsdist_ffi_stat_node_t
   {
   }
 
+  mutable std::string fullname;
   const StatNode& node;
   const StatNode::Stat& self;
   const StatNode::Stat& children;
index 8f58ae6b8e9c17e13725668b096a843bad38ce90..78ac1081a965da54a3525dae98f6a7cdb7188217 100644 (file)
@@ -66,9 +66,11 @@ unsigned int dnsdist_ffi_stat_node_get_labels_count(const dnsdist_ffi_stat_node_
 
 void dnsdist_ffi_stat_node_get_full_name_raw(const dnsdist_ffi_stat_node_t* node, const char** name, size_t* nameSize)
 {
-  const auto& storage = node->node.fullname;
-  *name = storage.c_str();
-  *nameSize = storage.size();
+  if (node->fullname.empty()) {
+    node->fullname = node->node.fullname.toString();
+  }
+  *name = node->fullname.c_str();
+  *nameSize = node->fullname.size();
 }
 
 unsigned int dnsdist_ffi_stat_node_get_children_count(const dnsdist_ffi_stat_node_t* node)
index 798713671b0f9d7498e19072774c6c868e483efa..8c08dbb3905e2ad63ba68c0476a40237fb0a9774 100644 (file)
@@ -902,7 +902,7 @@ void setupLuaInspection(LuaContext& luaCtx)
                                                               [](const StatNode& node) -> unsigned int {
                                                                 return node.size();
                                                               });
-  luaCtx.registerMember("fullname", &StatNode::fullname);
+  luaCtx.registerMember<std::string(StatNode::*)>(std::string("fullname"), [](const StatNode& node) -> std::string { return node.fullname.toString(); });
   luaCtx.registerMember("labelsCount", &StatNode::labelsCount);
   luaCtx.registerMember("servfails", &StatNode::Stat::servfails);
   luaCtx.registerMember("nxdomains", &StatNode::Stat::nxdomains);
index 801419a6cae1050181c6b45441c1ef1d723ddcf4..4edccff53624a7036cc2b543c1d74fc8b09558af 100644 (file)
@@ -57,7 +57,7 @@ void StatNode::submit(const DNSName& domain, int rcode, unsigned int bytes, bool
   }
 
   auto last = tmp.end() - 1;
-  children[*last].submit(last, tmp.begin(), "", rcode, bytes, remote, 1, hit, samplingRate);
+  children[*last].submit(last, tmp.begin(), g_rootdnsname, rcode, bytes, remote, 1, hit, samplingRate);
 }
 
 static uint64_t adjustForSampling(uint32_t count, size_t samplingRate)
@@ -76,7 +76,7 @@ static uint64_t adjustForSampling(uint32_t count, size_t samplingRate)
    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, const std::optional<ComboAddress>& remote, unsigned int count, bool hit, size_t samplingRate)
+void StatNode::submit(std::vector<string>::const_iterator end, std::vector<string>::const_iterator begin, const DNSName& domain, int rcode, unsigned int bytes, const std::optional<ComboAddress>& remote, unsigned int count, bool hit, size_t samplingRate)
 {
   //  cerr<<"Submit called for domain='"<<domain<<"': ";
   //  for(const std::string& n :  labels) 
@@ -93,13 +93,8 @@ void StatNode::submit(std::vector<string>::const_iterator end, std::vector<strin
 
   if (end == begin) {
     if (fullname.empty()) {
-      size_t needed = name.size() + 1 + domain.size();
-      if (fullname.capacity() < needed) {
-        fullname.reserve(needed);
-      }
-      fullname = name;
-      fullname.append(".");
-      fullname.append(domain);
+      fullname = domain;
+      fullname.prependRawLabel(name);
       labelsCount = count;
     }
     //    cerr<<"Hit the end, set our fullname to '"<<fullname<<"'"<<endl<<endl;
@@ -128,13 +123,8 @@ void StatNode::submit(std::vector<string>::const_iterator end, std::vector<strin
   }
   else {
     if (fullname.empty()) {
-      size_t needed = name.size() + 1 + domain.size();
-      if (fullname.capacity() < needed) {
-        fullname.reserve(needed);
-      }
-      fullname = name;
-      fullname.append(".");
-      fullname.append(domain);
+      fullname = domain;
+      fullname.prependRawLabel(name);
       labelsCount = count;
     }
     //    cerr<<"Not yet end, set our fullname to '"<<fullname<<"', recursing"<<endl;
index 6635c4953197596d121f5ebb547c4d68238523f7..c2da59c022830f2eb280847a831ca0fd7a159e14 100644 (file)
@@ -61,7 +61,7 @@ public:
 
   Stat s;
   std::string name;
-  std::string fullname;
+  DNSName fullname;
   uint8_t labelsCount{0};
 
   void submit(const DNSName& domain, int rcode, uint32_t bytes, bool hit, const std::optional<ComboAddress>& remote, size_t samplingRate);
@@ -77,7 +77,7 @@ public:
   }
 
 private:
-  void submit(std::vector<string>::const_iterator end, std::vector<string>::const_iterator begin, const std::string& domain, int rcode, uint32_t bytes, const std::optional<ComboAddress>& remote, unsigned int count, bool hit, size_t samplingRate);
+  void submit(std::vector<string>::const_iterator end, std::vector<string>::const_iterator begin, const DNSName& domain, int rcode, uint32_t bytes, const std::optional<ComboAddress>& remote, unsigned int count, bool hit, size_t samplingRate);
 
   using children_t = std::map<std::string, StatNode, CIStringCompare>;
   children_t children;