Commit 86233a20 authored by Michal 'vorner' Vaner's avatar Michal 'vorner' Vaner
Browse files

[2378] Fix InMemory iterator

Not directly related, but it breaks tests of the ZoneLoader. The NSEC3
namespace and all RRSIGs were missing from the returned data.
parent 62df1d46
......@@ -209,14 +209,20 @@ private:
RdataIteratorPtr rdata_iterator_;
bool separate_rrs_;
bool ready_;
bool examined_rrsigs_;
// In case there's nsec3 namespace in the zone, it is represented the same
// way as the usual namespace. So we reuse the iterator implementation for
// it.
ZoneIteratorPtr nsec3_namespace_;
public:
MemoryIterator(const RRClass& rrclass,
const ZoneTree& tree, const Name& origin,
bool separate_rrs) :
const ZoneTree& tree, const NSEC3Data* nsec3_data,
const Name& origin, bool separate_rrs) :
rrclass_(rrclass),
tree_(tree),
separate_rrs_(separate_rrs),
ready_(true)
ready_(true),
examined_rrsigs_(false)
{
// Find the first node (origin) and preserve the node chain for future
// searches
......@@ -235,10 +241,25 @@ public:
rdata_iterator_ = rrset_->getRdataIterator();
}
}
// If we have the NSEC3 namespace, get an iterator for it so we can
// delegate to it later.
if (nsec3_data != NULL) {
nsec3_namespace_ =
ZoneIteratorPtr(new MemoryIterator(rrclass,
nsec3_data->getNSEC3Tree(),
NULL, origin,
separate_rrs));
}
}
virtual ConstRRsetPtr getNextRRset() {
if (!ready_) {
// We are done iterating. But in case there's the nsec3 one,
// iterate through that one.
if (nsec3_namespace_ != ZoneIteratorPtr()) {
return (nsec3_namespace_->getNextRRset());
}
isc_throw(Unexpected, "Iterating past the zone end");
}
/*
......@@ -259,13 +280,19 @@ public:
rrset_.reset(new TreeNodeRRset(rrclass_,
node_, set_node_, true));
rdata_iterator_ = rrset_->getRdataIterator();
examined_rrsigs_ = false;
}
}
}
if (node_ == NULL) {
// That's all, folks
ready_ = false;
return (ConstRRsetPtr());
if (nsec3_namespace_ != ZoneIteratorPtr()) {
// In case we have the NSEC3 namespace, get one from there.
return (nsec3_namespace_->getNextRRset());
} else {
return (ConstRRsetPtr());
}
}
if (separate_rrs_) {
......@@ -273,10 +300,24 @@ public:
// 'current' rdata
RRsetPtr result(new RRset(rrset_->getName(),
rrset_->getClass(),
rrset_->getType(),
// If we are looking into the signature,
// we need to adjust the type too.
examined_rrsigs_ ? RRType::RRSIG() :
rrset_->getType(),
rrset_->getTTL()));
result->addRdata(rdata_iterator_->getCurrent());
rdata_iterator_->next();
if (!examined_rrsigs_ && rdata_iterator_->isLast()) {
// We got to the last RR of the RRset, but we need to look at
// the signatures too, if there are any.
examined_rrsigs_ = true;
const ConstRRsetPtr rrsig = rrset_->getRRsig();
if (rrsig != ConstRRsetPtr()) {
rrset_ = rrsig;
rdata_iterator_ = rrsig->getRdataIterator();
} // else - no RRSIG. rdata_iterator_ stays at last, next
// condition applies
}
if (rdata_iterator_->isLast()) {
// all used up, next.
set_node_ = set_node_->getNext();
......@@ -286,6 +327,7 @@ public:
rrset_.reset(new TreeNodeRRset(rrclass_,
node_, set_node_, true));
rdata_iterator_ = rrset_->getRdataIterator();
examined_rrsigs_ = false;
}
}
return (result);
......@@ -317,7 +359,8 @@ InMemoryClient::getIterator(const Name& name, bool separate_rrs) const {
return (ZoneIteratorPtr(new MemoryIterator(
getClass(),
result.zone_data->getZoneTree(), name,
result.zone_data->getZoneTree(),
result.zone_data->getNSEC3Data(), name,
separate_rrs)));
}
......
......@@ -690,6 +690,25 @@ TEST_F(MemoryClientTest, getIteratorSeparateRRs) {
EXPECT_EQ(ConstRRsetPtr(), iterator2->getNextRRset());
}
// Test we get RRSIGs and NSEC3s too for iterating with separate RRs
TEST_F(MemoryClientTest, getIteratorSeparateSigned) {
client_->load(Name("example.org"),
TEST_DATA_DIR "/example.org-nsec3-signed.zone");
ZoneIteratorPtr iterator(client_->getIterator(Name("example.org"), true));
bool seen_rrsig = false, seen_nsec3 = false;
for (ConstRRsetPtr rrset = iterator->getNextRRset();
rrset != ConstRRsetPtr(); rrset = iterator->getNextRRset()) {
if (rrset->getType() == RRType::RRSIG()) {
seen_rrsig = true;
} else if (rrset->getType() == RRType::NSEC3()) {
seen_nsec3 = true;
}
}
EXPECT_TRUE(seen_rrsig);
EXPECT_TRUE(seen_nsec3);
}
TEST_F(MemoryClientTest, getIteratorGetSOAThrowsNotImplemented) {
client_->load(Name("example.org"), TEST_DATA_DIR "/example.org-empty.zone");
ZoneIteratorPtr iterator(client_->getIterator(Name("example.org")));
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment