From: JINMEI Tatuya Date: Fri, 25 Jan 2013 02:45:37 +0000 (-0800) Subject: [2310] extend findAtOrigin so it can handle use_minttl correctly. X-Git-Tag: bind10-1.0.0-rc-release~25^2~10^2~4 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4760fba1fcc4d0fdb762b69cd6090002b9190be1;p=thirdparty%2Fkea.git [2310] extend findAtOrigin so it can handle use_minttl correctly. --- diff --git a/src/lib/datasrc/memory/zone_finder.cc b/src/lib/datasrc/memory/zone_finder.cc index fe4e3e1ace..ea8f9d1d9b 100644 --- a/src/lib/datasrc/memory/zone_finder.cc +++ b/src/lib/datasrc/memory/zone_finder.cc @@ -23,10 +23,13 @@ #include #include #include +#include #include #include +#include + #include #include @@ -104,14 +107,19 @@ createTreeNodeRRset(const ZoneNode* node, const RdataSet* rdataset, const RRClass& rrclass, ZoneFinder::FindOptions options, - const Name* realname = NULL) + const Name* realname = NULL, + const void* ttl_data = NULL) { const bool dnssec = ((options & ZoneFinder::FIND_DNSSEC) != 0); - if (node != NULL && rdataset != NULL) { - if (realname != NULL) { + if (node && rdataset) { + if (realname) { return (TreeNodeRRsetPtr(new TreeNodeRRset(*realname, rrclass, node, rdataset, dnssec))); + } else if (ttl_data) { + assert(!realname); // these two cases should be mixed in our use + return (TreeNodeRRsetPtr(new TreeNodeRRset(rrclass, node, rdataset, + dnssec, ttl_data))); } else { return (TreeNodeRRsetPtr(new TreeNodeRRset(rrclass, node, rdataset, dnssec))); @@ -229,6 +237,12 @@ createNSEC3RRset(const ZoneNode* node, const RRClass& rrclass) { ZoneFinder::FIND_DNSSEC)); } +inline RRTTL +createTTLFromData(const void* ttl_data) { + util::InputBuffer b(ttl_data, sizeof(uint32_t)); + return (RRTTL(b)); +} + // convenience function to fill in the final details // // Set up ZoneFinderResultContext object as a return value of find(), @@ -250,7 +264,8 @@ createFindResult(const RRClass& rrclass, const RdataSet* rdataset, ZoneFinder::FindOptions options, bool wild = false, - const Name* qname = NULL) + const Name* qname = NULL, + bool use_minttl = false) { ZoneFinder::FindResultFlags flags = ZoneFinder::RESULT_DEFAULT; const Name* rename = NULL; @@ -268,6 +283,15 @@ createFindResult(const RRClass& rrclass, } } + if (use_minttl && rdataset && + createTTLFromData(zone_data.getMinTTLData()) < + createTTLFromData(rdataset->getTTLData())) { + return (ZoneFinderResultContext( + code, + createTreeNodeRRset(node, rdataset, rrclass, options, + rename, zone_data.getMinTTLData()), + flags, zone_data, node, rdataset)); + } return (ZoneFinderResultContext(code, createTreeNodeRRset(node, rdataset, rrclass, options, rename), @@ -743,7 +767,7 @@ InMemoryZoneFinder::findAll(const isc::dns::Name& name, boost::shared_ptr InMemoryZoneFinder::findAtOrigin(const isc::dns::RRType& type, - bool /*use_minttl*/, // not yet supported + bool use_minttl, const FindOptions options) { const ZoneNode* const node = zone_data_.getOriginNode(); @@ -755,7 +779,8 @@ InMemoryZoneFinder::findAtOrigin(const isc::dns::RRType& type, return (ZoneFinderContextPtr( new Context(*this, options, rrclass_, createFindResult(rrclass_, zone_data_, SUCCESS, - node, found, options)))); + node, found, options, false, + NULL, use_minttl)))); } return (ZoneFinderContextPtr( new Context(*this, options, rrclass_, @@ -764,7 +789,8 @@ InMemoryZoneFinder::findAtOrigin(const isc::dns::RRType& type, getNSECForNXRRSET(zone_data_, options, node), - options)))); + options, false, NULL, + use_minttl)))); } ZoneFinderResultContext diff --git a/src/lib/datasrc/memory/zone_finder.h b/src/lib/datasrc/memory/zone_finder.h index b36d7c0703..cd2bd58840 100644 --- a/src/lib/datasrc/memory/zone_finder.h +++ b/src/lib/datasrc/memory/zone_finder.h @@ -62,6 +62,10 @@ public: /// \brief Search for an RRset of given RR type at the zone origin /// specialized for in-memory data source. + /// + /// This specialized version exploits internal data structure to find + /// RRsets at the zone origin and (if \c use_minttl is true) extract + /// the SOA Minimum TTL much more efficiently. virtual boost::shared_ptr findAtOrigin( const isc::dns::RRType& type, bool use_minttl, FindOptions options); diff --git a/src/lib/datasrc/tests/memory/zone_finder_unittest.cc b/src/lib/datasrc/tests/memory/zone_finder_unittest.cc index 4e1b90a6fb..abfbe1d007 100644 --- a/src/lib/datasrc/tests/memory/zone_finder_unittest.cc +++ b/src/lib/datasrc/tests/memory/zone_finder_unittest.cc @@ -63,7 +63,11 @@ using result::EXIST; /// be a concern here. ConstRRsetPtr convertRRset(ConstRRsetPtr src) { - return (textToRRset(src->toText())); + // If the type is SOA, textToRRset performs a stricter check, so we should + // specify the origin. + const Name& origin = (src->getType() == RRType::SOA()) ? + src->getName() : Name::ROOT_NAME(); + return (textToRRset(src->toText(), src->getClass(), origin)); } /// \brief Test fixture for the InMemoryZoneFinder class @@ -322,7 +326,7 @@ protected: memory::InMemoryZoneFinder* zone_finder = NULL, ZoneFinder::FindOptions options = ZoneFinder::FIND_DEFAULT, - bool check_wild_answer = false) + bool use_minttl = false) { SCOPED_TRACE("findAtOriginTest for " + rrtype.toText()); @@ -330,9 +334,9 @@ protected: zone_finder = &zone_finder_; } ZoneFinderContextPtr find_result(zone_finder->findAtOrigin( - rrtype, false, options)); + rrtype, use_minttl, options)); findTestCommon(origin_, result, find_result, check_answer, answer, - expected_flags, options, check_wild_answer); + expected_flags, options, false); } private: @@ -627,7 +631,6 @@ TEST_F(InMemoryZoneFinderTest, glue) { findTest(rr_child_glue_->getName(), RRType::A(), ZoneFinder::DELEGATION, true, rr_child_ns_); - // If we do it in the "glue OK" mode, we should find the exact match. findTest(rr_child_glue_->getName(), RRType::A(), ZoneFinder::SUCCESS, true, rr_child_glue_, ZoneFinder::RESULT_DEFAULT, NULL, @@ -701,6 +704,55 @@ TEST_F(InMemoryZoneFinderTest, findAtOrigin) { ZoneFinder::FIND_DNSSEC); } +TEST_F(InMemoryZoneFinderTest, findAtOriginWithMinTTL) { + // Install zone's SOA. This also sets internal zone data min TTL field. + addToZoneData(rr_soa_); + + // Specify the use of min TTL, then the resulting TTL should be derived + // from the SOA MINTTL (which is smaller). + findAtOriginTest(RRType::SOA(), ZoneFinder::SUCCESS, true, + textToRRset("example.org. 100 IN SOA . . 0 0 0 0 100", + class_, origin_), + ZoneFinder::RESULT_DEFAULT, NULL, + ZoneFinder::FIND_DEFAULT, true); + + // Add signed NS for the following test. + RRsetPtr ns_rrset(textToRRset("example.org. 300 IN NS ns.example.org.")); + ns_rrset->addRRsig(createRdata(RRType::RRSIG(), RRClass::IN(), + "NS 5 3 3600 20120814220826 20120715220826 " + "1234 example.org. FAKE")); + addToZoneData(ns_rrset); + + // If DNSSEC is requested, TTL of the RRSIG should also be the min. + ns_rrset->setTTL(RRTTL(100)); // reset TTL to the expected one + findAtOriginTest(RRType::NS(), ZoneFinder::SUCCESS, true, ns_rrset, + ZoneFinder::RESULT_DEFAULT, NULL, + ZoneFinder::FIND_DEFAULT, true); + + // If we don't request the use of min TTL, the original TTL will be used. + findAtOriginTest(RRType::SOA(), ZoneFinder::SUCCESS, true, rr_soa_, + ZoneFinder::RESULT_DEFAULT, NULL, + ZoneFinder::FIND_DEFAULT, false); + + // If no RRset is returned, use_minttl doesn't matter (it shouldn't cause + // disruption) + findAtOriginTest(RRType::TXT(), ZoneFinder::NXRRSET, true, ConstRRsetPtr(), + ZoneFinder::RESULT_DEFAULT, NULL, + ZoneFinder::FIND_DEFAULT, true); + + // If it results in NXRRSET with NSEC, and if we specify the use of min + // TTL, the NSEC and RRSIG should have the min TTL (again, though, this + // use case is not really the intended one) + rr_nsec_->addRRsig(createRdata(RRType::RRSIG(), RRClass::IN(), + "NSEC 5 3 3600 20120814220826 " + "20120715220826 1234 example.org. FAKE")); + addToZoneData(rr_nsec_); + rr_nsec_->setTTL(RRTTL(100)); // reset it to the expected one + findAtOriginTest(RRType::TXT(), ZoneFinder::NXRRSET, true, rr_nsec_, + ZoneFinder::RESULT_NSEC_SIGNED, NULL, + ZoneFinder::FIND_DNSSEC, true); +} + /** * \brief Test searching. *