Show
Ignore:
Timestamp:
04/14/06 12:13:13 (7 years ago)
Author:
ahu
Message:

add query-local-port, and make us move around if unset
log netmasks allowed a bit prettier
add nasty warning

Files:
1 modified

Legend:

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

    r697 r698  
    120120} 
    121121static int d_clientsock; 
     122static int d_prevclientsock; 
    122123static vector<int> d_udpserversocks; 
    123124 
     
    451452} 
    452453 
    453 void makeClientSocket() 
    454 { 
     454// this stuff is a tad complicated. There are two client sockets, the current one and the previous one (prevclientsocket) 
     455// if this function is called, and more than 5 seconds have passed since the previous call, the previous client socket is closed, 
     456// and replaced by the current one, which is then reopened. 
     457void remakeClientSocket() 
     458{ 
     459  static time_t lastChange; 
     460 
     461  if(d_clientsock>=0 && !::arg()["query-local-port"].empty()) // already have a port, and we are fixed 
     462    return; 
     463 
     464  if(!lastChange) 
     465    lastChange=time(0)-10; 
     466 
     467  if(lastChange > time(0) - 5) 
     468    return; 
     469 
     470  lastChange=time(0); 
     471 
     472  if(d_prevclientsock >= 0) { 
     473    close(d_prevclientsock); 
     474  } 
     475  d_prevclientsock=d_clientsock;   
     476 
    455477  d_clientsock=socket(AF_INET, SOCK_DGRAM,0); 
    456478  if(d_clientsock<0)  
     
    467489  int tries=10; 
    468490  while(--tries) { 
    469     uint16_t port=10000+Utility::random()%10000; 
     491    uint16_t port; 
     492    if(::arg()["query-local-port"].empty()) 
     493      port=10000+Utility::random()%50000; 
     494    else { 
     495      port=::arg().asNum("query-local-port"); 
     496      tries=1; 
     497    } 
    470498    sin.sin_port = htons(port);  
    471499     
     
    475503  } 
    476504  if(!tries) 
    477     throw AhuException("Resolver binding to local socket: "+stringerror()); 
     505    throw AhuException("Resolver binding to local query client socket: "+stringerror()); 
    478506 
    479507  Utility::setNonBlocking(d_clientsock); 
    480  
    481   L<<Logger::Error<<"Sending UDP queries from "<<inet_ntoa(sin.sin_addr)<<":"<< ntohs(sin.sin_port)  <<endl; 
     508   
     509  //  L<<Logger::Error<<"Sending UDP queries from "<<inet_ntoa(sin.sin_addr)<<":"<< ntohs(sin.sin_port)  <<endl; 
    482510} 
    483511 
     
    738766    ::arg().set("delegation-only","Which domains we only accept delegations from")=""; 
    739767    ::arg().set("query-local-address","Source IP address for sending queries")="0.0.0.0"; 
     768    ::arg().set("query-local-port","Source port address for sending queries, defaults to random")=""; 
    740769    ::arg().set("client-tcp-timeout","Timeout in seconds when talking to TCP clients")="2"; 
    741770    ::arg().set("max-tcp-clients","Maximum number of simultaneous TCP clients")="128"; 
     
    766795    } 
    767796 
    768     if(!::arg()["allow-from"].empty()) { 
    769       g_allowFrom=new NetmaskGroup; 
    770       vector<string> ips; 
    771       stringtok(ips, ::arg()["allow-from"], ", "); 
    772       for(vector<string>::const_iterator i = ips.begin(); i!= ips.end(); ++i) 
    773         g_allowFrom->addMask(*i); 
    774     } 
    775  
    776797    L.setName("pdns_recursor"); 
    777798 
     
    787808      "according to the terms of the GPL version 2."<<endl; 
    788809     
     810 
     811    if(!::arg()["allow-from"].empty()) { 
     812      g_allowFrom=new NetmaskGroup; 
     813      vector<string> ips; 
     814      stringtok(ips, ::arg()["allow-from"], ", "); 
     815      L<<Logger::Warning<<"Only allowing queries from: "; 
     816      for(vector<string>::const_iterator i = ips.begin(); i!= ips.end(); ++i) { 
     817        g_allowFrom->addMask(*i); 
     818        if(i!=ips.begin()) 
     819          L<<Logger::Warning<<", "; 
     820        L<<Logger::Warning<<*i; 
     821      } 
     822      L<<Logger::Warning<<endl; 
     823    } 
     824    else if(::arg()["local-address"]!="127.0.0.1" && ::arg().asNum("local-port")==53) 
     825      L<<Logger::Error<<"WARNING: Allowing queries from all IP addresses - this can be a security risk!"<<endl; 
    789826     
    790827    g_quiet=::arg().mustDo("quiet"); 
     
    804841      L<<Logger::Warning<<"This is forked pid "<<getpid()<<endl; 
    805842    } 
    806     makeClientSocket(); 
     843    d_clientsock=d_prevclientsock=-1; 
     844    remakeClientSocket(); 
    807845 
    808846    makeControlChannelSocket(); 
     
    856894      while(MT->schedule()); // housekeeping, let threads do their thing 
    857895       
    858       if(!((counter++)%500))  
     896      if(!((counter++)%500)) { 
     897        remakeClientSocket(); 
    859898        MT->makeThread(houseKeeping,0); 
     899      } 
    860900      if(statsWanted) { 
    861901        doStats(); 
     
    873913      FD_ZERO( &writefds ); 
    874914      FD_SET( d_clientsock, &readfds ); 
     915      if(d_prevclientsock >= 0) 
     916        FD_SET( d_prevclientsock, &readfds ); 
     917 
    875918      FD_SET( s_rcc.d_fd, &readfds); 
    876919      int fdmax=max(d_clientsock, s_rcc.d_fd); 
     
    936979        command(); 
    937980      } 
    938  
    939       if(FD_ISSET(d_clientsock,&readfds)) { // do we have a UDP question response from a server ("we are the client", hence d_clientsock) 
    940         while((d_len=recvfrom(d_clientsock, data, sizeof(data), 0, (sockaddr *)&fromaddr, &addrlen)) >= 0) { 
    941           dnsheader dh; 
    942           if((size_t) d_len >= sizeof(dnsheader)) { 
    943             memcpy(&dh, data, sizeof(dh)); 
    944              
    945             if(dh.qr && dh.qdcount) { 
    946               pident.remote=fromaddr; 
    947               pident.id=dh.id; 
    948               string packet; 
    949               packet.assign(data, d_len); 
    950               if(!MT->sendEvent(pident, &packet)) { 
    951                 if(logCommonErrors) 
    952                   L<<Logger::Warning<<"Discarding unexpected packet from "<<sockAddrToString((struct sockaddr_in*) &fromaddr, addrlen)<<endl; 
    953                 g_stats.unexpectedCount++; 
     981       
     982      for(int port=0; port < 2; ++port) { 
     983        if(port && d_prevclientsock < 0) 
     984          break; 
     985        int sock = port ? d_prevclientsock : d_clientsock; 
     986           
     987        if(FD_ISSET(sock,&readfds)) { // do we have a UDP question response from a server ("we are the client", hence d_clientsock) 
     988          while((d_len=recvfrom(sock, data, sizeof(data), 0, (sockaddr *)&fromaddr, &addrlen)) >= 0) { 
     989            dnsheader dh; 
     990            if((size_t) d_len >= sizeof(dnsheader)) { 
     991              memcpy(&dh, data, sizeof(dh)); 
     992               
     993              if(dh.qr && dh.qdcount) { 
     994                pident.remote=fromaddr; 
     995                pident.id=dh.id; 
     996                string packet; 
     997                packet.assign(data, d_len); 
     998                if(!MT->sendEvent(pident, &packet)) { 
     999                  if(logCommonErrors) 
     1000                    L<<Logger::Warning<<"Discarding unexpected packet from "<<sockAddrToString((struct sockaddr_in*) &fromaddr, addrlen)<<endl; 
     1001                  g_stats.unexpectedCount++; 
     1002                } 
    9541003              } 
    955             } 
    956             else  
    957               L<<Logger::Warning<<"Ignoring question on outgoing socket from "<< sockAddrToString((struct sockaddr_in*) &fromaddr, addrlen)  <<endl; 
    958           } 
    959           else { 
    960             g_stats.serverParseError++;  
    961             if(logCommonErrors) 
    962               L<<Logger::Error<<"Unable to parse packet from remote UDP server "<< sockAddrToString((struct sockaddr_in*) &fromaddr, addrlen) <<": packet too small"<<endl; 
     1004              else  
     1005                L<<Logger::Warning<<"Ignoring question on outgoing socket from "<< sockAddrToString((struct sockaddr_in*) &fromaddr, addrlen)  <<endl; 
     1006            } 
     1007            else { 
     1008              g_stats.serverParseError++;  
     1009              if(logCommonErrors) 
     1010                L<<Logger::Error<<"Unable to parse packet from remote UDP server "<< sockAddrToString((struct sockaddr_in*) &fromaddr, addrlen) <<": packet too small"<<endl; 
     1011            } 
    9631012          } 
    9641013        }