[svn] commit: r889 - in /branches/each-ds/src/lib: auth/cpp/TODO auth/cpp/data_source.cc auth/cpp/data_source_static.cc auth/cpp/query.h dns/cpp/rdata/generic/mx_15.cc

BIND 10 source code commits bind10-changes at lists.isc.org
Sat Feb 20 03:09:56 UTC 2010


Author: each
Date: Sat Feb 20 03:09:55 2010
New Revision: 889

Log:
checkpoint:
 - do not return glue data in additional section when processing MX
   queries.  (same for SRV and NAPTR, when they are supported.)
 - added ANY query support to static 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_static.cc
    branches/each-ds/src/lib/auth/cpp/query.h
    branches/each-ds/src/lib/dns/cpp/rdata/generic/mx_15.cc

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 Sat Feb 20 03:09:55 2010
@@ -1,9 +1,7 @@
 Data source:
 - change filenames so we don't have everything starting with "data_source_"?
-- make sure glue is not returned in additional section except for NS.
-  we need a way to indicate "glue OK" in calls to findExactRRset().
 
-SQL data source optimization and cleanup:
+SQL data source:
 - should implement findAddrs() and findReferral() directly instead of
   using the implementation in DataSrc.
 - need ANY queries

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 Sat Feb 20 03:09:55 2010
@@ -30,12 +30,16 @@
         if (rrset->getType() == RRType::NS()) {
             const generic::NS& ns = dynamic_cast<const generic::NS&>(rd);
 
-            t = new QueryTask(ns.getNSName(), q.qclass(), Section::ADDITIONAL(),
-                              QueryTask::ADDR_QUERY, QueryTask::GETADDITIONAL); 
+            t = new QueryTask(ns.getNSName(), q.qclass(),
+                              Section::ADDITIONAL(),
+                              QueryTask::GLUE_QUERY,
+                              QueryTask::GETADDITIONAL); 
         } else if (rrset->getType() == RRType::MX()) {
             const generic::MX& mx = dynamic_cast<const generic::MX&>(rd);
-            t = new QueryTask(mx.getMXName(), q.qclass(), Section::ADDITIONAL(),
-                              QueryTask::ADDR_QUERY, QueryTask::GETADDITIONAL); 
+            t = new QueryTask(mx.getMXName(), q.qclass(),
+                              Section::ADDITIONAL(),
+                              QueryTask::NOGLUE_QUERY,
+                              QueryTask::GETADDITIONAL); 
         }
         if (t != NULL) {
             q.tasks().push(*t);
@@ -77,7 +81,7 @@
     RdataIteratorPtr it;
     it = rrset->getRdataIterator();
 
-    // More than one DNAME RR in the RRset is illegal, so we only have
+    // More than one CNAME RR in the RRset is illegal, so we only have
     // to process the first one.
     it->first();
     if (it->isLast()) {
@@ -104,7 +108,8 @@
         return (ds->findExactRRset(q, task.qname, task.qclass, task.qtype,
                                    target, task.flags, task.zone));
 
-    case QueryTask::ADDR_QUERY:
+    case QueryTask::GLUE_QUERY:
+    case QueryTask::NOGLUE_QUERY:
         return (ds->findAddrs(q, task.qname, task.qclass, target,
                               task.flags, task.zone));
 
@@ -112,6 +117,9 @@
         return (ds->findReferral(q, task.qname, task.qclass, target,
                                  task.flags, task.zone));
     }
+
+    // Not reached
+    return (DataSrc::ERROR);
 }
 
 //
@@ -136,9 +144,9 @@
         QueryTask task = q.tasks().front();
         q.tasks().pop();
 
-        // No task type other than these should ever be on the task queue.
-        if (task.op != QueryTask::AUTH_QUERY &&
-            task.op != QueryTask::ADDR_QUERY) {
+        // These task types should never be on the task queue.
+        if (task.op == QueryTask::SIMPLE_QUERY ||
+            task.op == QueryTask::REF_QUERY) {
             m.setRcode(Rcode::SERVFAIL());
             q.setStatus(Query::FAILURE);
             return;
@@ -162,56 +170,64 @@
             task.flags = NO_SUCH_ZONE;
         } else {
             task.zone = new Name(*zone);
-            if (task.op == QueryTask::AUTH_QUERY) {
-                // 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--) {
-                            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;
-                                break;
+
+            // For these query task types, if there is more than
+            // one level between the zone name and qname, we need to
+            // check the intermediate nodes for referrals.
+            if (task.op == QueryTask::AUTH_QUERY ||
+                task.op == QueryTask::NOGLUE_QUERY) {
+                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--) {
+                        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;
+                            break;
+                        }
+                    }
+
+                    // Found a referral while getting additional data
+                    // for something other than NS; we skip it.
+                    if (found && task.op == QueryTask::NOGLUE_QUERY) {
+                        continue;
+                    }
+
+                    // Found a referral while getting answer data;
+                    // send a delegation.
+                    if (found) {
+                        if (RRsetPtr r = ref[RRType::DNAME()]) {
+                            RRsetList syn;
+                            m.addRRset(Section::ANSWER(), r,
+                                       q.wantDnssec());
+                            synthesizeCname(q, task, r, syn);
+                            if (syn.size() == 1) {
+                                m.addRRset(Section::ANSWER(), syn[0],
+                                           q.wantDnssec());
+                                chaseCname(q, task, syn[0]);
+                                continue;
                             }
                         }
-
-                        if (found) {
-                            if (RRsetPtr r = ref[RRType::DNAME()]) {
-                                RRsetList syn;
-                                m.addRRset(Section::ANSWER(), r,
+                        BOOST_FOREACH (RRsetPtr r, ref) {
+                            if (r->getType() != RRType::DNAME()) {
+                                m.addRRset(Section::AUTHORITY(), r,
                                            q.wantDnssec());
-                                synthesizeCname(q, task, r, syn);
-                                if (syn.size() == 1) {
-                                    m.addRRset(Section::ANSWER(), syn[0],
-                                               q.wantDnssec());
-                                    chaseCname(q, task, syn[0]);
-                                    continue;
-                                }
+                                getAdditional(q, r);
                             }
-                            BOOST_FOREACH (RRsetPtr r, ref) {
-                                if (r->getType() != RRType::DNAME()) {
-                                    m.addRRset(Section::AUTHORITY(), r,
-                                               q.wantDnssec());
-                                    getAdditional(q, r);
-                                }
-                            }
-                            continue;
-                        }
+                        }
+                        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.)
-                if (task.state == QueryTask::GETANSWER) {
+                if (task.op == QueryTask::AUTH_QUERY &&
+                    task.state == QueryTask::GETANSWER) {
                     m.setHeaderFlag(MessageFlag::AA());
                 }
             }
@@ -224,51 +240,54 @@
             }
 
             // 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
+            // i.e., if an NS was at the zone apex, or if we were querying
+            // specifically for the NS, DS or DNAME record.
             if ((task.flags & REFERRAL) &&
                 (zone->getLabelCount() == task.qname.getLabelCount() ||
-                 task.qtype == RRType::DS() || task.qtype == RRType::DNAME())) {
+                 task.qtype == RRType::NS() ||
+                 task.qtype == RRType::DS() ||
+                 task.qtype == RRType::DNAME())) {
                 task.flags &= ~REFERRAL;
             }
         }
 
         if (result == SUCCESS && task.flags == 0) {
-            bool have_ns = false;
+            bool have_ns = false, need_auth = false;
             switch (task.state) {
             case QueryTask::GETANSWER:
             case QueryTask::FOLLOWCNAME:
                 BOOST_FOREACH(RRsetPtr rrset, data) {
                     m.addRRset(task.section, rrset, q.wantDnssec());
+                    if (q.tasks().empty()) {
+                        need_auth = true;
+                    }
                     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 (!have_ns) {
-                        RRsetList auth;
-                        QueryTask t(Name(*zone), task.qclass,
-                                    QueryTask::REF_QUERY); 
-                        result = doQueryTask(ds, q, t, auth);
-                        if (result != SUCCESS) {
-                            m.setRcode(Rcode::SERVFAIL());
-                            q.setStatus(Query::FAILURE);
-                            return;
-                        }
-
-                        BOOST_FOREACH(RRsetPtr rrset, auth) {
-                            if (rrset->getType() == RRType::DNAME()) {
-                                continue;
-                            }
-                            m.addRRset(Section::AUTHORITY(), rrset,
-                                       q.wantDnssec());
-                            getAdditional(q, rrset);
-                        }
+                if (need_auth && !have_ns) {
+                // Data found, no additional processing needed.
+                // Add the NS records for the enclosing zone to
+                // the authority section.
+                    RRsetList auth;
+                    QueryTask t(Name(*zone), task.qclass,
+                                QueryTask::REF_QUERY); 
+                    result = doQueryTask(ds, q, t, auth);
+                    if (result != SUCCESS) {
+                        m.setRcode(Rcode::SERVFAIL());
+                        q.setStatus(Query::FAILURE);
+                        return;
+                    }
+
+                    BOOST_FOREACH(RRsetPtr rrset, auth) {
+                        if (rrset->getType() == RRType::DNAME()) {
+                            continue;
+                        }
+                        m.addRRset(Section::AUTHORITY(), rrset,
+                                   q.wantDnssec());
+                        getAdditional(q, rrset);
                     }
                 }
                 continue;
@@ -283,23 +302,6 @@
                         continue;
                     }
                     additional.addRRset(rrset);
-                }
-                if (q.tasks().empty()) {
-                    // We're done, so now copy in the additional data:
-                    // data first, then signatures.  (If we run out of
-                    // space, signatures in additional section are
-                    // optional.)
-                    BOOST_FOREACH(RRsetPtr rrset, additional) {
-                        m.addRRset(Section::AUTHORITY(), rrset, false);
-                    }
-                    if (q.wantDnssec()) {
-                        BOOST_FOREACH(RRsetPtr rrset, additional) {
-                            m.addRRset(Section::ADDITIONAL(),
-                                       rrset->getRRsig(), false);
-                        }
-                    }
-                    q.setStatus(Query::SUCCESS);
-                    return;
                 }
                 continue;
 
@@ -342,7 +344,7 @@
                     }
                     getAdditional(q, rrset);
                 }
-            }
+            } 
             continue;
         } else if (task.flags & NO_SUCH_ZONE) {
             // No such zone.  If we're chasing cnames or adding additional
@@ -504,7 +506,24 @@
             return;
         }
     }
-};
-
-}
-}
+
+    // We're done, so now copy in the additional data:
+    // data first, then signatures.  (If we run out of
+    // space, signatures in additional section are
+    // optional.)
+    BOOST_FOREACH(RRsetPtr rrset, additional) {
+        m.addRRset(Section::ADDITIONAL(), rrset, false);
+    }
+    if (q.wantDnssec()) {
+        BOOST_FOREACH(RRsetPtr rrset, additional) {
+            if (rrset->getRRsig()) {
+                m.addRRset(Section::ADDITIONAL(),
+                           rrset->getRRsig(), false);
+            }
+        }
+    }
+    q.setStatus(Query::SUCCESS);
+}
+
+}
+}

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 Sat Feb 20 03:09:55 2010
@@ -79,21 +79,23 @@
 {
     flags = 0;
     if (qname == version_name &&
-        qclass == version->getClass() && qtype == version->getType()) {
+        qclass == version->getClass() &&
+        (qtype == version->getType() || qtype == RRType::ANY())) {
         target.addRRset(version);
         return (SUCCESS);
     } else if (qname == version_name &&
                qclass == version_ns->getClass() &&
-               qtype == version_ns->getType()) {
+               (qtype == version->getType() || qtype == RRType::ANY())) {
         target.addRRset(version_ns);
         return (SUCCESS);
     } else if (qname == authors_name &&
-               qclass == authors->getClass() && qtype == authors->getType()) {
+               qclass == authors->getClass() &&
+               (qtype == authors->getType() || qtype == RRType::ANY())) {
         target.addRRset(authors);
         return (SUCCESS);
     } else if (qname == authors_name &&
                qclass == authors_ns->getClass() &&
-               qtype == authors_ns->getType()) {
+               (qtype == authors->getType() || qtype == RRType::ANY())) {
         target.addRRset(authors_ns);
         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 Sat Feb 20 03:09:55 2010
@@ -38,7 +38,7 @@
     // moved to private and wrapped in get() functions later.
 
     // The standard query tuple: qname/qclass/qtype.
-    // Note that qtype is ignored in the ADDR_QUERY case.
+    // Note that qtype is ignored in the GLUE_QUERY/NOGLUE_QUERY case.
     const Name& qname;
     const RRClass& qclass;
     const RRType& qtype;
@@ -64,13 +64,16 @@
     // - AUTH_QUERY: look for a match for qname/qclass/qtype, or
     //   for qname/qclass/CNAME, or for a referral.
     //
-    // - ADDR_QUERY: look for matches with qname/qclass/A
+    // - GLUE_QUERY: look for matches with qname/qclass/A
     //   OR qname/class/AAAA in local data, regardless of
     //   authority, for use in glue.  (This can be implemented
     //   as two successive SIMPLE_QUERY tasks, but might be
     //   optimized by the concrete data source implementation
     //   by turning it into a single database lookup.)
     //
+    // - NOGLUE_QUERY: same as GLUE_QUERY except that answers
+    //   are rejected if they are below a zone cut.
+    //
     // - REF_QUERY: look for matches for qname/qclass/NS,
     //   qname/qclass/DS, and qname/qclass/DNAME.  Used
     //   to search for a zone cut.
@@ -78,8 +81,9 @@
     const enum Op {
         SIMPLE_QUERY,
         AUTH_QUERY,
-        ADDR_QUERY,
-        REF_QUERY
+        GLUE_QUERY,
+        NOGLUE_QUERY,
+        REF_QUERY,
     } op;
 
     // The state field indicates the state of the query; it controls
@@ -154,12 +158,12 @@
             throw "invalid constructor for this task operation";
         }
     }
-    // An address query doesn't need to specify type.
+    // A glue (or noglue) 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()), zone(NULL),
         section(sect), op(o), state(st), flags(0) {
-        if (op != ADDR_QUERY) {
+        if (op != GLUE_QUERY && op != NOGLUE_QUERY) {
             throw "invalid constructor for this task operation";
         }
     }

Modified: branches/each-ds/src/lib/dns/cpp/rdata/generic/mx_15.cc
==============================================================================
--- branches/each-ds/src/lib/dns/cpp/rdata/generic/mx_15.cc (original)
+++ branches/each-ds/src/lib/dns/cpp/rdata/generic/mx_15.cc Sat Feb 20 03:09:55 2010
@@ -38,10 +38,21 @@
     // check consistency.
 }
 
-MX::MX(const std::string& mxstr) :
+MX::MX(const std::string& mx_str) :
     preference_(0), mxname_(".")
 {
-    dns_throw(InvalidRdataText, "Not implemented yet");
+    istringstream iss(mx_str);
+    uint16_t pref;
+    string mxname;
+
+    iss >> pref >> mxname;
+
+    if (iss.bad() || iss.fail() || !iss.eof()) {
+        dns_throw(InvalidRdataText, "Invalid MX text format");
+    }
+
+    preference_ = pref;
+    mxname_ = Name(mxname);
 }
 
 MX::MX(uint16_t preference, const Name& mxname) :




More information about the bind10-changes mailing list