Parcourir la source

[trac117] shared the "from wire" bitmap operation between NSEC and NSEC3

this fixed various bugs in the NSEC3 implementation.
also added tests for NSEC3.
JINMEI Tatuya il y a 14 ans
Parent
commit
e935dae553

+ 3 - 0
src/lib/dns/Makefile.am

@@ -88,6 +88,8 @@ libdns___la_SOURCES += tsigkey.h tsigkey.cc
 
 nodist_libdns___la_SOURCES = rdataclass.cc rrclass.h rrtype.h
 nodist_libdns___la_SOURCES += rrparamregistry.cc
+nodist_libdns___la_SOURCES += rdata/generic/detail/nsec_bitmap.h
+nodist_libdns___la_SOURCES += rdata/generic/detail/nsec_bitmap.cc
 
 rrclass.h: rrclass-placeholder.h
 rrtype.h: rrtype-placeholder.h
@@ -117,5 +119,6 @@ libdns___include_HEADERS = \
 	tsigkey.h
 # Purposely not installing these headers:
 # util/*.h: used only internally, and not actually DNS specific
+# rdata/*/detail/*.h: these are internal use only
 # rrclass-placeholder.h
 # rrtype-placeholder.h

+ 76 - 0
src/lib/dns/rdata/generic/detail/nsec_bitmap.cc

@@ -0,0 +1,76 @@
+// Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <stdint.h>
+
+#include <vector>
+
+#include <dns/exceptions.h>
+
+using namespace std;
+
+namespace isc {
+namespace dns {
+namespace rdata {
+namespace generic {
+namespace detail {
+namespace nsec {
+void
+buildRRTypeBitmap(const char* const rrtype_name,
+                  const size_t total_len, vector<uint8_t>& typebits)
+{
+    int len = 0;
+    bool first = true;
+    unsigned int block, lastblock = 0;
+    for (int i = 0; i < total_len; i += len) {
+        if (i + 2 > total_len) {
+            isc_throw(DNSMessageFORMERR, rrtype_name <<
+                      " RDATA from wire: incomplete bit map field");
+        }
+        block = typebits[i];
+        len = typebits[i + 1];
+        // Check that bitmap window blocks are in the correct order.
+        if (!first && block <= lastblock) {
+            isc_throw(DNSMessageFORMERR, rrtype_name <<
+                      " RDATA from wire: Disordered window blocks found: "
+                      << lastblock << " then " << block);
+        }
+        // Check for legal length
+        if (len < 1 || len > 32) {
+            isc_throw(DNSMessageFORMERR, rrtype_name <<
+                      " RDATA from wire: Invalid bitmap length: " << len);
+        }
+        // Check for overflow.
+        i += 2;
+        if (i + len > total_len) {
+            isc_throw(DNSMessageFORMERR, rrtype_name <<
+                      " RDATA from wire: bitmap length too large: " << len);
+                      
+        }
+        // The last octet of the bitmap must be non zero.
+        if (typebits[i + len - 1] == 0) {
+            isc_throw(DNSMessageFORMERR, rrtype_name <<
+                      " RDATA from wire: bitmap ending an all-zero byte");
+        }
+
+        lastblock = block;
+        first = false;
+    }
+}
+}
+}
+}
+}
+}
+}

+ 38 - 0
src/lib/dns/rdata/generic/detail/nsec_bitmap.h

@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2011  Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <stdint.h>
+
+#include <vector>
+
+namespace isc {
+namespace dns {
+namespace rdata {
+namespace generic {
+namespace detail {
+namespace nsec {
+void buildRRTypeBitmap(const char* const rrtype_name,
+                       const size_t total_len, std::vector<uint8_t>& typebits);
+}
+}
+}
+}
+}
+}
+
+// Local Variables: 
+// mode: c++
+// End: 

+ 10 - 20
src/lib/dns/rdata/generic/nsec3_50.cc

@@ -30,11 +30,13 @@
 #include <dns/rrttl.h>
 #include <dns/rdata.h>
 #include <dns/rdataclass.h>
+#include <dns/rdata/generic/detail/nsec_bitmap.h>
 
 #include <stdio.h>
 #include <time.h>
 
 using namespace std;
+using namespace isc::dns::rdata::generic::detail::nsec;
 
 // BEGIN_ISC_NAMESPACE
 // BEGIN_RDATA_NAMESPACE
@@ -126,17 +128,18 @@ NSEC3::NSEC3(const string& nsec3_str) :
 }
 
 NSEC3::NSEC3(InputBuffer& buffer, size_t rdata_len) {
+    // NSEC3 RR must have at least 5 octets:
+    // hash(1), flags(1), iteration(2), saltlen(1)
     if (rdata_len < 5) {
         isc_throw(InvalidRdataLength, "NSEC3 too short");
     }
 
-    uint8_t hashalg = buffer.readUint8();
-    uint8_t flags = buffer.readUint8();
-    uint16_t iterations = buffer.readUint16();
-    rdata_len -= 4;
+    const uint8_t hashalg = buffer.readUint8();
+    const uint8_t flags = buffer.readUint8();
+    const uint16_t iterations = buffer.readUint16();
 
-    uint8_t saltlen = buffer.readUint8();
-    --rdata_len;
+    const uint8_t saltlen = buffer.readUint8();
+    rdata_len -= 5;
 
     if (rdata_len < saltlen) {
         isc_throw(InvalidRdataLength, "NSEC3 salt too short");
@@ -163,20 +166,7 @@ NSEC3::NSEC3(InputBuffer& buffer, size_t rdata_len) {
 
     vector<uint8_t> typebits(rdata_len);
     buffer.readData(&typebits[0], rdata_len);
-
-    int len = 0;
-    for (int i = 0; i < typebits.size(); i += len) {
-        if (i + 2 > typebits.size()) {
-            isc_throw(DNSMessageFORMERR, "Invalid rdata: "
-                                         "bad NSEC3 type bitmap");
-        }
-        len = typebits[i + 1];
-        if (len > 31) {
-            isc_throw(DNSMessageFORMERR, "Invalid rdata: "
-                                         "bad NSEC3 type bitmap");
-        }
-        i += 2;
-    }
+    buildRRTypeBitmap("NSEC3", rdata_len, typebits);
 
     impl_ = new NSEC3Impl(hashalg, flags, iterations, salt, next, typebits);
 }

+ 3 - 37
src/lib/dns/rdata/generic/nsec_47.cc

@@ -26,11 +26,13 @@
 #include <dns/rrttl.h>
 #include <dns/rdata.h>
 #include <dns/rdataclass.h>
+#include <dns/rdata/generic/detail/nsec_bitmap.h>
 
 #include <stdio.h>
 #include <time.h>
 
 using namespace std;
+using namespace isc::dns::rdata::generic::detail::nsec;
 
 // BEGIN_ISC_NAMESPACE
 // BEGIN_RDATA_NAMESPACE
@@ -103,43 +105,7 @@ NSEC::NSEC(InputBuffer& buffer, size_t rdata_len) {
 
     vector<uint8_t> typebits(rdata_len);
     buffer.readData(&typebits[0], rdata_len);
-
-    int len = 0;
-    bool first = true;
-    unsigned int block, lastblock = 0;
-    for (int i = 0; i < rdata_len; i += len) {
-        if (i + 2 > rdata_len) {
-            isc_throw(DNSMessageFORMERR, "NSEC RDATA from wire: "
-                      "incomplete bit map field");
-        }
-        block = typebits[i];
-        len = typebits[i + 1];
-        // Check that bitmap window blocks are in the correct order.
-        if (!first && block <= lastblock) {
-            isc_throw(DNSMessageFORMERR, "NSEC RDATA from wire: Disordered "
-                      "window blocks found: " << lastblock <<
-                      " then " << block);
-        }
-        // Check for legal length
-        if (len < 1 || len > 32) {
-            isc_throw(DNSMessageFORMERR, "NSEC RDATA from wire: Invalid bitmap "
-                      "length: " << len);
-        }
-        // Check for overflow.
-        i += 2;
-        if (i + len > rdata_len) {
-            isc_throw(DNSMessageFORMERR, "NSEC RDATA from wire: bitmap length "
-                      "too large: " << len);
-        }
-        // The last octet of the bitmap must be non zero.
-        if (typebits[i + len - 1] == 0) {
-            isc_throw(DNSMessageFORMERR, "NSEC RDATA from wire: bitmap ending "
-                      "an all-zero byte");
-        }
-
-        lastblock = block;
-        first = false;
-    }
+    buildRRTypeBitmap("NSEC", rdata_len, typebits);
 
     impl_ = new NSECImpl(nextname, typebits);
 }

+ 22 - 23
src/lib/dns/tests/rdata_nsec3_unittest.cc

@@ -95,33 +95,32 @@ TEST_F(Rdata_NSEC3_Test, createFromWire) {
                                       "rdata_nsec3_fromWire2"),
                  InvalidRdataLength);
 
-    // Invalid type bits
+    // These tests are the same as NSEC tests.  See the NSEC cases for
+    // details.
     EXPECT_THROW(rdataFactoryFromFile(RRType::NSEC3(), RRClass::IN(),
                                       "rdata_nsec3_fromWire3"),
                  DNSMessageFORMERR);
 
-    try {
-    rdataFactoryFromFile(RRType::NSEC3(), RRClass::IN(),
-                         "rdata_nsec3_fromWire4.wire");
-    rdataFactoryFromFile(RRType::NSEC3(), RRClass::IN(),
-                         "rdata_nsec3_fromWire5.wire");
-
-    rdataFactoryFromFile(RRType::NSEC3(), RRClass::IN(),
-                         "rdata_nsec3_fromWire7.wire");
-    rdataFactoryFromFile(RRType::NSEC3(), RRClass::IN(),
-                         "rdata_nsec3_fromWire8.wire");
-
-    // the following tests currently fail.
-    rdataFactoryFromFile(RRType::NSEC3(), RRClass::IN(),
-                         "rdata_nsec3_fromWire6.wire");
-    rdataFactoryFromFile(RRType::NSEC3(), RRClass::IN(),
-                         "rdata_nsec3_fromWire9.wire");
-    rdataFactoryFromFile(RRType::NSEC3(), RRClass::IN(),
-                         "rdata_nsec3_fromWire10.wire");
-    } catch (const std::exception& ex) {
-        cout << "got exception: " << ex.what() << endl;
-    }
-
+    EXPECT_THROW(rdataFactoryFromFile(RRType::NSEC3(), RRClass::IN(),
+                                      "rdata_nsec3_fromWire4.wire"),
+                 DNSMessageFORMERR);
+    EXPECT_THROW(rdataFactoryFromFile(RRType::NSEC3(), RRClass::IN(),
+                                      "rdata_nsec3_fromWire5.wire"),
+                 DNSMessageFORMERR);
+    EXPECT_THROW(rdataFactoryFromFile(RRType::NSEC3(), RRClass::IN(),
+                                      "rdata_nsec3_fromWire6.wire"),
+                 DNSMessageFORMERR);
+    EXPECT_NO_THROW(rdataFactoryFromFile(RRType::NSEC3(), RRClass::IN(),
+                                         "rdata_nsec3_fromWire7.wire"));
+    EXPECT_THROW(rdataFactoryFromFile(RRType::NSEC3(), RRClass::IN(),
+                                      "rdata_nsec3_fromWire8.wire"),
+                 DNSMessageFORMERR);
+    EXPECT_THROW(rdataFactoryFromFile(RRType::NSEC3(), RRClass::IN(),
+                                      "rdata_nsec3_fromWire9.wire"),
+                 DNSMessageFORMERR);
+    EXPECT_THROW(rdataFactoryFromFile(RRType::NSEC3(), RRClass::IN(),
+                                      "rdata_nsec3_fromWire10.wire"),
+                 DNSMessageFORMERR);
 }
 
 TEST_F(Rdata_NSEC3_Test, toWireRenderer) {

+ 8 - 0
src/lib/dns/tests/testdata/Makefile.am

@@ -8,6 +8,10 @@ BUILT_SOURCES += rdata_nsec_fromWire4.wire rdata_nsec_fromWire5.wire
 BUILT_SOURCES += rdata_nsec_fromWire6.wire rdata_nsec_fromWire7.wire
 BUILT_SOURCES += rdata_nsec_fromWire8.wire rdata_nsec_fromWire9.wire
 BUILT_SOURCES += rdata_nsec_fromWire10.wire
+BUILT_SOURCES += rdata_nsec3_fromWire4.wire rdata_nsec3_fromWire5.wire
+BUILT_SOURCES += rdata_nsec3_fromWire6.wire rdata_nsec3_fromWire7.wire
+BUILT_SOURCES += rdata_nsec3_fromWire8.wire rdata_nsec3_fromWire9.wire
+BUILT_SOURCES += rdata_nsec3_fromWire10.wire
 BUILT_SOURCES += rdata_rrsig_fromWire2.wire
 BUILT_SOURCES += rdata_soa_toWireUncompressed.wire
 BUILT_SOURCES +=  rdata_txt_fromWire2.wire rdata_txt_fromWire3.wire
@@ -51,6 +55,10 @@ EXTRA_DIST += rdata_nsec_fromWire4.spec rdata_nsec_fromWire5.spec
 EXTRA_DIST += rdata_nsec_fromWire6.spec rdata_nsec_fromWire7.spec
 EXTRA_DIST += rdata_nsec_fromWire8.spec rdata_nsec_fromWire9.spec
 EXTRA_DIST += rdata_nsec_fromWire10.spec
+EXTRA_DIST += rdata_nsec3_fromWire4.spec rdata_nsec3_fromWire5.spec
+EXTRA_DIST += rdata_nsec3_fromWire6.spec rdata_nsec3_fromWire7.spec
+EXTRA_DIST += rdata_nsec3_fromWire8.spec rdata_nsec3_fromWire9.spec
+EXTRA_DIST += rdata_nsec3_fromWire10.spec
 EXTRA_DIST += rdata_opt_fromWire rdata_rrsig_fromWire1
 EXTRA_DIST += rdata_rrsig_fromWire2.spec
 EXTRA_DIST += rdata_soa_fromWire rdata_soa_toWireUncompressed.spec