[svn] commit: r829 - in /branches/each-ds/src/lib/auth/cpp: TODO data_source.cc data_source.h query.h

BIND 10 source code commits bind10-changes at lists.isc.org
Tue Feb 16 06:17:21 UTC 2010


Author: each
Date: Tue Feb 16 06:17:21 2010
New Revision: 829

Log:
checkpoint:
 - omit records from additional section that were already returned in
   the answer section
 - improve support for multiple-RRset answers (e.g., from ANY queries,
   though those are still not supported by the underlying data source)

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/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 Tue Feb 16 06:17:21 2010
@@ -1,11 +1,9 @@
 Data source:
 - change RRsetList to something that can be indexed by the RRType
-- improve support for multiple-RRset answers from the data source
 - add support for type-ANY queries
 - consider altering the "task queue" design (at this point it's relatively
   rare for it to have more than one item).
 - check want_additional before adding additional data
-- omit additional data that's already in the answer section
 - make sure glue is not returned in additional section except for NS
 
 DNSSEC:
@@ -29,3 +27,5 @@
 Other changes:
 - add Message method getSectionCount() so it isn't necessary to iterate
   over the question section to find out how many there are.
+- add Name method reverse() to reverse labels (might return a Name, or
+  maybe just a string).

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 Tue Feb 16 06:17:21 2010
@@ -122,6 +122,7 @@
     Result result;
     Message& m = q.message();
 
+    m.clearHeaderFlag(MessageFlag::AA());
     while (!q.tasks().empty()) {
         RdataIteratorPtr it;
         RRsetList data, sigs;
@@ -197,14 +198,7 @@
             }
 
             result = doQueryTask(ds, q, task, data);
-            if (result == SUCCESS) {
-                if (task.op == QueryTask::ADDR_QUERY) {
-                    BOOST_FOREACH (RRsetPtr rrset, data) {
-                        m.addRRset(task.section, rrset);
-                    }
-                    continue;
-                }
-            } else if (result == REFERRAL_FOUND) {
+            if (result == REFERRAL_FOUND) {
                 if (zone->getLabelCount() == task.qname.getLabelCount()) {
                     // An NS at the zone apex is expected.
                     result = SUCCESS;
@@ -212,47 +206,71 @@
             }
         }
 
+        bool have_ns = false;
+
         switch (result) {
         case SUCCESS:
-            // This will need to be able to handle multiple RRsets
-            // once RRType ANY and/or DNSSEC are supported.  For right
-            // now, however, we assume that an auth query will return
-            // only one RRset: either the data requested or a CNAME.
-            m.addRRset(task.section, data[0]);
+            // XXX: This will need to be able to handle multiple RRsets
+            // once RRType ANY is supported.  For right now, however, we
+            // can assume that an auth query that reaches this point has
+            // only one RRset: either the data requested, or a CNAME.
 
             switch (task.state) {
             case QueryTask::GETANSWER:
             case QueryTask::FOLLOWCNAME:
-                getAdditional(q, data[0]);
+                BOOST_FOREACH(RRsetPtr rrset, data) {
+                    m.addRRset(task.section, rrset);
+                    getAdditional(q, rrset);
+                    if (rrset->getType() == RRType::NS()) {
+                        have_ns = true;
+                    }
+                }
+                q.setStatus(Query::ANSWERED);
                 if (q.tasks().empty()) {
                     // Data found, no additional processing needed.
                     // Add the NS records for the enclosing zone to
                     // the authority section.
-                    if (data[0]->getType() != RRType::NS()) {
+                    if (!have_ns) {
                         RRsetList auth;
-                        QueryTask t(Name(*zone), task.qclass, RRType::NS(), 
-                                    QueryTask::SIMPLE_QUERY); 
+                        QueryTask t(Name(*zone), task.qclass,
+                                    QueryTask::REF_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]);
+                        BOOST_FOREACH(RRsetPtr rrset, auth) {
+                            if (rrset->getType() == RRType::DNAME()) {
+                                continue;
+                            }
+                            m.addRRset(Section::AUTHORITY(), rrset);
+                            getAdditional(q, rrset);
+                        }
                     }
                 }
                 continue;
 
-            case QueryTask::GETADDITIONAL:
+            case QueryTask::GETAUTHORITY:
+                BOOST_FOREACH(RRsetPtr rrset, data) {
+                    m.addRRset(task.section, rrset);
+                    getAdditional(q, rrset);
+                }
                 if (q.tasks().empty()) {
                     q.setStatus(Query::SUCCESS);
                     return;
                 }
                 continue;
 
-            case QueryTask::GETAUTHORITY:
-                getAdditional(q, data[0]);
+            case QueryTask::GETADDITIONAL:
+                BOOST_FOREACH(RRsetPtr rrset, data) {
+                    if (q.status() == Query::ANSWERED &&
+                        rrset->getName() == q.qname() &&
+                        rrset->getType() == q.qtype()) {
+                        continue;
+                    }
+                    m.addRRset(task.section, rrset);
+                }
                 if (q.tasks().empty()) {
                     q.setStatus(Query::SUCCESS);
                     return;
@@ -279,15 +297,19 @@
             if (task.state == QueryTask::GETANSWER) {
                 RRsetList auth;
                 m.clearHeaderFlag(MessageFlag::AA());
-                QueryTask t(task.qname, task.qclass, RRType::NS(),
-                            QueryTask::SIMPLE_QUERY);
+                QueryTask t(task.qname, task.qclass, QueryTask::REF_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]);
+                BOOST_FOREACH (RRsetPtr rrset, auth) {
+                    if (rrset->getType() == RRType::DNAME()) {
+                        continue;
+                    }
+                    m.addRRset(Section::AUTHORITY(), rrset);
+                    getAdditional(q, rrset);
+                }
             }
             continue;
 
@@ -324,24 +346,35 @@
                     // 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 (r == CNAME_FOUND) {
-                            chaseCname(q, task, wild[0]);
-                        } else {
-                            RRsetList auth;
-                            QueryTask t(Name(*zone), task.qclass, RRType::NS(), 
-                                        QueryTask::SIMPLE_QUERY); 
-                            r = doQueryTask(ds, q, t, auth);
-                            if (r != SUCCESS) {
-                                m.setRcode(Rcode::SERVFAIL());
-                                return;
+                        // XXX: since this is a SIMPLE_QUERY, there can
+                        // only be one rrset returned in wild.  But
+                        // eventually this will need to handle ANY queries,
+                        // so wrap it in a BOOST_FOREACH statement anyway.
+                        BOOST_FOREACH (RRsetPtr rrset, wild) {
+                            rrset->setName(task.qname);
+                            m.addRRset(Section::ANSWER(), rrset);
+
+                            if (r == CNAME_FOUND &&
+                                q.qtype() != RRType::ANY()) {
+                                chaseCname(q, task, rrset);
+                            } else {
+                                RRsetList auth;
+                                QueryTask t(Name(*zone), task.qclass,
+                                            QueryTask::REF_QUERY); 
+                                r = doQueryTask(ds, q, t, auth);
+                                if (r != SUCCESS) {
+                                    m.setRcode(Rcode::SERVFAIL());
+                                    return;
+                                }
+
+                                BOOST_FOREACH (RRsetPtr rrset, data) {
+                                    if (rrset->getType() == RRType::DNAME()) {
+                                        continue;
+                                    }
+                                    m.addRRset(Section::AUTHORITY(), rrset);
+                                    getAdditional(q, rrset);
+                                }
                             }
-
-                            m.addRRset(Section::AUTHORITY(), auth[0]);
-                            getAdditional(q, auth[0]);
                         }
                         continue;
                     }
@@ -383,7 +416,6 @@
             }
             continue;
 
-        case DNAME_FOUND:       // XXX: not yet implemented
         case NOT_IMPLEMENTED:
         case ERROR:
             m.setRcode(Rcode::SERVFAIL());

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 Tue Feb 16 06:17:21 2010
@@ -40,7 +40,6 @@
         ERROR,
         NOT_IMPLEMENTED,
         CNAME_FOUND,
-        DNAME_FOUND,
         REFERRAL_FOUND,
         ZONE_NOT_FOUND,
         NAME_NOT_FOUND,

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 Tue Feb 16 06:17:21 2010
@@ -165,6 +165,7 @@
     // The state of a query: running, succeeded, or failed.
     enum Status {
         RUNNING,
+        ANSWERED,
         SUCCESS,
         FAILURE
     };




More information about the bind10-changes mailing list