[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