[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