From a98fc15799b0d8898ab3b5071ba55dd8935d45dc Mon Sep 17 00:00:00 2001 From: Michal 'vorner' Vaner Date: Wed, 11 Apr 2012 16:57:40 +0200 Subject: [PATCH] [1577] Reuse more code in findNSEC3 The internal function used to create normal RRs when looking them up is reused for the ones from NSEC3 namespace as well. --- src/lib/datasrc/database.cc | 59 ++++++++++++++++++++++++++----------- src/lib/datasrc/database.h | 7 ++++- 2 files changed, 48 insertions(+), 18 deletions(-) diff --git a/src/lib/datasrc/database.cc b/src/lib/datasrc/database.cc index 2d16320c28..b455dadbf0 100644 --- a/src/lib/datasrc/database.cc +++ b/src/lib/datasrc/database.cc @@ -180,15 +180,17 @@ private: DatabaseClient::Finder::FoundRRsets DatabaseClient::Finder::getRRsets(const string& name, const WantedTypes& types, bool check_ns, const string* construct_name, - bool any) + bool any, + DatabaseAccessor::IteratorContextPtr context) { RRsigStore sig_store; bool records_found = false; std::map result; - // Request the context - DatabaseAccessor::IteratorContextPtr - context(accessor_->getRecords(name, zone_id_)); + // Request the context in case we didn't get one + if (!context) { + context = accessor_->getRecords(name, zone_id_); + } // It must not return NULL, that's a bug of the implementation if (!context) { isc_throw(isc::Unexpected, "Iterator context null at " + name); @@ -320,6 +322,30 @@ namespace { // ask from it. typedef std::set WantedTypes; +const WantedTypes& +NSEC3_TYPES() { + static bool initialized(false); + static WantedTypes result; + + if (!initialized) { + result.insert(RRType::NSEC3()); + initialized = true; + } + return (result); +} + +const WantedTypes& +NSEC3PARAM_TYPES() { + static bool initialized(false); + static WantedTypes result; + + if (!initialized) { + result.insert(RRType::NSEC3PARAM()); + initialized = true; + } + return (result); +} + const WantedTypes& NSEC_TYPES() { static bool initialized(false); @@ -928,8 +954,11 @@ DatabaseClient::Finder::findNSEC3(const Name& name, bool) { // Now, we need to get the NSEC3 params from the apex and create the hash // creator for it. - ZoneFinderContextPtr nsec3param(find(getOrigin(), RRType::NSEC3PARAM())); - if (nsec3param->code != SUCCESS) { // No NSEC3 params? :-( + const FoundRRsets nsec3param(getRRsets(getOrigin().toText(), + NSEC3PARAM_TYPES(), false)); + const FoundIterator param(nsec3param.second.find(RRType::NSEC3PARAM())); + if (!nsec3param.first || param == nsec3param.second.end()) { + // No NSEC3 params? :-( isc_throw(DataSourceError, "findNSEC3 attempt for non NSEC3 signed " << "zone: " << getOrigin() << "/" << getClass()); } @@ -938,24 +967,20 @@ DatabaseClient::Finder::findNSEC3(const Name& name, bool) { // the hash calculator class from it. const scoped_ptr calculator(NSEC3Hash::create( dynamic_cast( - nsec3param->rrset->getRdataIterator()->getCurrent()))); + param->second->getRdataIterator()->getCurrent()))); // Compute the hash and find the corresponding NSEC3 const string hash(calculator->calculate(name)); DatabaseAccessor::IteratorContextPtr context(accessor_->getNSEC3Records(hash, zone_id_)); - // We store the data here - string columns[DatabaseAccessor::COLUMN_COUNT]; - // TODO: Stop assuming the data is there. This is temporary, just for this - // commit. - context->getNext(columns); - RRsetPtr result(new RRset(Name(hash).concatenate(getOrigin()), getClass(), - RRType::NSEC3(), - RRTTL(columns[DatabaseAccessor::TTL_COLUMN]))); - result->addRdata(generic::NSEC3(columns[DatabaseAccessor::RDATA_COLUMN])); + const FoundRRsets nsec3(getRRsets(hash + "." + getOrigin().toText(), + NSEC3_TYPES(), false, NULL, false, + context)); + // Return an expected exact match for now - return (FindNSEC3Result(true, name.getLabelCount(), result, + return (FindNSEC3Result(true, name.getLabelCount(), + nsec3.second.find(RRType::NSEC3())->second, ConstRRsetPtr())); } diff --git a/src/lib/datasrc/database.h b/src/lib/datasrc/database.h index d9d6dfadde..8fe9c843af 100644 --- a/src/lib/datasrc/database.h +++ b/src/lib/datasrc/database.h @@ -887,6 +887,9 @@ public: /// ones requested by types. It also puts a NULL pointer under the /// ANY type into the result, if it finds any RRs at all, to easy the /// identification of success. + /// \param srcContext This can be set to non-NULL value to override the + /// iterator context used for obtaining the data. This can be used, + /// for example, to get data from the NSEC3 namespace. /// \return A pair, where the first element indicates if the domain /// contains any RRs at all (not only the requested, it may happen /// this is set to true, but the second part is empty). The second @@ -898,7 +901,9 @@ public: FoundRRsets getRRsets(const std::string& name, const WantedTypes& types, bool check_ns, const std::string* construct_name = NULL, - bool any = false); + bool any = false, + DatabaseAccessor::IteratorContextPtr srcContext = + DatabaseAccessor::IteratorContextPtr()); /// \brief Search result of \c findDelegationPoint(). ///