rdata_unittest.cc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. // Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. #include <vector>
  15. #include <string>
  16. #include <sstream>
  17. #include <dns/buffer.h>
  18. #include <dns/messagerenderer.h>
  19. #include <dns/rdata.h>
  20. #include <dns/rdataclass.h>
  21. #include <dns/rrclass.h>
  22. #include <dns/rrtype.h>
  23. #include <gtest/gtest.h>
  24. #include <dns/tests/unittest_util.h>
  25. #include <dns/tests/rdata_unittest.h>
  26. using isc::UnitTestUtil;
  27. using namespace std;
  28. using namespace isc::dns;
  29. using namespace isc::dns::rdata;
  30. namespace isc {
  31. namespace dns {
  32. namespace rdata {
  33. RdataTest::RdataTest() :
  34. obuffer(0), renderer(obuffer),
  35. rdata_nomatch(createRdata(RRType(0), RRClass(1), "\\# 0"))
  36. {}
  37. RdataPtr
  38. RdataTest::rdataFactoryFromFile(const RRType& rrtype, const RRClass& rrclass,
  39. const char* datafile, size_t position)
  40. {
  41. std::vector<unsigned char> data;
  42. UnitTestUtil::readWireData(datafile, data);
  43. InputBuffer buffer(&data[0], data.size());
  44. buffer.setPosition(position);
  45. uint16_t rdlen = buffer.readUint16();
  46. return (createRdata(rrtype, rrclass, buffer, rdlen));
  47. }
  48. }
  49. }
  50. }
  51. namespace {
  52. class Rdata_Unknown_Test : public RdataTest {
  53. protected:
  54. static string getLongestRdataTxt();
  55. static void getLongestRdataWire(vector<uint8_t>& v);
  56. };
  57. string
  58. Rdata_Unknown_Test::getLongestRdataTxt() {
  59. ostringstream oss;
  60. oss << "\\# " << MAX_RDLENGTH << " ";
  61. oss.fill('0');
  62. oss << right << hex;
  63. for (int i = 0; i < MAX_RDLENGTH; i++) {
  64. oss << setw(2) << (i & 0xff);
  65. }
  66. return (oss.str());
  67. }
  68. void
  69. Rdata_Unknown_Test::getLongestRdataWire(vector<uint8_t>& v) {
  70. unsigned char ch = 0;
  71. for (int i = 0; i < MAX_RDLENGTH; ++i, ++ch) {
  72. v.push_back(ch);
  73. }
  74. }
  75. const string rdata_unknowntxt("\\# 4 a1b2c30d");
  76. const generic::Generic rdata_unknown(rdata_unknowntxt);
  77. // Wire-format data correspond to rdata_unknown. Note that it doesn't include
  78. // RDLENGTH
  79. const uint8_t wiredata_unknown[] = { 0xa1, 0xb2, 0xc3, 0x0d };
  80. // "Unknown" RR Type used for the test cases below. If/when we use this
  81. // type number as a "well-known" (probably experimental) type, we'll need to
  82. // renumber it.
  83. const RRType unknown_rrtype = RRType(65000);
  84. TEST_F(Rdata_Unknown_Test, createFromText) {
  85. // valid construction. This also tests a normal case of "FromWire".
  86. EXPECT_EQ(0, generic::Generic("\\# 4 a1b2c30d").compare(
  87. *rdataFactoryFromFile(unknown_rrtype, RRClass::IN(),
  88. "rdata_unknown_fromWire")));
  89. // upper case hexadecimal digits should also be okay.
  90. EXPECT_EQ(0, generic::Generic("\\# 4 A1B2C30D").compare(
  91. *rdataFactoryFromFile(unknown_rrtype, RRClass::IN(),
  92. "rdata_unknown_fromWire")));
  93. // 0-length RDATA should be accepted
  94. EXPECT_EQ(0, generic::Generic("\\# 0").compare(
  95. *rdataFactoryFromFile(unknown_rrtype, RRClass::IN(),
  96. "rdata_unknown_fromWire", 6)));
  97. // hex encoding can be space-separated
  98. EXPECT_EQ(0, generic::Generic("\\# 4 a1 b2c30d").compare(rdata_unknown));
  99. EXPECT_EQ(0, generic::Generic("\\# 4 a1b2 c30d").compare(rdata_unknown));
  100. EXPECT_EQ(0, generic::Generic("\\# 4 a1 b2 c3 0d").compare(rdata_unknown));
  101. EXPECT_EQ(0, generic::Generic("\\# 4 a1\tb2c3 0d").compare(rdata_unknown));
  102. // Max-length RDATA
  103. vector<uint8_t> v;
  104. getLongestRdataWire(v);
  105. InputBuffer ibuffer(&v[0], v.size());
  106. EXPECT_EQ(0, generic::Generic(getLongestRdataTxt()).compare(
  107. generic::Generic(ibuffer, v.size())));
  108. // the length field must match the encoding data length.
  109. EXPECT_THROW(generic::Generic("\\# 4 1080c0ff00"), InvalidRdataLength);
  110. EXPECT_THROW(generic::Generic("\\# 5 1080c0ff"), InvalidRdataLength);
  111. // RDATA encoding part must consist of an even number of hex digits.
  112. EXPECT_THROW(generic::Generic("\\# 1 1"), InvalidRdataText);
  113. EXPECT_THROW(generic::Generic("\\# 1 ax"), InvalidRdataText);
  114. // the length should be 16-bit unsigned integer
  115. EXPECT_THROW(generic::Generic("\\# 65536 a1b2c30d"), InvalidRdataLength);
  116. EXPECT_THROW(generic::Generic("\\# -1 a1b2c30d"), InvalidRdataLength);
  117. EXPECT_THROW(generic::Generic("\\# 1.1 a1"), InvalidRdataText);
  118. EXPECT_THROW(generic::Generic("\\# 0a 00010203040506070809"),
  119. InvalidRdataText);
  120. // should reject if the special token is missing.
  121. EXPECT_THROW(generic::Generic("4 a1b2c30d"), InvalidRdataText);
  122. // the special token, the RDLENGTH and the data must be space separated.
  123. EXPECT_THROW(generic::Generic("\\#0"), InvalidRdataText);
  124. EXPECT_THROW(generic::Generic("\\# 1ff"), InvalidRdataText);
  125. }
  126. TEST_F(Rdata_Unknown_Test, createFromWire) {
  127. // normal case (including 0-length data) is covered in createFromText.
  128. // buffer too short. the error should be detected in buffer read
  129. EXPECT_THROW(rdataFactoryFromFile(unknown_rrtype, RRClass::IN(),
  130. "rdata_unknown_fromWire", 8),
  131. InvalidBufferPosition);
  132. // too large data
  133. vector<uint8_t> v;
  134. getLongestRdataWire(v);
  135. v.push_back(0); // making it too long
  136. InputBuffer ibuffer(&v[0], v.size());
  137. EXPECT_THROW(generic::Generic(ibuffer, v.size()), InvalidRdataLength);
  138. }
  139. // The following 3 sets of tests check the behavior of createRdata() variants
  140. // with the "unknown" RRtype. The result should be RRclass independent.
  141. TEST_F(Rdata_Unknown_Test, createRdataFromString) {
  142. EXPECT_EQ(0, rdata_unknown.compare(
  143. *createRdata(unknown_rrtype, RRClass::IN(),
  144. rdata_unknowntxt)));
  145. EXPECT_EQ(0, rdata_unknown.compare(
  146. *createRdata(unknown_rrtype, RRClass::CH(),
  147. rdata_unknowntxt)));
  148. EXPECT_EQ(0, rdata_unknown.compare(
  149. *createRdata(unknown_rrtype, RRClass("CLASS65000"),
  150. rdata_unknowntxt)));
  151. }
  152. TEST_F(Rdata_Unknown_Test, createRdataFromWire) {
  153. InputBuffer ibuffer(wiredata_unknown, sizeof(wiredata_unknown));
  154. EXPECT_EQ(0, rdata_unknown.compare(
  155. *createRdata(unknown_rrtype, RRClass::IN(),
  156. ibuffer, sizeof(wiredata_unknown))));
  157. InputBuffer ibuffer2(wiredata_unknown, sizeof(wiredata_unknown));
  158. EXPECT_EQ(0, rdata_unknown.compare(
  159. *createRdata(unknown_rrtype, RRClass::CH(),
  160. ibuffer2, sizeof(wiredata_unknown))));
  161. InputBuffer ibuffer3(wiredata_unknown, sizeof(wiredata_unknown));
  162. EXPECT_EQ(0, rdata_unknown.compare(
  163. *createRdata(unknown_rrtype, RRClass(65000),
  164. ibuffer3, sizeof(wiredata_unknown))));
  165. }
  166. TEST_F(Rdata_Unknown_Test, createRdataByCopy) {
  167. EXPECT_EQ(0, rdata_unknown.compare(
  168. *createRdata(unknown_rrtype, RRClass::IN(), rdata_unknown)));
  169. EXPECT_EQ(0, rdata_unknown.compare(
  170. *createRdata(unknown_rrtype, RRClass::CH(), rdata_unknown)));
  171. EXPECT_EQ(0, rdata_unknown.compare(
  172. *createRdata(unknown_rrtype, RRClass(65000),
  173. rdata_unknown)));
  174. }
  175. TEST_F(Rdata_Unknown_Test, copyConstruct) {
  176. generic::Generic copy(rdata_unknown);
  177. EXPECT_EQ(0, copy.compare(rdata_unknown));
  178. // Check the copied data is valid even after the original is deleted
  179. generic::Generic* copy2 = new generic::Generic(rdata_unknown);
  180. generic::Generic copy3(*copy2);
  181. delete copy2;
  182. EXPECT_EQ(0, copy3.compare(rdata_unknown));
  183. }
  184. TEST_F(Rdata_Unknown_Test, assignment) {
  185. generic::Generic copy("\\# 1 10");
  186. copy = rdata_unknown;
  187. EXPECT_EQ(0, copy.compare(rdata_unknown));
  188. // Check if the copied data is valid even after the original is deleted
  189. generic::Generic* copy2 = new generic::Generic(rdata_unknown);
  190. generic::Generic copy3("\\# 1 10");
  191. copy3 = *copy2;
  192. delete copy2;
  193. EXPECT_EQ(0, copy3.compare(rdata_unknown));
  194. // Self assignment
  195. copy = copy;
  196. EXPECT_EQ(0, copy.compare(rdata_unknown));
  197. }
  198. TEST_F(Rdata_Unknown_Test, toText) {
  199. EXPECT_EQ(rdata_unknowntxt, rdata_unknown.toText());
  200. EXPECT_EQ(getLongestRdataTxt(),
  201. generic::Generic(getLongestRdataTxt()).toText());
  202. }
  203. TEST_F(Rdata_Unknown_Test, toWireBuffer) {
  204. rdata_unknown.toWire(obuffer);
  205. EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
  206. obuffer.getData(), obuffer.getLength(),
  207. wiredata_unknown, sizeof(wiredata_unknown));
  208. }
  209. TEST_F(Rdata_Unknown_Test, toWireRenderer) {
  210. rdata_unknown.toWire(renderer);
  211. EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
  212. obuffer.getData(), obuffer.getLength(),
  213. wiredata_unknown, sizeof(wiredata_unknown));
  214. }
  215. TEST_F(Rdata_Unknown_Test, compare) {
  216. // comparison as left-justified unsigned octet sequences:
  217. EXPECT_EQ(0, rdata_unknown.compare(rdata_unknown));
  218. generic::Generic rdata_unknown_small("\\# 4 00b2c3ff");
  219. EXPECT_GT(0, rdata_unknown_small.compare(rdata_unknown));
  220. EXPECT_LT(0, rdata_unknown.compare(rdata_unknown_small));
  221. generic::Generic rdata_unknown_large("\\# 4 ffb2c300");
  222. EXPECT_LT(0, rdata_unknown_large.compare(rdata_unknown));
  223. EXPECT_GT(0, rdata_unknown.compare(rdata_unknown_large));
  224. // the absence of an octet sorts before a zero octet.
  225. generic::Generic rdata_unknown_short("\\# 3 a1b2c3");
  226. EXPECT_GT(0, rdata_unknown_short.compare(rdata_unknown));
  227. EXPECT_LT(0, rdata_unknown.compare(rdata_unknown_short));
  228. }
  229. TEST_F(Rdata_Unknown_Test, LeftShiftOperator) {
  230. ostringstream oss;
  231. oss << rdata_unknown;
  232. EXPECT_EQ(rdata_unknown.toText(), oss.str());
  233. }
  234. //
  235. // Tests for global utility functions
  236. //
  237. TEST_F(RdataTest, compareNames) {
  238. Name small("a.example");
  239. Name large("example");
  240. // Check the case where the order is different from the owner name
  241. // comparison:
  242. EXPECT_TRUE(small > large);
  243. EXPECT_EQ(-1, compareNames(small, large));
  244. EXPECT_EQ(1, compareNames(large, small));
  245. // Check case insensitive comparison:
  246. Name small_upper("A.EXAMPLE");
  247. EXPECT_EQ(0, compareNames(small, small_upper));
  248. // the absence of an octet sorts before a zero octet.
  249. Name large2("a.example2");
  250. EXPECT_EQ(-1, compareNames(small, large2));
  251. EXPECT_EQ(1, compareNames(large2, small));
  252. }
  253. }