[svn] commit: r829 - in /branches/each-ds/src/lib/auth/cpp: TODO data_source.cc data_source.h query.h
BIND 10 source code commits
bind10-changes at lists.isc.org
Tue Feb 16 06:17:21 UTC 2010
Author: each
Date: Tue Feb 16 06:17:21 2010
New Revision: 829
Log:
checkpoint:
- omit records from additional section that were already returned in
the answer section
- improve support for multiple-RRset answers (e.g., from ANY queries,
though those are still not supported by the underlying data source)
Modified:
branches/each-ds/src/lib/auth/cpp/TODO
branches/each-ds/src/lib/auth/cpp/data_source.cc
branches/each-ds/src/lib/auth/cpp/data_source.h
branches/each-ds/src/lib/auth/cpp/query.h
Modified: branches/each-ds/src/lib/auth/cpp/TODO
==============================================================================
--- branches/each-ds/src/lib/auth/cpp/TODO (original)
+++ branches/each-ds/src/lib/auth/cpp/TODO Tue Feb 16 06:17:21 2010
@@ -1,11 +1,9 @@
Data source:
- change RRsetList to something that can be indexed by the RRType
-- improve support for multiple-RRset answers from the data source
- add support for type-ANY queries
- consider altering the "task queue" design (at this point it's relatively
rare for it to have more than one item).
- check want_additional before adding additional data
-- omit additional data that's already in the answer section
- make sure glue is not returned in additional section except for NS
DNSSEC:
@@ -29,3 +27,5 @@
Other changes:
- add Message method getSectionCount() so it isn't necessary to iterate
over the question section to find out how many there are.
+- add Name method reverse() to reverse labels (might return a Name, or
+ maybe just a string).
Modified: branches/each-ds/src/lib/auth/cpp/data_source.cc
==============================================================================
--- branches/each-ds/src/lib/auth/cpp/data_source.cc (original)
+++ branches/each-ds/src/lib/auth/cpp/data_source.cc Tue Feb 16 06:17:21 2010
@@ -122,6 +122,7 @@
Result result;
Message& m = q.message();
+ m.clearHeaderFlag(MessageFlag::AA());
while (!q.tasks().empty()) {
RdataIteratorPtr it;
RRsetList data, sigs;
@@ -197,14 +198,7 @@
}
result = doQueryTask(ds, q, task, data);
- if (result == SUCCESS) {
- if (task.op == QueryTask::ADDR_QUERY) {
- BOOST_FOREACH (RRsetPtr rrset, data) {
- m.addRRset(task.section, rrset);
- }
- continue;
- }
- } else if (result == REFERRAL_FOUND) {
+ if (result == REFERRAL_FOUND) {
if (zone->getLabelCount() == task.qname.getLabelCount()) {
// An NS at the zone apex is expected.
result = SUCCESS;
@@ -212,47 +206,71 @@
}
}
+ bool have_ns = false;
+
switch (result) {
case SUCCESS:
- // This will need to be able to handle multiple RRsets
- // once RRType ANY and/or DNSSEC are supported. For right
- // now, however, we assume that an auth query will return
- // only one RRset: either the data requested or a CNAME.
- m.addRRset(task.section, data[0]);
+ // XXX: This will need to be able to handle multiple RRsets
+ // once RRType ANY is supported. For right now, however, we
+ // can assume that an auth query that reaches this point has
+ // only one RRset: either the data requested, or a CNAME.
switch (task.state) {
case QueryTask::GETANSWER:
case QueryTask::FOLLOWCNAME:
- getAdditional(q, data[0]);
+ BOOST_FOREACH(RRsetPtr rrset, data) {
+ m.addRRset(task.section, rrset);
+ getAdditional(q, rrset);
+ if (rrset->getType() == RRType::NS()) {
+ have_ns = true;
+ }
+ }
+ q.setStatus(Query::ANSWERED);
if (q.tasks().empty()) {
// Data found, no additional processing needed.
// Add the NS records for the enclosing zone to
// the authority section.
- if (data[0]->getType() != RRType::NS()) {
+ if (!have_ns) {
RRsetList auth;
- QueryTask t(Name(*zone), task.qclass, RRType::NS(),
- QueryTask::SIMPLE_QUERY);
+ QueryTask t(Name(*zone), task.qclass,
+ QueryTask::REF_QUERY);
result = doQueryTask(ds, q, t, auth);
if (result != SUCCESS) {
m.setRcode(Rcode::SERVFAIL());
return;
}
- m.addRRset(Section::AUTHORITY(), auth[0]);
- getAdditional(q, auth[0]);
+ BOOST_FOREACH(RRsetPtr rrset, auth) {
+ if (rrset->getType() == RRType::DNAME()) {
+ continue;
+ }
+ m.addRRset(Section::AUTHORITY(), rrset);
+ getAdditional(q, rrset);
+ }
}
}
continue;
- case QueryTask::GETADDITIONAL:
+ case QueryTask::GETAUTHORITY:
+ BOOST_FOREACH(RRsetPtr rrset, data) {
+ m.addRRset(task.section, rrset);
+ getAdditional(q, rrset);
+ }
if (q.tasks().empty()) {
q.setStatus(Query::SUCCESS);
return;
}
continue;
- case QueryTask::GETAUTHORITY:
- getAdditional(q, data[0]);
+ case QueryTask::GETADDITIONAL:
+ BOOST_FOREACH(RRsetPtr rrset, data) {
+ if (q.status() == Query::ANSWERED &&
+ rrset->getName() == q.qname() &&
+ rrset->getType() == q.qtype()) {
+ continue;
+ }
+ m.addRRset(task.section, rrset);
+ }
if (q.tasks().empty()) {
q.setStatus(Query::SUCCESS);
return;
@@ -279,15 +297,19 @@
if (task.state == QueryTask::GETANSWER) {
RRsetList auth;
m.clearHeaderFlag(MessageFlag::AA());
- QueryTask t(task.qname, task.qclass, RRType::NS(),
- QueryTask::SIMPLE_QUERY);
+ QueryTask t(task.qname, task.qclass, QueryTask::REF_QUERY);
result = doQueryTask(ds, q, t, auth);
if (result != SUCCESS) {
m.setRcode(Rcode::SERVFAIL());
return;
}
- m.addRRset(Section::AUTHORITY(), auth[0]);
- getAdditional(q, auth[0]);
+ BOOST_FOREACH (RRsetPtr rrset, auth) {
+ if (rrset->getType() == RRType::DNAME()) {
+ continue;
+ }
+ m.addRRset(Section::AUTHORITY(), rrset);
+ getAdditional(q, rrset);
+ }
}
continue;
@@ -324,24 +346,35 @@
// answer: if a CNAME, chase the target, otherwise
// add authority.
if (found) {
- // XXX: will need to handle multiple answers later
- wild[0]->setName(task.qname);
- m.addRRset(Section::ANSWER(), wild[0]);
-
- if (r == CNAME_FOUND) {
- chaseCname(q, task, wild[0]);
- } else {
- RRsetList auth;
- QueryTask t(Name(*zone), task.qclass, RRType::NS(),
- QueryTask::SIMPLE_QUERY);
- r = doQueryTask(ds, q, t, auth);
- if (r != SUCCESS) {
- m.setRcode(Rcode::SERVFAIL());
- return;
+ // XXX: since this is a SIMPLE_QUERY, there can
+ // only be one rrset returned in wild. But
+ // eventually this will need to handle ANY queries,
+ // so wrap it in a BOOST_FOREACH statement anyway.
+ BOOST_FOREACH (RRsetPtr rrset, wild) {
+ rrset->setName(task.qname);
+ m.addRRset(Section::ANSWER(), rrset);
+
+ if (r == CNAME_FOUND &&
+ q.qtype() != RRType::ANY()) {
+ chaseCname(q, task, rrset);
+ } else {
+ RRsetList auth;
+ QueryTask t(Name(*zone), task.qclass,
+ QueryTask::REF_QUERY);
+ r = doQueryTask(ds, q, t, auth);
+ if (r != SUCCESS) {
+ m.setRcode(Rcode::SERVFAIL());
+ return;
+ }
+
+ BOOST_FOREACH (RRsetPtr rrset, data) {
+ if (rrset->getType() == RRType::DNAME()) {
+ continue;
+ }
+ m.addRRset(Section::AUTHORITY(), rrset);
+ getAdditional(q, rrset);
+ }
}
-
- m.addRRset(Section::AUTHORITY(), auth[0]);
- getAdditional(q, auth[0]);
}
continue;
}
@@ -383,7 +416,6 @@
}
continue;
- case DNAME_FOUND: // XXX: not yet implemented
case NOT_IMPLEMENTED:
case ERROR:
m.setRcode(Rcode::SERVFAIL());
Modified: branches/each-ds/src/lib/auth/cpp/data_source.h
==============================================================================
--- branches/each-ds/src/lib/auth/cpp/data_source.h (original)
+++ branches/each-ds/src/lib/auth/cpp/data_source.h Tue Feb 16 06:17:21 2010
@@ -40,7 +40,6 @@
ERROR,
NOT_IMPLEMENTED,
CNAME_FOUND,
- DNAME_FOUND,
REFERRAL_FOUND,
ZONE_NOT_FOUND,
NAME_NOT_FOUND,
Modified: branches/each-ds/src/lib/auth/cpp/query.h
==============================================================================
--- branches/each-ds/src/lib/auth/cpp/query.h (original)
+++ branches/each-ds/src/lib/auth/cpp/query.h Tue Feb 16 06:17:21 2010
@@ -165,6 +165,7 @@
// The state of a query: running, succeeded, or failed.
enum Status {
RUNNING,
+ ANSWERED,
SUCCESS,
FAILURE
};
More information about the bind10-changes
mailing list