diff --git a/ChangeLog b/ChangeLog index 82e920b64f..96aaf0be56 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +292. [func] dvv + Implement the DLV rrtype according to RFC4431. + (Trac #1144, git TBD) + 291. [func] naokikambe Statistics items are specified by each module's spec file. Stats module can read these through the config manager. Stats diff --git a/src/lib/dns/Makefile.am b/src/lib/dns/Makefile.am index 3d4a663079..0d2bffd59a 100644 --- a/src/lib/dns/Makefile.am +++ b/src/lib/dns/Makefile.am @@ -24,6 +24,9 @@ EXTRA_DIST += rdata/generic/cname_5.h EXTRA_DIST += rdata/generic/detail/nsec_bitmap.cc EXTRA_DIST += rdata/generic/detail/nsec_bitmap.h EXTRA_DIST += rdata/generic/detail/txt_like.h +EXTRA_DIST += rdata/generic/detail/ds_like.h +EXTRA_DIST += rdata/generic/dlv_32769.cc +EXTRA_DIST += rdata/generic/dlv_32769.h EXTRA_DIST += rdata/generic/dname_39.cc EXTRA_DIST += rdata/generic/dname_39.h EXTRA_DIST += rdata/generic/dnskey_48.cc @@ -107,6 +110,7 @@ libdns___la_SOURCES += character_string.h character_string.cc libdns___la_SOURCES += rdata/generic/detail/nsec_bitmap.h libdns___la_SOURCES += rdata/generic/detail/nsec_bitmap.cc libdns___la_SOURCES += rdata/generic/detail/txt_like.h +libdns___la_SOURCES += rdata/generic/detail/ds_like.h libdns___la_CPPFLAGS = $(AM_CPPFLAGS) # Most applications of libdns++ will only implicitly rely on libcryptolink, diff --git a/src/lib/dns/rdata/generic/detail/ds_like.h b/src/lib/dns/rdata/generic/detail/ds_like.h new file mode 100644 index 0000000000..b5a35cd967 --- /dev/null +++ b/src/lib/dns/rdata/generic/detail/ds_like.h @@ -0,0 +1,225 @@ +// Copyright (C) 2011 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 __DS_LIKE_H +#define __DS_LIKE_H 1 + +#include + +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include + +namespace isc { +namespace dns { +namespace rdata { +namespace generic { +namespace detail { + +/// \brief \c rdata::DSLikeImpl class represents the DS-like RDATA for DS +/// and DLV types. +/// +/// This class implements the basic interfaces inherited by the DS and DLV +/// classes from the abstract \c rdata::Rdata class, and provides trivial +/// accessors to DS-like RDATA. +template class DSLikeImpl { + // Common sequence of toWire() operations used for the two versions of + // toWire(). + template + void + toWireCommon(Output& output) const { + output.writeUint16(tag_); + output.writeUint8(algorithm_); + output.writeUint8(digest_type_); + output.writeData(&digest_[0], digest_.size()); + } + +public: + /// \brief Constructor from string. + /// + /// Exceptions + /// + /// \c InvalidRdataText is thrown if the method cannot process the + /// parameter data for any of the number of reasons. + DSLikeImpl(const std::string& ds_str) { + std::istringstream iss(ds_str); + // peekc should be of iss's char_type for isspace to work + std::istringstream::char_type peekc; + std::stringbuf digestbuf; + uint32_t tag, algorithm, digest_type; + + iss >> tag >> algorithm >> digest_type; + if (iss.bad() || iss.fail()) { + isc_throw(InvalidRdataText, + "Invalid " << RRType(typeCode) << " text"); + } + if (tag > 0xffff) { + isc_throw(InvalidRdataText, + RRType(typeCode) << " tag out of range"); + } + if (algorithm > 0xff) { + isc_throw(InvalidRdataText, + RRType(typeCode) << " algorithm out of range"); + } + if (digest_type > 0xff) { + isc_throw(InvalidRdataText, + RRType(typeCode) << " digest type out of range"); + } + + iss.read(&peekc, 1); + if (!iss.good() || !isspace(peekc, iss.getloc())) { + isc_throw(InvalidRdataText, + RRType(typeCode) << " presentation format error"); + } + + iss >> &digestbuf; + + tag_ = tag; + algorithm_ = algorithm; + digest_type_ = digest_type; + decodeHex(digestbuf.str(), digest_); + } + + /// \brief Constructor from wire-format data. + /// + /// \param buffer A buffer storing the wire format data. + /// \param rdata_len The length of the RDATA in bytes, normally expected + /// to be the value of the RDLENGTH field of the corresponding RR. + /// + /// Exceptions + /// + /// \c InvalidRdataLength is thrown if the input data is too short for the + /// type. + DSLikeImpl(InputBuffer& buffer, size_t rdata_len) { + if (rdata_len < 4) { + isc_throw(InvalidRdataLength, RRType(typeCode) << " too short"); + } + + tag_ = buffer.readUint16(); + algorithm_ = buffer.readUint8(); + digest_type_ = buffer.readUint8(); + + rdata_len -= 4; + digest_.resize(rdata_len); + buffer.readData(&digest_[0], rdata_len); + } + + /// \brief The copy constructor. + /// + /// Trivial for now, we could've used the default one. + DSLikeImpl(const DSLikeImpl& source) { + digest_ = source.digest_; + tag_ = source.tag_; + algorithm_ = source.algorithm_; + digest_type_ = source.digest_type_; + } + + /// \brief Convert the DS-like data to a string. + /// + /// \return A \c string object that represents the DS-like data. + std::string + toText() const { + using namespace boost; + return (lexical_cast(static_cast(tag_)) + + " " + lexical_cast(static_cast(algorithm_)) + + " " + lexical_cast(static_cast(digest_type_)) + + " " + encodeHex(digest_)); + } + + /// \brief Render the DS-like data in the wire format to an OutputBuffer + /// object. + /// + /// \param buffer An output buffer to store the wire data. + void + toWire(OutputBuffer& buffer) const { + toWireCommon(buffer); + } + + /// \brief Render the DS-like data in the wire format to an + /// AbstractMessageRenderer object. + /// + /// \param renderer A renderer object to send the wire data to. + void + toWire(AbstractMessageRenderer& renderer) const { + toWireCommon(renderer); + } + + /// \brief Compare two instances of DS-like RDATA. + /// + /// It is up to the caller to make sure that \c other is an object of the + /// same \c DSLikeImpl class. + /// + /// \param other the right-hand operand to compare against. + /// \return < 0 if \c this would be sorted before \c other. + /// \return 0 if \c this is identical to \c other in terms of sorting + /// order. + /// \return > 0 if \c this would be sorted after \c other. + int + compare(const DSLikeImpl& other_ds) const { + if (tag_ != other_ds.tag_) { + return (tag_ < other_ds.tag_ ? -1 : 1); + } + if (algorithm_ != other_ds.algorithm_) { + return (algorithm_ < other_ds.algorithm_ ? -1 : 1); + } + if (digest_type_ != other_ds.digest_type_) { + return (digest_type_ < other_ds.digest_type_ ? -1 : 1); + } + + size_t this_len = digest_.size(); + size_t other_len = other_ds.digest_.size(); + size_t cmplen = min(this_len, other_len); + int cmp = memcmp(&digest_[0], &other_ds.digest_[0], cmplen); + if (cmp != 0) { + return (cmp); + } else { + return ((this_len == other_len) + ? 0 : (this_len < other_len) ? -1 : 1); + } + } + + /// \brief Accessors + uint16_t + getTag() const { + return (tag_); + } + +private: + // straightforward representation of DS RDATA fields + uint16_t tag_; + uint8_t algorithm_; + uint8_t digest_type_; + std::vector digest_; +}; + +} +} +} +} +} +#endif // __DS_LIKE_H + +// Local Variables: +// mode: c++ +// End: diff --git a/src/lib/dns/rdata/generic/dlv_32769.cc b/src/lib/dns/rdata/generic/dlv_32769.cc new file mode 100644 index 0000000000..9887aa88bd --- /dev/null +++ b/src/lib/dns/rdata/generic/dlv_32769.cc @@ -0,0 +1,121 @@ +// Copyright (C) 2011 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. + +#include + +#include +#include + +#include +#include +#include + +#include + +using namespace std; +using namespace isc::util; +using namespace isc::util::encode; +using namespace isc::dns::rdata::generic::detail; + +// BEGIN_ISC_NAMESPACE +// BEGIN_RDATA_NAMESPACE + +/// \brief Constructor from string. +/// +/// A copy of the implementation object is allocated and constructed. +DLV::DLV(const string& ds_str) : + impl_(new DLVImpl(ds_str)) +{} + +/// \brief Constructor from wire-format data. +/// +/// A copy of the implementation object is allocated and constructed. +DLV::DLV(InputBuffer& buffer, size_t rdata_len) : + impl_(new DLVImpl(buffer, rdata_len)) +{} + +/// \brief Copy constructor +/// +/// A copy of the implementation object is allocated and constructed. +DLV::DLV(const DLV& source) : + Rdata(), impl_(new DLVImpl(*source.impl_)) +{} + +/// \brief Assignment operator +/// +/// PIMPL-induced logic +DLV& +DLV::operator=(const DLV& source) { + if (impl_ == source.impl_) { + return (*this); + } + + DLVImpl* newimpl = new DLVImpl(*source.impl_); + delete impl_; + impl_ = newimpl; + + return (*this); +} + +/// \brief Destructor +/// +/// Deallocates an internal resource. +DLV::~DLV() { + delete impl_; +} + +/// \brief Convert the \c DLV to a string. +/// +/// A pass-thru to the corresponding implementation method. +string +DLV::toText() const { + return (impl_->toText()); +} + +/// \brief Render the \c DLV in the wire format to a OutputBuffer object +/// +/// A pass-thru to the corresponding implementation method. +void +DLV::toWire(OutputBuffer& buffer) const { + impl_->toWire(buffer); +} + +/// \brief Render the \c DLV in the wire format to a AbstractMessageRenderer +/// object +/// +/// A pass-thru to the corresponding implementation method. +void +DLV::toWire(AbstractMessageRenderer& renderer) const { + impl_->toWire(renderer); +} + +/// \brief Compare two instances of \c DLV RDATA. +/// +/// The type check is performed here. Otherwise, a pass-thru to the +/// corresponding implementation method. +int +DLV::compare(const Rdata& other) const { + const DLV& other_ds = dynamic_cast(other); + + return (impl_->compare(*other_ds.impl_)); +} + +/// \brief Tag accessor +uint16_t +DLV::getTag() const { + return (impl_->getTag()); +} + +// END_RDATA_NAMESPACE +// END_ISC_NAMESPACE diff --git a/src/lib/dns/rdata/generic/dlv_32769.h b/src/lib/dns/rdata/generic/dlv_32769.h new file mode 100644 index 0000000000..86cd98ce05 --- /dev/null +++ b/src/lib/dns/rdata/generic/dlv_32769.h @@ -0,0 +1,77 @@ +// Copyright (C) 2011 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. + +// BEGIN_HEADER_GUARD + +#include + +#include + +#include +#include +#include +#include + +// BEGIN_ISC_NAMESPACE + +// BEGIN_COMMON_DECLARATIONS +// END_COMMON_DECLARATIONS + +// BEGIN_RDATA_NAMESPACE + +namespace detail { +template class DSLikeImpl; +} + +/// \brief \c rdata::generic::DLV class represents the DLV RDATA as defined in +/// RFC4431. +/// +/// This class implements the basic interfaces inherited from the abstract +/// \c rdata::Rdata class, and provides trivial accessors specific to the +/// DLV RDATA. +class DLV : public Rdata { +public: + // BEGIN_COMMON_MEMBERS + // END_COMMON_MEMBERS + + /// \brief Assignment operator. + /// + /// It internally allocates a resource, and if it fails a corresponding + /// standard exception will be thrown. + /// This operator never throws an exception otherwise. + /// + /// This operator provides the strong exception guarantee: When an + /// exception is thrown the content of the assignment target will be + /// intact. + DLV& operator=(const DLV& source); + + /// \brief The destructor. + ~DLV(); + + /// \brief Return the value of the Tag field. + /// + /// This method never throws an exception. + uint16_t getTag() const; +private: + typedef detail::DSLikeImpl DLVImpl; + DLVImpl* impl_; +}; + +// END_RDATA_NAMESPACE +// END_ISC_NAMESPACE +// END_HEADER_GUARD + +// Local Variables: +// mode: c++ +// End: diff --git a/src/lib/dns/rdata/generic/ds_43.cc b/src/lib/dns/rdata/generic/ds_43.cc index 1b48456d8b..20b62dca83 100644 --- a/src/lib/dns/rdata/generic/ds_43.cc +++ b/src/lib/dns/rdata/generic/ds_43.cc @@ -1,4 +1,4 @@ -// Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2011 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 @@ -12,87 +12,32 @@ // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // PERFORMANCE OF THIS SOFTWARE. -#include #include -#include -#include - -#include #include #include #include -#include #include #include -#include -#include +#include using namespace std; using namespace isc::util; using namespace isc::util::encode; +using namespace isc::dns::rdata::generic::detail; // BEGIN_ISC_NAMESPACE // BEGIN_RDATA_NAMESPACE -struct DSImpl { - // straightforward representation of DS RDATA fields - DSImpl(uint16_t tag, uint8_t algorithm, uint8_t digest_type, - const vector& digest) : - tag_(tag), algorithm_(algorithm), digest_type_(digest_type), - digest_(digest) - {} - - uint16_t tag_; - uint8_t algorithm_; - uint8_t digest_type_; - const vector digest_; -}; - DS::DS(const string& ds_str) : - impl_(NULL) -{ - istringstream iss(ds_str); - unsigned int tag, algorithm, digest_type; - stringbuf digestbuf; + impl_(new DSImpl(ds_str)) +{} - iss >> tag >> algorithm >> digest_type >> &digestbuf; - if (iss.bad() || iss.fail()) { - isc_throw(InvalidRdataText, "Invalid DS text"); - } - if (tag > 0xffff) { - isc_throw(InvalidRdataText, "DS tag out of range"); - } - if (algorithm > 0xff) { - isc_throw(InvalidRdataText, "DS algorithm out of range"); - } - if (digest_type > 0xff) { - isc_throw(InvalidRdataText, "DS digest type out of range"); - } - - vector digest; - decodeHex(digestbuf.str(), digest); - - impl_ = new DSImpl(tag, algorithm, digest_type, digest); -} - -DS::DS(InputBuffer& buffer, size_t rdata_len) { - if (rdata_len < 4) { - isc_throw(InvalidRdataLength, "DS too short"); - } - - uint16_t tag = buffer.readUint16(); - uint16_t algorithm = buffer.readUint8(); - uint16_t digest_type = buffer.readUint8(); - - rdata_len -= 4; - vector digest(rdata_len); - buffer.readData(&digest[0], rdata_len); - - impl_ = new DSImpl(tag, algorithm, digest_type, digest); -} +DS::DS(InputBuffer& buffer, size_t rdata_len) : + impl_(new DSImpl(buffer, rdata_len)) +{} DS::DS(const DS& source) : Rdata(), impl_(new DSImpl(*source.impl_)) @@ -117,57 +62,29 @@ DS::~DS() { string DS::toText() const { - using namespace boost; - return (lexical_cast(static_cast(impl_->tag_)) + - " " + lexical_cast(static_cast(impl_->algorithm_)) + - " " + lexical_cast(static_cast(impl_->digest_type_)) + - " " + encodeHex(impl_->digest_)); + return (impl_->toText()); } void DS::toWire(OutputBuffer& buffer) const { - buffer.writeUint16(impl_->tag_); - buffer.writeUint8(impl_->algorithm_); - buffer.writeUint8(impl_->digest_type_); - buffer.writeData(&impl_->digest_[0], impl_->digest_.size()); + impl_->toWire(buffer); } void DS::toWire(AbstractMessageRenderer& renderer) const { - renderer.writeUint16(impl_->tag_); - renderer.writeUint8(impl_->algorithm_); - renderer.writeUint8(impl_->digest_type_); - renderer.writeData(&impl_->digest_[0], impl_->digest_.size()); + impl_->toWire(renderer); } int DS::compare(const Rdata& other) const { const DS& other_ds = dynamic_cast(other); - if (impl_->tag_ != other_ds.impl_->tag_) { - return (impl_->tag_ < other_ds.impl_->tag_ ? -1 : 1); - } - if (impl_->algorithm_ != other_ds.impl_->algorithm_) { - return (impl_->algorithm_ < other_ds.impl_->algorithm_ ? -1 : 1); - } - if (impl_->digest_type_ != other_ds.impl_->digest_type_) { - return (impl_->digest_type_ < other_ds.impl_->digest_type_ ? -1 : 1); - } - - size_t this_len = impl_->digest_.size(); - size_t other_len = other_ds.impl_->digest_.size(); - size_t cmplen = min(this_len, other_len); - int cmp = memcmp(&impl_->digest_[0], &other_ds.impl_->digest_[0], cmplen); - if (cmp != 0) { - return (cmp); - } else { - return ((this_len == other_len) ? 0 : (this_len < other_len) ? -1 : 1); - } + return (impl_->compare(*other_ds.impl_)); } uint16_t DS::getTag() const { - return (impl_->tag_); + return (impl_->getTag()); } // END_RDATA_NAMESPACE diff --git a/src/lib/dns/rdata/generic/ds_43.h b/src/lib/dns/rdata/generic/ds_43.h index 03b19a0903..2697f513be 100644 --- a/src/lib/dns/rdata/generic/ds_43.h +++ b/src/lib/dns/rdata/generic/ds_43.h @@ -1,4 +1,4 @@ -// Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2011 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 @@ -12,6 +12,8 @@ // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // PERFORMANCE OF THIS SOFTWARE. +// BEGIN_HEADER_GUARD + #include #include @@ -21,8 +23,6 @@ #include #include -// BEGIN_HEADER_GUARD - // BEGIN_ISC_NAMESPACE // BEGIN_COMMON_DECLARATIONS @@ -30,20 +30,41 @@ // BEGIN_RDATA_NAMESPACE -struct DSImpl; +namespace detail { +template class DSLikeImpl; +} +/// \brief \c rdata::generic::DS class represents the DS RDATA as defined in +/// RFC3658. +/// +/// This class implements the basic interfaces inherited from the abstract +/// \c rdata::Rdata class, and provides trivial accessors specific to the +/// DS RDATA. class DS : public Rdata { public: // BEGIN_COMMON_MEMBERS // END_COMMON_MEMBERS + + /// \brief Assignment operator. + /// + /// It internally allocates a resource, and if it fails a corresponding + /// standard exception will be thrown. + /// This operator never throws an exception otherwise. + /// + /// This operator provides the strong exception guarantee: When an + /// exception is thrown the content of the assignment target will be + /// intact. DS& operator=(const DS& source); + + /// \brief The destructor. ~DS(); + /// \brief Return the value of the Tag field. /// - /// Specialized methods - /// + /// This method never throws an exception. uint16_t getTag() const; private: + typedef detail::DSLikeImpl DSImpl; DSImpl* impl_; }; diff --git a/src/lib/dns/tests/Makefile.am b/src/lib/dns/tests/Makefile.am index 5f90cea949..37946782bd 100644 --- a/src/lib/dns/tests/Makefile.am +++ b/src/lib/dns/tests/Makefile.am @@ -35,7 +35,7 @@ run_unittests_SOURCES += rdata_dname_unittest.cc run_unittests_SOURCES += rdata_afsdb_unittest.cc run_unittests_SOURCES += rdata_opt_unittest.cc run_unittests_SOURCES += rdata_dnskey_unittest.cc -run_unittests_SOURCES += rdata_ds_unittest.cc +run_unittests_SOURCES += rdata_ds_like_unittest.cc run_unittests_SOURCES += rdata_nsec_unittest.cc run_unittests_SOURCES += rdata_nsec3_unittest.cc run_unittests_SOURCES += rdata_nsecbitmap_unittest.cc diff --git a/src/lib/dns/tests/rdata_ds_like_unittest.cc b/src/lib/dns/tests/rdata_ds_like_unittest.cc new file mode 100644 index 0000000000..d49e22987e --- /dev/null +++ b/src/lib/dns/tests/rdata_ds_like_unittest.cc @@ -0,0 +1,171 @@ +// Copyright (C) 2011 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. + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +using isc::UnitTestUtil; +using namespace std; +using namespace isc::dns; +using namespace isc::util; +using namespace isc::dns::rdata; + +namespace { +// hacks to make templates work +template +class RRTYPE : public RRType { +public: + RRTYPE(); +}; + +template<> RRTYPE::RRTYPE() : RRType(RRType::DS()) {} +template<> RRTYPE::RRTYPE() : RRType(RRType::DLV()) {} + +template +class Rdata_DS_LIKE_Test : public RdataTest { +protected: + static DS_LIKE const rdata_ds_like; +}; + +string ds_like_txt("12892 5 2 F1E184C0E1D615D20EB3C223ACED3B03C773DD952D" + "5F0EB5C777586DE18DA6B5"); + +template +DS_LIKE const Rdata_DS_LIKE_Test::rdata_ds_like(ds_like_txt); + +// The list of types we want to test. +typedef testing::Types Implementations; + +TYPED_TEST_CASE(Rdata_DS_LIKE_Test, Implementations); + +TYPED_TEST(Rdata_DS_LIKE_Test, toText_DS_LIKE) { + EXPECT_EQ(ds_like_txt, this->rdata_ds_like.toText()); +} + +TYPED_TEST(Rdata_DS_LIKE_Test, badText_DS_LIKE) { + EXPECT_THROW(const TypeParam ds_like2("99999 5 2 BEEF"), InvalidRdataText); + EXPECT_THROW(const TypeParam ds_like2("11111 555 2 BEEF"), + InvalidRdataText); + EXPECT_THROW(const TypeParam ds_like2("11111 5 22222 BEEF"), + InvalidRdataText); + EXPECT_THROW(const TypeParam ds_like2("11111 5 2"), InvalidRdataText); + EXPECT_THROW(const TypeParam ds_like2("GARBAGE IN"), InvalidRdataText); + // no space between the digest type and the digest. + EXPECT_THROW(const TypeParam ds_like2( + "12892 5 2F1E184C0E1D615D20EB3C223ACED3B03C773DD952D" + "5F0EB5C777586DE18DA6B5"), InvalidRdataText); +} + +TYPED_TEST(Rdata_DS_LIKE_Test, createFromWire_DS_LIKE) { + EXPECT_EQ(0, this->rdata_ds_like.compare( + *this->rdataFactoryFromFile(RRTYPE(), RRClass::IN(), + "rdata_ds_fromWire"))); +} + +TYPED_TEST(Rdata_DS_LIKE_Test, assignment_DS_LIKE) { + TypeParam copy((string(ds_like_txt))); + copy = this->rdata_ds_like; + EXPECT_EQ(0, copy.compare(this->rdata_ds_like)); + + // Check if the copied data is valid even after the original is deleted + TypeParam* copy2 = new TypeParam(this->rdata_ds_like); + TypeParam copy3((string(ds_like_txt))); + copy3 = *copy2; + delete copy2; + EXPECT_EQ(0, copy3.compare(this->rdata_ds_like)); + + // Self assignment + copy = copy; + EXPECT_EQ(0, copy.compare(this->rdata_ds_like)); +} + +TYPED_TEST(Rdata_DS_LIKE_Test, getTag_DS_LIKE) { + EXPECT_EQ(12892, this->rdata_ds_like.getTag()); +} + +TYPED_TEST(Rdata_DS_LIKE_Test, toWireRenderer) { + Rdata_DS_LIKE_Test::renderer.skip(2); + TypeParam rdata_ds_like(ds_like_txt); + rdata_ds_like.toWire(this->renderer); + + vector data; + UnitTestUtil::readWireData("rdata_ds_fromWire", data); + EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, + static_cast + (this->obuffer.getData()) + 2, + this->obuffer.getLength() - 2, + &data[2], data.size() - 2); +} + +TYPED_TEST(Rdata_DS_LIKE_Test, toWireBuffer) { + TypeParam rdata_ds_like(ds_like_txt); + rdata_ds_like.toWire(this->obuffer); +} + +string ds_like_txt1("12892 5 2 F1E184C0E1D615D20EB3C223ACED3B03C773DD952D" + "5F0EB5C777586DE18DA6B5"); +// different tag +string ds_like_txt2("12893 5 2 F1E184C0E1D615D20EB3C223ACED3B03C773DD952D" + "5F0EB5C777586DE18DA6B5"); +// different algorithm +string ds_like_txt3("12892 6 2 F1E184C0E1D615D20EB3C223ACED3B03C773DD952D" + "5F0EB5C777586DE18DA6B5"); +// different digest type +string ds_like_txt4("12892 5 3 F1E184C0E1D615D20EB3C223ACED3B03C773DD952D" + "5F0EB5C777586DE18DA6B5"); +// different digest +string ds_like_txt5("12892 5 2 F2E184C0E1D615D20EB3C223ACED3B03C773DD952D" + "5F0EB5C777586DE18DA6B5"); +// different digest length +string ds_like_txt6("12892 5 2 F2E184C0E1D615D20EB3C223ACED3B03C773DD952D" + "5F0EB5C777586DE18DA6B555"); + +TYPED_TEST(Rdata_DS_LIKE_Test, compare) { + // trivial case: self equivalence + EXPECT_EQ(0, TypeParam(ds_like_txt).compare(TypeParam(ds_like_txt))); + + // non-equivalence tests + EXPECT_LT(TypeParam(ds_like_txt1).compare(TypeParam(ds_like_txt2)), 0); + EXPECT_GT(TypeParam(ds_like_txt2).compare(TypeParam(ds_like_txt1)), 0); + + EXPECT_LT(TypeParam(ds_like_txt1).compare(TypeParam(ds_like_txt3)), 0); + EXPECT_GT(TypeParam(ds_like_txt3).compare(TypeParam(ds_like_txt1)), 0); + + EXPECT_LT(TypeParam(ds_like_txt1).compare(TypeParam(ds_like_txt4)), 0); + EXPECT_GT(TypeParam(ds_like_txt4).compare(TypeParam(ds_like_txt1)), 0); + + EXPECT_LT(TypeParam(ds_like_txt1).compare(TypeParam(ds_like_txt5)), 0); + EXPECT_GT(TypeParam(ds_like_txt5).compare(TypeParam(ds_like_txt1)), 0); + + EXPECT_LT(TypeParam(ds_like_txt1).compare(TypeParam(ds_like_txt6)), 0); + EXPECT_GT(TypeParam(ds_like_txt6).compare(TypeParam(ds_like_txt1)), 0); + + // comparison attempt between incompatible RR types should be rejected + EXPECT_THROW(this->rdata_ds_like.compare(*RdataTest::rdata_nomatch), + bad_cast); +} + +} diff --git a/src/lib/dns/tests/rdata_ds_unittest.cc b/src/lib/dns/tests/rdata_ds_unittest.cc deleted file mode 100644 index 59886208cf..0000000000 --- a/src/lib/dns/tests/rdata_ds_unittest.cc +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright (C) 2010 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. - -#include - -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -using isc::UnitTestUtil; -using namespace std; -using namespace isc::dns; -using namespace isc::util; -using namespace isc::dns::rdata; - -namespace { -class Rdata_DS_Test : public RdataTest { - // there's nothing to specialize -}; - -string ds_txt("12892 5 2 F1E184C0E1D615D20EB3C223ACED3B03C773DD952D" - "5F0EB5C777586DE18DA6B5"); -const generic::DS rdata_ds(ds_txt); - -TEST_F(Rdata_DS_Test, toText_DS) { - EXPECT_EQ(ds_txt, rdata_ds.toText()); -} - -TEST_F(Rdata_DS_Test, badText_DS) { - EXPECT_THROW(const generic::DS ds2("99999 5 2 BEEF"), InvalidRdataText); - EXPECT_THROW(const generic::DS ds2("11111 555 2 BEEF"), InvalidRdataText); - EXPECT_THROW(const generic::DS ds2("11111 5 22222 BEEF"), InvalidRdataText); - EXPECT_THROW(const generic::DS ds2("11111 5 2"), InvalidRdataText); - EXPECT_THROW(const generic::DS ds2("GARBAGE IN"), InvalidRdataText); -} - -// this test currently fails; we must fix it, and then migrate the test to -// badText_DS -TEST_F(Rdata_DS_Test, DISABLED_badText_DS) { - // no space between the digest type and the digest. - EXPECT_THROW(const generic::DS ds2( - "12892 5 2F1E184C0E1D615D20EB3C223ACED3B03C773DD952D" - "5F0EB5C777586DE18DA6B5"), InvalidRdataText); -} - -TEST_F(Rdata_DS_Test, createFromWire_DS) { - EXPECT_EQ(0, rdata_ds.compare( - *rdataFactoryFromFile(RRType::DS(), RRClass::IN(), - "rdata_ds_fromWire"))); -} - -TEST_F(Rdata_DS_Test, getTag_DS) { - EXPECT_EQ(12892, rdata_ds.getTag()); -} - -TEST_F(Rdata_DS_Test, toWireRenderer) { - renderer.skip(2); - generic::DS rdata_ds(ds_txt); - rdata_ds.toWire(renderer); - - vector data; - UnitTestUtil::readWireData("rdata_ds_fromWire", data); - EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, - static_cast(obuffer.getData()) + 2, - obuffer.getLength() - 2, &data[2], data.size() - 2); -} - -TEST_F(Rdata_DS_Test, toWireBuffer) { - generic::DS rdata_ds(ds_txt); - rdata_ds.toWire(obuffer); -} - -TEST_F(Rdata_DS_Test, compare) { - // trivial case: self equivalence - EXPECT_EQ(0, generic::DS(ds_txt).compare(generic::DS(ds_txt))); - - // TODO: need more tests -} - -} diff --git a/tests/system/cleanall.sh b/tests/system/cleanall.sh index 17c3d4a6eb..d23d103882 100755 --- a/tests/system/cleanall.sh +++ b/tests/system/cleanall.sh @@ -27,7 +27,10 @@ find . -type f \( \ status=0 -for d in `find . -type d -maxdepth 1 -mindepth 1 -print` +for d in ./.* ./* do + case $d in ./.|./..) continue ;; esac + test -d $d || continue + test ! -f $d/clean.sh || ( cd $d && sh clean.sh ) done