From: Paul Selkirk Date: Thu, 16 May 2013 21:27:58 +0000 (-0400) Subject: [2522] add MasterLexer constructors for in::SSHFP, ch::A, hs::A. X-Git-Tag: bind10-1.2.0beta1-release~430^2~17 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=8cb0a56a019c3cbaacc8ccdeebaf3906eeda8a74;p=thirdparty%2Fkea.git [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. --- diff --git a/src/lib/dns/gen-rdatacode.py.in b/src/lib/dns/gen-rdatacode.py.in index 27ab2f34f0..3fd3b33112 100755 --- a/src/lib/dns/gen-rdatacode.py.in +++ b/src/lib/dns/gen-rdatacode.py.in @@ -24,42 +24,6 @@ from os.path import getmtime import re 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+)') classcode2txt = {} typecode2txt = {} @@ -69,7 +33,7 @@ meta_types = { # Real meta types. We won't have Rdata implement for them, but we need # RRType constants. '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. '3': 'md', '4': 'mf', '7': 'mb', '8': 'mg', '9': 'mr', '30': 'nxt', '38': 'a6', '254': 'maila', @@ -378,28 +342,15 @@ def generate_rrparam(fileprefix, basemtime): indent = ' ' * 8 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': typeandclassparams += 'add("' + type_utxt + '", ' typeandclassparams += str(type_code) + ', "' + class_utxt typeandclassparams += '", ' + str(class_code) - typeandclassparams += ', RdataFactoryPtr(new ' + rdf_class + '<' + typeandclassparams += ', RdataFactoryPtr(new ' + 'RdataFactory' + '<' typeandclassparams += class_txt + '::' + type_utxt + '>()));\n' else: typeandclassparams += 'add("' + type_utxt + '", ' + str(type_code) - typeandclassparams += ', RdataFactoryPtr(new ' + rdf_class + '<' + typeandclassparams += ', RdataFactoryPtr(new ' + 'RdataFactory' + '<' typeandclassparams += class_txt + '::' + type_utxt + '>()));\n' typeandclassparams += indent + '// Meta and non-implemented RR types\n' diff --git a/src/lib/dns/rdata/ch_3/a_1.cc b/src/lib/dns/rdata/ch_3/a_1.cc index 3d13a9e446..8b0e442e1b 100644 --- a/src/lib/dns/rdata/ch_3/a_1.cc +++ b/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 // purpose with or without fee is hereby granted, provided that the above @@ -31,6 +31,11 @@ A::A(const std::string&) { // TBD } +A::A(MasterLexer&, const Name*, + MasterLoader::Options, MasterLoaderCallbacks&) { + // TBD +} + A::A(InputBuffer&, size_t) { // TBD } diff --git a/src/lib/dns/rdata/generic/sshfp_44.cc b/src/lib/dns/rdata/generic/sshfp_44.cc index 64b3cc175a..a238b2f78e 100644 --- a/src/lib/dns/rdata/generic/sshfp_44.cc +++ b/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 // 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_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) { isc_throw(InvalidRdataText, "SSHFP algorithm number out of range"); } + algorithm_ = static_cast(algorithm); + const uint32_t fingerprint_type = + lexer.getNextToken(MasterToken::NUMBER).getNumber(); if (fingerprint_type > 255) { isc_throw(InvalidRdataText, "SSHFP fingerprint type out of range"); } + fingerprint_type_ = static_cast(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 { - 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) { isc_throw(InvalidRdataText, "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, diff --git a/src/lib/dns/rdata/generic/sshfp_44.h b/src/lib/dns/rdata/generic/sshfp_44.h index d9ebea46f5..1c42b8405e 100644 --- a/src/lib/dns/rdata/generic/sshfp_44.h +++ b/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 // purpose with or without fee is hereby granted, provided that the above @@ -33,7 +33,8 @@ public: // BEGIN_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 @@ -43,6 +44,8 @@ public: size_t getFingerprintLen() const; private: + void constructFromLexer(MasterLexer& lexer); + /// Note: this is a prototype version; we may reconsider /// this representation later. uint8_t algorithm_; diff --git a/src/lib/dns/rdata/hs_4/a_1.cc b/src/lib/dns/rdata/hs_4/a_1.cc index 3d13a9e446..8b0e442e1b 100644 --- a/src/lib/dns/rdata/hs_4/a_1.cc +++ b/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 // purpose with or without fee is hereby granted, provided that the above @@ -31,6 +31,11 @@ A::A(const std::string&) { // TBD } +A::A(MasterLexer&, const Name*, + MasterLoader::Options, MasterLoaderCallbacks&) { + // TBD +} + A::A(InputBuffer&, size_t) { // TBD } diff --git a/src/lib/dns/tests/rdata_sshfp_unittest.cc b/src/lib/dns/tests/rdata_sshfp_unittest.cc index 6c13ad98b7..7c8e367844 100644 --- a/src/lib/dns/tests/rdata_sshfp_unittest.cc +++ b/src/lib/dns/tests/rdata_sshfp_unittest.cc @@ -103,7 +103,8 @@ TEST_F(Rdata_SSHFP_Test, algorithmTypes) { TEST_F(Rdata_SSHFP_Test, badText) { 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("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) {