Commit 8cb0a56a authored by Paul Selkirk's avatar Paul Selkirk
Browse files

[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.
parent b48e4ef0
......@@ -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'
......
// 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
}
......
// 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<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
......@@ -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_;
......
// 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
}
......
......@@ -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) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment