rdataset_unittest.cc 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748
  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. const RdataPtr& actual(createRdata(*rrtype, RRClass::IN(), b, size));
  90. const RdataPtr& expected(createRdata(*rrtype, RRClass::IN(), **it));
  91. EXPECT_EQ(0, actual->compare(*expected)) << actual->toText() <<
  92. " vs. " << expected->toText();
  93. ++(*it); // move to the next expected data
  94. }
  95. // This is a set of checks for an RdataSet created with some simple
  96. // conditions. expected_data/sigs contain the RDATAs and RRSIGs that are
  97. // supposed to be contained in rdataset. They can be empty if rdataset misses
  98. // RDATA or RRSIG (but not both).
  99. void
  100. checkRdataSet(const RdataSet& rdataset,
  101. vector<string> expected_data, // we use a local copy
  102. const vector<string>& expected_sigs)
  103. {
  104. EXPECT_FALSE(rdataset.next); // by default the next pointer should be NULL
  105. EXPECT_EQ(RRType::A(), rdataset.type);
  106. // See the RdataSetTest constructor for the magic number.
  107. EXPECT_EQ(RRTTL(1076895760), restoreTTL(rdataset.getTTLData()));
  108. EXPECT_EQ(expected_data.size(), rdataset.getRdataCount());
  109. EXPECT_EQ(expected_sigs.size(), rdataset.getSigRdataCount());
  110. // extend expected_data with sigs for the convenience of RdataReader
  111. expected_data.insert(expected_data.end(), expected_sigs.begin(),
  112. expected_sigs.end());
  113. // A simple test for the data content. Detailed tests for the encoder/
  114. // reader should be basically sufficient for various cases of the data,
  115. // and the fact that this test doesn't detect memory leak should be
  116. // reasonably sufficient that the implementation handles the data region
  117. // correctly. Here we check one simple case for a simple form of RDATA
  118. // and RRSIG, mainly for checking the behavior of getDataBuf().
  119. vector<string>::const_iterator it = expected_data.begin();
  120. RRType rrtype = RRType::A();
  121. RdataReader reader(RRClass::IN(), RRType::A(),
  122. reinterpret_cast<const uint8_t*>(
  123. rdataset.getDataBuf()),
  124. rdataset.getRdataCount(), rdataset.getSigRdataCount(),
  125. &RdataReader::emptyNameAction,
  126. boost::bind(checkData, _1, _2, &rrtype, &it,
  127. expected_data.end()));
  128. reader.iterate();
  129. rrtype = RRType::RRSIG();
  130. reader.iterateAllSigs();
  131. EXPECT_TRUE(it == expected_data.end());
  132. }
  133. TEST_F(RdataSetTest, create) {
  134. // A simple case of creating an RdataSet. Confirming the resulting
  135. // fields have the expected values, and then destroying it (TearDown()
  136. // would detect any memory leak)
  137. RdataSet* rdataset = RdataSet::create(mem_sgmt_, encoder_, a_rrset_,
  138. ConstRRsetPtr());
  139. checkRdataSet(*rdataset, def_rdata_txt_, vector<string>());
  140. RdataSet::destroy(mem_sgmt_, rdataset, RRClass::IN());
  141. }
  142. // This is similar to the simple create test, but we check all combinations
  143. // of old and new data.
  144. TEST_F(RdataSetTest, mergeCreate) {
  145. // Prepare test data
  146. const char* const a_rdatas[] = { "192.0.2.1", "192.0.2.2" };
  147. const char* const sig_rdatas[] = {
  148. "A 5 2 3600 20120814220826 20120715220826 1234 example.com. FAKE",
  149. "A 5 2 3600 20120814220826 20120715220826 4321 example.com. FAKE" };
  150. vector<ConstRRsetPtr> a_rrsets;
  151. a_rrsets.push_back(textToRRset("www.example.com. 1076895760 IN A "
  152. + string(a_rdatas[0])));
  153. a_rrsets.push_back(textToRRset("www.example.com. 1076895760 IN A "
  154. + string(a_rdatas[1])));
  155. vector<ConstRRsetPtr> rrsig_rrsets;
  156. rrsig_rrsets.push_back(textToRRset("www.example.com. 1076895760 IN RRSIG "
  157. + string(sig_rdatas[0])));
  158. rrsig_rrsets.push_back(textToRRset("www.example.com. 1076895760 IN RRSIG "
  159. + string(sig_rdatas[1])));
  160. ConstRRsetPtr null_rrset; // convenience shortcut
  161. // We are going to check all combinations of:
  162. // with/without old/new RDATA/RRSIGs.
  163. // counter variables i, j control the old and new data, respectively, and
  164. // the meaning of the value is: bit 1: with RDATA, bit 2: with RRSIG.
  165. // Note that at least one RDATA or RRSIG should be contained, so there's
  166. // no case for value 0.
  167. for (int i = 1; i < 4; ++i) {
  168. for (int j = 1; j < 4; ++j) {
  169. SCOPED_TRACE("creating merge case " + lexical_cast<string>(i) +
  170. ", " + lexical_cast<string>(j));
  171. // Create old rdataset
  172. SegmentObjectHolder<RdataSet, RRClass> holder1(mem_sgmt_, rrclass);
  173. holder1.set(RdataSet::create(mem_sgmt_, encoder_,
  174. (i & 1) != 0 ? a_rrsets[0] : null_rrset,
  175. (i & 2) != 0 ? rrsig_rrsets[0] : null_rrset));
  176. // Create merged rdataset, based on the old one and RRsets
  177. SegmentObjectHolder<RdataSet, RRClass> holder2(mem_sgmt_, rrclass);
  178. holder2.set(RdataSet::create(mem_sgmt_, encoder_,
  179. (j & 1) != 0 ? a_rrsets[1] : null_rrset,
  180. (j & 2) != 0 ? rrsig_rrsets[1] : null_rrset,
  181. holder1.get()));
  182. // Set up the expected data for the case.
  183. vector<string> expected_rdata;
  184. if ((i & 1) != 0) {
  185. expected_rdata.push_back(a_rdatas[0]);
  186. }
  187. if ((j & 1) != 0) {
  188. expected_rdata.push_back(a_rdatas[1]);
  189. }
  190. vector<string> expected_sigs;
  191. if ((i & 2) != 0) {
  192. expected_sigs.push_back(sig_rdatas[0]);
  193. }
  194. if ((j & 2) != 0) {
  195. expected_sigs.push_back(sig_rdatas[1]);
  196. }
  197. // Then perform the check
  198. checkRdataSet(*holder2.get(), expected_rdata, expected_sigs);
  199. }
  200. }
  201. }
  202. TEST_F(RdataSetTest, subtract) {
  203. // Prepare test data
  204. const char* const a_rdatas[] = { "192.0.2.1", "192.0.2.2" };
  205. const char* const sig_rdatas[] = {
  206. "A 5 2 3600 20120814220826 20120715220826 1234 example.com. FAKE",
  207. "A 5 2 3600 20120814220826 20120715220826 4321 example.com. FAKE" };
  208. ConstRRsetPtr a_rrsets = textToRRset("www.example.com. 1076895760 IN A "
  209. + string(a_rdatas[0]) + "\n"
  210. + "www.example.com. 1076895760 IN A "
  211. + string(a_rdatas[1]));
  212. ConstRRsetPtr rrsig_rrsets =
  213. textToRRset("www.example.com. 1076895760 IN RRSIG "
  214. + string(sig_rdatas[0]) + "\n"
  215. + "www.example.com. 1076895760 IN RRSIG "
  216. + string(sig_rdatas[1]));
  217. ConstRRsetPtr null_rrset; // convenience shortcut
  218. // Prepare the data to subtract (they have one common and one differing
  219. // element each).
  220. const char* const a_rdatas_rm[] = { "192.0.2.1", "192.0.2.3" };
  221. const char* const sig_rdatas_rm[] = {
  222. "A 5 2 3600 20120814220826 20120715220826 1234 example.com. FAKE",
  223. "A 5 2 3600 20120814220826 20120715220826 5678 example.com. FAKE" };
  224. ConstRRsetPtr a_rrsets_rm =
  225. textToRRset("www.example.com. 1076895760 IN A "
  226. + string(a_rdatas_rm[0]) + "\n"
  227. + "www.example.com. 1076895760 IN A "
  228. + string(a_rdatas_rm[1]));
  229. ConstRRsetPtr rrsig_rrsets_rm =
  230. textToRRset("www.example.com. 1076895760 IN RRSIG "
  231. + string(sig_rdatas_rm[0]) + "\n"
  232. + "www.example.com. 1076895760 IN RRSIG "
  233. + string(sig_rdatas_rm[1]));
  234. // A similar cycle as in the mergeCreate test.
  235. for (int i = 1; i < 4; ++i) {
  236. for (int j = 1; j < 4; ++j) {
  237. SCOPED_TRACE("creating subtract case " + lexical_cast<string>(i) +
  238. ", " + lexical_cast<string>(j));
  239. // Create old rdataset
  240. SegmentObjectHolder<RdataSet, RRClass> holder1(mem_sgmt_, rrclass);
  241. holder1.set(RdataSet::create(mem_sgmt_, encoder_,
  242. (i & 1) ? a_rrsets : null_rrset,
  243. (i & 2) ? rrsig_rrsets : null_rrset));
  244. // Create subtracted rdataset, from the old one and RRsets
  245. SegmentObjectHolder<RdataSet, RRClass> holder2(mem_sgmt_, rrclass);
  246. holder2.set(RdataSet::subtract(mem_sgmt_, encoder_,
  247. (j & 1) ? a_rrsets_rm : null_rrset,
  248. (j & 2) ? rrsig_rrsets_rm : null_rrset,
  249. *holder1.get()));
  250. // Set up the expected data for the case.
  251. vector<string> expected_rdata;
  252. if (i & 1) {
  253. if (!(j & 1)) { // Not removed the other
  254. expected_rdata.push_back(a_rdatas[0]);
  255. }
  256. expected_rdata.push_back(a_rdatas[1]);
  257. }
  258. vector<string> expected_sigs;
  259. if (i & 2) {
  260. if (!(j & 2)) { // Not removed the other
  261. expected_sigs.push_back(sig_rdatas[0]);
  262. }
  263. expected_sigs.push_back(sig_rdatas[1]);
  264. }
  265. // Then perform the check
  266. checkRdataSet(*holder2.get(), expected_rdata, expected_sigs);
  267. }
  268. }
  269. // Reusing the data we have, test some corner cases.
  270. SegmentObjectHolder<RdataSet, RRClass> holder_old(mem_sgmt_, rrclass);
  271. holder_old.set(RdataSet::create(mem_sgmt_, encoder_, a_rrsets,
  272. rrsig_rrsets));
  273. // It throws if no Rdata passed.
  274. EXPECT_THROW(RdataSet::subtract(mem_sgmt_, encoder_, null_rrset,
  275. null_rrset, *holder_old.get()),
  276. isc::BadValue);
  277. // If we remove everything, it returns NULL
  278. EXPECT_EQ(NULL, RdataSet::subtract(mem_sgmt_, encoder_, a_rrsets,
  279. rrsig_rrsets, *holder_old.get()));
  280. }
  281. TEST_F(RdataSetTest, duplicate) {
  282. // Create RRset and RRSIG containing duplicate RDATA.
  283. ConstRRsetPtr dup_rrset =
  284. textToRRset("www.example.com. 1076895760 IN A 192.0.2.1\n"
  285. "www.example.com. 1076895760 IN A 192.0.2.1\n");
  286. ConstRRsetPtr dup_rrsig =
  287. textToRRset("www.example.com. 1076895760 IN RRSIG " +
  288. def_rrsig_txt_[0] +
  289. "\nwww.example.com. 1076895760 IN RRSIG " +
  290. def_rrsig_txt_[0]);
  291. // After suppressing duplicates, it should be the same as the default
  292. // RdataSet. Check that.
  293. SegmentObjectHolder<RdataSet, RRClass> holder1(mem_sgmt_, rrclass);
  294. holder1.set(RdataSet::create(mem_sgmt_, encoder_, dup_rrset, dup_rrsig));
  295. checkRdataSet(*holder1.get(), def_rdata_txt_, def_rrsig_txt_);
  296. // Confirm the same thing for the merge mode.
  297. SegmentObjectHolder<RdataSet, RRClass> holder2(mem_sgmt_, rrclass);
  298. holder2.set(RdataSet::create(mem_sgmt_, encoder_, a_rrset_, rrsig_rrset_,
  299. holder1.get()));
  300. checkRdataSet(*holder2.get(), def_rdata_txt_, def_rrsig_txt_);
  301. }
  302. TEST_F(RdataSetTest, getNext) {
  303. RdataSet* rdataset = RdataSet::create(mem_sgmt_, encoder_, a_rrset_,
  304. ConstRRsetPtr());
  305. // By default, the next pointer should be NULL (already tested in other
  306. // test cases), which should be the case with getNext(). We test both
  307. // mutable and immutable versions of getNext().
  308. EXPECT_EQ(static_cast<RdataSet*>(NULL), rdataset->getNext());
  309. EXPECT_EQ(static_cast<const RdataSet*>(NULL),
  310. static_cast<const RdataSet*>(rdataset)->getNext());
  311. // making a link (it would form an infinite loop, but it doesn't matter
  312. // in this test), and check the pointer returned by getNext().
  313. rdataset->next = rdataset;
  314. EXPECT_EQ(rdataset, static_cast<const RdataSet*>(rdataset)->getNext());
  315. RdataSet::destroy(mem_sgmt_, rdataset, RRClass::IN());
  316. }
  317. TEST_F(RdataSetTest, find) {
  318. // Create some RdataSets and make a chain of them.
  319. SegmentObjectHolder<RdataSet, RRClass> holder1(mem_sgmt_, RRClass::IN());
  320. holder1.set(RdataSet::create(mem_sgmt_, encoder_, a_rrset_,
  321. ConstRRsetPtr()));
  322. ConstRRsetPtr aaaa_rrset =
  323. textToRRset("www.example.com. 1076895760 IN AAAA 2001:db8::1");
  324. SegmentObjectHolder<RdataSet, RRClass> holder2(mem_sgmt_, RRClass::IN());
  325. holder2.set(RdataSet::create(mem_sgmt_, encoder_, aaaa_rrset,
  326. ConstRRsetPtr()));
  327. ConstRRsetPtr sigonly_rrset =
  328. textToRRset("www.example.com. 1076895760 IN RRSIG "
  329. "TXT 5 2 3600 20120814220826 20120715220826 "
  330. "1234 example.com. FAKE");
  331. SegmentObjectHolder<RdataSet, RRClass> holder3(mem_sgmt_, RRClass::IN());
  332. holder3.set(RdataSet::create(mem_sgmt_, encoder_, ConstRRsetPtr(),
  333. sigonly_rrset));
  334. RdataSet* rdataset_a = holder1.get();
  335. RdataSet* rdataset_aaaa = holder2.get();
  336. RdataSet* rdataset_sigonly = holder3.get();
  337. RdataSet* rdataset_null = NULL;
  338. rdataset_a->next = rdataset_aaaa;
  339. rdataset_aaaa->next = rdataset_sigonly;
  340. // If a non-RRSIG part of rdataset exists for the given type, it will be
  341. // returned regardless of the value of sigonly_ok. If it's RRSIG-only
  342. // rdataset, it returns non NULL iff sigonly_ok is explicitly set to true.
  343. EXPECT_EQ(rdataset_aaaa, RdataSet::find(rdataset_a, RRType::AAAA()));
  344. EXPECT_EQ(rdataset_aaaa, RdataSet::find(rdataset_a, RRType::AAAA(), true));
  345. EXPECT_EQ(rdataset_aaaa, RdataSet::find(rdataset_a, RRType::AAAA(), false));
  346. EXPECT_EQ(rdataset_null, RdataSet::find(rdataset_a, RRType::TXT()));
  347. EXPECT_EQ(rdataset_sigonly, RdataSet::find(rdataset_a, RRType::TXT(),
  348. true));
  349. EXPECT_EQ(rdataset_null, RdataSet::find(rdataset_a, RRType::TXT(), false));
  350. // Same tests for the const version of find().
  351. const RdataSet* rdataset_a_const = holder1.get();
  352. EXPECT_EQ(rdataset_aaaa, RdataSet::find(rdataset_a_const, RRType::AAAA()));
  353. EXPECT_EQ(rdataset_aaaa, RdataSet::find(rdataset_a_const, RRType::AAAA(),
  354. true));
  355. EXPECT_EQ(rdataset_aaaa, RdataSet::find(rdataset_a_const, RRType::AAAA(),
  356. false));
  357. EXPECT_EQ(rdataset_null, RdataSet::find(rdataset_a_const, RRType::TXT()));
  358. EXPECT_EQ(rdataset_sigonly, RdataSet::find(rdataset_a_const, RRType::TXT(),
  359. true));
  360. EXPECT_EQ(rdataset_null, RdataSet::find(rdataset_a_const, RRType::TXT(),
  361. false));
  362. }
  363. // A helper function to create an RRset containing the given number of
  364. // unique RDATAs. We return non const pointer so that we can extend it.
  365. RRsetPtr
  366. getRRsetWithRdataCount(size_t rdata_count) {
  367. RRsetPtr rrset(new RRset(Name("example.com"), RRClass::IN(), RRType::TXT(),
  368. RRTTL(3600)));
  369. for (size_t i = 0; i < rdata_count; ++i) {
  370. rrset->addRdata(rdata::createRdata(RRType::TXT(), RRClass::IN(),
  371. lexical_cast<std::string>(i)));
  372. }
  373. return (rrset);
  374. }
  375. void
  376. RdataSetTest::checkCreateManyRRs(CreateFn create_fn, size_t n_old_rdata) {
  377. // RRset with possible maximum number of RDATAs, taking into account
  378. // "pre-existing" RDATAs
  379. RRsetPtr large_rrset = getRRsetWithRdataCount(8191 - n_old_rdata);
  380. RdataSet* rdataset = create_fn(mem_sgmt_, encoder_, large_rrset,
  381. ConstRRsetPtr());
  382. EXPECT_EQ(8191, rdataset->getRdataCount());
  383. EXPECT_EQ(0, rdataset->getSigRdataCount());
  384. RdataSet::destroy(mem_sgmt_, rdataset, rrclass);
  385. // Duplicate RDATA will be ignored in this check.
  386. large_rrset->addRdata(createRdata(RRType::TXT(), rrclass, "0"));
  387. rdataset = create_fn(mem_sgmt_, encoder_, large_rrset, ConstRRsetPtr());
  388. EXPECT_EQ(8191, rdataset->getRdataCount());
  389. RdataSet::destroy(mem_sgmt_, rdataset, rrclass);
  390. // Exceeding that will result in an exception.
  391. large_rrset->addRdata(createRdata(RRType::TXT(), rrclass, "8192"));
  392. EXPECT_THROW(create_fn(mem_sgmt_, encoder_, large_rrset, ConstRRsetPtr()),
  393. RdataSetError);
  394. // To be very sure even try larger number than the threshold
  395. EXPECT_THROW(create_fn(mem_sgmt_, encoder_,
  396. getRRsetWithRdataCount(65535 - n_old_rdata),
  397. ConstRRsetPtr()),
  398. RdataSetError);
  399. }
  400. TEST_F(RdataSetTest, createManyRRs) {
  401. checkCreateManyRRs(boost::bind(&RdataSet::create, _1, _2, _3, _4,
  402. static_cast<const RdataSet*>(NULL)), 0);
  403. }
  404. TEST_F(RdataSetTest, mergeCreateManyRRs) {
  405. ConstRRsetPtr rrset = textToRRset("example.com. 3600 IN TXT some-text");
  406. SegmentObjectHolder<RdataSet, RRClass> holder(mem_sgmt_, RRClass::IN());
  407. holder.set(RdataSet::create(mem_sgmt_, encoder_, rrset, ConstRRsetPtr()));
  408. checkCreateManyRRs(boost::bind(&RdataSet::create, _1, _2, _3, _4,
  409. holder.get()), rrset->getRdataCount());
  410. }
  411. TEST_F(RdataSetTest, createWithRRSIG) {
  412. RdataSet* rdataset = RdataSet::create(mem_sgmt_, encoder_, a_rrset_,
  413. rrsig_rrset_);
  414. checkRdataSet(*rdataset, def_rdata_txt_, def_rrsig_txt_);
  415. RdataSet::destroy(mem_sgmt_, rdataset, RRClass::IN());
  416. }
  417. // A helper function to create an RRSIG RRset containing the given number of
  418. // unique RDATAs.
  419. RRsetPtr
  420. getRRSIGWithRdataCount(size_t sig_count) {
  421. RRsetPtr rrset(new RRset(Name("example.com"), RRClass::IN(),
  422. RRType::RRSIG(), RRTTL(3600)));
  423. // We use a base wire-format image and tweak the original TTL field to
  424. // generate unique RDATAs in the loop. (Creating them from corresponding
  425. // text is simpler, but doing so for a large number of RRSIGs is
  426. // relatively heavy and could be too long for unittests).
  427. ConstRdataPtr rrsig_base =
  428. rdata::createRdata(RRType::RRSIG(), RRClass::IN(),
  429. "A 5 2 3600 20120814220826 20120715220826 1234 "
  430. "example.com. FAKE");
  431. isc::util::OutputBuffer ob(0);
  432. rrsig_base->toWire(ob);
  433. for (size_t i = 0; i < sig_count; ++i) {
  434. ob.writeUint16At((i >> 16) & 0xffff, 4);
  435. ob.writeUint16At(i & 0xffff, 6);
  436. isc::util::InputBuffer ib(ob.getData(), ob.getLength());
  437. rrset->addRdata(rdata::createRdata(RRType::RRSIG(), RRClass::IN(),
  438. ib, ib.getLength()));
  439. }
  440. return (rrset);
  441. }
  442. void
  443. RdataSetTest::checkCreateManyRRSIGs(CreateFn create_fn, size_t n_old_sig) {
  444. // 7 has a special meaning in the implementation: if the number of the
  445. // RRSIGs reaches this value, an extra 'sig count' field will be created.
  446. RdataSet* rdataset = create_fn(mem_sgmt_, encoder_, a_rrset_,
  447. getRRSIGWithRdataCount(7 - n_old_sig));
  448. EXPECT_EQ(7, rdataset->getSigRdataCount());
  449. RdataSet::destroy(mem_sgmt_, rdataset, RRClass::IN());
  450. // 8 would cause overflow in the normal 3-bit field if there were no extra
  451. // count field.
  452. rdataset = create_fn(mem_sgmt_, encoder_, a_rrset_,
  453. getRRSIGWithRdataCount(8 - n_old_sig));
  454. EXPECT_EQ(8, rdataset->getSigRdataCount());
  455. RdataSet::destroy(mem_sgmt_, rdataset, RRClass::IN());
  456. // Up to 2^16-1 RRSIGs are allowed (although that would be useless
  457. // in practice)
  458. RRsetPtr large_rrsig = getRRSIGWithRdataCount(65535 - n_old_sig);
  459. rdataset = create_fn(mem_sgmt_, encoder_, a_rrset_, large_rrsig);
  460. EXPECT_EQ(65535, rdataset->getSigRdataCount());
  461. RdataSet::destroy(mem_sgmt_, rdataset, RRClass::IN());
  462. // Duplicate shouldn't be counted
  463. large_rrsig->addRdata(
  464. createRdata(RRType::RRSIG(), rrclass,
  465. "A 5 2 0 20120814220826 20120715220826 1234 "
  466. "example.com. FAKE"));
  467. rdataset = create_fn(mem_sgmt_, encoder_, a_rrset_, large_rrsig);
  468. EXPECT_EQ(65535, rdataset->getSigRdataCount());
  469. RdataSet::destroy(mem_sgmt_, rdataset, RRClass::IN());
  470. // Exceeding this limit will result in an exception.
  471. large_rrsig->addRdata(
  472. createRdata(RRType::RRSIG(), rrclass,
  473. "A 5 2 65536 20120814220826 20120715220826 1234 "
  474. "example.com. FAKE"));
  475. EXPECT_THROW(create_fn(mem_sgmt_, encoder_, a_rrset_, large_rrsig),
  476. RdataSetError);
  477. // To be very sure even try larger number than the threshold
  478. EXPECT_THROW(create_fn(mem_sgmt_, encoder_, a_rrset_,
  479. getRRSIGWithRdataCount(70000 - n_old_sig)),
  480. RdataSetError);
  481. }
  482. TEST_F(RdataSetTest, createManyRRSIGs) {
  483. checkCreateManyRRSIGs(boost::bind(&RdataSet::create, _1, _2, _3, _4,
  484. static_cast<const RdataSet*>(NULL)), 0);
  485. }
  486. TEST_F(RdataSetTest, mergeCreateManyRRSIGs) {
  487. // Create "old" RRSIG that shouldn't be a duplicate of ones created in
  488. // checkCreateManyRRSIGs (signature is different).
  489. ConstRRsetPtr rrsig = textToRRset(
  490. "example.com. 3600 IN RRSIG A 5 2 3600 20120814220826 20120715220826 "
  491. "1234 example.com. FAKEFAKE");
  492. SegmentObjectHolder<RdataSet, RRClass> holder(mem_sgmt_, rrclass);
  493. holder.set(RdataSet::create(mem_sgmt_, encoder_, ConstRRsetPtr(), rrsig));
  494. checkCreateManyRRSIGs(boost::bind(&RdataSet::create, _1, _2, _3, _4,
  495. holder.get()), rrsig->getRdataCount());
  496. }
  497. TEST_F(RdataSetTest, createWithRRSIGOnly) {
  498. // A rare, but allowed, case: RdataSet without the main RRset but with
  499. // RRSIG.
  500. RdataSet* rdataset = RdataSet::create(mem_sgmt_, encoder_, ConstRRsetPtr(),
  501. rrsig_rrset_);
  502. checkRdataSet(*rdataset, vector<string>(), def_rrsig_txt_);
  503. RdataSet::destroy(mem_sgmt_, rdataset, RRClass::IN());
  504. }
  505. // Checking initial validation for both versions of create().
  506. void
  507. RdataSetTest::checkBadCreate(CreateFn create_fn) {
  508. // Neither the RRset nor RRSIG RRset is given
  509. EXPECT_THROW(create_fn(mem_sgmt_, encoder_, ConstRRsetPtr(),
  510. ConstRRsetPtr()), isc::BadValue);
  511. // Empty RRset (An RRset without RDATA)
  512. ConstRRsetPtr empty_rrset(new RRset(Name("example.com"), RRClass::IN(),
  513. RRType::A(), RRTTL(3600)));
  514. EXPECT_THROW(create_fn(mem_sgmt_, encoder_, empty_rrset,
  515. ConstRRsetPtr()), isc::BadValue);
  516. ConstRRsetPtr empty_rrsig(new RRset(Name("example.com"), RRClass::IN(),
  517. RRType::RRSIG(), RRTTL(3600)));
  518. EXPECT_THROW(create_fn(mem_sgmt_, encoder_, ConstRRsetPtr(),
  519. empty_rrsig), isc::BadValue);
  520. // The RRset type and RRSIG's type covered don't match
  521. ConstRRsetPtr bad_rrsig(textToRRset(
  522. "www.example.com. 1076895760 IN RRSIG "
  523. "NS 5 2 3600 20120814220826 20120715220826 "
  524. "1234 example.com. FAKE"));
  525. EXPECT_THROW(create_fn(mem_sgmt_, encoder_, a_rrset_, bad_rrsig),
  526. isc::BadValue);
  527. // Pass non RRSIG for the sig parameter
  528. EXPECT_THROW(create_fn(mem_sgmt_, encoder_, a_rrset_, a_rrset_),
  529. isc::BadValue);
  530. // Pass RRSIG for normal RRset (the RdataEncoder will catch this and throw)
  531. EXPECT_THROW(create_fn(mem_sgmt_, encoder_, rrsig_rrset_, rrsig_rrset_),
  532. isc::BadValue);
  533. // RR class doesn't match between RRset and RRSIG
  534. ConstRRsetPtr badclass_rrsig(textToRRset(
  535. "www.example.com. 1076895760 CH RRSIG "
  536. "A 5 2 3600 20120814220826 "
  537. "20120715220826 1234 example.com. FAKE",
  538. RRClass::CH()));
  539. EXPECT_THROW(create_fn(mem_sgmt_, encoder_, a_rrset_, badclass_rrsig),
  540. isc::BadValue);
  541. }
  542. TEST_F(RdataSetTest, badCreate) {
  543. checkBadCreate(boost::bind(&RdataSet::create, _1, _2, _3, _4,
  544. static_cast<const RdataSet*>(NULL)));
  545. }
  546. TEST_F(RdataSetTest, badMergeCreate) {
  547. // The 'old RdataSet' for merge. Its content doesn't matter much; the test
  548. // should trigger exception before examining it except for the last checks.
  549. SegmentObjectHolder<RdataSet, RRClass> holder(mem_sgmt_, RRClass::IN());
  550. holder.set(RdataSet::create(mem_sgmt_, encoder_,
  551. textToRRset("www.example.com. 0 IN AAAA 2001:db8::1"),
  552. ConstRRsetPtr()));
  553. checkBadCreate(boost::bind(&RdataSet::create, _1, _2, _3, _4,
  554. holder.get()));
  555. // Type mismatch: this case is specific to the merge create.
  556. EXPECT_THROW(RdataSet::create(mem_sgmt_, encoder_, a_rrset_,
  557. ConstRRsetPtr(), holder.get()),
  558. isc::BadValue);
  559. EXPECT_THROW(RdataSet::create(mem_sgmt_, encoder_, ConstRRsetPtr(),
  560. rrsig_rrset_, holder.get()),
  561. isc::BadValue);
  562. }
  563. TEST_F(RdataSetTest, varyingTTL) {
  564. // Creating RdataSets with different TTLs. The lowest one should win.
  565. ConstRRsetPtr aaaa_smaller = textToRRset("example. 5 IN AAAA 2001:db8::");
  566. ConstRRsetPtr aaaa_small = textToRRset("example. 10 IN AAAA 2001:db8::1");
  567. ConstRRsetPtr aaaa_large = textToRRset("example. 20 IN AAAA 2001:db8::2");
  568. ConstRRsetPtr sig_smaller =
  569. textToRRset("www.example.com. 5 IN RRSIG AAAA 5 2 3600 "
  570. "20120814220826 20120715220826 1111 example.com. FAKE");
  571. ConstRRsetPtr sig_small =
  572. textToRRset("www.example.com. 10 IN RRSIG AAAA 5 2 3600 "
  573. "20120814220826 20120715220826 1234 example.com. FAKE");
  574. ConstRRsetPtr sig_large =
  575. textToRRset("www.example.com. 20 IN RRSIG AAAA 5 2 3600 "
  576. "20120814220826 20120715220826 4321 example.com. FAKE");
  577. // RRSIG's TTL is larger
  578. RdataSet* rdataset = RdataSet::create(mem_sgmt_, encoder_, aaaa_small,
  579. sig_large);
  580. EXPECT_EQ(RRTTL(10), restoreTTL(rdataset->getTTLData()));
  581. RdataSet::destroy(mem_sgmt_, rdataset, rrclass);
  582. // RRSIG's TTL is smaller
  583. SegmentObjectHolder<RdataSet, RRClass> holder1(mem_sgmt_, rrclass);
  584. holder1.set(RdataSet::create(mem_sgmt_, encoder_, aaaa_large, sig_small));
  585. EXPECT_EQ(RRTTL(10), restoreTTL(holder1.get()->getTTLData()));
  586. // Merging another RRset (w/o sig) that has larger TTL
  587. rdataset = RdataSet::create(mem_sgmt_, encoder_, aaaa_large,
  588. ConstRRsetPtr(), holder1.get());
  589. EXPECT_EQ(RRTTL(10), restoreTTL(rdataset->getTTLData()));
  590. RdataSet::destroy(mem_sgmt_, rdataset, rrclass);
  591. // Merging another RRset (w/o sig) that has smaller TTL
  592. rdataset = RdataSet::create(mem_sgmt_, encoder_, aaaa_smaller,
  593. ConstRRsetPtr(), holder1.get());
  594. EXPECT_EQ(RRTTL(5), restoreTTL(rdataset->getTTLData()));
  595. RdataSet::destroy(mem_sgmt_, rdataset, rrclass);
  596. // Merging another RRSIG (w/o RRset) that has larger TTL
  597. rdataset = RdataSet::create(mem_sgmt_, encoder_, ConstRRsetPtr(),
  598. sig_large, holder1.get());
  599. EXPECT_EQ(RRTTL(10), restoreTTL(rdataset->getTTLData()));
  600. RdataSet::destroy(mem_sgmt_, rdataset, rrclass);
  601. // Merging another RRSIG (w/o RRset) that has smaller TTL
  602. rdataset = RdataSet::create(mem_sgmt_, encoder_, ConstRRsetPtr(),
  603. sig_smaller, holder1.get());
  604. EXPECT_EQ(RRTTL(5), restoreTTL(rdataset->getTTLData()));
  605. RdataSet::destroy(mem_sgmt_, rdataset, rrclass);
  606. // Merging another RRset and RRSIG that have larger TTL
  607. rdataset = RdataSet::create(mem_sgmt_, encoder_, aaaa_large, sig_large,
  608. holder1.get());
  609. EXPECT_EQ(RRTTL(10), restoreTTL(rdataset->getTTLData()));
  610. RdataSet::destroy(mem_sgmt_, rdataset, rrclass);
  611. // Merging another RRset and RRSIG that have smaller TTL
  612. rdataset = RdataSet::create(mem_sgmt_, encoder_, aaaa_smaller, sig_smaller,
  613. holder1.get());
  614. EXPECT_EQ(RRTTL(5), restoreTTL(rdataset->getTTLData()));
  615. RdataSet::destroy(mem_sgmt_, rdataset, rrclass);
  616. }
  617. // Creation of rdataset with bad params, with create and subtract
  618. TEST_F(RdataSetTest, badParams) {
  619. const ConstRRsetPtr empty_rrset(new RRset(Name("www.example.com"),
  620. RRClass::IN(), RRType::A(),
  621. RRTTL(3600)));
  622. const ConstRRsetPtr a_rrset = textToRRset("www.example.com. 3600 IN A "
  623. "192.0.2.1");
  624. const ConstRRsetPtr aaaa_rrset = textToRRset("www.example.com. 3600 IN AAAA "
  625. "2001:db8::1");
  626. const ConstRRsetPtr sig_rrset = textToRRset("www.example.com. 3600 IN RRSIG "
  627. "A 5 2 3600 20120814220826 "
  628. "20120715220826 1234 "
  629. "example.com. FAKE");
  630. const ConstRRsetPtr sig_rrset_ch = textToRRset("www.example.com. 3600 CH RRSIG "
  631. "A 5 2 3600 20120814220826 "
  632. "20120715220826 1234 "
  633. "example.com. FAKE",
  634. RRClass::CH());
  635. SegmentObjectHolder<RdataSet, RRClass> holder(mem_sgmt_, rrclass);
  636. holder.set(RdataSet::create(mem_sgmt_, encoder_, a_rrset, sig_rrset));
  637. // Empty RRset as rdata
  638. EXPECT_THROW(RdataSet::create(mem_sgmt_, encoder_, empty_rrset, sig_rrset),
  639. isc::BadValue);
  640. // The same for rrsig
  641. EXPECT_THROW(RdataSet::create(mem_sgmt_, encoder_, a_rrset, empty_rrset),
  642. isc::BadValue);
  643. // Similar for subtract
  644. EXPECT_THROW(RdataSet::subtract(mem_sgmt_, encoder_, empty_rrset,
  645. sig_rrset, *holder.get()),
  646. isc::BadValue);
  647. EXPECT_THROW(RdataSet::subtract(mem_sgmt_, encoder_, a_rrset, empty_rrset,
  648. *holder.get()),
  649. isc::BadValue);
  650. // Class mismatch
  651. EXPECT_THROW(RdataSet::create(mem_sgmt_, encoder_, a_rrset, sig_rrset_ch),
  652. isc::BadValue);
  653. EXPECT_THROW(RdataSet::subtract(mem_sgmt_, encoder_, a_rrset,
  654. sig_rrset_ch, *holder.get()),
  655. isc::BadValue);
  656. // Bad rrtype
  657. EXPECT_THROW(RdataSet::create(mem_sgmt_, encoder_, aaaa_rrset,
  658. ConstRRsetPtr(), holder.get()),
  659. isc::BadValue);
  660. EXPECT_THROW(RdataSet::subtract(mem_sgmt_, encoder_, aaaa_rrset,
  661. ConstRRsetPtr(), *holder.get()),
  662. isc::BadValue);
  663. }
  664. }