BIND 10 master, updated. 12f57073eb9f5ff5d11035852e253d25071debab [master] Merge branch 'trac1747'
BIND 10 source code commits
bind10-changes at lists.isc.org
Thu Mar 15 14:52:41 UTC 2012
The branch, master has been updated
via 12f57073eb9f5ff5d11035852e253d25071debab (commit)
via 5c681eddd0ab1819dc7fadd692cadf98991a4d64 (commit)
via 83474d8f558bebb4be0b0f75e843fab993ee3713 (commit)
via 961f28cdfb0f5cc1f5be9613d5f60a7801c92b0a (commit)
via cf5904a4ad2685c8923f4fbee1987132595908db (commit)
via 3d402d65a8aa0f271190b40f5e141c4e5ee7b31d (commit)
via c0c59aceac2afeec9ae3e2711b21e177046b9db3 (commit)
via 460facf264d8a653a959013ce6d7c25875695bc3 (commit)
via 4f93a3a8366f971078dc9c8fe4c846c447a7a45d (commit)
via 70c188de44d2705f6944e37c3e1513572fb5d3d9 (commit)
via 3e344c14a192be56666978933dd4ca0af3cd6a86 (commit)
via 0c1908c1225e8933ac6f2e093f63ef12d3dfc6ee (commit)
from 61992b3bdb4d128971e459da4e6d741a48ad01d1 (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 12f57073eb9f5ff5d11035852e253d25071debab
Merge: 61992b3bdb4d128971e459da4e6d741a48ad01d1 5c681eddd0ab1819dc7fadd692cadf98991a4d64
Author: Jelte Jansen <jelte at isc.org>
Date: Thu Mar 15 15:29:48 2012 +0100
[master] Merge branch 'trac1747'
-----------------------------------------------------------------------
Summary of changes:
src/bin/auth/auth_srv.cc | 5 +-
src/bin/auth/query.cc | 227 +++++++------
src/bin/auth/query.h | 103 +++++-
src/bin/auth/tests/query_unittest.cc | 360 +++++++++++---------
.../configurations/example.org.inmem.config | 1 +
tests/lettuce/data/example.org | 12 +
tests/lettuce/features/queries.feature | 81 +++++
7 files changed, 489 insertions(+), 300 deletions(-)
create mode 100644 tests/lettuce/configurations/example.org.inmem.config
create mode 100644 tests/lettuce/data/example.org
create mode 100644 tests/lettuce/features/queries.feature
-----------------------------------------------------------------------
diff --git a/src/bin/auth/auth_srv.cc b/src/bin/auth/auth_srv.cc
index 2489945..5bef3f8 100644
--- a/src/bin/auth/auth_srv.cc
+++ b/src/bin/auth/auth_srv.cc
@@ -163,6 +163,8 @@ private:
// validateStatistics
bool validateStatistics(isc::data::ConstElementPtr data) const;
+
+ auth::Query query_;
};
AuthSrvImpl::AuthSrvImpl(const bool use_cache,
@@ -554,8 +556,7 @@ AuthSrvImpl::processNormalQuery(const IOMessage& io_message, Message& message,
if (memory_client_ && memory_client_class_ == question->getClass()) {
const RRType& qtype = question->getType();
const Name& qname = question->getName();
- auth::Query(*memory_client_, qname, qtype, message,
- dnssec_ok).process();
+ query_.process(*memory_client_, qname, qtype, message, dnssec_ok);
} else {
datasrc::Query query(message, cache_, dnssec_ok);
data_sources_.doQuery(query);
diff --git a/src/bin/auth/query.cc b/src/bin/auth/query.cc
index 7d50393..db1223d 100644
--- a/src/bin/auth/query.cc
+++ b/src/bin/auth/query.cc
@@ -42,6 +42,11 @@ public:
msg_(msg), section_(section), dnssec_(dnssec)
{}
void operator()(const ConstRRsetPtr& rrset) {
+ /*
+ * FIXME:
+ * The const-cast is wrong, but the Message interface seems
+ * to insist.
+ */
msg_.addRRset(section_,
boost::const_pointer_cast<AbstractRRset>(rrset),
dnssec_);
@@ -85,6 +90,7 @@ getAdditional(const Name& qname, RRType qtype,
results.push_back(*it);
}
}
+
}
namespace isc {
@@ -98,13 +104,7 @@ Query::addSOA(ZoneFinder& finder) {
isc_throw(NoSOA, "There's no SOA record in zone " <<
finder.getOrigin().toText());
} else {
- /*
- * FIXME:
- * The const-cast is wrong, but the Message interface seems
- * to insist.
- */
- response_.addRRset(Message::SECTION_AUTHORITY,
- boost::const_pointer_cast<AbstractRRset>(soa_ctx->rrset), dnssec_);
+ authorities_.push_back(soa_ctx->rrset);
}
}
@@ -123,8 +123,7 @@ Query::addNXDOMAINProofByNSEC(ZoneFinder& finder, ConstRRsetPtr nsec) {
}
// Add the NSEC proving NXDOMAIN to the authority section.
- response_.addRRset(Message::SECTION_AUTHORITY,
- boost::const_pointer_cast<AbstractRRset>(nsec), dnssec_);
+ authorities_.push_back(nsec);
// Next, identify the best possible wildcard name that would match
// the query name. It's the longer common suffix with the qname
@@ -135,14 +134,14 @@ Query::addNXDOMAINProofByNSEC(ZoneFinder& finder, ConstRRsetPtr nsec) {
// and the best possible wildcard is *.b.example.com. If the NXDOMAIN
// NSEC is a.example.com. NSEC c.b.example.com., the longer suffix
// is the next domain of the NSEC, and we get the same wildcard name.
- const int qlabels = qname_.getLabelCount();
- const int olabels = qname_.compare(nsec->getName()).getCommonLabels();
- const int nlabels = qname_.compare(
+ const int qlabels = qname_->getLabelCount();
+ const int olabels = qname_->compare(nsec->getName()).getCommonLabels();
+ const int nlabels = qname_->compare(
dynamic_cast<const generic::NSEC&>(nsec->getRdataIterator()->
getCurrent()).
getNextName()).getCommonLabels();
const int common_labels = std::max(olabels, nlabels);
- const Name wildname(Name("*").concatenate(qname_.split(qlabels -
+ const Name wildname(Name("*").concatenate(qname_->split(qlabels -
common_labels)));
// Confirm the wildcard doesn't exist (this should result in NXDOMAIN;
@@ -161,9 +160,7 @@ Query::addNXDOMAINProofByNSEC(ZoneFinder& finder, ConstRRsetPtr nsec) {
// stage of performance optimization, we should consider optimizing this
// for some optimized data source implementations.
if (nsec->getName() != fcontext->rrset->getName()) {
- response_.addRRset(Message::SECTION_AUTHORITY,
- boost::const_pointer_cast<AbstractRRset>(fcontext->rrset),
- dnssec_);
+ authorities_.push_back(fcontext->rrset);
}
}
@@ -183,16 +180,10 @@ Query::addClosestEncloserProof(ZoneFinder& finder, const Name& name,
}
if (add_closest) {
- response_.addRRset(Message::SECTION_AUTHORITY,
- boost::const_pointer_cast<AbstractRRset>(
- result.closest_proof),
- dnssec_);
+ authorities_.push_back(result.closest_proof);
}
if (result.next_proof) {
- response_.addRRset(Message::SECTION_AUTHORITY,
- boost::const_pointer_cast<AbstractRRset>(
- result.next_proof),
- dnssec_);
+ authorities_.push_back(result.next_proof);
}
return (result.closest_labels);
}
@@ -208,10 +199,7 @@ Query::addNSEC3ForName(ZoneFinder& finder, const Name& name, bool match) {
<< (result.matched ? "matching" : "covering")
<< " NSEC3 found for " << name);
}
- response_.addRRset(Message::SECTION_AUTHORITY,
- boost::const_pointer_cast<AbstractRRset>(
- result.closest_proof),
- dnssec_);
+ authorities_.push_back(result.closest_proof);
}
void
@@ -219,12 +207,12 @@ Query::addNXDOMAINProofByNSEC3(ZoneFinder& finder) {
// Firstly get the NSEC3 proves for Closest Encloser Proof
// See Section 7.2.1 of RFC 5155.
const uint8_t closest_labels =
- addClosestEncloserProof(finder, qname_, false);
+ addClosestEncloserProof(finder, *qname_, false);
// Next, construct the wildcard name at the closest encloser, i.e.,
// '*' followed by the closest encloser, and add NSEC3 for it.
const Name wildname(Name("*").concatenate(
- qname_.split(qname_.getLabelCount() - closest_labels)));
+ qname_->split(qname_->getLabelCount() - closest_labels)));
addNSEC3ForName(finder, wildname, false);
}
@@ -239,17 +227,14 @@ 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.
ConstZoneFinderContextPtr fcontext =
- finder.find(qname_, RRType::NSEC(),
+ finder.find(*qname_, RRType::NSEC(),
dnssec_opt_ | ZoneFinder::NO_WILDCARD);
if (fcontext->code != ZoneFinder::NXDOMAIN || !fcontext->rrset ||
fcontext->rrset->getRdataCount() == 0) {
isc_throw(BadNSEC,
"Unexpected NSEC result for wildcard proof");
}
- response_.addRRset(Message::SECTION_AUTHORITY,
- boost::const_pointer_cast<AbstractRRset>(
- fcontext->rrset),
- dnssec_);
+ authorities_.push_back(fcontext->rrset);
} else if (db_context.isNSEC3Signed()) {
// Case for RFC 5155 Section 7.2.6.
//
@@ -257,7 +242,7 @@ Query::addWildcardProof(ZoneFinder& finder,
// of the matching wildcard, so NSEC3 for its next closer (and only
// that NSEC3) is what we are expected to provided per the RFC (if
// this assumption isn't met the zone is broken anyway).
- addClosestEncloserProof(finder, qname_, false, false);
+ addClosestEncloserProof(finder, *qname_, false, false);
}
}
@@ -270,7 +255,7 @@ Query::addWildcardNXRRSETProof(ZoneFinder& finder, ConstRRsetPtr nsec) {
}
ConstZoneFinderContextPtr fcontext =
- finder.find(qname_, RRType::NSEC(),
+ finder.find(*qname_, RRType::NSEC(),
dnssec_opt_ | ZoneFinder::NO_WILDCARD);
if (fcontext->code != ZoneFinder::NXDOMAIN || !fcontext->rrset ||
fcontext->rrset->getRdataCount() == 0) {
@@ -279,9 +264,7 @@ Query::addWildcardNXRRSETProof(ZoneFinder& finder, ConstRRsetPtr nsec) {
if (nsec->getName() != fcontext->rrset->getName()) {
// one NSEC RR proves wildcard_nxrrset that no matched QNAME.
- response_.addRRset(Message::SECTION_AUTHORITY,
- boost::const_pointer_cast<AbstractRRset>(fcontext->rrset),
- dnssec_);
+ authorities_.push_back(fcontext->rrset);
}
}
@@ -290,10 +273,7 @@ Query::addDS(ZoneFinder& finder, const Name& dname) {
ConstZoneFinderContextPtr ds_context =
finder.find(dname, RRType::DS(), dnssec_opt_);
if (ds_context->code == ZoneFinder::SUCCESS) {
- response_.addRRset(Message::SECTION_AUTHORITY,
- boost::const_pointer_cast<AbstractRRset>(
- ds_context->rrset),
- dnssec_);
+ authorities_.push_back(ds_context->rrset);
} else if (ds_context->code == ZoneFinder::NXRRSET &&
ds_context->isNSECSigned()) {
addNXRRsetProof(finder, *ds_context);
@@ -312,29 +292,26 @@ Query::addNXRRsetProof(ZoneFinder& finder,
const ZoneFinder::Context& db_context)
{
if (db_context.isNSECSigned() && db_context.rrset) {
- response_.addRRset(Message::SECTION_AUTHORITY,
- boost::const_pointer_cast<AbstractRRset>(
- db_context.rrset),
- dnssec_);
+ authorities_.push_back(db_context.rrset);
if (db_context.isWildcard()) {
addWildcardNXRRSETProof(finder, db_context.rrset);
}
} else if (db_context.isNSEC3Signed() && !db_context.isWildcard()) {
- if (qtype_ == RRType::DS()) {
+ if (*qtype_ == RRType::DS()) {
// RFC 5155, Section 7.2.4. Add either NSEC3 for the qname or
// closest (provable) encloser proof in case of optout.
- addClosestEncloserProof(finder, qname_, true);
+ addClosestEncloserProof(finder, *qname_, true);
} else {
// RFC 5155, Section 7.2.3. Just add NSEC3 for the qname.
- addNSEC3ForName(finder, qname_, true);
+ addNSEC3ForName(finder, *qname_, true);
}
} else if (db_context.isNSEC3Signed() && db_context.isWildcard()) {
// Case for RFC 5155 Section 7.2.5: add closest encloser proof for the
// qname, construct the matched wildcard name and add NSEC3 for it.
const uint8_t closest_labels =
- addClosestEncloserProof(finder, qname_, false);
+ addClosestEncloserProof(finder, *qname_, false);
const Name wname = Name("*").concatenate(
- qname_.split(qname_.getLabelCount() - closest_labels));
+ qname_->split(qname_->getLabelCount() - closest_labels));
addNSEC3ForName(finder, wname, true);
}
}
@@ -354,10 +331,8 @@ Query::addAuthAdditional(ZoneFinder& finder,
isc_throw(NoApexNS, "There's no apex NS records in zone " <<
finder.getOrigin().toText());
}
- response_.addRRset(Message::SECTION_AUTHORITY,
- boost::const_pointer_cast<AbstractRRset>(
- ns_context->rrset), dnssec_);
- getAdditional(qname_, qtype_, *ns_context, additionals);
+ authorities_.push_back(ns_context->rrset);
+ getAdditional(*qname_, *qtype_, *ns_context, additionals);
}
namespace {
@@ -377,10 +352,20 @@ findZone(const DataSourceClient& client, const Name& qname, RRType qtype) {
}
void
-Query::process() {
+Query::process(datasrc::DataSourceClient& datasrc_client,
+ const isc::dns::Name& qname, const isc::dns::RRType& qtype,
+ isc::dns::Message& response, bool dnssec)
+{
+ // Set up the cleaner object so internal pointers and vectors are
+ // always reset after scope leaves this method
+ QueryCleaner cleaner(*this);
+
+ // Set up query parameters for the rest of the (internal) methods
+ initialize(datasrc_client, qname, qtype, response, dnssec);
+
// Found a zone which is the nearest ancestor to QNAME
- const DataSourceClient::FindResult result = findZone(datasrc_client_,
- qname_, qtype_);
+ const DataSourceClient::FindResult result = findZone(*datasrc_client_,
+ *qname_, *qtype_);
// If we have no matching authoritative zone for the query name, return
// REFUSED. In short, this is to be compatible with BIND 9, but the
@@ -392,38 +377,34 @@ Query::process() {
// If we tried to find a "parent zone" for a DS query and failed,
// we may still have authority at the child side. If we do, the query
// has to be handled there.
- if (qtype_ == RRType::DS() && qname_.getLabelCount() > 1 &&
+ if (*qtype_ == RRType::DS() && qname_->getLabelCount() > 1 &&
processDSAtChild()) {
return;
}
- response_.setHeaderFlag(Message::HEADERFLAG_AA, false);
- response_.setRcode(Rcode::REFUSED());
+ response_->setHeaderFlag(Message::HEADERFLAG_AA, false);
+ response_->setRcode(Rcode::REFUSED());
return;
}
ZoneFinder& zfinder = *result.zone_finder;
// We have authority for a zone that contain the query name (possibly
// indirectly via delegation). Look into the zone.
- response_.setHeaderFlag(Message::HEADERFLAG_AA);
- response_.setRcode(Rcode::NOERROR());
- vector<ConstRRsetPtr> target;
- vector<ConstRRsetPtr> additionals;
+ response_->setHeaderFlag(Message::HEADERFLAG_AA);
+ response_->setRcode(Rcode::NOERROR());
boost::function0<ZoneFinderContextPtr> find;
- const bool qtype_is_any = (qtype_ == RRType::ANY());
+ const bool qtype_is_any = (*qtype_ == RRType::ANY());
if (qtype_is_any) {
- find = boost::bind(&ZoneFinder::findAll, &zfinder, qname_,
- boost::ref(target), dnssec_opt_);
+ find = boost::bind(&ZoneFinder::findAll, &zfinder, *qname_,
+ boost::ref(answers_), dnssec_opt_);
} else {
- find = boost::bind(&ZoneFinder::find, &zfinder, qname_, qtype_,
+ find = boost::bind(&ZoneFinder::find, &zfinder, *qname_, *qtype_,
dnssec_opt_);
}
ZoneFinderContextPtr db_context(find());
switch (db_context->code) {
case ZoneFinder::DNAME: {
// First, put the dname into the answer
- response_.addRRset(Message::SECTION_ANSWER,
- boost::const_pointer_cast<AbstractRRset>(db_context->rrset),
- dnssec_);
+ answers_.push_back(db_context->rrset);
/*
* Empty DNAME should never get in, as it is impossible to
* create one in master file.
@@ -436,7 +417,7 @@ Query::process() {
dynamic_cast<const rdata::generic::DNAME&>(
db_context->rrset->getRdataIterator()->getCurrent()));
// The yet unmatched prefix dname
- const Name prefix(qname_.split(0, qname_.getLabelCount() -
+ const Name prefix(qname_->split(0, qname_->getLabelCount() -
db_context->rrset->getName().getLabelCount()));
// If we put it together, will it be too long?
// (The prefix contains trailing ., which will be removed
@@ -446,20 +427,20 @@ Query::process() {
* In case the synthesized name is too long, section 4.1
* of RFC 2672 mandates we return YXDOMAIN.
*/
- response_.setRcode(Rcode::YXDOMAIN());
- return;
+ response_->setRcode(Rcode::YXDOMAIN());
+ break;
}
// 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_context->rrset->getClass(),
+ RRsetPtr cname(new RRset(*qname_, db_context->rrset->getClass(),
RRType::CNAME(), db_context->rrset->getTTL()));
// Construct the new target by replacing the end
- cname->addRdata(rdata::generic::CNAME(qname_.split(0,
- qname_.getLabelCount() -
+ cname->addRdata(rdata::generic::CNAME(qname_->split(0,
+ qname_->getLabelCount() -
db_context->rrset->getName().getLabelCount()).
concatenate(dname.getDname())));
- response_.addRRset(Message::SECTION_ANSWER, cname, dnssec_);
+ answers_.push_back(cname);
break;
}
case ZoneFinder::CNAME:
@@ -472,9 +453,7 @@ Query::process() {
*
* So, just put it there.
*/
- response_.addRRset(Message::SECTION_ANSWER,
- boost::const_pointer_cast<AbstractRRset>(db_context->rrset),
- dnssec_);
+ answers_.push_back(db_context->rrset);
// If the answer is a result of wildcard substitution,
// add a proof that there's no closer name.
@@ -483,21 +462,13 @@ Query::process() {
}
break;
case ZoneFinder::SUCCESS:
- 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<AbstractRRset>(rrset), dnssec_);
- }
- } else {
- response_.addRRset(Message::SECTION_ANSWER,
- boost::const_pointer_cast<AbstractRRset>(db_context->rrset),
- dnssec_);
+ // If query type is ANY, the rrs have already been added
+ if (!qtype_is_any) {
+ answers_.push_back(db_context->rrset);
}
// Retrieve additional records for the answer
- getAdditional(qname_, qtype_, *db_context, additionals);
+ getAdditional(*qname_, *qtype_, *db_context, additionals_);
// If apex NS records haven't been provided in the answer
// section, insert apex NS records into the authority section
@@ -507,9 +478,9 @@ Query::process() {
// qname is the zone origin.
if (result.code != result::SUCCESS ||
db_context->code != ZoneFinder::SUCCESS ||
- (qtype_ != RRType::NS() && !qtype_is_any))
+ (*qtype_ != RRType::NS() && !qtype_is_any))
{
- addAuthAdditional(*result.zone_finder, additionals);
+ addAuthAdditional(*result.zone_finder, additionals_);
}
// If the answer is a result of wildcard substitution,
@@ -523,16 +494,14 @@ Query::process() {
// if we are an authority of the child, too. If so, we need to
// complete the process in the child as specified in Section
// 2.2.1.2. of RFC3658.
- if (qtype_ == RRType::DS() && processDSAtChild()) {
+ if (*qtype_ == RRType::DS() && processDSAtChild()) {
return;
}
- response_.setHeaderFlag(Message::HEADERFLAG_AA, false);
- response_.addRRset(Message::SECTION_AUTHORITY,
- boost::const_pointer_cast<AbstractRRset>(db_context->rrset),
- dnssec_);
+ response_->setHeaderFlag(Message::HEADERFLAG_AA, false);
+ authorities_.push_back(db_context->rrset);
// Retrieve additional records for the name servers
- db_context->getAdditional(A_AND_AAAA(), additionals);
+ db_context->getAdditional(A_AND_AAAA(), additionals_);
// If DNSSEC is requested, see whether there is a DS
// record for this delegation.
@@ -541,7 +510,7 @@ Query::process() {
}
break;
case ZoneFinder::NXDOMAIN:
- response_.setRcode(Rcode::NXDOMAIN());
+ response_->setRcode(Rcode::NXDOMAIN());
addSOA(*result.zone_finder);
if (dnssec_) {
if (db_context->isNSECSigned() && db_context->rrset) {
@@ -565,15 +534,48 @@ Query::process() {
break;
}
- for_each(additionals.begin(), additionals.end(),
- RRsetInserter(response_, Message::SECTION_ADDITIONAL,
- dnssec_));
+ createResponse();
+}
+
+void
+Query::initialize(datasrc::DataSourceClient& datasrc_client,
+ const isc::dns::Name& qname, const isc::dns::RRType& qtype,
+ isc::dns::Message& response, bool dnssec)
+{
+ datasrc_client_ = &datasrc_client;
+ qname_ = &qname;
+ qtype_ = &qtype;
+ response_ = &response;
+ dnssec_ = dnssec;
+ dnssec_opt_ = (dnssec ? isc::datasrc::ZoneFinder::FIND_DNSSEC :
+ isc::datasrc::ZoneFinder::FIND_DEFAULT);
+}
+
+void
+Query::createResponse() {
+ for_each(answers_.begin(), answers_.end(),
+ RRsetInserter(*response_, Message::SECTION_ANSWER, dnssec_));
+ for_each(authorities_.begin(), authorities_.end(),
+ RRsetInserter(*response_, Message::SECTION_AUTHORITY, dnssec_));
+ for_each(additionals_.begin(), additionals_.end(),
+ RRsetInserter(*response_, Message::SECTION_ADDITIONAL, dnssec_));
+}
+
+void
+Query::reset() {
+ datasrc_client_ = NULL;
+ qname_ = NULL;
+ qtype_ = NULL;
+ response_ = NULL;
+ answers_.clear();
+ authorities_.clear();
+ additionals_.clear();
}
bool
Query::processDSAtChild() {
const DataSourceClient::FindResult zresult =
- datasrc_client_.findZone(qname_);
+ datasrc_client_->findZone(*qname_);
if (zresult.code != result::SUCCESS) {
return (false);
@@ -588,17 +590,18 @@ Query::processDSAtChild() {
// The important point in this case is to return SOA so that the resolver
// that happens to contact us can hunt for the appropriate parent zone
// by seeing the SOA.
- response_.setHeaderFlag(Message::HEADERFLAG_AA);
- response_.setRcode(Rcode::NOERROR());
+ response_->setHeaderFlag(Message::HEADERFLAG_AA);
+ response_->setRcode(Rcode::NOERROR());
addSOA(*zresult.zone_finder);
ConstZoneFinderContextPtr ds_context =
- zresult.zone_finder->find(qname_, RRType::DS(), dnssec_opt_);
+ zresult.zone_finder->find(*qname_, RRType::DS(), dnssec_opt_);
if (ds_context->code == ZoneFinder::NXRRSET) {
if (dnssec_) {
addNXRRsetProof(*zresult.zone_finder, *ds_context);
}
}
+ createResponse();
return (true);
}
diff --git a/src/bin/auth/query.h b/src/bin/auth/query.h
index f8a8f02..e295d91 100644
--- a/src/bin/auth/query.h
+++ b/src/bin/auth/query.h
@@ -18,6 +18,8 @@
#include <dns/rrset.h>
#include <datasrc/zone.h>
+#include <boost/noncopyable.hpp>
+
#include <vector>
namespace isc {
@@ -34,6 +36,13 @@ class DataSourceClient;
namespace auth {
+/// \brief Initial reserved size for the vectors in Query
+///
+/// The value is larger than we expect the vectors to even become, and
+/// has been chosen arbitrarily. The reason to set them quite high is
+/// to prevent reallocation on addition.
+const size_t RESERVE_RRSETS = 64;
+
/// The \c Query class represents a standard DNS query that encapsulates
/// processing logic to answer the query.
///
@@ -64,7 +73,7 @@ namespace auth {
/// likely to misuse one of the classes instead of the other
/// accidentally, and since it's considered a temporary development state,
/// we keep this name at the moment.
-class Query {
+class Query : boost::noncopyable {
private:
/// \brief Adds a SOA.
@@ -226,10 +235,10 @@ private:
void addNSEC3ForName(isc::datasrc::ZoneFinder& finder,
const isc::dns::Name& name, bool match);
-public:
- /// Constructor from query parameters.
+ /// Set up the Query object for a new query lookup
///
- /// This constructor never throws an exception.
+ /// This is the first step of the process() method, and initializes
+ /// the member data
///
/// \param datasrc_client The datasource wherein the answer to the query is
/// to be found.
@@ -238,14 +247,56 @@ public:
/// \param response The response message to store the answer to the query.
/// \param dnssec If the answer should include signatures and NSEC/NSEC3 if
/// possible.
- Query(const isc::datasrc::DataSourceClient& datasrc_client,
- const isc::dns::Name& qname, const isc::dns::RRType& qtype,
- isc::dns::Message& response, bool dnssec = false) :
- datasrc_client_(datasrc_client), qname_(qname), qtype_(qtype),
- response_(response), dnssec_(dnssec),
- dnssec_opt_(dnssec ? isc::datasrc::ZoneFinder::FIND_DNSSEC :
- isc::datasrc::ZoneFinder::FIND_DEFAULT)
- {}
+ void initialize(datasrc::DataSourceClient& datasrc_client,
+ const isc::dns::Name& qname, const isc::dns::RRType& qtype,
+ isc::dns::Message& response, bool dnssec = false);
+
+ /// \brief Fill in the response sections
+ ///
+ /// This is the final step of the process() method, and within
+ /// that method, it should be called before it returns (if any
+ /// response data is to be added)
+ ///
+ /// This will take each RRset collected in answers_, authorities_, and
+ /// additionals_, and add them to their corresponding sections in
+ /// the response message.
+ ///
+ /// After they are added, the vectors are cleared.
+ void createResponse();
+
+ /// \brief Resets any partly built response data, and internal pointers
+ ///
+ /// Called by the QueryCleaner object upon its destruction
+ void reset();
+
+ /// \brief Internal class used for cleanup of Query members
+ ///
+ /// The process() call creates an object of this class, which
+ /// upon its destruction, calls Query::reset(), so that outside
+ /// of single calls to process(), the query state is always clean.
+ class QueryCleaner {
+ public:
+ QueryCleaner(isc::auth::Query& query) : query_(query) {}
+ ~QueryCleaner() { query_.reset(); }
+ private:
+ isc::auth::Query& query_;
+ };
+
+public:
+ /// Default constructor.
+ ///
+ /// Query parameters will be set by the call to process()
+ ///
+ Query() :
+ datasrc_client_(NULL), qname_(NULL), qtype_(NULL),
+ response_(NULL), dnssec_(false),
+ dnssec_opt_(isc::datasrc::ZoneFinder::FIND_DEFAULT)
+ {
+ answers_.reserve(RESERVE_RRSETS);
+ authorities_.reserve(RESERVE_RRSETS);
+ additionals_.reserve(RESERVE_RRSETS);
+ }
+
/// Process the query.
///
@@ -273,7 +324,17 @@ public:
/// This might throw BadZone or any of its specific subclasses, but that
/// shouldn't happen in real-life (as BadZone means wrong data, it should
/// have been rejected upon loading).
- void process();
+ ///
+ /// \param datasrc_client The datasource wherein the answer to the query is
+ /// to be found.
+ /// \param qname The query name
+ /// \param qtype The RR type of the query
+ /// \param response The response message to store the answer to the query.
+ /// \param dnssec If the answer should include signatures and NSEC/NSEC3 if
+ /// possible.
+ void process(datasrc::DataSourceClient& datasrc_client,
+ const isc::dns::Name& qname, const isc::dns::RRType& qtype,
+ isc::dns::Message& response, bool dnssec = false);
/// \short Bad zone data encountered.
///
@@ -342,12 +403,16 @@ public:
};
private:
- const isc::datasrc::DataSourceClient& datasrc_client_;
- const isc::dns::Name& qname_;
- const isc::dns::RRType& qtype_;
- isc::dns::Message& response_;
- const bool dnssec_;
- const isc::datasrc::ZoneFinder::FindOptions dnssec_opt_;
+ const isc::datasrc::DataSourceClient* datasrc_client_;
+ const isc::dns::Name* qname_;
+ const isc::dns::RRType* qtype_;
+ isc::dns::Message* response_;
+ bool dnssec_;
+ isc::datasrc::ZoneFinder::FindOptions dnssec_opt_;
+
+ std::vector<isc::dns::ConstRRsetPtr> answers_;
+ std::vector<isc::dns::ConstRRsetPtr> authorities_;
+ std::vector<isc::dns::ConstRRsetPtr> additionals_;
};
}
diff --git a/src/bin/auth/tests/query_unittest.cc b/src/bin/auth/tests/query_unittest.cc
index 3c901aa..b74ebcc 100644
--- a/src/bin/auth/tests/query_unittest.cc
+++ b/src/bin/auth/tests/query_unittest.cc
@@ -903,6 +903,7 @@ protected:
const qid_t qid;
const uint16_t query_code;
const string ns_addrs_and_sig_txt; // convenient shortcut
+ Query query;
};
// A wrapper to check resulting response message commonly used in
@@ -946,25 +947,40 @@ TEST_F(QueryTest, noZone) {
// There's no zone in the memory datasource. So the response should have
// REFUSED.
InMemoryClient empty_memory_client;
- Query nozone_query(empty_memory_client, qname, qtype, response);
- EXPECT_NO_THROW(nozone_query.process());
+ EXPECT_NO_THROW(query.process(empty_memory_client, qname, qtype,
+ response));
EXPECT_EQ(Rcode::REFUSED(), response.getRcode());
}
TEST_F(QueryTest, exactMatch) {
- Query query(memory_client, qname, qtype, response);
- EXPECT_NO_THROW(query.process());
+ EXPECT_NO_THROW(query.process(memory_client, qname, qtype, response));
// find match rrset
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 1, 3, 3,
www_a_txt, zone_ns_txt, ns_addrs_txt);
}
+TEST_F(QueryTest, exactMatchMultipleQueries) {
+ EXPECT_NO_THROW(query.process(memory_client, qname, qtype, response));
+ // find match rrset
+ responseCheck(response, Rcode::NOERROR(), AA_FLAG, 1, 3, 3,
+ www_a_txt, zone_ns_txt, ns_addrs_txt);
+
+ // clean up response for second query
+ response.clear(isc::dns::Message::RENDER);
+ response.setRcode(Rcode::NOERROR());
+ response.setOpcode(Opcode::QUERY());
+ EXPECT_NO_THROW(query.process(memory_client, qname, qtype, response));
+ // find match rrset
+ SCOPED_TRACE("Second query");
+ responseCheck(response, Rcode::NOERROR(), AA_FLAG, 1, 3, 3,
+ www_a_txt, zone_ns_txt, ns_addrs_txt);
+}
+
TEST_F(QueryTest, exactMatchIgnoreSIG) {
// Check that we do not include the RRSIG when not requested even when
// we receive it from the data source.
mock_finder->setIncludeRRSIGAnyway(true);
- Query query(memory_client, qname, qtype, response);
- EXPECT_NO_THROW(query.process());
+ EXPECT_NO_THROW(query.process(memory_client, qname, qtype, response));
// find match rrset
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 1, 3, 3,
www_a_txt, zone_ns_txt, ns_addrs_txt);
@@ -972,8 +988,8 @@ TEST_F(QueryTest, exactMatchIgnoreSIG) {
TEST_F(QueryTest, dnssecPositive) {
// Just like exactMatch, but the signatures should be included as well
- Query query(memory_client, qname, qtype, response, true);
- EXPECT_NO_THROW(query.process());
+ EXPECT_NO_THROW(query.process(memory_client, qname, qtype, response,
+ true));
// find match rrset
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 2, 4, 6,
(www_a_txt + std::string("www.example.com. 3600 IN RRSIG "
@@ -991,8 +1007,9 @@ TEST_F(QueryTest, dnssecPositive) {
TEST_F(QueryTest, exactAddrMatch) {
// find match rrset, omit additional data which has already been provided
// in the answer section from the additional.
- EXPECT_NO_THROW(Query(memory_client, Name("noglue.example.com"), qtype,
- response).process());
+ EXPECT_NO_THROW(query.process(memory_client,
+ Name("noglue.example.com"),
+ qtype, response));
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 1, 3, 2,
"noglue.example.com. 3600 IN A 192.0.2.53\n", zone_ns_txt,
@@ -1003,8 +1020,8 @@ TEST_F(QueryTest, exactAddrMatch) {
TEST_F(QueryTest, apexNSMatch) {
// find match rrset, omit authority data which has already been provided
// in the answer section from the authority section.
- EXPECT_NO_THROW(Query(memory_client, Name("example.com"), RRType::NS(),
- response).process());
+ EXPECT_NO_THROW(query.process(memory_client, Name("example.com"),
+ RRType::NS(), response));
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 3, 0, 3,
zone_ns_txt, NULL, ns_addrs_txt);
@@ -1014,8 +1031,8 @@ TEST_F(QueryTest, apexNSMatch) {
TEST_F(QueryTest, exactAnyMatch) {
// find match rrset, omit additional data which has already been provided
// in the answer section from the additional.
- EXPECT_NO_THROW(Query(memory_client, Name("noglue.example.com"),
- RRType::ANY(), response).process());
+ EXPECT_NO_THROW(query.process(memory_client, Name("noglue.example.com"),
+ RRType::ANY(), response));
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 2, 3, 2,
(string("noglue.example.com. 3600 IN A 192.0.2.53\n") +
@@ -1028,8 +1045,8 @@ TEST_F(QueryTest, exactAnyMatch) {
TEST_F(QueryTest, apexAnyMatch) {
// find match rrset, omit additional data which has already been provided
// in the answer section from the additional.
- EXPECT_NO_THROW(Query(memory_client, Name("example.com"),
- RRType::ANY(), response).process());
+ EXPECT_NO_THROW(query.process(memory_client, Name("example.com"),
+ RRType::ANY(), response));
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 5, 0, 3,
(string(soa_txt) + string(zone_ns_txt) +
string(nsec_apex_txt)).c_str(),
@@ -1037,23 +1054,23 @@ TEST_F(QueryTest, apexAnyMatch) {
}
TEST_F(QueryTest, mxANYMatch) {
- EXPECT_NO_THROW(Query(memory_client, Name("mx.example.com"),
- RRType::ANY(), response).process());
+ EXPECT_NO_THROW(query.process(memory_client, Name("mx.example.com"),
+ RRType::ANY(), response));
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 4, 3, 4,
(string(mx_txt) + string(nsec_mx_txt)).c_str(), zone_ns_txt,
(string(ns_addrs_txt) + string(www_a_txt)).c_str());
}
TEST_F(QueryTest, glueANYMatch) {
- EXPECT_NO_THROW(Query(memory_client, Name("delegation.example.com"),
- RRType::ANY(), response).process());
+ EXPECT_NO_THROW(query.process(memory_client, Name("delegation.example.com"),
+ RRType::ANY(), response));
responseCheck(response, Rcode::NOERROR(), 0, 0, 4, 3,
NULL, delegation_txt, ns_addrs_txt);
}
TEST_F(QueryTest, nodomainANY) {
- EXPECT_NO_THROW(Query(memory_client, Name("nxdomain.example.com"),
- RRType::ANY(), response).process());
+ EXPECT_NO_THROW(query.process(memory_client, Name("nxdomain.example.com"),
+ RRType::ANY(), response));
responseCheck(response, Rcode::NXDOMAIN(), AA_FLAG, 0, 1, 0,
NULL, soa_txt, NULL, mock_finder->getOrigin());
}
@@ -1065,23 +1082,24 @@ TEST_F(QueryTest, noApexNS) {
// Disable apex NS record
mock_finder->setApexNSFlag(false);
- EXPECT_THROW(Query(memory_client, Name("noglue.example.com"), qtype,
- response).process(), Query::NoApexNS);
+ EXPECT_THROW(query.process(memory_client, Name("noglue.example.com"), qtype,
+ response), Query::NoApexNS);
// We don't look into the response, as it threw
}
TEST_F(QueryTest, delegation) {
- EXPECT_NO_THROW(Query(memory_client, Name("delegation.example.com"),
- qtype, response).process());
+ EXPECT_NO_THROW(query.process(memory_client,
+ Name("delegation.example.com"),
+ qtype, response));
responseCheck(response, Rcode::NOERROR(), 0, 0, 4, 3,
NULL, delegation_txt, ns_addrs_txt);
}
TEST_F(QueryTest, secureDelegation) {
- EXPECT_NO_THROW(Query(memory_client,
- Name("foo.signed-delegation.example.com"),
- qtype, response, true).process());
+ EXPECT_NO_THROW(query.process(memory_client,
+ Name("foo.signed-delegation.example.com"),
+ qtype, response, true));
// Should now contain RRSIG and DS record as well.
responseCheck(response, Rcode::NOERROR(), 0, 0, 3, 0,
@@ -1094,9 +1112,9 @@ TEST_F(QueryTest, secureDelegation) {
}
TEST_F(QueryTest, secureUnsignedDelegation) {
- EXPECT_NO_THROW(Query(memory_client,
- Name("foo.unsigned-delegation.example.com"),
- qtype, response, true).process());
+ EXPECT_NO_THROW(query.process(memory_client,
+ Name("foo.unsigned-delegation.example.com"),
+ qtype, response, true));
// Should now contain RRSIG and NSEC record as well.
responseCheck(response, Rcode::NOERROR(), 0, 0, 3, 0,
@@ -1115,8 +1133,9 @@ TEST_F(QueryTest, secureUnsignedDelegationWithNSEC3) {
mock_finder->setNSEC3Flag(true);
mock_finder->addRecord(unsigned_delegation_nsec3_txt);
- Query(memory_client, Name("foo.unsigned-delegation.example.com"),
- qtype, response, true).process();
+ query.process(memory_client,
+ Name("foo.unsigned-delegation.example.com"),
+ qtype, response, true);
// The response should contain the NS and matching NSEC3 with its RRSIG
responseCheck(response, Rcode::NOERROR(), 0, 0, 3, 0,
@@ -1133,8 +1152,9 @@ TEST_F(QueryTest, secureUnsignedDelegationWithNSEC3OptOut) {
// Similar to the previous case, but the delegation is an optout.
mock_finder->setNSEC3Flag(true);
- Query(memory_client, Name("foo.unsigned-delegation.example.com"),
- qtype, response, true).process();
+ query.process(memory_client,
+ Name("foo.unsigned-delegation.example.com"),
+ qtype, response, true);
// The response should contain the NS and the closest provable encloser
// proof (and their RRSIGs). The closest encloser is the apex (origin),
@@ -1157,19 +1177,22 @@ TEST_F(QueryTest, secureUnsignedDelegationWithNSEC3OptOut) {
TEST_F(QueryTest, badSecureDelegation) {
// Test whether exception is raised if DS query at delegation results in
// something different than SUCCESS or NXRRSET
- EXPECT_THROW(Query(memory_client, Name("bad-delegation.example.com"),
- qtype, response, true).process(), Query::BadDS);
+ EXPECT_THROW(query.process(memory_client,
+ Name("bad-delegation.example.com"),
+ qtype, response, true), Query::BadDS);
// But only if DNSSEC is requested (it shouldn't even try to look for
// the DS otherwise)
- EXPECT_NO_THROW(Query(memory_client, Name("bad-delegation.example.com"),
- qtype, response).process());
+ EXPECT_NO_THROW(query.process(memory_client,
+ Name("bad-delegation.example.com"),
+ qtype, response));
}
TEST_F(QueryTest, nxdomain) {
- EXPECT_NO_THROW(Query(memory_client, Name("nxdomain.example.com"), qtype,
- response).process());
+ EXPECT_NO_THROW(query.process(memory_client,
+ Name("nxdomain.example.com"), qtype,
+ response));
responseCheck(response, Rcode::NXDOMAIN(), AA_FLAG, 0, 1, 0,
NULL, soa_txt, NULL, mock_finder->getOrigin());
}
@@ -1178,8 +1201,9 @@ TEST_F(QueryTest, nxdomainWithNSEC) {
// NXDOMAIN with DNSSEC proof. We should have SOA, NSEC that proves
// NXDOMAIN and NSEC that proves nonexistence of matching wildcard,
// as well as their RRSIGs.
- EXPECT_NO_THROW(Query(memory_client, Name("nxdomain.example.com"), qtype,
- response, true).process());
+ EXPECT_NO_THROW(query.process(memory_client,
+ Name("nxdomain.example.com"), qtype,
+ response, true));
responseCheck(response, Rcode::NXDOMAIN(), AA_FLAG, 0, 6, 0,
NULL, (string(soa_txt) +
string("example.com. 3600 IN RRSIG ") +
@@ -1198,8 +1222,8 @@ TEST_F(QueryTest, nxdomainWithNSEC2) {
// is derived from the next domain of the NSEC that proves NXDOMAIN, and
// the NSEC to provide the non existence of wildcard is different from
// the first NSEC.
- Query(memory_client, Name("(.no.example.com"), qtype,
- response, true).process();
+ query.process(memory_client, Name("(.no.example.com"), qtype, response,
+ true);
responseCheck(response, Rcode::NXDOMAIN(), AA_FLAG, 0, 6, 0,
NULL, (string(soa_txt) +
string("example.com. 3600 IN RRSIG ") +
@@ -1216,8 +1240,8 @@ TEST_F(QueryTest, nxdomainWithNSEC2) {
TEST_F(QueryTest, nxdomainWithNSECDuplicate) {
// See comments about nz_txt. In this case we only need one NSEC,
// which proves both NXDOMAIN and the non existence of wildcard.
- Query(memory_client, Name("nx.no.example.com"), qtype,
- response, true).process();
+ query.process(memory_client, Name("nx.no.example.com"), qtype, response,
+ true);
responseCheck(response, Rcode::NXDOMAIN(), AA_FLAG, 0, 4, 0,
NULL, (string(soa_txt) +
string("example.com. 3600 IN RRSIG ") +
@@ -1233,8 +1257,8 @@ TEST_F(QueryTest, nxdomainBadNSEC1) {
mock_finder->setNSECResult(Name("badnsec.example.com"),
ZoneFinder::NXDOMAIN,
mock_finder->dname_rrset_);
- EXPECT_THROW(Query(memory_client, Name("badnsec.example.com"), qtype,
- response, true).process(),
+ EXPECT_THROW(query.process(memory_client, Name("badnsec.example.com"),
+ qtype, response, true),
std::bad_cast);
}
@@ -1243,8 +1267,8 @@ TEST_F(QueryTest, nxdomainBadNSEC2) {
mock_finder->setNSECResult(Name("emptynsec.example.com"),
ZoneFinder::NXDOMAIN,
mock_finder->empty_nsec_rrset_);
- EXPECT_THROW(Query(memory_client, Name("emptynsec.example.com"), qtype,
- response, true).process(),
+ EXPECT_THROW(query.process(memory_client, Name("emptynsec.example.com"),
+ qtype, response, true),
Query::BadNSEC);
}
@@ -1253,8 +1277,8 @@ TEST_F(QueryTest, nxdomainBadNSEC3) {
mock_finder->setNSECResult(Name("*.example.com"),
ZoneFinder::SUCCESS,
mock_finder->dname_rrset_);
- EXPECT_THROW(Query(memory_client, Name("nxdomain.example.com"), qtype,
- response, true).process(),
+ EXPECT_THROW(query.process(memory_client, Name("nxdomain.example.com"),
+ qtype, response, true),
Query::BadNSEC);
}
@@ -1262,8 +1286,8 @@ TEST_F(QueryTest, nxdomainBadNSEC4) {
// "no-wildcard proof" doesn't return RRset.
mock_finder->setNSECResult(Name("*.example.com"),
ZoneFinder::NXDOMAIN, ConstRRsetPtr());
- EXPECT_THROW(Query(memory_client, Name("nxdomain.example.com"), qtype,
- response, true).process(),
+ EXPECT_THROW(query.process(memory_client, Name("nxdomain.example.com"),
+ qtype, response, true),
Query::BadNSEC);
}
@@ -1273,8 +1297,8 @@ TEST_F(QueryTest, nxdomainBadNSEC5) {
ZoneFinder::NXDOMAIN,
mock_finder->dname_rrset_);
// This is a bit odd, but we'll simply include the returned RRset.
- Query(memory_client, Name("nxdomain.example.com"), qtype,
- response, true).process();
+ query.process(memory_client, Name("nxdomain.example.com"), qtype,
+ response, true);
responseCheck(response, Rcode::NXDOMAIN(), AA_FLAG, 0, 6, 0,
NULL, (string(soa_txt) +
string("example.com. 3600 IN RRSIG ") +
@@ -1293,14 +1317,14 @@ TEST_F(QueryTest, nxdomainBadNSEC6) {
mock_finder->setNSECResult(Name("*.example.com"),
ZoneFinder::NXDOMAIN,
mock_finder->empty_nsec_rrset_);
- EXPECT_THROW(Query(memory_client, Name("nxdomain.example.com"), qtype,
- response, true).process(),
+ EXPECT_THROW(query.process(memory_client, Name("nxdomain.example.com"),
+ qtype, response, true),
Query::BadNSEC);
}
TEST_F(QueryTest, nxrrset) {
- EXPECT_NO_THROW(Query(memory_client, Name("www.example.com"),
- RRType::TXT(), response).process());
+ EXPECT_NO_THROW(query.process(memory_client, Name("www.example.com"),
+ RRType::TXT(), response));
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 0, 1, 0,
NULL, soa_txt, NULL, mock_finder->getOrigin());
@@ -1309,8 +1333,8 @@ TEST_F(QueryTest, nxrrset) {
TEST_F(QueryTest, nxrrsetWithNSEC) {
// NXRRSET with DNSSEC proof. We should have SOA, NSEC that proves the
// NXRRSET and their RRSIGs.
- Query(memory_client, Name("www.example.com"), RRType::TXT(), response,
- true).process();
+ query.process(memory_client, Name("www.example.com"), RRType::TXT(),
+ response, true);
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 0, 4, 0, NULL,
(string(soa_txt) + string("example.com. 3600 IN RRSIG ") +
@@ -1330,8 +1354,8 @@ TEST_F(QueryTest, emptyNameWithNSEC) {
// exact match), so we only need one NSEC.
// From the point of the Query::process(), this is actually no different
// from the other NXRRSET case, but we check that explicitly just in case.
- Query(memory_client, Name("no.example.com"), RRType::A(), response,
- true).process();
+ query.process(memory_client, Name("no.example.com"), RRType::A(),
+ response, true);
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 0, 4, 0, NULL,
(string(soa_txt) + string("example.com. 3600 IN RRSIG ") +
@@ -1346,8 +1370,8 @@ TEST_F(QueryTest, nxrrsetWithoutNSEC) {
// NXRRSET with DNSSEC proof requested, but there's no NSEC at that node.
// This is an unexpected event (if the zone is supposed to be properly
// signed with NSECs), but we accept and ignore the oddity.
- Query(memory_client, Name("nonsec.example.com"), RRType::TXT(), response,
- true).process();
+ query.process(memory_client, Name("nonsec.example.com"), RRType::TXT(),
+ response, true);
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 0, 2, 0, NULL,
(string(soa_txt) + string("example.com. 3600 IN RRSIG ") +
@@ -1358,8 +1382,8 @@ TEST_F(QueryTest, nxrrsetWithoutNSEC) {
TEST_F(QueryTest, wildcardNSEC) {
// The qname matches *.wild.example.com. The response should contain
// an NSEC that proves the non existence of a closer name.
- Query(memory_client, Name("www.wild.example.com"), RRType::A(), response,
- true).process();
+ query.process(memory_client, Name("www.wild.example.com"), RRType::A(),
+ response, true);
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 2, 6, 6,
(string(wild_txt).replace(0, 1, "www") +
string("www.wild.example.com. 3600 IN RRSIG ") +
@@ -1378,8 +1402,8 @@ TEST_F(QueryTest, wildcardNSEC) {
TEST_F(QueryTest, CNAMEwildNSEC) {
// Similar to the previous case, but the matching wildcard record is
// CNAME.
- Query(memory_client, Name("www.cnamewild.example.com"), RRType::A(),
- response, true).process();
+ query.process(memory_client, Name("www.cnamewild.example.com"),
+ RRType::A(), response, true);
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 2, 2, 0,
(string(cnamewild_txt).replace(0, 1, "www") +
string("www.cnamewild.example.com. 3600 IN RRSIG ") +
@@ -1401,8 +1425,8 @@ TEST_F(QueryTest, wildcardNSEC3) {
// of identifying the next closer name.
mock_finder->addRecord(nsec3_atwild_txt);
- Query(memory_client, Name("x.y.wild.example.com"), RRType::A(), response,
- true).process();
+ query.process(memory_client, Name("x.y.wild.example.com"), RRType::A(),
+ response, true);
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 2, 6, 6,
(string(wild_txt).replace(0, 1, "x.y") +
string("x.y.wild.example.com. 3600 IN RRSIG ") +
@@ -1426,8 +1450,8 @@ TEST_F(QueryTest, CNAMEwildNSEC3) {
mock_finder->setNSEC3Flag(true);
mock_finder->addRecord(nsec3_atcnamewild_txt);
- Query(memory_client, Name("www.cnamewild.example.com"), RRType::A(),
- response, true).process();
+ query.process(memory_client, Name("www.cnamewild.example.com"),
+ RRType::A(), response, true);
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 2, 2, 0,
(string(cnamewild_txt).replace(0, 1, "www") +
string("www.cnamewild.example.com. 3600 IN RRSIG ") +
@@ -1449,8 +1473,8 @@ TEST_F(QueryTest, badWildcardNSEC3) {
ConstRRsetPtr());
mock_finder->setNSEC3Result(&nsec3);
- EXPECT_THROW(Query(memory_client, Name("www.wild.example.com"),
- RRType::A(), response, true).process(),
+ EXPECT_THROW(query.process(memory_client, Name("www.wild.example.com"),
+ RRType::A(), response, true),
Query::BadNSEC3);
}
@@ -1460,8 +1484,8 @@ TEST_F(QueryTest, badWildcardProof1) {
mock_finder->setNSECResult(Name("www.wild.example.com"),
ZoneFinder::SUCCESS,
mock_finder->dname_rrset_);
- EXPECT_THROW(Query(memory_client, Name("www.wild.example.com"),
- RRType::A(), response, true).process(),
+ EXPECT_THROW(query.process(memory_client, Name("www.wild.example.com"),
+ RRType::A(), response, true),
Query::BadNSEC);
}
@@ -1469,8 +1493,8 @@ TEST_F(QueryTest, badWildcardProof2) {
// "wildcard proof" doesn't return RRset.
mock_finder->setNSECResult(Name("www.wild.example.com"),
ZoneFinder::NXDOMAIN, ConstRRsetPtr());
- EXPECT_THROW(Query(memory_client, Name("www.wild.example.com"),
- RRType::A(), response, true).process(),
+ EXPECT_THROW(query.process(memory_client, Name("www.wild.example.com"),
+ RRType::A(), response, true),
Query::BadNSEC);
}
@@ -1479,8 +1503,8 @@ TEST_F(QueryTest, badWildcardProof3) {
mock_finder->setNSECResult(Name("www.wild.example.com"),
ZoneFinder::NXDOMAIN,
mock_finder->empty_nsec_rrset_);
- EXPECT_THROW(Query(memory_client, Name("www.wild.example.com"),
- RRType::A(), response, true).process(),
+ EXPECT_THROW(query.process(memory_client, Name("www.wild.example.com"),
+ RRType::A(), response, true),
Query::BadNSEC);
}
@@ -1488,8 +1512,8 @@ TEST_F(QueryTest, wildcardNxrrsetWithDuplicateNSEC) {
// NXRRSET on WILDCARD with DNSSEC proof. We should have SOA, NSEC that
// proves the NXRRSET and their RRSIGs. In this case we only need one NSEC,
// which proves both NXDOMAIN and the non existence RRSETs of wildcard.
- Query(memory_client, Name("www.wild.example.com"), RRType::TXT(), response,
- true).process();
+ query.process(memory_client, Name("www.wild.example.com"), RRType::TXT(),
+ response, true);
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 0, 4, 0, NULL,
(string(soa_txt) + string("example.com. 3600 IN RRSIG ") +
@@ -1505,8 +1529,8 @@ TEST_F(QueryTest, wildcardNxrrsetWithNSEC) {
// proves the NXRRSET and their RRSIGs. In this case we need two NSEC RRs,
// one proves NXDOMAIN and the other proves non existence RRSETs of
// wildcard.
- Query(memory_client, Name("www1.uwild.example.com"), RRType::TXT(),
- response, true).process();
+ query.process(memory_client, Name("www1.uwild.example.com"),
+ RRType::TXT(), response, true);
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 0, 6, 0, NULL,
(string(soa_txt) + string("example.com. 3600 IN RRSIG ") +
@@ -1528,8 +1552,8 @@ TEST_F(QueryTest, wildcardNxrrsetWithNSEC3) {
mock_finder->addRecord(nsec3_uwild_txt);
mock_finder->setNSEC3Flag(true);
- Query(memory_client, Name("www1.uwild.example.com"), RRType::TXT(),
- response, true).process();
+ query.process(memory_client, Name("www1.uwild.example.com"),
+ RRType::TXT(), response, true);
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 0, 8, 0, NULL,
// SOA + its RRSIG
@@ -1562,8 +1586,8 @@ TEST_F(QueryTest, wildcardNxrrsetWithNSEC3Collision) {
ConstRRsetPtr());
mock_finder->setNSEC3Result(&nsec3);
- EXPECT_THROW(Query(memory_client, Name("www1.uwild.example.com"),
- RRType::TXT(), response, true).process(),
+ EXPECT_THROW(query.process(memory_client, Name("www1.uwild.example.com"),
+ RRType::TXT(), response, true),
Query::BadNSEC3);
}
@@ -1579,8 +1603,8 @@ TEST_F(QueryTest, wildcardNxrrsetWithNSEC3Broken) {
mock_finder->addRecord(nsec3_wild_txt);
mock_finder->addRecord(nsec3_uwild_txt);
- EXPECT_THROW(Query(memory_client, Name("www1.uwild.example.com"),
- RRType::TXT(), response, true).process(),
+ EXPECT_THROW(query.process(memory_client, Name("www1.uwild.example.com"),
+ RRType::TXT(), response, true),
Query::BadNSEC3);
}
@@ -1588,8 +1612,8 @@ TEST_F(QueryTest, wildcardEmptyWithNSEC) {
// Empty WILDCARD with DNSSEC proof. We should have SOA, NSEC that proves
// the NXDOMAIN and their RRSIGs. In this case we need two NSEC RRs,
// one proves NXDOMAIN and the other proves non existence wildcard.
- Query(memory_client, Name("a.t.example.com"), RRType::A(), response,
- true).process();
+ query.process(memory_client, Name("a.t.example.com"), RRType::A(),
+ response, true);
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 0, 6, 0, NULL,
(string(soa_txt) + string("example.com. 3600 IN RRSIG ") +
@@ -1612,19 +1636,19 @@ TEST_F(QueryTest, noSOA) {
mock_finder->setSOAFlag(false);
// The NX Domain
- EXPECT_THROW(Query(memory_client, Name("nxdomain.example.com"),
- qtype, response).process(), Query::NoSOA);
+ EXPECT_THROW(query.process(memory_client, Name("nxdomain.example.com"),
+ qtype, response), Query::NoSOA);
// Of course, we don't look into the response, as it throwed
// NXRRSET
- EXPECT_THROW(Query(memory_client, Name("nxrrset.example.com"),
- qtype, response).process(), Query::NoSOA);
+ EXPECT_THROW(query.process(memory_client, Name("nxrrset.example.com"),
+ qtype, response), Query::NoSOA);
}
TEST_F(QueryTest, noMatchZone) {
// there's a zone in the memory datasource but it doesn't match the qname.
// should result in REFUSED.
- Query(memory_client, Name("example.org"), qtype, response).process();
+ query.process(memory_client, Name("example.org"), qtype, response);
EXPECT_EQ(Rcode::REFUSED(), response.getRcode());
}
@@ -1635,8 +1659,8 @@ TEST_F(QueryTest, noMatchZone) {
* A record, other to unknown out of zone one.
*/
TEST_F(QueryTest, MX) {
- Query(memory_client, Name("mx.example.com"), RRType::MX(),
- response).process();
+ query.process(memory_client, Name("mx.example.com"), RRType::MX(),
+ response);
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 3, 3, 4,
mx_txt, NULL,
@@ -1649,8 +1673,8 @@ TEST_F(QueryTest, MX) {
* This should not trigger the additional processing for the exchange.
*/
TEST_F(QueryTest, MXAlias) {
- Query(memory_client, Name("cnamemx.example.com"), RRType::MX(),
- response).process();
+ query.process(memory_client, Name("cnamemx.example.com"), RRType::MX(),
+ response);
// there shouldn't be no additional RRs for the exchanges (we have 3
// RRs for the NS). The normal MX case is tested separately so we don't
@@ -1669,8 +1693,8 @@ TEST_F(QueryTest, MXAlias) {
* returned.
*/
TEST_F(QueryTest, CNAME) {
- Query(memory_client, Name("cname.example.com"), RRType::A(),
- response).process();
+ query.process(memory_client, Name("cname.example.com"), RRType::A(),
+ response);
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 1, 0, 0,
cname_txt, NULL, NULL);
@@ -1679,8 +1703,8 @@ TEST_F(QueryTest, CNAME) {
TEST_F(QueryTest, explicitCNAME) {
// same owner name as the CNAME test but explicitly query for CNAME RR.
// expect the same response as we don't provide a full chain yet.
- Query(memory_client, Name("cname.example.com"), RRType::CNAME(),
- response).process();
+ query.process(memory_client, Name("cname.example.com"), RRType::CNAME(),
+ response);
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 1, 3, 3,
cname_txt, zone_ns_txt, ns_addrs_txt);
@@ -1691,8 +1715,8 @@ TEST_F(QueryTest, CNAME_NX_RRSET) {
// note: with chaining, what should be expected is not trivial:
// BIND 9 returns the CNAME in answer and SOA in authority, no additional.
// NSD returns the CNAME, NS in authority, A/AAAA for NS in additional.
- Query(memory_client, Name("cname.example.com"), RRType::TXT(),
- response).process();
+ query.process(memory_client, Name("cname.example.com"), RRType::TXT(),
+ response);
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 1, 0, 0,
cname_txt, NULL, NULL);
@@ -1700,8 +1724,8 @@ TEST_F(QueryTest, CNAME_NX_RRSET) {
TEST_F(QueryTest, explicitCNAME_NX_RRSET) {
// same owner name as the NXRRSET test but explicitly query for CNAME RR.
- Query(memory_client, Name("cname.example.com"), RRType::CNAME(),
- response).process();
+ query.process(memory_client, Name("cname.example.com"), RRType::CNAME(),
+ response);
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 1, 3, 3,
cname_txt, zone_ns_txt, ns_addrs_txt);
@@ -1714,8 +1738,8 @@ TEST_F(QueryTest, CNAME_NX_DOMAIN) {
// RCODE being NXDOMAIN.
// NSD returns the CNAME, NS in authority, A/AAAA for NS in additional,
// RCODE being NOERROR.
- Query(memory_client, Name("cnamenxdom.example.com"), RRType::A(),
- response).process();
+ query.process(memory_client, Name("cnamenxdom.example.com"), RRType::A(),
+ response);
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 1, 0, 0,
cname_nxdom_txt, NULL, NULL);
@@ -1723,8 +1747,8 @@ TEST_F(QueryTest, CNAME_NX_DOMAIN) {
TEST_F(QueryTest, explicitCNAME_NX_DOMAIN) {
// same owner name as the NXDOMAIN test but explicitly query for CNAME RR.
- Query(memory_client, Name("cnamenxdom.example.com"), RRType::CNAME(),
- response).process();
+ query.process(memory_client, Name("cnamenxdom.example.com"),
+ RRType::CNAME(), response);
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 1, 3, 3,
cname_nxdom_txt, zone_ns_txt, ns_addrs_txt);
@@ -1739,8 +1763,8 @@ TEST_F(QueryTest, CNAME_OUT) {
* Then the same test should be done with .org included there and
* see what it does (depends on what we want to do)
*/
- Query(memory_client, Name("cnameout.example.com"), RRType::A(),
- response).process();
+ query.process(memory_client, Name("cnameout.example.com"), RRType::A(),
+ response);
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 1, 0, 0,
cname_out_txt, NULL, NULL);
@@ -1748,8 +1772,8 @@ TEST_F(QueryTest, CNAME_OUT) {
TEST_F(QueryTest, explicitCNAME_OUT) {
// same owner name as the OUT test but explicitly query for CNAME RR.
- Query(memory_client, Name("cnameout.example.com"), RRType::CNAME(),
- response).process();
+ query.process(memory_client, Name("cnameout.example.com"), RRType::CNAME(),
+ response);
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 1, 3, 3,
cname_out_txt, zone_ns_txt, ns_addrs_txt);
@@ -1764,8 +1788,8 @@ TEST_F(QueryTest, explicitCNAME_OUT) {
* pointing to NXRRSET and NXDOMAIN cases (similarly as with CNAME).
*/
TEST_F(QueryTest, DNAME) {
- Query(memory_client, Name("www.dname.example.com"), RRType::A(),
- response).process();
+ query.process(memory_client, Name("www.dname.example.com"), RRType::A(),
+ response);
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 2, 0, 0,
(string(dname_txt) + synthetized_cname_txt).c_str(),
@@ -1780,8 +1804,8 @@ TEST_F(QueryTest, DNAME) {
* DNAME.
*/
TEST_F(QueryTest, DNAME_ANY) {
- Query(memory_client, Name("www.dname.example.com"), RRType::ANY(),
- response).process();
+ query.process(memory_client, Name("www.dname.example.com"), RRType::ANY(),
+ response);
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 2, 0, 0,
(string(dname_txt) + synthetized_cname_txt).c_str(), NULL, NULL);
@@ -1789,8 +1813,8 @@ TEST_F(QueryTest, DNAME_ANY) {
// Test when we ask for DNAME explicitly, it does no synthetizing.
TEST_F(QueryTest, explicitDNAME) {
- Query(memory_client, Name("dname.example.com"), RRType::DNAME(),
- response).process();
+ query.process(memory_client, Name("dname.example.com"), RRType::DNAME(),
+ response);
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 1, 3, 3,
dname_txt, zone_ns_txt, ns_addrs_txt);
@@ -1801,8 +1825,8 @@ TEST_F(QueryTest, explicitDNAME) {
* the CNAME, it should return the RRset.
*/
TEST_F(QueryTest, DNAME_A) {
- Query(memory_client, Name("dname.example.com"), RRType::A(),
- response).process();
+ query.process(memory_client, Name("dname.example.com"), RRType::A(),
+ response);
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 1, 3, 3,
dname_a_txt, zone_ns_txt, ns_addrs_txt);
@@ -1813,8 +1837,8 @@ TEST_F(QueryTest, DNAME_A) {
* It should not synthetize the CNAME.
*/
TEST_F(QueryTest, DNAME_NX_RRSET) {
- EXPECT_NO_THROW(Query(memory_client, Name("dname.example.com"),
- RRType::TXT(), response).process());
+ EXPECT_NO_THROW(query.process(memory_client, Name("dname.example.com"),
+ RRType::TXT(), response));
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 0, 1, 0,
NULL, soa_txt, NULL, mock_finder->getOrigin());
@@ -1833,8 +1857,8 @@ TEST_F(QueryTest, LongDNAME) {
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa."
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa."
"dname.example.com.");
- EXPECT_NO_THROW(Query(memory_client, longname, RRType::A(),
- response).process());
+ EXPECT_NO_THROW(query.process(memory_client, longname, RRType::A(),
+ response));
responseCheck(response, Rcode::YXDOMAIN(), AA_FLAG, 1, 0, 0,
dname_txt, NULL, NULL);
@@ -1852,8 +1876,8 @@ TEST_F(QueryTest, MaxLenDNAME) {
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa."
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa."
"dname.example.com.");
- EXPECT_NO_THROW(Query(memory_client, longname, RRType::A(),
- response).process());
+ EXPECT_NO_THROW(query.process(memory_client, longname, RRType::A(),
+ response));
// Check the answer is OK
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 2, 0, 0,
@@ -2038,8 +2062,9 @@ TEST_F(QueryTest, dsAboveDelegation) {
// The following will succeed only if the search goes to the parent
// zone, not the child one we added above.
- EXPECT_NO_THROW(Query(memory_client, Name("delegation.example.com"),
- RRType::DS(), response, true).process());
+ EXPECT_NO_THROW(query.process(memory_client,
+ Name("delegation.example.com"),
+ RRType::DS(), response, true));
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 2, 4, 6,
(string(delegation_ds_txt) + "\n" +
@@ -2061,9 +2086,9 @@ TEST_F(QueryTest, dsAboveDelegationNoData) {
// The following will succeed only if the search goes to the parent
// zone, not the child one we added above.
- EXPECT_NO_THROW(Query(memory_client,
- Name("unsigned-delegation.example.com"),
- RRType::DS(), response, true).process());
+ EXPECT_NO_THROW(query.process(memory_client,
+ Name("unsigned-delegation.example.com"),
+ RRType::DS(), response, true));
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 0, 4, 0, NULL,
(string(soa_txt) +
@@ -2079,8 +2104,8 @@ TEST_F(QueryTest, dsAboveDelegationNoData) {
// when it happens to be sent to the child zone, as described in RFC 4035,
// section 3.1.4.1. The example is inspired by the B.8. example from the RFC.
TEST_F(QueryTest, dsBelowDelegation) {
- EXPECT_NO_THROW(Query(memory_client, Name("example.com"),
- RRType::DS(), response, true).process());
+ EXPECT_NO_THROW(query.process(memory_client, Name("example.com"),
+ RRType::DS(), response, true));
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 0, 4, 0, NULL,
(string(soa_txt) + string("example.com. 3600 IN RRSIG ") +
@@ -2096,8 +2121,8 @@ TEST_F(QueryTest, dsBelowDelegation) {
// In our implementation NSEC/NSEC3 isn't attached in this case.
TEST_F(QueryTest, dsBelowDelegationWithDS) {
mock_finder->addRecord(zone_ds_txt); // add the DS to the child's apex
- EXPECT_NO_THROW(Query(memory_client, Name("example.com"),
- RRType::DS(), response, true).process());
+ EXPECT_NO_THROW(query.process(memory_client, Name("example.com"),
+ RRType::DS(), response, true));
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 0, 2, 0, NULL,
(string(soa_txt) + string("example.com. 3600 IN RRSIG ") +
@@ -2109,16 +2134,16 @@ TEST_F(QueryTest, dsBelowDelegationWithDS) {
// server. It should just like the "noZone" test case, but DS query involves
// special processing, so we test it explicitly.
TEST_F(QueryTest, dsNoZone) {
- Query(memory_client, Name("example"), RRType::DS(), response,
- true).process();
+ query.process(memory_client, Name("example"), RRType::DS(), response,
+ true);
responseCheck(response, Rcode::REFUSED(), 0, 0, 0, 0, NULL, NULL, NULL);
}
// DS query for a "grandchild" zone. This should result in normal
// delegation (unless this server also has authority of the grandchild zone).
TEST_F(QueryTest, dsAtGrandParent) {
- Query(memory_client, Name("grand.delegation.example.com"), RRType::DS(),
- response, true).process();
+ query.process(memory_client, Name("grand.delegation.example.com"),
+ RRType::DS(), response, true);
responseCheck(response, Rcode::NOERROR(), 0, 0, 6, 6, NULL,
(string(delegation_txt) + string(delegation_ds_txt) +
"delegation.example.com. 3600 IN RRSIG " +
@@ -2136,7 +2161,7 @@ TEST_F(QueryTest, dsAtGrandParentAndChild) {
const Name childname("grand.delegation.example.com");
memory_client.addZone(ZoneFinderPtr(
new AlternateZoneFinder(childname)));
- Query(memory_client, childname, RRType::DS(), response, true).process();
+ query.process(memory_client, childname, RRType::DS(), response, true);
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 0, 4, 0, NULL,
(childname.toText() + " 3600 IN SOA . . 0 0 0 0 0\n" +
childname.toText() + " 3600 IN RRSIG " +
@@ -2154,8 +2179,8 @@ TEST_F(QueryTest, dsAtRoot) {
// Pretend to be a root server.
memory_client.addZone(ZoneFinderPtr(
new AlternateZoneFinder(Name::ROOT_NAME())));
- Query(memory_client, Name::ROOT_NAME(), RRType::DS(), response,
- true).process();
+ query.process(memory_client, Name::ROOT_NAME(), RRType::DS(), response,
+ true);
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 0, 4, 0, NULL,
(string(". 3600 IN SOA . . 0 0 0 0 0\n") +
". 3600 IN RRSIG " + getCommonRRSIGText("SOA") + "\n" +
@@ -2171,8 +2196,8 @@ TEST_F(QueryTest, dsAtRootWithDS) {
memory_client.addZone(ZoneFinderPtr(
new AlternateZoneFinder(Name::ROOT_NAME(),
true)));
- Query(memory_client, Name::ROOT_NAME(), RRType::DS(), response,
- true).process();
+ query.process(memory_client, Name::ROOT_NAME(), RRType::DS(), response,
+ true);
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 2, 2, 0,
(string(". 3600 IN DS 57855 5 1 49FD46E6C4B45C55D4AC69CBD"
"3CD34AC1AFE51DE\n") +
@@ -2188,8 +2213,8 @@ TEST_F(QueryTest, nxrrsetWithNSEC3) {
// NXRRSET with DNSSEC proof. We should have SOA, NSEC3 that proves the
// NXRRSET and their RRSIGs.
- Query(memory_client, Name("www.example.com"), RRType::TXT(), response,
- true).process();
+ query.process(memory_client, Name("www.example.com"), RRType::TXT(),
+ response, true);
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 0, 4, 0, NULL,
(string(soa_txt) + string("example.com. 3600 IN RRSIG ") +
@@ -2211,8 +2236,9 @@ TEST_F(QueryTest, nxrrsetMissingNSEC3) {
ConstRRsetPtr());
mock_finder->setNSEC3Result(&nsec3);
- EXPECT_THROW(Query(memory_client, Name("www.example.com"), RRType::TXT(),
- response, true).process(), Query::BadNSEC3);
+ EXPECT_THROW(query.process(memory_client, Name("www.example.com"),
+ RRType::TXT(), response, true),
+ Query::BadNSEC3);
}
TEST_F(QueryTest, nxrrsetWithNSEC3_ds_exact) {
@@ -2221,8 +2247,8 @@ TEST_F(QueryTest, nxrrsetWithNSEC3_ds_exact) {
// This delegation has no DS, but does have a matching NSEC3 record
// (See RFC5155 section 7.2.4)
- Query(memory_client, Name("unsigned-delegation.example.com."),
- RRType::DS(), response, true).process();
+ query.process(memory_client, Name("unsigned-delegation.example.com."),
+ RRType::DS(), response, true);
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 0, 4, 0, NULL,
(string(soa_txt) + string("example.com. 3600 IN RRSIG ") +
getCommonRRSIGText("SOA") + "\n" +
@@ -2243,8 +2269,8 @@ TEST_F(QueryTest, nxrrsetWithNSEC3_ds_no_exact) {
// 'next closer' should have opt-out set, though that is not
// actually checked)
// (See RFC5155 section 7.2.4)
- Query(memory_client, Name("unsigned-delegation-optout.example.com."),
- RRType::DS(), response, true).process();
+ query.process(memory_client, Name("unsigned-delegation-optout.example.com."),
+ RRType::DS(), response, true);
responseCheck(response, Rcode::NOERROR(), AA_FLAG, 0, 6, 0, NULL,
(string(soa_txt) + string("example.com. 3600 IN RRSIG ") +
getCommonRRSIGText("SOA") + "\n" +
@@ -2270,8 +2296,8 @@ TEST_F(QueryTest, nxdomainWithNSEC3Proof) {
// This will be the covering NSEC3 for the possible wildcard
mock_finder->addRecord(unsigned_delegation_nsec3_txt);
- Query(memory_client, Name("nxdomain.example.com"), qtype,
- response, true).process();
+ query.process(memory_client, Name("nxdomain.example.com"), qtype,
+ response, true);
responseCheck(response, Rcode::NXDOMAIN(), AA_FLAG, 0, 8, 0, NULL,
// SOA + its RRSIG
(string(soa_txt) +
@@ -2305,8 +2331,8 @@ TEST_F(QueryTest, nxdomainWithBadNextNSEC3Proof) {
ConstRRsetPtr());
mock_finder->setNSEC3Result(&nsec3);
- EXPECT_THROW(Query(memory_client, Name("nxdomain.example.com"),
- RRType::TXT(), response, true).process(),
+ EXPECT_THROW(query.process(memory_client, Name("nxdomain.example.com"),
+ RRType::TXT(), response, true),
Query::BadNSEC3);
}
@@ -2324,8 +2350,8 @@ TEST_F(QueryTest, nxdomainWithBadWildcardNSEC3Proof) {
ConstRRsetPtr());
mock_finder->setNSEC3Result(&nsec3, &wname);
- EXPECT_THROW(Query(memory_client, Name("nxdomain.example.com"), qtype,
- response, true).process(),
+ EXPECT_THROW(query.process(memory_client, Name("nxdomain.example.com"), qtype,
+ response, true),
Query::BadNSEC3);
}
diff --git a/tests/lettuce/configurations/example.org.inmem.config b/tests/lettuce/configurations/example.org.inmem.config
new file mode 100644
index 0000000..fa5f954
--- /dev/null
+++ b/tests/lettuce/configurations/example.org.inmem.config
@@ -0,0 +1 @@
+{"version": 2, "Logging": {"loggers": [{"severity": "DEBUG", "name": "auth", "debuglevel": 99}]}, "Auth": {"database_file": "", "listen_on": [{"port": 47806, "address": "127.0.0.1"}], "datasources": [{"zones": [{"origin": "example.org", "file": "data/example.org"}], "type": "memory"}]}}
diff --git a/tests/lettuce/data/example.org b/tests/lettuce/data/example.org
new file mode 100644
index 0000000..20a93be
--- /dev/null
+++ b/tests/lettuce/data/example.org
@@ -0,0 +1,12 @@
+example.org. 3600 IN SOA ns1.example.org. admin.example.org. 1234 3600 1800 2419200 7200
+example.org. 3600 IN NS ns1.example.org.
+example.org. 3600 IN NS ns2.example.org.
+example.org. 3600 IN MX 10 mail.example.org.
+www.example.org. 3600 IN A 192.0.2.1
+mail.example.org. 3600 IN A 192.0.2.10
+sub.example.org. 3600 IN NS ns.sub.example.org.
+ns.sub.example.org. 3600 IN A 192.0.2.101
+dname.example.org. 3600 IN DNAME dname.example.info.
+dname2.foo.example.org. 3600 IN DNAME dname2.example.info.
+ns1.example.org. 3600 IN A 192.0.2.3
+ns2.example.org. 3600 IN A 192.0.2.4
diff --git a/tests/lettuce/features/queries.feature b/tests/lettuce/features/queries.feature
new file mode 100644
index 0000000..b8f9b3d
--- /dev/null
+++ b/tests/lettuce/features/queries.feature
@@ -0,0 +1,81 @@
+Feature: Querying feature
+ This feature is a collection of non-specific querying tests;
+ for instance whether multiple queries in a row return consistent
+ answers.
+
+ Scenario: Repeated queries
+ Given I have bind10 running with configuration example.org.inmem.config
+ A query for www.example.org should have rcode NOERROR
+ The last query response should have flags qr aa rd
+ The last query response should have ancount 1
+ The last query response should have nscount 2
+ The last query response should have adcount 2
+
+ The answer section of the last query response should be
+ """
+ www.example.org. 3600 IN A 192.0.2.1
+ """
+ The authority section of the last query response should be
+ """
+ example.org. 3600 IN NS ns1.example.org.
+ example.org. 3600 IN NS ns2.example.org.
+ """
+ The additional section of the last query response should be
+ """
+ ns1.example.org. 3600 IN A 192.0.2.3
+ ns2.example.org. 3600 IN A 192.0.2.4
+ """
+
+ # Repeat of the above
+ A query for www.example.org should have rcode NOERROR
+ The last query response should have flags qr aa rd
+ The last query response should have ancount 1
+ The last query response should have nscount 2
+ The last query response should have adcount 2
+
+ The answer section of the last query response should be
+ """
+ www.example.org. 3600 IN A 192.0.2.1
+ """
+ The authority section of the last query response should be
+ """
+ example.org. 3600 IN NS ns1.example.org.
+ example.org. 3600 IN NS ns2.example.org.
+ """
+ The additional section of the last query response should be
+ """
+ ns1.example.org. 3600 IN A 192.0.2.3
+ ns2.example.org. 3600 IN A 192.0.2.4
+ """
+
+ # And now query something completely different
+ A query for nosuchname.example.org should have rcode NXDOMAIN
+ The last query response should have flags qr aa rd
+ The last query response should have ancount 0
+ The last query response should have nscount 1
+ The last query response should have adcount 0
+ The authority section of the last query response should be
+ """
+ example.org. 3600 IN SOA ns1.example.org. admin.example.org. 1234 3600 1800 2419200 7200
+ """
+
+ Scenario: ANY query
+ Given I have bind10 running with configuration example.org.inmem.config
+ A query for example.org type ANY should have rcode NOERROR
+ The last query response should have flags qr aa rd
+ The last query response should have ancount 4
+ The last query response should have nscount 0
+ The last query response should have adcount 3
+ The answer section of the last query response should be
+ """
+ example.org. 3600 IN NS ns1.example.org.
+ example.org. 3600 IN NS ns2.example.org.
+ example.org. 3600 IN SOA ns1.example.org. admin.example.org. 1234 3600 1800 2419200 7200
+ example.org. 3600 IN MX 10 mail.example.org.
+ """
+ The additional section of the last query response should be
+ """
+ ns1.example.org. 3600 IN A 192.0.2.3
+ ns2.example.org. 3600 IN A 192.0.2.4
+ mail.example.org. 3600 IN A 192.0.2.10
+ """
More information about the bind10-changes
mailing list