]> granicus.if.org Git - pdns/commitdiff
make tcpbench production ready
authorbert hubert <bert.hubert@netherlabs.nl>
Tue, 11 Jun 2013 11:39:50 +0000 (13:39 +0200)
committerbert hubert <bert.hubert@netherlabs.nl>
Tue, 11 Jun 2013 14:09:37 +0000 (16:09 +0200)
pdns/.gitignore
pdns/misc.hh
pdns/tcpbench.cc

index 4146647514e38b5f23bb65bbddcbda989054cb4a..974f72190f4436b78b0488c9400cf1d204be900b 100644 (file)
@@ -30,4 +30,5 @@
 /speedtest
 /toysdig
 /tsig-tests
+/tcpbench
 version_generated.h
index 7b1489aaac548fb2d156ddf639cc70e82c2298d4..4da6bdadc6258355572776b35963e65d4f4446e2 100644 (file)
@@ -349,6 +349,12 @@ public:
       return atomic_exchange_and_add( &value_, +1 ) + 1;
     }
 
+    unsigned int operator++(int)
+    {
+      return atomic_exchange_and_add( &value_, +1 );
+    }
+
+
     unsigned int operator--()
     {
       return atomic_exchange_and_add( &value_, -1 ) - 1;
index f30a6a80beec89f734e92367b406370fe6dc9bd0..0f4c047dacdc90b3135a7f5d33f54aa9f42a5658 100644 (file)
@@ -8,8 +8,13 @@
 StatBag S;
 
 bool g_onlyTCP;
+AtomicCounter g_networkErrors, g_otherErrors, g_OK, g_truncates;
+
+// echo 1 > /proc/sys/net/ipv4/tcp_tw_recycle 
+
 
 void doQuery(const std::string& qname, uint16_t qtype, const ComboAddress& dest)
+try
 {
   vector<uint8_t> packet;
   DNSPacketWriter pw(packet, qname, qtype);
@@ -25,10 +30,14 @@ void doQuery(const std::string& qname, uint16_t qtype, const ComboAddress& dest)
     MOADNSParser mdp(reply);
     if(!mdp.d_header.tc)
       return;
+    g_truncates++;
   }
 
 
   Socket sock(InterNetwork, Stream);
+  int tmp=1;
+  if(setsockopt(sock.getHandle(),SOL_SOCKET,SO_REUSEADDR,(char*)&tmp,sizeof tmp)<0) 
+    throw runtime_error("Unable to set socket reuse: "+string(strerror(errno)));
 
   sock.connect(dest);
   uint16_t len;
@@ -56,8 +65,19 @@ void doQuery(const std::string& qname, uint16_t qtype, const ComboAddress& dest)
   delete[] creply;
   
   MOADNSParser mdp(reply);
+  //  cout<<"Had correct TCP/IP response, "<<mdp.d_answers.size()<<" answers, aabit="<<mdp.d_header.aa<<endl;
+  g_OK++;
+}
+catch(NetworkError& ne)
+{
+  cerr<<"Network error: "<<ne.what()<<endl;
+  g_networkErrors++;
+}
+catch(...)
+{
+  g_otherErrors++;
 }
 
 /* read queries from stdin, put in vector
    launch n worker threads, each picks a query using AtomicCounter
@@ -74,12 +94,13 @@ struct Query
 
 vector<Query> g_queries;
 ComboAddress g_dest;
+
 void* worker(void*)
 {
   Query q;
   for(;;) {
-    unsigned int pos = ++g_pos
-    if(pos > g_queries.size())
+    unsigned int pos = g_pos++
+    if(pos >= g_queries.size())
       break;
     q=g_queries[pos];
     doQuery(q.qname, q.qtype, g_dest);
@@ -92,15 +113,31 @@ int main(int argc, char** argv)
 try
 {
   reportAllTypes();
-  g_onlyTCP=true;
-  g_dest = ComboAddress("127.0.0.1", 5300);
+  g_onlyTCP=false;
+
+  uint16_t port=53;
+  if(argc < 2) {
+    cerr<<"Syntax: tcpbench remote [port] < queries"<<endl;
+    cerr<<"Where queries is one query per line, format: qname qtype, just 1 space"<<endl;
+    exit(EXIT_FAILURE);
+  }
+  if(argc > 2)
+    port = atoi(argv[2]);
+
+  g_dest = ComboAddress(argv[1], port);
   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));
+  FILE* fp=fdopen(0, "r");
+  pair<string, string> q;
+  string line;
+  while(stringfgets(fp, line)) {
+    trim_right(line);
+    q=splitField(line, ' ');
+    g_queries.push_back(Query(q.first, DNSRecordContent::TypeToNumber(q.second)));
   }
-
+  fclose(fp);
+    
   for(unsigned int n = 0; n < numworkers; ++n) {
     pthread_create(&workers[n], 0, worker, 0);
   }
@@ -108,7 +145,8 @@ try
     void* status;
     pthread_join(workers[n], &status);
   }
-
+  cout<<"OK: "<<g_OK<<", network errors: "<<g_networkErrors<<", other errors: "<<g_otherErrors<<endl;
+  cout<<"Truncateds: "<<g_truncates<<endl;
 }
 catch(std::exception &e)
 {