Changeset 671

Show
Ignore:
Timestamp:
04/09/06 23:18:10 (4 years ago)
Author:
ahu
Message:

inline "strcasecmp" (stolen from glibc), short-circuit a lot of dnsencoding/decoding logic

Location:
trunk/pdns/pdns
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • trunk/pdns/pdns/misc.hh

    r670 r671  
    3737 
    3838#endif // WIN32 
    39  
    4039#include <deque> 
    4140#include <stdexcept> 
     
    294293  bool operator()(const string& a, const string& b) const 
    295294  { 
    296     return strcasecmp(a.c_str(), b.c_str()) < 0; 
     295    const unsigned char *p1 = (const unsigned char *) a.c_str(); 
     296    const unsigned char *p2 = (const unsigned char *) b.c_str(); 
     297    int result; 
     298     
     299    if (p1 == p2) 
     300      return 0; 
     301     
     302    while ((result = dns_tolower (*p1) - dns_tolower (*p2++)) == 0) 
     303      if (*p1++ == '\0') 
     304        break; 
     305     
     306    return result < 0; 
    297307  } 
    298308}; 
  • trunk/pdns/pdns/recursor_cache.cc

    r670 r671  
    3434#endif 
    3535 
     36string simpleCompress(const string& label) 
     37{ 
     38  typedef vector<pair<unsigned int, unsigned int> > parts_t; 
     39  parts_t parts; 
     40  vstringtok(parts, label, "."); 
     41  string ret; 
     42  ret.reserve(label.size()+4); 
     43  for(parts_t::const_iterator i=parts.begin(); i!=parts.end(); ++i) { 
     44    ret.append(1, (char)(i->second - i->first)); 
     45    ret.append(label.c_str() + i->first, i->second - i->first); 
     46  } 
     47  ret.append(1,0); 
     48  return ret; 
     49} 
     50 
     51void simpleExpandTo(const string& label, unsigned int frompos, string& ret) 
     52{ 
     53  unsigned int labellen=0; 
     54  while((labellen=label.at(frompos++))) { 
     55    ret.append(label.c_str()+frompos, labellen); 
     56    ret.append(1,'.'); 
     57    frompos+=labellen; 
     58  } 
     59} 
     60 
    3661DNSResourceRecord String2DNSRR(const string& qname, const QType& qt, const string& serial, uint32_t ttd) 
    3762{ 
    38   //  cerr<<"Serial: '"<<makeHexDump(serial)<<"'"<<endl; 
    39   shared_ptr<DNSRecordContent> regen=DNSRecordContent::unserialize(qname,qt.getCode(), serial); 
    4063  DNSResourceRecord rr; 
    41   rr.qname=regen->label; 
    4264  rr.ttl=ttd;  
    43   rr.content=regen->getZoneRepresentation(); 
    44   rr.qtype=regen->d_qtype; 
    45  
    46   rr.content.reserve(0); 
    47   rr.qname.reserve(0); 
     65  rr.qtype=qt; 
     66  rr.qname=qname; 
     67 
     68  if(rr.qtype.getCode()==QType::A) { 
     69    uint32_t ip; 
     70    memcpy((char*)&ip, serial.c_str(), 4); 
     71    rr.content=U32ToIP(ntohl(ip)); 
     72  } 
     73  else if(rr.qtype.getCode()==QType::CNAME || rr.qtype.getCode()==QType::NS || rr.qtype.getCode()==QType::PTR) { 
     74    unsigned int frompos=0; 
     75    unsigned char labellen; 
     76 
     77    while((labellen=serial.at(frompos++))) { 
     78      if((labellen & 0xc0) == 0xc0) { 
     79        string encoded=simpleCompress(qname); 
     80        uint16_t offset=256*(labellen & ~0xc0) + (unsigned int)serial.at(frompos++) - sizeof(dnsheader)-5; 
     81 
     82        simpleExpandTo(encoded, offset, rr.content); 
     83        //      cerr<<"Oops, fallback, content so far: '"<<rr.content<<"', offset: "<<offset<<", '"<<qname<<"', "<<qt.getName()<<"\n"; 
     84        break; 
     85      } 
     86      rr.content.append(serial.c_str()+frompos, labellen); 
     87      frompos+=labellen; 
     88      rr.content.append(1,'.'); 
     89    } 
     90  } 
     91  else { 
     92    shared_ptr<DNSRecordContent> regen=DNSRecordContent::unserialize(qname,qt.getCode(), serial); 
     93    rr.content=regen->getZoneRepresentation(); 
     94  } 
     95 
     96  //  rr.content.reserve(0); 
     97  //  rr.qname.reserve(0); 
    4898  return rr; 
    4999} 
     
    51101string DNSRR2String(const DNSResourceRecord& rr) 
    52102{ 
    53   vector<uint8_t> packet; 
    54    
    55103  uint16_t type=rr.qtype.getCode(); 
    56   shared_ptr<DNSRecordContent> drc(DNSRecordContent::mastermake(type, 1, rr.content)); 
    57   string ret=drc->serialize(rr.qname); 
     104 
     105  if(type==QType::A) { 
     106    uint32_t ip; 
     107    IpToU32(rr.content, &ip); 
     108    return string((char*)&ip, 4); 
     109  } 
     110  else if(type==QType::NS) { 
     111    NSRecordContent ar(rr.content); 
     112    return ar.serialize(rr.qname); 
     113  } 
     114  else if(type==QType::CNAME) { 
     115    CNAMERecordContent ar(rr.content); 
     116    return ar.serialize(rr.qname); 
     117  } 
     118  else { 
     119    string ret; 
     120    shared_ptr<DNSRecordContent> drc(DNSRecordContent::mastermake(type, 1, rr.content)); 
     121    ret=drc->serialize(rr.qname); 
    58122  //  cerr<<"stored '"<<rr.qname<<" '"<<rr.qtype.getName()<<"' '"<<rr.content<<"' as "<<ret.size()<<" bytes"<<endl; 
    59   return ret; 
     123    return ret; 
     124  } 
    60125} 
    61126