rdata_serialization_unittest.cc 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842
  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. #include <exceptions/exceptions.h>
  15. #include <util/buffer.h>
  16. #include <dns/name.h>
  17. #include <dns/labelsequence.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 <datasrc/memory/rdata_serialization.h>
  24. #include <util/unittests/wiredata.h>
  25. #include <gtest/gtest.h>
  26. #include <boost/bind.hpp>
  27. #include <boost/foreach.hpp>
  28. #include <cstring>
  29. #include <set>
  30. #include <string>
  31. #include <vector>
  32. using namespace isc::dns;
  33. using namespace isc::dns::rdata;
  34. using namespace isc::datasrc::memory;
  35. using isc::util::unittests::matchWireData;
  36. using std::string;
  37. using std::vector;
  38. // A trick to steal some private definitions of the implementation we use here
  39. namespace isc {
  40. namespace datasrc{
  41. namespace memory {
  42. #include <datasrc/memory/rdata_serialization_priv.cc>
  43. }
  44. }
  45. }
  46. namespace {
  47. // This defines a tuple of test data used in test_rdata_list below.
  48. struct TestRdata {
  49. const char* const rrclass; // RR class, textual form
  50. const char* const rrtype; // RR type, textual form
  51. const char* const rdata; // textual RDATA
  52. const size_t n_varlen_fields; // expected # of variable-len fields
  53. };
  54. // This test data consist of (almost) all supported types of RDATA (+ some
  55. // unusual and corner cases).
  56. const TestRdata test_rdata_list[] = {
  57. {"IN", "A", "192.0.2.1", 0},
  58. {"IN", "NS", "ns.example.com.", 0},
  59. {"IN", "CNAME", "cname.example.com.", 0},
  60. {"IN", "SOA", "ns.example.com. root.example.com. 0 0 0 0 0", 0},
  61. {"IN", "PTR", "reverse.example.com.", 0},
  62. {"IN", "HINFO", "\"cpu-info\" \"OS-info\"", 1},
  63. {"IN", "MINFO", "root.example.com. mbox.example.com.", 0},
  64. {"IN", "MX", "10 mx.example.com.", 0},
  65. {"IN", "TXT", "\"test1\" \"test 2\"", 1},
  66. {"IN", "RP", "root.example.com. rp-text.example.com.", 0},
  67. {"IN", "AFSDB", "1 afsdb.example.com.", 0},
  68. {"IN", "AAAA", "2001:db8::1", 0},
  69. {"IN", "SRV", "1 0 10 target.example.com.", 0},
  70. {"IN", "NAPTR", "100 50 \"s\" \"http\" \"\" _http._tcp.example.com.", 1},
  71. {"IN", "DNAME", "dname.example.com.", 0},
  72. {"IN", "DS", "12892 5 2 5F0EB5C777586DE18DA6B5", 1},
  73. {"IN", "SSHFP", "1 1 dd465c09cfa51fb45020cc83316fff", 1},
  74. // We handle RRSIG separately, so it's excluded from the list
  75. {"IN", "NSEC", "next.example.com. A AAAA NSEC RRSIG", 1},
  76. {"IN", "DNSKEY", "256 3 5 FAKEFAKE", 1},
  77. {"IN", "DHCID", "FAKEFAKE", 1},
  78. {"IN", "NSEC3", "1 1 12 AABBCCDD FAKEFAKE A RRSIG", 1},
  79. {"IN", "NSEC3PARAM", "1 0 12 AABBCCDD", 1},
  80. {"IN", "SPF", "v=spf1 +mx a:colo.example.com/28 -all", 1},
  81. {"IN", "DLV", "12892 5 2 5F0EB5C777586DE18DA6B5", 1},
  82. {"IN", "TYPE65000", "\\# 3 010203", 1}, // some "custom" type
  83. {"IN", "TYPE65535", "\\# 0", 1}, // max RR type, 0-length RDATA
  84. {"CH", "A", "\\# 2 0102", 1}, // A RR for non-IN class; varlen data
  85. {"CH", "NS", "ns.example.com.", 0}, // class CH, generic data
  86. {"CH", "TXT", "BIND10", 1}, // ditto
  87. {"HS", "A", "\\# 5 0102030405", 1}, // A RR for non-IN class; varlen data
  88. {NULL, NULL, NULL, 0}
  89. };
  90. // The following two functions will be used to generate wire format data
  91. // from encoded representation of each RDATA.
  92. void
  93. renderNameField(MessageRenderer* renderer, bool additional_required,
  94. const LabelSequence& labels, RdataNameAttributes attributes)
  95. {
  96. EXPECT_EQ(additional_required, (attributes & NAMEATTR_ADDITIONAL) != 0);
  97. renderer->writeName(labels, (attributes & NAMEATTR_COMPRESSIBLE) != 0);
  98. }
  99. void
  100. renderDataField(MessageRenderer* renderer, const void* data, size_t data_len) {
  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 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. vector<ConstRdataPtr>());
  144. void addRdataCommon(const vector<ConstRdataPtr>& rrsigs);
  145. void addRdataMultiCommon(const vector<ConstRdataPtr>& rrsigs);
  146. };
  147. // Used across more classes and scopes. But it's just uninteresting
  148. // constant.
  149. const Name& dummyName2() {
  150. static const Name result("example.com");
  151. return (result);
  152. }
  153. bool
  154. additionalRequired(const RRType& type) {
  155. // The set of RR types that require additional section processing.
  156. // We'll use it to determine what value should the renderNameField get
  157. // and, if the stored attributes are as expected.
  158. static std::set<RRType> need_additionals;
  159. if (need_additionals.empty()) {
  160. need_additionals.insert(RRType::NS());
  161. need_additionals.insert(RRType::MX());
  162. need_additionals.insert(RRType::SRV());
  163. }
  164. return (need_additionals.find(type) != need_additionals.end());
  165. }
  166. // A decoder that does not use RdataReader. Not recommended for use,
  167. // but it allows the tests to check the internals of the data.
  168. class ManualDecoderStyle {
  169. public:
  170. static void foreachRdataField(RRClass rrclass, RRType rrtype,
  171. size_t rdata_count,
  172. const vector<uint8_t>& encoded_data,
  173. const vector<uint16_t>& varlen_list,
  174. RdataReader::NameAction name_callback,
  175. RdataReader::DataAction data_callback)
  176. {
  177. const RdataEncodeSpec& encode_spec = getRdataEncodeSpec(rrclass,
  178. rrtype);
  179. size_t off = 0;
  180. size_t varlen_count = 0;
  181. size_t name_count = 0;
  182. for (size_t count = 0; count < rdata_count; ++count) {
  183. for (size_t i = 0; i < encode_spec.field_count; ++i) {
  184. const RdataFieldSpec& field_spec = encode_spec.fields[i];
  185. switch (field_spec.type) {
  186. case RdataFieldSpec::FIXEDLEN_DATA:
  187. if (data_callback) {
  188. data_callback(&encoded_data.at(off),
  189. field_spec.fixeddata_len);
  190. }
  191. off += field_spec.fixeddata_len;
  192. break;
  193. case RdataFieldSpec::VARLEN_DATA:
  194. {
  195. const size_t varlen = varlen_list.at(varlen_count);
  196. if (data_callback && varlen > 0) {
  197. data_callback(&encoded_data.at(off), varlen);
  198. }
  199. off += varlen;
  200. ++varlen_count;
  201. break;
  202. }
  203. case RdataFieldSpec::DOMAIN_NAME:
  204. {
  205. ++name_count;
  206. const LabelSequence labels(&encoded_data.at(off));
  207. if (name_callback) {
  208. name_callback(labels,
  209. field_spec.name_attributes);
  210. }
  211. off += labels.getSerializedLength();
  212. break;
  213. }
  214. }
  215. }
  216. }
  217. assert(name_count == encode_spec.name_count * rdata_count);
  218. assert(varlen_count == encode_spec.varlen_count * rdata_count);
  219. }
  220. static void foreachRRSig(const vector<uint8_t>& encoded_data,
  221. const vector<uint16_t>& rrsiglen_list,
  222. RdataReader::DataAction data_callback)
  223. {
  224. size_t rrsig_totallen = 0;
  225. for (vector<uint16_t>::const_iterator it = rrsiglen_list.begin();
  226. it != rrsiglen_list.end();
  227. ++it) {
  228. rrsig_totallen += *it;
  229. }
  230. assert(encoded_data.size() >= rrsig_totallen);
  231. const uint8_t* dp = &encoded_data[encoded_data.size() -
  232. rrsig_totallen];
  233. for (size_t i = 0; i < rrsiglen_list.size(); ++i) {
  234. data_callback(dp, rrsiglen_list[i]);
  235. dp += rrsiglen_list[i];
  236. }
  237. }
  238. static void decode(const isc::dns::RRClass& rrclass,
  239. const isc::dns::RRType& rrtype,
  240. size_t rdata_count,
  241. size_t rrsig_count,
  242. size_t expected_varlen_fields,
  243. // Warning: this test actualy might change the
  244. // encoded_data !
  245. vector<uint8_t>& encoded_data, size_t,
  246. MessageRenderer& renderer)
  247. {
  248. // If this type of RDATA is expected to contain variable-length fields,
  249. // we brute force the encoded data, exploiting our knowledge of actual
  250. // encoding, then adjust the encoded data excluding the list of length
  251. // fields. This is ugly, but for tests only.
  252. vector<uint16_t> varlen_list;
  253. if (expected_varlen_fields > 0) {
  254. const size_t varlen_list_size =
  255. rdata_count * expected_varlen_fields * sizeof(uint16_t);
  256. ASSERT_LE(varlen_list_size, encoded_data.size());
  257. varlen_list.resize(rdata_count * expected_varlen_fields);
  258. std::memcpy(&varlen_list[0], &encoded_data[0], varlen_list_size);
  259. encoded_data.assign(encoded_data.begin() + varlen_list_size,
  260. encoded_data.end());
  261. }
  262. // If RRSIGs are given, we need to extract the list of the RRSIG
  263. // lengths and adjust encoded_data_ further.
  264. vector<uint16_t> rrsiglen_list;
  265. if (rrsig_count > 0) {
  266. const size_t rrsig_len_size = rrsig_count * sizeof(uint16_t);
  267. ASSERT_LE(rrsig_len_size, encoded_data.size());
  268. rrsiglen_list.resize(rrsig_count * rrsig_len_size);
  269. std::memcpy(&rrsiglen_list[0], &encoded_data[0], rrsig_len_size);
  270. encoded_data.assign(encoded_data.begin() + rrsig_len_size,
  271. encoded_data.end());
  272. }
  273. // Create wire-format data from the encoded data
  274. foreachRdataField(rrclass, rrtype, rdata_count, encoded_data,
  275. varlen_list,
  276. boost::bind(renderNameField, &renderer,
  277. additionalRequired(rrtype), _1, _2),
  278. boost::bind(renderDataField, &renderer, _1, _2));
  279. // 2nd dummy name
  280. renderer.writeName(dummyName2());
  281. // Finally, dump any RRSIGs in wire format.
  282. foreachRRSig(encoded_data, rrsiglen_list,
  283. boost::bind(renderDataField, &renderer, _1, _2));
  284. }
  285. };
  286. // Check using callbacks and calling next until the end.
  287. class CallbackDecoder {
  288. public:
  289. static void decode(const isc::dns::RRClass& rrclass,
  290. const isc::dns::RRType& rrtype,
  291. size_t rdata_count, size_t sig_count, size_t,
  292. const vector<uint8_t>& encoded_data, size_t,
  293. MessageRenderer& renderer)
  294. {
  295. RdataReader reader(rrclass, rrtype, &encoded_data[0], rdata_count,
  296. sig_count,
  297. boost::bind(renderNameField, &renderer,
  298. additionalRequired(rrtype), _1, _2),
  299. boost::bind(renderDataField, &renderer, _1, _2));
  300. while (reader.next() != RdataReader::RRSET_BOUNDARY) {}
  301. renderer.writeName(dummyName2());
  302. while (reader.nextSig() != RdataReader::RRSET_BOUNDARY) {}
  303. }
  304. };
  305. // Check using callbacks and calling iterate.
  306. class IterateDecoder {
  307. public:
  308. static void decode(const isc::dns::RRClass& rrclass,
  309. const isc::dns::RRType& rrtype,
  310. size_t rdata_count, size_t sig_count, size_t,
  311. const vector<uint8_t>& encoded_data, size_t,
  312. MessageRenderer& renderer)
  313. {
  314. RdataReader reader(rrclass, rrtype, &encoded_data[0],
  315. rdata_count, sig_count,
  316. boost::bind(renderNameField, &renderer,
  317. additionalRequired(rrtype), _1, _2),
  318. boost::bind(renderDataField, &renderer, _1, _2));
  319. reader.iterate();
  320. renderer.writeName(dummyName2());
  321. reader.iterateAllSigs();
  322. }
  323. };
  324. namespace {
  325. // Render the data to renderer, if one is set, or put it inside
  326. // a data buffer.
  327. void
  328. appendOrRenderData(vector<uint8_t>* where, MessageRenderer** renderer,
  329. const void* data, size_t size)
  330. {
  331. if (*renderer != NULL) {
  332. (*renderer)->writeData(data, size);
  333. } else {
  334. where->insert(where->end(), reinterpret_cast<const uint8_t*>(data),
  335. reinterpret_cast<const uint8_t*>(data) + size);
  336. }
  337. }
  338. }
  339. // Similar to IterateDecoder, but it first iterates a little and rewinds
  340. // before actual rendering.
  341. class RewindAndDecode {
  342. private:
  343. static void writeName(MessageRenderer** renderer,
  344. const LabelSequence& labels,
  345. RdataNameAttributes attributes)
  346. {
  347. (*renderer)->writeName(labels,
  348. (attributes & NAMEATTR_COMPRESSIBLE) != 0);
  349. }
  350. public:
  351. static void decode(const isc::dns::RRClass& rrclass,
  352. const isc::dns::RRType& rrtype,
  353. size_t rdata_count, size_t sig_count, size_t,
  354. const vector<uint8_t>& encoded_data, size_t,
  355. MessageRenderer& renderer)
  356. {
  357. MessageRenderer dump; // A place to dump the extra data from before
  358. // actual rendering.
  359. MessageRenderer* current = &dump;
  360. vector<uint8_t> placeholder; // boost::bind does not like NULL
  361. RdataReader reader(rrclass, rrtype, &encoded_data[0],
  362. rdata_count, sig_count,
  363. boost::bind(writeName, &current, _1, _2),
  364. boost::bind(appendOrRenderData, &placeholder,
  365. &current, _1, _2));
  366. // Iterate a little and rewind
  367. reader.next();
  368. reader.nextSig();
  369. reader.rewind();
  370. // Do the actual rendering
  371. // cppcheck-suppress unreadVariable
  372. current = &renderer;
  373. reader.iterate();
  374. renderer.writeName(dummyName2());
  375. reader.iterateAllSigs();
  376. }
  377. };
  378. // Decode using the iteration over one rdata each time.
  379. // We also count there's the correct count of Rdatas.
  380. class SingleIterateDecoder {
  381. public:
  382. static void decode(const isc::dns::RRClass& rrclass,
  383. const isc::dns::RRType& rrtype,
  384. size_t rdata_count, size_t sig_count, size_t,
  385. const vector<uint8_t>& encoded_data, size_t,
  386. MessageRenderer& renderer)
  387. {
  388. RdataReader reader(rrclass, rrtype, &encoded_data[0],
  389. rdata_count, sig_count,
  390. boost::bind(renderNameField, &renderer,
  391. additionalRequired(rrtype), _1, _2),
  392. boost::bind(renderDataField, &renderer, _1, _2));
  393. size_t actual_count = 0;
  394. while (reader.iterateRdata()) {
  395. ++actual_count;
  396. }
  397. EXPECT_EQ(rdata_count, actual_count);
  398. actual_count = 0;
  399. renderer.writeName(dummyName2());
  400. while (reader.iterateSingleSig()) {
  401. ++actual_count;
  402. }
  403. EXPECT_EQ(sig_count, actual_count);
  404. }
  405. };
  406. // This one does not adhere to the usual way the reader is used, trying
  407. // to confuse it. It iterates part of the data manually and then reads
  408. // the rest through iterate. It also reads the signatures in the middle
  409. // of rendering.
  410. template<bool start_data, bool start_sig>
  411. class HybridDecoder {
  412. public:
  413. static void decode(const isc::dns::RRClass& rrclass,
  414. const isc::dns::RRType& rrtype,
  415. size_t rdata_count, size_t sig_count, size_t,
  416. const vector<uint8_t>& encoded_data,
  417. size_t encoded_data_len,
  418. MessageRenderer& renderer)
  419. {
  420. vector<uint8_t> data;
  421. MessageRenderer* current;
  422. RdataReader reader(rrclass, rrtype, &encoded_data[0],
  423. rdata_count, sig_count,
  424. boost::bind(renderNameField, &renderer,
  425. additionalRequired(rrtype), _1, _2),
  426. boost::bind(appendOrRenderData, &data, &current, _1,
  427. _2));
  428. // The size matches
  429. EXPECT_EQ(encoded_data_len, reader.getSize());
  430. if (start_sig) {
  431. current = NULL;
  432. reader.nextSig();
  433. }
  434. // Render first part of data. If there's none, return empty Result and
  435. // do nothing.
  436. if (start_data) {
  437. current = &renderer;
  438. reader.next();
  439. }
  440. // Now, we let all sigs to be copied to data. We disable the
  441. // renderer for this.
  442. current = NULL;
  443. reader.iterateAllSigs();
  444. // Now return the renderer and render the rest of the data
  445. // cppcheck-suppress redundantAssignment
  446. // cppcheck-suppress unreadVariable
  447. current = &renderer;
  448. reader.iterate();
  449. // Now, this should not break anything and should be valid, but should
  450. // return ends.
  451. EXPECT_EQ(RdataReader::RRSET_BOUNDARY, reader.next());
  452. EXPECT_EQ(RdataReader::RRSET_BOUNDARY, reader.nextSig());
  453. // Render the name and the sigs
  454. renderer.writeName(dummyName2());
  455. renderer.writeData(&data[0], data.size());
  456. // The size matches even after use
  457. EXPECT_EQ(encoded_data_len, reader.getSize());
  458. }
  459. };
  460. typedef ::testing::Types<ManualDecoderStyle,
  461. CallbackDecoder, IterateDecoder, SingleIterateDecoder,
  462. HybridDecoder<true, true>, HybridDecoder<true, false>,
  463. HybridDecoder<false, true>,
  464. HybridDecoder<false, false> >
  465. DecoderStyles;
  466. // Each decoder style must contain a decode() method. Such method is expected
  467. // to decode the passed data, first render the Rdata into the passed renderer,
  468. // then write the dummyName2() there and write the RRSig data after that.
  469. // It may do other checks too.
  470. //
  471. // There are some slight differences to how to do the decoding, that's why we
  472. // have the typed test.
  473. TYPED_TEST_CASE(RdataEncodeDecodeTest, DecoderStyles);
  474. void
  475. RdataSerializationTest::encodeWrapper(size_t data_len) {
  476. // make sure the data buffer is large enough for the canary
  477. encoded_data_.resize(data_len + 2);
  478. // set the canary data
  479. encoded_data_.at(data_len) = 0xde;
  480. encoded_data_.at(data_len + 1) = 0xad;
  481. // encode, then check the canary is intact
  482. encoder_.encode(&encoded_data_[0], data_len);
  483. EXPECT_EQ(0xde, encoded_data_.at(data_len));
  484. EXPECT_EQ(0xad, encoded_data_.at(data_len + 1));
  485. // shrink the data buffer to the originally expected size (some tests
  486. // expect that). the actual encoded data should be intact.
  487. encoded_data_.resize(data_len);
  488. }
  489. template<class DecoderStyle>
  490. void
  491. RdataEncodeDecodeTest<DecoderStyle>::
  492. checkEncode(RRClass rrclass, RRType rrtype,
  493. const vector<ConstRdataPtr>& rdata_list,
  494. size_t expected_varlen_fields,
  495. const vector<ConstRdataPtr>& rrsig_list)
  496. {
  497. // These two names will be rendered before and after the test RDATA,
  498. // to check in case the RDATA contain a domain name whether it's
  499. // compressed or not correctly. The names in the RDATA should basically
  500. // a subdomain of example.com, so it can be compressed due to dummyName2().
  501. // Likewise, dummyName2() should be able to be fully compressed due to
  502. // the name in the RDATA.
  503. const Name dummy_name("com");
  504. expected_renderer_.clear();
  505. actual_renderer_.clear();
  506. encoded_data_.clear();
  507. // Build expected wire-format data
  508. expected_renderer_.writeName(dummy_name);
  509. BOOST_FOREACH(const ConstRdataPtr& rdata, rdata_list) {
  510. rdata->toWire(expected_renderer_);
  511. }
  512. expected_renderer_.writeName(dummyName2());
  513. BOOST_FOREACH(const ConstRdataPtr& rdata, rrsig_list) {
  514. rdata->toWire(expected_renderer_);
  515. }
  516. // Then build wire format data using the encoded data.
  517. // 1st dummy name
  518. actual_renderer_.writeName(dummy_name);
  519. // Create encoded data
  520. encoder_.start(rrclass, rrtype);
  521. BOOST_FOREACH(const ConstRdataPtr& rdata, rdata_list) {
  522. encoder_.addRdata(*rdata);
  523. }
  524. BOOST_FOREACH(const ConstRdataPtr& rdata, rrsig_list) {
  525. encoder_.addSIGRdata(*rdata);
  526. }
  527. const size_t storage_len = encoder_.getStorageLength();
  528. encodeWrapper(storage_len);
  529. DecoderStyle::decode(rrclass, rrtype, rdata_list.size(), rrsig_list.size(),
  530. expected_varlen_fields, encoded_data_, storage_len,
  531. actual_renderer_);
  532. // Two sets of wire-format data should be identical.
  533. matchWireData(expected_renderer_.getData(), expected_renderer_.getLength(),
  534. actual_renderer_.getData(), actual_renderer_.getLength());
  535. }
  536. template<class DecoderStyle>
  537. void
  538. RdataEncodeDecodeTest<DecoderStyle>::
  539. addRdataCommon(const vector<ConstRdataPtr>& rrsigs) {
  540. // Basic check on the encoded data for (most of) all supported RR types,
  541. // in a comprehensive manner.
  542. for (size_t i = 0; test_rdata_list[i].rrclass != NULL; ++i) {
  543. SCOPED_TRACE(string(test_rdata_list[i].rrclass) + "/" +
  544. test_rdata_list[i].rrtype);
  545. const RRClass rrclass(test_rdata_list[i].rrclass);
  546. const RRType rrtype(test_rdata_list[i].rrtype);
  547. const ConstRdataPtr rdata = createRdata(rrtype, rrclass,
  548. test_rdata_list[i].rdata);
  549. rdata_list_.clear();
  550. rdata_list_.push_back(rdata);
  551. checkEncode(rrclass, rrtype, rdata_list_,
  552. test_rdata_list[i].n_varlen_fields, rrsigs);
  553. }
  554. }
  555. TYPED_TEST(RdataEncodeDecodeTest, addRdata) {
  556. vector<ConstRdataPtr> rrsigs;
  557. this->addRdataCommon(rrsigs); // basic tests without RRSIGs (empty vector)
  558. // Test with RRSIGs (covered type doesn't always match, but the encoder
  559. // doesn't check that)
  560. rrsigs.push_back(this->rrsig_rdata_);
  561. this->addRdataCommon(rrsigs);
  562. }
  563. template<class DecoderStyle>
  564. void
  565. RdataEncodeDecodeTest<DecoderStyle>::
  566. addRdataMultiCommon(const vector<ConstRdataPtr>& rrsigs) {
  567. // Similar to addRdata(), but test with multiple RDATAs.
  568. // Four different cases are tested: a single fixed-len RDATA (A),
  569. // fixed-len data + domain name (MX), variable-len data only (TXT),
  570. // variable-len data + domain name (NAPTR).
  571. ConstRdataPtr a_rdata2 = createRdata(RRType::A(), RRClass::IN(),
  572. "192.0.2.54");
  573. rdata_list_.clear();
  574. rdata_list_.push_back(a_rdata_);
  575. rdata_list_.push_back(a_rdata2);
  576. checkEncode(RRClass::IN(), RRType::A(), rdata_list_, 0, rrsigs);
  577. ConstRdataPtr mx_rdata1 = createRdata(RRType::MX(), RRClass::IN(),
  578. "5 mx1.example.com");
  579. ConstRdataPtr mx_rdata2 = createRdata(RRType::MX(), RRClass::IN(),
  580. "10 mx2.example.com");
  581. rdata_list_.clear();
  582. rdata_list_.push_back(mx_rdata1);
  583. rdata_list_.push_back(mx_rdata2);
  584. checkEncode(RRClass::IN(), RRType::MX(), rdata_list_, 0, rrsigs);
  585. ConstRdataPtr txt_rdata1 = createRdata(RRType::TXT(), RRClass::IN(),
  586. "foo bar baz");
  587. ConstRdataPtr txt_rdata2 = createRdata(RRType::TXT(), RRClass::IN(),
  588. "another text data");
  589. rdata_list_.clear();
  590. rdata_list_.push_back(txt_rdata1);
  591. rdata_list_.push_back(txt_rdata2);
  592. checkEncode(RRClass::IN(), RRType::TXT(), rdata_list_, 1, rrsigs);
  593. ConstRdataPtr naptr_rdata1 =
  594. createRdata(RRType::NAPTR(), RRClass::IN(),
  595. "100 50 \"s\" \"http\" \"\" _http._tcp.example.com");
  596. ConstRdataPtr naptr_rdata2 =
  597. createRdata(RRType::NAPTR(), RRClass::IN(),
  598. "200 100 \"s\" \"http\" \"\" _http._tcp.example.com");
  599. rdata_list_.clear();
  600. rdata_list_.push_back(naptr_rdata1);
  601. rdata_list_.push_back(naptr_rdata2);
  602. checkEncode(RRClass::IN(), RRType::NAPTR(), rdata_list_, 1, rrsigs);
  603. }
  604. void ignoreName(const LabelSequence&, unsigned) {
  605. }
  606. void
  607. checkLargeData(const in::DHCID* decoded, bool* called, const void* encoded,
  608. size_t length)
  609. {
  610. EXPECT_FALSE(*called); // Called exactly once
  611. *called = true;
  612. // Reconstruct the Rdata and check it.
  613. isc::util::InputBuffer ib(encoded, length);
  614. const in::DHCID reconstructed(ib, ib.getLength());
  615. EXPECT_EQ(0, reconstructed.compare(*decoded));
  616. }
  617. TEST_F(RdataSerializationTest, encodeLargeRdata) {
  618. // There should be no reason for a large RDATA to fail in encoding,
  619. // but we check such a case explicitly.
  620. encoded_data_.resize(65535); // max unsigned 16-bit int
  621. isc::util::InputBuffer buffer(&encoded_data_[0], encoded_data_.size());
  622. const in::DHCID large_dhcid(buffer, encoded_data_.size());
  623. encoder_.start(RRClass::IN(), RRType::DHCID());
  624. encoder_.addRdata(large_dhcid);
  625. encodeWrapper(encoder_.getStorageLength());
  626. // The encoded data should be identical to the original one.
  627. bool called = false;
  628. RdataReader reader(RRClass::IN(), RRType::DHCID(), &encoded_data_[0], 1, 0,
  629. ignoreName, boost::bind(checkLargeData, &large_dhcid,
  630. &called, _1, _2));
  631. reader.iterate();
  632. EXPECT_TRUE(called);
  633. called = false;
  634. reader.iterateAllSigs();
  635. EXPECT_FALSE(called);
  636. }
  637. TYPED_TEST(RdataEncodeDecodeTest, addRdataMulti) {
  638. vector<ConstRdataPtr> rrsigs;
  639. this->addRdataMultiCommon(rrsigs); // test without RRSIGs (empty vector)
  640. // Tests with two RRSIGs
  641. rrsigs.push_back(this->rrsig_rdata_);
  642. rrsigs.push_back(createRdata(RRType::RRSIG(), RRClass::IN(),
  643. "A 5 2 3600 20120814220826 "
  644. "20120715220826 54321 com. FAKE"));
  645. this->addRdataMultiCommon(rrsigs);
  646. }
  647. TEST_F(RdataSerializationTest, badAddRdata) {
  648. // Some operations must follow start().
  649. EXPECT_THROW(encoder_.addRdata(*a_rdata_), isc::InvalidOperation);
  650. EXPECT_THROW(encoder_.getStorageLength(), isc::InvalidOperation);
  651. // will allocate space of some arbitrary size (256 bytes)
  652. EXPECT_THROW(encodeWrapper(256), isc::InvalidOperation);
  653. // Bad buffer for encode
  654. encoder_.start(RRClass::IN(), RRType::A());
  655. encoder_.addRdata(*a_rdata_);
  656. const size_t buf_len = encoder_.getStorageLength();
  657. // NULL buffer for encode
  658. EXPECT_THROW(encoder_.encode(NULL, buf_len), isc::BadValue);
  659. // buffer length is too short (we don't use the wrraper because we don't
  660. // like to tweak the length arg to encode()).
  661. encoded_data_.resize(buf_len - 1);
  662. EXPECT_THROW(encoder_.encode(&encoded_data_[0], buf_len - 1),
  663. isc::BadValue);
  664. // Type of RDATA and the specified RR type don't match. addRdata() should
  665. // detect this inconsistency.
  666. encoder_.start(RRClass::IN(), RRType::AAAA());
  667. EXPECT_THROW(encoder_.addRdata(*a_rdata_), isc::BadValue);
  668. // Likewise.
  669. encoder_.start(RRClass::IN(), RRType::A());
  670. EXPECT_THROW(encoder_.addRdata(*aaaa_rdata_), isc::BadValue);
  671. // Likewise. The encoder expects the first name completes the data, and
  672. // throws on the second due as an unexpected name field.
  673. const ConstRdataPtr rp_rdata =
  674. createRdata(RRType::RP(), RRClass::IN(), "a.example. b.example");
  675. encoder_.start(RRClass::IN(), RRType::NS());
  676. EXPECT_THROW(encoder_.addRdata(*rp_rdata), isc::BadValue);
  677. // Likewise. The encoder considers the name data a variable length data
  678. // field, and throws on the first name.
  679. encoder_.start(RRClass::IN(), RRType::DHCID());
  680. EXPECT_THROW(encoder_.addRdata(*rp_rdata), isc::BadValue);
  681. // Likewise. The text RDATA (2 bytes) will be treated as MX preference,
  682. // and the encoder will still expect to see a domain name.
  683. const ConstRdataPtr txt_rdata = createRdata(RRType::TXT(), RRClass::IN(),
  684. "a");
  685. encoder_.start(RRClass::IN(), RRType::MX());
  686. EXPECT_THROW(encoder_.addRdata(*txt_rdata), isc::BadValue);
  687. // Similar to the previous one, but in this case there's no data field
  688. // in the spec.
  689. encoder_.start(RRClass::IN(), RRType::NS());
  690. EXPECT_THROW(encoder_.addRdata(*txt_rdata), isc::BadValue);
  691. // Likewise. Inconsistent name compression policy.
  692. const ConstRdataPtr ns_rdata =
  693. createRdata(RRType::NS(), RRClass::IN(), "ns.example");
  694. encoder_.start(RRClass::IN(), RRType::DNAME());
  695. EXPECT_THROW(encoder_.addRdata(*ns_rdata), isc::BadValue);
  696. // Same as the previous one, opposite inconsistency.
  697. const ConstRdataPtr dname_rdata =
  698. createRdata(RRType::DNAME(), RRClass::IN(), "dname.example");
  699. encoder_.start(RRClass::IN(), RRType::NS());
  700. EXPECT_THROW(encoder_.addRdata(*dname_rdata), isc::BadValue);
  701. // RDATA len exceeds the 16-bit range. Technically not invalid, but
  702. // we don't support that (and it's practically useless anyway).
  703. encoded_data_.resize(65536); // use encoded_data_ for placeholder
  704. isc::util::InputBuffer buffer(&encoded_data_[0], encoded_data_.size());
  705. encoder_.start(RRClass::IN(), RRType::DHCID());
  706. EXPECT_THROW(encoder_.addRdata(in::DHCID(buffer, encoded_data_.size())),
  707. RdataEncodingError);
  708. // RRSIG cannot be used as the main RDATA type (can only be added as
  709. // a signature for some other type of RDATAs).
  710. EXPECT_THROW(encoder_.start(RRClass::IN(), RRType::RRSIG()),
  711. isc::BadValue);
  712. }
  713. void
  714. checkSigData(const ConstRdataPtr& decoded, bool* called, const void* encoded,
  715. size_t length)
  716. {
  717. EXPECT_FALSE(*called); // Called exactly once
  718. *called = true;
  719. // Reconstruct the RRSig and check it.
  720. isc::util::InputBuffer ib(encoded, length);
  721. const generic::RRSIG reconstructed(ib, ib.getLength());
  722. EXPECT_EQ(0, reconstructed.compare(*decoded));
  723. }
  724. TEST_F(RdataSerializationTest, addSIGRdataOnly) {
  725. // Encoded data that only contain RRSIGs. Mostly useless, but can happen
  726. // (in a partially broken zone) and it's accepted.
  727. encoder_.start(RRClass::IN(), RRType::A());
  728. encoder_.addSIGRdata(*rrsig_rdata_);
  729. encodeWrapper(encoder_.getStorageLength());
  730. ASSERT_LT(sizeof(uint16_t), encoder_.getStorageLength());
  731. bool called = false;
  732. RdataReader reader(RRClass::IN(), RRType::A(), &encoded_data_[0], 0, 1,
  733. ignoreName, boost::bind(checkSigData, rrsig_rdata_,
  734. &called, _1, _2));
  735. reader.iterate();
  736. EXPECT_FALSE(called);
  737. reader.iterateAllSigs();
  738. EXPECT_TRUE(called);
  739. }
  740. TEST_F(RdataSerializationTest, badAddSIGRdata) {
  741. // try adding SIG before start
  742. EXPECT_THROW(encoder_.addSIGRdata(*rrsig_rdata_), isc::InvalidOperation);
  743. // Very big RRSIG. This implementation rejects it.
  744. isc::util::OutputBuffer ob(0);
  745. rrsig_rdata_->toWire(ob);
  746. // append dummy trailing signature to make it too big
  747. vector<uint8_t> dummy_sig(65536 - ob.getLength());
  748. ob.writeData(&dummy_sig[0], dummy_sig.size());
  749. ASSERT_EQ(65536, ob.getLength());
  750. isc::util::InputBuffer ib(ob.getData(), ob.getLength());
  751. const generic::RRSIG big_sigrdata(ib, ob.getLength());
  752. encoder_.start(RRClass::IN(), RRType::A());
  753. EXPECT_THROW(encoder_.addSIGRdata(big_sigrdata), RdataEncodingError);
  754. }
  755. }