123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260 |
- // 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.
- #include <dns/exceptions.h>
- #include <dns/rdata.h>
- #include <dns/rdataclass.h>
- #include <dns/rrclass.h>
- #include <dns/rrtype.h>
- #include <gtest/gtest.h>
- #include <dns/tests/unittest_util.h>
- #include <dns/tests/rdata_unittest.h>
- #include <string>
- #include <vector>
- using namespace std;
- using isc::UnitTestUtil;
- using namespace isc::dns;
- using namespace isc::dns::rdata;
- namespace {
- // Template for shared tests for NSEC3 and NSEC3PARAM
- template <typename RDATA_TYPE>
- class NSEC3PARAMLikeTest : public RdataTest {
- protected:
- NSEC3PARAMLikeTest() :
- salt_txt("1 1 1 D399EAAB" + getCommonText()),
- nosalt_txt("1 1 1 -" + getCommonText()),
- obuffer(0)
- {}
- RDATA_TYPE fromText(const string& rdata_text) {
- return (RDATA_TYPE(rdata_text));
- }
- void compareCheck() const {
- typename vector<RDATA_TYPE>::const_iterator it;
- typename vector<RDATA_TYPE>::const_iterator const it_end =
- compare_set.end();
- for (it = compare_set.begin(); it != it_end - 1; ++it) {
- SCOPED_TRACE("compare " + it->toText() + " to " +
- (it + 1)->toText());
- EXPECT_GT(0, (*it).compare(*(it + 1)));
- EXPECT_LT(0, (*(it + 1)).compare(*it));
- }
- }
- const string salt_txt; // RDATA text with salt
- const string nosalt_txt; // RDATA text without salt
- OutputBuffer obuffer; // used in toWire() tests
- MessageRenderer renderer; // ditto
- vector<RDATA_TYPE> compare_set; // used in compare() tests
- // Convert generic Rdata to the corresponding derived Rdata class object.
- // Defined here because it depends on the template parameter.
- static const RDATA_TYPE& convert(const Rdata& rdata) {
- return (dynamic_cast<const RDATA_TYPE&>(rdata));
- }
- // These depend on the specific RR type. We use specialized methods
- // for them.
- static RRType getType(); // return either RRType::NSEC3() or NSEC3PARAM()
- static string getWireFilePrefix();
- static string getCommonText(); // commonly used part of textual form
- };
- // Instantiate specific typed tests
- typedef ::testing::Types<generic::NSEC3, generic::NSEC3PARAM> TestRdataTypes;
- TYPED_TEST_CASE(NSEC3PARAMLikeTest, TestRdataTypes);
- template <>
- RRType
- NSEC3PARAMLikeTest<generic::NSEC3>::getType() {
- return (RRType::NSEC3());
- }
- template <>
- RRType
- NSEC3PARAMLikeTest<generic::NSEC3PARAM>::getType() {
- return (RRType::NSEC3PARAM());
- }
- template <>
- string
- NSEC3PARAMLikeTest<generic::NSEC3>::getWireFilePrefix() {
- return ("rdata_nsec3_");
- }
- template <>
- string
- NSEC3PARAMLikeTest<generic::NSEC3PARAM>::getWireFilePrefix() {
- return ("rdata_nsec3param_");
- }
- template <>
- string
- NSEC3PARAMLikeTest<generic::NSEC3>::getCommonText() {
- // next hash + RR type bitmap
- return (" H9RSFB7FPF2L8HG35CMPC765TDK23RP6 "
- "NS SOA RRSIG DNSKEY NSEC3PARAM");
- }
- template <>
- string
- NSEC3PARAMLikeTest<generic::NSEC3PARAM>::getCommonText() {
- // there's no more text for NSEC3PARAM
- return ("");
- }
- TYPED_TEST(NSEC3PARAMLikeTest, fromText) {
- // Numeric parameters have possible maximum values. Unusual, but must
- // be accepted.
- EXPECT_NO_THROW(this->fromText("255 255 65535 D399EAAB" +
- this->getCommonText()));
- // 0-length salt
- EXPECT_EQ(0, this->fromText(this->nosalt_txt).getSalt().size());
- // salt that has the possible max length
- EXPECT_EQ(255, this->fromText("1 1 1 " + string(255 * 2, '0') +
- this->getCommonText()).getSalt().size());
- }
- TYPED_TEST(NSEC3PARAMLikeTest, badText) {
- // Bad salt hex
- EXPECT_THROW(this->fromText("1 1 1 SPORK0" + this->getCommonText()),
- isc::BadValue);
- EXPECT_THROW(this->fromText("1 1 1 ADDAFEE" + this->getCommonText()),
- isc::BadValue);
- // Space within salt
- EXPECT_THROW(this->fromText("1 1 1 ADDAFE ADDAFEEE" +
- this->getCommonText()),
- InvalidRdataText);
- // Similar to empty salt, but not really. This shouldn't cause confusion.
- EXPECT_THROW(this->fromText("1 1 1 --" + this->getCommonText()),
- isc::BadValue);
- // Too large algorithm
- EXPECT_THROW(this->fromText("1000000 1 1 ADDAFEEE" + this->getCommonText()),
- InvalidRdataText);
- // Too large flags
- EXPECT_THROW(this->fromText("1 1000000 1 ADDAFEEE" + this->getCommonText()),
- InvalidRdataText);
- // Too large iterations
- EXPECT_THROW(this->fromText("1 1 65536 ADDAFEEE" + this->getCommonText()),
- InvalidRdataText);
- // There should be a space between "1" and "D399EAAB" (salt)
- EXPECT_THROW(this->fromText("1 1 1D399EAAB" + this->getCommonText()),
- InvalidRdataText);
- // Salt is too long (possible max + 1 bytes)
- EXPECT_THROW(this->fromText("1 1 1 " + string(256 * 2, '0') +
- this->getCommonText()),
- InvalidRdataText);
- }
- TYPED_TEST(NSEC3PARAMLikeTest, toText) {
- // normal case
- EXPECT_EQ(this->salt_txt, this->fromText(this->salt_txt).toText());
- // empty salt case
- EXPECT_EQ(this->nosalt_txt, this->fromText(this->nosalt_txt).toText());
- }
- TYPED_TEST(NSEC3PARAMLikeTest, createFromWire) {
- // Normal case
- EXPECT_EQ(0, this->fromText(this->salt_txt).compare(
- *this->rdataFactoryFromFile(this->getType(), RRClass::IN(),
- (this->getWireFilePrefix() +
- "fromWire1").c_str())));
- // Too short RDLENGTH: it doesn't even contain the first 5 octets.
- EXPECT_THROW(this->rdataFactoryFromFile(this->getType(), RRClass::IN(),
- (this->getWireFilePrefix() +
- "fromWire2.wire").c_str()),
- DNSMessageFORMERR);
- // salt length is too large
- EXPECT_THROW(this->rdataFactoryFromFile(this->getType(), RRClass::IN(),
- (this->getWireFilePrefix() +
- "fromWire11.wire").c_str()),
- DNSMessageFORMERR);
- // empty salt. not so usual, but valid.
- ConstRdataPtr rdata =
- this->rdataFactoryFromFile(this->getType(), RRClass::IN(),
- (this->getWireFilePrefix() +
- "fromWire13.wire").c_str());
- EXPECT_EQ(0, this->convert(*rdata).getSalt().size());
- }
- template <typename OUTPUT_TYPE>
- void
- toWireCheck(RRType rrtype, OUTPUT_TYPE& output, const string& data_file) {
- vector<uint8_t> data;
- UnitTestUtil::readWireData(data_file.c_str(), data);
- InputBuffer buffer(&data[0], data.size());
- const uint16_t rdlen = buffer.readUint16();
- output.clear();
- output.writeUint16(rdlen);
- createRdata(rrtype, RRClass::IN(), buffer, rdlen)->toWire(output);
- EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData, output.getData(),
- output.getLength(), &data[0], data.size());
- }
- TYPED_TEST(NSEC3PARAMLikeTest, toWire) {
- // normal case
- toWireCheck(this->getType(), this->renderer,
- this->getWireFilePrefix() + "fromWire1");
- toWireCheck(this->getType(), this->obuffer,
- this->getWireFilePrefix() + "fromWire1");
- // empty salt
- toWireCheck(this->getType(), this->renderer,
- this->getWireFilePrefix() + "fromWire13.wire");
- toWireCheck(this->getType(), this->obuffer,
- this->getWireFilePrefix() + "fromWire13.wire");
- }
- TYPED_TEST(NSEC3PARAMLikeTest, compare) {
- // test RDATAs, sorted in the ascendent order.
- this->compare_set.push_back(this->fromText("0 0 0 D399EAAB" +
- this->getCommonText()));
- this->compare_set.push_back(this->fromText("1 0 0 D399EAAB" +
- this->getCommonText()));
- this->compare_set.push_back(this->fromText("1 1 0 D399EAAB" +
- this->getCommonText()));
- this->compare_set.push_back(this->fromText("1 1 1 -" +
- this->getCommonText()));
- this->compare_set.push_back(this->fromText("1 1 1 D399EAAB" +
- this->getCommonText()));
- this->compare_set.push_back(this->fromText("1 1 1 FF99EAAB" +
- this->getCommonText()));
- this->compare_set.push_back(this->fromText("1 1 1 FF99EA0000" +
- this->getCommonText()));
- this->compareCheck();
- }
- }
|