Changeset 931

Show
Ignore:
Timestamp:
12/16/06 16:04:10 (2 years ago)
Author:
ahu
Message:

implement rest of speedups + some debugging output + i386 specific code (sorry)

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/pdns/pdns/misc.hh

    r927 r931  
    2020#define MISC_HH 
    2121 
    22 #if 0 
     22#if 1 
    2323#define RDTSC(qp) \ 
    2424do { \ 
  • trunk/pdns/pdns/pdns_recursor.cc

    r923 r931  
    283283    --d_numsocks; 
    284284  } 
    285 }g_udpclientsocks; 
     285} g_udpclientsocks; 
    286286 
    287287 
     
    395395  setBuffer(fd, SO_SNDBUF, size); 
    396396} 
     397 
    397398 
    398399static void writePid(void) 
     
    486487{ 
    487488  DNSComboWriter* dc=(DNSComboWriter *)p; 
     489 
    488490  try { 
    489491    uint16_t maxudpsize=512; 
     
    494496     
    495497    vector<DNSResourceRecord> ret; 
    496      
    497498    vector<uint8_t> packet; 
    498     DNSPacketWriter pw(packet, dc->d_mdp.d_qname, dc->d_mdp.d_qtype, dc->d_mdp.d_qclass); 
     499 
     500    DNSPacketWriter pw(packet, dc->d_mdp.d_qname, dc->d_mdp.d_qtype, dc->d_mdp.d_qclass);  
    499501 
    500502    pw.getHeader()->aa=0; 
     
    514516 
    515517    int res=sr.beginResolve(dc->d_mdp.d_qname, QType(dc->d_mdp.d_qtype), dc->d_mdp.d_qclass, ret); 
     518 
    516519    if(res<0) { 
    517520      pw.getHeader()->rcode=RCode::ServFail; 
     
    535538      if(ret.size()) { 
    536539        shuffle(ret); 
    537         for(vector<DNSResourceRecord>::const_iterator i=ret.begin();i!=ret.end();++i) { 
    538           pw.startRecord(i->qname, i->qtype.getCode(), i->ttl, i->qclass, (DNSPacketWriter::Place)i->d_place); 
    539           shared_ptr<DNSRecordContent> drc(DNSRecordContent::mastermake(i->qtype.getCode(), i->qclass, i->content)); 
     540 
     541        for(vector<DNSResourceRecord>::const_iterator i=ret.begin(); i!=ret.end(); ++i) { 
     542          pw.startRecord(i->qname, i->qtype.getCode(), i->ttl, i->qclass, (DNSPacketWriter::Place)i->d_place);  
    540543           
    541           drc->toPacket(pw); 
    542          
     544          if(i->qtype.getCode() == QType::A) { // blast out A record w/o doing whole dnswriter thing 
     545            uint32_t ip=0; 
     546            IpToU32(i->content, &ip); 
     547            pw.xfr32BitInt(htonl(ip)); 
     548          } else { 
     549            shared_ptr<DNSRecordContent> drc(DNSRecordContent::mastermake(i->qtype.getCode(), i->qclass, i->content));  
     550            drc->toPacket(pw); 
     551          } 
    543552          if(!dc->d_tcp && pw.size() > maxudpsize) { 
    544553            pw.rollback(); 
     
    548557          } 
    549558        } 
     559 
    550560        pw.commit(); 
    551561      } 
     
    594604      } 
    595605    } 
    596  
     606     
    597607    if(!g_quiet) { 
    598608      L<<Logger::Error<<"["<<MT->getTid()<<"] answer to "<<(dc->d_mdp.d_header.rd?"":"non-rd ")<<"question '"<<dc->d_mdp.d_qname<<"|"<<DNSRecordContent::NumberToType(dc->d_mdp.d_qtype); 
     
    600610        sr.d_throttledqueries<<" throttled, "<<sr.d_timeouts<<" timeouts, "<<sr.d_tcpoutqueries<<" tcp connections, rcode="<<res<<endl; 
    601611    } 
    602      
     612 
    603613    sr.d_outqueries ? RC.cacheMisses++ : RC.cacheHits++;  
    604614    float spent=makeFloat(sr.d_now-dc->d_now); 
     
    617627    if(newLat < 1000000)  // outliers of several minutes exist.. 
    618628      g_stats.avgLatencyUsec=(uint64_t)((1-0.0001)*g_stats.avgLatencyUsec + 0.0001*newLat); 
     629 
    619630    delete dc; 
    620631  } 
     
    765776} 
    766777  
     778void questionExpand(const char* packet, uint16_t len, char* qname, int maxlen, uint16_t& type) 
     779{ 
     780  type=0; 
     781  const unsigned char* end=(const unsigned char*)packet+len; 
     782  unsigned char* lbegin=(unsigned char*)packet+12; 
     783  unsigned char* pos=lbegin; 
     784  unsigned char labellen; 
     785 
     786  // 3www4ds9a2nl0 
     787  char *dst=qname; 
     788  char* lend=dst + maxlen; 
     789   
     790  if(!*pos) 
     791    *dst++='.'; 
     792 
     793  while((labellen=*pos++) && pos < end) { // "scan and copy" 
     794    if(dst >= lend) 
     795      throw runtime_error("Label length exceeded destination length"); 
     796    for(;labellen;--labellen) 
     797      *dst++ = *pos++; 
     798    *dst++='.'; 
     799  } 
     800  *dst=0; 
     801 
     802  if(pos + labellen + 2 <= end)  // is this correct XXX FIXME? 
     803    type=(*pos)*256 + *(pos+1); 
     804 
     805 
     806  //  cerr<<"Returning: '"<< string(tmp+1, pos) <<"'\n"; 
     807} 
     808 
     809string questionExpand(const char* packet, uint16_t len, uint16_t& type) 
     810{ 
     811  char tmp[512]; 
     812  questionExpand(packet, len, tmp, sizeof(tmp), type); 
     813  return tmp; 
     814} 
     815 
    767816void handleNewUDPQuestion(int fd, boost::any& var) 
    768817{ 
     
    771820  ComboAddress fromaddr; 
    772821  socklen_t addrlen=sizeof(fromaddr); 
     822  uint64_t tsc1, tsc2; 
    773823 
    774824  if((len=recvfrom(fd, data, sizeof(data), 0, (sockaddr *)&fromaddr, &addrlen)) >= 0) { 
     825    RDTSC(tsc1);       
    775826    g_stats.addRemote(fromaddr); 
     827 
    776828    if(g_allowFrom && !g_allowFrom->match(&fromaddr)) { 
    777829      if(!g_quiet)  
     
    782834    } 
    783835    try { 
    784       DNSComboWriter* dc = new DNSComboWriter(data, len, g_now); 
    785       dc->setRemote(&fromaddr); 
     836      dnsheader* dh=(dnsheader*)data; 
    786837       
    787       if(dc->d_mdp.d_header.qr) { 
     838      if(dh->qr) { 
    788839        if(g_logCommonErrors) 
    789           L<<Logger::Error<<"Ignoring answer from "<<dc->getRemote()<<" on server socket!"<<endl; 
    790         delete dc; 
     840          L<<Logger::Error<<"Ignoring answer from "<<fromaddr.toString()<<" on server socket!"<<endl; 
    791841      } 
    792842      else { 
    793843        ++g_stats.qcounter; 
     844        uint16_t type; 
     845        char qname[256]; 
     846        questionExpand(data, len, qname, sizeof(qname), type);   
     847         
     848        // must all be same length answers right now! 
     849        if((type==QType::A || type==QType::AAAA) && dh->arcount==0 && dh->ancount==0 && dh->nscount ==0 && ntohs(dh->qdcount)==1 ) { 
     850          char *record[10]; 
     851          uint16_t rlen[10]; 
     852          uint32_t ttd[10]; 
     853          int count; 
     854          if((count=RC.getDirect(g_now.tv_sec, qname, QType(type), ttd, record, rlen))) {  
     855            if(len + count*(sizeof(dnsrecordheader) + 2 + rlen[0]) > 512) 
     856              goto slow; 
     857 
     858            random_shuffle(record, &record[count]); 
     859            dh->qr=1; 
     860            dh->ra=1; 
     861            dh->ancount=ntohs(count); 
     862            for(int n=0; n < count ; ++n) { 
     863              memcpy(data+len, "\xc0\x0c", 2); // answer label pointer 
     864              len+=2; 
     865              struct dnsrecordheader drh; 
     866              drh.d_type=htons(type); 
     867              drh.d_class=htons(1); 
     868              drh.d_ttl=htonl(ttd[n] - g_now.tv_sec); 
     869              drh.d_clen=htons(rlen[n]); 
     870              memcpy(data+len, &drh, sizeof(drh)); 
     871              len+=sizeof(drh); 
     872              memcpy(data+len, record[n], rlen[n]); 
     873              len+=rlen[n]; 
     874            } 
     875            RDTSC(tsc2);             
     876            g_stats.shunted++; 
     877            sendto(fd, data, len, 0, (struct sockaddr *)(&fromaddr), fromaddr.getSocklen()); 
     878            cerr<<"shunted: " << (tsc2-tsc1) / 3000.0 << endl; 
     879            return; 
     880          } 
     881        } 
     882      slow: 
     883        DNSComboWriter* dc = new DNSComboWriter(data, len, g_now); 
    794884        dc->setSocket(fd); 
     885        dc->setRemote(&fromaddr); 
     886 
    795887        dc->d_tcp=false; 
     888 
    796889        MT->makeThread(startDoResolve, (void*) dc); // deletes dc 
    797890      } 
     
    10281121} 
    10291122; 
    1030  
    1031 string questionExpand(const char* packet, uint16_t len, uint16_t& type) 
    1032 { 
    1033   type=0; 
    1034   const unsigned char* end=(const unsigned char*)packet+len; 
    1035   const unsigned char* pos=(const unsigned char*)packet+12; 
    1036   unsigned char labellen; 
    1037   string ret; 
    1038   ret.reserve(len-12); 
    1039   while((labellen=*pos++)) { 
    1040     if(pos+labellen > end) 
    1041       break; 
    1042     ret.append((const char*)pos, labellen); 
    1043     ret.append(1,'.'); 
    1044     pos+=labellen; 
    1045   } 
    1046   if(ret.empty()) 
    1047     ret="."; 
    1048  
    1049   if(pos + labellen + 2 <= end)  // is this correct XXX FIXME? 
    1050     type=(*pos)*256 + *(pos+1); 
    1051      
    1052   return ret; 
    1053 } 
    10541123 
    10551124 
  • trunk/pdns/pdns/recursor_cache.cc

    r901 r931  
    143143} 
    144144 
     145int MemRecursorCache::getDirect(time_t now, const char* qname, const QType& qt, uint32_t ttd[10], char* data[10], uint16_t len[10]) 
     146{ 
     147  if(!d_cachecachevalid || Utility::strcasecmp(d_cachedqname.c_str(), qname)) { 
     148    cerr<<"had cache cache miss for '"<<qname<<"'"<<endl; 
     149    d_cachedqname=qname; 
     150    d_cachecache=d_cache.equal_range(tie(qname)); 
     151    d_cachecachevalid=true; 
     152  } 
     153  else 
     154    ; 
     155  //    cerr<<"had cache cache hit!"<<endl; 
     156 
     157  if(d_cachecache.first == d_cachecache.second) 
     158    return false; 
     159 
     160  pair<cache_t::iterator, cache_t::iterator> range = d_cachecache; 
     161   
     162  unsigned int n=0; 
     163  for(;range.first != range.second; ++range.first) { 
     164    if(range.first->d_qtype == QType::CNAME) // if we see a cname, we need the whole shebang (for now) 
     165      return false; 
     166    if(range.first->d_qtype != qt.getCode()) 
     167      continue; 
     168    if(range.first->getTTD() < (unsigned int) now) 
     169      return false; 
     170     
     171    if(range.first->d_records.empty() || range.first->d_records.size() > 9 ) 
     172      return false; 
     173     
     174    size_t limit=range.first->d_records.size(); 
     175    n=0; 
     176    for(; n < limit; ++n) { 
     177      data[n]=(char*)range.first->d_records[n].d_string.c_str(); 
     178      len[n]=range.first->d_records[n].d_string.length(); 
     179      ttd[n]=range.first->d_records[n].d_ttd; 
     180    } 
     181    if(n<10) { 
     182      data[n]=0; 
     183      typedef cache_t::nth_index<1>::type sequence_t; 
     184      sequence_t& sidx=d_cache.get<1>(); 
     185      sequence_t::iterator si=d_cache.project<1>(range.first); 
     186      sidx.relocate(sidx.end(), si); // move it in the LRU list  
     187      // can't yet return, need to figure out if there isn't a CNAME that messes things up 
     188    } 
     189    else 
     190      return false; 
     191  } 
     192  return n; 
     193 
     194} 
    145195 
    146196int MemRecursorCache::get(time_t now, const string &qname, const QType& qt, set<DNSResourceRecord>* res) 
  • trunk/pdns/pdns/recursor_cache.hh

    r896 r931  
    3333  unsigned int bytes(); 
    3434  int get(time_t, const string &qname, const QType& qt, set<DNSResourceRecord>* res); 
     35 
     36  int getDirect(time_t now, const char* qname, const QType& qt, uint32_t ttd[10], char* data[10], uint16_t len[10]); 
    3537  void replace(time_t, const string &qname, const QType& qt,  const set<DNSResourceRecord>& content, bool auth); 
    3638  void doPrune(void); 
     
    9698      return earliest; 
    9799    } 
    98  
    99100  }; 
    100101 
  • trunk/pdns/pdns/syncres.hh

    r901 r931  
    478478  uint64_t chainResends; 
    479479  uint64_t nsSetInvalidations; 
     480  uint64_t shunted; 
    480481 
    481482  typedef vector<ComboAddress> remotes_t;