Browse Source

[1641] consolidated rrtype bitmap parser for NSEC and NSEC3.

JINMEI Tatuya 13 years ago
parent
commit
d9640f6f30

+ 48 - 3
src/lib/dns/rdata/generic/detail/nsec_bitmap.cc

@@ -12,11 +12,15 @@
 // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 // PERFORMANCE OF THIS SOFTWARE.
 
-#include <stdint.h>
-
-#include <vector>
+#include <exceptions/exceptions.h>
 
 #include <dns/exceptions.h>
+#include <dns/rdata.h>
+#include <dns/rrtype.h>
+
+#include <sstream>
+#include <vector>
+#include <stdint.h>
 
 using namespace std;
 
@@ -70,6 +74,47 @@ checkRRTypeBitmaps(const char* const rrtype_name,
         first = false;
     }
 }
+
+void
+buildBitmapsFromText(const char* const rrtype_name,
+                     istringstream& iss, vector<uint8_t>& typebits)
+{
+    uint8_t bitmap[8 * 1024];       // 64k bits
+    memset(bitmap, 0, sizeof(bitmap));
+
+    do {
+        string type;
+        iss >> type;
+        if (iss.bad() || iss.fail()) {
+            isc_throw(InvalidRdataText, "Unexpected input for "
+                      << rrtype_name << " bitmap");
+        }
+        try {
+            const int code = RRType(type).getCode();
+            bitmap[code / 8] |= (0x80 >> (code % 8));
+        } catch (const InvalidRRType&) {
+            isc_throw(InvalidRdataText, "Invalid RRtype in "
+                      << rrtype_name << " bitmap: " << type);
+        }
+    } while (!iss.eof());
+
+    for (int window = 0; window < 256; ++window) {
+        int octet;
+        for (octet = 31; octet >= 0; octet--) {
+            if (bitmap[window * 32 + octet] != 0) {
+                break;
+            }
+        }
+        if (octet < 0) {
+            continue;
+        }
+        typebits.push_back(window);
+        typebits.push_back(octet + 1);
+        for (int i = 0; i <= octet; ++i) {
+            typebits.push_back(bitmap[window * 32 + i]);
+        }
+    }
+}
 }
 }
 }

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

@@ -14,6 +14,7 @@
 
 #include <stdint.h>
 
+#include <sstream>
 #include <vector>
 
 namespace isc {
@@ -39,6 +40,10 @@ namespace nsec {
 /// is the total length of the bitmaps.
 void checkRRTypeBitmaps(const char* const rrtype_name,
                         const std::vector<uint8_t>& typebits);
+
+void buildBitmapsFromText(const char* const rrtype_name,
+                          std::istringstream& iss,
+                          std::vector<uint8_t>& typebits);
 }
 }
 }

+ 1 - 30
src/lib/dns/rdata/generic/nsec3_50.cc

@@ -116,36 +116,7 @@ NSEC3::NSEC3(const string& nsec3_str) :
     }
 
     vector<uint8_t> typebits;
-    uint8_t bitmap[8 * 1024];       // 64k bits
-    memset(bitmap, 0, sizeof(bitmap));
-    do { 
-        string type;
-        iss >> type;
-        if (type.length() != 0) {
-            try {
-                const int code = RRType(type).getCode();
-                bitmap[code / 8] |= (0x80 >> (code % 8));
-            } catch (...) {
-                isc_throw(InvalidRdataText, "Invalid RRtype in NSEC3");
-            }
-        }
-    } while (!iss.eof());
-
-    for (int window = 0; window < 256; window++) {
-        int octet;
-        for (octet = 31; octet >= 0; octet--) {
-            if (bitmap[window * 32 + octet] != 0) {
-                break;
-            }
-        }
-        if (octet < 0)
-            continue;
-        typebits.push_back(window);
-        typebits.push_back(octet + 1);
-        for (int i = 0; i <= octet; i++) {
-            typebits.push_back(bitmap[window * 32 + i]);
-        }
-    }
+    buildBitmapsFromText("NSEC3", iss, typebits);
 
     impl_ = new NSEC3Impl(hashalg, flags, iterations, salt, next, typebits);
 }

+ 2 - 29
src/lib/dns/rdata/generic/nsec_47.cc

@@ -54,8 +54,6 @@ NSEC::NSEC(const string& nsec_str) :
 {
     istringstream iss(nsec_str);
     string nextname;
-    uint8_t bitmap[8 * 1024];       // 64k bits
-    vector<uint8_t> typebits;
 
     iss >> nextname;
     if (iss.bad() || iss.fail()) {
@@ -65,33 +63,8 @@ NSEC::NSEC(const string& nsec_str) :
         isc_throw(InvalidRdataText, "NSEC bitmap is missing");
     }
 
-    memset(bitmap, 0, sizeof(bitmap));
-    do { 
-        string type;
-        iss >> type;
-        try {
-            const int code = RRType(type).getCode();
-            bitmap[code / 8] |= (0x80 >> (code % 8));
-        } catch (...) {
-            isc_throw(InvalidRdataText, "Invalid RRtype in NSEC");
-        }
-    } while (!iss.eof());
-
-    for (int window = 0; window < 256; window++) {
-        int octet;
-        for (octet = 31; octet >= 0; octet--) {
-            if (bitmap[window * 32 + octet] != 0) {
-                break;
-            }
-        }
-        if (octet < 0)
-            continue;
-        typebits.push_back(window);
-        typebits.push_back(octet + 1);
-        for (int i = 0; i <= octet; i++) {
-            typebits.push_back(bitmap[window * 32 + i]);
-        }
-    }
+    vector<uint8_t> typebits;
+    buildBitmapsFromText("NSEC", iss, typebits);
 
     impl_ = new NSECImpl(Name(nextname), typebits);
 }

+ 7 - 0
src/lib/dns/tests/rdata_nsecbitmap_unittest.cc

@@ -168,6 +168,13 @@ TYPED_TEST(NSECLikeBitmapTest, createFromWire) {
                  DNSMessageFORMERR);
 }
 
+TYPED_TEST(NSECLikeBitmapTest, badText) {
+    // redundant space after the sequence
+    EXPECT_THROW(this->fromText(this->getCommonText() + "A "),
+                 InvalidRdataText);
+}
+
+
 // This tests the result of toText() with various kinds of NSEC/NSEC3 bitmaps.
 // It also tests the "from text" constructor as a result.
 TYPED_TEST(NSECLikeBitmapTest, toText) {