Changeset 996

Show
Ignore:
Timestamp:
03/25/07 20:11:19 (6 years ago)
Author:
ahu
Message:

fix TXT storage and processing model. Each TXT record must now be in "quotes", and for records that need it, we support multiple TXT records which are then all parsed or sent out

Location:
trunk/pdns/pdns
Files:
8 modified

Legend:

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

    r972 r996  
    359359} 
    360360 
    361 string PacketReader::getText() 
     361static string txtEscape(const string &name) 
     362{ 
     363  string ret; 
     364 
     365  for(string::const_iterator i=name.begin();i!=name.end();++i) 
     366    if(*i=='"' || *i=='\\'){ 
     367      ret += '\\'; 
     368      ret += *i; 
     369    } 
     370    else 
     371      ret += *i; 
     372  return ret; 
     373} 
     374 
     375// exceptions thrown here do not result in logging in the main pdns auth server - just so you know! 
     376string PacketReader::getText(bool multi) 
    362377{ 
    363378  string ret; 
    364379  ret.reserve(40); 
    365  
    366   unsigned char labellen=d_content.at(d_pos++); 
    367   ret.append(&d_content.at(d_pos), &d_content.at(d_pos+labellen-1)+1); // the end is one beyond the packet 
    368   d_pos+=labellen; 
    369   return ret; 
    370 } 
     380  while(d_pos < d_startrecordpos + d_recordlen ) { 
     381    if(!ret.empty()) { 
     382      ret.append(1,' '); 
     383    } 
     384    unsigned char labellen=d_content.at(d_pos++); 
     385     
     386    ret.append(1,'"'); 
     387    string val(&d_content.at(d_pos), &d_content.at(d_pos+labellen-1)+1); 
     388     
     389    ret.append(txtEscape(val)); // the end is one beyond the packet 
     390    ret.append(1,'"'); 
     391    d_pos+=labellen; 
     392    if(!multi) 
     393      break; 
     394  } 
     395 
     396  return ret; 
     397} 
     398 
    371399 
    372400void PacketReader::getLabelFromContent(const vector<uint8_t>& content, uint16_t& frompos, string& ret, int recurs)  
  • trunk/pdns/pdns/dnsparser.hh

    r972 r996  
    110110  } 
    111111 
    112   void xfrText(string &text) 
    113   { 
    114     text=getText(); 
     112  void xfrText(string &text, bool multi=false) 
     113  { 
     114    text=getText(multi); 
    115115  } 
    116116 
     
    126126 
    127127  string getLabel(unsigned int recurs=0); 
    128   string getText(); 
     128  string getText(bool multi); 
    129129 
    130130  uint16_t d_pos; 
  • trunk/pdns/pdns/dnsrecords.cc

    r978 r996  
    11/* 
    22    PowerDNS Versatile Database Driven Nameserver 
    3     Copyright (C) 2005 - 2006  PowerDNS.COM BV 
     3    Copyright (C) 2005 - 2007  PowerDNS.COM BV 
    44 
    55    This program is free software; you can redistribute it and/or modify 
     
    178178boilerplate_conv(PTR, ns_t_ptr, conv.xfrLabel(d_content, true)); 
    179179boilerplate_conv(CNAME, ns_t_cname, conv.xfrLabel(d_content, true)); 
    180 boilerplate_conv(TXT, ns_t_txt, conv.xfrText(d_text)); 
    181 boilerplate_conv(SPF, 99, conv.xfrText(d_text)); 
     180boilerplate_conv(TXT, ns_t_txt, conv.xfrText(d_text, true)); 
     181boilerplate_conv(SPF, 99, conv.xfrText(d_text, true)); 
    182182boilerplate_conv(HINFO, ns_t_hinfo,  conv.xfrText(d_cpu);   conv.xfrText(d_host)); 
    183183 
  • trunk/pdns/pdns/dnswriter.cc

    r962 r996  
    22#include "misc.hh" 
    33#include "dnsparser.hh" 
     4#include <boost/tokenizer.hpp> 
    45 
    56DNSPacketWriter::DNSPacketWriter(vector<uint8_t>& content, const string& qname, uint16_t  qtype, uint16_t qclass, uint8_t opcode) 
     
    116117} 
    117118 
    118 void DNSPacketWriter::xfrText(const string& text) 
    119 { 
    120   d_record.push_back(text.length()); 
    121   const uint8_t* ptr=(uint8_t*)(text.c_str()); 
    122   d_record.insert(d_record.end(), ptr, ptr+text.size()); 
     119void DNSPacketWriter::xfrText(const string& text, bool) 
     120{ 
     121  escaped_list_separator<char> sep('\\', ' ' , '"'); 
     122  tokenizer<escaped_list_separator<char> > tok(text, sep); 
     123 
     124  tokenizer<escaped_list_separator<char> >::iterator beg=tok.begin(); 
     125 
     126  if(beg==tok.end()) { 
     127    d_record.push_back(0); 
     128  } 
     129  else  
     130    for(; beg!=tok.end(); ++beg){ 
     131      d_record.push_back(beg->length()); 
     132      const uint8_t* ptr=(uint8_t*)(beg->c_str()); 
     133      d_record.insert(d_record.end(), ptr, ptr+beg->length()); 
     134    } 
    123135} 
    124136 
  • trunk/pdns/pdns/dnswriter.hh

    r962 r996  
    8484 
    8585  void xfrLabel(const string& label, bool compress=false); 
    86   void xfrText(const string& text); 
     86  void xfrText(const string& text, bool multi=false); 
    8787  void xfrBlob(const string& blob); 
    8888  void xfrHexBlob(const string& blob); 
  • trunk/pdns/pdns/rcpgenerator.cc

    r926 r996  
    207207} 
    208208 
    209  
    210 void RecordTextReader::xfrText(string& val) 
    211 { 
    212   skipSpaces(); 
    213   if(d_string[d_pos]!='"') 
    214     throw RecordTextException("Data field in DNS should start with quote (\") at position "+lexical_cast<string>(d_pos)+" of '"+d_string+"'"); 
    215  
     209void RecordTextReader::xfrText(string& val, bool multi) 
     210{ 
    216211  val.clear(); 
    217212  val.reserve(d_end - d_pos); 
    218    
    219   while(++d_pos < d_end && d_string[d_pos]!='"') { 
    220     if(d_string[d_pos]=='\\' && d_pos+1!=d_end) { 
    221       ++d_pos; 
     213 
     214  while(d_pos != d_end) { 
     215    if(!val.empty()) 
     216      val.append(1, ' '); 
     217 
     218    skipSpaces(); 
     219    if(d_string[d_pos]!='"') 
     220      throw RecordTextException("Data field in DNS should start with quote (\") at position "+lexical_cast<string>(d_pos)+" of '"+d_string+"'"); 
     221 
     222    val.append(1, '"'); 
     223    while(++d_pos < d_end && d_string[d_pos]!='"') { 
     224      if(d_string[d_pos]=='\\' && d_pos+1!=d_end) { 
     225        val.append(1, d_string[d_pos++]); 
     226      } 
     227      val.append(1, d_string[d_pos]); 
    222228    } 
    223     val.append(1, d_string[d_pos]); 
    224   } 
    225   if(d_pos == d_end) 
    226     throw RecordTextException("Data field in DNS should end on a quote (\") in '"+d_string+"'"); 
    227   d_pos++; 
     229    val.append(1,'"'); 
     230    if(d_pos == d_end) 
     231      throw RecordTextException("Data field in DNS should end on a quote (\") in '"+d_string+"'"); 
     232    d_pos++; 
     233    if(!multi) 
     234      break; 
     235  } 
    228236} 
    229237 
     
    384392} 
    385393 
    386 void RecordTextWriter::xfrText(const string& val) 
    387 { 
    388   if(!d_string.empty()) 
    389     d_string.append(1,' '); 
    390   d_string.append(1,'"'); 
    391  
    392   if(val.find_first_of("\\\"") == string::npos) 
    393     d_string+=val; 
    394   else { 
    395     string::size_type end=val.size(); 
    396      
    397     for(string::size_type pos=0; pos < end; ++pos) { 
    398       if(val[pos]=='\'' || val[pos]=='"') 
    399         d_string.append(1,'\\'); 
    400       d_string.append(1, val[pos]); 
    401     } 
    402   } 
    403  
    404   d_string.append(1,'"'); 
     394void RecordTextWriter::xfrText(const string& val, bool multi) 
     395{ 
     396  if(!d_string.empty()) 
     397    d_string.append(1,' '); 
     398 
     399  d_string.append(val); 
    405400} 
    406401 
  • trunk/pdns/pdns/rcpgenerator.hh

    r802 r996  
    5151 
    5252  void xfrLabel(string& val, bool compress=false); 
    53   void xfrText(string& val); 
     53  void xfrText(string& val, bool multi=false); 
    5454  void xfrHexBlob(string& val); 
    5555  void xfrBlob(string& val); 
     
    7676  void xfrType(const uint16_t& val); 
    7777  void xfrLabel(const string& val, bool compress=false); 
    78   void xfrText(const string& val); 
     78  void xfrText(const string& val, bool multi=false); 
    7979  void xfrBlob(const string& val); 
    8080  void xfrHexBlob(const string& val); 
  • trunk/pdns/pdns/zoneparser-tng.cc

    r989 r996  
    281281    } 
    282282    catch(...) { 
    283       cerr<<"Oops, this doesn't look like a qtype, stopping loop\n"; 
    284       break; 
     283      throw runtime_error("Parsing zone content line: '"+nextpart+"' doesn't look like a qtype, stopping loop"); 
    285284    } 
    286285  }