]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Add a debugging function to load a grepq into the rings 9984/head
authorRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 18 Jan 2021 10:19:56 +0000 (11:19 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 18 Jan 2021 10:19:56 +0000 (11:19 +0100)
pdns/dnsdist-rings.cc
pdns/dnsdist-rings.hh
pdns/dnsdistdist/Makefile.am

index c7cb57d22bfb0b2e9fdd4a9341c2824a3e484d68..29da4431b46c44f6608d116a45b40dd85349f674 100644 (file)
@@ -20,6 +20,8 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
+#include <fstream>
+
 #include "dnsdist-rings.hh"
 
 size_t Rings::numDistinctRequestors()
@@ -79,3 +81,73 @@ std::unordered_map<int, vector<boost::variant<string,double>>> Rings::getTopBand
   ret.insert({count, {"Rest", rest, total > 0 ? 100.0*rest/total : 100.0}});
   return ret;
 }
+
+size_t Rings::loadFromFile(const std::string& filepath, const struct timespec& now)
+{
+  ifstream ifs(filepath);
+  if (!ifs) {
+    throw std::runtime_error("unable to open the file at " + filepath);
+  }
+
+  size_t inserted = 0;
+  string line;
+  dnsheader dh;
+  memset(&dh, 0, sizeof(dh));
+
+  while (std::getline(ifs, line)) {
+    boost::trim_right_if(line, boost::is_any_of(" \r\n\x1a"));
+    boost::trim_left(line);
+    bool isResponse = false;
+    vector<string> parts;
+    stringtok(parts, line, " \t,");
+
+    if (parts.size() == 7) {
+    }
+    else if (parts.size() >= 10 && parts.size() <= 12) {
+      isResponse = true;
+    }
+    else {
+      cerr<<"skipping line with "<<parts.size()<<"parts: "<<line<<endl;
+      continue;
+    }
+
+    size_t idx = 0;
+    vector<string> timeStr;
+    stringtok(timeStr, parts.at(idx++), ".");
+    if (timeStr.size() != 2) {
+      cerr<<"skipping invalid time "<<parts.at(0)<<endl;
+      continue;
+    }
+
+    struct timespec when;
+    try {
+      when.tv_sec = now.tv_sec + std::stoi(timeStr.at(0));
+      when.tv_nsec = now.tv_nsec + std::stoi(timeStr.at(1)) * 100 * 1000 * 1000;
+    }
+    catch (const std::exception& e) {
+      cerr<<"error parsing time "<<parts.at(idx-1)<<" from line "<<line<<endl;
+      continue;
+    }
+
+    ComboAddress from(parts.at(idx++));
+    ComboAddress to;
+
+    if (isResponse) {
+      to = ComboAddress(parts.at(idx++));
+    }
+    /* skip ID */
+    idx++;
+    DNSName qname(parts.at(idx++));
+    QType qtype(QType::chartocode(parts.at(idx++).c_str()));
+
+    if (!isResponse) {
+      insertResponse(when, from, qname, qtype.getCode(), 0, 0, dh, to);
+    }
+    else {
+      insertQuery(when, from, qname, qtype.getCode(), 0, dh);
+    }
+    ++inserted;
+  }
+
+  return inserted;
+}
index 8a3e089d5cfdad3cd1ccc936c2bfef074f33ba7c..511c522c1cd9ce4d50fdbf0010285960628430db 100644 (file)
@@ -191,6 +191,10 @@ struct Rings {
     d_deferredResponseInserts.store(0);
   }
 
+  /* load the content of the ring buffer from a file in the format emitted by grepq(),
+     only useful for debugging purposes */
+  size_t loadFromFile(const std::string& filepath, const struct timespec& now);
+
   std::vector<std::unique_ptr<Shard> > d_shards;
   std::atomic<uint64_t> d_blockingQueryInserts;
   std::atomic<uint64_t> d_blockingResponseInserts;
index b3b254baed4f413d62f435e3576930bade08d161..dd8d2e3bd131278ad0b87025200a348cf84fecd1 100644 (file)
@@ -233,7 +233,7 @@ testrunner_SOURCES = \
        dnsdist-lua-ffi-interface.h dnsdist-lua-ffi-interface.inc \
        dnsdist-lua-ffi.cc dnsdist-lua-ffi.hh \
        dnsdist-lua-vars.cc \
-       dnsdist-rings.hh \
+       dnsdist-rings.cc dnsdist-rings.hh \
        dnsdist-xpf.cc dnsdist-xpf.hh \
        dnsdist.hh \
        dnslabeltext.cc \