|
@@ -49,14 +49,15 @@ using namespace isc::dns;
|
|
using namespace isc::dns::rdata;
|
|
using namespace isc::dns::rdata;
|
|
|
|
|
|
namespace isc {
|
|
namespace isc {
|
|
-namespace auth {
|
|
+namespace datasrc {
|
|
|
|
|
|
typedef boost::shared_ptr<const Nsec3Param> ConstNsec3ParamPtr;
|
|
typedef boost::shared_ptr<const Nsec3Param> ConstNsec3ParamPtr;
|
|
|
|
|
|
|
|
+namespace {
|
|
// Add a task to the query task queue to look up additional data
|
|
// Add a task to the query task queue to look up additional data
|
|
// (i.e., address records for the names included in NS or MX records)
|
|
// (i.e., address records for the names included in NS or MX records)
|
|
-static void
|
|
+void
|
|
-getAdditional(Query& q, RRsetPtr rrset) {
|
|
+getAdditional(Query& q, ConstRRsetPtr rrset) {
|
|
if (!q.wantAdditional()) {
|
|
if (!q.wantAdditional()) {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
@@ -64,31 +65,27 @@ getAdditional(Query& q, RRsetPtr rrset) {
|
|
RdataIteratorPtr it = rrset->getRdataIterator();
|
|
RdataIteratorPtr it = rrset->getRdataIterator();
|
|
for (it->first(); !it->isLast(); it->next()) {
|
|
for (it->first(); !it->isLast(); it->next()) {
|
|
const Rdata& rd(it->getCurrent());
|
|
const Rdata& rd(it->getCurrent());
|
|
- QueryTaskPtr newtask = QueryTaskPtr();
|
|
|
|
-
|
|
|
|
if (rrset->getType() == RRType::NS()) {
|
|
if (rrset->getType() == RRType::NS()) {
|
|
const generic::NS& ns = dynamic_cast<const generic::NS&>(rd);
|
|
const generic::NS& ns = dynamic_cast<const generic::NS&>(rd);
|
|
-
|
|
+ q.tasks().push(QueryTaskPtr(
|
|
- newtask = QueryTaskPtr(new QueryTask(ns.getNSName(), q.qclass(),
|
|
+ new QueryTask(ns.getNSName(), q.qclass(),
|
|
- Section::ADDITIONAL(),
|
|
+ Section::ADDITIONAL(),
|
|
- QueryTask::GLUE_QUERY,
|
|
+ QueryTask::GLUE_QUERY,
|
|
- QueryTask::GETADDITIONAL));
|
|
+ QueryTask::GETADDITIONAL)));
|
|
} else if (rrset->getType() == RRType::MX()) {
|
|
} else if (rrset->getType() == RRType::MX()) {
|
|
const generic::MX& mx = dynamic_cast<const generic::MX&>(rd);
|
|
const generic::MX& mx = dynamic_cast<const generic::MX&>(rd);
|
|
- newtask = QueryTaskPtr(new QueryTask(mx.getMXName(), q.qclass(),
|
|
+ q.tasks().push(QueryTaskPtr(
|
|
- Section::ADDITIONAL(),
|
|
+ new QueryTask(mx.getMXName(), q.qclass(),
|
|
- QueryTask::NOGLUE_QUERY,
|
|
+ Section::ADDITIONAL(),
|
|
- QueryTask::GETADDITIONAL));
|
|
+ QueryTask::NOGLUE_QUERY,
|
|
- }
|
|
+ QueryTask::GETADDITIONAL)));
|
|
- if (newtask) {
|
|
|
|
- q.tasks().push(newtask);
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// Synthesize a CNAME answer, for the benefit of clients that don't
|
|
// Synthesize a CNAME answer, for the benefit of clients that don't
|
|
// understand DNAME
|
|
// understand DNAME
|
|
-static void
|
|
+void
|
|
synthesizeCname(QueryTaskPtr task, RRsetPtr rrset, RRsetList& target) {
|
|
synthesizeCname(QueryTaskPtr task, RRsetPtr rrset, RRsetList& target) {
|
|
RdataIteratorPtr it = rrset->getRdataIterator();
|
|
RdataIteratorPtr it = rrset->getRdataIterator();
|
|
|
|
|
|
@@ -117,9 +114,8 @@ synthesizeCname(QueryTaskPtr task, RRsetPtr rrset, RRsetList& target) {
|
|
|
|
|
|
// Add a task to the query task queue to look up the data pointed
|
|
// Add a task to the query task queue to look up the data pointed
|
|
// to by a CNAME record
|
|
// to by a CNAME record
|
|
-static void
|
|
+void
|
|
-chaseCname(Query& q, QueryTaskPtr task, RRsetPtr rrset)
|
|
+chaseCname(Query& q, QueryTaskPtr task, RRsetPtr rrset) {
|
|
-{
|
|
|
|
RdataIteratorPtr it = rrset->getRdataIterator();
|
|
RdataIteratorPtr it = rrset->getRdataIterator();
|
|
|
|
|
|
// More than one CNAME RR in the RRset is illegal, so we only have
|
|
// More than one CNAME RR in the RRset is illegal, so we only have
|
|
@@ -143,7 +139,7 @@ chaseCname(Query& q, QueryTaskPtr task, RRsetPtr rrset)
|
|
}
|
|
}
|
|
|
|
|
|
// Perform the query specified in a QueryTask object
|
|
// Perform the query specified in a QueryTask object
|
|
-static DataSrc::Result
|
|
+DataSrc::Result
|
|
doQueryTask(const DataSrc* ds, const Name* zonename, QueryTask& task,
|
|
doQueryTask(const DataSrc* ds, const Name* zonename, QueryTask& task,
|
|
RRsetList& target)
|
|
RRsetList& target)
|
|
{
|
|
{
|
|
@@ -171,9 +167,8 @@ doQueryTask(const DataSrc* ds, const Name* zonename, QueryTask& task,
|
|
}
|
|
}
|
|
|
|
|
|
// Copy referral information into the authority section of a message
|
|
// Copy referral information into the authority section of a message
|
|
-static inline void
|
|
+inline void
|
|
-copyAuth(Query& q, RRsetList& auth)
|
|
+copyAuth(Query& q, RRsetList& auth) {
|
|
-{
|
|
|
|
BOOST_FOREACH(RRsetPtr rrset, auth) {
|
|
BOOST_FOREACH(RRsetPtr rrset, auth) {
|
|
if (rrset->getType() == RRType::DNAME()) {
|
|
if (rrset->getType() == RRType::DNAME()) {
|
|
continue;
|
|
continue;
|
|
@@ -187,11 +182,11 @@ copyAuth(Query& q, RRsetList& auth)
|
|
}
|
|
}
|
|
|
|
|
|
// Query for referrals (i.e., NS/DS or DNAME) at a given name
|
|
// Query for referrals (i.e., NS/DS or DNAME) at a given name
|
|
-static inline bool
|
|
+inline bool
|
|
-refQuery(const Name& name, Query& q, const DataSrc* ds, const Name* zonename,
|
|
+refQuery(const Name& name, const RRClass& qclass, const DataSrc* ds,
|
|
- RRsetList& target)
|
|
+ const Name* zonename, RRsetList& target)
|
|
{
|
|
{
|
|
- QueryTask newtask(name, q.qclass(), QueryTask::REF_QUERY);
|
|
+ QueryTask newtask(name, qclass, QueryTask::REF_QUERY);
|
|
|
|
|
|
if (doQueryTask(ds, zonename, newtask, target) != DataSrc::SUCCESS) {
|
|
if (doQueryTask(ds, zonename, newtask, target) != DataSrc::SUCCESS) {
|
|
// Lookup failed
|
|
// Lookup failed
|
|
@@ -208,18 +203,18 @@ refQuery(const Name& name, Query& q, const DataSrc* ds, const Name* zonename,
|
|
|
|
|
|
// Match downward, from the zone apex to the query name, looking for
|
|
// Match downward, from the zone apex to the query name, looking for
|
|
// referrals.
|
|
// referrals.
|
|
-static inline bool
|
|
+inline bool
|
|
hasDelegation(const DataSrc* ds, const Name* zonename, Query& q,
|
|
hasDelegation(const DataSrc* ds, const Name* zonename, Query& q,
|
|
QueryTaskPtr task)
|
|
QueryTaskPtr task)
|
|
{
|
|
{
|
|
- int nlen = task->qname.getLabelCount();
|
|
+ const int nlen = task->qname.getLabelCount();
|
|
- int diff = nlen - zonename->getLabelCount();
|
|
+ const int diff = nlen - zonename->getLabelCount();
|
|
if (diff > 1) {
|
|
if (diff > 1) {
|
|
bool found = false;
|
|
bool found = false;
|
|
RRsetList ref;
|
|
RRsetList ref;
|
|
for (int i = diff; i > 1; --i) {
|
|
for (int i = diff; i > 1; --i) {
|
|
const Name sub(task->qname.split(i - 1, nlen - i));
|
|
const Name sub(task->qname.split(i - 1, nlen - i));
|
|
- if (refQuery(sub, q, ds, zonename, ref)) {
|
|
+ if (refQuery(sub, q.qclass(), ds, zonename, ref)) {
|
|
found = true;
|
|
found = true;
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
@@ -267,7 +262,7 @@ hasDelegation(const DataSrc* ds, const Name* zonename, Query& q,
|
|
return (false);
|
|
return (false);
|
|
}
|
|
}
|
|
|
|
|
|
-static inline DataSrc::Result
|
|
+inline DataSrc::Result
|
|
addSOA(Query& q, const Name* zonename, const DataSrc* ds) {
|
|
addSOA(Query& q, const Name* zonename, const DataSrc* ds) {
|
|
Message& m = q.message();
|
|
Message& m = q.message();
|
|
RRsetList soa;
|
|
RRsetList soa;
|
|
@@ -284,7 +279,7 @@ addSOA(Query& q, const Name* zonename, const DataSrc* ds) {
|
|
return (DataSrc::SUCCESS);
|
|
return (DataSrc::SUCCESS);
|
|
}
|
|
}
|
|
|
|
|
|
-static inline DataSrc::Result
|
|
+inline DataSrc::Result
|
|
addNSEC(Query& q, const QueryTaskPtr task, const Name& name,
|
|
addNSEC(Query& q, const QueryTaskPtr task, const Name& name,
|
|
const Name& zonename, const DataSrc* ds)
|
|
const Name& zonename, const DataSrc* ds)
|
|
{
|
|
{
|
|
@@ -302,7 +297,7 @@ addNSEC(Query& q, const QueryTaskPtr task, const Name& name,
|
|
return (DataSrc::SUCCESS);
|
|
return (DataSrc::SUCCESS);
|
|
}
|
|
}
|
|
|
|
|
|
-static inline DataSrc::Result
|
|
+inline DataSrc::Result
|
|
getNsec3(const DataSrc* ds, const Name& zonename, const RRClass& qclass,
|
|
getNsec3(const DataSrc* ds, const Name& zonename, const RRClass& qclass,
|
|
string& hash, RRsetPtr& target)
|
|
string& hash, RRsetPtr& target)
|
|
{
|
|
{
|
|
@@ -312,7 +307,7 @@ getNsec3(const DataSrc* ds, const Name& zonename, const RRClass& qclass,
|
|
return (DataSrc::SUCCESS);
|
|
return (DataSrc::SUCCESS);
|
|
}
|
|
}
|
|
|
|
|
|
-static ConstNsec3ParamPtr
|
|
+ConstNsec3ParamPtr
|
|
getNsec3Param(Query& q, const DataSrc* ds, const Name& zonename) {
|
|
getNsec3Param(Query& q, const DataSrc* ds, const Name& zonename) {
|
|
DataSrc::Result result;
|
|
DataSrc::Result result;
|
|
RRsetList nsec3param;
|
|
RRsetList nsec3param;
|
|
@@ -345,7 +340,7 @@ getNsec3Param(Query& q, const DataSrc* ds, const Name& zonename) {
|
|
np.getSalt())));
|
|
np.getSalt())));
|
|
}
|
|
}
|
|
|
|
|
|
-static inline DataSrc::Result
|
|
+inline DataSrc::Result
|
|
proveNX(Query& q, QueryTaskPtr task, const DataSrc* ds,
|
|
proveNX(Query& q, QueryTaskPtr task, const DataSrc* ds,
|
|
const Name& zonename, const bool wildcard)
|
|
const Name& zonename, const bool wildcard)
|
|
{
|
|
{
|
|
@@ -354,7 +349,7 @@ proveNX(Query& q, QueryTaskPtr task, const DataSrc* ds,
|
|
if (nsec3 != NULL) {
|
|
if (nsec3 != NULL) {
|
|
// Attach the NSEC3 record covering the QNAME
|
|
// Attach the NSEC3 record covering the QNAME
|
|
RRsetPtr rrset;
|
|
RRsetPtr rrset;
|
|
- string hash1(nsec3->getHash(task->qname)), hash2;
|
|
+ string hash1(nsec3->getHash(task->qname));
|
|
RETERR(getNsec3(ds, zonename, q.qclass(), hash1, rrset));
|
|
RETERR(getNsec3(ds, zonename, q.qclass(), hash1, rrset));
|
|
m.addRRset(Section::AUTHORITY(), rrset, true);
|
|
m.addRRset(Section::AUTHORITY(), rrset, true);
|
|
|
|
|
|
@@ -365,8 +360,9 @@ proveNX(Query& q, QueryTaskPtr task, const DataSrc* ds,
|
|
|
|
|
|
// Find the closest provable enclosing name for QNAME
|
|
// Find the closest provable enclosing name for QNAME
|
|
Name enclosure(zonename);
|
|
Name enclosure(zonename);
|
|
- int nlen = task->qname.getLabelCount();
|
|
+ const int nlen = task->qname.getLabelCount();
|
|
- int diff = nlen - enclosure.getLabelCount();
|
|
+ const int diff = nlen - enclosure.getLabelCount();
|
|
|
|
+ string hash2;
|
|
for (int i = 1; i <= diff; ++i) {
|
|
for (int i = 1; i <= diff; ++i) {
|
|
enclosure = task->qname.split(i, nlen - i);
|
|
enclosure = task->qname.split(i, nlen - i);
|
|
string nodehash(nsec3->getHash(enclosure));
|
|
string nodehash(nsec3->getHash(enclosure));
|
|
@@ -424,7 +420,7 @@ proveNX(Query& q, QueryTaskPtr task, const DataSrc* ds,
|
|
}
|
|
}
|
|
|
|
|
|
// Attempt a wildcard lookup
|
|
// Attempt a wildcard lookup
|
|
-static inline DataSrc::Result
|
|
+inline DataSrc::Result
|
|
tryWildcard(Query& q, QueryTaskPtr task, const DataSrc* ds,
|
|
tryWildcard(Query& q, QueryTaskPtr task, const DataSrc* ds,
|
|
const Name* zonename, bool& found)
|
|
const Name* zonename, bool& found)
|
|
{
|
|
{
|
|
@@ -502,7 +498,7 @@ tryWildcard(Query& q, QueryTaskPtr task, const DataSrc* ds,
|
|
}
|
|
}
|
|
|
|
|
|
RRsetList auth;
|
|
RRsetList auth;
|
|
- if (! refQuery(*zonename, q, ds, zonename, auth)) {
|
|
+ if (!refQuery(*zonename, q.qclass(), ds, zonename, auth)) {
|
|
return (DataSrc::ERROR);
|
|
return (DataSrc::ERROR);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -512,13 +508,13 @@ tryWildcard(Query& q, QueryTaskPtr task, const DataSrc* ds,
|
|
|
|
|
|
return (DataSrc::SUCCESS);
|
|
return (DataSrc::SUCCESS);
|
|
}
|
|
}
|
|
|
|
+} // end of anonymous namespace
|
|
|
|
|
|
//
|
|
//
|
|
// doQuery: Processes a query.
|
|
// doQuery: Processes a query.
|
|
//
|
|
//
|
|
void
|
|
void
|
|
-DataSrc::doQuery(Query& q)
|
|
+DataSrc::doQuery(Query& q) {
|
|
-{
|
|
|
|
Message& m = q.message();
|
|
Message& m = q.message();
|
|
vector<RRsetPtr> additional;
|
|
vector<RRsetPtr> additional;
|
|
|
|
|
|
@@ -543,7 +539,7 @@ DataSrc::doQuery(Query& q)
|
|
// Find the closest enclosing zone for which we are authoritative,
|
|
// Find the closest enclosing zone for which we are authoritative,
|
|
// and the concrete data source which is authoritative for it.
|
|
// and the concrete data source which is authoritative for it.
|
|
// (Note that RRtype DS queries need to go to the parent.)
|
|
// (Note that RRtype DS queries need to go to the parent.)
|
|
- int nlabels = task->qname.getLabelCount() - 1;
|
|
+ const int nlabels = task->qname.getLabelCount() - 1;
|
|
NameMatch match(nlabels != 0 && task->qtype == RRType::DS() ?
|
|
NameMatch match(nlabels != 0 && task->qtype == RRType::DS() ?
|
|
task->qname.split(1, task->qname.getLabelCount() - 1) :
|
|
task->qname.split(1, task->qname.getLabelCount() - 1) :
|
|
task->qname);
|
|
task->qname);
|
|
@@ -618,7 +614,8 @@ DataSrc::doQuery(Query& q)
|
|
// Add the NS records for the enclosing zone to
|
|
// Add the NS records for the enclosing zone to
|
|
// the authority section.
|
|
// the authority section.
|
|
RRsetList auth;
|
|
RRsetList auth;
|
|
- if (!refQuery(*zonename, q, datasource, zonename, auth)) {
|
|
+ if (!refQuery(*zonename, q.qclass(), datasource, zonename,
|
|
|
|
+ auth)) {
|
|
m.setRcode(Rcode::SERVFAIL());
|
|
m.setRcode(Rcode::SERVFAIL());
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
@@ -661,7 +658,8 @@ DataSrc::doQuery(Query& q)
|
|
if (task->state == QueryTask::GETANSWER) {
|
|
if (task->state == QueryTask::GETANSWER) {
|
|
RRsetList auth;
|
|
RRsetList auth;
|
|
m.clearHeaderFlag(MessageFlag::AA());
|
|
m.clearHeaderFlag(MessageFlag::AA());
|
|
- if (!refQuery(task->qname, q, datasource, zonename, auth)) {
|
|
+ if (!refQuery(task->qname, q.qclass(), datasource, zonename,
|
|
|
|
+ auth)) {
|
|
m.setRcode(Rcode::SERVFAIL());
|
|
m.setRcode(Rcode::SERVFAIL());
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
@@ -806,8 +804,7 @@ DataSrc::findReferral(const Name& qname, const RRClass& qclass,
|
|
}
|
|
}
|
|
|
|
|
|
flags = 0;
|
|
flags = 0;
|
|
- r = findExactRRset(qname, qclass, RRType::DNAME(), target, flags,
|
|
+ r = findExactRRset(qname, qclass, RRType::DNAME(), target, flags, zonename);
|
|
- zonename);
|
|
|
|
if (r == SUCCESS && flags == 0) {
|
|
if (r == SUCCESS && flags == 0) {
|
|
dname = true;
|
|
dname = true;
|
|
} else if ((flags & (NO_SUCH_ZONE|NAME_NOT_FOUND))) {
|
|
} else if ((flags & (NO_SUCH_ZONE|NAME_NOT_FOUND))) {
|
|
@@ -824,8 +821,7 @@ DataSrc::findReferral(const Name& qname, const RRClass& qclass,
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
void
|
|
-MetaDataSrc::addDataSrc(ConstDataSrcPtr data_src)
|
|
+MetaDataSrc::addDataSrc(ConstDataSrcPtr data_src) {
|
|
-{
|
|
|
|
if (getClass() != RRClass::ANY() && data_src->getClass() != getClass()) {
|
|
if (getClass() != RRClass::ANY() && data_src->getClass() != getClass()) {
|
|
isc_throw(Unexpected, "class mismatch");
|
|
isc_throw(Unexpected, "class mismatch");
|
|
}
|
|
}
|
|
@@ -834,8 +830,7 @@ MetaDataSrc::addDataSrc(ConstDataSrcPtr data_src)
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
void
|
|
-MetaDataSrc::removeDataSrc(ConstDataSrcPtr data_src)
|
|
+MetaDataSrc::removeDataSrc(ConstDataSrcPtr data_src) {
|
|
-{
|
|
|
|
std::vector<ConstDataSrcPtr>::iterator it, itr;
|
|
std::vector<ConstDataSrcPtr>::iterator it, itr;
|
|
for (it = data_sources.begin(); it != data_sources.end(); it++) {
|
|
for (it = data_sources.begin(); it != data_sources.end(); it++) {
|
|
if (*it == data_src) {
|
|
if (*it == data_src) {
|
|
@@ -859,14 +854,12 @@ MetaDataSrc::findClosestEnclosure(NameMatch& match, const RRClass& qclass) const
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-NameMatch::~NameMatch()
|
|
+NameMatch::~NameMatch() {
|
|
-{
|
|
|
|
delete closest_name_;
|
|
delete closest_name_;
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
void
|
|
-NameMatch::update(const DataSrc& new_source, const Name& container)
|
|
+NameMatch::update(const DataSrc& new_source, const Name& container) {
|
|
-{
|
|
|
|
if (closest_name_ == NULL) {
|
|
if (closest_name_ == NULL) {
|
|
closest_name_ = new Name(container);
|
|
closest_name_ = new Name(container);
|
|
best_source_ = &new_source;
|
|
best_source_ = &new_source;
|
|
@@ -875,14 +868,14 @@ NameMatch::update(const DataSrc& new_source, const Name& container)
|
|
|
|
|
|
if (container.compare(*closest_name_).getRelation() ==
|
|
if (container.compare(*closest_name_).getRelation() ==
|
|
NameComparisonResult::SUBDOMAIN) {
|
|
NameComparisonResult::SUBDOMAIN) {
|
|
- Name* newname = new Name(container);
|
|
+ const Name* newname = new Name(container);
|
|
delete closest_name_;
|
|
delete closest_name_;
|
|
closest_name_ = newname;
|
|
closest_name_ = newname;
|
|
best_source_ = &new_source;
|
|
best_source_ = &new_source;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-Nsec3Param::Nsec3Param(uint8_t a, uint8_t f, uint16_t i,
|
|
+Nsec3Param::Nsec3Param(const uint8_t a, const uint8_t f, const uint16_t i,
|
|
const std::vector<uint8_t>& s) :
|
|
const std::vector<uint8_t>& s) :
|
|
algorithm_(a), flags_(f), iterations_(i), salt_(s)
|
|
algorithm_(a), flags_(f), iterations_(i), salt_(s)
|
|
{}
|
|
{}
|
|
@@ -893,7 +886,7 @@ Nsec3Param::getHash(const Name& name) const {
|
|
name.toWire(buf);
|
|
name.toWire(buf);
|
|
|
|
|
|
uint8_t digest[SHA1_HASHSIZE];
|
|
uint8_t digest[SHA1_HASHSIZE];
|
|
- uint8_t* input = (uint8_t*) buf.getData();
|
|
+ const uint8_t* input = static_cast<const uint8_t*>(buf.getData());
|
|
size_t inlength = buf.getLength();
|
|
size_t inlength = buf.getLength();
|
|
const uint8_t saltlen = salt_.size();
|
|
const uint8_t saltlen = salt_.size();
|
|
|
|
|