]> granicus.if.org Git - pdns/commitdiff
add test case for domains with more than 34 parts which our static vector can't compr...
authorbert hubert <bert.hubert@netherlabs.nl>
Sat, 27 Aug 2016 12:53:54 +0000 (14:53 +0200)
committerbert hubert <bert.hubert@netherlabs.nl>
Sat, 27 Aug 2016 12:53:54 +0000 (14:53 +0200)
pdns/dnsrecords.hh
pdns/dnswriter.cc
pdns/test-dnsname_cc.cc

index 47c42573cdd6fdd1b9a8ea2e6bc366936cd2d33a..e00a41ef68eb95656e21cb26b8383a1e3e828041 100644 (file)
@@ -189,7 +189,7 @@ class PTRRecordContent : public DNSRecordContent
 {
 public:
   includeboilerplate(PTR)
-
+  explicit PTRRecordContent(const DNSName& content) : d_content(content){}
 private:
   DNSName d_content;
 };
index fb90cc1454b9cc287914d85d32fcfefbef4c8252..a369a8f60a7dee1b615d9e51bd4a43c137b20a2a 100644 (file)
@@ -199,11 +199,18 @@ uint16_t DNSPacketWriter::lookupName(const DNSName& name, uint16_t* matchLen)
   *matchLen=0;
   boost::container::static_vector<uint16_t, 34> nvect, pvect;
 
-  for(auto riter= raw.cbegin(); riter < raw.cend(); ) {
-    if(!*riter)
-      break;
-    nvect.push_back(riter - raw.cbegin());
-    riter+=*riter+1;
+  try {
+    for(auto riter= raw.cbegin(); riter < raw.cend(); ) {
+      if(!*riter)
+        break;
+      nvect.push_back(riter - raw.cbegin());
+      riter+=*riter+1;
+    }
+  }
+  catch(std::bad_alloc& ba) {
+    if(l_verbose)
+      cout<<"Domain "<<name<<" too large to compress"<<endl;
+    return 0;
   }
   
   if(l_verbose) {
@@ -226,24 +233,29 @@ uint16_t DNSPacketWriter::lookupName(const DNSName& name, uint16_t* matchLen)
     }
     // memcmp here makes things _slower_
     pvect.clear();
-    for(auto iter = d_content.cbegin() + p; iter < d_content.cend();) {
-
-      uint8_t c=*iter;
-      if(l_verbose)
-        cout<<"Found label length: "<<(int)c<<endl;
-      if(c & 0xc0) {
-
-        uint16_t npos = 0x100*(c & (~0xc0)) + *++iter;
-        iter = d_content.begin() + npos;
+    try {
+      for(auto iter = d_content.cbegin() + p; iter < d_content.cend();) {
+        uint8_t c=*iter;
         if(l_verbose)
-          cout<<"Is compressed label to newpos "<<npos<<", going there"<<endl;
-        // check against going forward here
-        continue;
+          cout<<"Found label length: "<<(int)c<<endl;
+        if(c & 0xc0) {
+          uint16_t npos = 0x100*(c & (~0xc0)) + *++iter;
+          iter = d_content.begin() + npos;
+          if(l_verbose)
+            cout<<"Is compressed label to newpos "<<npos<<", going there"<<endl;
+          // check against going forward here
+          continue;
+        }
+        if(!c)
+          break;
+        pvect.push_back(iter - d_content.cbegin());
+        iter+=*iter+1;
       }
-      if(!c)
-        break;
-      pvect.push_back(iter - d_content.cbegin());
-      iter+=*iter+1;
+    }
+    catch(std::bad_alloc& ba) {
+      if(l_verbose)
+        cout<<"Domain "<<name<<" too large to compress"<<endl;
+      continue;
     }
     if(l_verbose) {
       cout<<"Packet vector: "<<endl;
@@ -280,7 +292,6 @@ uint16_t DNSPacketWriter::lookupName(const DNSName& name, uint16_t* matchLen)
   }
   return bestpos;
 }
-
 // this is the absolute hottest function in the pdns recursor
 void DNSPacketWriter::xfrName(const DNSName& name, bool compress, bool)
 {
index 412b0211aa0ce1afb99efc2f6512f4c88390728e..4995ee45e87f3342719f32d1135c0eb4a04c450b 100644 (file)
@@ -286,6 +286,30 @@ BOOST_AUTO_TEST_CASE(test_packetCompress) {
 
 }
 
+BOOST_AUTO_TEST_CASE(test_packetCompressLong) {
+  reportBasicTypes();
+  vector<unsigned char> packet;
+  DNSName loopback("1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa");
+  DNSPacketWriter dpw(packet, loopback, QType::PTR);
+
+  dpw.startRecord(loopback, QType::PTR);
+  PTRRecordContent prc(DNSName("localhost"));
+  prc.toPacket(dpw);
+  dpw.commit();
+  DNSName roundtrip((char*)&packet[0], packet.size(), 12, false);
+  BOOST_CHECK_EQUAL(loopback,roundtrip);
+  
+  packet.clear();
+  DNSName longer("1.2.3.4.5.6.7.8.1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa");
+  DNSPacketWriter dpw2(packet, longer, QType::PTR);
+
+  dpw2.startRecord(DNSName("a.b.c.d.e")+longer, QType::PTR);
+  PTRRecordContent prc2(DNSName("localhost"));
+  prc2.toPacket(dpw2);
+  dpw2.commit();
+
+}
+