BIND 10 master, updated. a47f01b6c860c565516456d329a4aebe63d346a0 Merge #1483
BIND 10 source code commits
bind10-changes at lists.isc.org
Tue Dec 20 14:12:15 UTC 2011
The branch, master has been updated
via a47f01b6c860c565516456d329a4aebe63d346a0 (commit)
via 87a72f002abc5c6db9baeb3b3e2ac20c0a1e24ce (commit)
via 424113eeebb77e6edac02231a64595729bc04bbc (commit)
via 30b1cc45e2b536acdf0216a02b88de39c4fce4b3 (commit)
via 86b08bc45b6e3c8934971625b8b189012ef51357 (commit)
via 702631dc5f42c288ebb701eb5a8b67074f675de5 (commit)
via 0d0b9b0ebea1a12b35cdd646700f332c9f5a7cb5 (commit)
via d254b329691d43307184e78b33c2704eafa39f77 (commit)
via 7ffef24a4823b63694628ee9fdab0b196d7caa06 (commit)
via b2da8d97a3f24f2f80af7f408f6b8d461f3dccd4 (commit)
via 90c77658e79a21c3a60da992f22eb2f2660db667 (commit)
via 8e93f114a93671c4eda46f420c81e1101fc16e05 (commit)
via 118d0d9c047879133c412390d67dda70004da589 (commit)
via cbddeb5ad8ecb4d3ef403943e588fa2c858b0d3b (commit)
from b0d0bf39fbdc29a7879315f9b8e6d602ef3afb1b (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit a47f01b6c860c565516456d329a4aebe63d346a0
Merge: b0d0bf39fbdc29a7879315f9b8e6d602ef3afb1b 87a72f002abc5c6db9baeb3b3e2ac20c0a1e24ce
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date: Tue Dec 20 14:59:03 2011 +0100
Merge #1483
commit 87a72f002abc5c6db9baeb3b3e2ac20c0a1e24ce
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date: Mon Dec 19 18:04:08 2011 +0100
[1483] Doxygen
-----------------------------------------------------------------------
Summary of changes:
src/bin/auth/query.cc | 284 +++++++++++-----------
src/bin/auth/tests/query_unittest.cc | 38 ++-
src/lib/datasrc/database.cc | 80 +++++--
src/lib/datasrc/database.h | 174 ++++++++------
src/lib/datasrc/datasrc_messages.mes | 9 +
src/lib/datasrc/memory_datasrc.cc | 19 +-
src/lib/datasrc/memory_datasrc.h | 14 +-
src/lib/datasrc/tests/database_unittest.cc | 162 +++++++++++--
src/lib/datasrc/tests/memory_datasrc_unittest.cc | 138 ++++++-----
src/lib/datasrc/zone.h | 26 ++-
src/lib/python/isc/datasrc/finder_python.cc | 2 +-
11 files changed, 604 insertions(+), 342 deletions(-)
-----------------------------------------------------------------------
diff --git a/src/bin/auth/query.cc b/src/bin/auth/query.cc
index f159262..2bf8f5e 100644
--- a/src/bin/auth/query.cc
+++ b/src/bin/auth/query.cc
@@ -15,6 +15,8 @@
#include <algorithm> // for std::max
#include <vector>
#include <boost/foreach.hpp>
+#include <boost/bind.hpp>
+#include <boost/function.hpp>
#include <dns/message.h>
#include <dns/rcode.h>
@@ -67,7 +69,7 @@ Query::addAdditionalAddrs(ZoneFinder& zone, const Name& qname,
// Find A rrset
if (qname_ != qname || qtype_ != RRType::A()) {
- ZoneFinder::FindResult a_result = zone.find(qname, RRType::A(), NULL,
+ ZoneFinder::FindResult a_result = zone.find(qname, RRType::A(),
options | dnssec_opt_);
if (a_result.code == ZoneFinder::SUCCESS) {
response_.addRRset(Message::SECTION_ADDITIONAL,
@@ -78,7 +80,7 @@ Query::addAdditionalAddrs(ZoneFinder& zone, const Name& qname,
// Find AAAA rrset
if (qname_ != qname || qtype_ != RRType::AAAA()) {
ZoneFinder::FindResult aaaa_result =
- zone.find(qname, RRType::AAAA(), NULL, options | dnssec_opt_);
+ zone.find(qname, RRType::AAAA(), options | dnssec_opt_);
if (aaaa_result.code == ZoneFinder::SUCCESS) {
response_.addRRset(Message::SECTION_ADDITIONAL,
boost::const_pointer_cast<RRset>(aaaa_result.rrset),
@@ -90,7 +92,7 @@ Query::addAdditionalAddrs(ZoneFinder& zone, const Name& qname,
void
Query::addSOA(ZoneFinder& finder) {
ZoneFinder::FindResult soa_result(finder.find(finder.getOrigin(),
- RRType::SOA(), NULL, dnssec_opt_));
+ RRType::SOA(), dnssec_opt_));
if (soa_result.code != ZoneFinder::SUCCESS) {
isc_throw(NoSOA, "There's no SOA record in zone " <<
finder.getOrigin().toText());
@@ -146,7 +148,7 @@ Query::addNXDOMAINProof(ZoneFinder& finder, ConstRRsetPtr nsec) {
// otherwise we shouldn't have got NXDOMAIN for the original query in
// the first place).
const ZoneFinder::FindResult fresult = finder.find(wildname,
- RRType::NSEC(), NULL,
+ RRType::NSEC(),
dnssec_opt_);
if (fresult.code != ZoneFinder::NXDOMAIN || !fresult.rrset ||
fresult.rrset->getRdataCount() == 0) {
@@ -171,7 +173,7 @@ Query::addWildcardProof(ZoneFinder& finder) {
// substitution. Confirm that by specifying NO_WILDCARD. It should result
// in NXDOMAIN and an NSEC RR that proves it should be returned.
const ZoneFinder::FindResult fresult =
- finder.find(qname_, RRType::NSEC(), NULL,
+ finder.find(qname_, RRType::NSEC(),
dnssec_opt_ | ZoneFinder::NO_WILDCARD);
if (fresult.code != ZoneFinder::NXDOMAIN || !fresult.rrset ||
fresult.rrset->getRdataCount() == 0) {
@@ -194,7 +196,7 @@ Query::addWildcardNXRRSETProof(ZoneFinder& finder, ConstRRsetPtr nsec) {
boost::const_pointer_cast<RRset>(nsec), dnssec_);
const ZoneFinder::FindResult fresult =
- finder.find(qname_, RRType::NSEC(), NULL,
+ finder.find(qname_, RRType::NSEC(),
dnssec_opt_ | ZoneFinder::NO_WILDCARD);
if (fresult.code != ZoneFinder::NXDOMAIN || !fresult.rrset ||
fresult.rrset->getRdataCount() == 0) {
@@ -213,8 +215,7 @@ void
Query::addAuthAdditional(ZoneFinder& finder) {
// Fill in authority and addtional sections.
ZoneFinder::FindResult ns_result = finder.find(finder.getOrigin(),
- RRType::NS(), NULL,
- dnssec_opt_);
+ RRType::NS(), dnssec_opt_);
// zone origin name should have NS records
if (ns_result.code != ZoneFinder::SUCCESS) {
isc_throw(NoApexNS, "There's no apex NS records in zone " <<
@@ -229,7 +230,6 @@ Query::addAuthAdditional(ZoneFinder& finder) {
void
Query::process() {
- bool keep_doing = true;
const bool qtype_is_any = (qtype_ == RRType::ANY());
response_.setHeaderFlag(Message::HEADERFLAG_AA, false);
@@ -251,147 +251,151 @@ Query::process() {
// Found a zone which is the nearest ancestor to QNAME, set the AA bit
response_.setHeaderFlag(Message::HEADERFLAG_AA);
response_.setRcode(Rcode::NOERROR());
- while (keep_doing) {
- keep_doing = false;
- std::auto_ptr<RRsetList> target(qtype_is_any ? new RRsetList : NULL);
- const ZoneFinder::FindResult db_result(
- zfinder.find(qname_, qtype_, target.get(), dnssec_opt_));
- switch (db_result.code) {
- case ZoneFinder::DNAME: {
- // First, put the dname into the answer
- response_.addRRset(Message::SECTION_ANSWER,
- boost::const_pointer_cast<RRset>(db_result.rrset),
- dnssec_);
+ std::vector<ConstRRsetPtr> target;
+ boost::function0<ZoneFinder::FindResult> find;
+ if (qtype_is_any) {
+ find = boost::bind(&ZoneFinder::findAll, &zfinder, qname_,
+ boost::ref(target), dnssec_opt_);
+ } else {
+ find = boost::bind(&ZoneFinder::find, &zfinder, qname_, qtype_,
+ dnssec_opt_);
+ }
+ ZoneFinder::FindResult db_result(find());
+ switch (db_result.code) {
+ case ZoneFinder::DNAME: {
+ // First, put the dname into the answer
+ response_.addRRset(Message::SECTION_ANSWER,
+ boost::const_pointer_cast<RRset>(db_result.rrset),
+ dnssec_);
+ /*
+ * Empty DNAME should never get in, as it is impossible to
+ * create one in master file.
+ *
+ * FIXME: Other way to prevent this should be done
+ */
+ assert(db_result.rrset->getRdataCount() > 0);
+ // Get the data of DNAME
+ const rdata::generic::DNAME& dname(
+ dynamic_cast<const rdata::generic::DNAME&>(
+ db_result.rrset->getRdataIterator()->getCurrent()));
+ // The yet unmatched prefix dname
+ const Name prefix(qname_.split(0, qname_.getLabelCount() -
+ db_result.rrset->getName().getLabelCount()));
+ // If we put it together, will it be too long?
+ // (The prefix contains trailing ., which will be removed
+ if (prefix.getLength() - Name::ROOT_NAME().getLength() +
+ dname.getDname().getLength() > Name::MAX_WIRE) {
/*
- * Empty DNAME should never get in, as it is impossible to
- * create one in master file.
- *
- * FIXME: Other way to prevent this should be done
+ * In case the synthesized name is too long, section 4.1
+ * of RFC 2672 mandates we return YXDOMAIN.
*/
- assert(db_result.rrset->getRdataCount() > 0);
- // Get the data of DNAME
- const rdata::generic::DNAME& dname(
- dynamic_cast<const rdata::generic::DNAME&>(
- db_result.rrset->getRdataIterator()->getCurrent()));
- // The yet unmatched prefix dname
- const Name prefix(qname_.split(0, qname_.getLabelCount() -
- db_result.rrset->getName().getLabelCount()));
- // If we put it together, will it be too long?
- // (The prefix contains trailing ., which will be removed
- if (prefix.getLength() - Name::ROOT_NAME().getLength() +
- dname.getDname().getLength() > Name::MAX_WIRE) {
- /*
- * In case the synthesized name is too long, section 4.1
- * of RFC 2672 mandates we return YXDOMAIN.
- */
- response_.setRcode(Rcode::YXDOMAIN());
- return;
- }
- // The new CNAME we are creating (it will be unsigned even
- // with DNSSEC, the DNAME is signed and it can be validated
- // by that)
- RRsetPtr cname(new RRset(qname_, db_result.rrset->getClass(),
- RRType::CNAME(), db_result.rrset->getTTL()));
- // Construct the new target by replacing the end
- cname->addRdata(rdata::generic::CNAME(qname_.split(0,
- qname_.getLabelCount() -
- db_result.rrset->getName().getLabelCount()).
- concatenate(dname.getDname())));
- response_.addRRset(Message::SECTION_ANSWER, cname, dnssec_);
- break;
+ response_.setRcode(Rcode::YXDOMAIN());
+ return;
}
- case ZoneFinder::CNAME:
- case ZoneFinder::WILDCARD_CNAME:
- /*
- * We don't do chaining yet. Therefore handling a CNAME is
- * mostly the same as handling SUCCESS, but we didn't get
- * what we expected. It means no exceptions in ANY or NS
- * on the origin (though CNAME in origin is probably
- * forbidden anyway).
- *
- * So, just put it there.
- */
- response_.addRRset(Message::SECTION_ANSWER,
- boost::const_pointer_cast<RRset>(db_result.rrset),
- dnssec_);
+ // The new CNAME we are creating (it will be unsigned even
+ // with DNSSEC, the DNAME is signed and it can be validated
+ // by that)
+ RRsetPtr cname(new RRset(qname_, db_result.rrset->getClass(),
+ RRType::CNAME(), db_result.rrset->getTTL()));
+ // Construct the new target by replacing the end
+ cname->addRdata(rdata::generic::CNAME(qname_.split(0,
+ qname_.getLabelCount() -
+ db_result.rrset->getName().getLabelCount()).
+ concatenate(dname.getDname())));
+ response_.addRRset(Message::SECTION_ANSWER, cname, dnssec_);
+ break;
+ }
+ case ZoneFinder::CNAME:
+ case ZoneFinder::WILDCARD_CNAME:
+ /*
+ * We don't do chaining yet. Therefore handling a CNAME is
+ * mostly the same as handling SUCCESS, but we didn't get
+ * what we expected. It means no exceptions in ANY or NS
+ * on the origin (though CNAME in origin is probably
+ * forbidden anyway).
+ *
+ * So, just put it there.
+ */
+ response_.addRRset(Message::SECTION_ANSWER,
+ boost::const_pointer_cast<RRset>(db_result.rrset),
+ dnssec_);
- // If the answer is a result of wildcard substitution,
- // add a proof that there's no closer name.
- if (dnssec_ && db_result.code == ZoneFinder::WILDCARD_CNAME) {
- addWildcardProof(*result.zone_finder);
- }
- break;
- case ZoneFinder::SUCCESS:
- case ZoneFinder::WILDCARD:
- if (qtype_is_any) {
- // If quety type is ANY, insert all RRs under the domain
- // into answer section.
- BOOST_FOREACH(RRsetPtr rrset, *target) {
- response_.addRRset(Message::SECTION_ANSWER, rrset,
- dnssec_);
- // Handle additional for answer section
- addAdditional(*result.zone_finder, *rrset.get());
- }
- } else {
+ // If the answer is a result of wildcard substitution,
+ // add a proof that there's no closer name.
+ if (dnssec_ && db_result.code == ZoneFinder::WILDCARD_CNAME) {
+ addWildcardProof(*result.zone_finder);
+ }
+ break;
+ case ZoneFinder::SUCCESS:
+ case ZoneFinder::WILDCARD:
+ if (qtype_is_any) {
+ // If quety type is ANY, insert all RRs under the domain
+ // into answer section.
+ BOOST_FOREACH(ConstRRsetPtr rrset, target) {
response_.addRRset(Message::SECTION_ANSWER,
- boost::const_pointer_cast<RRset>(db_result.rrset),
- dnssec_);
+ boost::const_pointer_cast<RRset>(rrset), dnssec_);
// Handle additional for answer section
- addAdditional(*result.zone_finder, *db_result.rrset);
+ addAdditional(*result.zone_finder, *rrset.get());
}
- // If apex NS records haven't been provided in the answer
- // section, insert apex NS records into the authority section
- // and AAAA/A RRS of each of the NS RDATA into the additional
- // section.
- if (qname_ != result.zone_finder->getOrigin() ||
- db_result.code != ZoneFinder::SUCCESS ||
- (qtype_ != RRType::NS() && !qtype_is_any))
- {
- addAuthAdditional(*result.zone_finder);
- }
-
- // If the answer is a result of wildcard substitution,
- // add a proof that there's no closer name.
- if (dnssec_ && db_result.code == ZoneFinder::WILDCARD) {
- addWildcardProof(*result.zone_finder);
- }
- break;
- case ZoneFinder::DELEGATION:
- response_.setHeaderFlag(Message::HEADERFLAG_AA, false);
- response_.addRRset(Message::SECTION_AUTHORITY,
+ } else {
+ response_.addRRset(Message::SECTION_ANSWER,
boost::const_pointer_cast<RRset>(db_result.rrset),
dnssec_);
+ // Handle additional for answer section
addAdditional(*result.zone_finder, *db_result.rrset);
- break;
- case ZoneFinder::NXDOMAIN:
- response_.setRcode(Rcode::NXDOMAIN());
- addSOA(*result.zone_finder);
- if (dnssec_ && db_result.rrset) {
- addNXDOMAINProof(zfinder, db_result.rrset);
- }
- break;
- case ZoneFinder::NXRRSET:
- addSOA(*result.zone_finder);
- if (dnssec_ && db_result.rrset) {
- response_.addRRset(Message::SECTION_AUTHORITY,
- boost::const_pointer_cast<RRset>(
- db_result.rrset),
- dnssec_);
- }
- break;
- case ZoneFinder::WILDCARD_NXRRSET:
- addSOA(*result.zone_finder);
- if (dnssec_ && db_result.rrset) {
- addWildcardNXRRSETProof(zfinder, db_result.rrset);
- }
- break;
- default:
- // This is basically a bug of the data source implementation,
- // but could also happen in the middle of development where
- // we try to add a new result code.
- isc_throw(isc::NotImplemented, "Unknown result code");
- break;
- }
+ }
+ // If apex NS records haven't been provided in the answer
+ // section, insert apex NS records into the authority section
+ // and AAAA/A RRS of each of the NS RDATA into the additional
+ // section.
+ if (qname_ != result.zone_finder->getOrigin() ||
+ db_result.code != ZoneFinder::SUCCESS ||
+ (qtype_ != RRType::NS() && !qtype_is_any))
+ {
+ addAuthAdditional(*result.zone_finder);
+ }
+
+ // If the answer is a result of wildcard substitution,
+ // add a proof that there's no closer name.
+ if (dnssec_ && db_result.code == ZoneFinder::WILDCARD) {
+ addWildcardProof(*result.zone_finder);
+ }
+ break;
+ case ZoneFinder::DELEGATION:
+ response_.setHeaderFlag(Message::HEADERFLAG_AA, false);
+ response_.addRRset(Message::SECTION_AUTHORITY,
+ boost::const_pointer_cast<RRset>(db_result.rrset),
+ dnssec_);
+ addAdditional(*result.zone_finder, *db_result.rrset);
+ break;
+ case ZoneFinder::NXDOMAIN:
+ response_.setRcode(Rcode::NXDOMAIN());
+ addSOA(*result.zone_finder);
+ if (dnssec_ && db_result.rrset) {
+ addNXDOMAINProof(zfinder, db_result.rrset);
+ }
+ break;
+ case ZoneFinder::NXRRSET:
+ addSOA(*result.zone_finder);
+ if (dnssec_ && db_result.rrset) {
+ response_.addRRset(Message::SECTION_AUTHORITY,
+ boost::const_pointer_cast<RRset>(
+ db_result.rrset),
+ dnssec_);
+ }
+ break;
+ case ZoneFinder::WILDCARD_NXRRSET:
+ addSOA(*result.zone_finder);
+ if (dnssec_ && db_result.rrset) {
+ addWildcardNXRRSETProof(zfinder, db_result.rrset);
+ }
+ break;
+ default:
+ // This is basically a bug of the data source implementation,
+ // but could also happen in the middle of development where
+ // we try to add a new result code.
+ isc_throw(isc::NotImplemented, "Unknown result code");
+ break;
}
}
diff --git a/src/bin/auth/tests/query_unittest.cc b/src/bin/auth/tests/query_unittest.cc
index 14067ab..858759e 100644
--- a/src/bin/auth/tests/query_unittest.cc
+++ b/src/bin/auth/tests/query_unittest.cc
@@ -211,8 +211,10 @@ public:
virtual isc::dns::RRClass getClass() const { return (rrclass_); }
virtual FindResult find(const isc::dns::Name& name,
const isc::dns::RRType& type,
- RRsetList* target = NULL,
const FindOptions options = FIND_DEFAULT);
+ virtual FindResult findAll(const isc::dns::Name& name,
+ std::vector<ConstRRsetPtr>& target,
+ const FindOptions options = FIND_DEFAULT);
// If false is passed, it makes the zone broken as if it didn't have the
// SOA.
@@ -305,8 +307,29 @@ substituteWild(const RRset& wild_rrset, const Name& real_name) {
}
ZoneFinder::FindResult
+MockZoneFinder::findAll(const Name& name, std::vector<ConstRRsetPtr>& target,
+ const FindOptions options)
+{
+ ZoneFinder::FindResult result(find(name, RRType::ANY(), options));
+ if (result.code == NXRRSET) {
+ const Domains::const_iterator found_domain = domains_.find(name);
+ if (!found_domain->second.empty()) {
+ for (RRsetStore::const_iterator found_rrset =
+ found_domain->second.begin();
+ found_rrset != found_domain->second.end(); ++found_rrset) {
+ // Insert RRs under the domain name into target
+ target.push_back(found_rrset->second);
+ }
+ return (FindResult(SUCCESS, RRsetPtr()));
+ }
+ }
+
+ return (result);
+}
+
+ZoneFinder::FindResult
MockZoneFinder::find(const Name& name, const RRType& type,
- RRsetList* target, const FindOptions options)
+ const FindOptions options)
{
// Emulating a broken zone: mandatory apex RRs are missing if specifically
// configured so (which are rare cases).
@@ -358,17 +381,6 @@ MockZoneFinder::find(const Name& name, const RRType& type,
return (FindResult(SUCCESS, rrset));
}
- // If not found but we have a target, fill it with all RRsets here
- if (!found_domain->second.empty() && target != NULL) {
- for (found_rrset = found_domain->second.begin();
- found_rrset != found_domain->second.end(); ++found_rrset) {
- // Insert RRs under the domain name into target
- target->addRRset(
- boost::const_pointer_cast<RRset>(found_rrset->second));
- }
- return (FindResult(SUCCESS, found_domain->second.begin()->second));
- }
-
// Otherwise, if this domain name has CNAME, return it.
found_rrset = found_domain->second.find(RRType::CNAME());
if (found_rrset != found_domain->second.end()) {
diff --git a/src/lib/datasrc/database.cc b/src/lib/datasrc/database.cc
index 6620c85..2e85af6 100644
--- a/src/lib/datasrc/database.cc
+++ b/src/lib/datasrc/database.cc
@@ -176,7 +176,8 @@ private:
DatabaseClient::Finder::FoundRRsets
DatabaseClient::Finder::getRRsets(const string& name, const WantedTypes& types,
- bool check_ns, const string* construct_name)
+ bool check_ns, const string* construct_name,
+ bool any)
{
RRsigStore sig_store;
bool records_found = false;
@@ -221,7 +222,7 @@ DatabaseClient::Finder::getRRsets(const string& name, const WantedTypes& types,
columns[DatabaseAccessor::RDATA_COLUMN]));
}
- if (types.find(cur_type) != types.end()) {
+ if (types.find(cur_type) != types.end() || any) {
// This type is requested, so put it into result
const RRTTL cur_ttl(columns[DatabaseAccessor::TTL_COLUMN]);
// Ths sigtype column was an optimization for finding the
@@ -286,6 +287,12 @@ DatabaseClient::Finder::getRRsets(const string& name, const WantedTypes& types,
sig_store.appendSignatures(i->second);
}
+ if (records_found && any) {
+ result[RRType::ANY()] = RRsetPtr();
+ // These will be sitting on the other RRsets.
+ result.erase(RRType::RRSIG());
+ }
+
return (FoundRRsets(records_found, result));
}
@@ -389,6 +396,25 @@ DatabaseClient::Finder::findNSECCover(const Name& name) {
return (ConstRRsetPtr());
}
+ZoneFinder::FindResult
+DatabaseClient::Finder::findAll(const isc::dns::Name& name,
+ std::vector<isc::dns::ConstRRsetPtr>& target,
+ const FindOptions options)
+{
+ return (findInternal(name, RRType::ANY(), &target, options));
+}
+
+ZoneFinder::FindResult
+DatabaseClient::Finder::find(const isc::dns::Name& name,
+ const isc::dns::RRType& type,
+ const FindOptions options)
+{
+ if (type == RRType::ANY()) {
+ isc_throw(isc::Unexpected, "Use findAll to answer ANY");
+ }
+ return (findInternal(name, type, NULL, options));
+}
+
DatabaseClient::Finder::DelegationSearchResult
DatabaseClient::Finder::findDelegationPoint(const isc::dns::Name& name,
const FindOptions options)
@@ -550,7 +576,8 @@ DatabaseClient::Finder::findDelegationPoint(const isc::dns::Name& name,
ZoneFinder::FindResult
DatabaseClient::Finder::findWildcardMatch(
const isc::dns::Name& name, const isc::dns::RRType& type,
- const FindOptions options, const DelegationSearchResult& dresult)
+ const FindOptions options, const DelegationSearchResult& dresult,
+ std::vector<isc::dns::ConstRRsetPtr>* target)
{
// Note that during the search we are going to search not only for the
// requested type, but also for types that indicate a delegation -
@@ -569,7 +596,7 @@ DatabaseClient::Finder::findWildcardMatch(
// RFC 4592 section 4.4).
// Search for a match. The types are the same as with original query.
FoundRRsets found = getRRsets(wildcard, final_types, true,
- &construct_name);
+ &construct_name, type == RRType::ANY());
if (found.first) {
// Found something - but what?
@@ -594,7 +621,7 @@ DatabaseClient::Finder::findWildcardMatch(
// The wildcard match is the best one, find the final result
// at it. Note that wildcard should never be the zone origin.
return (findOnNameResult(name, type, options, false,
- found, &wildcard));
+ found, &wildcard, target));
} else {
// more specified match found, cancel wildcard match
@@ -660,7 +687,9 @@ DatabaseClient::Finder::findOnNameResult(const Name& name,
const FindOptions options,
const bool is_origin,
const FoundRRsets& found,
- const string* wildname)
+ const string* wildname,
+ std::vector<isc::dns::ConstRRsetPtr>*
+ target)
{
const bool wild = (wildname != NULL);
@@ -698,14 +727,29 @@ DatabaseClient::Finder::findOnNameResult(const Name& name,
DATASRC_DATABASE_FOUND_CNAME));
} else if (wti != found.second.end()) {
+ bool any(type == RRType::ANY());
+ isc::log::MessageID lid(wild ? DATASRC_DATABASE_WILDCARD_MATCH :
+ DATASRC_DATABASE_FOUND_RRSET);
+ if (any) {
+ // An ANY query, copy everything to the target instead of returning
+ // directly.
+ for (FoundIterator it(found.second.begin());
+ it != found.second.end(); ++it) {
+ if (it->second) {
+ // Skip over the empty ANY
+ target->push_back(it->second);
+ }
+ }
+ lid = wild ? DATASRC_DATABASE_WILDCARD_ANY :
+ DATASRC_DATABASE_FOUND_ANY;
+ }
// Found an RR matching the query, so return it. (Note that this
// includes the case where we were explicitly querying for a CNAME and
// found it. It also includes the case where we were querying for an
// NS RRset and found it at the apex of the zone.)
return (logAndCreateResult(name, wildname, type,
wild ? WILDCARD : SUCCESS, wti->second,
- wild ? DATASRC_DATABASE_WILDCARD_MATCH :
- DATASRC_DATABASE_FOUND_RRSET));
+ lid));
}
// If we get here, we have found something at the requested name but not
@@ -747,7 +791,9 @@ DatabaseClient::Finder::findOnNameResult(const Name& name,
ZoneFinder::FindResult
DatabaseClient::Finder::findNoNameResult(const Name& name, const RRType& type,
FindOptions options,
- const DelegationSearchResult& dresult)
+ const DelegationSearchResult& dresult,
+ std::vector<isc::dns::ConstRRsetPtr>*
+ target)
{
const bool dnssec_data = ((options & FIND_DNSSEC) != 0);
@@ -771,7 +817,7 @@ DatabaseClient::Finder::findNoNameResult(const Name& name, const RRType& type,
// (i.e. all results except NXDOMAIN) return it; otherwise fall
// through to the NXDOMAIN case below.
const ZoneFinder::FindResult wresult =
- findWildcardMatch(name, type, options, dresult);
+ findWildcardMatch(name, type, options, dresult, target);
if (wresult.code != NXDOMAIN) {
return (FindResult(wresult.code, wresult.rrset));
}
@@ -786,9 +832,9 @@ DatabaseClient::Finder::findNoNameResult(const Name& name, const RRType& type,
}
ZoneFinder::FindResult
-DatabaseClient::Finder::find(const isc::dns::Name& name,
+DatabaseClient::Finder::findInternal(const isc::dns::Name& name,
const isc::dns::RRType& type,
- isc::dns::RRsetList*,
+ std::vector<isc::dns::ConstRRsetPtr>* target,
const FindOptions options)
{
LOG_DEBUG(logger, DBG_TRACE_DETAILED, DATASRC_DATABASE_FIND_RECORDS)
@@ -820,16 +866,18 @@ DatabaseClient::Finder::find(const isc::dns::Name& name,
WantedTypes final_types(FINAL_TYPES());
final_types.insert(type);
const FoundRRsets found = getRRsets(name.toText(), final_types,
- !is_origin);
+ !is_origin, NULL,
+ type == RRType::ANY());
if (found.first) {
// Something found at the domain name. Look into it further to get
// the final result.
- return (findOnNameResult(name, type, options, is_origin, found, NULL));
+ return (findOnNameResult(name, type, options, is_origin, found, NULL,
+ target));
} else {
// Did not find anything at all at the domain name, so check for
// subdomains or wildcards.
- return (findNoNameResult(name, type, options, dresult));
+ return (findNoNameResult(name, type, options, dresult, target));
}
}
@@ -897,7 +945,7 @@ public:
// Find the SOA of the zone (may or may not succeed). Note that
// this must be done before starting the iteration context.
soa_ = DatabaseClient::Finder(accessor_, zone.second, zone_name).
- find(zone_name, RRType::SOA(), NULL).rrset;
+ find(zone_name, RRType::SOA()).rrset;
// Request the context
context_ = accessor_->getAllRecords(zone.second);
diff --git a/src/lib/datasrc/database.h b/src/lib/datasrc/database.h
index c1b71cd..fdbaa0a 100644
--- a/src/lib/datasrc/database.h
+++ b/src/lib/datasrc/database.h
@@ -714,11 +714,6 @@ public:
/// (this implementation is not complete, and currently only
/// does full matches, CNAMES, and the signatures for matches and
/// CNAMEs)
- /// \note target was used in the original design to handle ANY
- /// queries. This is not implemented yet, and may use
- /// target again for that, but it might also use something
- /// different. It is left in for compatibility at the moment.
- /// \note options are ignored at this moment
///
/// \note Maybe counter intuitively, this method is not a const member
/// function. This is intentional; some of the underlying
@@ -741,13 +736,19 @@ public:
///
/// \param name The name to find
/// \param type The RRType to find
- /// \param target Unused at this moment
/// \param options Options about how to search.
/// See ZoneFinder::FindOptions.
virtual FindResult find(const isc::dns::Name& name,
const isc::dns::RRType& type,
- isc::dns::RRsetList* target = NULL,
const FindOptions options = FIND_DEFAULT);
+ /// \brief Implementation of the ZoneFinder::findAll method.
+ ///
+ /// In short, it is mostly the same thing as find, but it returns all
+ /// RRsets in the named node through the target parameter in successful
+ /// case. It acts the same in the unsuccessful one.
+ virtual FindResult findAll(const isc::dns::Name& name,
+ std::vector<isc::dns::ConstRRsetPtr>& target,
+ const FindOptions options = FIND_DEFAULT);
/// \brief Implementation of ZoneFinder::findPreviousName method.
virtual isc::dns::Name findPreviousName(const isc::dns::Name& query)
@@ -773,12 +774,57 @@ public:
boost::shared_ptr<DatabaseAccessor> accessor_;
const int zone_id_;
const isc::dns::Name origin_;
- //
/// \brief Shortcut name for the result of getRRsets
typedef std::pair<bool, std::map<dns::RRType, dns::RRsetPtr> >
FoundRRsets;
/// \brief Just shortcut for set of types
typedef std::set<dns::RRType> WantedTypes;
+ /// \brief Internal logit of find and findAll methods.
+ ///
+ /// Most of their handling is in the "error" cases and delegations
+ /// and so on. So they share the logic here and find and findAll provide
+ /// just an interface for it.
+ ///
+ /// Parameters and behaviour is like of those combined together.
+ /// Unexpected parameters, like type != ANY and having the target, are
+ /// just that - unexpected and not checked.
+ FindResult findInternal(const isc::dns::Name& name,
+ const isc::dns::RRType& type,
+ std::vector<isc::dns::ConstRRsetPtr>* target,
+ const FindOptions options = FIND_DEFAULT);
+ /// \brief Searches database for RRsets of one domain.
+ ///
+ /// This method scans RRs of single domain specified by name and
+ /// extracts any RRsets found and requested by parameters.
+ ///
+ /// It is used internally by find(), because it is called multiple
+ /// times (usually with different domains).
+ ///
+ /// \param name Which domain name should be scanned.
+ /// \param types List of types the caller is interested in.
+ /// \param check_ns If this is set to true, it checks nothing lives
+ /// together with NS record (with few little exceptions, like RRSIG
+ /// or NSEC). This check is meant for non-apex NS records.
+ /// \param construct_name If this is NULL, the resulting RRsets have
+ /// their name set to name. If it is not NULL, it overrides the name
+ /// and uses this one (this can be used for wildcard synthesized
+ /// records).
+ /// \param any If this is true, it records all the types, not only the
+ /// 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.
+ /// \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
+ /// part is map from RRtypes to RRsets of the corresponding types.
+ /// If the RRset is not present in DB, the RRtype is not there at
+ /// all (so you'll not find NULL pointer in the result).
+ /// \throw DataSourceError If there's a low-level error with the
+ /// database or the database contains bad data.
+ FoundRRsets getRRsets(const std::string& name,
+ const WantedTypes& types, bool check_ns,
+ const std::string* construct_name = NULL,
+ bool any = false);
/// \brief Search result of \c findDelegationPoint().
///
@@ -813,35 +859,6 @@ public:
const size_t last_known; ///< No. labels in last non-empty domain
};
- /// \brief Searches database for RRsets of one domain.
- ///
- /// This method scans RRs of single domain specified by name and
- /// extracts any RRsets found and requested by parameters.
- ///
- /// It is used internally by find(), because it is called multiple
- /// times (usually with different domains).
- ///
- /// \param name Which domain name should be scanned.
- /// \param types List of types the caller is interested in.
- /// \param check_ns If this is set to true, it checks nothing lives
- /// together with NS record (with few little exceptions, like RRSIG
- /// or NSEC). This check is meant for non-apex NS records.
- /// \param construct_name If this is NULL, the resulting RRsets have
- /// their name set to name. If it is not NULL, it overrides the name
- /// and uses this one (this can be used for wildcard synthesized
- /// records).
- /// \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
- /// part is map from RRtypes to RRsets of the corresponding types.
- /// If the RRset is not present in DB, the RRtype is not there at
- /// all (so you'll not find NULL pointer in the result).
- /// \throw DataSourceError If there's a low-level error with the
- /// database or the database contains bad data.
- FoundRRsets getRRsets(const std::string& name,
- const WantedTypes& types, bool check_ns,
- const std::string* construct_name = NULL);
-
/// \brief Find delegation point
///
/// Given a name, searches through the superdomains from the origin
@@ -908,6 +925,9 @@ public:
/// for ZoneFinder::FindOptions.
/// \param dresult Result of the search through the zone for a
/// delegation.
+ /// \param target If the type happens to be ANY, it will insert all
+ /// the RRsets of the found name (if any is found) here instead
+ /// of being returned by the result.
///
/// \return Tuple holding the result of the search - the RRset of the
/// wildcard records matching the name, together with a status
@@ -919,49 +939,54 @@ public:
FindResult findWildcardMatch(
const isc::dns::Name& name,
const isc::dns::RRType& type, const FindOptions options,
- const DelegationSearchResult& dresult);
+ const DelegationSearchResult& dresult,
+ std::vector<isc::dns::ConstRRsetPtr>* target);
- /// \brief Handle matching results for name
- ///
- /// This is called when something is found in the underlying database
- /// whose domain name is an exact match of the name to be searched for.
- /// It explores four possible cases to decide the final lookup result:
- /// - The name is a zone cut due to an NS RR.
- /// - CNAME is found (while the requested RR type is not CNAME).
- /// In this case multiple CNAMEs are checked and rejected with
- /// a \c DataSourceError exception.
- /// - Requested type is not found at that name.
- /// - A record of the requested type is found.
- /// and returns a corresponding find result.
- ///
- /// This method is commonly used for normal (non wildcard) and wildcard
- /// matches.
- ///
+ /// \brief Handle matching results for name
+ ///
+ /// This is called when something is found in the underlying database
+ /// whose domain name is an exact match of the name to be searched for.
+ /// It explores four possible cases to decide the final lookup result:
+ /// - The name is a zone cut due to an NS RR.
+ /// - CNAME is found (while the requested RR type is not CNAME).
+ /// In this case multiple CNAMEs are checked and rejected with
+ /// a \c DataSourceError exception.
+ /// - Requested type is not found at that name.
+ /// - A record of the requested type is found, or the query is ANY and
+ /// some records were found.
+ /// and returns a corresponding find result.
+ ///
+ /// This method is commonly used for normal (non wildcard) and wildcard
+ /// matches.
+ ///
/// \param name The name to find
/// \param type The RRType to find
/// \param options Options about how to search. See the documentation
/// for ZoneFinder::FindOptions.
- /// \param is_origin If name is the zone's origin name.
- /// \param found A set of found RRsets in the search for the name
- /// and type. It could contain one or more of the requested
- /// type, CNAME, NS, and NSEC RRsets of the name.
- /// \param wildname If non NULL, the method is called on a wildcard
- /// match, and points to a string object representing
- /// a textual form of the matched wildcard name;
- /// it's NULL in the case of non wildcard match.
- ///
+ /// \param is_origin If name is the zone's origin name.
+ /// \param found A set of found RRsets in the search for the name
+ /// and type. It could contain one or more of the requested
+ /// type, CNAME, NS, and NSEC RRsets of the name.
+ /// \param wildname If non NULL, the method is called on a wildcard
+ /// match, and points to a string object representing
+ /// a textual form of the matched wildcard name;
+ /// it's NULL in the case of non wildcard match.
+ /// \param target When the query is any, this must be set to a vector
+ /// where the result will be stored.
+ ///
/// \return Tuple holding the result of the search - the RRset of the
/// wildcard records matching the name, together with a status
- /// indicating the match type (corresponding to the each of
- /// the above 4 cases). The return value is intended to be
- /// usable as a return value of the caller of this helper
- /// method.
+ /// indicating the match type (corresponding to the each of
+ /// the above 4 cases). The return value is intended to be
+ /// usable as a return value of the caller of this helper
+ /// method.
FindResult findOnNameResult(const isc::dns::Name& name,
const isc::dns::RRType& type,
const FindOptions options,
const bool is_origin,
const FoundRRsets& found,
- const std::string* wildname);
+ const std::string* wildname,
+ std::vector<isc::dns::ConstRRsetPtr>* target);
/// \brief Handle no match for name
///
@@ -983,6 +1008,9 @@ public:
/// for ZoneFinder::FindOptions.
/// \param dresult Result of the search through the zone for a
/// delegation.
+ /// \param target If the query is for type ANY, the successfull result,
+ /// if there happens to be one, will be returned through the
+ /// parameter, as it doesn't fit into the result.
///
/// \return Tuple holding the result of the search - the RRset of the
/// wildcard records matching the name, together with a status
@@ -992,17 +1020,19 @@ public:
FindResult findNoNameResult(const isc::dns::Name& name,
const isc::dns::RRType& type,
FindOptions options,
- const DelegationSearchResult& dresult);
+ const DelegationSearchResult& dresult,
+ std::vector<isc::dns::ConstRRsetPtr>*
+ target);
/// Logs condition and creates result
///
/// A convenience function used by findOnNameResult(), it both creates
- /// the FindResult object that find() will return to its caller as well
+ /// the FindResult object that find() will return to its caller as well
/// as logging a debug message for the information being returned.
///
/// \param name Domain name of the RR that was being sought.
/// \param wildname Domain name string of a matched wildcard name or
- /// NULL for non wildcard match.
+ /// NULL for non wildcard match.
/// \param type Type of RR being sought.
/// \param code Result of the find operation
/// \param rrset RRset found as a result of the find (which may be
diff --git a/src/lib/datasrc/datasrc_messages.mes b/src/lib/datasrc/datasrc_messages.mes
index 01fb082..fd46896 100644
--- a/src/lib/datasrc/datasrc_messages.mes
+++ b/src/lib/datasrc/datasrc_messages.mes
@@ -78,6 +78,10 @@ different TTL values. This isn't allowed on the wire and is considered
an error, so we set it to the lowest value we found (but we don't modify the
database). The data in database should be checked and fixed.
+% DATASRC_DATABASE_FOUND_ANY search in datasource %1 resulted in returning all records of %2
+The data returned by the database backend contained data for the given domain
+name, so all the RRsets of the domain are returned.
+
% DATASRC_DATABASE_FOUND_CNAME search in datasource %1 for %2/%3/%4 found CNAME, resulting in %5
When searching the domain for a name a CNAME was found at that name.
Even though it was not the RR type being sought, it is returned. (The
@@ -178,6 +182,11 @@ whether the data is still valid. The zone name, its class, and the
underlying database name as well as the error message thrown from the
database module are shown in the log message.
+% DATASRC_DATABASE_WILDCARD_ANY search in datasource %1 resulted in wildcard match type ANY on %2
+The database doesn't contain directly matching name. When searching
+for a wildcard match, a wildcard record matching the name of the query
+containing some RRsets was found. All the RRsets of the node are returned.
+
% DATASRC_DATABASE_WILDCARD_CANCEL_NS canceled wildcard match on %3 because %2 contains NS (data source %1)
The database was queried to provide glue data and it didn't find direct match.
It could create it from given wildcard, but matching wildcards is forbidden
diff --git a/src/lib/datasrc/memory_datasrc.cc b/src/lib/datasrc/memory_datasrc.cc
index a79ee5b..d09eb6d 100644
--- a/src/lib/datasrc/memory_datasrc.cc
+++ b/src/lib/datasrc/memory_datasrc.cc
@@ -422,7 +422,8 @@ struct InMemoryZoneFinder::InMemoryZoneFinderImpl {
// Implementation of InMemoryZoneFinder::find
FindResult find(const Name& name, RRType type,
- RRsetList* target, const FindOptions options) const
+ std::vector<ConstRRsetPtr> *target,
+ const FindOptions options) const
{
LOG_DEBUG(logger, DBG_TRACE_BASIC, DATASRC_MEM_FIND).arg(name).
arg(type);
@@ -572,9 +573,7 @@ struct InMemoryZoneFinder::InMemoryZoneFinderImpl {
for (found = node->getData()->begin();
found != node->getData()->end(); ++found)
{
- target->addRRset(
- boost::const_pointer_cast<RRset>(prepareRRset(name,
- found->second, rename)));
+ target->push_back(prepareRRset(name, found->second, rename));
}
LOG_DEBUG(logger, DBG_TRACE_DATA, DATASRC_MEM_ANY_SUCCESS).
arg(name);
@@ -629,9 +628,17 @@ InMemoryZoneFinder::getClass() const {
ZoneFinder::FindResult
InMemoryZoneFinder::find(const Name& name, const RRType& type,
- RRsetList* target, const FindOptions options)
+ const FindOptions options)
+{
+ return (impl_->find(name, type, NULL, options));
+}
+
+ZoneFinder::FindResult
+InMemoryZoneFinder::findAll(const Name& name,
+ std::vector<ConstRRsetPtr>& target,
+ const FindOptions options)
{
- return (impl_->find(name, type, target, options));
+ return (impl_->find(name, RRType::ANY(), &target, options));
}
result::Result
diff --git a/src/lib/datasrc/memory_datasrc.h b/src/lib/datasrc/memory_datasrc.h
index b852eb3..32cf518 100644
--- a/src/lib/datasrc/memory_datasrc.h
+++ b/src/lib/datasrc/memory_datasrc.h
@@ -69,14 +69,20 @@ public:
///
/// See documentation in \c Zone.
///
- /// It returns NULL pointer in case of NXDOMAIN and NXRRSET,
- /// and also SUCCESS if target is not NULL(TYPE_ANY query).
- /// (the base class documentation does not seem to require that).
+ /// It returns NULL pointer in case of NXDOMAIN and NXRRSET.
virtual FindResult find(const isc::dns::Name& name,
const isc::dns::RRType& type,
- isc::dns::RRsetList* target = NULL,
const FindOptions options = FIND_DEFAULT);
+ /// \brief Version of find that returns all types at once
+ ///
+ /// It acts the same as find, just that when the correct node is found,
+ /// all the RRsets are filled into the target parameter instead of being
+ /// returned by the result.
+ virtual FindResult findAll(const isc::dns::Name& name,
+ std::vector<isc::dns::ConstRRsetPtr>& target,
+ const FindOptions options = FIND_DEFAULT);
+
/// \brief Imelementation of the ZoneFinder::findPreviousName method
///
/// This one throws NotImplemented exception, as InMemory doesn't
diff --git a/src/lib/datasrc/tests/database_unittest.cc b/src/lib/datasrc/tests/database_unittest.cc
index 01c16f3..4ade8a1 100644
--- a/src/lib/datasrc/tests/database_unittest.cc
+++ b/src/lib/datasrc/tests/database_unittest.cc
@@ -1419,8 +1419,7 @@ doFindTest(ZoneFinder& finder,
const ZoneFinder::FindOptions options = ZoneFinder::FIND_DEFAULT)
{
SCOPED_TRACE("doFindTest " + name.toText() + " " + type.toText());
- const ZoneFinder::FindResult result = finder.find(name, type, NULL,
- options);
+ const ZoneFinder::FindResult result = finder.find(name, type, options);
ASSERT_EQ(expected_result, result.code) << name << " " << type;
if (!expected_rdatas.empty() && result.rrset) {
checkRRset(result.rrset, expected_name != Name(".") ? expected_name :
@@ -1444,6 +1443,39 @@ doFindTest(ZoneFinder& finder,
}
}
+void
+doFindAllTestResult(ZoneFinder& finder, const isc::dns::Name& name,
+ ZoneFinder::Result expected_result,
+ const isc::dns::RRType expected_type,
+ std::vector<std::string> expected_rdata,
+ const isc::dns::Name& expected_name =
+ isc::dns::Name::ROOT_NAME(),
+ const ZoneFinder::FindOptions options =
+ ZoneFinder::FIND_DEFAULT)
+{
+ SCOPED_TRACE("All test for " + name.toText());
+ std::vector<ConstRRsetPtr> target;
+ ZoneFinder::FindResult result(finder.findAll(name, target, options));
+ EXPECT_TRUE(target.empty());
+ EXPECT_EQ(expected_result, result.code);
+ EXPECT_EQ(expected_type, result.rrset->getType());
+ RdataIteratorPtr it(result.rrset->getRdataIterator());
+ std::vector<std::string> rdata;
+ while (!it->isLast()) {
+ rdata.push_back(it->getCurrent().toText());
+ it->next();
+ }
+ std::sort(rdata.begin(), rdata.end());
+ std::sort(expected_rdata.begin(), expected_rdata.end());
+ ASSERT_EQ(expected_rdata.size(), rdata.size());
+ for (size_t i(0); i < expected_rdata.size(); ++ i) {
+ EXPECT_EQ(expected_rdata[i], rdata[i]);
+ }
+ EXPECT_TRUE(expected_rdata == rdata);
+ EXPECT_EQ(expected_name == isc::dns::Name::ROOT_NAME() ? name :
+ expected_name, result.rrset->getName());
+}
+
// When asking for an RRset where RRs somehow have different TTLs, it should
// convert to the lowest one.
TEST_F(MockDatabaseClientTest, ttldiff) {
@@ -1670,58 +1702,58 @@ TYPED_TEST(DatabaseClientTest, find) {
EXPECT_THROW(finder->find(isc::dns::Name("badcname1.example.org."),
this->qtype_,
- NULL, ZoneFinder::FIND_DEFAULT),
+ ZoneFinder::FIND_DEFAULT),
DataSourceError);
EXPECT_THROW(finder->find(isc::dns::Name("badcname2.example.org."),
this->qtype_,
- NULL, ZoneFinder::FIND_DEFAULT),
+ ZoneFinder::FIND_DEFAULT),
DataSourceError);
EXPECT_THROW(finder->find(isc::dns::Name("badcname3.example.org."),
this->qtype_,
- NULL, ZoneFinder::FIND_DEFAULT),
+ ZoneFinder::FIND_DEFAULT),
DataSourceError);
EXPECT_THROW(finder->find(isc::dns::Name("badrdata.example.org."),
this->qtype_,
- NULL, ZoneFinder::FIND_DEFAULT),
+ ZoneFinder::FIND_DEFAULT),
DataSourceError);
EXPECT_THROW(finder->find(isc::dns::Name("badtype.example.org."),
this->qtype_,
- NULL, ZoneFinder::FIND_DEFAULT),
+ ZoneFinder::FIND_DEFAULT),
DataSourceError);
EXPECT_THROW(finder->find(isc::dns::Name("badttl.example.org."),
this->qtype_,
- NULL, ZoneFinder::FIND_DEFAULT),
+ ZoneFinder::FIND_DEFAULT),
DataSourceError);
EXPECT_THROW(finder->find(isc::dns::Name("badsig.example.org."),
this->qtype_,
- NULL, ZoneFinder::FIND_DEFAULT),
+ ZoneFinder::FIND_DEFAULT),
DataSourceError);
// Trigger the hardcoded exceptions and see if find() has cleaned up
if (this->is_mock_) {
EXPECT_THROW(finder->find(isc::dns::Name("dsexception.in.search."),
this->qtype_,
- NULL, ZoneFinder::FIND_DEFAULT),
+ ZoneFinder::FIND_DEFAULT),
DataSourceError);
EXPECT_THROW(finder->find(isc::dns::Name("iscexception.in.search."),
this->qtype_,
- NULL, ZoneFinder::FIND_DEFAULT),
+ ZoneFinder::FIND_DEFAULT),
isc::Exception);
EXPECT_THROW(finder->find(isc::dns::Name("basicexception.in.search."),
this->qtype_,
- NULL, ZoneFinder::FIND_DEFAULT),
+ ZoneFinder::FIND_DEFAULT),
std::exception);
EXPECT_THROW(finder->find(isc::dns::Name("dsexception.in.getnext."),
this->qtype_,
- NULL, ZoneFinder::FIND_DEFAULT),
+ ZoneFinder::FIND_DEFAULT),
DataSourceError);
EXPECT_THROW(finder->find(isc::dns::Name("iscexception.in.getnext."),
this->qtype_,
- NULL, ZoneFinder::FIND_DEFAULT),
+ ZoneFinder::FIND_DEFAULT),
isc::Exception);
EXPECT_THROW(finder->find(isc::dns::Name("basicexception.in.getnext."),
this->qtype_,
- NULL, ZoneFinder::FIND_DEFAULT),
+ ZoneFinder::FIND_DEFAULT),
std::exception);
}
@@ -1840,17 +1872,17 @@ TYPED_TEST(DatabaseClientTest, findDelegation) {
// This is broken dname, it contains two targets
EXPECT_THROW(finder->find(isc::dns::Name("below.baddname.example.org."),
- this->qtype_, NULL,
+ this->qtype_,
ZoneFinder::FIND_DEFAULT),
DataSourceError);
// Broken NS - it lives together with something else
EXPECT_THROW(finder->find(isc::dns::Name("brokenns1.example.org."),
- this->qtype_, NULL,
+ this->qtype_,
ZoneFinder::FIND_DEFAULT),
DataSourceError);
EXPECT_THROW(finder->find(isc::dns::Name("brokenns2.example.org."),
- this->qtype_, NULL,
+ this->qtype_,
ZoneFinder::FIND_DEFAULT),
DataSourceError);
}
@@ -2255,6 +2287,100 @@ TYPED_TEST(DatabaseClientTest, emptyNonterminalNSEC) {
Name::ROOT_NAME(), ZoneFinder::FIND_DNSSEC));
}
+TYPED_TEST(DatabaseClientTest, anyFromFind) {
+ // Find will reject answering an ANY query
+ EXPECT_THROW(this->getFinder()->find(isc::dns::Name("www2.example.org."),
+ RRType::ANY()), isc::Unexpected);
+}
+
+// Test the findAll method.
+TYPED_TEST(DatabaseClientTest, getAll) {
+ // The domain doesn't exist, so we must get the right NSEC
+ boost::shared_ptr<DatabaseClient::Finder> finder(this->getFinder());
+
+ // It should act the same on the "failures"
+ std::vector<ConstRRsetPtr> target;
+ EXPECT_EQ(ZoneFinder::NXDOMAIN,
+ finder->findAll(isc::dns::Name("nothere.example.org."),
+ target).code);
+ EXPECT_TRUE(target.empty());
+ EXPECT_EQ(ZoneFinder::NXRRSET,
+ finder->findAll(isc::dns::Name("here.wild.example.org."),
+ target).code);
+ this->expected_rdatas_.push_back("ns.delegation.example.org.");
+ this->expected_rdatas_.push_back("ns.example.com.");
+ doFindAllTestResult(*finder, isc::dns::Name("xx.delegation.example.org."),
+ ZoneFinder::DELEGATION, RRType::NS(),
+ this->expected_rdatas_,
+ isc::dns::Name("delegation.example.org."));
+ this->expected_rdatas_.clear();
+ this->expected_rdatas_.push_back("www.example.org.");
+ doFindAllTestResult(*finder, isc::dns::Name("cname.example.org"),
+ ZoneFinder::CNAME, RRType::CNAME(),
+ this->expected_rdatas_);
+ this->expected_rdatas_.clear();
+ this->expected_rdatas_.push_back("dname.example.com.");
+ doFindAllTestResult(*finder, isc::dns::Name("a.dname.example.org"),
+ ZoneFinder::DNAME, RRType::DNAME(),
+ this->expected_rdatas_,
+ isc::dns::Name("dname.example.org."));
+ // It should get the data on success
+ EXPECT_EQ(ZoneFinder::SUCCESS,
+ finder->findAll(isc::dns::Name("www2.example.org."),
+ target).code);
+ ASSERT_EQ(2, target.size());
+ size_t a_idx(target[1]->getType() == RRType::A());
+ EXPECT_EQ(RRType::A(), target[a_idx]->getType());
+ std::string previous;
+ size_t count(0);
+ for (RdataIteratorPtr it(target[a_idx]->getRdataIterator());
+ !it->isLast(); it->next()) {
+ count ++;
+ EXPECT_NE(previous, it->getCurrent().toText());
+ EXPECT_TRUE(it->getCurrent().toText() == "192.0.2.1" ||
+ it->getCurrent().toText() == "192.0.2.2");
+ previous = it->getCurrent().toText();
+ }
+ EXPECT_EQ(2, count);
+ EXPECT_EQ(RRType::AAAA(), target[1 - a_idx]->getType());
+ RdataIteratorPtr it(target[1 - a_idx]->getRdataIterator());
+ ASSERT_FALSE(it->isLast());
+ EXPECT_EQ("2001:db8::1", it->getCurrent().toText());
+ it->next();
+ EXPECT_TRUE(it->isLast());
+
+ // And on wildcard. Check the signatures as well.
+ target.clear();
+ EXPECT_EQ(ZoneFinder::WILDCARD,
+ finder->findAll(isc::dns::Name("a.wild.example.org"),
+ target, ZoneFinder::FIND_DNSSEC).code);
+ ASSERT_EQ(2, target.size());
+ a_idx = target[1]->getType() == RRType::A();
+ EXPECT_EQ(RRType::A(), target[a_idx]->getType());
+ it = target[a_idx]->getRdataIterator();
+ ASSERT_FALSE(it->isLast());
+ EXPECT_EQ("192.0.2.5", it->getCurrent().toText());
+ it->next();
+ EXPECT_TRUE(it->isLast());
+ ConstRRsetPtr sig(target[a_idx]->getRRsig());
+ ASSERT_TRUE(sig);
+ EXPECT_EQ(RRType::RRSIG(), sig->getType());
+ EXPECT_EQ("A 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE",
+ sig->getRdataIterator()->getCurrent().toText());
+ EXPECT_EQ(RRType::NSEC(), target[1 - a_idx]->getType());
+ it = target[1 - a_idx]->getRdataIterator();
+ ASSERT_FALSE(it->isLast());
+ EXPECT_EQ("cancel.here.wild.example.org. A RRSIG NSEC",
+ it->getCurrent().toText());
+ it->next();
+ EXPECT_TRUE(it->isLast());
+ sig = target[1 - a_idx]->getRRsig();
+ ASSERT_TRUE(sig);
+ EXPECT_EQ(RRType::RRSIG(), sig->getType());
+ EXPECT_EQ("NSEC 5 3 3600 20000101000000 20000201000000 12345 example.org. FAKEFAKEFAKE",
+ sig->getRdataIterator()->getCurrent().toText());
+}
+
TYPED_TEST(DatabaseClientTest, getOrigin) {
DataSourceClient::FindResult
zone(this->client_->findZone(Name("example.org")));
diff --git a/src/lib/datasrc/tests/memory_datasrc_unittest.cc b/src/lib/datasrc/tests/memory_datasrc_unittest.cc
index 01d3230..8a5a8db 100644
--- a/src/lib/datasrc/tests/memory_datasrc_unittest.cc
+++ b/src/lib/datasrc/tests/memory_datasrc_unittest.cc
@@ -16,6 +16,7 @@
#include <vector>
#include <boost/bind.hpp>
+#include <boost/foreach.hpp>
#include <exceptions/exceptions.h>
@@ -389,7 +390,6 @@ public:
ZoneFinder::Result result,
bool check_answer = true,
const ConstRRsetPtr& answer = ConstRRsetPtr(),
- RRsetList* target = NULL,
InMemoryZoneFinder* zone_finder = NULL,
ZoneFinder::FindOptions options = ZoneFinder::FIND_DEFAULT,
bool check_wild_answer = false)
@@ -402,7 +402,7 @@ public:
EXPECT_NO_THROW({
ZoneFinder::FindResult find_result(zone_finder->find(
name, rrtype,
- target, options));
+ options));
// Check it returns correct answers
EXPECT_EQ(result, find_result.code);
if (check_answer) {
@@ -438,6 +438,32 @@ public:
}
});
}
+ /**
+ * \brief Calls the findAll on the finder and checks the result.
+ */
+ std::vector<ConstRRsetPtr> findAllTest(const Name& name,
+ ZoneFinder::Result result,
+ size_t expected_size,
+ InMemoryZoneFinder* finder = NULL,
+ const ConstRRsetPtr &rrset_result =
+ ConstRRsetPtr(),
+ ZoneFinder::FindOptions options =
+ ZoneFinder::FIND_DEFAULT)
+ {
+ if (finder == NULL) {
+ finder = &zone_finder_;
+ }
+ std::vector<ConstRRsetPtr> target;
+ ZoneFinder::FindResult findResult(finder->findAll(name, target,
+ options));
+ EXPECT_EQ(result, findResult.code);
+ EXPECT_EQ(rrset_result, findResult.rrset);
+ BOOST_FOREACH(const ConstRRsetPtr& rrset, target) {
+ EXPECT_EQ(name, rrset->getName());
+ }
+ EXPECT_EQ(expected_size, target.size());
+ return (target);
+ }
// Internal part of the cancelWildcard test that is multiple times
void doCancelWildcardTest();
};
@@ -522,7 +548,7 @@ TEST_F(InMemoryZoneFinderTest, findCNAMEUnderZoneCut) {
RRTTL(300)));
EXPECT_EQ(SUCCESS, zone_finder_.add(rr_cname_under_cut_));
findTest(Name("cname.child.example.org"), RRType::AAAA(),
- ZoneFinder::CNAME, true, rr_cname_under_cut_, NULL, NULL,
+ ZoneFinder::CNAME, true, rr_cname_under_cut_, NULL,
ZoneFinder::FIND_GLUE_OK);
}
@@ -598,7 +624,7 @@ TEST_F(InMemoryZoneFinderTest, DNAMEUnderNS) {
findTest(lowName, RRType::A(), ZoneFinder::DELEGATION, true, rr_child_ns_);
findTest(lowName, RRType::A(), ZoneFinder::DNAME, true, rr_child_dname_,
- NULL, NULL, ZoneFinder::FIND_GLUE_OK);
+ NULL, ZoneFinder::FIND_GLUE_OK);
}
// Test adding child zones and zone cut handling
@@ -636,25 +662,19 @@ TEST_F(InMemoryZoneFinderTest, findAny) {
EXPECT_NO_THROW(EXPECT_EQ(SUCCESS, zone_finder_.add(rr_child_glue_)));
// origin
- RRsetList origin_rrsets;
- findTest(origin_, RRType::ANY(), ZoneFinder::SUCCESS, true,
- ConstRRsetPtr(), &origin_rrsets);
- EXPECT_EQ(2, origin_rrsets.size());
- EXPECT_EQ(rr_a_, origin_rrsets.findRRset(RRType::A(), RRClass::IN()));
- EXPECT_EQ(rr_ns_, origin_rrsets.findRRset(RRType::NS(), RRClass::IN()));
+ std::vector<ConstRRsetPtr> rrsets(findAllTest(origin_, ZoneFinder::SUCCESS,
+ 2));
+ EXPECT_FALSE(rrsets.end() == std::find(rrsets.begin(), rrsets.end(),
+ rr_a_));
+ EXPECT_FALSE(rrsets.end() == std::find(rrsets.begin(), rrsets.end(),
+ rr_ns_));
// out zone name
- RRsetList out_rrsets;
- findTest(Name("example.com"), RRType::ANY(), ZoneFinder::NXDOMAIN, true,
- ConstRRsetPtr(), &out_rrsets);
- EXPECT_EQ(0, out_rrsets.size());
-
- RRsetList glue_child_rrsets;
- findTest(rr_child_glue_->getName(), RRType::ANY(), ZoneFinder::SUCCESS,
- true, ConstRRsetPtr(), &glue_child_rrsets);
- EXPECT_EQ(rr_child_glue_, glue_child_rrsets.findRRset(RRType::A(),
- RRClass::IN()));
- EXPECT_EQ(1, glue_child_rrsets.size());
+ findAllTest(Name("example.com"), ZoneFinder::NXDOMAIN, 0);
+
+ rrsets = findAllTest(rr_child_glue_->getName(), ZoneFinder::SUCCESS, 1);
+ EXPECT_FALSE(rrsets.end() == std::find(rrsets.begin(), rrsets.end(),
+ rr_child_glue_));
// TODO: test NXRRSET case after rbtree non-terminal logic has
// been implemented
@@ -663,16 +683,12 @@ TEST_F(InMemoryZoneFinderTest, findAny) {
EXPECT_NO_THROW(EXPECT_EQ(SUCCESS, zone_finder_.add(rr_child_ns_)));
// zone cut
- RRsetList child_rrsets;
- findTest(rr_child_ns_->getName(), RRType::ANY(), ZoneFinder::DELEGATION,
- true, rr_child_ns_, &child_rrsets);
- EXPECT_EQ(0, child_rrsets.size());
+ findAllTest(rr_child_ns_->getName(), ZoneFinder::DELEGATION, 0, NULL,
+ rr_child_ns_);
// glue for this zone cut
- RRsetList new_glue_child_rrsets;
- findTest(rr_child_glue_->getName(), RRType::ANY(), ZoneFinder::DELEGATION,
- true, rr_child_ns_, &new_glue_child_rrsets);
- EXPECT_EQ(0, new_glue_child_rrsets.size());
+ findAllTest(rr_child_glue_->getName(),ZoneFinder::DELEGATION, 0, NULL,
+ rr_child_ns_);
}
TEST_F(InMemoryZoneFinderTest, glue) {
@@ -693,26 +709,26 @@ TEST_F(InMemoryZoneFinderTest, glue) {
// 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_, NULL, NULL, ZoneFinder::FIND_GLUE_OK);
+ rr_child_glue_, NULL, ZoneFinder::FIND_GLUE_OK);
// glue OK + NXRRSET case
findTest(rr_child_glue_->getName(), RRType::AAAA(), ZoneFinder::NXRRSET,
- true, ConstRRsetPtr(), NULL, NULL, ZoneFinder::FIND_GLUE_OK);
+ true, ConstRRsetPtr(), NULL, ZoneFinder::FIND_GLUE_OK);
// glue OK + NXDOMAIN case
findTest(Name("www.child.example.org"), RRType::A(),
- ZoneFinder::DELEGATION, true, rr_child_ns_, NULL, NULL,
+ ZoneFinder::DELEGATION, true, rr_child_ns_, NULL,
ZoneFinder::FIND_GLUE_OK);
// nested cut case. The glue should be found.
findTest(rr_grandchild_glue_->getName(), RRType::AAAA(),
ZoneFinder::SUCCESS,
- true, rr_grandchild_glue_, NULL, NULL, ZoneFinder::FIND_GLUE_OK);
+ true, rr_grandchild_glue_, NULL, ZoneFinder::FIND_GLUE_OK);
// A non-existent name in nested cut. This should result in delegation
// at the highest zone cut.
findTest(Name("www.grand.child.example.org"), RRType::TXT(),
- ZoneFinder::DELEGATION, true, rr_child_ns_, NULL, NULL,
+ ZoneFinder::DELEGATION, true, rr_child_ns_, NULL,
ZoneFinder::FIND_GLUE_OK);
}
@@ -801,14 +817,14 @@ TEST_F(InMemoryZoneFinderTest, load) {
// Now see there are some rrsets (we don't look inside, though)
findTest(Name("."), RRType::SOA(), ZoneFinder::SUCCESS, false,
- ConstRRsetPtr(), NULL, &rootzone);
+ ConstRRsetPtr(), &rootzone);
findTest(Name("."), RRType::NS(), ZoneFinder::SUCCESS, false,
- ConstRRsetPtr(), NULL, &rootzone);
+ ConstRRsetPtr(), &rootzone);
findTest(Name("a.root-servers.net."), RRType::A(), ZoneFinder::SUCCESS,
- false, ConstRRsetPtr(), NULL, &rootzone);
+ false, ConstRRsetPtr(), &rootzone);
// But this should no longer be here
findTest(rr_ns_a_->getName(), RRType::AAAA(), ZoneFinder::NXDOMAIN, true,
- ConstRRsetPtr(), NULL, &rootzone);
+ ConstRRsetPtr(), &rootzone);
// Try loading zone that is wrong in a different way
EXPECT_THROW(zone_finder_.load(TEST_DATA_DIR "/duplicate_rrset.zone"),
@@ -846,14 +862,14 @@ TEST_F(InMemoryZoneFinderTest, wildcard) {
{
SCOPED_TRACE("Search at created child");
findTest(Name("a.wild.example.org"), RRType::A(), ZoneFinder::SUCCESS,
- false, rr_wild_, NULL, NULL, ZoneFinder::FIND_DEFAULT, true);
+ false, rr_wild_, NULL, ZoneFinder::FIND_DEFAULT, true);
}
// Search another created name, this time little bit lower
{
SCOPED_TRACE("Search at created grand-child");
findTest(Name("a.b.wild.example.org"), RRType::A(),
- ZoneFinder::SUCCESS, false, rr_wild_, NULL, NULL,
+ ZoneFinder::SUCCESS, false, rr_wild_, NULL,
ZoneFinder::FIND_DEFAULT, true);
}
@@ -885,7 +901,7 @@ TEST_F(InMemoryZoneFinderTest, delegatedWildcard) {
{
SCOPED_TRACE("Looking under delegation point in GLUE_OK mode");
findTest(Name("a.child.example.org"), RRType::A(),
- ZoneFinder::DELEGATION, true, rr_child_ns_, NULL, NULL,
+ ZoneFinder::DELEGATION, true, rr_child_ns_, NULL,
ZoneFinder::FIND_GLUE_OK);
}
}
@@ -897,9 +913,9 @@ TEST_F(InMemoryZoneFinderTest, anyWildcard) {
// First try directly the name (normal match)
{
SCOPED_TRACE("Asking direcly for *");
- RRsetList target;
- findTest(Name("*.wild.example.org"), RRType::ANY(),
- ZoneFinder::SUCCESS, true, ConstRRsetPtr(), &target);
+ const std::vector<ConstRRsetPtr>
+ target(findAllTest(Name("*.wild.example.org"), ZoneFinder::SUCCESS,
+ 1));
ASSERT_EQ(1, target.size());
EXPECT_EQ(RRType::A(), (*target.begin())->getType());
EXPECT_EQ(Name("*.wild.example.org"), (*target.begin())->getName());
@@ -908,10 +924,9 @@ TEST_F(InMemoryZoneFinderTest, anyWildcard) {
// Then a wildcard match
{
SCOPED_TRACE("Asking in the wild way");
- RRsetList target;
- findTest(Name("a.wild.example.org"), RRType::ANY(),
- ZoneFinder::SUCCESS, true, ConstRRsetPtr(), &target);
- ASSERT_EQ(1, target.size());
+ const std::vector<ConstRRsetPtr>
+ target(findAllTest(Name("a.wild.example.org"), ZoneFinder::SUCCESS,
+ 1));
EXPECT_EQ(RRType::A(), (*target.begin())->getType());
EXPECT_EQ(Name("a.wild.example.org"), (*target.begin())->getName());
}
@@ -943,15 +958,9 @@ TEST_F(InMemoryZoneFinderTest, emptyWildcard) {
{
SCOPED_TRACE("Asking for ANY record");
- RRsetList normalTarget;
- findTest(Name("*.foo.example.org"), RRType::ANY(), ZoneFinder::NXRRSET,
- true, ConstRRsetPtr(), &normalTarget);
- EXPECT_EQ(0, normalTarget.size());
-
- RRsetList wildTarget;
- findTest(Name("a.foo.example.org"), RRType::ANY(),
- ZoneFinder::NXRRSET, true, ConstRRsetPtr(), &wildTarget);
- EXPECT_EQ(0, wildTarget.size());
+ findAllTest(Name("*.foo.example.org"), ZoneFinder::NXRRSET, 0);
+
+ findAllTest(Name("a.foo.example.org"), ZoneFinder::NXRRSET, 0);
}
{
@@ -1011,10 +1020,7 @@ TEST_F(InMemoryZoneFinderTest, nestedEmptyWildcard) {
for (const char** name = names; *name != NULL; ++ name) {
SCOPED_TRACE(string("Node ") + *name);
- RRsetList target;
- findTest(Name(*name), RRType::ANY(), ZoneFinder::NXRRSET, true,
- ConstRRsetPtr(), &target);
- EXPECT_EQ(0, target.size());
+ findAllTest(Name(*name), ZoneFinder::NXRRSET, 0);
}
}
}
@@ -1054,7 +1060,7 @@ InMemoryZoneFinderTest::doCancelWildcardTest() {
SCOPED_TRACE(string("Node ") + *name);
findTest(Name(*name), RRType::A(), ZoneFinder::SUCCESS, false,
- rr_wild_, NULL, NULL, ZoneFinder::FIND_DEFAULT, true);
+ rr_wild_, NULL, ZoneFinder::FIND_DEFAULT, true);
}
}
@@ -1125,13 +1131,13 @@ TEST_F(InMemoryZoneFinderTest, swap) {
EXPECT_EQ(RRClass::IN(), finder2.getClass());
// make sure the zone data is swapped, too
findTest(origin_, RRType::NS(), ZoneFinder::NXDOMAIN, false,
- ConstRRsetPtr(), NULL, &finder1);
+ ConstRRsetPtr(), &finder1);
findTest(other_origin, RRType::TXT(), ZoneFinder::SUCCESS, false,
- ConstRRsetPtr(), NULL, &finder1);
+ ConstRRsetPtr(), &finder1);
findTest(origin_, RRType::NS(), ZoneFinder::SUCCESS, false,
- ConstRRsetPtr(), NULL, &finder2);
+ ConstRRsetPtr(), &finder2);
findTest(other_origin, RRType::TXT(), ZoneFinder::NXDOMAIN, false,
- ConstRRsetPtr(), NULL, &finder2);
+ ConstRRsetPtr(), &finder2);
}
TEST_F(InMemoryZoneFinderTest, getFileName) {
diff --git a/src/lib/datasrc/zone.h b/src/lib/datasrc/zone.h
index e028bea..77e1148 100644
--- a/src/lib/datasrc/zone.h
+++ b/src/lib/datasrc/zone.h
@@ -237,9 +237,6 @@ public:
/// a successful match, and the code of \c SUCCESS will be returned.
/// - If the search name matches a delegation point of DNAME, it returns
/// the code of \c DNAME and that DNAME RR.
- /// - If the target isn't NULL, all RRsets under the domain are inserted
- /// there and SUCCESS (or NXDOMAIN, in case of empty domain) is returned
- /// instead of normall processing. This is intended to handle ANY query.
///
/// \note This behavior is controversial as we discussed in
/// https://lists.isc.org/pipermail/bind10-dev/2011-January/001918.html
@@ -276,16 +273,33 @@ public:
///
/// \param name The domain name to be searched for.
/// \param type The RR type to be searched for.
- /// \param target If target is not NULL, insert all RRs under the domain
- /// into it.
/// \param options The search options.
/// \return A \c FindResult object enclosing the search result (see above).
virtual FindResult find(const isc::dns::Name& name,
const isc::dns::RRType& type,
- isc::dns::RRsetList* target = NULL,
const FindOptions options
= FIND_DEFAULT) = 0;
+ ///
+ /// \brief Finds all RRsets in the given name.
+ ///
+ /// This function works almost exactly in the same way as the find one. The
+ /// only difference is, when the lookup is successful (eg. the code is
+ /// SUCCESS or WILDCARD), all the RRsets residing in the named node are
+ /// copied into the \c target parameter and the rrset member of the result
+ /// is NULL. All the other (unsuccessful) cases are handled the same,
+ /// including returning delegations, NSEC/NSEC3 proofs, etc. The options
+ /// parameter works the same way and it should conform to the same exception
+ /// restrictions.
+ ///
+ /// \param name \see find, parameter name
+ /// \param target the successfull result is returned through this
+ /// \param options \see find, parameter options
+ /// \return \see find and it's result
+ virtual FindResult findAll(const isc::dns::Name& name,
+ std::vector<isc::dns::ConstRRsetPtr> &target,
+ const FindOptions options = FIND_DEFAULT) = 0;
+
/// \brief Get previous name in the zone
///
/// Gets the previous name in the DNSSEC order. This can be used
diff --git a/src/lib/python/isc/datasrc/finder_python.cc b/src/lib/python/isc/datasrc/finder_python.cc
index 7f74133..5aa9c3e 100644
--- a/src/lib/python/isc/datasrc/finder_python.cc
+++ b/src/lib/python/isc/datasrc/finder_python.cc
@@ -74,7 +74,7 @@ PyObject* ZoneFinder_helper(ZoneFinder* finder, PyObject* args) {
static_cast<ZoneFinder::FindOptions>(options_int);
const ZoneFinder::FindResult find_result(
finder->find(PyName_ToName(name), PyRRType_ToRRType(rrtype),
- NULL, options));
+ options));
const ZoneFinder::Result r = find_result.code;
isc::dns::ConstRRsetPtr rrsp = find_result.rrset;
if (rrsp) {
More information about the bind10-changes
mailing list