]> granicus.if.org Git - pdns/commitdiff
add 'speedtest' infrastructure
authorBert Hubert <bert.hubert@netherlabs.nl>
Sat, 5 Sep 2009 14:05:36 +0000 (14:05 +0000)
committerBert Hubert <bert.hubert@netherlabs.nl>
Sat, 5 Sep 2009 14:05:36 +0000 (14:05 +0000)
git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@1401 d19b8d6e-7fed-0310-83ef-9ca221ded41b

pdns/Makefile.am
pdns/speedtest.cc [new file with mode: 0644]

index 1e7fd74a77a064c49b48087b55ab7504390a27c1..37ffe4fd189bbd75e469826f763a0b7268a34854 100644 (file)
@@ -19,7 +19,7 @@ bin_PROGRAMS = pdns_control
 endif
 
 
-EXTRA_PROGRAMS=pdns_recursor sdig dnspbench pdns_control dnsscope dnsgram dnsdemog dnswasher dnsreplay dnsscan dnslog nproxy notify
+EXTRA_PROGRAMS=pdns_recursor sdig speedtest dnspbench pdns_control dnsscope dnsgram dnsdemog dnswasher dnsreplay dnsscan dnslog nproxy notify
 
 pdns_server_SOURCES=dnspacket.cc nameserver.cc tcpreceiver.hh \
 qtype.cc logger.cc arguments.cc packethandler.cc tcpreceiver.cc \
@@ -51,9 +51,13 @@ sdig_SOURCES=sdig.cc sstuff.hh dnsparser.cc dnsparser.hh dnsrecords.cc dnswriter
        misc.cc misc.hh rcpgenerator.cc rcpgenerator.hh base64.cc base64.hh unix_utility.cc \
        logger.cc statbag.cc qtype.cc sillyrecords.cc
 
+speedtest_SOURCES=speedtest.cc dnsparser.cc dnsparser.hh dnsrecords.cc dnswriter.cc dnswriter.hh \
+       misc.cc misc.hh rcpgenerator.cc rcpgenerator.hh base64.cc base64.hh unix_utility.cc \
+       qtype.cc sillyrecords.cc logger.cc statbag.cc
+
 dnspbench_SOURCES=dnspbench.cc sstuff.hh dnsparser.cc dnsparser.hh dnsrecords.cc dnswriter.cc dnswriter.hh \
        misc.cc misc.hh rcpgenerator.cc rcpgenerator.hh base64.cc base64.hh unix_utility.cc logger.cc \
-       statbag.cc qtype.cc sillyrecords.cc
+       statbag.cc qtype.cc sillyrecords.cc 
 
 dnswasher_SOURCES=dnswasher.cc misc.cc unix_utility.cc qtype.cc \
        logger.cc statbag.cc  dnspcap.cc dnspcap.hh dnsparser.hh 
diff --git a/pdns/speedtest.cc b/pdns/speedtest.cc
new file mode 100644 (file)
index 0000000..70b78fb
--- /dev/null
@@ -0,0 +1,507 @@
+#include "dnsparser.hh"
+#include "sstuff.hh"
+#include "misc.hh"
+#include "dnswriter.hh"
+#include "dnsrecords.hh"
+#include <boost/format.hpp>
+#ifndef RECURSOR
+#include "statbag.hh"
+StatBag S;
+#endif
+
+uint64_t g_totalRuns;
+
+volatile bool g_stop;
+
+void alarmHandler(int)
+{
+  g_stop=true;
+}
+
+template<typename C> void doRun(const C& cmd, int mseconds=100)
+{
+  struct itimerval it;
+  it.it_value.tv_sec=mseconds/1000;
+  it.it_value.tv_usec = 1000* (mseconds%1000);
+  it.it_interval.tv_sec=0;
+  it.it_interval.tv_usec=0;
+
+  setitimer(ITIMER_VIRTUAL, &it, 0);
+
+
+  unsigned int runs=0;
+  g_stop=false;
+  DTime dt;
+  dt.set();
+  while(runs++, !g_stop) {
+    cmd();
+  }
+  double delta=dt.udiff()/1000000.0;
+  boost::format fmt("'%s' %.02f seconds: %.1f runs/s, %.02f usec/run");
+
+  cerr<< (fmt % cmd.getName() % delta % (runs/delta) % (delta* 1000000.0/runs)) << endl;
+  g_totalRuns += runs;
+}
+
+struct ARecordTest
+{
+  explicit ARecordTest(int records) : d_records(records) {}
+
+  string getName() const
+  {
+    return (boost::format("%d a records") % d_records).str();
+  }
+
+  void operator()() const
+  {
+    vector<uint8_t> packet;
+    DNSPacketWriter pw(packet, "outpost.ds9a.nl", QType::A);
+    for(int records = 0; records < d_records; records++) {
+      pw.startRecord("outpost.ds9a.nl", QType::A);
+      ARecordContent arc("1.2.3.4");
+      arc.toPacket(pw);
+    }
+    pw.commit();
+  }
+  int d_records;
+};
+
+
+struct MakeStringFromCharStarTest
+{
+  MakeStringFromCharStarTest() : d_size(0){}
+  string getName() const
+  {
+    return (boost::format("make a std::string")).str();
+  }
+
+  void operator()() const
+  {
+    string name("outpost.ds9a.nl");
+    d_size += name.length();
+    
+  }
+  mutable int d_size;
+};
+
+struct MakeARecordTest
+{
+  string getName() const
+  {
+    return (boost::format("make a-record")).str();
+  }
+
+  void operator()() const
+  {
+      static string src("1.2.3.4");
+      ARecordContent arc(src);
+      //ARecordContent arc(0x01020304);
+
+  }
+};
+
+struct MakeARecordTestMM
+{
+  string getName() const
+  {
+    return (boost::format("make a-record (mm)")).str();
+  }
+
+  void operator()() const
+  {
+      DNSRecordContent*drc = DNSRecordContent::mastermake(QType::A, 1, 
+                                                         "1.2.3.4");
+      delete drc;
+  }
+};
+
+
+struct A2RecordTest
+{
+  explicit A2RecordTest(int records) : d_records(records) {}
+
+  string getName() const
+  {
+    return (boost::format("%d a records") % d_records).str();
+  }
+
+  void operator()() const
+  {
+    vector<uint8_t> packet;
+    DNSPacketWriter pw(packet, "outpost.ds9a.nl", QType::A);
+    ARecordContent arc("1.2.3.4");
+    string name("outpost.ds9a.nl");
+    for(int records = 0; records < d_records; records++) {
+      pw.startRecord(name, QType::A);
+
+      arc.toPacket(pw);
+    }
+    pw.commit();
+  }
+  int d_records;
+};
+
+
+struct TXTRecordTest
+{
+  explicit TXTRecordTest(int records) : d_records(records) {}
+
+  string getName() const
+  {
+    return (boost::format("%d TXT records") % d_records).str();
+  }
+
+  void operator()() const
+  {
+    vector<uint8_t> packet;
+    DNSPacketWriter pw(packet, "outpost.ds9a.nl", QType::TXT);
+    for(int records = 0; records < d_records; records++) {
+      pw.startRecord("outpost.ds9a.nl", QType::TXT);
+      TXTRecordContent arc("\"een leuk verhaaltje in een TXT\"");
+      arc.toPacket(pw);
+    }
+    pw.commit();
+  }
+  int d_records;
+};
+
+
+struct GenericRecordTest
+{
+  explicit GenericRecordTest(int records, uint16_t type, const std::string& content) 
+    : d_records(records), d_type(type), d_content(content) {}
+
+  string getName() const
+  {
+    return (boost::format("%d %s records") % d_records % 
+           DNSRecordContent::NumberToType(d_type)).str();
+  }
+
+  void operator()() const
+  {
+    vector<uint8_t> packet;
+    DNSPacketWriter pw(packet, "outpost.ds9a.nl", d_type);
+    for(int records = 0; records < d_records; records++) {
+      pw.startRecord("outpost.ds9a.nl", d_type);
+      DNSRecordContent*drc = DNSRecordContent::mastermake(d_type, 1, 
+                                                         d_content);
+      drc->toPacket(pw);
+      delete drc;
+    }
+    pw.commit();
+  }
+  int d_records;
+  uint16_t d_type;
+  string d_content;
+};
+
+
+struct AAAARecordTest
+{
+  explicit AAAARecordTest(int records) : d_records(records) {}
+
+  string getName() const
+  {
+    return (boost::format("%d aaaa records (mm)") % d_records).str();
+  }
+
+  void operator()() const
+  {
+    vector<uint8_t> packet;
+    DNSPacketWriter pw(packet, "outpost.ds9a.nl", QType::AAAA);
+    for(int records = 0; records < d_records; records++) {
+      pw.startRecord("outpost.ds9a.nl", QType::AAAA);
+      DNSRecordContent*drc = DNSRecordContent::mastermake(QType::AAAA, 1, "fe80::21d:92ff:fe6d:8441");
+      drc->toPacket(pw);
+      delete drc;
+    }
+    pw.commit();
+  }
+  int d_records;
+};
+
+struct SOARecordTest
+{
+  explicit SOARecordTest(int records) : d_records(records) {}
+
+  string getName() const
+  {
+    return (boost::format("%d soa records (mm)") % d_records).str();
+  }
+
+  void operator()() const
+  {
+    vector<uint8_t> packet;
+    DNSPacketWriter pw(packet, "outpost.ds9a.nl", QType::SOA);
+
+    for(int records = 0; records < d_records; records++) {
+      pw.startRecord("outpost.ds9a.nl", QType::SOA);
+      DNSRecordContent*drc = DNSRecordContent::mastermake(QType::SOA, 1, "a0.org.afilias-nst.info. noc.afilias-nst.info. 2008758137 1800 900 604800 86400");
+      drc->toPacket(pw);
+      delete drc;
+    }
+    pw.commit();
+  }
+  int d_records;
+};
+
+vector<uint8_t> makeEmptyQuery()
+{
+  vector<uint8_t> packet;
+  DNSPacketWriter pw(packet, "outpost.ds9a.nl", QType::SOA);
+  return  packet;
+}
+
+
+vector<uint8_t> makeRootReferral()
+{
+  vector<uint8_t> packet;
+  DNSPacketWriter pw(packet, "outpost.ds9a.nl", QType::SOA);
+
+  // nobody reads what we output, but it appears to be the magic that shuts some nameservers up
+  static const char*ips[]={"198.41.0.4", "192.228.79.201", "192.33.4.12", "128.8.10.90", "192.203.230.10", "192.5.5.241", "192.112.36.4", "128.63.2.53", 
+                    "192.36.148.17","192.58.128.30", "193.0.14.129", "198.32.64.12", "202.12.27.33"};
+  static char templ[40];
+  strncpy(templ,"a.root-servers.net", sizeof(templ) - 1);
+  
+  
+  for(char c='a';c<='m';++c) {
+    *templ=c;
+    pw.startRecord(".", QType::NS, 3600, 1, DNSPacketWriter::AUTHORITY);
+    DNSRecordContent* drc = DNSRecordContent::mastermake(QType::NS, 1, templ);
+    drc->toPacket(pw);
+    delete drc;
+  }
+
+  for(char c='a';c<='m';++c) {
+    *templ=c;
+    pw.startRecord(".", QType::A, 3600, 1, DNSPacketWriter::ADDITIONAL);
+    DNSRecordContent* drc = DNSRecordContent::mastermake(QType::A, 1, ips[c-'a']);
+    drc->toPacket(pw);
+    delete drc;
+  }
+  pw.commit();
+  return  packet;
+
+}
+
+vector<uint8_t> makeTypicalReferral()
+{
+  vector<uint8_t> packet;
+  DNSPacketWriter pw(packet, "outpost.ds9a.nl", QType::A);
+
+  pw.startRecord("ds9a.nl", QType::NS, 3600, 1, DNSPacketWriter::AUTHORITY);
+  DNSRecordContent* drc = DNSRecordContent::mastermake(QType::NS, 1, "ns1.ds9a.nl");
+  drc->toPacket(pw);
+  delete drc;
+
+  pw.startRecord("ds9a.nl", QType::NS, 3600, 1, DNSPacketWriter::AUTHORITY);
+  drc = DNSRecordContent::mastermake(QType::NS, 1, "ns2.ds9a.nl");
+  drc->toPacket(pw);
+  delete drc;
+
+
+  pw.startRecord("ns1.ds9a.nl", QType::A, 3600, 1, DNSPacketWriter::ADDITIONAL);
+  drc = DNSRecordContent::mastermake(QType::A, 1, "1.2.3.4");
+  drc->toPacket(pw);
+  delete drc;
+
+  pw.startRecord("ns2.ds9a.nl", QType::A, 3600, 1, DNSPacketWriter::ADDITIONAL);
+  drc = DNSRecordContent::mastermake(QType::A, 1, "4.3.2.1");
+  drc->toPacket(pw);
+  delete drc;
+
+  pw.commit();
+  return  packet;
+}
+
+
+
+struct RootRefTest
+{
+  string getName() const
+  {
+    return "write rootreferral";
+  }
+
+  void operator()() const
+  {
+    vector<uint8_t> packet=makeRootReferral();
+  }
+
+};
+
+struct EmptyQueryTest
+{
+  string getName() const
+  {
+    return "write empty query";
+  }
+
+  void operator()() const
+  {
+    vector<uint8_t> packet=makeEmptyQuery();
+  }
+
+};
+
+struct TypicalRefTest
+{
+  string getName() const
+  {
+    return "write typical referral";
+  }
+
+  void operator()() const
+  {
+    vector<uint8_t> packet=makeTypicalReferral();
+  }
+
+};
+
+
+struct ParsePacketTest
+{
+  explicit ParsePacketTest(const vector<uint8_t>& packet, const std::string& name) 
+    : d_packet(packet), d_name(name)
+  {}
+
+  string getName() const
+  {
+    return "parse '"+d_name+"'";
+  }
+
+  void operator()() const
+  {
+    MOADNSParser mdp((const char*)&*d_packet.begin(), d_packet.size());
+  }
+  const vector<uint8_t>& d_packet;
+  std::string d_name;
+};
+
+struct SimpleCompressTest
+{
+  explicit SimpleCompressTest(const std::string& name) 
+    : d_name(name)
+  {}
+
+  string getName() const
+  {
+    return "compress '"+d_name+"'";
+  }
+
+  void operator()() const
+  {
+    simpleCompress(d_name);
+  }
+  std::string d_name;
+};
+
+struct VectorExpandTest
+{
+  string getName() const
+  {
+    return "vector expand";
+  }
+
+  void operator()() const
+  {
+    vector<uint8_t> d_record;
+    d_record.resize(12);
+
+    string out="\x03www\x04ds9a\x02nl";
+    string::size_type len = d_record.size();
+    d_record.resize(len + out.length());
+    memcpy(&d_record[len], out.c_str(), out.length());
+  }
+
+};
+
+struct NOPTest
+{
+  string getName() const
+  {
+    return "null test";
+  }
+
+  void operator()() const
+  {
+  }
+
+};
+
+
+
+int main(int argc, char** argv)
+try
+{
+  reportAllTypes();
+  signal(SIGVTALRM, alarmHandler);
+  
+  //  doRun(NOPTest());
+
+  vector<uint8_t> packet = makeRootReferral();
+  doRun(ParsePacketTest(packet, "root-referral"));
+
+  doRun(RootRefTest());
+
+  doRun(EmptyQueryTest());
+  doRun(TypicalRefTest());
+
+
+  packet = makeEmptyQuery();
+  doRun(ParsePacketTest(packet, "empty-query"));
+
+  packet = makeTypicalReferral();
+  cerr<<"typical referral size: "<<packet.size()<<endl;
+  doRun(ParsePacketTest(packet, "typical-referral"));
+
+
+  doRun(SimpleCompressTest("www.france.ds9a.nl"));
+
+  doRun(VectorExpandTest());
+
+  doRun(ARecordTest(1));
+  doRun(ARecordTest(2));
+  doRun(ARecordTest(4));
+  doRun(ARecordTest(64));
+
+  doRun(A2RecordTest(1));
+  doRun(A2RecordTest(2));
+  doRun(A2RecordTest(4));
+  doRun(A2RecordTest(64));
+
+  doRun(MakeStringFromCharStarTest());
+  doRun(MakeARecordTest());
+  doRun(MakeARecordTestMM());
+
+  doRun(AAAARecordTest(1));
+  doRun(AAAARecordTest(2));
+  doRun(AAAARecordTest(4));
+  doRun(AAAARecordTest(64));
+
+  doRun(TXTRecordTest(1));
+  doRun(TXTRecordTest(2));
+  doRun(TXTRecordTest(4));
+  doRun(TXTRecordTest(64));
+
+  doRun(GenericRecordTest(1, QType::NS, "powerdnssec1.ds9a.nl"));
+  doRun(GenericRecordTest(2, QType::NS, "powerdnssec1.ds9a.nl"));
+  doRun(GenericRecordTest(4, QType::NS, "powerdnssec1.ds9a.nl"));
+  doRun(GenericRecordTest(64, QType::NS, "powerdnssec1.ds9a.nl"));
+
+
+
+  doRun(SOARecordTest(1));
+  doRun(SOARecordTest(2));
+  doRun(SOARecordTest(4));
+  doRun(SOARecordTest(64));
+
+  cerr<<"Total runs: " << g_totalRuns<<endl;
+
+}
+catch(std::exception &e)
+{
+  cerr<<"Fatal: "<<e.what()<<endl;
+}
+