From: JINMEI Tatuya Date: Tue, 2 Oct 2012 21:15:14 +0000 (-0700) Subject: [2060] added the getAtOrigin() method to ZoneFinder::Context. X-Git-Tag: trac2351_base~9^2^2~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d73842ed35d5aea29466e25a9a6b2dfb4e550e97;p=thirdparty%2Fkea.git [2060] added the getAtOrigin() method to ZoneFinder::Context. defining the common interface and the default implementation. --- diff --git a/src/lib/datasrc/tests/testdata/contexttest.zone b/src/lib/datasrc/tests/testdata/contexttest.zone index a39649d376..0c1393cd56 100644 --- a/src/lib/datasrc/tests/testdata/contexttest.zone +++ b/src/lib/datasrc/tests/testdata/contexttest.zone @@ -1,9 +1,10 @@ ;; test zone file used for ZoneFinderContext tests. ;; RRSIGs are (obviouslly) faked ones for testing. -example.org. 3600 IN SOA ns1.example.org. bugs.x.w.example.org. 71 3600 300 3600000 3600 +example.org. 3600 IN SOA ns1.example.org. bugs.x.w.example.org. 74 3600 300 3600000 3600 example.org. 3600 IN NS ns1.example.org. example.org. 3600 IN NS ns2.example.org. +example.org. 3600 IN RRSIG NS 7 3 3600 20150420235959 20051021000000 40430 example.org. FAKEFAKEFAKE example.org. 3600 IN MX 1 mx1.example.org. example.org. 3600 IN MX 2 mx2.example.org. example.org. 3600 IN MX 3 mx.a.example.org. diff --git a/src/lib/datasrc/tests/zone_finder_context_unittest.cc b/src/lib/datasrc/tests/zone_finder_context_unittest.cc index 14429aea51..564de94cea 100644 --- a/src/lib/datasrc/tests/zone_finder_context_unittest.cc +++ b/src/lib/datasrc/tests/zone_finder_context_unittest.cc @@ -416,4 +416,37 @@ TEST_P(ZoneFinderContextTest, getAdditionalForAny) { result_sets_.begin(), result_sets_.end()); } +TEST_P(ZoneFinderContextTest, getAtOrigin) { + ConstRRsetPtr expected_ns_rrset = + textToRRset("example.org. 3600 IN NS ns1.example.org.\n" + "example.org. 3600 IN NS ns2.example.org.\n"); + + // Try getAtOrigin for an existing type (NS) record at the origin that + // has RRSIG. The RRSIG will be associated iff the original query + // has the FIND_DNSSEC option. + ZoneFinderContextPtr ctx = finder_->find(Name("ns1.example.org"), + RRType::A()); + EXPECT_EQ(ZoneFinder::SUCCESS, ctx->code); + ConstRRsetPtr ns_rrset = ctx->getAtOrigin(RRType::NS()); + ASSERT_TRUE(ns_rrset); + rrsetCheck(expected_ns_rrset, ns_rrset); + EXPECT_FALSE(ns_rrset->getRRsig()); + + ctx = finder_->find(Name("ns1.example.org"), RRType::A(), + ZoneFinder::FIND_DNSSEC); + ns_rrset = ctx->getAtOrigin(RRType::NS()); + ASSERT_TRUE(ns_rrset); + rrsetCheck(expected_ns_rrset, ns_rrset); + ASSERT_TRUE(ns_rrset->getRRsig()); + rrsetCheck(textToRRset("example.org. 3600 IN RRSIG NS 7 3 3600 " + "20150420235959 20051021000000 40430 " + "example.org. FAKEFAKEFAKE"), ns_rrset->getRRsig()); + + // For non-existing type we simply get NULL. + EXPECT_FALSE(ctx->getAtOrigin(RRType::TXT())); + + // Type ANY query isn't allowed. + EXPECT_THROW(ctx->getAtOrigin(RRType::ANY()), isc::InvalidParameter); +} + } diff --git a/src/lib/datasrc/zone.h b/src/lib/datasrc/zone.h index 2330412290..844c6e1b97 100644 --- a/src/lib/datasrc/zone.h +++ b/src/lib/datasrc/zone.h @@ -291,6 +291,67 @@ public: getAdditionalImpl(requested_types, result); } + /// \brief Find and return given type of RRset at the zone origin. + /// + /// DNS query processing often requires supplemental RRsets at the + /// zone origin; for example, for some negative answers we need to + /// provide the zone's SOA record; a full positive response normally + /// includes the zone's NS RRset. The application can easily get + /// these using the generic \c ZoneFinder::find() interface, but + /// depending on the underlying data source implementation, the generic + /// version could be more expensive and/or it might be possible to + /// substantially improve this particular case. + /// + /// This method allows the underlying implementation to do such + /// optimization. The interface is simplified; it just takes + /// an `RRType` and returns the corresponding RRset if found; + /// if not found it returns NULL. + /// + /// This method tries to find and return RRSIGs of the found RRset + /// if and only if the original lookup by \c ZoneFinder::find() has + /// the \c FIND_DNSSEC option. + /// + /// Type ANY must not be specified for this method. It will result + /// in \c isc::InvalidParameter exception. If the application + /// needs to get all types of RRsets at the origin, it should use + /// the \c ZoneFinder::findAll() method with the zone name. + /// + /// Note that the origin name should always exist, so there + /// shouldn't be the case where the name itself is not found + /// in the zone (i.e., the NXDOMAIN) case. But in any event + /// it does not distinguish such a hypothetical case from the + /// case where the specified type isn't found at the origin. + /// It simply returns NULL when the required type isn't found. + /// This also means it doesn't provide a DNSSEC proof of the + /// non-existence. If the application needs that proof, it must use + /// the generic \c find() method. + /// + /// A CNAME RR shouldn't exist at the zone origin at any sanely + /// configured zone (because there should be at least SOA there and + /// CNAME cannot coexist with it), and it's generally expected + /// the underlying implementation rejects the case where a CNAME + /// somehow exists at the zone origin. Even if such a situation + /// happens, this method does not return the CNAME when the given + /// type of RRset isn't found; it will just return NULL like in the + /// normal case. + /// + /// \throw isc::InvalidParameter Type ANY is specified + /// \throw std::bad_alloc Internal resource allocation failure + /// + /// \param type The RR type for which an RRset at the origin is to be + /// found. + /// \return A shared pointer to the requested type of RRset or NULL + /// if not found. + dns::ConstRRsetPtr getAtOrigin(const dns::RRType& type) { + // Perform common check, then delegate the actual work to + // derived class implementation, if provided. + if (type == dns::RRType::ANY()) { + isc_throw(isc::InvalidParameter, + "Type ANY isn't allowed for getAtOrigin"); + } + return (getAtOriginImpl(type)); + } + protected: /// \brief Actual implementation of getAdditional(). /// @@ -301,6 +362,13 @@ public: const std::vector& requested_types, std::vector& result); + /// \brief Actual implementation of getAtOrigin(). + /// + /// This base class defines a default implementation that can be + /// used for any type of data sources. A data source implementation + /// can override it. + virtual dns::ConstRRsetPtr getAtOriginImpl(const dns::RRType& type); + private: ZoneFinder& finder_; const FindResultFlags flags_; diff --git a/src/lib/datasrc/zone_finder_context.cc b/src/lib/datasrc/zone_finder_context.cc index 7913d71118..e98db4812e 100644 --- a/src/lib/datasrc/zone_finder_context.cc +++ b/src/lib/datasrc/zone_finder_context.cc @@ -98,5 +98,18 @@ ZoneFinder::Context::getAdditionalImpl(const vector& requested_types, } } +ConstRRsetPtr +ZoneFinder::Context::getAtOriginImpl(const dns::RRType& type) { + const ZoneFinder::FindOptions options = + (options_ & ZoneFinder::FIND_DNSSEC) != 0 ? + ZoneFinder::FIND_DNSSEC : ZoneFinder::FIND_DEFAULT; + ConstZoneFinderContextPtr ctx = finder_.find(finder_.getOrigin(), type, + options); + if (ctx->code == ZoneFinder::SUCCESS) { + return (ctx->rrset); + } + return (ConstRRsetPtr()); +} + } // namespace datasrc } // datasrc isc