From: JINMEI Tatuya Date: Sat, 16 Feb 2013 04:03:10 +0000 (-0800) Subject: [2440] handle varying TTL cases. X-Git-Tag: bind10-1.1.0beta1-release~70^2~5 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=231effe63004f65df8997eb6505c6df9259a30c5;p=thirdparty%2Fkea.git [2440] handle varying TTL cases. the behavior was changed slightly: on second thought it seemed to make more sense to adopt the smallest TTL. An existing test case was removed because it's now covered in more comprehensive tests for this change. --- diff --git a/src/lib/datasrc/memory/rdataset.cc b/src/lib/datasrc/memory/rdataset.cc index 5bcc2125bf..2d77da3823 100644 --- a/src/lib/datasrc/memory/rdataset.cc +++ b/src/lib/datasrc/memory/rdataset.cc @@ -26,6 +26,7 @@ #include #include +#include #include #include // for bad_cast #include // for the placement new @@ -48,6 +49,33 @@ getCoveredType(const Rdata& rdata) { isc_throw(BadValue, "Non RRSIG is given where it's expected"); } } + +// A helper for smallestTTL: restore RRTTL object from wire-format 32-bit data. +RRTTL +restoreTTL(const void* ttl_data) { + isc::util::InputBuffer b(ttl_data, sizeof(uint32_t)); + return (RRTTL(b)); +} + +// A helper function for create(): return the TTL that has smallest value +// amount the given those of given rdataset (if non NULL), rrset, sig_rrset. +RRTTL +smallestTTL(const RdataSet* rdataset, ConstRRsetPtr& rrset, + ConstRRsetPtr& sig_rrset) +{ + if (rrset && sig_rrset) { + const RRTTL tmp(std::min(rrset->getTTL(), sig_rrset->getTTL())); + return (rdataset ? + std::min(restoreTTL(rdataset->getTTLData()), tmp) : tmp); + } else if (rrset) { + return (rdataset ? std::min(restoreTTL(rdataset->getTTLData()), + rrset->getTTL()) : rrset->getTTL()); + } else { + return (rdataset ? std::min(restoreTTL(rdataset->getTTLData()), + sig_rrset->getTTL()) : + sig_rrset->getTTL()); + } +} } RdataSet* @@ -55,7 +83,6 @@ RdataSet::create(util::MemorySegment& mem_sgmt, RdataEncoder& encoder, ConstRRsetPtr rrset, ConstRRsetPtr sig_rrset, const RdataSet* old_rdataset) { - // TODO: taking min TTL // Check basic validity if (!rrset && !sig_rrset) { isc_throw(BadValue, "Both RRset and RRSIG are NULL"); @@ -76,7 +103,7 @@ RdataSet::create(util::MemorySegment& mem_sgmt, RdataEncoder& encoder, if (old_rdataset && old_rdataset->type != rrtype) { isc_throw(BadValue, "RR type doesn't match for merging RdataSet"); } - const RRTTL rrttl = rrset ? rrset->getTTL() : sig_rrset->getTTL(); + const RRTTL rrttl = smallestTTL(old_rdataset, rrset, sig_rrset); if (old_rdataset) { encoder.start(rrclass, rrtype, old_rdataset->getDataBuf(), old_rdataset->getRdataCount(), diff --git a/src/lib/datasrc/tests/memory/rdataset_unittest.cc b/src/lib/datasrc/tests/memory/rdataset_unittest.cc index 17e03a44fc..db42050e80 100644 --- a/src/lib/datasrc/tests/memory/rdataset_unittest.cc +++ b/src/lib/datasrc/tests/memory/rdataset_unittest.cc @@ -386,21 +386,10 @@ TEST_F(RdataSetTest, mergeCreateManyRRs) { } TEST_F(RdataSetTest, createWithRRSIG) { - // Normal case. RdataSet* rdataset = RdataSet::create(mem_sgmt_, encoder_, a_rrset_, rrsig_rrset_); checkRdataSet(*rdataset, def_rdata_txt_, def_rrsig_txt_); RdataSet::destroy(mem_sgmt_, rdataset, RRClass::IN()); - - // Unusual case: TTL doesn't match. This implementation accepts that, - // using the TTL of the covered RRset. - ConstRRsetPtr rrsig_badttl(textToRRset( - "www.example.com. 3600 IN RRSIG " - "A 5 2 3600 20120814220826 " - "20120715220826 1234 example.com. FAKE")); - rdataset = RdataSet::create(mem_sgmt_, encoder_, a_rrset_, rrsig_badttl); - checkRdataSet(*rdataset, def_rdata_txt_, def_rrsig_txt_); - RdataSet::destroy(mem_sgmt_, rdataset, RRClass::IN()); } // A helper function to create an RRSIG RRset containing the given number of @@ -572,4 +561,69 @@ TEST_F(RdataSetTest, badMergeCreate) { rrsig_rrset_, holder.get()), isc::BadValue); } + +TEST_F(RdataSetTest, varyingTTL) { + // Creating RdataSets with different TTLs. The smallest one should win. + + ConstRRsetPtr aaaa_smaller = textToRRset("example. 5 IN AAAA 2001:db8::"); + ConstRRsetPtr aaaa_small = textToRRset("example. 10 IN AAAA 2001:db8::1"); + ConstRRsetPtr aaaa_large = textToRRset("example. 20 IN AAAA 2001:db8::2"); + ConstRRsetPtr sig_smaller = + textToRRset("www.example.com. 5 IN RRSIG AAAA 5 2 3600 " + "20120814220826 20120715220826 1111 example.com. FAKE"); + ConstRRsetPtr sig_small = + textToRRset("www.example.com. 10 IN RRSIG AAAA 5 2 3600 " + "20120814220826 20120715220826 1234 example.com. FAKE"); + ConstRRsetPtr sig_large = + textToRRset("www.example.com. 20 IN RRSIG AAAA 5 2 3600 " + "20120814220826 20120715220826 4321 example.com. FAKE"); + + // RRSIG's TTL is larger + RdataSet* rdataset = RdataSet::create(mem_sgmt_, encoder_, aaaa_small, + sig_large); + EXPECT_EQ(RRTTL(10), restoreTTL(rdataset->getTTLData())); + RdataSet::destroy(mem_sgmt_, rdataset, rrclass); + + // RRSIG's TTL is smaller + SegmentObjectHolder holder1( + mem_sgmt_, + RdataSet::create(mem_sgmt_, encoder_, aaaa_large, sig_small), rrclass); + EXPECT_EQ(RRTTL(10), restoreTTL(holder1.get()->getTTLData())); + + // Merging another RRset (w/o sig) that has larger TTL + rdataset = RdataSet::create(mem_sgmt_, encoder_, aaaa_large, + ConstRRsetPtr(), holder1.get()); + EXPECT_EQ(RRTTL(10), restoreTTL(rdataset->getTTLData())); + RdataSet::destroy(mem_sgmt_, rdataset, rrclass); + + // Merging another RRset (w/o sig) that has smaller TTL + rdataset = RdataSet::create(mem_sgmt_, encoder_, aaaa_smaller, + ConstRRsetPtr(), holder1.get()); + EXPECT_EQ(RRTTL(5), restoreTTL(rdataset->getTTLData())); + RdataSet::destroy(mem_sgmt_, rdataset, rrclass); + + // Merging another RRSIG (w/o RRset) that has larger TTL + rdataset = RdataSet::create(mem_sgmt_, encoder_, ConstRRsetPtr(), + sig_large, holder1.get()); + EXPECT_EQ(RRTTL(10), restoreTTL(rdataset->getTTLData())); + RdataSet::destroy(mem_sgmt_, rdataset, rrclass); + + // Merging another RRSIG (w/o RRset) that has smaller TTL + rdataset = RdataSet::create(mem_sgmt_, encoder_, ConstRRsetPtr(), + sig_smaller, holder1.get()); + EXPECT_EQ(RRTTL(5), restoreTTL(rdataset->getTTLData())); + RdataSet::destroy(mem_sgmt_, rdataset, rrclass); + + // Merging another RRset and RRSIG that have larger TTL + rdataset = RdataSet::create(mem_sgmt_, encoder_, aaaa_large, sig_large, + holder1.get()); + EXPECT_EQ(RRTTL(10), restoreTTL(rdataset->getTTLData())); + RdataSet::destroy(mem_sgmt_, rdataset, rrclass); + + // Merging another RRset and RRSIG that have smaller TTL + rdataset = RdataSet::create(mem_sgmt_, encoder_, aaaa_smaller, sig_smaller, + holder1.get()); + EXPECT_EQ(RRTTL(5), restoreTTL(rdataset->getTTLData())); + RdataSet::destroy(mem_sgmt_, rdataset, rrclass); +} }