Browse Source

[2522] add MasterLexer constructors for in::SSHFP, ch::A, hs::A.

Also removed OldRdataFactory/new_rdata_factory_users stuff, since all Rdata classes now use the new RdataFactory.
Paul Selkirk 12 years ago
parent
commit
8cb0a56a01

+ 3 - 52
src/lib/dns/gen-rdatacode.py.in

@@ -24,42 +24,6 @@ from os.path import getmtime
 import re
 import re
 import sys
 import sys
 
 
-# new_rdata_factory_users[] is a list of tuples of the form (rrtype,
-# rrclass). Items in the list use the (new) RdataFactory class, and
-# items which are not in the list use OldRdataFactory class.
-# Note: rrtype and rrclass must be specified in lowercase in
-# new_rdata_factory_users.
-#
-# Example:
-#     new_rdata_factory_users = [('a', 'in'), ('a', 'ch'), ('soa', 'generic')]
-new_rdata_factory_users = [('a', 'in'),
-                           ('aaaa', 'in'),
-                           ('afsdb', 'generic'),
-                           ('cname', 'generic'),
-                           ('dhcid', 'in'),
-                           ('dlv', 'generic'),
-                           ('dname', 'generic'),
-                           ('dnskey', 'generic'),
-                           ('ds', 'generic'),
-                           ('hinfo', 'generic'),
-                           ('minfo', 'generic'),
-                           ('mx', 'generic'),
-                           ('naptr', 'generic'),
-                           ('ns', 'generic'),
-                           ('nsec', 'generic'),
-                           ('nsec3', 'generic'),
-                           ('nsec3param', 'generic'),
-                           ('opt', 'generic'),
-                           ('ptr', 'generic'),
-                           ('rp', 'generic'),
-                           ('rrsig', 'generic'),
-                           ('soa', 'generic'),
-                           ('spf', 'generic'),
-                           ('srv', 'in'),
-                           ('tsig', 'any'),
-                           ('txt', 'generic')
-                          ]
-
 re_typecode = re.compile('([\da-z\-]+)_(\d+)')
 re_typecode = re.compile('([\da-z\-]+)_(\d+)')
 classcode2txt = {}
 classcode2txt = {}
 typecode2txt = {}
 typecode2txt = {}
@@ -69,7 +33,7 @@ meta_types = {
     # Real meta types.  We won't have Rdata implement for them, but we need
     # Real meta types.  We won't have Rdata implement for them, but we need
     # RRType constants.
     # RRType constants.
     '251': 'ixfr', '252': 'axfr', '255': 'any',
     '251': 'ixfr', '252': 'axfr', '255': 'any',
-    # Obsolete types.  We probalby won't implement Rdata for them, but it's
+    # Obsolete types.  We probably won't implement Rdata for them, but it's
     # better to have RRType constants.
     # better to have RRType constants.
     '3': 'md', '4': 'mf', '7': 'mb', '8': 'mg', '9': 'mr', '30': 'nxt',
     '3': 'md', '4': 'mf', '7': 'mb', '8': 'mg', '9': 'mr', '30': 'nxt',
     '38': 'a6', '254': 'maila',
     '38': 'a6', '254': 'maila',
@@ -378,28 +342,15 @@ def generate_rrparam(fileprefix, basemtime):
         indent = ' ' * 8
         indent = ' ' * 8
         typeandclassparams += indent
         typeandclassparams += indent
 
 
-        # By default, we use OldRdataFactory (see bug #2497). If you
-        # want to pick RdataFactory for a particular type, add it to
-        # new_rdata_factory_users.  Note that we explicitly generate (for
-        # optimization) class-independent ("generic") factories for class IN
-        # for optimization.
-        if (((type_txt.lower(), class_txt.lower()) in
-             new_rdata_factory_users) or
-            ((class_txt.lower() == 'in') and
-             ((type_txt.lower(), 'generic') in new_rdata_factory_users))):
-            rdf_class = 'RdataFactory'
-        else:
-            rdf_class = 'OldRdataFactory'
-
         if class_tuple[1] != 'generic':
         if class_tuple[1] != 'generic':
             typeandclassparams += 'add("' + type_utxt + '", '
             typeandclassparams += 'add("' + type_utxt + '", '
             typeandclassparams += str(type_code) + ', "' + class_utxt
             typeandclassparams += str(type_code) + ', "' + class_utxt
             typeandclassparams += '", ' + str(class_code)
             typeandclassparams += '", ' + str(class_code)
-            typeandclassparams += ', RdataFactoryPtr(new ' + rdf_class + '<'
+            typeandclassparams += ', RdataFactoryPtr(new ' + 'RdataFactory' + '<'
             typeandclassparams += class_txt + '::' + type_utxt + '>()));\n'
             typeandclassparams += class_txt + '::' + type_utxt + '>()));\n'
         else:
         else:
             typeandclassparams += 'add("' + type_utxt + '", ' + str(type_code)
             typeandclassparams += 'add("' + type_utxt + '", ' + str(type_code)
-            typeandclassparams += ', RdataFactoryPtr(new ' + rdf_class + '<'
+            typeandclassparams += ', RdataFactoryPtr(new ' + 'RdataFactory' + '<'
             typeandclassparams += class_txt + '::' + type_utxt + '>()));\n'
             typeandclassparams += class_txt + '::' + type_utxt + '>()));\n'
 
 
     typeandclassparams += indent + '// Meta and non-implemented RR types\n'
     typeandclassparams += indent + '// Meta and non-implemented RR types\n'

+ 6 - 1
src/lib/dns/rdata/ch_3/a_1.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2010  Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2010-2013  Internet Systems Consortium, Inc. ("ISC")
 //
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
 // purpose with or without fee is hereby granted, provided that the above
@@ -31,6 +31,11 @@ A::A(const std::string&) {
     // TBD
     // TBD
 }
 }
 
 
+A::A(MasterLexer&, const Name*,
+     MasterLoader::Options, MasterLoaderCallbacks&) {
+    // TBD
+}
+
 A::A(InputBuffer&, size_t) {
 A::A(InputBuffer&, size_t) {
     // TBD
     // TBD
 }
 }

+ 79 - 30
src/lib/dns/rdata/generic/sshfp_44.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2012  Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2012-2013  Internet Systems Consortium, Inc. ("ISC")
 //
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
 // purpose with or without fee is hereby granted, provided that the above
@@ -35,49 +35,98 @@ using namespace isc::util::encode;
 // BEGIN_ISC_NAMESPACE
 // BEGIN_ISC_NAMESPACE
 // BEGIN_RDATA_NAMESPACE
 // BEGIN_RDATA_NAMESPACE
 
 
-SSHFP::SSHFP(InputBuffer& buffer, size_t rdata_len) {
-    if (rdata_len < 2) {
-        isc_throw(InvalidRdataLength, "SSHFP record too short");
-    }
-
-    algorithm_ = buffer.readUint8();
-    fingerprint_type_ = buffer.readUint8();
-
-    rdata_len -= 2;
-    if (rdata_len > 0) {
-        fingerprint_.resize(rdata_len);
-        buffer.readData(&fingerprint_[0], rdata_len);
-    }
-}
-
-SSHFP::SSHFP(const std::string& sshfp_str) {
-    std::istringstream iss(sshfp_str);
-    std::stringbuf fingerprintbuf;
-    uint32_t algorithm, fingerprint_type;
-
-    iss >> algorithm >> fingerprint_type;
-    if (iss.bad() || iss.fail()) {
-        isc_throw(InvalidRdataText, "Invalid SSHFP text");
-    }
-
+// helper function for string and lexer constructors
+void
+SSHFP::constructFromLexer(MasterLexer& lexer) {
+    const uint32_t algorithm =
+        lexer.getNextToken(MasterToken::NUMBER).getNumber();
     if (algorithm > 255) {
     if (algorithm > 255) {
         isc_throw(InvalidRdataText, "SSHFP algorithm number out of range");
         isc_throw(InvalidRdataText, "SSHFP algorithm number out of range");
     }
     }
+    algorithm_ = static_cast<uint8_t>(algorithm);
 
 
+    const uint32_t fingerprint_type =
+        lexer.getNextToken(MasterToken::NUMBER).getNumber();
     if (fingerprint_type > 255) {
     if (fingerprint_type > 255) {
         isc_throw(InvalidRdataText, "SSHFP fingerprint type out of range");
         isc_throw(InvalidRdataText, "SSHFP fingerprint type out of range");
     }
     }
+    fingerprint_type_ = static_cast<uint8_t>(fingerprint_type);
+
+    const MasterToken& token = lexer.getNextToken(MasterToken::STRING, true);
+    if ((token.getType() != MasterToken::END_OF_FILE) &&
+	(token.getType() != MasterToken::END_OF_LINE)) {
+        decodeHex(token.getString(), fingerprint_);
+    }
+}
 
 
-    iss >> &fingerprintbuf;
+/// \brief Constructor from string.
+///
+/// The given string must represent a valid SSHFP RDATA.  There can be
+/// extra space characters at the beginning or end of the text (which
+/// are simply ignored), but other extra text, including a new line,
+/// will make the construction fail with an exception.
+///
+/// The Algorithm and Fingerprint Type fields must be within their valid
+/// ranges, but are not contrained to the values defined in RFC4255.
+///
+/// The Fingerprint field may be absent, but if present it must contain a
+/// valid hex encoding of the fingerprint.
+///
+/// \throw InvalidRdataText if any fields are missing, out of their valid
+/// ranges, or incorrect.
+///
+/// \param sshfp_str A string containing the RDATA to be created
+SSHFP::SSHFP(const std::string& sshfp_str) {
     try {
     try {
-        decodeHex(fingerprintbuf.str(), fingerprint_);
+        std::istringstream ss(sshfp_str);
+        MasterLexer lexer;
+        lexer.pushSource(ss);
+
+        constructFromLexer(lexer);
+
+        if (lexer.getNextToken().getType() != MasterToken::END_OF_FILE) {
+            isc_throw(InvalidRdataText, "extra input text for SSHFP: "
+                      << sshfp_str);
+        }
+    } catch (const MasterLexer::LexerError& ex) {
+        isc_throw(InvalidRdataText, "Failed to construct SSHFP from '" <<
+                  sshfp_str << "': " << ex.what());
     } catch (const isc::BadValue& e) {
     } catch (const isc::BadValue& e) {
         isc_throw(InvalidRdataText,
         isc_throw(InvalidRdataText,
                   "Bad SSHFP fingerprint: " << e.what());
                   "Bad SSHFP fingerprint: " << e.what());
     }
     }
+}
 
 
-    algorithm_ = algorithm;
-    fingerprint_type_ = fingerprint_type;
+/// \brief Constructor with a context of MasterLexer.
+///
+/// The \c lexer should point to the beginning of valid textual representation
+/// of an SSHFP RDATA.
+///
+/// \throw MasterLexer::LexerError General parsing error such as missing field.
+/// \throw InvalidRdataText Fields are out of their valid range, or are
+/// incorrect.
+/// \throw BadValue Fingerprint is not a valid hex string.
+///
+/// \param lexer A \c MasterLexer object parsing a master file for the
+/// RDATA to be created
+SSHFP::SSHFP(MasterLexer& lexer, const Name*,
+       MasterLoader::Options, MasterLoaderCallbacks&) {
+    constructFromLexer(lexer);
+}
+
+SSHFP::SSHFP(InputBuffer& buffer, size_t rdata_len) {
+    if (rdata_len < 2) {
+        isc_throw(InvalidRdataLength, "SSHFP record too short");
+    }
+
+    algorithm_ = buffer.readUint8();
+    fingerprint_type_ = buffer.readUint8();
+
+    rdata_len -= 2;
+    if (rdata_len > 0) {
+        fingerprint_.resize(rdata_len);
+        buffer.readData(&fingerprint_[0], rdata_len);
+    }
 }
 }
 
 
 SSHFP::SSHFP(uint8_t algorithm, uint8_t fingerprint_type,
 SSHFP::SSHFP(uint8_t algorithm, uint8_t fingerprint_type,

+ 5 - 2
src/lib/dns/rdata/generic/sshfp_44.h

@@ -1,4 +1,4 @@
-// Copyright (C) 2012  Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2012-2013  Internet Systems Consortium, Inc. ("ISC")
 //
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
 // purpose with or without fee is hereby granted, provided that the above
@@ -33,7 +33,8 @@ public:
     // BEGIN_COMMON_MEMBERS
     // BEGIN_COMMON_MEMBERS
     // END_COMMON_MEMBERS
     // END_COMMON_MEMBERS
 
 
-    SSHFP(uint8_t algorithm, uint8_t fingerprint_type, const std::string& fingerprint);
+    SSHFP(uint8_t algorithm, uint8_t fingerprint_type,
+          const std::string& fingerprint);
 
 
     ///
     ///
     /// Specialized methods
     /// Specialized methods
@@ -43,6 +44,8 @@ public:
     size_t getFingerprintLen() const;
     size_t getFingerprintLen() const;
 
 
 private:
 private:
+    void constructFromLexer(MasterLexer& lexer);
+
     /// Note: this is a prototype version; we may reconsider
     /// Note: this is a prototype version; we may reconsider
     /// this representation later.
     /// this representation later.
     uint8_t algorithm_;
     uint8_t algorithm_;

+ 6 - 1
src/lib/dns/rdata/hs_4/a_1.cc

@@ -1,4 +1,4 @@
-// Copyright (C) 2010  Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2010-2013  Internet Systems Consortium, Inc. ("ISC")
 //
 //
 // Permission to use, copy, modify, and/or distribute this software for any
 // Permission to use, copy, modify, and/or distribute this software for any
 // purpose with or without fee is hereby granted, provided that the above
 // purpose with or without fee is hereby granted, provided that the above
@@ -31,6 +31,11 @@ A::A(const std::string&) {
     // TBD
     // TBD
 }
 }
 
 
+A::A(MasterLexer&, const Name*,
+     MasterLoader::Options, MasterLoaderCallbacks&) {
+    // TBD
+}
+
 A::A(InputBuffer&, size_t) {
 A::A(InputBuffer&, size_t) {
     // TBD
     // TBD
 }
 }

+ 2 - 1
src/lib/dns/tests/rdata_sshfp_unittest.cc

@@ -103,7 +103,8 @@ TEST_F(Rdata_SSHFP_Test, algorithmTypes) {
 TEST_F(Rdata_SSHFP_Test, badText) {
 TEST_F(Rdata_SSHFP_Test, badText) {
     EXPECT_THROW(const generic::SSHFP rdata_sshfp("1"), InvalidRdataText);
     EXPECT_THROW(const generic::SSHFP rdata_sshfp("1"), InvalidRdataText);
     EXPECT_THROW(const generic::SSHFP rdata_sshfp("BUCKLE MY SHOES"), InvalidRdataText);
     EXPECT_THROW(const generic::SSHFP rdata_sshfp("BUCKLE MY SHOES"), InvalidRdataText);
-    EXPECT_THROW(const generic::SSHFP rdata_sshfp("1 2 foo bar"), InvalidRdataText);
+    EXPECT_THROW(const generic::SSHFP rdata_sshfp("1 2 foo"), InvalidRdataText);
+    EXPECT_THROW(const generic::SSHFP rdata_sshfp("1 2 12ab bar"), InvalidRdataText);
 }
 }
 
 
 TEST_F(Rdata_SSHFP_Test, copy) {
 TEST_F(Rdata_SSHFP_Test, copy) {