rdata_serialization_unittest.cc 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724
  1. // Copyright (C) 2012 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. // Note: This file tests both the rdata_encoder and rdata_reader. They are
  15. // tested together because they form kind the oposite sides of the same
  16. // functionality.
  17. #include <exceptions/exceptions.h>
  18. #include <util/buffer.h>
  19. #include <dns/name.h>
  20. #include <dns/labelsequence.h>
  21. #include <dns/messagerenderer.h>
  22. #include <dns/rdata.h>
  23. #include <dns/rdataclass.h>
  24. #include <dns/rrclass.h>
  25. #include <dns/rrtype.h>
  26. #include <datasrc/memory/rdata_encoder.h>
  27. #include <datasrc/memory/rdata_field.h>
  28. #include <datasrc/memory/rdata_reader.h>
  29. #include <util/unittests/wiredata.h>
  30. #include <gtest/gtest.h>
  31. #include <boost/bind.hpp>
  32. #include <boost/foreach.hpp>
  33. #include <cstring>
  34. #include <set>
  35. #include <string>
  36. #include <vector>
  37. using namespace isc::dns;
  38. using namespace isc::dns::rdata;
  39. using namespace isc::datasrc::memory;
  40. using isc::util::unittests::matchWireData;
  41. using std::string;
  42. using std::vector;
  43. namespace {
  44. // This defines a tuple of test data used in test_rdata_list below.
  45. struct TestRdata {
  46. const char* const rrclass; // RR class, textual form
  47. const char* const rrtype; // RR type, textual form
  48. const char* const rdata; // textual RDATA
  49. const size_t n_varlen_fields; // expected # of variable-len fields
  50. };
  51. // This test data consist of (almost) all supported types of RDATA (+ some
  52. // unusual and corner cases).
  53. const TestRdata test_rdata_list[] = {
  54. {"IN", "A", "192.0.2.1", 0},
  55. {"IN", "NS", "ns.example.com", 0},
  56. {"IN", "CNAME", "cname.example.com", 0},
  57. {"IN", "SOA", "ns.example.com root.example.com 0 0 0 0 0", 0},
  58. {"IN", "PTR", "reverse.example.com", 0},
  59. {"IN", "HINFO", "\"cpu-info\" \"OS-info\"", 1},
  60. {"IN", "MINFO", "root.example.com mbox.example.com", 0},
  61. {"IN", "MX", "10 mx.example.com", 0},
  62. {"IN", "TXT", "\"test1\" \"test 2\"", 1},
  63. {"IN", "RP", "root.example.com. rp-text.example.com", 0},
  64. {"IN", "AFSDB", "1 afsdb.example.com", 0},
  65. {"IN", "AAAA", "2001:db8::1", 0},
  66. {"IN", "SRV", "1 0 10 target.example.com", 0},
  67. {"IN", "NAPTR", "100 50 \"s\" \"http\" \"\" _http._tcp.example.com", 1},
  68. {"IN", "DNAME", "dname.example.com", 0},
  69. {"IN", "DS", "12892 5 2 5F0EB5C777586DE18DA6B5", 1},
  70. {"IN", "SSHFP", "1 1 dd465c09cfa51fb45020cc83316fff", 1},
  71. // We handle RRSIG separately, so it's excluded from the list
  72. {"IN", "NSEC", "next.example.com. A AAAA NSEC RRSIG", 1},
  73. {"IN", "DNSKEY", "256 3 5 FAKEFAKE", 1},
  74. {"IN", "DHCID", "FAKEFAKE", 1},
  75. {"IN", "NSEC3", "1 1 12 AABBCCDD FAKEFAKE A RRSIG", 1},
  76. {"IN", "NSEC3PARAM", "1 0 12 AABBCCDD", 1},
  77. {"IN", "SPF", "v=spf1 +mx a:colo.example.com/28 -all", 1},
  78. {"IN", "DLV", "12892 5 2 5F0EB5C777586DE18DA6B5", 1},
  79. {"IN", "TYPE65000", "\\# 3 010203", 1}, // some "custom" type
  80. {"IN", "TYPE65535", "\\# 0", 1}, // max RR type, 0-length RDATA
  81. {"CH", "A", "\\# 2 0102", 1}, // A RR for non-IN class; varlen data
  82. {"CH", "NS", "ns.example.com", 0}, // class CH, generic data
  83. {"CH", "TXT", "BIND10", 1}, // ditto
  84. {"HS", "A", "\\# 5 0102030405", 1}, // A RR for non-IN class; varlen data
  85. {NULL, NULL, NULL, 0}
  86. };
  87. // The following two functions will be used to generate wire format data
  88. // from encoded representation of each RDATA.
  89. void
  90. renderNameField(MessageRenderer* renderer, bool additional_required,
  91. const LabelSequence& labels, unsigned attributes)
  92. {
  93. EXPECT_EQ(additional_required,
  94. (attributes & NAMEATTR_ADDITIONAL) != 0);
  95. renderer->writeName(labels, (attributes & NAMEATTR_COMPRESSIBLE) != 0);
  96. }
  97. void
  98. renderDataField(MessageRenderer* renderer, const uint8_t* data,
  99. size_t data_len)
  100. {
  101. renderer->writeData(data, data_len);
  102. }
  103. class RdataSerializationTest : public ::testing::Test {
  104. protected:
  105. RdataSerializationTest() : a_rdata_(createRdata(RRType::A(), RRClass::IN(),
  106. "192.0.2.53")),
  107. aaaa_rdata_(createRdata(RRType::AAAA(), RRClass::IN(),
  108. "2001:db8::53")),
  109. rrsig_rdata_(createRdata(
  110. RRType::RRSIG(), RRClass::IN(),
  111. "A 5 2 3600 20120814220826 "
  112. "20120715220826 12345 com. FAKE"))
  113. {}
  114. // A wraper for RdataEncoder::encode() with buffer overrun check.
  115. void encodeWrapper(size_t data_len);
  116. // Some commonly used RDATA
  117. const ConstRdataPtr a_rdata_;
  118. const ConstRdataPtr aaaa_rdata_;
  119. const ConstRdataPtr rrsig_rdata_;
  120. RdataEncoder encoder_;
  121. vector<uint8_t> encoded_data_;
  122. MessageRenderer expected_renderer_;
  123. MessageRenderer actual_renderer_;
  124. vector<ConstRdataPtr> rdata_list_;
  125. };
  126. // There are several ways to decode the data. For one, there are
  127. // more interfaces uses for RdataReader, and we use our own decoder,
  128. // to check the actual encoded data.
  129. //
  130. // These decoding ways are provided by the template parameter.
  131. template<class DecoderStyle>
  132. class RdataEncodeDecodeTest : public RdataSerializationTest {
  133. public:
  134. // This helper test method constructs encodes the given list of RDATAs
  135. // (in rdata_list), and then iterates over the data, rendering the fields
  136. // in the wire format. It then compares the wire data with the one
  137. // generated by the normal libdns++ interface to see the encoding/decoding
  138. // works as intended.
  139. void checkEncode(RRClass rrclass, RRType rrtype,
  140. const vector<ConstRdataPtr>& rdata_list,
  141. size_t expected_varlen_fields,
  142. const vector<ConstRdataPtr>& rrsig_list);
  143. void addRdataCommon(const vector<ConstRdataPtr>& rrsigs);
  144. void addRdataMultiCommon(const vector<ConstRdataPtr>& rrsigs);
  145. };
  146. // Used across more classes and scopes. But it's just uninteresting
  147. // constant.
  148. const Name dummy_name2("example.com");
  149. bool
  150. additionalRequired(const RRType& type) {
  151. // The set of RR types that require additional section processing.
  152. // We'll pass it to renderNameField to check the stored attribute matches
  153. // our expectation.
  154. static std::set<RRType> need_additionals;
  155. if (need_additionals.empty()) {
  156. need_additionals.insert(RRType::NS());
  157. need_additionals.insert(RRType::MX());
  158. need_additionals.insert(RRType::SRV());
  159. }
  160. return (need_additionals.find(type) != need_additionals.end());
  161. }
  162. // A decoder that does not use RdataReader. Not recommended for use,
  163. // but it allows the tests to check the internals of the data.
  164. class ManualDecoderStyle {
  165. public:
  166. static void foreachRdataField(RRClass rrclass, RRType rrtype,
  167. size_t rdata_count,
  168. const vector<uint8_t>& encoded_data,
  169. const vector<uint16_t>& varlen_list,
  170. RdataReader::NameAction name_callback,
  171. RdataReader::DataAction data_callback)
  172. {
  173. const RdataEncodeSpec& encode_spec = getRdataEncodeSpec(rrclass,
  174. rrtype);
  175. size_t off = 0;
  176. size_t varlen_count = 0;
  177. size_t name_count = 0;
  178. for (size_t count = 0; count < rdata_count; ++count) {
  179. for (size_t i = 0; i < encode_spec.field_count; ++i) {
  180. const RdataFieldSpec& field_spec = encode_spec.fields[i];
  181. switch (field_spec.type) {
  182. case RdataFieldSpec::FIXEDLEN_DATA:
  183. if (data_callback) {
  184. data_callback(&encoded_data.at(off),
  185. field_spec.fixeddata_len);
  186. }
  187. off += field_spec.fixeddata_len;
  188. break;
  189. case RdataFieldSpec::VARLEN_DATA:
  190. {
  191. const size_t varlen = varlen_list.at(varlen_count);
  192. if (data_callback && varlen > 0) {
  193. data_callback(&encoded_data.at(off), varlen);
  194. }
  195. off += varlen;
  196. ++varlen_count;
  197. break;
  198. }
  199. case RdataFieldSpec::DOMAIN_NAME:
  200. {
  201. ++name_count;
  202. const LabelSequence labels(&encoded_data.at(off));
  203. if (name_callback) {
  204. name_callback(labels,
  205. field_spec.name_attributes);
  206. }
  207. off += labels.getSerializedLength();
  208. break;
  209. }
  210. }
  211. }
  212. }
  213. assert(name_count == encode_spec.name_count * rdata_count);
  214. assert(varlen_count == encode_spec.varlen_count * rdata_count);
  215. }
  216. static void foreachRRSig(const vector<uint8_t>& encoded_data,
  217. const vector<uint16_t>& rrsiglen_list,
  218. RdataReader::DataAction data_callback)
  219. {
  220. size_t rrsig_totallen = 0;
  221. for (vector<uint16_t>::const_iterator it = rrsiglen_list.begin();
  222. it != rrsiglen_list.end();
  223. ++it) {
  224. rrsig_totallen += *it;
  225. }
  226. assert(encoded_data.size() >= rrsig_totallen);
  227. const uint8_t* dp = &encoded_data[encoded_data.size() -
  228. rrsig_totallen];
  229. for (size_t i = 0; i < rrsiglen_list.size(); ++i) {
  230. data_callback(dp, rrsiglen_list[i]);
  231. dp += rrsiglen_list[i];
  232. }
  233. }
  234. static void decode(const isc::dns::RRClass& rrclass,
  235. const isc::dns::RRType& rrtype,
  236. size_t rdata_count,
  237. size_t rrsig_count,
  238. size_t expected_varlen_fields,
  239. // Warning: this test actualy might change the
  240. // encoded_data !
  241. vector<uint8_t>& encoded_data,
  242. MessageRenderer& renderer)
  243. {
  244. // If this type of RDATA is expected to contain variable-length fields,
  245. // we brute force the encoded data, exploiting our knowledge of actual
  246. // encoding, then adjust the encoded data excluding the list of length
  247. // fields. This is ugly, but for tests only.
  248. vector<uint16_t> varlen_list;
  249. if (expected_varlen_fields > 0) {
  250. const size_t varlen_list_size =
  251. rdata_count * expected_varlen_fields * sizeof(uint16_t);
  252. ASSERT_LE(varlen_list_size, encoded_data.size());
  253. varlen_list.resize(rdata_count * expected_varlen_fields);
  254. std::memcpy(&varlen_list[0], &encoded_data[0], varlen_list_size);
  255. encoded_data.assign(encoded_data.begin() + varlen_list_size,
  256. encoded_data.end());
  257. }
  258. // If RRSIGs are given, we need to extract the list of the RRSIG lengths
  259. // and adjust encoded_data_ further.
  260. vector<uint16_t> rrsiglen_list;
  261. if (rrsig_count > 0) {
  262. const size_t rrsig_len_size = rrsig_count * sizeof(uint16_t);
  263. ASSERT_LE(rrsig_len_size, encoded_data.size());
  264. rrsiglen_list.resize(rrsig_count * rrsig_len_size);
  265. std::memcpy(&rrsiglen_list[0], &encoded_data[0], rrsig_len_size);
  266. encoded_data.assign(encoded_data.begin() + rrsig_len_size,
  267. encoded_data.end());
  268. }
  269. // Create wire-format data from the encoded data
  270. foreachRdataField(rrclass, rrtype, rdata_count, encoded_data,
  271. varlen_list,
  272. boost::bind(renderNameField, &renderer,
  273. additionalRequired(rrtype), _1, _2),
  274. boost::bind(renderDataField, &renderer, _1, _2));
  275. // 2nd dummy name
  276. renderer.writeName(dummy_name2);
  277. // Finally, dump any RRSIGs in wire format.
  278. foreachRRSig(encoded_data, rrsiglen_list,
  279. boost::bind(renderDataField, &renderer, _1, _2));
  280. }
  281. };
  282. // Decode using reader with the return value of next
  283. class NextDecoder {
  284. public:
  285. static void decode(const isc::dns::RRClass& rrclass,
  286. const isc::dns::RRType& rrtype,
  287. size_t rdata_count, size_t sig_count, size_t,
  288. const vector<uint8_t>& encoded_data,
  289. MessageRenderer& renderer)
  290. {
  291. RdataReader reader(rrclass, rrtype, encoded_data.size(),
  292. &encoded_data[0], rdata_count, sig_count);
  293. RdataReader::Result field;
  294. while (field = reader.next()) {
  295. switch (field.type()) {
  296. case RdataReader::DATA:
  297. renderer.writeData(field.data(), field.size());
  298. break;
  299. case RdataReader::NAME:
  300. renderer.writeName(field.label(), field.compressible());
  301. break;
  302. default:
  303. FAIL();
  304. }
  305. }
  306. renderer.writeName(dummy_name2);
  307. while (field = reader.nextSig()) {
  308. switch (field.type()) {
  309. case RdataReader::DATA:
  310. renderer.writeData(field.data(), field.size());
  311. break;
  312. default: // There are also no NAME fields in RRSigs
  313. FAIL();
  314. }
  315. }
  316. }
  317. };
  318. // Check using callbacks and calling next until the end.
  319. class CallbackDecoder {
  320. public:
  321. static void decode(const isc::dns::RRClass& rrclass,
  322. const isc::dns::RRType& rrtype,
  323. size_t rdata_count, size_t sig_count, size_t,
  324. const vector<uint8_t>& encoded_data,
  325. MessageRenderer& renderer)
  326. {
  327. RdataReader reader(rrclass, rrtype, encoded_data.size(),
  328. &encoded_data[0], rdata_count, sig_count,
  329. boost::bind(renderNameField, &renderer,
  330. additionalRequired(rrtype), _1, _2),
  331. boost::bind(renderDataField, &renderer, _1, _2));
  332. while (reader.next()) { }
  333. renderer.writeName(dummy_name2);
  334. while (reader.nextSig()) { }
  335. }
  336. };
  337. // Check using callbacks and calling iterate.
  338. class IterateDecoder {
  339. public:
  340. static void decode(const isc::dns::RRClass& rrclass,
  341. const isc::dns::RRType& rrtype,
  342. size_t rdata_count, size_t sig_count, size_t,
  343. const vector<uint8_t>& encoded_data,
  344. MessageRenderer& renderer)
  345. {
  346. RdataReader reader(rrclass, rrtype, encoded_data.size(),
  347. &encoded_data[0], rdata_count, sig_count,
  348. boost::bind(renderNameField, &renderer,
  349. additionalRequired(rrtype), _1, _2),
  350. boost::bind(renderDataField, &renderer, _1, _2));
  351. reader.iterate();
  352. renderer.writeName(dummy_name2);
  353. reader.iterateSig();
  354. }
  355. };
  356. typedef ::testing::Types<ManualDecoderStyle, NextDecoder, CallbackDecoder,
  357. IterateDecoder> DecoderStyles;
  358. TYPED_TEST_CASE(RdataEncodeDecodeTest, DecoderStyles);
  359. void
  360. RdataSerializationTest::encodeWrapper(size_t data_len) {
  361. // make sure the data buffer is large enough for the canary
  362. encoded_data_.resize(data_len + 2);
  363. // set the canary data
  364. encoded_data_.at(data_len) = 0xde;
  365. encoded_data_.at(data_len + 1) = 0xad;
  366. // encode, then check the canary is intact
  367. encoder_.encode(&encoded_data_[0], data_len);
  368. EXPECT_EQ(0xde, encoded_data_.at(data_len));
  369. EXPECT_EQ(0xad, encoded_data_.at(data_len + 1));
  370. // shrink the data buffer to the originally expected size (some tests
  371. // expect that). the actual encoded data should be intact.
  372. encoded_data_.resize(data_len);
  373. }
  374. template<class DecoderStyle>
  375. void
  376. RdataEncodeDecodeTest<DecoderStyle>::
  377. checkEncode(RRClass rrclass, RRType rrtype,
  378. const vector<ConstRdataPtr>& rdata_list,
  379. size_t expected_varlen_fields,
  380. const vector<ConstRdataPtr>& rrsig_list = vector<ConstRdataPtr>())
  381. {
  382. // These two names will be rendered before and after the test RDATA,
  383. // to check in case the RDATA contain a domain name whether it's
  384. // compressed or not correctly. The names in the RDATA should basically
  385. // a subdomain of example.com, so it can be compressed due to dummy_name.
  386. // Likewise, dummy_name2 should be able to be fully compressed due to
  387. // the name in the RDATA.
  388. const Name dummy_name("com");
  389. expected_renderer_.clear();
  390. actual_renderer_.clear();
  391. encoded_data_.clear();
  392. // Build expected wire-format data
  393. expected_renderer_.writeName(dummy_name);
  394. BOOST_FOREACH(const ConstRdataPtr& rdata, rdata_list) {
  395. rdata->toWire(expected_renderer_);
  396. }
  397. expected_renderer_.writeName(dummy_name2);
  398. BOOST_FOREACH(const ConstRdataPtr& rdata, rrsig_list) {
  399. rdata->toWire(expected_renderer_);
  400. }
  401. // Then build wire format data using the encoded data.
  402. // 1st dummy name
  403. actual_renderer_.writeName(dummy_name);
  404. // Create encoded data
  405. encoder_.start(rrclass, rrtype);
  406. BOOST_FOREACH(const ConstRdataPtr& rdata, rdata_list) {
  407. encoder_.addRdata(*rdata);
  408. }
  409. BOOST_FOREACH(const ConstRdataPtr& rdata, rrsig_list) {
  410. encoder_.addSIGRdata(*rdata);
  411. }
  412. encodeWrapper(encoder_.getStorageLength());
  413. DecoderStyle::decode(rrclass, rrtype, rdata_list.size(), rrsig_list.size(),
  414. expected_varlen_fields, encoded_data_,
  415. actual_renderer_);
  416. // Two sets of wire-format data should be identical.
  417. matchWireData(expected_renderer_.getData(), expected_renderer_.getLength(),
  418. actual_renderer_.getData(), actual_renderer_.getLength());
  419. }
  420. template<class DecoderStyle>
  421. void
  422. RdataEncodeDecodeTest<DecoderStyle>::
  423. addRdataCommon(const vector<ConstRdataPtr>& rrsigs) {
  424. // Basic check on the encoded data for (most of) all supported RR types,
  425. // in a comprehensive manner.
  426. for (size_t i = 0; test_rdata_list[i].rrclass != NULL; ++i) {
  427. SCOPED_TRACE(string(test_rdata_list[i].rrclass) + "/" +
  428. test_rdata_list[i].rrtype);
  429. const RRClass rrclass(test_rdata_list[i].rrclass);
  430. const RRType rrtype(test_rdata_list[i].rrtype);
  431. const ConstRdataPtr rdata = createRdata(rrtype, rrclass,
  432. test_rdata_list[i].rdata);
  433. rdata_list_.clear();
  434. rdata_list_.push_back(rdata);
  435. checkEncode(rrclass, rrtype, rdata_list_,
  436. test_rdata_list[i].n_varlen_fields, rrsigs);
  437. }
  438. }
  439. TYPED_TEST(RdataEncodeDecodeTest, addRdata) {
  440. vector<ConstRdataPtr> rrsigs;
  441. this->addRdataCommon(rrsigs); // basic tests without RRSIGs (empty vector)
  442. // Test with RRSIGs (covered type doesn't always match, but the encoder
  443. // doesn't check that)
  444. rrsigs.push_back(this->rrsig_rdata_);
  445. this->addRdataCommon(rrsigs);
  446. }
  447. template<class DecoderStyle>
  448. void
  449. RdataEncodeDecodeTest<DecoderStyle>::
  450. addRdataMultiCommon(const vector<ConstRdataPtr>& rrsigs) {
  451. // Similar to addRdata(), but test with multiple RDATAs.
  452. // Four different cases are tested: a single fixed-len RDATA (A),
  453. // fixed-len data + domain name (MX), variable-len data only (TXT),
  454. // variable-len data + domain name (NAPTR).
  455. ConstRdataPtr a_rdata2 = createRdata(RRType::A(), RRClass::IN(),
  456. "192.0.2.54");
  457. rdata_list_.clear();
  458. rdata_list_.push_back(a_rdata_);
  459. rdata_list_.push_back(a_rdata2);
  460. checkEncode(RRClass::IN(), RRType::A(), rdata_list_, 0, rrsigs);
  461. ConstRdataPtr mx_rdata1 = createRdata(RRType::MX(), RRClass::IN(),
  462. "5 mx1.example.com");
  463. ConstRdataPtr mx_rdata2 = createRdata(RRType::MX(), RRClass::IN(),
  464. "10 mx2.example.com");
  465. rdata_list_.clear();
  466. rdata_list_.push_back(mx_rdata1);
  467. rdata_list_.push_back(mx_rdata2);
  468. checkEncode(RRClass::IN(), RRType::MX(), rdata_list_, 0, rrsigs);
  469. ConstRdataPtr txt_rdata1 = createRdata(RRType::TXT(), RRClass::IN(),
  470. "foo bar baz");
  471. ConstRdataPtr txt_rdata2 = createRdata(RRType::TXT(), RRClass::IN(),
  472. "another text data");
  473. rdata_list_.clear();
  474. rdata_list_.push_back(txt_rdata1);
  475. rdata_list_.push_back(txt_rdata2);
  476. checkEncode(RRClass::IN(), RRType::TXT(), rdata_list_, 1, rrsigs);
  477. ConstRdataPtr naptr_rdata1 =
  478. createRdata(RRType::NAPTR(), RRClass::IN(),
  479. "100 50 \"s\" \"http\" \"\" _http._tcp.example.com");
  480. ConstRdataPtr naptr_rdata2 =
  481. createRdata(RRType::NAPTR(), RRClass::IN(),
  482. "200 100 \"s\" \"http\" \"\" _http._tcp.example.com");
  483. rdata_list_.clear();
  484. rdata_list_.push_back(naptr_rdata1);
  485. rdata_list_.push_back(naptr_rdata2);
  486. checkEncode(RRClass::IN(), RRType::NAPTR(), rdata_list_, 1, rrsigs);
  487. }
  488. TEST_F(RdataSerializationTest, encodeLargeRdata) {
  489. // There should be no reason for a large RDATA to fail in encoding,
  490. // but we check such a case explicitly.
  491. encoded_data_.resize(65535); // max unsigned 16-bit int
  492. isc::util::InputBuffer buffer(&encoded_data_[0], encoded_data_.size());
  493. const in::DHCID large_dhcid(buffer, encoded_data_.size());
  494. encoder_.start(RRClass::IN(), RRType::DHCID());
  495. encoder_.addRdata(large_dhcid);
  496. encodeWrapper(encoder_.getStorageLength());
  497. // The encoded data should be identical to the original one.
  498. ASSERT_LT(sizeof(uint16_t), encoder_.getStorageLength());
  499. isc::util::InputBuffer ib(&encoded_data_[2], encoded_data_.size() - 2);
  500. const in::DHCID encoded_dhcid(ib, ib.getLength());
  501. EXPECT_EQ(0, encoded_dhcid.compare(large_dhcid));
  502. }
  503. TYPED_TEST(RdataEncodeDecodeTest, addRdataMulti) {
  504. vector<ConstRdataPtr> rrsigs;
  505. this->addRdataMultiCommon(rrsigs); // test without RRSIGs (empty vector)
  506. // Tests with two RRSIGs
  507. rrsigs.push_back(this->rrsig_rdata_);
  508. rrsigs.push_back(createRdata(RRType::RRSIG(), RRClass::IN(),
  509. "A 5 2 3600 20120814220826 "
  510. "20120715220826 54321 com. FAKE"));
  511. this->addRdataMultiCommon(rrsigs);
  512. }
  513. TEST_F(RdataSerializationTest, badAddRdata) {
  514. // Some operations must follow start().
  515. EXPECT_THROW(encoder_.addRdata(*a_rdata_), isc::InvalidOperation);
  516. EXPECT_THROW(encoder_.getStorageLength(), isc::InvalidOperation);
  517. // will allocate space of some arbitrary size (256 bytes)
  518. EXPECT_THROW(encodeWrapper(256), isc::InvalidOperation);
  519. // Bad buffer for encode
  520. encoder_.start(RRClass::IN(), RRType::A());
  521. encoder_.addRdata(*a_rdata_);
  522. const size_t buf_len = encoder_.getStorageLength();
  523. // NULL buffer for encode
  524. EXPECT_THROW(encoder_.encode(NULL, buf_len), isc::BadValue);
  525. // buffer length is too short (we don't use the wrraper because we don't
  526. // like to tweak the length arg to encode()).
  527. encoded_data_.resize(buf_len - 1);
  528. EXPECT_THROW(encoder_.encode(&encoded_data_[0], buf_len - 1),
  529. isc::BadValue);
  530. // Type of RDATA and the specified RR type don't match. addRdata() should
  531. // detect this inconsistency.
  532. encoder_.start(RRClass::IN(), RRType::AAAA());
  533. EXPECT_THROW(encoder_.addRdata(*a_rdata_), isc::BadValue);
  534. // Likewise.
  535. encoder_.start(RRClass::IN(), RRType::A());
  536. EXPECT_THROW(encoder_.addRdata(*aaaa_rdata_), isc::BadValue);
  537. // Likewise. The encoder expects the first name completes the data, and
  538. // throws on the second due as an unexpected name field.
  539. const ConstRdataPtr rp_rdata =
  540. createRdata(RRType::RP(), RRClass::IN(), "a.example. b.example");
  541. encoder_.start(RRClass::IN(), RRType::NS());
  542. EXPECT_THROW(encoder_.addRdata(*rp_rdata), isc::BadValue);
  543. // Likewise. The encoder considers the name data a variable length data
  544. // field, and throws on the first name.
  545. encoder_.start(RRClass::IN(), RRType::DHCID());
  546. EXPECT_THROW(encoder_.addRdata(*rp_rdata), isc::BadValue);
  547. // Likewise. The text RDATA (2 bytes) will be treated as MX preference,
  548. // and the encoder will still expect to see a domain name.
  549. const ConstRdataPtr txt_rdata = createRdata(RRType::TXT(), RRClass::IN(),
  550. "a");
  551. encoder_.start(RRClass::IN(), RRType::MX());
  552. EXPECT_THROW(encoder_.addRdata(*txt_rdata), isc::BadValue);
  553. // Similar to the previous one, but in this case there's no data field
  554. // in the spec.
  555. encoder_.start(RRClass::IN(), RRType::NS());
  556. EXPECT_THROW(encoder_.addRdata(*txt_rdata), isc::BadValue);
  557. // Likewise. Inconsistent name compression policy.
  558. const ConstRdataPtr ns_rdata =
  559. createRdata(RRType::NS(), RRClass::IN(), "ns.example");
  560. encoder_.start(RRClass::IN(), RRType::DNAME());
  561. EXPECT_THROW(encoder_.addRdata(*ns_rdata), isc::BadValue);
  562. // Same as the previous one, opposite inconsistency.
  563. const ConstRdataPtr dname_rdata =
  564. createRdata(RRType::DNAME(), RRClass::IN(), "dname.example");
  565. encoder_.start(RRClass::IN(), RRType::NS());
  566. EXPECT_THROW(encoder_.addRdata(*dname_rdata), isc::BadValue);
  567. // RDATA len exceeds the 16-bit range. Technically not invalid, but
  568. // we don't support that (and it's practically useless anyway).
  569. encoded_data_.resize(65536); // use encoded_data_ for placeholder
  570. isc::util::InputBuffer buffer(&encoded_data_[0], encoded_data_.size());
  571. encoder_.start(RRClass::IN(), RRType::DHCID());
  572. EXPECT_THROW(encoder_.addRdata(in::DHCID(buffer, encoded_data_.size())),
  573. RdataEncodingError);
  574. // RRSIG cannot be used as the main RDATA type (can only be added as
  575. // a signature for some other type of RDATAs).
  576. EXPECT_THROW(encoder_.start(RRClass::IN(), RRType::RRSIG()),
  577. isc::BadValue);
  578. }
  579. TEST_F(RdataSerializationTest, addSIGRdataOnly) {
  580. // Encoded data that only contain RRSIGs. Mostly useless, but can happen
  581. // (in a partially broken zone) and it's accepted.
  582. encoder_.start(RRClass::IN(), RRType::A());
  583. encoder_.addSIGRdata(*rrsig_rdata_);
  584. encodeWrapper(encoder_.getStorageLength());
  585. ASSERT_LT(sizeof(uint16_t), encoder_.getStorageLength());
  586. // The encoded data should be identical to the given one.
  587. isc::util::InputBuffer ib(&encoded_data_[2], encoded_data_.size() - 2);
  588. const generic::RRSIG encoded_sig(ib, ib.getLength());
  589. EXPECT_EQ(0, encoded_sig.compare(*rrsig_rdata_));
  590. }
  591. TEST_F(RdataSerializationTest, badAddSIGRdata) {
  592. // try adding SIG before start
  593. EXPECT_THROW(encoder_.addSIGRdata(*rrsig_rdata_), isc::InvalidOperation);
  594. // Very big RRSIG. This implementation rejects it.
  595. isc::util::OutputBuffer ob(0);
  596. rrsig_rdata_->toWire(ob);
  597. // append dummy trailing signature to make it too big
  598. vector<uint8_t> dummy_sig(65536 - ob.getLength());
  599. ob.writeData(&dummy_sig[0], dummy_sig.size());
  600. ASSERT_EQ(65536, ob.getLength());
  601. isc::util::InputBuffer ib(ob.getData(), ob.getLength());
  602. const generic::RRSIG big_sigrdata(ib, ob.getLength());
  603. encoder_.start(RRClass::IN(), RRType::A());
  604. EXPECT_THROW(encoder_.addSIGRdata(big_sigrdata), RdataEncodingError);
  605. }
  606. // Test the result returns what it was constructed with.
  607. TEST_F(RdataSerializationTest, readerResult) {
  608. // Default constructor
  609. RdataReader::Result empty;
  610. // Everything should be at the "empty" values, type END
  611. EXPECT_EQ(RdataReader::END, empty.type());
  612. EXPECT_EQ(NULL, empty.data());
  613. EXPECT_EQ(0, empty.size());
  614. EXPECT_TRUE(empty.label().equals(LabelSequence(Name::ROOT_NAME())));
  615. EXPECT_FALSE(empty);
  616. EXPECT_FALSE(empty.compressible());
  617. EXPECT_FALSE(empty.additional());
  618. // Constructor from label sequence
  619. LabelSequence seq(Name("example.org"));
  620. RdataReader::Result compressible(seq, NAMEATTR_COMPRESSIBLE);
  621. EXPECT_EQ(RdataReader::NAME, compressible.type());
  622. EXPECT_EQ(NULL, compressible.data());
  623. EXPECT_EQ(0, compressible.size());
  624. EXPECT_TRUE(compressible.label().equals(seq));
  625. EXPECT_TRUE(compressible);
  626. EXPECT_TRUE(compressible.compressible());
  627. EXPECT_FALSE(compressible.additional());
  628. RdataReader::Result incompressible(seq, NAMEATTR_ADDITIONAL);
  629. EXPECT_EQ(RdataReader::NAME, incompressible.type());
  630. EXPECT_EQ(NULL, incompressible.data());
  631. EXPECT_EQ(0, incompressible.size());
  632. EXPECT_TRUE(incompressible.label().equals(seq));
  633. EXPECT_TRUE(incompressible);
  634. EXPECT_FALSE(incompressible.compressible());
  635. EXPECT_TRUE(incompressible.additional());
  636. // Constructor from data
  637. uint8_t byte;
  638. RdataReader::Result data(&byte, 1);
  639. EXPECT_EQ(RdataReader::DATA, data.type());
  640. EXPECT_EQ(&byte, data.data());
  641. EXPECT_EQ(1, data.size());
  642. EXPECT_TRUE(data.label().equals(LabelSequence(Name::ROOT_NAME())));
  643. EXPECT_TRUE(data);
  644. EXPECT_FALSE(data.compressible());
  645. EXPECT_FALSE(data.additional());
  646. }
  647. }