Browse Source

* Take MemoryDataSrc (instead of a zone table).
* If zone->find() is successful, add the returned RRset to the answer section of the response.


git-svn-id: svn://bind10.isc.org/svn/bind10/branches/trac439@3908 e5f2f494-b856-4b98-b285-d166d9295462

Jerry 14 years ago
parent
commit
d308d15037
4 changed files with 91 additions and 35 deletions
  1. 66 8
      src/bin/auth/query.cc
  2. 16 18
      src/bin/auth/query.h
  3. 8 8
      src/bin/auth/tests/query_unittest.cc
  4. 1 1
      src/lib/datasrc/data_source.h

+ 66 - 8
src/bin/auth/query.cc

@@ -14,29 +14,87 @@
 
 #include <dns/message.h>
 #include <dns/rcode.h>
+#include <iostream>
 
-#include <datasrc/zonetable.h>
+#include <datasrc/memory_datasrc.h>
 
 #include <auth/query.h>
 
 using namespace isc::dns;
 using namespace isc::datasrc;
+using namespace std;
 
 namespace isc {
 namespace auth {
+
+struct Query::QueryImpl {
+    QueryImpl(const MemoryDataSrc& memory_datasrc, const Name& qname,
+              const RRType& qtype, Message& response) :
+        memory_datasrc_(memory_datasrc), qname_(qname), qtype_(qtype),
+        response_(response)
+    {}
+
+    const MemoryDataSrc& memory_datasrc_;
+    const Name& qname_;
+    const RRType& qtype_;
+    Message& response_;
+};
+
+Query::Query(const MemoryDataSrc& memory_datasrc, const Name& qname,
+             const RRType& qtype, Message& response) :
+    impl_(new QueryImpl(memory_datasrc, qname, qtype, response))
+{}
+
+Query::~Query() {
+    delete impl_;
+}
+
 void
 Query::process() const {
-    const ZoneTable::FindResult result = zone_table_.findZone(qname_);
+    const MemoryDataSrc::FindResult result =
+        impl_->memory_datasrc_.findZone(impl_->qname_);
+    bool keep_doing = true;
 
-    if (result.code != isc::datasrc::result::SUCCESS &&
-        result.code != isc::datasrc::result::PARTIALMATCH) {
-        response_.setRcode(Rcode::SERVFAIL());
+    if (result.code != result::SUCCESS &&
+        result.code != result::PARTIALMATCH) {
+        impl_->response_.setRcode(Rcode::SERVFAIL());
         return;
     }
 
-    // Right now we have no code to search the zone, so we simply return
-    // NXDOMAIN for tests.
-    response_.setRcode(Rcode::NXDOMAIN());
+    while (keep_doing) {
+        keep_doing = false;
+        Zone::FindResult db_result = result.zone->find(impl_->qname_,
+                                                       impl_->qtype_);
+        switch (db_result.code) {
+            case Zone::SUCCESS:
+                impl_->response_.setRcode(Rcode::NOERROR());
+                impl_->response_.addRRset(Message::SECTION_ANSWER,
+                           boost::const_pointer_cast<RRset>(db_result.rrset));
+                // fill in authority and addtional sections.
+                break;
+            case Zone::DELEGATION:
+                // add NS to authority section, fill in additional section.
+                break;
+            case Zone::NXDOMAIN:
+                impl_->response_.setRcode(Rcode::NXDOMAIN());
+                // add SOA to authority section
+                break;
+            case Zone::NXRRSET:
+                impl_->response_.setRcode(Rcode::NXRRSET());
+                // add SOA to authority section
+                break;
+            case Zone::CNAME:
+            case Zone::DNAME:
+                // replace qname, continue lookup
+                keep_doing = true;
+                break;
+            // should not happen, catch programming error here.
+            default:
+                break;
+                isc_throw(Unexpected,
+                          "Zone::find return unexpected result.");
+        }
+    }
 }
 }
 }

+ 16 - 18
src/bin/auth/query.h

@@ -22,7 +22,7 @@ class RRType;
 }
 
 namespace datasrc {
-class ZoneTable;
+class MemoryDataSrc;
 }
 
 namespace auth {
@@ -32,11 +32,11 @@ namespace auth {
 ///
 /// Many of the design details for this class are still in flux.
 /// We'll revisit and update them as we add more functionality, for example:
-/// - zone_table parameter of the constructor.  This will eventually be
-///   replaced with a generic DataSrc object, or perhaps a notion of "view".
+/// - memory_datasrc parameter of the constructor.  It is a data source that
+///   uses in memory dedicated backend.
 /// - as a related point, we may have to pass the RR class of the query.
-///   in the initial implementation the RR class is an attribute of zone
-///   table and omitted.  It's not clear if this assumption holds with
+///   in the initial implementation the RR class is an attribute of memory
+///   datasource and omitted.  It's not clear if this assumption holds with
 ///   generic data sources.  On the other hand, it will help keep
 ///   implementation simpler, and we might rather want to modify the design
 ///   of the data source on this point.
@@ -47,8 +47,8 @@ namespace auth {
 ///   separate attribute setter.
 /// - likewise, we'll eventually need to do per zone access control, for which
 ///   we need querier's information such as its IP address.
-/// - zone_table (or DataSrc eventually) and response may better be parameters
-///   to process() instead of the constructor.
+/// - memory_datasrc and response may better be parameters to process() instead
+///   of the constructor.
 ///
 /// <b>Note:</b> The class name is intentionally the same as the one used in
 /// the datasrc library.  This is because the plan is to eventually merge
@@ -65,17 +65,17 @@ public:
     ///
     /// This constructor never throws an exception.
     ///
-    /// \param zone_table The zone table wherein the answer to the query is
+    /// \param memory_datasrc The memory datasource wherein the answer to the query is
     /// to be found.
     /// \param qname The query name
     /// \param qtype The RR type of the query
     /// \param response The response message to store the answer to the query.
-    Query(const isc::datasrc::ZoneTable& zone_table,
+    Query(const isc::datasrc::MemoryDataSrc& memory_datasrc,
           const isc::dns::Name& qname, const isc::dns::RRType& qtype,
-          isc::dns::Message& response) :
-        zone_table_(zone_table), qname_(qname), qtype_(qtype),
-        response_(response)
-    {}
+          isc::dns::Message& response);
+
+    /// The destructor.
+    virtual ~Query();
 
     /// Process the query.
     ///
@@ -87,7 +87,7 @@ public:
     /// successful search would result in adding a corresponding RRset to
     /// the answer section of the response.
     ///
-    /// If no matching zone is found in the zone table, the RCODE of
+    /// If no matching zone is found in the memory datasource, the RCODE of
     /// SERVFAIL will be set in the response.
     /// <b>Note:</b> this is different from the error code that BIND 9 returns
     /// by default when it's configured as an authoritative-only server (and
@@ -105,10 +105,8 @@ public:
     void process() const;
 
 private:
-    const isc::datasrc::ZoneTable& zone_table_;
-    const isc::dns::Name& qname_;
-    const isc::dns::RRType& qtype_;
-    isc::dns::Message& response_;
+    struct QueryImpl;
+    QueryImpl* impl_;
 };
 
 }

+ 8 - 8
src/bin/auth/tests/query_unittest.cc

@@ -17,7 +17,7 @@
 #include <dns/rcode.h>
 #include <dns/rrtype.h>
 
-#include <datasrc/zonetable.h>
+#include <datasrc/memory_datasrc.h>
 
 #include <auth/query.h>
 
@@ -33,11 +33,11 @@ protected:
     QueryTest() :
         qname(Name("www.example.com")), qclass(RRClass::IN()),
         qtype(RRType::A()), response(Message::RENDER),
-        query(zone_table, qname, qtype, response)
+        query(memory_datasrc, qname, qtype, response)
     {
         response.setRcode(Rcode::NOERROR());
     }
-    ZoneTable zone_table;
+    MemoryDataSrc memory_datasrc;
     const Name qname;
     const RRClass qclass;
     const RRType qtype;
@@ -46,7 +46,7 @@ protected:
 };
 
 TEST_F(QueryTest, noZone) {
-    // There's no zone in the zone table.  So the response should have
+    // There's no zone in the memory datasource.  So the response should have
     // SERVFAIL.
     query.process();
     EXPECT_EQ(Rcode::SERVFAIL(), response.getRcode());
@@ -55,15 +55,15 @@ TEST_F(QueryTest, noZone) {
 TEST_F(QueryTest, matchZone) {
     // add a matching zone.  since the zone is empty right now, the response
     // should have NXDOMAIN.
-    zone_table.addZone(ZonePtr(new MemoryZone(qclass, Name("example.com"))));
+    memory_datasrc.addZone(ZonePtr(new MemoryZone(qclass, Name("example.com"))));
     query.process();
     EXPECT_EQ(Rcode::NXDOMAIN(), response.getRcode());
 }
 
 TEST_F(QueryTest, noMatchZone) {
-    // there's a zone in the table but it doesn't match the qname.  should
-    // result in SERVFAIL.
-    zone_table.addZone(ZonePtr(new MemoryZone(qclass, Name("example.org"))));
+    // there's a zone in the memory datasource but it doesn't match the qname.
+    // should result in SERVFAIL.
+    memory_datasrc.addZone(ZonePtr(new MemoryZone(qclass, Name("example.org"))));
     query.process();
     EXPECT_EQ(Rcode::SERVFAIL(), response.getRcode());
 }

+ 1 - 1
src/lib/datasrc/data_source.h

@@ -248,7 +248,7 @@ public:
     void addDataSrc(ConstDataSrcPtr data_src);
     void removeDataSrc(ConstDataSrcPtr data_src);
     size_t dataSrcCount() { return (data_sources.size()); }
-    
+
     void findClosestEnclosure(DataSrcMatch& match) const;
 
     // Actual queries for data should not be sent to a MetaDataSrc object,