123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297 |
- // 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 <vector>
- #include <string>
- #include <sstream>
- #include <dns/buffer.h>
- #include <dns/messagerenderer.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>
- using isc::UnitTestUtil;
- using namespace std;
- using namespace isc::dns;
- using namespace isc::dns::rdata;
- namespace isc {
- namespace dns {
- namespace rdata {
- RdataTest::RdataTest() :
- obuffer(0), renderer(obuffer),
- rdata_nomatch(createRdata(RRType(0), RRClass(1), "\\# 0"))
- {}
- RdataPtr
- RdataTest::rdataFactoryFromFile(const RRType& rrtype, const RRClass& rrclass,
- const char* datafile, size_t position)
- {
- std::vector<unsigned char> data;
- UnitTestUtil::readWireData(datafile, data);
- InputBuffer buffer(&data[0], data.size());
- buffer.setPosition(position);
- uint16_t rdlen = buffer.readUint16();
- return (createRdata(rrtype, rrclass, buffer, rdlen));
- }
- }
- }
- }
- namespace {
- class Rdata_Unknown_Test : public RdataTest {
- protected:
- static string getLongestRdataTxt();
- static void getLongestRdataWire(vector<uint8_t>& v);
- };
- string
- Rdata_Unknown_Test::getLongestRdataTxt() {
- ostringstream oss;
- oss << "\\# " << MAX_RDLENGTH << " ";
- oss.fill('0');
- oss << right << hex;
- for (int i = 0; i < MAX_RDLENGTH; i++) {
- oss << setw(2) << (i & 0xff);
- }
- return (oss.str());
- }
- void
- Rdata_Unknown_Test::getLongestRdataWire(vector<uint8_t>& v) {
- unsigned char ch = 0;
- for (int i = 0; i < MAX_RDLENGTH; ++i, ++ch) {
- v.push_back(ch);
- }
- }
- const string rdata_unknowntxt("\\# 4 a1b2c30d");
- const generic::Generic rdata_unknown(rdata_unknowntxt);
- // Wire-format data correspond to rdata_unknown. Note that it doesn't include
- // RDLENGTH
- const uint8_t wiredata_unknown[] = { 0xa1, 0xb2, 0xc3, 0x0d };
- // "Unknown" RR Type used for the test cases below. If/when we use this
- // type number as a "well-known" (probably experimental) type, we'll need to
- // renumber it.
- const RRType unknown_rrtype = RRType(65000);
- TEST_F(Rdata_Unknown_Test, createFromText) {
- // valid construction. This also tests a normal case of "FromWire".
- EXPECT_EQ(0, generic::Generic("\\# 4 a1b2c30d").compare(
- *rdataFactoryFromFile(unknown_rrtype, RRClass::IN(),
- "rdata_unknown_fromWire")));
- // upper case hexadecimal digits should also be okay.
- EXPECT_EQ(0, generic::Generic("\\# 4 A1B2C30D").compare(
- *rdataFactoryFromFile(unknown_rrtype, RRClass::IN(),
- "rdata_unknown_fromWire")));
- // 0-length RDATA should be accepted
- EXPECT_EQ(0, generic::Generic("\\# 0").compare(
- *rdataFactoryFromFile(unknown_rrtype, RRClass::IN(),
- "rdata_unknown_fromWire", 6)));
- // hex encoding can be space-separated
- EXPECT_EQ(0, generic::Generic("\\# 4 a1 b2c30d").compare(rdata_unknown));
- EXPECT_EQ(0, generic::Generic("\\# 4 a1b2 c30d").compare(rdata_unknown));
- EXPECT_EQ(0, generic::Generic("\\# 4 a1 b2 c3 0d").compare(rdata_unknown));
- EXPECT_EQ(0, generic::Generic("\\# 4 a1\tb2c3 0d").compare(rdata_unknown));
- // Max-length RDATA
- vector<uint8_t> v;
- getLongestRdataWire(v);
- InputBuffer ibuffer(&v[0], v.size());
- EXPECT_EQ(0, generic::Generic(getLongestRdataTxt()).compare(
- generic::Generic(ibuffer, v.size())));
- // the length field must match the encoding data length.
- EXPECT_THROW(generic::Generic("\\# 4 1080c0ff00"), InvalidRdataLength);
- EXPECT_THROW(generic::Generic("\\# 5 1080c0ff"), InvalidRdataLength);
- // RDATA encoding part must consist of an even number of hex digits.
- EXPECT_THROW(generic::Generic("\\# 1 1"), InvalidRdataText);
- EXPECT_THROW(generic::Generic("\\# 1 ax"), InvalidRdataText);
- // the length should be 16-bit unsigned integer
- EXPECT_THROW(generic::Generic("\\# 65536 a1b2c30d"), InvalidRdataLength);
- EXPECT_THROW(generic::Generic("\\# -1 a1b2c30d"), InvalidRdataLength);
- EXPECT_THROW(generic::Generic("\\# 1.1 a1"), InvalidRdataText);
- EXPECT_THROW(generic::Generic("\\# 0a 00010203040506070809"),
- InvalidRdataText);
- // should reject if the special token is missing.
- EXPECT_THROW(generic::Generic("4 a1b2c30d"), InvalidRdataText);
- // the special token, the RDLENGTH and the data must be space separated.
- EXPECT_THROW(generic::Generic("\\#0"), InvalidRdataText);
- EXPECT_THROW(generic::Generic("\\# 1ff"), InvalidRdataText);
- }
- TEST_F(Rdata_Unknown_Test, createFromWire) {
- // normal case (including 0-length data) is covered in createFromText.
- // buffer too short. the error should be detected in buffer read
- EXPECT_THROW(rdataFactoryFromFile(unknown_rrtype, RRClass::IN(),
- "rdata_unknown_fromWire", 8),
- InvalidBufferPosition);
- // too large data
- vector<uint8_t> v;
- getLongestRdataWire(v);
- v.push_back(0); // making it too long
- InputBuffer ibuffer(&v[0], v.size());
- EXPECT_THROW(generic::Generic(ibuffer, v.size()), InvalidRdataLength);
- }
- // The following 3 sets of tests check the behavior of createRdata() variants
- // with the "unknown" RRtype. The result should be RRclass independent.
- TEST_F(Rdata_Unknown_Test, createRdataFromString) {
- EXPECT_EQ(0, rdata_unknown.compare(
- *createRdata(unknown_rrtype, RRClass::IN(),
- rdata_unknowntxt)));
- EXPECT_EQ(0, rdata_unknown.compare(
- *createRdata(unknown_rrtype, RRClass::CH(),
- rdata_unknowntxt)));
- EXPECT_EQ(0, rdata_unknown.compare(
- *createRdata(unknown_rrtype, RRClass("CLASS65000"),
- rdata_unknowntxt)));
- }
- TEST_F(Rdata_Unknown_Test, createRdataFromWire) {
- InputBuffer ibuffer(wiredata_unknown, sizeof(wiredata_unknown));
- EXPECT_EQ(0, rdata_unknown.compare(
- *createRdata(unknown_rrtype, RRClass::IN(),
- ibuffer, sizeof(wiredata_unknown))));
- InputBuffer ibuffer2(wiredata_unknown, sizeof(wiredata_unknown));
- EXPECT_EQ(0, rdata_unknown.compare(
- *createRdata(unknown_rrtype, RRClass::CH(),
- ibuffer2, sizeof(wiredata_unknown))));
- InputBuffer ibuffer3(wiredata_unknown, sizeof(wiredata_unknown));
- EXPECT_EQ(0, rdata_unknown.compare(
- *createRdata(unknown_rrtype, RRClass(65000),
- ibuffer3, sizeof(wiredata_unknown))));
- }
- TEST_F(Rdata_Unknown_Test, createRdataByCopy) {
- EXPECT_EQ(0, rdata_unknown.compare(
- *createRdata(unknown_rrtype, RRClass::IN(), rdata_unknown)));
- EXPECT_EQ(0, rdata_unknown.compare(
- *createRdata(unknown_rrtype, RRClass::CH(), rdata_unknown)));
- EXPECT_EQ(0, rdata_unknown.compare(
- *createRdata(unknown_rrtype, RRClass(65000),
- rdata_unknown)));
- }
- TEST_F(Rdata_Unknown_Test, copyConstruct) {
- generic::Generic copy(rdata_unknown);
- EXPECT_EQ(0, copy.compare(rdata_unknown));
- // Check the copied data is valid even after the original is deleted
- generic::Generic* copy2 = new generic::Generic(rdata_unknown);
- generic::Generic copy3(*copy2);
- delete copy2;
- EXPECT_EQ(0, copy3.compare(rdata_unknown));
- }
- TEST_F(Rdata_Unknown_Test, assignment) {
- generic::Generic copy("\\# 1 10");
- copy = rdata_unknown;
- EXPECT_EQ(0, copy.compare(rdata_unknown));
- // Check if the copied data is valid even after the original is deleted
- generic::Generic* copy2 = new generic::Generic(rdata_unknown);
- generic::Generic copy3("\\# 1 10");
- copy3 = *copy2;
- delete copy2;
- EXPECT_EQ(0, copy3.compare(rdata_unknown));
- // Self assignment
- copy = copy;
- EXPECT_EQ(0, copy.compare(rdata_unknown));
- }
- TEST_F(Rdata_Unknown_Test, toText) {
- EXPECT_EQ(rdata_unknowntxt, rdata_unknown.toText());
- EXPECT_EQ(getLongestRdataTxt(),
- generic::Generic(getLongestRdataTxt()).toText());
- }
- TEST_F(Rdata_Unknown_Test, toWireBuffer) {
- rdata_unknown.toWire(obuffer);
- EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
- obuffer.getData(), obuffer.getLength(),
- wiredata_unknown, sizeof(wiredata_unknown));
- }
- TEST_F(Rdata_Unknown_Test, toWireRenderer) {
- rdata_unknown.toWire(renderer);
- EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
- obuffer.getData(), obuffer.getLength(),
- wiredata_unknown, sizeof(wiredata_unknown));
- }
- TEST_F(Rdata_Unknown_Test, compare) {
- // comparison as left-justified unsigned octet sequences:
- EXPECT_EQ(0, rdata_unknown.compare(rdata_unknown));
- generic::Generic rdata_unknown_small("\\# 4 00b2c3ff");
- EXPECT_GT(0, rdata_unknown_small.compare(rdata_unknown));
- EXPECT_LT(0, rdata_unknown.compare(rdata_unknown_small));
- generic::Generic rdata_unknown_large("\\# 4 ffb2c300");
- EXPECT_LT(0, rdata_unknown_large.compare(rdata_unknown));
- EXPECT_GT(0, rdata_unknown.compare(rdata_unknown_large));
- // the absence of an octet sorts before a zero octet.
- generic::Generic rdata_unknown_short("\\# 3 a1b2c3");
- EXPECT_GT(0, rdata_unknown_short.compare(rdata_unknown));
- EXPECT_LT(0, rdata_unknown.compare(rdata_unknown_short));
- }
- TEST_F(Rdata_Unknown_Test, LeftShiftOperator) {
- ostringstream oss;
- oss << rdata_unknown;
- EXPECT_EQ(rdata_unknown.toText(), oss.str());
- }
- //
- // Tests for global utility functions
- //
- TEST_F(RdataTest, compareNames) {
- Name small("a.example");
- Name large("example");
- // Check the case where the order is different from the owner name
- // comparison:
- EXPECT_TRUE(small > large);
- EXPECT_EQ(-1, compareNames(small, large));
- EXPECT_EQ(1, compareNames(large, small));
- // Check case insensitive comparison:
- Name small_upper("A.EXAMPLE");
- EXPECT_EQ(0, compareNames(small, small_upper));
- // the absence of an octet sorts before a zero octet.
- Name large2("a.example2");
- EXPECT_EQ(-1, compareNames(small, large2));
- EXPECT_EQ(1, compareNames(large2, small));
- }
- }
|