rdataset_unittest.cc 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613
  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 <util/memory_segment_local.h>
  17. #include <dns/rdata.h>
  18. #include <dns/rdataclass.h>
  19. #include <dns/rrset.h>
  20. #include <dns/rrclass.h>
  21. #include <dns/rrtype.h>
  22. #include <dns/rrttl.h>
  23. #include <datasrc/memory/segment_object_holder.h>
  24. #include <datasrc/memory/rdata_serialization.h>
  25. #include <datasrc/memory/rdataset.h>
  26. #include <testutils/dnsmessage_test.h>
  27. #include <gtest/gtest.h>
  28. #include <boost/bind.hpp>
  29. #include <boost/lexical_cast.hpp>
  30. #include <vector>
  31. #include <string>
  32. using namespace isc::dns;
  33. using namespace isc::dns::rdata;
  34. using namespace isc::datasrc::memory;
  35. using namespace isc::testutils;
  36. using std::string;
  37. using std::vector;
  38. using isc::datasrc::memory::detail::SegmentObjectHolder;
  39. using boost::lexical_cast;
  40. namespace {
  41. class RdataSetTest : public ::testing::Test {
  42. protected:
  43. RdataSetTest() :
  44. rrclass(RRClass::IN()),
  45. // 1076895760 = 0x40302010. Use this so we fill in all 8-bit "field"
  46. // of the 32-bit TTL
  47. a_rrset_(textToRRset("www.example.com. 1076895760 IN A 192.0.2.1")),
  48. rrsig_rrset_(textToRRset("www.example.com. 1076895760 IN RRSIG "
  49. "A 5 2 3600 20120814220826 20120715220826 "
  50. "1234 example.com. FAKE"))
  51. {
  52. def_rdata_txt_.push_back("192.0.2.1");
  53. def_rrsig_txt_.push_back("A 5 2 3600 20120814220826 20120715220826 "
  54. "1234 example.com. FAKE");
  55. }
  56. void TearDown() {
  57. EXPECT_TRUE(mem_sgmt_.allMemoryDeallocated());
  58. }
  59. // Helper for checking common cases against both versions of create()
  60. typedef boost::function<RdataSet*(isc::util::MemorySegment&, RdataEncoder&,
  61. ConstRRsetPtr, ConstRRsetPtr)> CreateFn;
  62. void checkCreateManyRRs(CreateFn create_fn, size_t n_old_rdata);
  63. void checkCreateManyRRSIGs(CreateFn create_fn, size_t n_old_sig);
  64. void checkBadCreate(CreateFn create_fn);
  65. const RRClass rrclass;
  66. ConstRRsetPtr a_rrset_, rrsig_rrset_;
  67. isc::util::MemorySegmentLocal mem_sgmt_;
  68. RdataEncoder encoder_;
  69. // These are placeholder for default expected values used in checkRdataSet.
  70. vector<string> def_rdata_txt_;
  71. vector<string> def_rrsig_txt_;
  72. };
  73. // Convert the given 32-bit integer (network byte order) to the corresponding
  74. // RRTTL object.
  75. RRTTL
  76. restoreTTL(const void* ttl_data) {
  77. isc::util::InputBuffer b(ttl_data, sizeof(uint32_t));
  78. return (RRTTL(b));
  79. }
  80. // A helper callback for checkRdataSet. This confirms the given data
  81. // is the expected RDATA of the specified type.
  82. void
  83. checkData(const void* data, size_t size, const RRType* rrtype,
  84. vector<string>::const_iterator* it,
  85. vector<string>::const_iterator it_end)
  86. {
  87. ASSERT_TRUE(*it != it_end); // shouldn't reach the end yet
  88. isc::util::InputBuffer b(data, size);
  89. EXPECT_EQ(0, createRdata(*rrtype, RRClass::IN(), b, size)->compare(
  90. *createRdata(*rrtype, RRClass::IN(), **it)));
  91. ++(*it); // move to the next expected data
  92. }
  93. // This is a set of checks for an RdataSet created with some simple
  94. // conditions. expected_data/sigs contain the RDATAs and RRSIGs that are
  95. // supposed to be contained in rdataset. They can be empty if rdataset misses
  96. // RDATA or RRSIG (but not both).
  97. void
  98. checkRdataSet(const RdataSet& rdataset,
  99. vector<string> expected_data, // we use a local copy
  100. const vector<string>& expected_sigs)
  101. {
  102. EXPECT_FALSE(rdataset.next); // by default the next pointer should be NULL
  103. EXPECT_EQ(RRType::A(), rdataset.type);
  104. // See the RdataSetTest constructor for the magic number.
  105. EXPECT_EQ(RRTTL(1076895760), restoreTTL(rdataset.getTTLData()));
  106. EXPECT_EQ(expected_data.size(), rdataset.getRdataCount());
  107. EXPECT_EQ(expected_sigs.size(), rdataset.getSigRdataCount());
  108. // extend expected_data with sigs for the convenience of RdataReader
  109. expected_data.insert(expected_data.end(), expected_sigs.begin(),
  110. expected_sigs.end());
  111. // A simple test for the data content. Detailed tests for the encoder/
  112. // reader should be basically sufficient for various cases of the data,
  113. // and the fact that this test doesn't detect memory leak should be
  114. // reasonably sufficient that the implementation handles the data region
  115. // correctly. Here we check one simple case for a simple form of RDATA
  116. // and RRSIG, mainly for checking the behavior of getDataBuf().
  117. vector<string>::const_iterator it = expected_data.begin();
  118. RRType rrtype = RRType::A();
  119. RdataReader reader(RRClass::IN(), RRType::A(),
  120. reinterpret_cast<const uint8_t*>(
  121. rdataset.getDataBuf()),
  122. rdataset.getRdataCount(), rdataset.getSigRdataCount(),
  123. &RdataReader::emptyNameAction,
  124. boost::bind(checkData, _1, _2, &rrtype, &it,
  125. expected_data.end()));
  126. reader.iterate();
  127. rrtype = RRType::RRSIG();
  128. reader.iterateAllSigs();
  129. EXPECT_TRUE(it == expected_data.end());
  130. }
  131. TEST_F(RdataSetTest, create) {
  132. // A simple case of creating an RdataSet. Confirming the resulting
  133. // fields have the expected values, and then destroying it (TearDown()
  134. // would detect any memory leak)
  135. RdataSet* rdataset = RdataSet::create(mem_sgmt_, encoder_, a_rrset_,
  136. ConstRRsetPtr());
  137. checkRdataSet(*rdataset, def_rdata_txt_, vector<string>());
  138. RdataSet::destroy(mem_sgmt_, rdataset, RRClass::IN());
  139. }
  140. // This is similar to the simple create test, but we check all combinations
  141. // of old and new data.
  142. TEST_F(RdataSetTest, mergeCreate) {
  143. // Prepare test data
  144. const char* const a_rdatas[] = { "192.0.2.1", "192.0.2.2" };
  145. const char* const sig_rdatas[] = {
  146. "A 5 2 3600 20120814220826 20120715220826 1234 example.com. FAKE",
  147. "A 5 2 3600 20120814220826 20120715220826 4321 example.com. FAKE" };
  148. vector<ConstRRsetPtr> a_rrsets;
  149. a_rrsets.push_back(textToRRset("www.example.com. 1076895760 IN A "
  150. + string(a_rdatas[0])));
  151. a_rrsets.push_back(textToRRset("www.example.com. 1076895760 IN A "
  152. + string(a_rdatas[1])));
  153. vector<ConstRRsetPtr> rrsig_rrsets;
  154. rrsig_rrsets.push_back(textToRRset("www.example.com. 1076895760 IN RRSIG "
  155. + string(sig_rdatas[0])));
  156. rrsig_rrsets.push_back(textToRRset("www.example.com. 1076895760 IN RRSIG "
  157. + string(sig_rdatas[1])));
  158. ConstRRsetPtr null_rrset; // convenience shortcut
  159. // We are going to check all combinations of:
  160. // with/without old/new RDATA/RRSIGs.
  161. // counter variables i, j control the old and new data, respectively, and
  162. // the meaning of the value is: bit 1: with RDATA, bit 2: with RRSIG.
  163. // Note that at least one RDATA or RRSIG should be contained, so there's
  164. // no case for value 0.
  165. for (int i = 1; i < 4; ++i) {
  166. for (int j = 1; j < 4; ++j) {
  167. SCOPED_TRACE("creating merge case " + lexical_cast<string>(i) +
  168. ", " + lexical_cast<string>(j));
  169. // Create old rdataset
  170. SegmentObjectHolder<RdataSet, RRClass> holder1(mem_sgmt_, rrclass);
  171. holder1.set(RdataSet::create(mem_sgmt_, encoder_,
  172. (i & 1) != 0 ? a_rrsets[0] : null_rrset,
  173. (i & 2) != 0 ? rrsig_rrsets[0] : null_rrset));
  174. // Create merged rdataset, based on the old one and RRsets
  175. SegmentObjectHolder<RdataSet, RRClass> holder2(mem_sgmt_, rrclass);
  176. holder2.set(RdataSet::create(mem_sgmt_, encoder_,
  177. (j & 1) != 0 ? a_rrsets[1] : null_rrset,
  178. (j & 2) != 0 ? rrsig_rrsets[1] : null_rrset,
  179. holder1.get()));
  180. // Set up the expected data for the case.
  181. vector<string> expected_rdata;
  182. if ((i & 1) != 0) {
  183. expected_rdata.push_back(a_rdatas[0]);
  184. }
  185. if ((j & 1) != 0) {
  186. expected_rdata.push_back(a_rdatas[1]);
  187. }
  188. vector<string> expected_sigs;
  189. if ((i & 2) != 0) {
  190. expected_sigs.push_back(sig_rdatas[0]);
  191. }
  192. if ((j & 2) != 0) {
  193. expected_sigs.push_back(sig_rdatas[1]);
  194. }
  195. // Then perform the check
  196. checkRdataSet(*holder2.get(), expected_rdata, expected_sigs);
  197. }
  198. }
  199. }
  200. TEST_F(RdataSetTest, duplicate) {
  201. // Create RRset and RRSIG containing duplicate RDATA.
  202. ConstRRsetPtr dup_rrset =
  203. textToRRset("www.example.com. 1076895760 IN A 192.0.2.1\n"
  204. "www.example.com. 1076895760 IN A 192.0.2.1\n");
  205. ConstRRsetPtr dup_rrsig =
  206. textToRRset("www.example.com. 1076895760 IN RRSIG " +
  207. def_rrsig_txt_[0] +
  208. "\nwww.example.com. 1076895760 IN RRSIG " +
  209. def_rrsig_txt_[0]);
  210. // After suppressing duplicates, it should be the same as the default
  211. // RdataSet. Check that.
  212. SegmentObjectHolder<RdataSet, RRClass> holder1(mem_sgmt_, rrclass);
  213. holder1.set(RdataSet::create(mem_sgmt_, encoder_, dup_rrset, dup_rrsig));
  214. checkRdataSet(*holder1.get(), def_rdata_txt_, def_rrsig_txt_);
  215. // Confirm the same thing for the merge mode.
  216. SegmentObjectHolder<RdataSet, RRClass> holder2(mem_sgmt_, rrclass);
  217. holder2.set(RdataSet::create(mem_sgmt_, encoder_, a_rrset_, rrsig_rrset_,
  218. holder1.get()));
  219. checkRdataSet(*holder2.get(), def_rdata_txt_, def_rrsig_txt_);
  220. }
  221. TEST_F(RdataSetTest, getNext) {
  222. RdataSet* rdataset = RdataSet::create(mem_sgmt_, encoder_, a_rrset_,
  223. ConstRRsetPtr());
  224. // By default, the next pointer should be NULL (already tested in other
  225. // test cases), which should be the case with getNext(). We test both
  226. // mutable and immutable versions of getNext().
  227. EXPECT_EQ(static_cast<RdataSet*>(NULL), rdataset->getNext());
  228. EXPECT_EQ(static_cast<const RdataSet*>(NULL),
  229. static_cast<const RdataSet*>(rdataset)->getNext());
  230. // making a link (it would form an infinite loop, but it doesn't matter
  231. // in this test), and check the pointer returned by getNext().
  232. rdataset->next = rdataset;
  233. EXPECT_EQ(rdataset, static_cast<const RdataSet*>(rdataset)->getNext());
  234. RdataSet::destroy(mem_sgmt_, rdataset, RRClass::IN());
  235. }
  236. TEST_F(RdataSetTest, find) {
  237. // Create some RdataSets and make a chain of them.
  238. SegmentObjectHolder<RdataSet, RRClass> holder1(mem_sgmt_, RRClass::IN());
  239. holder1.set(RdataSet::create(mem_sgmt_, encoder_, a_rrset_,
  240. ConstRRsetPtr()));
  241. ConstRRsetPtr aaaa_rrset =
  242. textToRRset("www.example.com. 1076895760 IN AAAA 2001:db8::1");
  243. SegmentObjectHolder<RdataSet, RRClass> holder2(mem_sgmt_, RRClass::IN());
  244. holder2.set(RdataSet::create(mem_sgmt_, encoder_, aaaa_rrset,
  245. ConstRRsetPtr()));
  246. ConstRRsetPtr sigonly_rrset =
  247. textToRRset("www.example.com. 1076895760 IN RRSIG "
  248. "TXT 5 2 3600 20120814220826 20120715220826 "
  249. "1234 example.com. FAKE");
  250. SegmentObjectHolder<RdataSet, RRClass> holder3(mem_sgmt_, RRClass::IN());
  251. holder3.set(RdataSet::create(mem_sgmt_, encoder_, ConstRRsetPtr(),
  252. sigonly_rrset));
  253. RdataSet* rdataset_a = holder1.get();
  254. RdataSet* rdataset_aaaa = holder2.get();
  255. RdataSet* rdataset_sigonly = holder3.get();
  256. RdataSet* rdataset_null = NULL;
  257. rdataset_a->next = rdataset_aaaa;
  258. rdataset_aaaa->next = rdataset_sigonly;
  259. // If a non-RRSIG part of rdataset exists for the given type, it will be
  260. // returned regardless of the value of sigonly_ok. If it's RRSIG-only
  261. // rdataset, it returns non NULL iff sigonly_ok is explicitly set to true.
  262. EXPECT_EQ(rdataset_aaaa, RdataSet::find(rdataset_a, RRType::AAAA()));
  263. EXPECT_EQ(rdataset_aaaa, RdataSet::find(rdataset_a, RRType::AAAA(), true));
  264. EXPECT_EQ(rdataset_aaaa, RdataSet::find(rdataset_a, RRType::AAAA(), false));
  265. EXPECT_EQ(rdataset_null, RdataSet::find(rdataset_a, RRType::TXT()));
  266. EXPECT_EQ(rdataset_sigonly, RdataSet::find(rdataset_a, RRType::TXT(),
  267. true));
  268. EXPECT_EQ(rdataset_null, RdataSet::find(rdataset_a, RRType::TXT(), false));
  269. // Same tests for the const version of find().
  270. const RdataSet* rdataset_a_const = holder1.get();
  271. EXPECT_EQ(rdataset_aaaa, RdataSet::find(rdataset_a_const, RRType::AAAA()));
  272. EXPECT_EQ(rdataset_aaaa, RdataSet::find(rdataset_a_const, RRType::AAAA(),
  273. true));
  274. EXPECT_EQ(rdataset_aaaa, RdataSet::find(rdataset_a_const, RRType::AAAA(),
  275. false));
  276. EXPECT_EQ(rdataset_null, RdataSet::find(rdataset_a_const, RRType::TXT()));
  277. EXPECT_EQ(rdataset_sigonly, RdataSet::find(rdataset_a_const, RRType::TXT(),
  278. true));
  279. EXPECT_EQ(rdataset_null, RdataSet::find(rdataset_a_const, RRType::TXT(),
  280. false));
  281. }
  282. // A helper function to create an RRset containing the given number of
  283. // unique RDATAs. We return non const pointer so that we can extend it.
  284. RRsetPtr
  285. getRRsetWithRdataCount(size_t rdata_count) {
  286. RRsetPtr rrset(new RRset(Name("example.com"), RRClass::IN(), RRType::TXT(),
  287. RRTTL(3600)));
  288. for (size_t i = 0; i < rdata_count; ++i) {
  289. rrset->addRdata(rdata::createRdata(RRType::TXT(), RRClass::IN(),
  290. lexical_cast<std::string>(i)));
  291. }
  292. return (rrset);
  293. }
  294. void
  295. RdataSetTest::checkCreateManyRRs(CreateFn create_fn, size_t n_old_rdata) {
  296. // RRset with possible maximum number of RDATAs, taking into account
  297. // "pre-existing" RDATAs
  298. RRsetPtr large_rrset = getRRsetWithRdataCount(8191 - n_old_rdata);
  299. RdataSet* rdataset = create_fn(mem_sgmt_, encoder_, large_rrset,
  300. ConstRRsetPtr());
  301. EXPECT_EQ(8191, rdataset->getRdataCount());
  302. EXPECT_EQ(0, rdataset->getSigRdataCount());
  303. RdataSet::destroy(mem_sgmt_, rdataset, rrclass);
  304. // Duplicate RDATA will be ignored in this check.
  305. large_rrset->addRdata(createRdata(RRType::TXT(), rrclass, "0"));
  306. rdataset = create_fn(mem_sgmt_, encoder_, large_rrset, ConstRRsetPtr());
  307. EXPECT_EQ(8191, rdataset->getRdataCount());
  308. RdataSet::destroy(mem_sgmt_, rdataset, rrclass);
  309. // Exceeding that will result in an exception.
  310. large_rrset->addRdata(createRdata(RRType::TXT(), rrclass, "8192"));
  311. EXPECT_THROW(create_fn(mem_sgmt_, encoder_, large_rrset, ConstRRsetPtr()),
  312. RdataSetError);
  313. // To be very sure even try larger number than the threshold
  314. EXPECT_THROW(create_fn(mem_sgmt_, encoder_,
  315. getRRsetWithRdataCount(65535 - n_old_rdata),
  316. ConstRRsetPtr()),
  317. RdataSetError);
  318. }
  319. TEST_F(RdataSetTest, createManyRRs) {
  320. checkCreateManyRRs(boost::bind(&RdataSet::create, _1, _2, _3, _4,
  321. static_cast<const RdataSet*>(NULL)), 0);
  322. }
  323. TEST_F(RdataSetTest, mergeCreateManyRRs) {
  324. ConstRRsetPtr rrset = textToRRset("example.com. 3600 IN TXT some-text");
  325. SegmentObjectHolder<RdataSet, RRClass> holder(mem_sgmt_, RRClass::IN());
  326. holder.set(RdataSet::create(mem_sgmt_, encoder_, rrset, ConstRRsetPtr()));
  327. checkCreateManyRRs(boost::bind(&RdataSet::create, _1, _2, _3, _4,
  328. holder.get()), rrset->getRdataCount());
  329. }
  330. TEST_F(RdataSetTest, createWithRRSIG) {
  331. RdataSet* rdataset = RdataSet::create(mem_sgmt_, encoder_, a_rrset_,
  332. rrsig_rrset_);
  333. checkRdataSet(*rdataset, def_rdata_txt_, def_rrsig_txt_);
  334. RdataSet::destroy(mem_sgmt_, rdataset, RRClass::IN());
  335. }
  336. // A helper function to create an RRSIG RRset containing the given number of
  337. // unique RDATAs.
  338. RRsetPtr
  339. getRRSIGWithRdataCount(size_t sig_count) {
  340. RRsetPtr rrset(new RRset(Name("example.com"), RRClass::IN(),
  341. RRType::RRSIG(), RRTTL(3600)));
  342. // We use a base wire-format image and tweak the original TTL field to
  343. // generate unique RDATAs in the loop. (Creating them from corresponding
  344. // text is simpler, but doing so for a large number of RRSIGs is
  345. // relatively heavy and could be too long for unittests).
  346. ConstRdataPtr rrsig_base =
  347. rdata::createRdata(RRType::RRSIG(), RRClass::IN(),
  348. "A 5 2 3600 20120814220826 20120715220826 1234 "
  349. "example.com. FAKE");
  350. isc::util::OutputBuffer ob(0);
  351. rrsig_base->toWire(ob);
  352. for (size_t i = 0; i < sig_count; ++i) {
  353. ob.writeUint16At((i >> 16) & 0xffff, 4);
  354. ob.writeUint16At(i & 0xffff, 6);
  355. isc::util::InputBuffer ib(ob.getData(), ob.getLength());
  356. rrset->addRdata(rdata::createRdata(RRType::RRSIG(), RRClass::IN(),
  357. ib, ib.getLength()));
  358. }
  359. return (rrset);
  360. }
  361. void
  362. RdataSetTest::checkCreateManyRRSIGs(CreateFn create_fn, size_t n_old_sig) {
  363. // 7 has a special meaning in the implementation: if the number of the
  364. // RRSIGs reaches this value, an extra 'sig count' field will be created.
  365. RdataSet* rdataset = create_fn(mem_sgmt_, encoder_, a_rrset_,
  366. getRRSIGWithRdataCount(7 - n_old_sig));
  367. EXPECT_EQ(7, rdataset->getSigRdataCount());
  368. RdataSet::destroy(mem_sgmt_, rdataset, RRClass::IN());
  369. // 8 would cause overflow in the normal 3-bit field if there were no extra
  370. // count field.
  371. rdataset = create_fn(mem_sgmt_, encoder_, a_rrset_,
  372. getRRSIGWithRdataCount(8 - n_old_sig));
  373. EXPECT_EQ(8, rdataset->getSigRdataCount());
  374. RdataSet::destroy(mem_sgmt_, rdataset, RRClass::IN());
  375. // Up to 2^16-1 RRSIGs are allowed (although that would be useless
  376. // in practice)
  377. RRsetPtr large_rrsig = getRRSIGWithRdataCount(65535 - n_old_sig);
  378. rdataset = create_fn(mem_sgmt_, encoder_, a_rrset_, large_rrsig);
  379. EXPECT_EQ(65535, rdataset->getSigRdataCount());
  380. RdataSet::destroy(mem_sgmt_, rdataset, RRClass::IN());
  381. // Duplicate shouldn't be counted
  382. large_rrsig->addRdata(
  383. createRdata(RRType::RRSIG(), rrclass,
  384. "A 5 2 0 20120814220826 20120715220826 1234 "
  385. "example.com. FAKE"));
  386. rdataset = create_fn(mem_sgmt_, encoder_, a_rrset_, large_rrsig);
  387. EXPECT_EQ(65535, rdataset->getSigRdataCount());
  388. RdataSet::destroy(mem_sgmt_, rdataset, RRClass::IN());
  389. // Exceeding this limit will result in an exception.
  390. large_rrsig->addRdata(
  391. createRdata(RRType::RRSIG(), rrclass,
  392. "A 5 2 65536 20120814220826 20120715220826 1234 "
  393. "example.com. FAKE"));
  394. EXPECT_THROW(create_fn(mem_sgmt_, encoder_, a_rrset_, large_rrsig),
  395. RdataSetError);
  396. // To be very sure even try larger number than the threshold
  397. EXPECT_THROW(create_fn(mem_sgmt_, encoder_, a_rrset_,
  398. getRRSIGWithRdataCount(70000 - n_old_sig)),
  399. RdataSetError);
  400. }
  401. TEST_F(RdataSetTest, createManyRRSIGs) {
  402. checkCreateManyRRSIGs(boost::bind(&RdataSet::create, _1, _2, _3, _4,
  403. static_cast<const RdataSet*>(NULL)), 0);
  404. }
  405. TEST_F(RdataSetTest, mergeCreateManyRRSIGs) {
  406. // Create "old" RRSIG that shouldn't be a duplicate of ones created in
  407. // checkCreateManyRRSIGs (signature is different).
  408. ConstRRsetPtr rrsig = textToRRset(
  409. "example.com. 3600 IN RRSIG A 5 2 3600 20120814220826 20120715220826 "
  410. "1234 example.com. FAKEFAKE");
  411. SegmentObjectHolder<RdataSet, RRClass> holder(mem_sgmt_, rrclass);
  412. holder.set(RdataSet::create(mem_sgmt_, encoder_, ConstRRsetPtr(), rrsig));
  413. checkCreateManyRRSIGs(boost::bind(&RdataSet::create, _1, _2, _3, _4,
  414. holder.get()), rrsig->getRdataCount());
  415. }
  416. TEST_F(RdataSetTest, createWithRRSIGOnly) {
  417. // A rare, but allowed, case: RdataSet without the main RRset but with
  418. // RRSIG.
  419. RdataSet* rdataset = RdataSet::create(mem_sgmt_, encoder_, ConstRRsetPtr(),
  420. rrsig_rrset_);
  421. checkRdataSet(*rdataset, vector<string>(), def_rrsig_txt_);
  422. RdataSet::destroy(mem_sgmt_, rdataset, RRClass::IN());
  423. }
  424. // Checking initial validation for both versions of create().
  425. void
  426. RdataSetTest::checkBadCreate(CreateFn create_fn) {
  427. // Neither the RRset nor RRSIG RRset is given
  428. EXPECT_THROW(create_fn(mem_sgmt_, encoder_, ConstRRsetPtr(),
  429. ConstRRsetPtr()), isc::BadValue);
  430. // Empty RRset (An RRset without RDATA)
  431. ConstRRsetPtr empty_rrset(new RRset(Name("example.com"), RRClass::IN(),
  432. RRType::A(), RRTTL(3600)));
  433. EXPECT_THROW(create_fn(mem_sgmt_, encoder_, empty_rrset,
  434. ConstRRsetPtr()), isc::BadValue);
  435. ConstRRsetPtr empty_rrsig(new RRset(Name("example.com"), RRClass::IN(),
  436. RRType::RRSIG(), RRTTL(3600)));
  437. EXPECT_THROW(create_fn(mem_sgmt_, encoder_, ConstRRsetPtr(),
  438. empty_rrsig), isc::BadValue);
  439. // The RRset type and RRSIG's type covered don't match
  440. ConstRRsetPtr bad_rrsig(textToRRset(
  441. "www.example.com. 1076895760 IN RRSIG "
  442. "NS 5 2 3600 20120814220826 20120715220826 "
  443. "1234 example.com. FAKE"));
  444. EXPECT_THROW(create_fn(mem_sgmt_, encoder_, a_rrset_, bad_rrsig),
  445. isc::BadValue);
  446. // Pass non RRSIG for the sig parameter
  447. EXPECT_THROW(create_fn(mem_sgmt_, encoder_, a_rrset_, a_rrset_),
  448. isc::BadValue);
  449. // Pass RRSIG for normal RRset (the RdataEncoder will catch this and throw)
  450. EXPECT_THROW(create_fn(mem_sgmt_, encoder_, rrsig_rrset_, rrsig_rrset_),
  451. isc::BadValue);
  452. // RR class doesn't match between RRset and RRSIG
  453. ConstRRsetPtr badclass_rrsig(textToRRset(
  454. "www.example.com. 1076895760 CH RRSIG "
  455. "A 5 2 3600 20120814220826 "
  456. "20120715220826 1234 example.com. FAKE",
  457. RRClass::CH()));
  458. EXPECT_THROW(create_fn(mem_sgmt_, encoder_, a_rrset_, badclass_rrsig),
  459. isc::BadValue);
  460. }
  461. TEST_F(RdataSetTest, badCreate) {
  462. checkBadCreate(boost::bind(&RdataSet::create, _1, _2, _3, _4,
  463. static_cast<const RdataSet*>(NULL)));
  464. }
  465. TEST_F(RdataSetTest, badMergeCreate) {
  466. // The 'old RdataSet' for merge. Its content doesn't matter much; the test
  467. // should trigger exception before examining it except for the last checks.
  468. SegmentObjectHolder<RdataSet, RRClass> holder(mem_sgmt_, RRClass::IN());
  469. holder.set(RdataSet::create(mem_sgmt_, encoder_,
  470. textToRRset("www.example.com. 0 IN AAAA 2001:db8::1"),
  471. ConstRRsetPtr()));
  472. checkBadCreate(boost::bind(&RdataSet::create, _1, _2, _3, _4,
  473. holder.get()));
  474. // Type mismatch: this case is specific to the merge create.
  475. EXPECT_THROW(RdataSet::create(mem_sgmt_, encoder_, a_rrset_,
  476. ConstRRsetPtr(), holder.get()),
  477. isc::BadValue);
  478. EXPECT_THROW(RdataSet::create(mem_sgmt_, encoder_, ConstRRsetPtr(),
  479. rrsig_rrset_, holder.get()),
  480. isc::BadValue);
  481. }
  482. TEST_F(RdataSetTest, varyingTTL) {
  483. // Creating RdataSets with different TTLs. The lowest one should win.
  484. ConstRRsetPtr aaaa_smaller = textToRRset("example. 5 IN AAAA 2001:db8::");
  485. ConstRRsetPtr aaaa_small = textToRRset("example. 10 IN AAAA 2001:db8::1");
  486. ConstRRsetPtr aaaa_large = textToRRset("example. 20 IN AAAA 2001:db8::2");
  487. ConstRRsetPtr sig_smaller =
  488. textToRRset("www.example.com. 5 IN RRSIG AAAA 5 2 3600 "
  489. "20120814220826 20120715220826 1111 example.com. FAKE");
  490. ConstRRsetPtr sig_small =
  491. textToRRset("www.example.com. 10 IN RRSIG AAAA 5 2 3600 "
  492. "20120814220826 20120715220826 1234 example.com. FAKE");
  493. ConstRRsetPtr sig_large =
  494. textToRRset("www.example.com. 20 IN RRSIG AAAA 5 2 3600 "
  495. "20120814220826 20120715220826 4321 example.com. FAKE");
  496. // RRSIG's TTL is larger
  497. RdataSet* rdataset = RdataSet::create(mem_sgmt_, encoder_, aaaa_small,
  498. sig_large);
  499. EXPECT_EQ(RRTTL(10), restoreTTL(rdataset->getTTLData()));
  500. RdataSet::destroy(mem_sgmt_, rdataset, rrclass);
  501. // RRSIG's TTL is smaller
  502. SegmentObjectHolder<RdataSet, RRClass> holder1(mem_sgmt_, rrclass);
  503. holder1.set(RdataSet::create(mem_sgmt_, encoder_, aaaa_large, sig_small));
  504. EXPECT_EQ(RRTTL(10), restoreTTL(holder1.get()->getTTLData()));
  505. // Merging another RRset (w/o sig) that has larger TTL
  506. rdataset = RdataSet::create(mem_sgmt_, encoder_, aaaa_large,
  507. ConstRRsetPtr(), holder1.get());
  508. EXPECT_EQ(RRTTL(10), restoreTTL(rdataset->getTTLData()));
  509. RdataSet::destroy(mem_sgmt_, rdataset, rrclass);
  510. // Merging another RRset (w/o sig) that has smaller TTL
  511. rdataset = RdataSet::create(mem_sgmt_, encoder_, aaaa_smaller,
  512. ConstRRsetPtr(), holder1.get());
  513. EXPECT_EQ(RRTTL(5), restoreTTL(rdataset->getTTLData()));
  514. RdataSet::destroy(mem_sgmt_, rdataset, rrclass);
  515. // Merging another RRSIG (w/o RRset) that has larger TTL
  516. rdataset = RdataSet::create(mem_sgmt_, encoder_, ConstRRsetPtr(),
  517. sig_large, holder1.get());
  518. EXPECT_EQ(RRTTL(10), restoreTTL(rdataset->getTTLData()));
  519. RdataSet::destroy(mem_sgmt_, rdataset, rrclass);
  520. // Merging another RRSIG (w/o RRset) that has smaller TTL
  521. rdataset = RdataSet::create(mem_sgmt_, encoder_, ConstRRsetPtr(),
  522. sig_smaller, holder1.get());
  523. EXPECT_EQ(RRTTL(5), restoreTTL(rdataset->getTTLData()));
  524. RdataSet::destroy(mem_sgmt_, rdataset, rrclass);
  525. // Merging another RRset and RRSIG that have larger TTL
  526. rdataset = RdataSet::create(mem_sgmt_, encoder_, aaaa_large, sig_large,
  527. holder1.get());
  528. EXPECT_EQ(RRTTL(10), restoreTTL(rdataset->getTTLData()));
  529. RdataSet::destroy(mem_sgmt_, rdataset, rrclass);
  530. // Merging another RRset and RRSIG that have smaller TTL
  531. rdataset = RdataSet::create(mem_sgmt_, encoder_, aaaa_smaller, sig_smaller,
  532. holder1.get());
  533. EXPECT_EQ(RRTTL(5), restoreTTL(rdataset->getTTLData()));
  534. RdataSet::destroy(mem_sgmt_, rdataset, rrclass);
  535. }
  536. }