Changeset 510

Show
Ignore:
Timestamp:
10/08/05 18:12:49 (8 years ago)
Author:
ahu
Message:

fix double-srv regression test error
add label compression to dnswriter, make parser, string parser, sting generator ignore that
make mx, cname, ptr, ns, soa do label compression
fix string parser to not add a trailing . when no zone is configured for expansion
add some comments to DNSPacketWriter
add dnspbench to benchmark and test the new infrastructure away from sdig

new infra appears to generate 100.000 simple packets/s on 1.4GHz

remove a warning in misc.cc

Location:
trunk/pdns
Files:
1 added
10 modified

Legend:

Unmodified
Added
Removed
  • trunk/pdns/pdns/Makefile.am

    r503 r510  
    1919bin_PROGRAMS = pdns_control  dnswasher dnsreplay  
    2020 
    21 EXTRA_PROGRAMS=pdns_recursor sdig pdns_control qgen dnsscope dnsreplay_mindex 
     21EXTRA_PROGRAMS=pdns_recursor sdig dnspbench pdns_control qgen dnsscope dnsreplay_mindex 
    2222 
    2323pdns_server_SOURCES=dnspacket.cc nameserver.cc tcpreceiver.hh \ 
     
    4545sdig_SOURCES=sdig.cc sstuff.hh dnsparser.cc dnsparser.hh dnsrecords.cc dnswriter.cc dnswriter.hh \ 
    4646        misc.cc misc.hh rcpgenerator.cc rcpgenerator.hh base64.cc base64.hh 
     47 
     48dnspbench_SOURCES=dnspbench.cc sstuff.hh dnsparser.cc dnsparser.hh dnsrecords.cc dnswriter.cc dnswriter.hh \ 
     49        misc.cc misc.hh rcpgenerator.cc rcpgenerator.hh base64.cc base64.hh 
     50 
    4751 
    4852qgen_SOURCES=resolver.cc resolver.hh misc.cc unix_utility.cc qtype.cc \ 
  • trunk/pdns/pdns/dnsparser.hh

    r507 r510  
    112112 
    113113 
    114   void xfrLabel(string &label) 
     114  void xfrLabel(string &label, bool compress=false) 
    115115  { 
    116116    label=getLabel(); 
  • trunk/pdns/pdns/dnsrecords.cc

    r508 r510  
    3232  static void report(void) 
    3333  { 
    34     regist(1,ns_t_aaaa,&make,"AAAA"); 
     34    regist(1, ns_t_aaaa, &make, "AAAA"); 
    3535  } 
    3636 
     
    152152 
    153153 
    154 boilerplate_conv(NS, ns_t_ns, conv.xfrLabel(d_content)); 
    155 boilerplate_conv(PTR, ns_t_ptr, conv.xfrLabel(d_content)); 
    156 boilerplate_conv(CNAME, ns_t_cname, conv.xfrLabel(d_content)); 
     154boilerplate_conv(NS, ns_t_ns, conv.xfrLabel(d_content, true)); 
     155boilerplate_conv(PTR, ns_t_ptr, conv.xfrLabel(d_content, true)); 
     156boilerplate_conv(CNAME, ns_t_cname, conv.xfrLabel(d_content, true)); 
    157157boilerplate_conv(TXT, ns_t_txt, conv.xfrText(d_text)); 
    158158boilerplate_conv(SPF, 99, conv.xfrText(d_text)); 
     
    175175boilerplate_conv(MX, ns_t_mx,  
    176176                 conv.xfr16BitInt(d_preference); 
    177                  conv.xfrLabel(d_mxname); 
     177                 conv.xfrLabel(d_mxname, true); 
    178178                 ) 
    179179 
     
    205205 
    206206boilerplate_conv(SOA, ns_t_soa,  
    207                  conv.xfrLabel(d_mname); 
    208                  conv.xfrLabel(d_rname); 
     207                 conv.xfrLabel(d_mname, true); 
     208                 conv.xfrLabel(d_rname, true); 
    209209                 conv.xfr32BitInt(d_st.serial); 
    210210                 conv.xfr32BitInt(d_st.refresh); 
     
    222222                 ) 
    223223 
    224  
    225  
    226224boilerplate_conv(RRSIG, 46,  
    227225                 conv.xfrType(d_type);  
     
    237235                 ) 
    238236                  
    239  
    240  
    241237boilerplate_conv(DNSKEY, 48,  
    242238                 conv.xfr16BitInt(d_flags);  
     
    246242                 ) 
    247243 
    248  
    249  
    250                   
    251  
    252244static struct Reporter 
    253245{ 
     
    256248    ARecordContent::report(); 
    257249    AAAARecordContent::report(); 
    258     //   OneLabelRecordContent::report(); 
    259250    NSRecordContent::report(); 
    260251    CNAMERecordContent::report(); 
  • trunk/pdns/pdns/dnswriter.cc

    r508 r510  
    22#include "misc.hh" 
    33#include "dnsparser.hh" 
    4  
    5 static const string EncodeDNSLabel(const string& input) 
    6 { 
    7   typedef vector<string> parts_t; 
    8   parts_t parts; 
    9   stringtok(parts,input,"."); 
    10  
    11   string ret; 
    12   for(parts_t::const_iterator i=parts.begin(); i!=parts.end(); ++i) { 
    13     ret.append(1, (char)i->length()); 
    14     ret.append(*i); 
    15   } 
    16   ret.append(1,(char)0); 
    17   return ret; 
    18 } 
    194 
    205DNSPacketWriter::DNSPacketWriter(vector<uint8_t>& content, const string& qname, uint16_t  qtype, uint16_t qclass) 
     
    3116  d_content.insert(d_content.end(), ptr, ptr + sizeof(dnsheader));     
    3217   
    33   string label=EncodeDNSLabel(d_qname); 
    34   ptr=(const uint8_t*) label.c_str(); 
    35   d_content.insert(d_content.end(), ptr, ptr + label.length());     
    36    
     18  xfrLabel(qname, false); 
     19  d_content.insert(d_content.end(), d_record.begin(), d_record.end()); 
     20  d_record.clear(); 
     21 
    3722  qtype=htons(qtype); 
    3823  ptr=(const uint8_t*)&qtype; 
     
    5944  d_recordqclass=qclass; 
    6045  d_recordttl=ttl; 
     46 
     47  d_stuff = 0;  
     48 
     49  xfrLabel(d_recordqname, true); 
     50  d_content.insert(d_content.end(), d_record.begin(), d_record.end()); 
     51  d_record.clear(); 
     52 
     53  d_stuff = sizeof(dnsrecordheader); // this is needed to get compressed label offsets right, the dnsrecordheader will be interspersed 
    6154 
    6255  dnsheader* dh=reinterpret_cast<dnsheader*>( &*d_content.begin()); 
     
    119112} 
    120113 
    121 void DNSPacketWriter::xfrLabel(const string& label) 
     114 
     115void DNSPacketWriter::xfrLabel(const string& label, bool compress) 
    122116{ 
    123   string encoded=EncodeDNSLabel(label); 
    124   const uint8_t* ptr=reinterpret_cast<const uint8_t*>(encoded.c_str()); 
     117  typedef vector<string> parts_t; 
     118  parts_t parts; 
     119  stringtok(parts, label, "."); 
     120   
     121  string enc; 
     122  unsigned int pos=d_content.size() + d_record.size() + d_stuff; // d_stuff is amount of stuff that is yet to be written out - the dnsrecordheader for example 
     123  string chopped(label); 
     124   
     125  for(parts_t::const_iterator i=parts.begin(); i!=parts.end(); ++i) { 
     126    map<string, uint16_t>::iterator li; 
     127    if(compress && (li=d_labelmap.find(chopped))!=d_labelmap.end()) {   // see if we've written out this domain before 
     128      uint16_t offset=li->second; 
     129      offset|=0xc000; 
     130      enc.append(1, (char)(offset >> 8)); 
     131      enc.append(1, (char)(offset & 0xff)); 
     132      goto out;                                 // skip trailing 0 in case of compression 
     133    } 
     134    else if(compress || d_labelmap.count(chopped)) { // if 'compress' is true, li will be equal to d_labelmap.end() 
     135      d_labelmap[chopped]=pos;                       //  if untrue, we need to count  
     136    } 
     137    enc.append(1, (char)i->length()); 
     138    enc.append(*i); 
     139    pos+=i->length()+1; 
     140    chopOff(chopped);                   // www.powerdns.com -> powerdns.com -> com  
     141  } 
     142  enc.append(1,(char)0); 
    125143 
    126   d_record.insert(d_record.end(), ptr, ptr+encoded.size()); 
     144 out:; 
     145 
     146  const uint8_t* ptr=reinterpret_cast<const uint8_t*>(enc.c_str()); 
     147  d_record.insert(d_record.end(), ptr, ptr+enc.size()); 
    127148} 
    128149 
     
    137158void DNSPacketWriter::commit() 
    138159{ 
    139   string label=EncodeDNSLabel(d_recordqname); // write out qname 
    140  
    141   const uint8_t* ptr=(const uint8_t*) label.c_str(); 
    142   d_content.insert(d_content.end(), ptr, ptr + label.length()); 
    143  
    144   // write out dnsrecordheader 
     160  // build dnsrecordheader 
    145161  struct dnsrecordheader drh; 
    146162  drh.d_type=htons(d_recordqtype); 
     
    149165  drh.d_clen=htons(d_record.size()); 
    150166 
    151   ptr=(const uint8_t*)&drh; 
     167  // and write out the header 
     168  const uint8_t* ptr=(const uint8_t*)&drh; 
    152169  d_content.insert(d_content.end(), ptr, ptr+sizeof(drh)); 
    153170 
     
    155172  d_content.insert(d_content.end(), d_record.begin(), d_record.end()); 
    156173 
    157   d_record.clear();   // clear d_record 
     174  d_record.clear();   // clear d_record, ready for next record 
    158175} 
    159176 
  • trunk/pdns/pdns/dnswriter.hh

    r508 r510  
    44#include <string> 
    55#include <vector> 
     6#include <map> 
    67#include <stdint.h> 
    78 
     
    3940  enum Place {ANSWER=1, AUTHORITY=2, ADDITIONAL=3};  
    4041 
     42  //! Start a DNS Packet in the vector passed, with question qname, qtype and qclass 
    4143  DNSPacketWriter(vector<uint8_t>& content, const string& qname, uint16_t  qtype, uint16_t qclass=1); 
     44   
     45  /** Start a new DNS record within this packet for namq, qtype, ttl, class and in the requested place. Note that packets can only be written in natural order -  
     46      ANSWER, AUTHORITY, ADDITIONAL */ 
    4247  void startRecord(const string& name, uint16_t qtype, uint32_t ttl=3600, uint16_t qclass=1, Place place=ANSWER); 
     48 
     49  /** Shorthand way to add an Opt-record, for example for EDNS0 purposes */ 
    4350  void addOpt(int udpsize, int extRCode, int Z); 
     51 
     52  /** needs to be called after the last record is added, but can be called again and again later on. Is called internally by startRecord too. 
     53      The content of the vector<> passed to the constructor is inconsistent until commit is called. 
     54   */ 
     55  void commit(); 
    4456 
    4557  void xfr32BitInt(uint32_t val); 
     
    6173  void xfr8BitInt(uint8_t val); 
    6274 
    63   void xfrLabel(const string& label); 
     75  void xfrLabel(const string& label, bool compress=false); 
    6476  void xfrText(const string& text); 
    6577  void xfrBlob(const string& blob); 
    66   void commit(); 
    67    
     78 
    6879  uint16_t d_pos; 
    6980 
     
    7788  uint16_t d_recordqtype, d_recordqclass; 
    7889  uint32_t d_recordttl; 
     90  map<string, uint16_t> d_labelmap; 
     91  uint16_t d_stuff; 
    7992}; 
    8093#endif 
  • trunk/pdns/pdns/misc.cc

    r504 r510  
    322322  char tmp[5]; 
    323323  string ret; 
    324   ret.resize(str.size()*2.2); 
     324  ret.resize((int)(str.size()*2.2)); 
    325325 
    326326  for(string::size_type n=0;n<str.size();++n) { 
  • trunk/pdns/pdns/rcpgenerator.cc

    r507 r510  
    100100 
    101101 
    102 void RecordTextReader::xfrLabel(string& val) 
     102void RecordTextReader::xfrLabel(string& val, bool) 
    103103{ 
    104104  skipSpaces(); 
     
    110110  if(val.empty()) 
    111111    val=d_zone; 
    112   else { 
     112  else if(!d_zone.empty()) { 
    113113    char last=val[val.size()-1]; 
    114114    
     
    241241 
    242242 
    243 void RecordTextWriter::xfrLabel(const string& val) 
     243void RecordTextWriter::xfrLabel(const string& val, bool) 
    244244{ 
    245245  if(!d_string.empty()) 
  • trunk/pdns/pdns/rcpgenerator.hh

    r507 r510  
    4646  void xfrTime(uint32_t& val); 
    4747 
    48   void xfrLabel(string& val); 
     48  void xfrLabel(string& val, bool compress=false); 
    4949  void xfrText(string& val); 
    5050  void xfrBlob(string& val); 
     
    7070 
    7171  void xfrType(const uint16_t& val); 
    72   void xfrLabel(const string& val); 
     72  void xfrLabel(const string& val, bool compress=false); 
    7373  void xfrText(const string& val); 
    7474  void xfrBlob(const string& val); 
  • trunk/pdns/pdns/sdig.cc

    r508 r510  
    1717  vector<uint8_t> packet; 
    1818 
     19   
    1920  DNSPacketWriter pw(packet, argv[3], DNSRecordContent::TypeToNumber(argv[4])); 
     21#if 0   
     22  static 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",  
     23                     "192.36.148.17","192.58.128.30", "193.0.14.129", "198.32.64.12", "202.12.27.33"}; 
     24  static char templ[40]; 
     25  strncpy(templ,"a.root-servers.net", sizeof(templ) - 1); 
     26  for(char c='a';c<='m';++c) { 
     27    *templ=c; 
     28     
     29    pw.startRecord("", DNSRecordContent::TypeToNumber("NS")); 
     30    NSRecordContent nrc(templ); 
     31    nrc.toPacket(pw); 
     32  } 
    2033   
    21   pw.setRD(true); 
     34  for(char c='a';c<='m';++c) { 
     35    *templ=c; 
     36     
     37    pw.startRecord(templ, DNSRecordContent::TypeToNumber("A"), 3600, 1, DNSPacketWriter::ADDITIONAL); 
     38    ARecordContent arc(ips[c-'a']); 
     39    arc.toPacket(pw); 
     40  } 
     41#endif 
     42  pw.commit(); 
    2243 
     44  //  pw.setRD(true); 
     45 
     46  
    2347  /* 
    24   pw.startRecord("enum.powerdns.com", DNSRecordContent::TypeToNumber("NSEC")); 
     48  pw.startRecord("powerdns.com", DNSRecordContent::TypeToNumber("NS")); 
     49  NSRecordContent nrc("ns1.powerdns.com"); 
     50  nrc.toPacket(pw); 
    2551 
    26   NSECRecordContent nrc("jnum.powerdns.com SRV A AAAA RRSIG"); 
    27   nrc.toPacket(pw); 
     52  pw.startRecord("powerdns.com", DNSRecordContent::TypeToNumber("NS")); 
     53  NSRecordContent nrc2("ns2.powerdns.com"); 
     54  nrc2.toPacket(pw); 
     55 
     56  //  pw.addOpt(2800, 0, 0x8000); 
    2857  */ 
    29  
    30   pw.addOpt(2800, 0, 0x8000); 
    3158 
    3259  pw.commit(); 
  • trunk/pdns/regression-tests/double-srv/expected_result

    r509 r510  
    110       _double._tcp.dc.test.com.       IN      SRV     3600    0 100 389 server1.test.com. 
     20       _double._tcp.dc.test.com.       IN      SRV     3600    1 100 389 server1.test.com. 
    23Rcode: 0, RD: 0, TC: 0, AA: 1, opcode: 0 
    34Reply to question for qname='_double._tcp.dc.test.com.', qtype=SRV