Changeset 700

Show
Ignore:
Timestamp:
04/14/06 14:35:19 (4 years ago)
Author:
ahu
Message:

make anti-spoofing measures question and not ip address specific, make them tunable

Location:
trunk/pdns/pdns
Files:
6 modified

Legend:

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

    r699 r700  
    4747  Socket s(InterNetwork, Datagram); 
    4848   
    49   IPEndpoint rem("127.0.0.1",1232), loc("213.156.2.1", 53); 
     49  IPEndpoint rem("10.0.1.6",35515), loc("213.156.2.1", 53); 
    5050  s.bind(loc); 
    5151 
  • trunk/pdns/pdns/lwres.cc

    r697 r700  
    8989    // sleep until we see an answer to this, interface to mtasker 
    9090     
    91     ret=arecvfrom(reinterpret_cast<char *>(d_buf), d_bufsize-1,0,(struct sockaddr*)(&toaddr), &addrlen, &d_len, pw.getHeader()->id); 
     91    ret=arecvfrom(reinterpret_cast<char *>(d_buf), d_bufsize-1,0,(struct sockaddr*)(&toaddr), &addrlen, &d_len, pw.getHeader()->id, domain); 
    9292  } 
    9393  else { 
  • trunk/pdns/pdns/lwres.hh

    r694 r700  
    4545 
    4646int asendto(const char *data, int len, int flags, struct sockaddr *toaddr, int addrlen, int id); 
    47 int arecvfrom(char *data, int len, int flags, struct sockaddr *toaddr, Utility::socklen_t *addrlen, int *d_len, int id); 
     47int arecvfrom(char *data, int len, int flags, struct sockaddr *toaddr, Utility::socklen_t *addrlen, int *d_len, int id, const string& domain); 
    4848 
    4949class LWResException : public AhuException 
  • trunk/pdns/pdns/pdns_recursor.cc

    r699 r700  
    173173 
    174174// -1 is error, 0 is timeout, 1 is success 
    175 int arecvfrom(char *data, int len, int flags, struct sockaddr *toaddr, Utility::socklen_t *addrlen, int *d_len, int id) 
    176 { 
     175int arecvfrom(char *data, int len, int flags, struct sockaddr *toaddr, Utility::socklen_t *addrlen, int *d_len, int id, const string& domain) 
     176{ 
     177  static optional<unsigned int> nearMissLimit; 
     178  if(!nearMissLimit)  
     179    nearMissLimit=::arg().asNum("spoof-nearmiss-max"); 
     180 
    177181  PacketID pident; 
    178182  pident.id=id; 
     183  pident.domain=domain; 
    179184  memcpy(&pident.remote, toaddr, sizeof(pident.remote)); 
    180185 
     
    184189    *d_len=packet.size(); 
    185190    memcpy(data,packet.c_str(),min(len,*d_len)); 
    186     if(pident.nearMisses > 100) { 
    187       L<<Logger::Error<<"Too many ("<<pident.nearMisses<<") bogus answers came in from "<<sockAddrToString((struct sockaddr_in*)toaddr, sizeof(pident.remote))<<", assuming spoof attempt."<<endl; 
     191    if(*nearMissLimit && pident.nearMisses > *nearMissLimit) { 
     192      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; 
     193      g_stats.spoofCount++; 
    188194      return -1; 
    189195    } 
     
    741747} 
    742748#endif 
     749 
     750string questionExpand(const char* packet, uint16_t len) 
     751{ 
     752  const char* end=packet+len; 
     753  const char* pos=packet+12; 
     754  unsigned char labellen; 
     755  string ret; 
     756 
     757  while((labellen=*pos++)) { 
     758    if(pos+labellen > end) 
     759      break; 
     760    ret.append(pos, labellen); 
     761    ret.append(1,'.'); 
     762    pos+=labellen; 
     763  } 
     764  if(ret.empty()) 
     765    ret="."; 
     766  return ret; 
     767} 
    743768 
    744769int main(int argc, char **argv)  
     
    779804    ::arg().set("max-tcp-per-client", "If set, maximum number of TCP sessions per client (IP address)")="0"; 
    780805    ::arg().set("fork", "If set, fork the daemon for possible double performance")="no"; 
     806    ::arg().set("spoof-nearmiss-max", "If non-zero, assume spoofing after this many near misses")="20"; 
    781807 
    782808    ::arg().setCmd("help","Provide a helpful message"); 
     
    9991025                pident.remote=fromaddr; 
    10001026                pident.id=dh.id; 
     1027                pident.domain=questionExpand(data, d_len); 
    10011028                string packet; 
    10021029                packet.assign(data, d_len); 
    10031030                if(!MT->sendEvent(pident, &packet)) { 
    10041031                  if(logCommonErrors) 
    1005                     L<<Logger::Warning<<"Discarding unexpected packet from "<<sockAddrToString((struct sockaddr_in*) &fromaddr, addrlen)<<endl; 
     1032                    L<<Logger::Warning<<"Discarding unexpected packet answering '"<<pident.domain<<"' from "<<sockAddrToString((struct sockaddr_in*) &fromaddr, addrlen)<<endl; 
    10061033                  g_stats.unexpectedCount++; 
    10071034                   
    10081035                  for(MT_t::waiters_t::iterator mthread=MT->d_waiters.begin(); mthread!=MT->d_waiters.end(); ++mthread) { 
    1009                     if(!memcmp(&mthread->key.remote.sin_addr, &pident.remote.sin_addr, sizeof(pident.remote.sin_addr))) { 
     1036                    if(!memcmp(&mthread->key.remote.sin_addr, &pident.remote.sin_addr, sizeof(pident.remote.sin_addr)) && !strcasecmp(pident.domain.c_str(), mthread->key.domain.c_str())) { 
    10101037                      mthread->key.nearMisses++; 
    10111038                    } 
  • trunk/pdns/pdns/rec_channel_rec.cc

    r678 r700  
    154154 
    155155  addGetStat("qa-latency", &g_stats.avgLatencyUsec); 
     156  addGetStat("unexpected-packets", &g_stats.unexpectedCount); 
     157  addGetStat("spoof-prevents", &g_stats.spoofCount); 
    156158 
    157159  addGetStat("negcache-entries", boost::bind(&SyncRes::negcache_t::size, ref(SyncRes::s_negcache))); 
  • trunk/pdns/pdns/syncres.hh

    r699 r700  
    323323  uint16_t id;  // wait for a specific id/remote pair 
    324324  struct sockaddr_in remote;  // this is the remote 
     325  string domain;             // this is the question  
    325326 
    326327  Socket* sock;  // or wait for an event on a TCP fd 
     
    337338    int ourSock= sock ? sock->getHandle() : 0; 
    338339    int bSock = b.sock ? b.sock->getHandle() : 0; 
    339     return  
    340       tie(id, remote.sin_addr.s_addr, remote.sin_port, ourSock) < 
    341       tie(b.id, b.remote.sin_addr.s_addr, b.remote.sin_port, bSock); 
     340    if( tie(id, remote.sin_addr.s_addr, remote.sin_port, ourSock) < 
     341        tie(b.id, b.remote.sin_addr.s_addr, b.remote.sin_port, bSock)) 
     342      return true; 
     343    if( tie(id, remote.sin_addr.s_addr, remote.sin_port, ourSock) > 
     344        tie(b.id, b.remote.sin_addr.s_addr, b.remote.sin_port, bSock)) 
     345      return false; 
     346 
     347    return strcasecmp(domain.c_str(), b.domain.c_str()) < 0; 
    342348  } 
    343349}; 
     
    362368  uint64_t serverParseError; 
    363369  uint64_t unexpectedCount; 
     370  uint64_t spoofCount; 
    364371}; 
    365372