[Pdns-dev] Truncated long TXT records + patch

David Leadbeater dgl at dgl.cx
Sun Dec 10 06:25:18 CET 2006


pdns-recursor seems to drop the last parts of TXT records which have
multiple character strings. (I'm unrelated to the person who
reported this as #111 on trac BTW).

There was also some odd behaviour with TXT records of 0 length, they
were passed through the first time, but once cached it seems to have problems:

   DNS parser error: 2.t.dg.cx., Error parsing packet of 39 bytes (rd=0), out of bounds: vector::_M_range_check

Patch attached.

David
-------------- next part --------------
Index: pdns/dnswriter.cc
===================================================================
--- pdns/dnswriter.cc	(revision 924)
+++ pdns/dnswriter.cc	(working copy)
@@ -109,9 +109,17 @@
 
 void DNSPacketWriter::xfrText(const string& text)
 {
-  d_record.push_back(text.length());
-  const uint8_t* ptr=(uint8_t*)(text.c_str());
-  d_record.insert(d_record.end(), ptr, ptr+text.size());
+  string::size_type txtpos = 0, txtlen = text.length();
+  do {
+    unsigned len = txtlen - txtpos > 255 ? 255 : txtlen - txtpos;
+    d_record.push_back(len);
+
+    if(len) {
+      const uint8_t* ptr=reinterpret_cast<const uint8_t*>(&text.at(txtpos));
+      d_record.insert(d_record.end(), ptr, ptr+len);
+      txtpos += len;
+    }
+  } while(txtlen && txtpos < txtlen);
 }
 
 // this is the absolute hottest function in the pdns recursor
Index: pdns/dnsparser.cc
===================================================================
--- pdns/dnsparser.cc	(revision 924)
+++ pdns/dnsparser.cc	(working copy)
@@ -363,9 +363,14 @@
   string ret;
   ret.reserve(40);
 
-  unsigned char labellen=d_content.at(d_pos++);
-  ret.append(&d_content.at(d_pos), &d_content.at(d_pos+labellen-1)+1); // the end is one beyond the packet
-  d_pos+=labellen;
+  unsigned char labellen;
+  do {
+    labellen=d_content.at(d_pos++);
+    if(labellen)
+      ret.append(&d_content.at(d_pos), &d_content.at(d_pos+labellen-1)+1); // the end is one beyond the packet
+    d_pos+=labellen;
+  } while(labellen && (d_pos - d_startrecordpos < d_recordlen));
+
   return ret;
 }
 
Index: pdns/dnspacket.cc
===================================================================
--- pdns/dnspacket.cc	(revision 924)
+++ pdns/dnspacket.cc	(working copy)
@@ -804,9 +804,15 @@
  makeHeader(p, qtype, ttl);
  string piece3;
  piece3.reserve(txt.length()+1);
- piece3.append(1,txt.length());
- piece3.append(txt);
 
+ string::size_type txtpos = 0, txtlen = txt.length();
+ do {
+   unsigned len = txtlen - txtpos > 255 ? 255 : txtlen - txtpos;
+   piece3.append(1,len);
+   piece3.append(txt, txtpos, len);
+   txtpos += len;
+ } while(txtlen && txtpos < txtlen);
+
  p[8]=piece3.length()/256;;
  p[9]=piece3.length()%256;
 


More information about the Pdns-dev mailing list