Changeset 726

Show
Ignore:
Timestamp:
04/18/06 18:44:10 (7 years ago)
Author:
ahu
Message:

make clientside ipv4/ip6 agnostic, including allow-from
fix address printing
fix tcp client limiting when listening on multiple addresses

Location:
trunk/pdns/pdns
Files:
6 modified

Legend:

Unmodified
Added
Removed
  • trunk/pdns/pdns/dnspacket.cc

    r680 r726  
    5353string DNSPacket::getLocal() const 
    5454{ 
    55   struct sockaddr_in sa; 
    56   int addrlen=sizeof(struct sockaddr_in); 
     55  struct sockaddr_in6 sa; 
     56  int addrlen=sizeof(sa); 
    5757 
    5858  getsockname(d_socket, (struct sockaddr *)&sa, (socklen_t *)&addrlen); 
    59   return sockAddrToString(&sa, (socklen_t)addrlen); 
     59  return sockAddrToString(&sa); 
    6060} 
    6161 
     
    6363string DNSPacket::getRemote() const 
    6464{ 
    65   return sockAddrToString((struct sockaddr_in *)remote, d_socklen); 
     65  return sockAddrToString((struct sockaddr_in *)remote); 
    6666} 
    6767 
  • trunk/pdns/pdns/dnsproxy.cc

    r680 r726  
    140140      if(i->second.created) 
    141141        L<<Logger::Warning<<"Recursive query for remote "<< 
    142           sockAddrToString((struct sockaddr_in *)&i->second.remote, i->second.addrlen)<<" with internal id "<<n<< 
     142          sockAddrToString((struct sockaddr_in *)&i->second.remote)<<" with internal id "<<n<< 
    143143          " was not answered by backend within timeout, reusing id"<<endl; 
    144144       
  • trunk/pdns/pdns/iputils.hh

    r681 r726  
    3535using namespace std; 
    3636 
     37union ComboAddress { 
     38  struct sockaddr_in sin4; 
     39  struct sockaddr_in6 sin6; 
     40 
     41  bool operator<(const ComboAddress& rhs) const 
     42  { 
     43    if(sin4.sin_family < rhs.sin4.sin_family) 
     44      return true; 
     45    if(sin4.sin_family > rhs.sin4.sin_family) 
     46      return false; 
     47     
     48    if(sin4.sin_family == AF_INET) 
     49      return sin4.sin_addr.s_addr < rhs.sin4.sin_addr.s_addr; 
     50    else 
     51      return memcmp(&sin6.sin6_addr.s6_addr, &rhs.sin6_addr.s6_addr, 16) < 0; 
     52  } 
     53 
     54  string toString() const 
     55  { 
     56    char tmp[128]; 
     57    if(sin4.sin_family==AF_INET && !inet_ntop(AF_INET, ( const char * ) &sin4.sin_addr, tmp, sizeof(tmp))) 
     58      return tmp; 
     59 
     60    if(sin4.sin_family==AF_INET6 && !inet_ntop(AF_INET6, ( const char * ) &sin6.sin6_addr, tmp, sizeof(tmp))) 
     61      return tmp; 
     62       
     63    return tmp; 
     64  } 
     65}; 
     66 
    3767/** This exception is thrown by the Netmask class and by extension by the NetmaskGroup class */ 
    3868class NetmaskException: public AhuException  
     
    4272}; 
    4373 
     74inline ComboAddress makeComboAddress(const string& str) 
     75{ 
     76  ComboAddress address; 
     77  address.sin4.sin_family=AF_INET; 
     78  if(inet_pton(AF_INET, str.c_str(), &address.sin4.sin_addr) <= 0) { 
     79    address.sin4.sin_family=AF_INET6; 
     80    if(inet_pton(AF_INET6, str.c_str(), &address.sin6.sin6_addr) <= 0) 
     81      throw NetmaskException("Unable to convert '"+str+"' to a netmask");        
     82  } 
     83  return address; 
     84} 
     85 
    4486/** This class represents a netmask and can be queried to see if a certain 
    4587    IP address is matched by this mask */ 
    46  
    4788class Netmask 
    4889{ 
     
    5192  Netmask(const string &mask)  
    5293  { 
    53     char *p; 
    54     uint8_t bits=32; 
    55     d_mask=0xFFFFFFFF; 
    56  
    57     if((p=strchr(mask.c_str(),'/'))) 
    58       bits = (uint8_t) atoi(p+1); 
    59  
    60     if( bits < 32 ) 
    61     d_mask=~(0xFFFFFFFF>>bits); 
    62  
    63     struct in_addr a; 
    64     if(!Utility::inet_aton(mask.substr(0,p-mask.c_str()).c_str(), &a)) 
    65       throw NetmaskException("Unable to convert '"+mask+"' to a netmask"); 
    66     d_network=htonl(a.s_addr); 
     94    pair<string,string> split=splitField(mask,'/'); 
     95    d_network=makeComboAddress(split.first); 
     96     
     97    if(!split.second.empty()) { 
     98      d_bits = (uint8_t) atoi(split.second.c_str()); 
     99      if(d_bits<32) 
     100        d_mask=~(0xFFFFFFFF>>d_bits); 
     101    } 
     102    else if(d_network.sin4.sin_family==AF_INET) { 
     103      d_bits = 32; 
     104      d_mask = 0xFFFFFFFF; 
     105    } 
     106    else  
     107      d_bits=128; 
    67108  } 
    68109 
    69110  //! If this IP address in socket address matches 
    70   bool match(const struct sockaddr_in *ip) const 
     111  bool match(const ComboAddress *ip) const 
    71112  { 
    72     return match(htonl((unsigned int)ip->sin_addr.s_addr)); 
     113    if(d_network.sin4.sin_family != ip->sin4.sin_family) { 
     114      return false; 
     115    } 
     116    if(d_network.sin4.sin_family == AF_INET) { 
     117      return match4(htonl((unsigned int)ip->sin4.sin_addr.s_addr)); 
     118    } 
     119    if(d_network.sin6.sin6_family == AF_INET6) { 
     120      uint8_t bytes=d_bits/8, n; 
     121      const uint8_t *us=(const uint8_t*) &d_network.sin6.sin6_addr.s6_addr; 
     122      const uint8_t *them=(const uint8_t*) &ip->sin6.sin6_addr.s6_addr; 
     123       
     124      for(n=0; n < bytes; ++n) { 
     125        if(us[n]!=them[n]) { 
     126          return false; 
     127        } 
     128      } 
     129      // still here, now match remaining bits 
     130      uint8_t bits=bytes%8; 
     131      uint8_t mask= ~(0xFF>>bits); 
     132      return((us[n] & mask) == (them[n] & mask)); 
     133    } 
     134    return false; 
    73135  } 
    74136 
     
    76138  bool match(const string &ip) const 
    77139  { 
    78     struct in_addr a; 
    79     Utility::inet_aton(ip.c_str(), &a); 
    80     return match(htonl(a.s_addr)); 
     140    ComboAddress address=makeComboAddress(ip); 
     141    return match(&address); 
    81142  } 
    82143 
    83144  //! If this IP address in native format matches 
    84   bool match(uint32_t ip) const 
     145  bool match4(uint32_t ip) const 
    85146  { 
    86     return (ip & d_mask) == (d_network & d_mask); 
     147    return (ip & d_mask) == (ntohl(d_network.sin4.sin_addr.s_addr) & d_mask); 
    87148  } 
    88149 
    89  
    90150private: 
    91   uint32_t d_network; 
     151  ComboAddress d_network; 
    92152  uint32_t d_mask; 
     153  uint8_t d_bits; 
    93154}; 
    94155 
     
    100161public: 
    101162  //! If this IP address is matched by any of the classes within 
    102   bool match(struct sockaddr_in *ip) 
     163  bool match(ComboAddress *ip) 
    103164  { 
    104165    for(container_t::const_iterator i=d_masks.begin();i!=d_masks.end();++i) 
  • trunk/pdns/pdns/misc.cc

    r692 r726  
    367367} 
    368368 
    369 const string sockAddrToString(struct sockaddr_in *remote, Utility::socklen_t socklen)  
     369 
     370const string sockAddrToString(struct sockaddr_in *remote)  
    370371{     
    371   if(socklen==sizeof(struct sockaddr_in)) { 
     372  if(remote->sin_family == AF_INET) { 
    372373    struct sockaddr_in sip; 
    373374    memcpy(&sip,(struct sockaddr_in*)remote,sizeof(sip)); 
    374375    return inet_ntoa(sip.sin_addr); 
    375376  } 
    376 #ifdef HAVE_IPV6 
    377377  else { 
    378378    char tmp[128]; 
     
    383383    return tmp; 
    384384  } 
    385 #endif 
    386  
    387   return "untranslateable"; 
    388385} 
    389386 
  • trunk/pdns/pdns/misc.hh

    r692 r726  
    182182  struct timeval d_set; 
    183183}; 
    184 const string sockAddrToString(struct sockaddr_in *remote, Utility::socklen_t socklen); 
     184const string sockAddrToString(struct sockaddr_in *remote); 
    185185int sendData(const char *buffer, int replen, int outsock); 
    186186 
  • trunk/pdns/pdns/pdns_recursor.cc

    r724 r726  
    7272NetmaskGroup* g_allowFrom; 
    7373string s_programname="pdns_recursor"; 
    74 int g_tcpListenSocket; 
     74vector<int> g_tcpListenSockets; 
    7575int g_tcpTimeout; 
    7676 
     
    7979  {} 
    8080  MOADNSParser d_mdp; 
    81   void setRemote(struct sockaddr* sa, socklen_t len) 
     81  void setRemote(ComboAddress* sa) 
    8282  { 
    83     memcpy((void *)d_remote, (void *)sa, len); 
    84     d_socklen=len; 
     83    d_remote=*sa; 
     84    d_socklen= d_remote.sin4.sin_family == AF_INET ? sizeof(sockaddr_in) : sizeof(sockaddr_in6); 
    8585  } 
    8686 
     
    9292  string getRemote() const 
    9393  { 
    94     return sockAddrToString((struct sockaddr_in *)d_remote, d_socklen); 
     94    return d_remote.toString(); 
    9595  } 
    9696 
    9797  struct timeval d_now; 
    98   char d_remote[sizeof(sockaddr_in6)]; 
     98  ComboAddress d_remote; 
    9999  socklen_t d_socklen; 
    100100  bool d_tcp; 
     
    311311    memcpy(data,packet.c_str(),min(len,*d_len)); 
    312312    if(*nearMissLimit && pident.nearMisses > *nearMissLimit) { 
    313       L<<Logger::Error<<"Too many ("<<pident.nearMisses<<" > "<<*nearMissLimit<<") bogus answers for '"<<domain<<"' from "<<sockAddrToString((struct sockaddr_in*)toaddr, sizeof(pident.remote))<<", assuming spoof attempt."<<endl; 
     313      L<<Logger::Error<<"Too many ("<<pident.nearMisses<<" > "<<*nearMissLimit<<") bogus answers for '"<<domain<<"' from "<<sockAddrToString((struct sockaddr_in*)toaddr)<<", assuming spoof attempt."<<endl; 
    314314      g_stats.spoofCount++; 
    315315      return -1; 
     
    405405} 
    406406 
    407 map<uint32_t, uint32_t> g_tcpClientCounts; 
     407map<ComboAddress, uint32_t> g_tcpClientCounts; 
    408408 
    409409struct TCPConnection 
     
    413413  int qlen; 
    414414  int bytesread; 
    415   struct sockaddr_in remote; 
     415  ComboAddress remote; 
    416416  char data[65535]; 
    417417  time_t startTime; 
     
    420420  { 
    421421    close(fd); 
    422     if(!g_tcpClientCounts[remote.sin_addr.s_addr]--)  
    423       g_tcpClientCounts.erase(remote.sin_addr.s_addr); 
     422    if(!g_tcpClientCounts[remote]--)  
     423      g_tcpClientCounts.erase(remote); 
    424424    s_currentConnections--; 
    425425  } 
     
    500500  sendit:; 
    501501    if(!dc->d_tcp) { 
    502       sendto(dc->d_socket, &*packet.begin(), packet.size(), 0, (struct sockaddr *)(dc->d_remote), dc->d_socklen); 
     502      sendto(dc->d_socket, &*packet.begin(), packet.size(), 0, (struct sockaddr *)(&dc->d_remote), dc->d_socklen); 
    503503    } 
    504504    else { 
     
    617617    if(!bytes || bytes < 0) { 
    618618      if(g_logCommonErrors) 
    619         L<<Logger::Error<<"TCP client "<<sockAddrToString(&conn.remote,sizeof(conn.remote))<<" disconnected after first byte"<<endl; 
     619        L<<Logger::Error<<"TCP client "<< conn.remote.toString() <<" disconnected after first byte"<<endl; 
    620620      TCPConnection tmp(conn);  
    621621      g_fdm->removeReadFD(fd); 
     
    627627    int bytes=read(conn.fd,conn.data + conn.bytesread,conn.qlen - conn.bytesread); 
    628628    if(!bytes || bytes < 0) { 
    629       L<<Logger::Error<<"TCP client "<<sockAddrToString(&conn.remote,sizeof(conn.remote))<<" disconnected while reading question body"<<endl; 
     629      L<<Logger::Error<<"TCP client "<< conn.remote.toString() <<" disconnected while reading question body"<<endl; 
    630630      TCPConnection tmp(conn); 
    631631      g_fdm->removeReadFD(fd); 
     
    643643      catch(MOADNSException &mde) { 
    644644        g_stats.clientParseError++;  
    645         L<<Logger::Error<<"Unable to parse packet from TCP client "<<sockAddrToString(&conn.remote,sizeof(conn.remote))<<endl; 
     645        L<<Logger::Error<<"Unable to parse packet from TCP client "<< conn.remote.toString() <<endl; 
    646646        TCPConnection tmp(conn);  
    647647        g_fdm->removeReadFD(fd); 
     
    652652      dc->setSocket(conn.fd); 
    653653      dc->d_tcp=true; 
    654       dc->setRemote((struct sockaddr *)&conn.remote,sizeof(conn.remote)); 
     654      dc->setRemote(&conn.remote); 
    655655      if(dc->d_mdp.d_header.qr) 
    656656        L<<Logger::Error<<"Ignoring answer on server socket!"<<endl; 
     
    668668void handleNewTCPQuestion(int fd, boost::any& ) 
    669669{ 
    670   struct sockaddr_in addr; 
     670  ComboAddress addr; 
    671671  socklen_t addrlen=sizeof(addr); 
    672672  int newsock=accept(fd, (struct sockaddr*)&addr, &addrlen); 
     
    678678    } 
    679679     
    680     if(g_maxTCPPerClient && g_tcpClientCounts.count(addr.sin_addr.s_addr) && g_tcpClientCounts[addr.sin_addr.s_addr] >= g_maxTCPPerClient) { 
     680    if(g_maxTCPPerClient && g_tcpClientCounts.count(addr) && g_tcpClientCounts[addr] >= g_maxTCPPerClient) { 
    681681      g_stats.tcpClientOverflow++; 
    682682      close(newsock); // don't call TCPConnection::closeAndCleanup here - did not enter it in the counts yet! 
    683683      return; 
    684684    } 
    685     g_tcpClientCounts[addr.sin_addr.s_addr]++; 
     685    g_tcpClientCounts[addr]++; 
    686686    Utility::setNonBlocking(newsock); 
    687687    TCPConnection tc; 
     
    700700void makeTCPServerSockets() 
    701701{ 
     702  int fd; 
    702703  vector<string>locals; 
    703704  stringtok(locals,::arg()["local-address"]," ,"); 
     
    706707    throw AhuException("No local address specified"); 
    707708   
     709  ComboAddress sin; 
    708710  for(vector<string>::const_iterator i=locals.begin();i!=locals.end();++i) { 
    709     g_tcpListenSocket=socket(AF_INET, SOCK_STREAM,0); 
    710     if(g_tcpListenSocket<0)  
    711       throw AhuException("Making a server socket for resolver: "+stringerror()); 
    712    
    713     struct sockaddr_in sin; 
    714711    memset((char *)&sin,0, sizeof(sin)); 
    715      
    716     sin.sin_family = AF_INET; 
    717     if(!IpToU32(*i, &sin.sin_addr.s_addr)) 
    718       throw AhuException("Unable to resolve local address '"+ *i +"'");  
     712    ComboAddress sin; 
     713    sin.sin4.sin_family = AF_INET; 
     714    if(!IpToU32(*i, &sin.sin4.sin_addr.s_addr)) { 
     715      sin.sin6.sin6_family = AF_INET6; 
     716      if(inet_pton(AF_INET6, i->c_str(), &sin.sin6.sin6_addr) <= 0) 
     717        throw AhuException("Unable to resolve local address '"+ *i +"'");  
     718    } 
     719 
     720    fd=socket(sin.sin6.sin6_family, SOCK_STREAM, 0); 
     721    if(fd<0)  
     722      throw AhuException("Making a TCP server socket for resolver: "+stringerror()); 
    719723 
    720724    int tmp=1; 
    721     if(setsockopt(g_tcpListenSocket,SOL_SOCKET,SO_REUSEADDR,(char*)&tmp,sizeof tmp)<0) { 
     725    if(setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,(char*)&tmp,sizeof tmp)<0) { 
    722726      L<<Logger::Error<<"Setsockopt failed for TCP listening socket"<<endl; 
    723727      exit(1); 
     
    725729     
    726730#ifdef TCP_DEFER_ACCEPT 
    727     if(setsockopt(g_tcpListenSocket, SOL_TCP,TCP_DEFER_ACCEPT,(char*)&tmp,sizeof tmp) >= 0) { 
    728       L<<Logger::Error<<"Enabled TCP data-ready filter for (slight) DoS protection"<<endl; 
     731    if(setsockopt(fd, SOL_TCP,TCP_DEFER_ACCEPT,(char*)&tmp,sizeof tmp) >= 0) { 
     732      if(i==locals.begin()) 
     733        L<<Logger::Error<<"Enabled TCP data-ready filter for (slight) DoS protection"<<endl; 
    729734    } 
    730735#endif 
    731736 
    732     sin.sin_port = htons(::arg().asNum("local-port"));  
    733      
    734     if (::bind(g_tcpListenSocket, (struct sockaddr *)&sin, sizeof(sin))<0)  
     737    sin.sin4.sin_port = htons(::arg().asNum("local-port"));  
     738    int socklen=sin.sin4.sin_family==AF_INET ? sizeof(sin.sin4) : sizeof(sin.sin6); 
     739    if (::bind(fd, (struct sockaddr *)&sin, socklen )<0)  
    735740      throw AhuException("Binding TCP server socket for "+*i+": "+stringerror()); 
    736741     
    737     Utility::setNonBlocking(g_tcpListenSocket); 
    738     setSendBuffer(g_tcpListenSocket, 65000); 
    739     listen(g_tcpListenSocket, 128); 
    740     g_fdm->addReadFD(g_tcpListenSocket, handleNewTCPQuestion); 
    741     L<<Logger::Error<<"Listening for TCP queries on "<<inet_ntoa(sin.sin_addr)<<":"<<::arg().asNum("local-port")<<endl; 
     742    Utility::setNonBlocking(fd); 
     743    setSendBuffer(fd, 65000); 
     744    listen(fd, 128); 
     745    g_fdm->addReadFD(fd, handleNewTCPQuestion); 
     746    L<<Logger::Error<<"Listening for TCP queries on "<< sockAddrToString(&sin.sin4) <<":"<<::arg().asNum("local-port")<<endl; 
    742747  } 
    743748} 
     
    747752  int d_len; 
    748753  char data[1500]; 
    749   struct sockaddr_in fromaddr; 
     754  ComboAddress fromaddr; 
    750755  socklen_t addrlen=sizeof(fromaddr); 
    751756 
     
    759764      DNSComboWriter* dc = new DNSComboWriter(data, d_len, g_now); 
    760765       
    761       dc->setRemote((struct sockaddr *)&fromaddr, addrlen); 
     766      dc->setRemote(&fromaddr); 
    762767       
    763768      if(dc->d_mdp.d_header.qr) { 
     
    774779    catch(MOADNSException& mde) { 
    775780      g_stats.clientParseError++;  
    776       L<<Logger::Error<<"Unable to parse packet from remote UDP client "<< sockAddrToString((struct sockaddr_in*) &fromaddr, addrlen) <<": "<<mde.what()<<endl; 
     781      L<<Logger::Error<<"Unable to parse packet from remote UDP client "<<fromaddr.toString() <<": "<<mde.what()<<endl; 
    777782    } 
    778783  } 
     
    793798 
    794799  for(vector<string>::const_iterator i=locals.begin();i!=locals.end();++i) { 
    795     int fd=socket(AF_INET, SOCK_DGRAM,0); 
     800    ComboAddress sin; 
     801    memset(&sin, 0, sizeof(sin)); 
     802    sin.sin4.sin_family = AF_INET; 
     803    if(!IpToU32(*i, &sin.sin4.sin_addr.s_addr)) { 
     804      sin.sin6.sin6_family = AF_INET6; 
     805      if(inet_pton(AF_INET6, i->c_str(), &sin.sin6.sin6_addr) <= 0) 
     806        throw AhuException("Unable to resolve local address '"+ *i +"'");  
     807    } 
     808     
     809    int fd=socket(sin.sin4.sin_family, SOCK_DGRAM,0); 
    796810    if(fd<0)  
    797       throw AhuException("Making a server socket for resolver: "+stringerror()); 
     811      throw AhuException("Making a UDP server socket for resolver: "+stringerror()); 
     812 
    798813    setReceiveBuffer(fd, 200000); 
    799     struct sockaddr_in sin; 
    800     memset((char *)&sin,0, sizeof(sin)); 
    801      
    802     sin.sin_family = AF_INET; 
    803     if(!IpToU32(*i, &sin.sin_addr.s_addr)) 
    804       throw AhuException("Unable to resolve local address '"+ *i +"'");  
    805      
    806     sin.sin_port = htons(::arg().asNum("local-port"));  
    807      
    808     if (::bind(fd, (struct sockaddr *)&sin, sizeof(sin))<0)  
     814    sin.sin4.sin_port = htons(::arg().asNum("local-port"));  
     815 
     816    int socklen=sin.sin4.sin_family==AF_INET ? sizeof(sin.sin4) : sizeof(sin.sin6); 
     817    if (::bind(fd, (struct sockaddr *)&sin, socklen)<0)  
    809818      throw AhuException("Resolver binding to server socket for "+*i+": "+stringerror()); 
    810819     
    811820    Utility::setNonBlocking(fd); 
    812821    g_fdm->addReadFD(fd, handleNewUDPQuestion); 
    813     L<<Logger::Error<<"Listening for UDP queries on "<<inet_ntoa(sin.sin_addr)<<":"<<::arg().asNum("local-port")<<endl; 
     822    g_tcpListenSockets.push_back(fd); 
     823    L<<Logger::Error<<"Listening for UDP queries on "<<sin.toString()<<":"<<::arg().asNum("local-port")<<endl; 
    814824  } 
    815825} 
     
    10611071      g_stats.serverParseError++;  
    10621072      if(g_logCommonErrors) 
    1063         L<<Logger::Error<<"Unable to parse packet from remote UDP server "<< sockAddrToString((struct sockaddr_in*) &fromaddr, addrlen) << 
     1073        L<<Logger::Error<<"Unable to parse packet from remote UDP server "<< sockAddrToString((struct sockaddr_in*) &fromaddr) << 
    10641074          ": packet smalller than DNS header"<<endl; 
    10651075    } 
     
    11001110  } 
    11011111  else 
    1102     L<<Logger::Warning<<"Ignoring question on outgoing socket from "<< sockAddrToString((struct sockaddr_in*) &fromaddr, addrlen)  <<endl; 
     1112    L<<Logger::Warning<<"Ignoring question on outgoing socket from "<< sockAddrToString((struct sockaddr_in*) &fromaddr)  <<endl; 
    11031113} 
    11041114 
     
    12921302          if(conn.state != TCPConnection::DONE) { 
    12931303            if(g_logCommonErrors) 
    1294               L<<Logger::Warning<<"Timeout from remote TCP client "<<sockAddrToString(&conn.remote,sizeof(conn.remote))<<endl; 
     1304              L<<Logger::Warning<<"Timeout from remote TCP client "<< conn.remote.toString() <<endl; 
    12951305            g_fdm->removeReadFD(i->first); 
    12961306            conn.closeAndCleanup(); 
     
    13091319 
    13101320      if(listenOnTCP) { 
    1311         if(TCPConnection::s_currentConnections > maxTcpClients) { 
    1312           g_fdm->removeReadFD(g_tcpListenSocket); 
     1321        if(TCPConnection::s_currentConnections > maxTcpClients) {  // shutdown 
     1322          for_each(g_tcpListenSockets.begin(), g_tcpListenSockets.end(),  
     1323                   boost::bind(&FDMultiplexer::removeReadFD, g_fdm, _1)); 
    13131324          listenOnTCP=false; 
    13141325        } 
    13151326      } 
    13161327      else { 
    1317         if(TCPConnection::s_currentConnections <= maxTcpClients) { 
    1318           g_fdm->addReadFD(g_tcpListenSocket, handleNewTCPQuestion); 
     1328        if(TCPConnection::s_currentConnections <= maxTcpClients) {  // reenable 
     1329          for_each(g_tcpListenSockets.begin(), g_tcpListenSockets.end(),  
     1330                   boost::bind(&FDMultiplexer::addReadFD,  
     1331                               g_fdm, _1, handleNewTCPQuestion, boost::any())); 
    13191332          listenOnTCP=true; 
    13201333        }