]> granicus.if.org Git - pdns/commitdiff
add initial tcpbench - untested
authorbert hubert <bert.hubert@netherlabs.nl>
Tue, 11 Jun 2013 10:57:14 +0000 (12:57 +0200)
committerbert hubert <bert.hubert@netherlabs.nl>
Tue, 11 Jun 2013 14:09:28 +0000 (16:09 +0200)
pdns/Makefile.am
pdns/tcpbench.cc [new file with mode: 0644]

index c46d95df3b7587a03d9df8a63ab4a1d5eb3e3930..6d50bbd860a6e25898be0c3456caab3c15a8e22c 100644 (file)
@@ -39,7 +39,7 @@ sbin_PROGRAMS = pdns_server
 bin_PROGRAMS = pdns_control pdnssec dnsreplay
 endif
 
-EXTRA_PROGRAMS=pdns_recursor sdig tsig-tests speedtest pdns_control dnsscope dnsgram \
+EXTRA_PROGRAMS=pdns_recursor sdig tcpbench tsig-tests speedtest pdns_control dnsscope dnsgram \
 testrunner \
 toysdig dnsdemog dnswasher dnsscan nproxy notify pdnssec dnsbulktest nsec3dig # dnslabel # tcptorture
 
@@ -142,6 +142,11 @@ 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 nsecrecords.cc base32.cc
 
+tcpbench_SOURCES=tcpbench.cc sstuff.hh dnsparser.cc dnsparser.hh dnsrecords.cc dnswriter.cc dnslabeltext.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 nsecrecords.cc base32.cc
+
+
 nsec3dig_SOURCES=nsec3dig.cc sstuff.hh dnsparser.cc dnsparser.hh dnsrecords.cc dnswriter.cc dnslabeltext.cc \
     dnswriter.hh dnssecinfra.cc \
        misc.cc misc.hh rcpgenerator.cc rcpgenerator.hh base64.cc base64.hh unix_utility.cc \
diff --git a/pdns/tcpbench.cc b/pdns/tcpbench.cc
new file mode 100644 (file)
index 0000000..f30a6a8
--- /dev/null
@@ -0,0 +1,116 @@
+#include "dnsparser.hh"
+#include "sstuff.hh"
+#include "misc.hh"
+#include "dnswriter.hh"
+#include "dnsrecords.hh"
+#include "statbag.hh"
+#include <boost/array.hpp>
+StatBag S;
+
+bool g_onlyTCP;
+
+void doQuery(const std::string& qname, uint16_t qtype, const ComboAddress& dest)
+{
+  vector<uint8_t> packet;
+  DNSPacketWriter pw(packet, qname, qtype);
+
+  string reply;
+
+  if(!g_onlyTCP) {
+    Socket udpsock(InterNetwork, Datagram);
+    
+    udpsock.sendTo(string((char*)&*packet.begin(), (char*)&*packet.end()), dest);
+    ComboAddress origin;
+    udpsock.recvFrom(reply, origin);
+    MOADNSParser mdp(reply);
+    if(!mdp.d_header.tc)
+      return;
+  }
+
+
+  Socket sock(InterNetwork, Stream);
+
+  sock.connect(dest);
+  uint16_t len;
+  len = htons(packet.size());
+  if(sock.write((char *) &len, 2) != 2)
+    throw AhuException("tcp write failed");
+  
+  sock.writen(string((char*)&*packet.begin(), (char*)&*packet.end()));
+  
+  if(sock.read((char *) &len, 2) != 2)
+    throw AhuException("tcp read failed");
+  
+  len=ntohs(len);
+  char *creply = new char[len];
+  int n=0;
+  int numread;
+  while(n<len) {
+    numread=sock.read(creply+n, len-n);
+    if(numread<0)
+      throw AhuException("tcp read failed");
+    n+=numread;
+  }
+  
+  reply=string(creply, len);
+  delete[] creply;
+  
+  MOADNSParser mdp(reply);
+}
+
+/* read queries from stdin, put in vector
+   launch n worker threads, each picks a query using AtomicCounter
+   If a worker reaches the end of its queue, it stops */
+
+AtomicCounter g_pos;
+struct Query
+{
+  Query(const std::string& qname_, uint16_t qtype_) : qname(qname_), qtype(qtype_) {}
+  Query(){}
+  std::string qname;
+  uint16_t qtype;
+};
+
+vector<Query> g_queries;
+ComboAddress g_dest;
+void* worker(void*)
+{
+  Query q;
+  for(;;) {
+    unsigned int pos = ++g_pos; 
+    if(pos > g_queries.size())
+      break;
+    q=g_queries[pos];
+    doQuery(q.qname, q.qtype, g_dest);
+  }
+  return 0;
+}
+
+
+int main(int argc, char** argv)
+try
+{
+  reportAllTypes();
+  g_onlyTCP=true;
+  g_dest = ComboAddress("127.0.0.1", 5300);
+  unsigned int numworkers=100;
+  pthread_t workers[numworkers];
+
+  for(unsigned int n = 0; n < 1000000; ++n) {
+    g_queries.push_back(Query("www.powerdns.com", QType::A));
+  }
+
+  for(unsigned int n = 0; n < numworkers; ++n) {
+    pthread_create(&workers[n], 0, worker, 0);
+  }
+  for(unsigned int n = 0; n < numworkers; ++n) {
+    void* status;
+    pthread_join(workers[n], &status);
+  }
+
+}
+catch(std::exception &e)
+{
+  cerr<<"Fatal: "<<e.what()<<endl;
+}