[svn] commit: r874 - in /branches/each-ds/src/lib/auth/cpp: TODO data_source.cc data_source.h data_source_sqlite3.cc data_source_sqlite3.h data_source_static.cc data_source_static.h query.h
BIND 10 source code commits
bind10-changes at lists.isc.org
Fri Feb 19 01:25:28 UTC 2010
Author: each
Date: Fri Feb 19 01:25:28 2010
New Revision: 874
Log:
Add code to allow the parent zone to answer DS queries when the server
is also authoritative for the child zone. (This is done by passing an
optional zone-name pointer to findRRset() and related functions. It would
probably be faster to do this via an opaque data-source state vector
instead.)
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/data_source_sqlite3.cc
branches/each-ds/src/lib/auth/cpp/data_source_sqlite3.h
branches/each-ds/src/lib/auth/cpp/data_source_static.cc
branches/each-ds/src/lib/auth/cpp/data_source_static.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 Fri Feb 19 01:25:28 2010
@@ -12,9 +12,6 @@
- add at least minimal EDNS0 support sufficient to recognize the DO bit
- implement NSEC rdata type; add NSEC/NSEC3 to authority section in
negative answers (including positive wildcard answers)
-- add special-case code so that when the server is authoritative for
- both the parent and child zone, that DS queries are served by the
- parent
- instead of adding additional data directly to the reply message,
add it to a temporary storage space, then copy it to the reply
afterward, so that A records can be included and RRSIGs omitted if
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 Fri Feb 19 01:25:28 2010
@@ -94,18 +94,19 @@
switch (task.op) {
case QueryTask::AUTH_QUERY:
return (ds->findRRset(q, task.qname, task.qclass, task.qtype,
- target, task.flags));
+ target, task.flags, task.zone));
case QueryTask::SIMPLE_QUERY:
return (ds->findExactRRset(q, task.qname, task.qclass, task.qtype,
- target, task.flags));
+ target, task.flags, task.zone));
case QueryTask::ADDR_QUERY:
- return (ds->findAddrs(q, task.qname, task.qclass, target, task.flags));
+ return (ds->findAddrs(q, task.qname, task.qclass, target,
+ task.flags, task.zone));
case QueryTask::REF_QUERY:
return (ds->findReferral(q, task.qname, task.qclass, target,
- task.flags));
+ task.flags, task.zone));
}
}
@@ -138,15 +139,20 @@
return;
}
- // Find the closest enclosing zone for which we are authoritative
- // (and the concrete data source which is authoritative for it).
- NameMatch match(task.qname);
+ // Find the closest enclosing zone for which we are authoritative,
+ // and the concrete data source which is authoritative for it.
+ // (Note that RRtype DS queries need to go to the parent.)
+ Name search(".");
+ if (task.qtype == RRType::DS()) {
+ search = task.qname.split(1, task.qname.getLabelCount() - 1);
+ } else {
+ search = task.qname;
+ }
+ NameMatch match(search);
findClosestEnclosure(match);
const DataSrc* ds = match.bestDataSrc();
const Name* zone = match.closestName();
-
- // XXX: we need to special-case queries of type RRType::DS(),
- // because they only come from the parent zone.
+ task.zone = new Name(*zone);
if (ds == NULL) {
task.flags = NO_SUCH_ZONE;
@@ -163,8 +169,8 @@
bool found = false;
RRsetList ref;
for(int i = diff; i > 1; i--) {
- QueryTask t(task.qname.split(i - 1, nlen - i),
- task.qclass, QueryTask::REF_QUERY);
+ 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;
@@ -206,9 +212,18 @@
}
result = doQueryTask(ds, q, task, data);
- if (result == SUCCESS && (task.flags & REFERRAL) &&
- (zone->getLabelCount() == task.qname.getLabelCount())) {
- // An NS found at the zone apex is expected.
+ if (result != SUCCESS) {
+ m.setRcode(Rcode::SERVFAIL());
+ q.setStatus(Query::FAILURE);
+ return;
+ }
+
+ // 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
+ if ((task.flags & REFERRAL) &&
+ (zone->getLabelCount() == task.qname.getLabelCount() ||
+ task.qtype == RRType::DS() || task.qtype == RRType::DNAME())) {
task.flags &= ~REFERRAL;
}
}
@@ -237,6 +252,7 @@
result = doQueryTask(ds, q, t, auth);
if (result != SUCCESS) {
m.setRcode(Rcode::SERVFAIL());
+ q.setStatus(Query::FAILURE);
return;
}
@@ -291,6 +307,7 @@
result = doQueryTask(ds, q, t, auth);
if (result != SUCCESS) {
m.setRcode(Rcode::SERVFAIL());
+ q.setStatus(Query::FAILURE);
return;
}
BOOST_FOREACH (RRsetPtr rrset, auth) {
@@ -376,6 +393,7 @@
r = doQueryTask(ds, q, t, auth);
if (r != SUCCESS || t.flags != 0) {
m.setRcode(Rcode::SERVFAIL());
+ q.setStatus(Query::FAILURE);
return;
}
@@ -408,6 +426,7 @@
result = doQueryTask(ds, q, t, soa);
if (result != SUCCESS || t.flags != 0) {
m.setRcode(Rcode::SERVFAIL());
+ q.setStatus(Query::FAILURE);
return;
}
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 Fri Feb 19 01:25:28 2010
@@ -81,14 +81,16 @@
const RRClass& qclass,
const RRType& qtype,
RRsetList& target,
- uint32_t& flags) const = 0;
+ uint32_t& flags,
+ Name* zone = NULL) const = 0;
virtual Result findExactRRset(const Query& q,
const Name& qname,
const RRClass& qclass,
const RRType& qtype,
RRsetList& target,
- uint32_t& flags) const = 0;
+ uint32_t& flags,
+ Name* zone = NULL) const = 0;
// These will have dumb implementations in the general DataSrc
// class, and SHOULD be overwritten by subclasses.
@@ -96,13 +98,15 @@
const Name& qname,
const RRClass& qclass,
RRsetList& target,
- uint32_t& flags) const = 0;
+ uint32_t& flags,
+ Name* zone = NULL) const = 0;
virtual Result findReferral(const Query& q,
const Name& qname,
const RRClass& qclass,
RRsetList& target,
- uint32_t& flags) const = 0;
+ uint32_t& flags,
+ Name* zone = NULL) const = 0;
};
// Base class for a DNS Data Source
@@ -127,31 +131,35 @@
const RRClass& qclass,
const RRType& qtype,
RRsetList& target,
- uint32_t& flags) const = 0;
+ uint32_t& flags,
+ Name* zone = NULL) const = 0;
virtual Result findExactRRset(const Query& q,
const Name& qname,
const RRClass& qclass,
const RRType& qtype,
RRsetList& target,
- uint32_t& flags) const = 0;
+ uint32_t& flags,
+ Name* zone = NULL) const = 0;
virtual Result findAddrs(const Query& q,
const Name& qname,
const RRClass& qclass,
RRsetList& target,
- uint32_t& flags) const {
+ uint32_t& flags,
+ Name* zone = NULL) const {
Result r;
bool a = false, aaaa = false;
flags = 0;
- r = findExactRRset(q, qname, qclass, RRType::A(), target, flags);
+ r = findExactRRset(q, qname, qclass, RRType::A(), target, flags, zone);
if (r == SUCCESS && flags == 0) {
a = true;
}
flags = 0;
- r = findExactRRset(q, qname, qclass, RRType::AAAA(), target, flags);
+ r = findExactRRset(q, qname, qclass, RRType::AAAA(), target,
+ flags, zone);
if (r == SUCCESS && flags == 0) {
aaaa = true;
}
@@ -169,12 +177,13 @@
const Name& qname,
const RRClass& qclass,
RRsetList& target,
- uint32_t& flags) const {
+ uint32_t& flags,
+ Name* zone = NULL) const {
Result r;
bool ns = false, ds = false, dname = false;
flags = 0;
- r = findExactRRset(q, qname, qclass, RRType::NS(), target, flags);
+ r = findExactRRset(q, qname, qclass, RRType::NS(), target, flags, zone);
if (r == SUCCESS && flags == 0) {
ns = true;
} else if ((flags & (NO_SUCH_ZONE|NAME_NOT_FOUND))) {
@@ -182,7 +191,7 @@
}
flags = 0;
- r = findExactRRset(q, qname, qclass, RRType::DS(), target, flags);
+ r = findExactRRset(q, qname, qclass, RRType::DS(), target, flags, zone);
if (r == SUCCESS && flags == 0) {
ds = true;
} else if ((flags & (NO_SUCH_ZONE|NAME_NOT_FOUND))) {
@@ -190,7 +199,8 @@
}
flags = 0;
- r = findExactRRset(q, qname, qclass, RRType::DNAME(), target, flags);
+ r = findExactRRset(q, qname, qclass, RRType::DNAME(), target,
+ flags, zone);
if (r == SUCCESS && flags == 0) {
dname = true;
} else if ((flags & (NO_SUCH_ZONE|NAME_NOT_FOUND))) {
@@ -243,25 +253,29 @@
Result findRRset(const Query& q, const Name& qname,
const RRClass& qclass, const RRType& qtype,
- RRsetList& target, uint32_t& flags) const {
+ RRsetList& target, uint32_t& flags,
+ Name* zone = NULL) const {
return (NOT_IMPLEMENTED);
}
Result findExactRRset(const Query& q, const Name& qname,
const RRClass& qclass, const RRType& qtype,
- RRsetList& target, uint32_t& flags) const {
+ RRsetList& target, uint32_t& flags,
+ Name* zone = NULL) const {
return (NOT_IMPLEMENTED);
}
Result findAddrs(const Query& q,
const Name& qname, const RRClass& qclass,
- RRsetList& target, uint32_t& flags) const {
+ RRsetList& target, uint32_t& flags,
+ Name* zone = NULL) const {
return (NOT_IMPLEMENTED);
}
Result findReferral(const Query& q,
const Name& qname, const RRClass& qclass,
- RRsetList& target, uint32_t& flags) const {
+ RRsetList& target, uint32_t& flags,
+ Name* zone = NULL) const {
return (NOT_IMPLEMENTED);
}
Modified: branches/each-ds/src/lib/auth/cpp/data_source_sqlite3.cc
==============================================================================
--- branches/each-ds/src/lib/auth/cpp/data_source_sqlite3.cc (original)
+++ branches/each-ds/src/lib/auth/cpp/data_source_sqlite3.cc Fri Feb 19 01:25:28 2010
@@ -70,7 +70,7 @@
int
Sqlite3DataSrc::
findRecords(const Name& name, const RRType& rdtype, RRsetList& target,
- uint32_t& flags) const
+ Name* zone, uint32_t& flags) const
{
int rc;
const string s_name = name.toText();
@@ -80,7 +80,15 @@
flags = 0;
- int zone_id = findClosest(c_name, NULL);
+ int zone_id;
+ if (zone == NULL) {
+ zone_id = findClosest(c_name, NULL);
+ } else {
+ const string s_zone = zone->toText();
+ const char *c_zone = s_zone.c_str();
+ zone_id = findClosest(c_zone, NULL);
+ }
+
if (zone_id < 0) {
flags = NO_SUCH_ZONE;
return (0);
@@ -374,9 +382,10 @@
const RRClass& qclass,
const RRType& qtype,
RRsetList& target,
- uint32_t& flags) const
-{
- findRecords(qname, qtype, target, flags);
+ uint32_t& flags,
+ Name* zone) const
+{
+ findRecords(qname, qtype, target, zone, flags);
return (SUCCESS);
}
@@ -386,9 +395,10 @@
const RRClass& qclass,
const RRType& qtype,
RRsetList& target,
- uint32_t& flags) const
-{
- findRecords(qname, qtype, target, flags);
+ uint32_t& flags,
+ Name* zone) const
+{
+ findRecords(qname, qtype, target, zone, flags);
// Ignore referrals in this case
flags &= ~REFERRAL;
Modified: branches/each-ds/src/lib/auth/cpp/data_source_sqlite3.h
==============================================================================
--- branches/each-ds/src/lib/auth/cpp/data_source_sqlite3.h (original)
+++ branches/each-ds/src/lib/auth/cpp/data_source_sqlite3.h Fri Feb 19 01:25:28 2010
@@ -38,14 +38,16 @@
const RRClass& qclass,
const RRType& qtype,
RRsetList& target,
- uint32_t& flags) const;
+ uint32_t& flags,
+ Name* zone = NULL) const;
virtual Result findExactRRset(const Query& q,
const Name& qname,
const RRClass& qclass,
const RRType& qtype,
RRsetList& target,
- uint32_t& flags) const;
+ uint32_t& flags,
+ Name* zone = NULL) const;
virtual Result init();
virtual Result close();
@@ -57,7 +59,7 @@
int getVersion(void);
int hasExactZone(const char *name) const;
int findRecords(const Name& name, const RRType& rdtype, RRsetList& target,
- uint32_t& flags) const;
+ Name* zone, uint32_t& flags) const;
int findClosest(const char *name, const char **position) const;
void loadVersion(void);
void setupPreparedStatements(void);
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 Fri Feb 19 01:25:28 2010
@@ -74,7 +74,8 @@
const RRClass& qclass,
const RRType& qtype,
RRsetList& target,
- uint32_t& flags) const
+ uint32_t& flags,
+ Name* zone) const
{
flags = 0;
if (qname == version_name &&
Modified: branches/each-ds/src/lib/auth/cpp/data_source_static.h
==============================================================================
--- branches/each-ds/src/lib/auth/cpp/data_source_static.h (original)
+++ branches/each-ds/src/lib/auth/cpp/data_source_static.h Fri Feb 19 01:25:28 2010
@@ -44,16 +44,18 @@
const RRClass& qclass,
const RRType& qtype,
RRsetList& target,
- uint32_t& flags) const;
+ uint32_t& flags,
+ Name* zone = NULL) const;
Result findExactRRset(const Query& q,
const Name& qname,
const RRClass& qclass,
const RRType& qtype,
RRsetList& target,
- uint32_t& flags) const
+ uint32_t& flags,
+ Name* zone = NULL) const
{
- return (findRRset(q, qname, qclass, qtype, target, flags));
+ return (findRRset(q, qname, qclass, qtype, target, flags, zone));
}
Result init() { 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 Fri Feb 19 01:25:28 2010
@@ -39,9 +39,16 @@
// The standard query tuple: qname/qclass/qtype.
// Note that qtype is ignored in the ADDR_QUERY case.
- const Name qname;
+ const Name& qname;
const RRClass& qclass;
const RRType& qtype;
+
+ // Optional: name for the containing zone, if known.
+ // This is particularly needed when looking up data in a
+ // zone other than the closest enclosure (such as getting
+ // DS queries from a parent zone on a server which serves
+ // both parent and child).
+ Name* zone;
// The section of the reply into which the data should be
// written after it has been fetched from the data source.
@@ -112,20 +119,20 @@
// Constructors
QueryTask(const Name& n, const RRClass& c,
const RRType& t, const Section& sect) :
- qname(n), qclass(c), qtype(t),
+ qname(n), qclass(c), qtype(t), zone(NULL),
section(sect), op(AUTH_QUERY), state(GETANSWER), flags(0) {}
QueryTask(const Name& n, const RRClass& c,
const RRType& t, const Section& sect, const Op o) :
- qname(n), qclass(c), qtype(t),
+ qname(n), qclass(c), qtype(t), zone(NULL),
section(sect), op(o), state(GETANSWER), flags(0) {}
QueryTask(const Name& n, const RRClass& c,
const RRType& t, const Section& sect, const State st) :
- qname(n), qclass(c), qtype(t),
+ qname(n), qclass(c), qtype(t), zone(NULL),
section(sect), op(AUTH_QUERY), state(st), flags(0) {}
QueryTask(const Name& n, const RRClass& c,
const RRType& t, const Section& sect,
const Op o, const State st) :
- qname(n), qclass(c), qtype(t),
+ qname(n), qclass(c), qtype(t), zone(NULL),
section(sect), op(o), state(st), flags(0) {}
// These are special constructors for particular query task types,
@@ -133,16 +140,16 @@
//
// A simple query doesn't need to specify section or state.
QueryTask(const Name& n, const RRClass& c, const RRType& t, const Op o) :
- qname(n), qclass(c), qtype(t), section(Section::ANSWER()),
- op(o), state(GETANSWER), flags(0) {
+ qname(n), qclass(c), qtype(t), zone(NULL),
+ section(Section::ANSWER()), op(o), state(GETANSWER), flags(0) {
if (op != SIMPLE_QUERY) {
throw "invalid constructor for this task operation";
}
}
// A referral query doesn't need to specify section, state, or type.
QueryTask(const Name& n, const RRClass& c, const Op o) :
- qname(n), qclass(c), qtype(RRType::ANY()), section(Section::ANSWER()),
- op(o), state(GETANSWER), flags(0) {
+ qname(n), qclass(c), qtype(RRType::ANY()), zone(NULL),
+ section(Section::ANSWER()), op(o), state(GETANSWER), flags(0) {
if (op != REF_QUERY) {
throw "invalid constructor for this task operation";
}
@@ -150,7 +157,7 @@
// An address 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()),
+ qname(n), qclass(c), qtype(RRType::ANY()), zone(NULL),
section(sect), op(o), state(st), flags(0) {
if (op != ADDR_QUERY) {
throw "invalid constructor for this task operation";
More information about the bind10-changes
mailing list