Show
Ignore:
Timestamp:
12/24/09 17:54:31 (3 years ago)
Author:
ahu
Message:

expand speedtest infrastructure

Files:
1 modified

Legend:

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

    r1401 r1470  
    111111  { 
    112112      DNSRecordContent*drc = DNSRecordContent::mastermake(QType::A, 1,  
    113                                                           "1.2.3.4"); 
     113                                                          "1.2.3.4"); 
    114114      delete drc; 
    115115  } 
     
    175175  { 
    176176    return (boost::format("%d %s records") % d_records %  
    177             DNSRecordContent::NumberToType(d_type)).str(); 
     177            DNSRecordContent::NumberToType(d_type)).str(); 
    178178  } 
    179179 
     
    185185      pw.startRecord("outpost.ds9a.nl", d_type); 
    186186      DNSRecordContent*drc = DNSRecordContent::mastermake(d_type, 1,  
    187                                                           d_content); 
     187                                                          d_content); 
    188188      drc->toPacket(pw); 
    189189      delete drc; 
     
    261261  // nobody reads what we output, but it appears to be the magic that shuts some nameservers up 
    262262  static const char*ips[]={"198.41.0.4", "192.228.79.201", "192.33.4.12", "128.8.10.90", "192.203.230.10", "192.5.5.241", "192.112.36.4", "128.63.2.53",  
    263                      "192.36.148.17","192.58.128.30", "193.0.14.129", "198.32.64.12", "202.12.27.33"}; 
     263                     "192.36.148.17","192.58.128.30", "193.0.14.129", "198.32.64.12", "202.12.27.33"}; 
    264264  static char templ[40]; 
    265265  strncpy(templ,"a.root-servers.net", sizeof(templ) - 1); 
     
    332332}; 
    333333 
     334struct StackMallocTest 
     335{ 
     336  string getName() const 
     337  { 
     338    return "stack allocation"; 
     339  } 
     340 
     341  void operator()() const 
     342  { 
     343    char *buffer= new char[200000]; 
     344    delete buffer; 
     345  } 
     346 
     347}; 
     348 
     349 
    334350struct EmptyQueryTest 
    335351{ 
     
    359375 
    360376}; 
     377 
     378struct TCacheComp 
     379{ 
     380  bool operator()(const pair<string, QType>& a, const pair<string, QType>& b) const 
     381  { 
     382    int cmp=strcasecmp(a.first.c_str(), b.first.c_str()); 
     383    if(cmp < 0) 
     384      return true; 
     385    if(cmp > 0) 
     386      return false; 
     387 
     388    return a.second < b.second; 
     389  } 
     390}; 
     391 
     392struct NegCacheEntry 
     393{ 
     394  string d_name; 
     395  QType d_qtype; 
     396  string d_qname; 
     397  uint32_t d_ttd; 
     398}; 
     399 
     400struct timeval d_now; 
     401 
     402static bool magicAddrMatch(const QType& query, const QType& answer) 
     403{ 
     404  if(query.getCode() != QType::ADDR) 
     405    return false; 
     406  return answer.getCode() == QType::A || answer.getCode() == QType::AAAA; 
     407} 
     408 
     409 
     410bool moreSpecificThan(const string& a, const string &b) 
     411{ 
     412  static string dot("."); 
     413  int counta=(a!=dot), countb=(b!=dot); 
     414   
     415  for(string::size_type n=0;n<a.size();++n) 
     416    if(a[n]=='.') 
     417      counta++; 
     418  for(string::size_type n=0;n<b.size();++n) 
     419    if(b[n]=='.') 
     420      countb++; 
     421  return counta>countb; 
     422} 
    361423 
    362424 
     
    375437  { 
    376438    MOADNSParser mdp((const char*)&*d_packet.begin(), d_packet.size()); 
     439    typedef map<pair<string, QType>, set<DNSResourceRecord>, TCacheComp > tcache_t; 
     440    tcache_t tcache; 
     441     
     442    struct { 
     443            vector<DNSResourceRecord> d_result; 
     444            bool d_aabit; 
     445            int d_rcode; 
     446    } lwr; 
     447    DNSResourceRecord rr; 
     448    for(MOADNSParser::answers_t::const_iterator i=mdp.d_answers.begin(); i!=mdp.d_answers.end(); ++i) {           
     449      DNSResourceRecord rr; 
     450      rr.qtype=i->first.d_type; 
     451      rr.qname=i->first.d_label; 
     452     
     453      rr.ttl=i->first.d_ttl; 
     454      rr.content=i->first.d_content->getZoneRepresentation();  // this should be the serialised form 
     455      rr.d_place=(DNSResourceRecord::Place) i->first.d_place; 
     456      lwr.d_result.push_back(rr); 
     457    } 
     458 
     459     
     460     
     461 
     462      // reap all answers from this packet that are acceptable 
     463      for(vector<DNSResourceRecord>::iterator i=lwr.d_result.begin();i != lwr.d_result.end();++i) { 
     464        if(i->qtype.getCode() == QType::OPT) { 
     465          // <<prefix<<qname<<": skipping OPT answer '"<<i->qname<<"' from '"<<auth<<"' nameservers" <<endl; 
     466          continue; 
     467        } 
     468        // LOG<<prefix<<qname<<": accept answer '"<<i->qname<<"|"<<i->qtype.getName()<<"|"<<i->content<<"' from '"<<auth<<"' nameservers? "; 
     469        if(i->qtype.getCode()==QType::ANY) { 
     470          // LOG<<"NO! - we don't accept 'ANY' data"<<endl; 
     471          continue; 
     472        } 
     473        string auth("."); 
     474        if(dottedEndsOn(i->qname, auth)) { 
     475          if(lwr.d_aabit && lwr.d_rcode==RCode::NoError && i->d_place==DNSResourceRecord::ANSWER && 0) { 
     476            // LOG<<"NO! Is from delegation-only zone"<<endl; 
     477            // s_nodelegated++; 
     478            return; // RCode::NXDomain; 
     479          } 
     480          else { 
     481            // LOG<<"YES!"<<endl; 
     482 
     483          //  i->ttl=min(s_maxcachettl, i->ttl); 
     484             
     485            DNSResourceRecord rr=*i; 
     486            rr.d_place=DNSResourceRecord::ANSWER; 
     487 
     488            // rr.ttl += d_now.tv_sec; 
     489 
     490            if(rr.qtype.getCode() == QType::NS) // people fiddle with the case 
     491              rr.content=toLower(rr.content); // this must stay! (the cache can't be case-insensitive on the RHS of records) 
     492            tcache[make_pair(i->qname,i->qtype)].insert(rr); 
     493          } 
     494        }          
     495        else 
     496          ; // LOG<<"NO!"<<endl; 
     497      } 
     498     
     499      // supplant 
     500      for(tcache_t::iterator i=tcache.begin();i!=tcache.end();++i) { 
     501        if(i->second.size() > 1) {  // need to group the ttl to be the minimum of the RRSET (RFC 2181, 5.2) 
     502          uint32_t lowestTTL=numeric_limits<uint32_t>::max(); 
     503          for(tcache_t::value_type::second_type::iterator j=i->second.begin(); j != i->second.end(); ++j) 
     504            lowestTTL=min(lowestTTL, j->ttl); 
     505           
     506          for(tcache_t::value_type::second_type::iterator j=i->second.begin(); j != i->second.end(); ++j) 
     507            ((tcache_t::value_type::second_type::value_type*)&(*j))->ttl=lowestTTL; 
     508        } 
     509 
     510        // RC.replace(d_now.tv_sec, i->first.first, i->first.second, i->second, lwr.d_aabit); 
     511      } 
     512      set<string, CIStringCompare> nsset;   
     513      // LOG<<prefix<<qname<<": determining status after receiving this packet"<<endl; 
     514 
     515      bool done=false, realreferral=false, negindic=false; 
     516      string newauth, soaname, newtarget; 
     517      string qname("."); 
     518      vector<DNSResourceRecord> ret; 
     519      QType qtype(QType::A); 
     520      string auth("."); 
     521  
     522      for(vector<DNSResourceRecord>::const_iterator i=lwr.d_result.begin();i!=lwr.d_result.end();++i) { 
     523        if(i->d_place==DNSResourceRecord::AUTHORITY && dottedEndsOn(qname,i->qname) && i->qtype.getCode()==QType::SOA &&  
     524           lwr.d_rcode==RCode::NXDomain) { 
     525          // LOG<<prefix<<qname<<": got negative caching indication for RECORD '"<<qname+"'"<<endl; 
     526          ret.push_back(*i); 
     527 
     528          NegCacheEntry ne; 
     529 
     530          ne.d_qname=i->qname; 
     531          ne.d_ttd=d_now.tv_sec + min(i->ttl, 3600U); // controversial 
     532          ne.d_name=qname; 
     533          ne.d_qtype=QType(0); // this encodes 'whole record' 
     534           
     535          { 
     536            // Lock l(&s_negcachelock); 
     537            // replacing_insert(s_negcache, ne); 
     538          } 
     539          negindic=true; 
     540        } 
     541        else if(i->d_place==DNSResourceRecord::ANSWER && iequals(i->qname, qname) && i->qtype.getCode()==QType::CNAME && (!(qtype==QType(QType::CNAME)))) { 
     542          ret.push_back(*i); 
     543          newtarget=i->content; 
     544        } 
     545        // for ANY answers we *must* have an authoritive answer 
     546        else if(i->d_place==DNSResourceRecord::ANSWER && pdns_iequals(i->qname, qname) &&  
     547                ( 
     548                 i->qtype==qtype || (lwr.d_aabit && (qtype==QType(QType::ANY) || magicAddrMatch(qtype, i->qtype) ) ) 
     549                )  
     550               )    
     551          { 
     552           
     553          // LOG<<prefix<<qname<<": answer is in: resolved to '"<< i->content<<"|"<<i->qtype.getName()<<"'"<<endl; 
     554 
     555          done=true; 
     556          ret.push_back(*i); 
     557        } 
     558        else if(i->d_place==DNSResourceRecord::AUTHORITY && dottedEndsOn(qname,i->qname) && i->qtype.getCode()==QType::NS) {  
     559          if(moreSpecificThan(i->qname,auth)) { 
     560            newauth=i->qname; 
     561            // LOG<<prefix<<qname<<": got NS record '"<<i->qname<<"' -> '"<<i->content<<"'"<<endl; 
     562            realreferral=true; 
     563          } 
     564          else  
     565            ;// // LOG<<prefix<<qname<<": got upwards/level NS record '"<<i->qname<<"' -> '"<<i->content<<"', had '"<<auth<<"'"<<endl; 
     566          nsset.insert(i->content); 
     567        } 
     568        else if(!done && i->d_place==DNSResourceRecord::AUTHORITY && dottedEndsOn(qname,i->qname) && i->qtype.getCode()==QType::SOA &&  
     569           lwr.d_rcode==RCode::NoError) { 
     570          // LOG<<prefix<<qname<<": got negative caching indication for '"<< (qname+"|"+i->qtype.getName()+"'") <<endl; 
     571          ret.push_back(*i); 
     572           
     573          NegCacheEntry ne; 
     574          ne.d_qname=i->qname; 
     575          ne.d_ttd=d_now.tv_sec + i->ttl; 
     576          ne.d_name=qname; 
     577          ne.d_qtype=qtype; 
     578          if(qtype.getCode()) {  // prevents us from blacking out a whole domain 
     579           // Lock l(&s_negcachelock); 
     580            // replacing_insert(s_negcache, ne); 
     581          } 
     582          negindic=true; 
     583        } 
     584      } 
     585 
    377586  } 
    378587  const vector<uint8_t>& d_packet; 
    379588  std::string d_name; 
    380589}; 
     590 
     591struct ParsePacketBareTest 
     592{ 
     593  explicit ParsePacketBareTest(const vector<uint8_t>& packet, const std::string& name)  
     594    : d_packet(packet), d_name(name) 
     595  {} 
     596 
     597  string getName() const 
     598  { 
     599    return "parse '"+d_name+"' bare"; 
     600  } 
     601 
     602  void operator()() const 
     603  { 
     604    MOADNSParser mdp((const char*)&*d_packet.begin(), d_packet.size()); 
     605  } 
     606  const vector<uint8_t>& d_packet; 
     607  std::string d_name; 
     608}; 
     609 
    381610 
    382611struct SimpleCompressTest 
     
    418647}; 
    419648 
     649 
     650 
     651struct IEqualsTest 
     652{ 
     653  string getName() const 
     654  { 
     655    return "iequals test"; 
     656  } 
     657 
     658  void operator()() const 
     659  { 
     660      static string a("www.ds9a.nl"), b("www.lwn.net"); 
     661      bool ret = iequals(a, b); 
     662  } 
     663 
     664}; 
     665 
     666struct MyIEqualsTest 
     667{ 
     668  string getName() const 
     669  { 
     670    return "pdns_iequals test"; 
     671  } 
     672 
     673  void operator()() const 
     674  { 
     675      static string a("www.ds9a.nl"), b("www.lwn.net"); 
     676      bool ret = pdns_iequals(a, b); 
     677  } 
     678 
     679}; 
     680 
     681 
     682struct StrcasecmpTest 
     683{ 
     684  string getName() const 
     685  { 
     686    return "strcasecmp test"; 
     687  } 
     688 
     689  void operator()() const 
     690  { 
     691      static string a("www.ds9a.nl"), b("www.lwn.net"); 
     692      bool ret = strcasecmp(a.c_str(), b.c_str()); 
     693  } 
     694}; 
     695 
     696 
    420697struct NOPTest 
    421698{ 
     
    439716  signal(SIGVTALRM, alarmHandler); 
    440717   
    441   //  doRun(NOPTest()); 
     718  doRun(NOPTest()); 
     719   
     720  doRun(IEqualsTest()); 
     721  doRun(MyIEqualsTest()); 
     722  doRun(StrcasecmpTest()); 
     723 
     724  doRun(StackMallocTest()); 
    442725 
    443726  vector<uint8_t> packet = makeRootReferral(); 
     727  doRun(ParsePacketBareTest(packet, "root-referral")); 
    444728  doRun(ParsePacketTest(packet, "root-referral")); 
    445729 
     
    455739  packet = makeTypicalReferral(); 
    456740  cerr<<"typical referral size: "<<packet.size()<<endl; 
     741  doRun(ParsePacketBareTest(packet, "typical-referral")); 
     742 
    457743  doRun(ParsePacketTest(packet, "typical-referral")); 
    458744 
    459  
    460745  doRun(SimpleCompressTest("www.france.ds9a.nl")); 
    461746 
     747   
    462748  doRun(VectorExpandTest()); 
    463749