]> granicus.if.org Git - pdns/commitdiff
implement explicit (configurable) limit to number of mthreads - we are usually implic...
authorBert Hubert <bert.hubert@netherlabs.nl>
Mon, 1 Feb 2010 21:54:44 +0000 (21:54 +0000)
committerBert Hubert <bert.hubert@netherlabs.nl>
Mon, 1 Feb 2010 21:54:44 +0000 (21:54 +0000)
git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@1505 d19b8d6e-7fed-0310-83ef-9ca221ded41b

pdns/pdns_recursor.cc
pdns/syncres.hh

index 6f338f6cc4dd9f5061509a2b27b95eed93608190..dedeac933bf5bf7511534276484b8ea54c3aa6f5 100644 (file)
@@ -106,6 +106,7 @@ string s_programname="pdns_recursor";
 typedef vector<int> tcpListenSockets_t;
 tcpListenSockets_t g_tcpListenSockets;   // shared across threads, but this is fine, never written to from a thread. All threads listen on all sockets
 int g_tcpTimeout;
+unsigned int g_maxMThreads;
 struct timeval g_now; // timestamp, updated (too) frequently
 map<int, ComboAddress> g_listenSocketsAddresses; // is shared across all threads right now
 
@@ -749,6 +750,12 @@ void handleNewTCPQuestion(int fd, FDMultiplexer::funcparam_t& )
   socklen_t addrlen=sizeof(addr);
   int newsock=(int)accept(fd, (struct sockaddr*)&addr, &addrlen);
   if(newsock>0) {
+    if(MT->numProcesses() > g_maxMThreads) {
+      g_stats.overCapacityDrops++;
+      Utility::closesocket(newsock);
+      return;
+    }
+
     g_stats.addRemote(addr);
     if(t_allowFrom && !t_allowFrom->match(&addr)) {
       if(!g_quiet) 
@@ -787,7 +794,9 @@ void handleNewUDPQuestion(int fd, FDMultiplexer::funcparam_t& var)
   ComboAddress fromaddr;
   socklen_t addrlen=sizeof(fromaddr);
 
+  
   if((len=recvfrom(fd, data, sizeof(data), 0, (sockaddr *)&fromaddr, &addrlen)) >= 0) {
+
     g_stats.addRemote(fromaddr);
 
     if(t_allowFrom && !t_allowFrom->match(&fromaddr)) {
@@ -824,6 +833,11 @@ void handleNewUDPQuestion(int fd, FDMultiplexer::funcparam_t& var)
         catch(std::exception& e) {
           throw MOADNSException(e.what()); // translate
         }
+        if(MT->numProcesses() > g_maxMThreads) {
+          g_stats.overCapacityDrops++;
+          return;
+        }
+  
         DNSComboWriter* dc = new DNSComboWriter(data, len, g_now);
         dc->setSocket(fd);
         dc->setRemote(&fromaddr);
@@ -1528,6 +1542,13 @@ int serviceMain(int argc, char*argv[])
   
   L<<Logger::Warning<<"Operating in "<<(sizeof(unsigned long)*8) <<" bits mode"<<endl;
   
+  #if 0
+  unsigned int maxFDs, curFDs;
+  getFDLimits(curFDs, maxFDs);
+  if(curFDs < 2048) 
+    L<<Logger::Warning<<"Only "<<curFDs<<" file descriptors available (out of: "<<maxFDs<<"), may not be suitable for high performance"<<endl;
+  #endif
+  
   seedRandom(::arg()["entropy-source"]);
 
   parseACLs();
@@ -1631,6 +1652,7 @@ int serviceMain(int argc, char*argv[])
   
   g_tcpTimeout=::arg().asNum("client-tcp-timeout");
   g_maxTCPPerClient=::arg().asNum("max-tcp-per-client");
+  g_maxMThreads=::arg().asNum("max-mthreads");
   
   int numThreads = ::arg().asNum("threads");
   if(numThreads == 1) {
@@ -1854,6 +1876,7 @@ int main(int argc, char **argv)
     ::arg().set("query-local-address","Source IP address for sending queries")="0.0.0.0";
     ::arg().set("query-local-address6","Source IPv6 address for sending queries")="";
     ::arg().set("client-tcp-timeout","Timeout in seconds when talking to TCP clients")="2";
+    ::arg().set("max-mthreads", "Maximum number of simultaneous Mtasker threads")="2048";
     ::arg().set("max-tcp-clients","Maximum number of simultaneous TCP clients")="128";
     ::arg().set("hint-file", "If set, load root hints from this file")="";
     ::arg().set("max-cache-entries", "If set, maximum number of entries in the main cache")="1000000";
index 577bff03e048f41b5e9b92e441fd7b1622a87813..12b1b17f60309dd4cb8537f9cbba945b364853ba 100644 (file)
@@ -471,6 +471,7 @@ struct RecursorStats
   uint64_t caseMismatchCount;
   uint64_t spoofCount;
   uint64_t resourceLimits;
+  uint64_t overCapacityDrops;
   uint64_t ipv6queries;
   uint64_t chainResends;
   uint64_t nsSetInvalidations;