[svn] commit: r816 - /branches/each-ds/src/lib/auth/cpp/data_source.cc

BIND 10 source code commits bind10-changes at lists.isc.org
Sun Feb 14 08:19:09 UTC 2010


Author: each
Date: Sun Feb 14 08:19:09 2010
New Revision: 816

Log:
checkpoint:
 - out-of-zone referrals work now

Modified:
    branches/each-ds/src/lib/auth/cpp/data_source.cc

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 08:19:09 2010
@@ -85,7 +85,7 @@
         QueryTask task = q.tasks().front();
         q.tasks().pop();
 
-        // Other task types should never be pushed onto the task queue.
+        // No task type other than these should ever be on the task queue.
         if (task.op != QueryTask::AUTH_QUERY &&
             task.op != QueryTask::ADDR_QUERY) {
             m.setRcode(Rcode::SERVFAIL());
@@ -100,8 +100,46 @@
         const DataSrc* ds = match.bestDataSrc();
         const Name* zone = match.closestName();
 
-        if (ds != NULL) {
-            m.setHeaderFlag(MessageFlag::AA());
+        if (ds == NULL) {
+            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.
+                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--) {
+                            QueryTask t(task.qname.split(i - 1, nlen - i),
+                                        task.qclass, RRType::ANY(),
+                                        Section::AUTHORITY(),
+                                        QueryTask::REF_QUERY); 
+                            result = doQueryTask(ds, q, t, ref);
+                            if (result == SUCCESS) {
+                                found = true;
+                                break;
+                            }
+                        }
+                        // XXX: Currently ref will only have NS;
+                        // later it must handle NS, DS, or DNAME
+                        if (found) {
+                            m.addRRset(Section::AUTHORITY(), ref[0]);
+                            getAdditional(q, ref[0]);
+                            continue;
+                        }
+                    }
+                }
+            }
+
             result = doQueryTask(ds, q, task, data);
             if (result == SUCCESS) {
                 if (task.op == QueryTask::ADDR_QUERY) {
@@ -116,8 +154,6 @@
                     result = SUCCESS;
                 }
             }
-        } else {
-            result = ZONE_NOT_FOUND;
         }
 
         switch (result) {




More information about the bind10-changes mailing list