From d73842ed35d5aea29466e25a9a6b2dfb4e550e97 Mon Sep 17 00:00:00 2001 From: JINMEI Tatuya Date: Tue, 2 Oct 2012 14:15:14 -0700 Subject: [PATCH 1/3] [2060] added the getAtOrigin() method to ZoneFinder::Context. defining the common interface and the default implementation. --- .../datasrc/tests/testdata/contexttest.zone | 3 +- .../tests/zone_finder_context_unittest.cc | 33 +++++++++ src/lib/datasrc/zone.h | 68 +++++++++++++++++++ src/lib/datasrc/zone_finder_context.cc | 13 ++++ 4 files changed, 116 insertions(+), 1 deletion(-) 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 From e0ce6d2f3010bfc5998e6c7da202258cbe28c6c6 Mon Sep 17 00:00:00 2001 From: JINMEI Tatuya Date: Tue, 2 Oct 2012 16:12:29 -0700 Subject: [PATCH 2/3] [2060] (unrelated) make the finder Context class "more basic" by defining a generic derived class and moving optional member variables there. this essentially addresses the issue of #1767. --- src/bin/auth/tests/auth_srv_unittest.cc | 2 +- src/bin/auth/tests/query_unittest.cc | 17 ++-- src/lib/datasrc/database.cc | 16 +-- src/lib/datasrc/memory/zone_finder.cc | 18 +++- src/lib/datasrc/memory_datasrc.cc | 11 ++- src/lib/datasrc/zone.h | 124 +++++++++++++++++------- src/lib/datasrc/zone_finder_context.cc | 26 ++++- 7 files changed, 154 insertions(+), 60 deletions(-) diff --git a/src/bin/auth/tests/auth_srv_unittest.cc b/src/bin/auth/tests/auth_srv_unittest.cc index e7b4ca7dea..00816123a5 100644 --- a/src/bin/auth/tests/auth_srv_unittest.cc +++ b/src/bin/auth/tests/auth_srv_unittest.cc @@ -1286,7 +1286,7 @@ public: if (fake_rrset_ && fake_rrset_->getName() == name && fake_rrset_->getType() == type) { - return (ZoneFinderContextPtr(new ZoneFinder::Context( + return (ZoneFinderContextPtr(new ZoneFinder::GenericContext( *this, options, ResultContext(SUCCESS, fake_rrset_)))); diff --git a/src/bin/auth/tests/query_unittest.cc b/src/bin/auth/tests/query_unittest.cc index 603bf5c3b6..84b7f8a262 100644 --- a/src/bin/auth/tests/query_unittest.cc +++ b/src/bin/auth/tests/query_unittest.cc @@ -442,10 +442,9 @@ public: ConstRRsetPtr rrset) { nsec_name_ = nsec_name; - nsec_context_.reset(new Context(*this, - FIND_DEFAULT, // a fake value - ResultContext(code, rrset, - RESULT_NSEC_SIGNED))); + nsec_context_.reset( + new GenericContext(*this, FIND_DEFAULT, // a fake value + ResultContext(code, rrset, RESULT_NSEC_SIGNED))); } // Once called, the findNSEC3 will return the provided result for the next @@ -487,8 +486,8 @@ protected: { ConstRRsetPtr rp = stripRRsigs(rrset, options); return (ZoneFinderContextPtr( - new Context(*this, options, - ResultContext(code, rp, flags)))); + new GenericContext(*this, options, + ResultContext(code, rp, flags)))); } private: @@ -604,9 +603,9 @@ MockZoneFinder::findAll(const Name& name, std::vector& target, target.push_back(stripRRsigs(found_rrset->second, options)); } return (ZoneFinderContextPtr( - new Context(*this, options, - ResultContext(SUCCESS, RRsetPtr()), - target))); + new GenericContext(*this, options, + ResultContext(SUCCESS, RRsetPtr()), + target))); } } diff --git a/src/lib/datasrc/database.cc b/src/lib/datasrc/database.cc index ede7aa367b..fbada44a33 100644 --- a/src/lib/datasrc/database.cc +++ b/src/lib/datasrc/database.cc @@ -386,10 +386,11 @@ DatabaseClient::Finder::findAll(const isc::dns::Name& name, std::vector& target, const FindOptions options) { - return (ZoneFinderContextPtr(new Context(*this, options, - findInternal(name, RRType::ANY(), - &target, options), - target))); + return (ZoneFinderContextPtr(new GenericContext( + *this, options, + findInternal(name, RRType::ANY(), + &target, options), + target))); } ZoneFinderContextPtr @@ -400,9 +401,10 @@ DatabaseClient::Finder::find(const isc::dns::Name& name, if (type == RRType::ANY()) { isc_throw(isc::Unexpected, "Use findAll to answer ANY"); } - return (ZoneFinderContextPtr(new Context(*this, options, - findInternal(name, type, NULL, - options)))); + return (ZoneFinderContextPtr(new GenericContext( + *this, options, + findInternal(name, type, NULL, + options)))); } DatabaseClient::Finder::DelegationSearchResult diff --git a/src/lib/datasrc/memory/zone_finder.cc b/src/lib/datasrc/memory/zone_finder.cc index 9403c4fec8..7c975aed17 100644 --- a/src/lib/datasrc/memory/zone_finder.cc +++ b/src/lib/datasrc/memory/zone_finder.cc @@ -528,17 +528,26 @@ FindNodeResult findNode(const ZoneData& zone_data, /// context. class InMemoryZoneFinder::Context : public ZoneFinder::Context { public: - Context(ZoneFinder& finder, ZoneFinder::FindOptions options, + Context(InMemoryZoneFinder& finder, ZoneFinder::FindOptions options, const RRClass& rrclass, const ZoneFinderResultContext& result) : - ZoneFinder::Context(finder, options, - ResultContext(result.code, result.rrset, - result.flags)), + ZoneFinder::Context(options, ResultContext(result.code, result.rrset, + result.flags)), + finder_(finder), // NOTE: when #2284 is done we won't need this rrclass_(rrclass), zone_data_(result.zone_data), found_node_(result.found_node), found_rdset_(result.found_rdset) {} protected: + // When #2284 is done this can simply return NULL. + virtual ZoneFinder* getFinder() { return (&finder_); } + + // We don't use the default protected methods that rely on this method, + // so we can simply return NULL. + virtual const std::vector* getAllRRsets() const { + return (NULL); + } + virtual void getAdditionalImpl(const std::vector& requested_types, std::vector& result) { @@ -620,6 +629,7 @@ private: } private: + InMemoryZoneFinder& finder_; const RRClass rrclass_; const ZoneData* const zone_data_; const ZoneNode* const found_node_; diff --git a/src/lib/datasrc/memory_datasrc.cc b/src/lib/datasrc/memory_datasrc.cc index e38a48725e..53cf077d43 100644 --- a/src/lib/datasrc/memory_datasrc.cc +++ b/src/lib/datasrc/memory_datasrc.cc @@ -792,13 +792,19 @@ public: /// context. Context(ZoneFinder& finder, ZoneFinder::FindOptions options, const RBNodeResultContext& result) : - ZoneFinder::Context(finder, options, + ZoneFinder::Context(options, ResultContext(result.code, result.rrset, result.flags)), - rrset_(result.rrset), found_node_(result.found_node) + finder_(finder), rrset_(result.rrset), found_node_(result.found_node) {} protected: + virtual ZoneFinder* getFinder() { return (&finder_); } + + virtual const std::vector* getAllRRsets() const { + return (NULL); + } + virtual void getAdditionalImpl(const vector& requested_types, vector& result) { @@ -866,6 +872,7 @@ private: } } + ZoneFinder& finder_; const ConstRBNodeRRsetPtr rrset_; const DomainNode* const found_node_; }; diff --git a/src/lib/datasrc/zone.h b/src/lib/datasrc/zone.h index 844c6e1b97..a417500399 100644 --- a/src/lib/datasrc/zone.h +++ b/src/lib/datasrc/zone.h @@ -168,48 +168,25 @@ public: /// can define a derived class of the base Context and override the /// specific virtual method. /// + /// This base class defines these common protected methods along with + /// some helper pure virtual methods that would be necessary for the + /// common methods. If a derived class wants to use the common version + /// of the protected method, it needs to provide expected result through + /// their implementation of the pure virtual methods. + /// /// This class object is generally expected to be associated with the /// ZoneFinder that originally performed the \c find() call, and expects /// the finder is valid throughout the lifetime of this object. It's /// caller's responsibility to ensure that assumption. class Context { public: - /// \brief The constructor for the normal find call. + /// \brief The constructor. /// - /// This constructor is expected to be called from the \c find() - /// method when it constructs the return value. - /// - /// \param finder The ZoneFinder on which find() is called. /// \param options The find options specified for the find() call. /// \param result The result of the find() call. - Context(ZoneFinder& finder, FindOptions options, - const ResultContext& result) : + Context(FindOptions options, const ResultContext& result) : code(result.code), rrset(result.rrset), - finder_(finder), flags_(result.flags), options_(options) - {} - - /// \brief The constructor for the normal findAll call. - /// - /// This constructor is expected to be called from the \c findAll() - /// method when it constructs the return value. - /// - /// It copies the vector that is to be returned to the caller of - /// \c findAll() for possible subsequent use. Note that it cannot - /// simply hold a reference to the vector because the caller may - /// alter it after the \c findAll() call. - /// - /// \param finder The ZoneFinder on which findAll() is called. - /// \param options The find options specified for the findAll() call. - /// \param result The result of the findAll() call (whose rrset is - /// expected to be NULL). - /// \param all_set Reference to the vector given by the caller of - /// \c findAll(), storing the RRsets to be returned. - Context(ZoneFinder& finder, FindOptions options, - const ResultContext& result, - const std::vector &all_set) : - code(result.code), rrset(result.rrset), - finder_(finder), flags_(result.flags), options_(options), - all_set_(all_set) + flags_(result.flags), options_(options) {} /// \brief The destructor. @@ -353,11 +330,34 @@ public: } protected: + /// \brief Return the \c ZoneFinder that created this \c Context. + /// + /// A derived class implementation can return NULL if it specializes + /// other protected methods that require a non NULL result from + /// this method. Otherwise it must return a valid, non NULL pointer + /// to the \c ZoneFinder object. + virtual ZoneFinder* getFinder() = 0; + + /// \brief Return a vector of RRsets corresponding to findAll() result. + /// + /// This method returns a set of RRsets that correspond to the + /// returned RRsets to a prior \c findAll() call. + /// + /// A derived class implementation can return NULL if it specializes + /// other protected methods that require a non NULL result from + /// this method. Otherwise it must return a valid, non NULL pointer + /// to a vector that correspond to the expected set of RRsets. + virtual const std::vector* + getAllRRsets() const = 0; + /// \brief Actual implementation of getAdditional(). /// /// This base class defines a default implementation that can be /// used for any type of data sources. A data source implementation /// can override it. + /// + /// The default version of this implementation requires both + /// \c getFinder() and \c getAllRRsets() return valid results. virtual void getAdditionalImpl( const std::vector& requested_types, std::vector& result); @@ -367,14 +367,72 @@ public: /// This base class defines a default implementation that can be /// used for any type of data sources. A data source implementation /// can override it. + /// + /// The default version of this implementation requires + /// \c getFinder() return a valid result. virtual dns::ConstRRsetPtr getAtOriginImpl(const dns::RRType& type); private: - ZoneFinder& finder_; + const FindResultFlags flags_; protected: const FindOptions options_; + }; + + /// \brief Generic ZoneFinder context that works for all implementations. + /// + /// This is a concrete derived class of \c ZoneFinder::Context that + /// only use the generic (default) versions of the protected methods + /// and therefore work for any data source implementation. + /// + /// A data source implementation can use this class to create a + /// \c Context object as a return value of \c find() or \c findAll() + /// method if it doesn't have to optimize specific protected methods. + class GenericContext : public Context { + public: + /// \brief The constructor for the normal find call. + /// + /// This constructor is expected to be called from the \c find() + /// method when it constructs the return value. + /// + /// \param finder The ZoneFinder on which find() is called. + /// \param options See the \c Context class. + /// \param result See the \c Context class. + GenericContext(ZoneFinder& finder, FindOptions options, + const ResultContext& result) : + Context(options, result), finder_(finder) + {} + + /// \brief The constructor for the normal findAll call. + /// + /// This constructor is expected to be called from the \c findAll() + /// method when it constructs the return value. + /// + /// It copies the vector that is to be returned to the caller of + /// \c findAll() for possible subsequent use. Note that it cannot + /// simply hold a reference to the vector because the caller may + /// alter it after the \c findAll() call. + /// + /// \param finder The ZoneFinder on which findAll() is called. + /// \param options See the \c Context class. + /// \param result See the \c Context class. + /// \param all_set Reference to the vector given by the caller of + /// \c findAll(), storing the RRsets to be returned. + GenericContext(ZoneFinder& finder, FindOptions options, + const ResultContext& result, + const std::vector& all_set) : + Context(options, result), finder_(finder), all_set_(all_set) + {} + + protected: + virtual ZoneFinder* getFinder() { return (&finder_); } + virtual const std::vector* + getAllRRsets() const { + return (&all_set_); + } + private: + ZoneFinder& finder_; std::vector all_set_; }; diff --git a/src/lib/datasrc/zone_finder_context.cc b/src/lib/datasrc/zone_finder_context.cc index e98db4812e..f661e987d4 100644 --- a/src/lib/datasrc/zone_finder_context.cc +++ b/src/lib/datasrc/zone_finder_context.cc @@ -12,6 +12,8 @@ // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR // PERFORMANCE OF THIS SOFTWARE. +#include + #include #include #include @@ -87,13 +89,22 @@ ZoneFinder::Context::getAdditionalImpl(const vector& requested_types, { // If rrset is non NULL, it should have been SUCCESS/DELEGATION; otherwise // we should have responded to type ANY query. + ZoneFinder* finder = getFinder(); + if (finder == NULL) { + // This is a bug of the derived class implementation. + isc_throw(isc::Unexpected, "NULL ZoneFinder in finder Context"); + } if (rrset) { - getAdditionalForRRset(finder_, *rrset, requested_types, result, + getAdditionalForRRset(*finder, *rrset, requested_types, result, options_); return; } - BOOST_FOREACH(ConstRRsetPtr rrset_in_set, all_set_) { - getAdditionalForRRset(finder_, *rrset_in_set, requested_types, result, + const vector* all_sets = getAllRRsets(); + if (all_sets == NULL) { // bug of the derived class implementation. + isc_throw(isc::Unexpected, "All RRsets is NULL in finder Context"); + } + BOOST_FOREACH(ConstRRsetPtr rrset_in_set, *getAllRRsets()) { + getAdditionalForRRset(*finder, *rrset_in_set, requested_types, result, options_); } } @@ -103,7 +114,14 @@ 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, + + ZoneFinder* finder = getFinder(); + if (finder == NULL) { + // This is a bug of the derived class implementation. + isc_throw(isc::Unexpected, "NULL ZoneFinder in finder Context"); + } + + ConstZoneFinderContextPtr ctx = finder->find(finder->getOrigin(), type, options); if (ctx->code == ZoneFinder::SUCCESS) { return (ctx->rrset); From fa51dffbe444e5d2ac6a768da001b60ad16d0341 Mon Sep 17 00:00:00 2001 From: JINMEI Tatuya Date: Wed, 3 Oct 2012 09:21:16 -0700 Subject: [PATCH 3/3] [2060] clarified the ownership of obj returned via getFinder/AllRRsets. --- src/lib/datasrc/zone.h | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/lib/datasrc/zone.h b/src/lib/datasrc/zone.h index a417500399..3885aeef74 100644 --- a/src/lib/datasrc/zone.h +++ b/src/lib/datasrc/zone.h @@ -332,10 +332,15 @@ public: protected: /// \brief Return the \c ZoneFinder that created this \c Context. /// - /// A derived class implementation can return NULL if it specializes + /// A derived class implementation can return NULL if it defines /// other protected methods that require a non NULL result from /// this method. Otherwise it must return a valid, non NULL pointer /// to the \c ZoneFinder object. + /// + /// When returning non NULL, the ownership of the pointed object + /// was not transferred to the caller; it cannot be assumed to be + /// valid after the originating \c Context object is destroyed. + /// Also, the caller must not try to delete the returned object. virtual ZoneFinder* getFinder() = 0; /// \brief Return a vector of RRsets corresponding to findAll() result. @@ -343,10 +348,15 @@ public: /// This method returns a set of RRsets that correspond to the /// returned RRsets to a prior \c findAll() call. /// - /// A derived class implementation can return NULL if it specializes + /// A derived class implementation can return NULL if it defines /// other protected methods that require a non NULL result from /// this method. Otherwise it must return a valid, non NULL pointer /// to a vector that correspond to the expected set of RRsets. + /// + /// When returning non NULL, the ownership of the pointed object + /// was not transferred to the caller; it cannot be assumed to be + /// valid after the originating \c Context object is destroyed. + /// Also, the caller must not try to delete the returned object. virtual const std::vector* getAllRRsets() const = 0;