[svn] commit: r1474 - /trunk/src/lib/auth/data_source.cc
BIND 10 source code commits
bind10-changes at lists.isc.org
Wed Mar 17 07:01:43 UTC 2010
Author: each
Date: Wed Mar 17 07:01:42 2010
New Revision: 1474
Log:
Correctly handle NSEC and NSEC3 responses when answering with a
wildcard record. (Unit tests to follow in the morning.)
Modified:
trunk/src/lib/auth/data_source.cc
Modified: trunk/src/lib/auth/data_source.cc
==============================================================================
--- trunk/src/lib/auth/data_source.cc (original)
+++ trunk/src/lib/auth/data_source.cc Wed Mar 17 07:01:42 2010
@@ -344,7 +344,8 @@
}
static inline DataSrc::Result
-proveNX(Query& q, QueryTaskPtr task, const DataSrc* ds, const Name& zonename)
+proveNX(Query& q, QueryTaskPtr task, const DataSrc* ds,
+ const Name& zonename, const bool wildcard)
{
Message& m = q.message();
ConstNsec3ParamPtr nsec3 = getNsec3Param(q, ds, zonename);
@@ -382,8 +383,13 @@
}
}
- // Now add a covering NSEC3 for a wildcard under the
- // closest provable enclosing name
+ // If we are processing a wildcard answer, we're done.
+ if (wildcard) {
+ return (DataSrc::SUCCESS);
+ }
+
+ // Otherwise, there is no wildcard record, so we must add a
+ // covering NSEC3 to prove that it doesn't exist.
string hash3(nsec3->getHash(Name("*").concatenate(enclosure)));
RETERR(getNsec3(ds, zonename, q.qclass(), hash3, rrset));
if (hash3 != hash1 && hash3 != hash2) {
@@ -391,7 +397,7 @@
}
} else {
Name nsecname(task->qname);
- if ((task->flags & DataSrc::NAME_NOT_FOUND) != 0) {
+ if ((task->flags & DataSrc::NAME_NOT_FOUND) != 0 || wildcard) {
ds->findPreviousName(task->qname, nsecname, &zonename);
}
@@ -402,6 +408,13 @@
return (DataSrc::SUCCESS);
}
+ // If we are processing a wildcard answer, we're done.
+ if (wildcard) {
+ return (DataSrc::SUCCESS);
+ }
+
+ // Otherwise, there is no wildcard record, so we must add an
+ // NSEC for the zone to prove the wildcard doesn't exist.
RETERR(addNSEC(q, task, zonename, zonename, ds));
}
@@ -431,7 +444,7 @@
RRsetList wild;
const Name star("*");
- uint32_t rflags = 0;
+ bool cname = false;
for (int i = 1; i <= diff; ++i) {
const Name& wname(star.concatenate(task->qname.split(i, nlen - i)));
@@ -439,12 +452,17 @@
QueryTask::AUTH_QUERY);
result = doQueryTask(ds, zonename, newtask, wild);
if (result == DataSrc::SUCCESS) {
- if (newtask.flags == 0 || (newtask.flags & DataSrc::CNAME_FOUND)) {
- rflags = newtask.flags;
+ task->flags &= ~DataSrc::NAME_NOT_FOUND;
+ task->flags &= ~DataSrc::TYPE_NOT_FOUND;
+ if (newtask.flags == 0) {
found = true;
break;
+ } else if ((newtask.flags & DataSrc::CNAME_FOUND) != 0) {
+ task->flags |= DataSrc::CNAME_FOUND;
+ found = true;
+ cname = true;
+ break;
} else if ((newtask.flags & DataSrc::TYPE_NOT_FOUND) != 0) {
- task->flags &= ~DataSrc::NAME_NOT_FOUND;
task->flags |= DataSrc::TYPE_NOT_FOUND;
break;
}
@@ -457,7 +475,13 @@
// answer: if a CNAME, chase the target, otherwise
// add authority.
if (found) {
- if ((rflags & DataSrc::CNAME_FOUND) != 0) {
+ result = proveNX(q, task, ds, *zonename, true);
+ if (result != DataSrc::SUCCESS) {
+ m.setRcode(Rcode::SERVFAIL());
+ return (DataSrc::ERROR);
+ }
+
+ if (cname) {
RRsetPtr rrset = wild.findRRset(RRType::CNAME(), q.qclass());
if (rrset != NULL) {
rrset->setName(task->qname);
@@ -688,7 +712,7 @@
}
if (q.wantDnssec()) {
- result = proveNX(q, task, datasource, *zonename);
+ result = proveNX(q, task, datasource, *zonename, false);
if (result != DataSrc::SUCCESS) {
m.setRcode(Rcode::SERVFAIL());
return;
More information about the bind10-changes
mailing list