[svn] commit: r818 - in /branches/each-ds/src/lib: auth/cpp/data_source.cc auth/cpp/data_source.h dns/cpp/message.cc dns/cpp/message.h dns/cpp/rrset.cc dns/cpp/rrset.h
BIND 10 source code commits
bind10-changes at lists.isc.org
Sun Feb 14 17:26:56 UTC 2010
Author: each
Date: Sun Feb 14 17:26:55 2010
New Revision: 818
Log:
checkpoint:
- wildcards fully supported now
- added setName() method to RRset to permit RRsets from wildcards
to be changed to match the query name.
- added comments
Modified:
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/dns/cpp/message.cc
branches/each-ds/src/lib/dns/cpp/message.h
branches/each-ds/src/lib/dns/cpp/rrset.cc
branches/each-ds/src/lib/dns/cpp/rrset.h
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 Sun Feb 14 17:26:55 2010
@@ -98,10 +98,6 @@
result = ZONE_NOT_FOUND;
} else {
if (task.op == QueryTask::AUTH_QUERY) {
- // We appear to have authoritative data; set the header
- // flag. (We may clear it later if we find a referral.)
- m.setHeaderFlag(MessageFlag::AA());
-
// 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.
@@ -131,6 +127,11 @@
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.)
+ m.setHeaderFlag(MessageFlag::AA());
}
}
@@ -203,6 +204,8 @@
}
case CNAME_FOUND:
+ // The qname node contains a CNAME. Add a new task to the
+ // queue to look up its target.
if (data.size() != 1 || data[0]->getType() != RRType::CNAME()) {
dns_throw (Unexpected, "invalid data");
}
@@ -223,6 +226,7 @@
continue;
case REFERRAL_FOUND:
+ // The qname node contains an out-of-zone referral.
m.clearHeaderFlag(MessageFlag::AA());
if (task.state == QueryTask::GETANSWER) {
RRsetList auth;
@@ -241,6 +245,77 @@
case NAME_NOT_FOUND:
case TYPE_NOT_FOUND:
+ // No data found at this qname. If we were looking for answer
+ // data, we need to check to see if there are any relevant
+ // wildcards.
+ 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 wild;
+ Name star("*");
+
+ for(int i = 1; i <= diff; i++) {
+ Name wname(star.concatenate(task.qname.split(i,
+ nlen - i)));
+ QueryTask t(wname, task.qclass, task.qtype,
+ Section::ANSWER(),
+ QueryTask::SIMPLE_QUERY);
+ result = doQueryTask(ds, q, t, wild);
+ if (result == SUCCESS || result == CNAME_FOUND) {
+ found = true;
+ break;
+ }
+ }
+
+ // A wildcard was found. Add the data to the answer
+ // section (but with the name changed to match the
+ // qname), and then continue as if this were a normal
+ // 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 (result == CNAME_FOUND) {
+ it = wild[0]->getRdataIterator();
+ for (it->first(); !it->isLast(); it->next()) {
+ const rdata::Rdata& rd(it->getCurrent());
+ const rdata::generic::CNAME& cname =
+ dynamic_cast<const rdata::generic::CNAME&>(rd);
+ const Name& target(cname.getCname());
+ QueryTask t(target, task.qclass, task.qtype,
+ Section::ANSWER(),
+ QueryTask::FOLLOWCNAME);
+ q.tasks().push(t);
+ break;
+ }
+ } else {
+ RRsetList auth;
+ QueryTask t(Name(*zone), task.qclass, RRType::NS(),
+ Section::AUTHORITY(),
+ QueryTask::SIMPLE_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]);
+ }
+ continue;
+ }
+ }
+ }
+
+ // If we've reached this point, there really is no answer.
+ // If we were chasing cnames or adding additional data, that's
+ // okay, but if we were doing an original query, return NXDOMAIN
+ // and the SOA.
if (task.state == QueryTask::GETANSWER) {
if (result == NAME_NOT_FOUND) {
m.setRcode(Rcode::NXDOMAIN());
@@ -262,6 +337,9 @@
continue;
case ZONE_NOT_FOUND:
+ // No such zone. If we're chasing cnames or adding additional
+ // data, that's okay, but if doing an original query, return
+ // REFUSED.
if (task.state == QueryTask::GETANSWER) {
m.setRcode(Rcode::REFUSED());
q.setStatus(Query::FAILURE);
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 Sun Feb 14 17:26:55 2010
@@ -162,13 +162,11 @@
RRsetList& target,
RRsetList& sigs) const {
Result r;
- bool found_ns = false;
- bool found_ds = false;
- bool found_dname = false;
+ bool ns = false, ds = false, dname = false;
r = findExactRRset(q, qname, qclass, RRType::NS(), target, sigs);
if (r == SUCCESS) {
- found_ns = true;
+ ns = true;
} else if (r != TYPE_NOT_FOUND) {
return (r);
}
@@ -179,20 +177,20 @@
#if 0
r = findExactRRset(q, qname, qclass, RRType::DS(), target, sigs);
if (r == SUCCESS) {
- found_ds = true;
+ ds = true;
} else if (r != TYPE_NOT_FOUND) {
return (r);
}
r = findExactRRset(q, qname, qclass, RRType::DNAME(), target, sigs);
if (r == SUCCESS) {
- found_dname = true;
+ dname = true;
} else if (r != TYPE_NOT_FOUND) {
return (r);
}
#endif
- if (found_ns || found_dname || found_ds) {
+ if (ns || dname || ds) {
return (SUCCESS);
} else {
return (TYPE_NOT_FOUND);
Modified: branches/each-ds/src/lib/dns/cpp/message.cc
==============================================================================
--- branches/each-ds/src/lib/dns/cpp/message.cc (original)
+++ branches/each-ds/src/lib/dns/cpp/message.cc Sun Feb 14 17:26:55 2010
@@ -214,6 +214,12 @@
Message::setHeaderFlag(const MessageFlag& flag)
{
impl_->flags_ |= flag.getBit();
+}
+
+void
+Message::clearHeaderFlag(const MessageFlag& flag)
+{
+ impl_->flags_ &= ~flag.getBit();
}
qid_t
Modified: branches/each-ds/src/lib/dns/cpp/message.h
==============================================================================
--- branches/each-ds/src/lib/dns/cpp/message.h (original)
+++ branches/each-ds/src/lib/dns/cpp/message.h Sun Feb 14 17:26:55 2010
@@ -478,6 +478,7 @@
public:
bool getHeaderFlag(const MessageFlag& flag) const;
void setHeaderFlag(const MessageFlag& flag);
+ void clearHeaderFlag(const MessageFlag& flag);
qid_t getQid() const;
void setQid(qid_t qid);
const Rcode& getRcode() const;
Modified: branches/each-ds/src/lib/dns/cpp/rrset.cc
==============================================================================
--- branches/each-ds/src/lib/dns/cpp/rrset.cc (original)
+++ branches/each-ds/src/lib/dns/cpp/rrset.cc Sun Feb 14 17:26:55 2010
@@ -140,6 +140,18 @@
BasicRRset::getName() const
{
return (impl_->name_);
+}
+
+void
+BasicRRset::setName(const Name& n) const
+{
+ impl_->name_ = n;
+}
+
+void
+BasicRRset::setName(const Name* n) const
+{
+ impl_->name_ = Name(*n);
}
const RRClass&
Modified: branches/each-ds/src/lib/dns/cpp/rrset.h
==============================================================================
--- branches/each-ds/src/lib/dns/cpp/rrset.h (original)
+++ branches/each-ds/src/lib/dns/cpp/rrset.h Sun Feb 14 17:26:55 2010
@@ -85,6 +85,8 @@
virtual unsigned int toWire(MessageRenderer& renderer) const;
virtual unsigned int getRdataCount() const = 0;
virtual const Name& getName() const = 0;
+ virtual void setName(const Name& n) const = 0;
+ virtual void setName(const Name* n) const = 0;
virtual const RRClass& getClass() const = 0;
virtual const RRType& getType() const = 0;
virtual const RRTTL& getTTL() const = 0;
@@ -154,6 +156,8 @@
//@{
virtual unsigned int getRdataCount() const;
virtual const Name& getName() const;
+ virtual void setName(const Name& n) const;
+ virtual void setName(const Name* n) const;
virtual const RRClass& getClass() const;
virtual const RRType& getType() const;
virtual const RRTTL& getTTL() const;
More information about the bind10-changes
mailing list