[svn] commit: r889 - in /branches/each-ds/src/lib: auth/cpp/TODO auth/cpp/data_source.cc auth/cpp/data_source_static.cc auth/cpp/query.h dns/cpp/rdata/generic/mx_15.cc
BIND 10 source code commits
bind10-changes at lists.isc.org
Sat Feb 20 03:09:56 UTC 2010
Author: each
Date: Sat Feb 20 03:09:55 2010
New Revision: 889
Log:
checkpoint:
- do not return glue data in additional section when processing MX
queries. (same for SRV and NAPTR, when they are supported.)
- added ANY query support to static 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_static.cc
branches/each-ds/src/lib/auth/cpp/query.h
branches/each-ds/src/lib/dns/cpp/rdata/generic/mx_15.cc
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 Sat Feb 20 03:09:55 2010
@@ -1,9 +1,7 @@
Data source:
- change filenames so we don't have everything starting with "data_source_"?
-- make sure glue is not returned in additional section except for NS.
- we need a way to indicate "glue OK" in calls to findExactRRset().
-SQL data source optimization and cleanup:
+SQL data source:
- should implement findAddrs() and findReferral() directly instead of
using the implementation in DataSrc.
- need ANY queries
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 Sat Feb 20 03:09:55 2010
@@ -30,12 +30,16 @@
if (rrset->getType() == RRType::NS()) {
const generic::NS& ns = dynamic_cast<const generic::NS&>(rd);
- t = new QueryTask(ns.getNSName(), q.qclass(), Section::ADDITIONAL(),
- QueryTask::ADDR_QUERY, QueryTask::GETADDITIONAL);
+ t = new QueryTask(ns.getNSName(), q.qclass(),
+ Section::ADDITIONAL(),
+ QueryTask::GLUE_QUERY,
+ QueryTask::GETADDITIONAL);
} else if (rrset->getType() == RRType::MX()) {
const generic::MX& mx = dynamic_cast<const generic::MX&>(rd);
- t = new QueryTask(mx.getMXName(), q.qclass(), Section::ADDITIONAL(),
- QueryTask::ADDR_QUERY, QueryTask::GETADDITIONAL);
+ t = new QueryTask(mx.getMXName(), q.qclass(),
+ Section::ADDITIONAL(),
+ QueryTask::NOGLUE_QUERY,
+ QueryTask::GETADDITIONAL);
}
if (t != NULL) {
q.tasks().push(*t);
@@ -77,7 +81,7 @@
RdataIteratorPtr it;
it = rrset->getRdataIterator();
- // More than one DNAME RR in the RRset is illegal, so we only have
+ // More than one CNAME RR in the RRset is illegal, so we only have
// to process the first one.
it->first();
if (it->isLast()) {
@@ -104,7 +108,8 @@
return (ds->findExactRRset(q, task.qname, task.qclass, task.qtype,
target, task.flags, task.zone));
- case QueryTask::ADDR_QUERY:
+ case QueryTask::GLUE_QUERY:
+ case QueryTask::NOGLUE_QUERY:
return (ds->findAddrs(q, task.qname, task.qclass, target,
task.flags, task.zone));
@@ -112,6 +117,9 @@
return (ds->findReferral(q, task.qname, task.qclass, target,
task.flags, task.zone));
}
+
+ // Not reached
+ return (DataSrc::ERROR);
}
//
@@ -136,9 +144,9 @@
QueryTask task = q.tasks().front();
q.tasks().pop();
- // No task type other than these should ever be on the task queue.
- if (task.op != QueryTask::AUTH_QUERY &&
- task.op != QueryTask::ADDR_QUERY) {
+ // These task types should never be on the task queue.
+ if (task.op == QueryTask::SIMPLE_QUERY ||
+ task.op == QueryTask::REF_QUERY) {
m.setRcode(Rcode::SERVFAIL());
q.setStatus(Query::FAILURE);
return;
@@ -162,56 +170,64 @@
task.flags = NO_SUCH_ZONE;
} else {
task.zone = new Name(*zone);
- if (task.op == QueryTask::AUTH_QUERY) {
- // If this is an authoritative query and there is more than
- // one level between the zone name and qname, we need to
- // check the intermediate nodes for referrals.
- if (task.state == QueryTask::GETANSWER ||
- task.state == QueryTask::FOLLOWCNAME) {
- int nlen = task.qname.getLabelCount();
- int diff = nlen - zone->getLabelCount();
- if (diff > 1) {
- bool found = false;
- RRsetList ref;
- for(int i = diff; i > 1; i--) {
- Name sub(task.qname.split(i - 1, nlen - i));
- QueryTask t(sub, task.qclass, QueryTask::REF_QUERY);
- result = doQueryTask(ds, q, t, ref);
- if (result == SUCCESS && t.flags == 0) {
- found = true;
- break;
+
+ // For these query task types, if there is more than
+ // one level between the zone name and qname, we need to
+ // check the intermediate nodes for referrals.
+ if (task.op == QueryTask::AUTH_QUERY ||
+ task.op == QueryTask::NOGLUE_QUERY) {
+ int nlen = task.qname.getLabelCount();
+ int diff = nlen - zone->getLabelCount();
+ if (diff > 1) {
+ bool found = false;
+ RRsetList ref;
+ for(int i = diff; i > 1; i--) {
+ Name sub(task.qname.split(i - 1, nlen - i));
+ QueryTask t(sub, task.qclass, QueryTask::REF_QUERY);
+ result = doQueryTask(ds, q, t, ref);
+ if (result == SUCCESS && t.flags == 0) {
+ found = true;
+ break;
+ }
+ }
+
+ // Found a referral while getting additional data
+ // for something other than NS; we skip it.
+ if (found && task.op == QueryTask::NOGLUE_QUERY) {
+ continue;
+ }
+
+ // Found a referral while getting answer data;
+ // send a delegation.
+ if (found) {
+ if (RRsetPtr r = ref[RRType::DNAME()]) {
+ RRsetList syn;
+ m.addRRset(Section::ANSWER(), r,
+ q.wantDnssec());
+ synthesizeCname(q, task, r, syn);
+ if (syn.size() == 1) {
+ m.addRRset(Section::ANSWER(), syn[0],
+ q.wantDnssec());
+ chaseCname(q, task, syn[0]);
+ continue;
}
}
-
- if (found) {
- if (RRsetPtr r = ref[RRType::DNAME()]) {
- RRsetList syn;
- m.addRRset(Section::ANSWER(), r,
+ BOOST_FOREACH (RRsetPtr r, ref) {
+ if (r->getType() != RRType::DNAME()) {
+ m.addRRset(Section::AUTHORITY(), r,
q.wantDnssec());
- synthesizeCname(q, task, r, syn);
- if (syn.size() == 1) {
- m.addRRset(Section::ANSWER(), syn[0],
- q.wantDnssec());
- chaseCname(q, task, syn[0]);
- continue;
- }
+ getAdditional(q, r);
}
- BOOST_FOREACH (RRsetPtr r, ref) {
- if (r->getType() != RRType::DNAME()) {
- m.addRRset(Section::AUTHORITY(), r,
- q.wantDnssec());
- getAdditional(q, r);
- }
- }
- continue;
- }
+ }
+ continue;
}
}
// We appear to have authoritative data; set the header
// flag. (We may clear it later if we find a referral
// at the actual qname node.)
- if (task.state == QueryTask::GETANSWER) {
+ if (task.op == QueryTask::AUTH_QUERY &&
+ task.state == QueryTask::GETANSWER) {
m.setHeaderFlag(MessageFlag::AA());
}
}
@@ -224,51 +240,54 @@
}
// Query found a referral; let's find out if that was expected--
- // i.e., is this an NS at the zone apex, or were we querying
- // for DS or DNAME
+ // i.e., if an NS was at the zone apex, or if we were querying
+ // specifically for the NS, DS or DNAME record.
if ((task.flags & REFERRAL) &&
(zone->getLabelCount() == task.qname.getLabelCount() ||
- task.qtype == RRType::DS() || task.qtype == RRType::DNAME())) {
+ task.qtype == RRType::NS() ||
+ task.qtype == RRType::DS() ||
+ task.qtype == RRType::DNAME())) {
task.flags &= ~REFERRAL;
}
}
if (result == SUCCESS && task.flags == 0) {
- bool have_ns = false;
+ bool have_ns = false, need_auth = false;
switch (task.state) {
case QueryTask::GETANSWER:
case QueryTask::FOLLOWCNAME:
BOOST_FOREACH(RRsetPtr rrset, data) {
m.addRRset(task.section, rrset, q.wantDnssec());
+ if (q.tasks().empty()) {
+ need_auth = true;
+ }
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 (!have_ns) {
- RRsetList auth;
- QueryTask t(Name(*zone), task.qclass,
- QueryTask::REF_QUERY);
- result = doQueryTask(ds, q, t, auth);
- if (result != SUCCESS) {
- m.setRcode(Rcode::SERVFAIL());
- q.setStatus(Query::FAILURE);
- return;
- }
-
- BOOST_FOREACH(RRsetPtr rrset, auth) {
- if (rrset->getType() == RRType::DNAME()) {
- continue;
- }
- m.addRRset(Section::AUTHORITY(), rrset,
- q.wantDnssec());
- getAdditional(q, rrset);
- }
+ if (need_auth && !have_ns) {
+ // Data found, no additional processing needed.
+ // Add the NS records for the enclosing zone to
+ // the authority section.
+ RRsetList auth;
+ QueryTask t(Name(*zone), task.qclass,
+ QueryTask::REF_QUERY);
+ result = doQueryTask(ds, q, t, auth);
+ if (result != SUCCESS) {
+ m.setRcode(Rcode::SERVFAIL());
+ q.setStatus(Query::FAILURE);
+ return;
+ }
+
+ BOOST_FOREACH(RRsetPtr rrset, auth) {
+ if (rrset->getType() == RRType::DNAME()) {
+ continue;
+ }
+ m.addRRset(Section::AUTHORITY(), rrset,
+ q.wantDnssec());
+ getAdditional(q, rrset);
}
}
continue;
@@ -283,23 +302,6 @@
continue;
}
additional.addRRset(rrset);
- }
- if (q.tasks().empty()) {
- // We're done, so now copy in the additional data:
- // data first, then signatures. (If we run out of
- // space, signatures in additional section are
- // optional.)
- BOOST_FOREACH(RRsetPtr rrset, additional) {
- m.addRRset(Section::AUTHORITY(), rrset, false);
- }
- if (q.wantDnssec()) {
- BOOST_FOREACH(RRsetPtr rrset, additional) {
- m.addRRset(Section::ADDITIONAL(),
- rrset->getRRsig(), false);
- }
- }
- q.setStatus(Query::SUCCESS);
- return;
}
continue;
@@ -342,7 +344,7 @@
}
getAdditional(q, rrset);
}
- }
+ }
continue;
} else if (task.flags & NO_SUCH_ZONE) {
// No such zone. If we're chasing cnames or adding additional
@@ -504,7 +506,24 @@
return;
}
}
-};
-
-}
-}
+
+ // We're done, so now copy in the additional data:
+ // data first, then signatures. (If we run out of
+ // space, signatures in additional section are
+ // optional.)
+ BOOST_FOREACH(RRsetPtr rrset, additional) {
+ m.addRRset(Section::ADDITIONAL(), rrset, false);
+ }
+ if (q.wantDnssec()) {
+ BOOST_FOREACH(RRsetPtr rrset, additional) {
+ if (rrset->getRRsig()) {
+ m.addRRset(Section::ADDITIONAL(),
+ rrset->getRRsig(), false);
+ }
+ }
+ }
+ q.setStatus(Query::SUCCESS);
+}
+
+}
+}
Modified: branches/each-ds/src/lib/auth/cpp/data_source_static.cc
==============================================================================
--- branches/each-ds/src/lib/auth/cpp/data_source_static.cc (original)
+++ branches/each-ds/src/lib/auth/cpp/data_source_static.cc Sat Feb 20 03:09:55 2010
@@ -79,21 +79,23 @@
{
flags = 0;
if (qname == version_name &&
- qclass == version->getClass() && qtype == version->getType()) {
+ qclass == version->getClass() &&
+ (qtype == version->getType() || qtype == RRType::ANY())) {
target.addRRset(version);
return (SUCCESS);
} else if (qname == version_name &&
qclass == version_ns->getClass() &&
- qtype == version_ns->getType()) {
+ (qtype == version->getType() || qtype == RRType::ANY())) {
target.addRRset(version_ns);
return (SUCCESS);
} else if (qname == authors_name &&
- qclass == authors->getClass() && qtype == authors->getType()) {
+ qclass == authors->getClass() &&
+ (qtype == authors->getType() || qtype == RRType::ANY())) {
target.addRRset(authors);
return (SUCCESS);
} else if (qname == authors_name &&
qclass == authors_ns->getClass() &&
- qtype == authors_ns->getType()) {
+ (qtype == authors->getType() || qtype == RRType::ANY())) {
target.addRRset(authors_ns);
return (SUCCESS);
}
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 Sat Feb 20 03:09:55 2010
@@ -38,7 +38,7 @@
// moved to private and wrapped in get() functions later.
// The standard query tuple: qname/qclass/qtype.
- // Note that qtype is ignored in the ADDR_QUERY case.
+ // Note that qtype is ignored in the GLUE_QUERY/NOGLUE_QUERY case.
const Name& qname;
const RRClass& qclass;
const RRType& qtype;
@@ -64,13 +64,16 @@
// - AUTH_QUERY: look for a match for qname/qclass/qtype, or
// for qname/qclass/CNAME, or for a referral.
//
- // - ADDR_QUERY: look for matches with qname/qclass/A
+ // - GLUE_QUERY: look for matches with qname/qclass/A
// OR qname/class/AAAA in local data, regardless of
// authority, for use in glue. (This can be implemented
// as two successive SIMPLE_QUERY tasks, but might be
// optimized by the concrete data source implementation
// by turning it into a single database lookup.)
//
+ // - NOGLUE_QUERY: same as GLUE_QUERY except that answers
+ // are rejected if they are below a zone cut.
+ //
// - REF_QUERY: look for matches for qname/qclass/NS,
// qname/qclass/DS, and qname/qclass/DNAME. Used
// to search for a zone cut.
@@ -78,8 +81,9 @@
const enum Op {
SIMPLE_QUERY,
AUTH_QUERY,
- ADDR_QUERY,
- REF_QUERY
+ GLUE_QUERY,
+ NOGLUE_QUERY,
+ REF_QUERY,
} op;
// The state field indicates the state of the query; it controls
@@ -154,12 +158,12 @@
throw "invalid constructor for this task operation";
}
}
- // An address query doesn't need to specify type.
+ // A glue (or noglue) query doesn't need to specify type.
QueryTask(const Name& n, const RRClass& c,
const Section& sect, const Op o, const State st) :
qname(n), qclass(c), qtype(RRType::ANY()), zone(NULL),
section(sect), op(o), state(st), flags(0) {
- if (op != ADDR_QUERY) {
+ if (op != GLUE_QUERY && op != NOGLUE_QUERY) {
throw "invalid constructor for this task operation";
}
}
Modified: branches/each-ds/src/lib/dns/cpp/rdata/generic/mx_15.cc
==============================================================================
--- branches/each-ds/src/lib/dns/cpp/rdata/generic/mx_15.cc (original)
+++ branches/each-ds/src/lib/dns/cpp/rdata/generic/mx_15.cc Sat Feb 20 03:09:55 2010
@@ -38,10 +38,21 @@
// check consistency.
}
-MX::MX(const std::string& mxstr) :
+MX::MX(const std::string& mx_str) :
preference_(0), mxname_(".")
{
- dns_throw(InvalidRdataText, "Not implemented yet");
+ istringstream iss(mx_str);
+ uint16_t pref;
+ string mxname;
+
+ iss >> pref >> mxname;
+
+ if (iss.bad() || iss.fail() || !iss.eof()) {
+ dns_throw(InvalidRdataText, "Invalid MX text format");
+ }
+
+ preference_ = pref;
+ mxname_ = Name(mxname);
}
MX::MX(uint16_t preference, const Name& mxname) :
More information about the bind10-changes
mailing list