Also removed OldRdataFactory/new_rdata_factory_users stuff, since all Rdata classes now use the new RdataFactory.
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 = {}
# 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',
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'
-// 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
// TBD
}
+A::A(MasterLexer&, const Name*,
+ MasterLoader::Options, MasterLoaderCallbacks&) {
+ // TBD
+}
+
A::A(InputBuffer&, size_t) {
// TBD
}
-// 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
// 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<uint8_t>(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<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 {
- 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,
-// 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
// 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
size_t getFingerprintLen() const;
private:
+ void constructFromLexer(MasterLexer& lexer);
+
/// Note: this is a prototype version; we may reconsider
/// this representation later.
uint8_t algorithm_;
-// 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
// TBD
}
+A::A(MasterLexer&, const Name*,
+ MasterLoader::Options, MasterLoaderCallbacks&) {
+ // TBD
+}
+
A::A(InputBuffer&, size_t) {
// TBD
}
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) {