Commit 6226330d authored by JINMEI Tatuya's avatar JINMEI Tatuya
Browse files

[2382] Merge branch 'trac2497' into trac2382

parents 9a5e89e0 c73280d2
......@@ -120,6 +120,7 @@ libb10_dns___la_SOURCES += tsigkey.h tsigkey.cc
libb10_dns___la_SOURCES += tsigrecord.h tsigrecord.cc
libb10_dns___la_SOURCES += character_string.h character_string.cc
libb10_dns___la_SOURCES += master_loader_callbacks.h
libb10_dns___la_SOURCES += master_loader.h
libb10_dns___la_SOURCES += rdata/generic/detail/nsec_bitmap.h
libb10_dns___la_SOURCES += rdata/generic/detail/nsec_bitmap.cc
libb10_dns___la_SOURCES += rdata/generic/detail/nsec3param_common.cc
......
......@@ -28,6 +28,7 @@ re_typecode = re.compile('([\da-z]+)_(\d+)')
classcode2txt = {}
typecode2txt = {}
typeandclass = []
new_rdatafactory_users = []
generic_code = 65536 # something larger than any code value
rdata_declarations = ''
class_definitions = ''
......@@ -271,15 +272,24 @@ def generate_rrparam(fileprefix, basemtime):
class_utxt = class_tuple[1].upper()
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_rdatafactory_users.
if type_txt in new_rdatafactory_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 RdataFactory<'
typeandclassparams += ', RdataFactoryPtr(new ' + rdf_class + '<'
typeandclassparams += class_txt + '::' + type_utxt + '>()));\n'
else:
typeandclassparams += 'add("' + type_utxt + '", ' + str(type_code)
typeandclassparams += ', RdataFactoryPtr(new RdataFactory<'
typeandclassparams += ', RdataFactoryPtr(new ' + rdf_class + '<'
typeandclassparams += class_txt + '::' + type_utxt + '>()));\n'
rrparam_temp = open(placeholder, 'r')
......
// Copyright (C) 2012 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
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#ifndef MASTER_LOADER_H
#define MASTER_LOADER_H
namespace isc {
namespace dns {
// Placeholder introduced by #2497. The real class should be updated in
// #2377.
class MasterLoader {
public:
enum Options {
MANY_ERRORS, // lenient mode
// also eventually some check policies like "check NS name"
};
};
}
}
#endif // MASTER_LOADER_H
......@@ -119,4 +119,4 @@ private:
}
}
#endif // LOADER_CALLBACKS_H
#endif // MASTER_LOADER_CALLBACKS_H
......@@ -65,7 +65,7 @@ createRdata(const RRType& rrtype, const RRClass& rrclass,
RdataPtr rdata =
RRParamRegistry::getRegistry().createRdata(rrtype, rrclass, buffer,
len);
if (buffer.getPosition() - old_pos != len) {
isc_throw(InvalidRdataLength, "RDLENGTH mismatch: " <<
buffer.getPosition() - old_pos << " != " << len);
......@@ -81,6 +81,17 @@ createRdata(const RRType& rrtype, const RRClass& rrclass, const Rdata& source)
source));
}
RdataPtr
createRdata(const RRType& rrtype, const RRClass& rrclass,
MasterLexer& lexer, const Name* origin,
MasterLoader::Options options,
MasterLoaderCallbacks& callbacks)
{
return (RRParamRegistry::getRegistry().createRdata(rrtype, rrclass,
lexer, origin,
options, callbacks));
}
int
compareNames(const Name& n1, const Name& n2) {
size_t len1 = n1.getLength();
......@@ -119,7 +130,8 @@ Generic::Generic(isc::util::InputBuffer& buffer, size_t rdata_len) {
impl_ = new GenericImpl(data);
}
Generic::Generic(const std::string& rdata_string) {
void
Generic::constructHelper(const std::string& rdata_string) {
istringstream iss(rdata_string);
string unknown_mark;
iss >> unknown_mark;
......@@ -180,6 +192,33 @@ Generic::Generic(const std::string& rdata_string) {
impl_ = new GenericImpl(data);
}
Generic::Generic(const std::string& rdata_string) {
constructHelper(rdata_string);
}
Generic::Generic(MasterLexer& lexer, const Name*,
MasterLoader::Options,
MasterLoaderCallbacks&)
{
std::string s;
while (true) {
const MasterLexer::Token& token = lexer.getNextToken();
if ((token.getType() == MasterLexer::Token::END_OF_FILE) ||
(token.getType() == MasterLexer::Token::END_OF_LINE)) {
break;
}
if (!s.empty()) {
s += " ";
}
s += token.getString();
}
constructHelper(s);
}
Generic::~Generic() {
delete impl_;
}
......
......@@ -15,11 +15,15 @@
#ifndef RDATA_H
#define RDATA_H 1
#include <stdint.h>
#include <dns/master_lexer.h>
#include <dns/master_loader.h>
#include <dns/master_loader_callbacks.h>
#include <exceptions/exceptions.h>
#include <boost/shared_ptr.hpp>
#include <exceptions/exceptions.h>
#include <stdint.h>
namespace isc {
namespace util {
......@@ -279,6 +283,11 @@ public:
/// \param rdata_len The length in buffer of the \c Rdata. In bytes.
Generic(isc::util::InputBuffer& buffer, size_t rdata_len);
/// \brief Constructor from master lexer.
///
Generic(MasterLexer& lexer, const Name* name,
MasterLoader::Options options, MasterLoaderCallbacks& callbacks);
///
/// \brief The destructor.
virtual ~Generic();
......@@ -367,7 +376,10 @@ public:
/// \return > 0 if \c this would be sorted after \c other.
virtual int compare(const Rdata& other) const;
//@}
private:
void constructHelper(const std::string& rdata_string);
GenericImpl* impl_;
};
......@@ -472,6 +484,14 @@ RdataPtr createRdata(const RRType& rrtype, const RRClass& rrclass,
/// \c Rdata object.
RdataPtr createRdata(const RRType& rrtype, const RRClass& rrclass,
const Rdata& source);
/// \brief Create RDATA of a given pair of RR type and class from the
/// master lexer.
RdataPtr createRdata(const RRType& rrtype, const RRClass& rrclass,
MasterLexer& lexer, const Name* origin,
MasterLoader::Options options,
MasterLoaderCallbacks& callbacks);
//@}
///
......@@ -511,6 +531,6 @@ int compareNames(const Name& n1, const Name& n2);
}
#endif // RDATA_H
// Local Variables:
// Local Variables:
// mode: c++
// End:
// End:
......@@ -37,10 +37,39 @@ using namespace std;
using namespace boost;
using namespace isc::util;
using namespace isc::dns::rdata;
using namespace isc::dns::rdata;
namespace isc {
namespace dns {
namespace rdata {
RdataPtr
AbstractRdataFactory::create(MasterLexer& lexer, const Name*,
MasterLoader::Options,
MasterLoaderCallbacks&) const
{
std::string s;
while (true) {
const MasterLexer::Token& token = lexer.getNextToken();
if ((token.getType() == MasterLexer::Token::END_OF_FILE) ||
(token.getType() == MasterLexer::Token::END_OF_LINE)) {
break;
}
if (!s.empty()) {
s += " ";
}
s += token.getString();
}
return (create(s));
}
} // end of namespace isc::dns::rdata
namespace {
///
/// The following function and class are a helper to define case-insensitive
......@@ -161,8 +190,10 @@ typedef map<RRTypeClass, RdataFactoryPtr> RdataFactoryMap;
typedef map<RRType, RdataFactoryPtr> GenericRdataFactoryMap;
template <typename T>
class RdataFactory : public AbstractRdataFactory {
class OldRdataFactory : public AbstractRdataFactory {
public:
using AbstractRdataFactory::create;
virtual RdataPtr create(const string& rdata_str) const
{
return (RdataPtr(new T(rdata_str)));
......@@ -179,6 +210,18 @@ public:
}
};
template <typename T>
class RdataFactory : public OldRdataFactory<T> {
public:
using OldRdataFactory<T>::create;
virtual RdataPtr create(MasterLexer& lexer, const Name* origin,
MasterLoader::Options options,
MasterLoaderCallbacks& callbacks) const {
return (RdataPtr(new T(lexer, origin, options, callbacks)));
}
};
///
/// \brief The \c RRParamRegistryImpl class is the actual implementation of
/// \c RRParamRegistry.
......@@ -305,7 +348,7 @@ namespace {
/// This could be simplified using strncasecmp(), but unfortunately it's not
/// included in <cstring>. To be as much as portable within the C++ standard
/// we take the "in house" approach here.
///
///
bool CICharEqual(char c1, char c2) {
return (tolower(static_cast<unsigned char>(c1)) ==
tolower(static_cast<unsigned char>(c2)));
......@@ -528,5 +571,26 @@ RRParamRegistry::createRdata(const RRType& rrtype, const RRClass& rrclass,
return (RdataPtr(new rdata::generic::Generic(
dynamic_cast<const generic::Generic&>(source))));
}
RdataPtr
RRParamRegistry::createRdata(const RRType& rrtype, const RRClass& rrclass,
MasterLexer& lexer, const Name* name,
MasterLoader::Options options,
MasterLoaderCallbacks& callbacks)
{
RdataFactoryMap::const_iterator found =
impl_->rdata_factories.find(RRTypeClass(rrtype, rrclass));
if (found != impl_->rdata_factories.end()) {
return (found->second->create(lexer, name, options, callbacks));
}
GenericRdataFactoryMap::const_iterator genfound =
impl_->genericrdata_factories.find(rrtype);
if (genfound != impl_->genericrdata_factories.end()) {
return (genfound->second->create(lexer, name, options, callbacks));
}
return (RdataPtr(new generic::Generic(lexer, name, options, callbacks)));
}
}
}
......@@ -82,7 +82,7 @@ public:
/// \name Factory methods for polymorphic creation.
///
//@{
///
/// \brief Create RDATA from a string.
///
/// This method creates from a string an \c Rdata object of specific class
......@@ -91,7 +91,7 @@ public:
/// \param rdata_str A string of textual representation of the \c Rdata.
/// \return An \c RdataPtr object pointing to the created \c Rdata object.
virtual RdataPtr create(const std::string& rdata_str) const = 0;
///
/// \brief Create RDATA from wire-format data.
///
/// This method creates from wire-format binary data an \c Rdata object
......@@ -103,7 +103,7 @@ public:
/// \param rdata_len The length in buffer of the \c Rdata. In bytes.
/// \return An \c RdataPtr object pointing to the created \c Rdata object.
virtual RdataPtr create(isc::util::InputBuffer& buffer, size_t rdata_len) const = 0;
///
/// \brief Create RDATA from another \c Rdata object of the same type.
///
/// This method creates an \c Rdata object of specific class corresponding
......@@ -118,6 +118,11 @@ public:
/// be copied to the created \c Rdata object.
/// \return An \c RdataPtr object pointing to the created \c Rdata object.
virtual RdataPtr create(const rdata::Rdata& source) const = 0;
/// \brief Create RDATA from MasterLexer
virtual RdataPtr create(MasterLexer& lexer, const Name*,
MasterLoader::Options,
MasterLoaderCallbacks&) const;
//@}
};
......@@ -498,6 +503,12 @@ public:
/// \c rdata::Rdata object.
rdata::RdataPtr createRdata(const RRType& rrtype, const RRClass& rrclass,
const rdata::Rdata& source);
/// \brief Create RDATA from MasterLexer
rdata::RdataPtr createRdata(const RRType& rrtype, const RRClass& rrclass,
MasterLexer& lexer, const Name* name,
MasterLoader::Options options,
MasterLoaderCallbacks& callbacks);
//@}
private:
......@@ -508,6 +519,6 @@ private:
}
#endif // RRPARAMREGISTRY_H
// Local Variables:
// Local Variables:
// mode: c++
// End:
// End:
......@@ -114,6 +114,18 @@ TEST_F(Rdata_AFSDB_Test, createFromWire) {
DNSMessageFORMERR);
}
TEST_F(Rdata_AFSDB_Test, createFromLexer) {
EXPECT_EQ(0, rdata_afsdb.compare(
*test::createRdataUsingLexer(RRType::AFSDB(), RRClass::IN(),
afsdb_text)));
// Check that bad input throws as usual
EXPECT_THROW({
*test::createRdataUsingLexer(RRType::AFSDB(), RRClass::IN(),
"1root.example.com.");
}, InvalidRdataText);
}
TEST_F(Rdata_AFSDB_Test, toWireBuffer) {
// construct actual data
rdata_afsdb.toWire(obuffer);
......
......@@ -87,6 +87,12 @@ TEST_F(Rdata_CNAME_Test, createFromWire) {
InvalidRdataLength);
}
TEST_F(Rdata_CNAME_Test, createFromLexer) {
EXPECT_EQ(0, rdata_cname.compare(
*test::createRdataUsingLexer(RRType::CNAME(), RRClass::IN(),
"cn.example.com")));
}
TEST_F(Rdata_CNAME_Test, toWireBuffer) {
rdata_cname.toWire(obuffer);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
......
......@@ -63,6 +63,17 @@ TEST_F(Rdata_DHCID_Test, createFromWire) {
// TBD: more tests
}
TEST_F(Rdata_DHCID_Test, createFromLexer) {
EXPECT_EQ(0, rdata_dhcid.compare(
*test::createRdataUsingLexer(RRType::DHCID(), RRClass::IN(),
string_dhcid)));
// Check that bad input throws as usual
EXPECT_THROW({
*test::createRdataUsingLexer(RRType::DHCID(), RRClass::IN(), "00");
}, isc::BadValue);
}
TEST_F(Rdata_DHCID_Test, toWireRenderer) {
rdata_dhcid.toWire(renderer);
......
......@@ -89,6 +89,12 @@ TEST_F(Rdata_DNAME_Test, createFromWire) {
InvalidRdataLength);
}
TEST_F(Rdata_DNAME_Test, createFromLexer) {
EXPECT_EQ(0, rdata_dname.compare(
*test::createRdataUsingLexer(RRType::DNAME(), RRClass::IN(),
"dn.example.com")));
}
TEST_F(Rdata_DNAME_Test, toWireBuffer) {
rdata_dname.toWire(obuffer);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
......
......@@ -82,6 +82,19 @@ TEST_F(Rdata_DNSKEY_Test, DISABLED_badText) {
InvalidRdataText);
}
TEST_F(Rdata_DNSKEY_Test, createFromLexer) {
generic::DNSKEY rdata_dnskey(dnskey_txt);
EXPECT_EQ(0, rdata_dnskey.compare(
*test::createRdataUsingLexer(RRType::DNSKEY(), RRClass::IN(),
dnskey_txt)));
// Check that bad input throws as usual
EXPECT_THROW({
*test::createRdataUsingLexer(RRType::DNSKEY(), RRClass::IN(),
"257 3 5");
}, InvalidRdataText);
}
TEST_F(Rdata_DNSKEY_Test, toWireRenderer) {
renderer.skip(2);
generic::DNSKEY rdata_dnskey(dnskey_txt);
......
......@@ -77,6 +77,19 @@ TEST_F(Rdata_HINFO_Test, createFromWire) {
EXPECT_EQ(string("Linux"), hinfo.getOS());
}
TEST_F(Rdata_HINFO_Test, createFromLexer) {
HINFO rdata_hinfo(hinfo_str);
EXPECT_EQ(0, rdata_hinfo.compare(
*test::createRdataUsingLexer(RRType::HINFO(), RRClass::IN(),
hinfo_str)));
// Check that bad input throws as usual
EXPECT_THROW({
*test::createRdataUsingLexer(RRType::HINFO(), RRClass::IN(),
"\"Pentium\"\"Linux\"");
}, InvalidRdataText);
}
TEST_F(Rdata_HINFO_Test, toText) {
HINFO hinfo(hinfo_str);
EXPECT_EQ(hinfo_str, hinfo.toText());
......
......@@ -68,6 +68,11 @@ TEST_F(Rdata_IN_A_Test, createFromWire) {
DNSMessageFORMERR);
}
TEST_F(Rdata_IN_A_Test, createFromLexer) {
EXPECT_EQ(0, rdata_in_a.compare(
*test::createRdataUsingLexer(RRType::A(), RRClass::IN(), "192.0.2.1")));
}
TEST_F(Rdata_IN_A_Test, toWireBuffer) {
rdata_in_a.toWire(obuffer);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
......
......@@ -66,6 +66,12 @@ TEST_F(Rdata_IN_AAAA_Test, createFromWire) {
DNSMessageFORMERR);
}
TEST_F(Rdata_IN_AAAA_Test, createFromLexer) {
EXPECT_EQ(0, rdata_in_aaaa.compare(
*test::createRdataUsingLexer(RRType::AAAA(), RRClass::IN(),
"2001:db8::1234")));
}
TEST_F(Rdata_IN_AAAA_Test, toWireBuffer) {
rdata_in_aaaa.toWire(obuffer);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
......
......@@ -103,6 +103,12 @@ TEST_F(Rdata_MINFO_Test, createFromWire) {
DNSMessageFORMERR);
}
TEST_F(Rdata_MINFO_Test, createFromLexer) {
EXPECT_EQ(0, rdata_minfo.compare(
*test::createRdataUsingLexer(RRType::MINFO(), RRClass::IN(),
minfo_txt)));
}
TEST_F(Rdata_MINFO_Test, assignment) {
generic::MINFO copy((string(minfo_txt2)));
copy = rdata_minfo;
......
......@@ -62,6 +62,17 @@ TEST_F(Rdata_MX_Test, createFromWire) {
// TBD: more tests
}
TEST_F(Rdata_MX_Test, createFromLexer) {
EXPECT_EQ(0, rdata_mx.compare(
*test::createRdataUsingLexer(RRType::MX(), RRClass::IN(),
"10 mx.example.com")));
EXPECT_THROW({
test::createRdataUsingLexer(RRType::MX(), RRClass::IN(),
"10 mx. example.com");
}, InvalidRdataText);
}
TEST_F(Rdata_MX_Test, toWireRenderer) {
renderer.writeName(Name("example.com"));
rdata_mx.toWire(renderer);
......
......@@ -128,6 +128,21 @@ TEST_F(Rdata_NAPTR_Test, createFromWire) {
EXPECT_EQ(Name("_sip._udp.example.com."), naptr.getReplacement());
}
TEST_F(Rdata_NAPTR_Test, createFromLexer) {
NAPTR rdata_naptr(naptr_str);
EXPECT_EQ(0, rdata_naptr.compare(
*test::createRdataUsingLexer(RRType::NAPTR(), RRClass::IN(),
naptr_str)));
// Check that bad input throws as usual (order > 65535)
EXPECT_THROW({
*test::createRdataUsingLexer(RRType::NAPTR(), RRClass::IN(),
"65536 10 S SIP \"\" "
"_sip._udp.example.com.");
}, InvalidRdataText);
}
TEST_F(Rdata_NAPTR_Test, toWire) {
NAPTR naptr(naptr_str);
naptr.toWire(obuffer);
......
......@@ -86,6 +86,17 @@ TEST_F(Rdata_NS_Test, createFromWire) {
InvalidRdataLength);
}
TEST_F(Rdata_NS_Test, createFromLexer) {
EXPECT_EQ(0, rdata_ns.compare(
*test::createRdataUsingLexer(RRType::NS(), RRClass::IN(),
"ns.example.com")));
EXPECT_THROW({
test::createRdataUsingLexer(RRType::NS(), RRClass::IN(),
"");
}, IncompleteName);
}
TEST_F(Rdata_NS_Test, toWireBuffer) {
rdata_ns.toWire(obuffer);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
......
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