mirror of
https://gitlab.isc.org/isc-projects/kea
synced 2025-08-30 21:45:37 +00:00
Merge #1483
This commit is contained in:
@@ -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.
|
||||
*/
|
||||
// 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(ConstRRsetPtr rrset, target) {
|
||||
response_.addRRset(Message::SECTION_ANSWER,
|
||||
boost::const_pointer_cast<RRset>(rrset), dnssec_);
|
||||
// Handle additional for answer section
|
||||
addAdditional(*result.zone_finder, *rrset.get());
|
||||
}
|
||||
} else {
|
||||
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 {
|
||||
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);
|
||||
}
|
||||
// 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_);
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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.
|
||||
@@ -304,9 +306,30 @@ substituteWild(const RRset& wild_rrset, const Name& real_name) {
|
||||
return (rrset);
|
||||
}
|
||||
|
||||
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()) {
|
||||
|
@@ -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);
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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, target, 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, RRType::ANY(), &target, options));
|
||||
}
|
||||
|
||||
result::Result
|
||||
|
@@ -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
|
||||
|
@@ -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")));
|
||||
|
@@ -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());
|
||||
findAllTest(Name("example.com"), ZoneFinder::NXDOMAIN, 0);
|
||||
|
||||
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());
|
||||
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());
|
||||
findAllTest(Name("*.foo.example.org"), ZoneFinder::NXRRSET, 0);
|
||||
|
||||
RRsetList wildTarget;
|
||||
findTest(Name("a.foo.example.org"), RRType::ANY(),
|
||||
ZoneFinder::NXRRSET, true, ConstRRsetPtr(), &wildTarget);
|
||||
EXPECT_EQ(0, wildTarget.size());
|
||||
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) {
|
||||
|
@@ -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
|
||||
|
@@ -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) {
|
||||
|
Reference in New Issue
Block a user