BIND 10 master, updated. 6b80e1e57145e8b0796d872f51ca39a0f4bbc17a Merge #2046

BIND 10 source code commits bind10-changes at lists.isc.org
Wed Jul 11 08:32:27 UTC 2012


The branch, master has been updated
       via  6b80e1e57145e8b0796d872f51ca39a0f4bbc17a (commit)
       via  71c5bdbe0993f0f1df977f7ac89e0eda9b3526c9 (commit)
       via  7d3bb3bf33a847c65749a9e38d07649579702055 (commit)
       via  d7aa2b1a7da3fab212446f0d09a8420e7718ae64 (commit)
       via  6c5668568a45cabd640df61816aee251a412e8b0 (commit)
      from  93ec40dd0a1df963c676037cc60c066c748b3030 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 6b80e1e57145e8b0796d872f51ca39a0f4bbc17a
Merge: 93ec40d 71c5bdb
Author: Michal 'vorner' Vaner <michal.vaner at nic.cz>
Date:   Wed Jul 11 10:03:47 2012 +0200

    Merge #2046

-----------------------------------------------------------------------

Summary of changes:
 src/lib/datasrc/client_list.cc                |  108 ++++++++++++++++++-------
 src/lib/datasrc/client_list.h                 |   20 +++--
 src/lib/datasrc/datasrc_messages.mes          |    7 ++
 src/lib/datasrc/tests/client_list_unittest.cc |   82 ++++++++++++++++++-
 4 files changed, 178 insertions(+), 39 deletions(-)

-----------------------------------------------------------------------
diff --git a/src/lib/datasrc/client_list.cc b/src/lib/datasrc/client_list.cc
index fab534d..e9718d4 100644
--- a/src/lib/datasrc/client_list.cc
+++ b/src/lib/datasrc/client_list.cc
@@ -16,6 +16,7 @@
 #include "client.h"
 #include "factory.h"
 #include "memory_datasrc.h"
+#include "logger.h"
 
 #include <memory>
 #include <boost/foreach.hpp>
@@ -30,11 +31,19 @@ namespace datasrc {
 
 ConfigurableClientList::DataSourceInfo::DataSourceInfo(
     DataSourceClient* data_src_client,
-    const DataSourceClientContainerPtr& container, bool hasCache) :
+    const DataSourceClientContainerPtr& container, bool has_cache) :
     data_src_client_(data_src_client),
     container_(container)
 {
-    if (hasCache) {
+    if (has_cache) {
+        cache_.reset(new InMemoryClient);
+    }
+}
+
+ConfigurableClientList::DataSourceInfo::DataSourceInfo(bool has_cache) :
+    data_src_client_(NULL)
+{
+    if (has_cache) {
         cache_.reset(new InMemoryClient);
     }
 }
@@ -58,49 +67,92 @@ ConfigurableClientList::configure(const Element& config, bool allow_cache) {
             if (paramConf == ConstElementPtr()) {
                 paramConf.reset(new NullElement());
             }
-            // TODO: Special-case the master files type.
-            // Ask the factory to create the data source for us
-            const DataSourcePair ds(this->getDataSourceClient(type,
-                                                              paramConf));
             const bool want_cache(allow_cache &&
                                   dconf->contains("cache-enable") &&
                                   dconf->get("cache-enable")->boolValue());
-            // And put it into the vector
-            new_data_sources.push_back(DataSourceInfo(ds.first, ds.second,
-                                                      want_cache));
+
+            if (type == "MasterFiles") {
+                // In case the cache is not allowed, we just skip the master
+                // files (at least for now)
+                if (!allow_cache) {
+                    // We're not going to load these zones. Issue warnings about it.
+                    const map<string, ConstElementPtr>
+                        zones_files(paramConf->mapValue());
+                    for (map<string, ConstElementPtr>::const_iterator
+                         it(zones_files.begin()); it != zones_files.end();
+                         ++it) {
+                        LOG_WARN(logger, DATASRC_LIST_NOT_CACHED).
+                            arg(it->first).arg(rrclass_);
+                    }
+                    continue;
+                }
+                if (!want_cache) {
+                    isc_throw(ConfigurationError, "The cache must be enabled "
+                              "for the MasterFiles type");
+                }
+                new_data_sources.push_back(DataSourceInfo(true));
+            } else {
+                // Ask the factory to create the data source for us
+                const DataSourcePair ds(this->getDataSourceClient(type,
+                                                                  paramConf));
+                // And put it into the vector
+                new_data_sources.push_back(DataSourceInfo(ds.first, ds.second,
+                                                          want_cache));
+            }
+
             if (want_cache) {
-                if (!dconf->contains("cache-zones")) {
+                if (!dconf->contains("cache-zones") && type != "MasterFiles") {
                     isc_throw(isc::NotImplemented, "Auto-detection of zones "
                               "to cache is not yet implemented, supply "
                               "cache-zones parameter");
                     // TODO: Auto-detect list of all zones in the
                     // data source.
                 }
-                const ConstElementPtr zones(dconf->get("cache-zones"));
+
+                // List the zones we are loading
+                vector<string> zones_origins;
+                if (type == "MasterFiles") {
+                    const map<string, ConstElementPtr>
+                        zones_files(paramConf->mapValue());
+                    for (map<string, ConstElementPtr>::const_iterator
+                         it(zones_files.begin()); it != zones_files.end();
+                         ++it) {
+                        zones_origins.push_back(it->first);
+                    }
+                } else {
+                    const ConstElementPtr zones(dconf->get("cache-zones"));
+                    for (size_t i(0); i < zones->size(); ++i) {
+                        zones_origins.push_back(zones->get(i)->stringValue());
+                    }
+                }
+
                 const shared_ptr<InMemoryClient>
                     cache(new_data_sources.back().cache_);
                 const DataSourceClient* const
                     client(new_data_sources.back().data_src_client_);
-                for (size_t i(0); i < zones->size(); ++i) {
-                    const Name origin(zones->get(i)->stringValue());
-                    const DataSourceClient::FindResult
-                        zone(client->findZone(origin));
-                    if (zone.code != result::SUCCESS) {
-                        // The data source does not contain the zone, it can't
-                        // be cached.
-                        isc_throw(ConfigurationError, "Unable to cache "
-                                  "non-existent zone " << origin);
-                    }
+                for (vector<string>::const_iterator it(zones_origins.begin());
+                     it != zones_origins.end(); ++it) {
+                    const Name origin(*it);
                     shared_ptr<InMemoryZoneFinder>
                         finder(new
-                            InMemoryZoneFinder(zone.zone_finder->getClass(),
-                                               origin));
-                    ZoneIteratorPtr iterator(client->getIterator(origin));
-                    if (!iterator) {
-                        isc_throw(isc::Unexpected, "Got NULL iterator for "
-                                  "zone " << origin);
+                            InMemoryZoneFinder(rrclass_, origin));
+                    if (type == "MasterFiles") {
+                        finder->load(paramConf->get(*it)->stringValue());
+                    } else {
+                        ZoneIteratorPtr iterator;
+                        try {
+                            iterator = client->getIterator(origin);
+                        }
+                        catch (const DataSourceError&) {
+                            isc_throw(ConfigurationError, "Unable to cache "
+                                      "non-existent zone " << origin);
+                        }
+                        if (!iterator) {
+                            isc_throw(isc::Unexpected, "Got NULL iterator for "
+                                      "zone " << origin);
+                        }
+                        finder->load(*iterator);
                     }
-                    finder->load(*iterator);
                     cache->addZone(finder);
                 }
             }
diff --git a/src/lib/datasrc/client_list.h b/src/lib/datasrc/client_list.h
index 5105d08..75dae74 100644
--- a/src/lib/datasrc/client_list.h
+++ b/src/lib/datasrc/client_list.h
@@ -16,6 +16,7 @@
 #define DATASRC_CONTAINER_H
 
 #include <dns/name.h>
+#include <dns/rrclass.h>
 #include <cc/data.h>
 #include <exceptions/exceptions.h>
 
@@ -186,6 +187,12 @@ typedef boost::shared_ptr<const ClientList> ConstClientListPtr;
 /// inherited except for tests.
 class ConfigurableClientList : public ClientList {
 public:
+    /// \brief Constructor
+    ///
+    /// \param rrclass For which class the list should work.
+    ConfigurableClientList(const isc::dns::RRClass &rrclass) :
+        rrclass_(rrclass)
+    {}
     /// \brief Exception thrown when there's an error in configuration.
     class ConfigurationError : public Exception {
     public:
@@ -229,16 +236,11 @@ public:
     ///
     /// \todo The content yet to be defined.
     struct DataSourceInfo {
-        /// \brief Default constructor.
-        ///
-        /// Don't use directly. It is here so the structure can live in
-        /// a vector.
-        DataSourceInfo() :
-            data_src_client_(NULL)
-        {}
+        // Plays a role of default constructor too (for vector)
+        DataSourceInfo(bool has_cache = false);
         DataSourceInfo(DataSourceClient* data_src_client,
                        const DataSourceClientContainerPtr& container,
-                       bool hasCache);
+                       bool has_cache);
         DataSourceClient* data_src_client_;
         DataSourceClientContainerPtr container_;
         boost::shared_ptr<InMemoryClient> cache_;
@@ -286,6 +288,8 @@ public:
     /// it might be, so it is just made public (there's no real reason to
     /// hide it).
     const DataSources& getDataSources() const { return (data_sources_); }
+private:
+    const isc::dns::RRClass rrclass_;
 };
 
 } // namespace datasrc
diff --git a/src/lib/datasrc/datasrc_messages.mes b/src/lib/datasrc/datasrc_messages.mes
index 7e3d5c2..6ae744e 100644
--- a/src/lib/datasrc/datasrc_messages.mes
+++ b/src/lib/datasrc/datasrc_messages.mes
@@ -298,6 +298,13 @@ not contain RRs the requested type.  AN NXRRSET indication is returned.
 A debug message indicating that a query for the given name and RR type is being
 processed.
 
+% DATASRC_LIST_NOT_CACHED zone %1/%2 not cached, cache disabled globally. Will not be available.
+The process disabled caching of RR data completely. However, the given zone
+is provided as a master file and it can be served from memory cache only.
+Therefore, the zone will not be available for this process. If this is
+a problem, you should move the zone to some database backend (sqlite3, for
+example) and use it from there.
+
 % DATASRC_MEM_ADD_RRSET adding RRset '%1/%2' into zone '%3'
 Debug information. An RRset is being added to the in-memory data source.
 
diff --git a/src/lib/datasrc/tests/client_list_unittest.cc b/src/lib/datasrc/tests/client_list_unittest.cc
index 7498d23..8625d33 100644
--- a/src/lib/datasrc/tests/client_list_unittest.cc
+++ b/src/lib/datasrc/tests/client_list_unittest.cc
@@ -45,7 +45,7 @@ public:
         Name getOrigin() const { return (origin_); }
         // The rest is not to be called, so just have them
         RRClass getClass() const {
-            return (RRClass::IN());
+            isc_throw(isc::NotImplemented, "Not implemented");
         }
         shared_ptr<Context> find(const Name&, const RRType&,
                                  const FindOptions)
@@ -106,6 +106,8 @@ public:
         type_(type),
         configuration_(configuration)
     {
+        EXPECT_NE("MasterFiles", type) << "MasterFiles is a special case "
+            "and it never should be created as a data source client";
         if (configuration_->getType() == Element::list) {
             for (size_t i(0); i < configuration_->size(); ++i) {
                 zones.insert(Name(configuration_->get(i)->stringValue()));
@@ -148,7 +150,12 @@ public:
         } else if (name == Name("null.org")) {
             return (ZoneIteratorPtr());
         } else {
-            return (ZoneIteratorPtr(new Iterator(name)));
+            FindResult result(findZone(name));
+            if (result.code == isc::datasrc::result::SUCCESS) {
+                return (ZoneIteratorPtr(new Iterator(name)));
+            } else {
+                isc_throw(DataSourceError, "No such zone");
+            }
         }
     }
     const string type_;
@@ -162,6 +169,9 @@ private:
 // some methods to dig directly in the internals, for the tests.
 class TestedList : public ConfigurableClientList {
 public:
+    TestedList(const RRClass& rrclass) :
+        ConfigurableClientList(rrclass)
+    {}
     DataSources& getDataSources() { return (data_sources_); }
     // Overwrite the list's method to get a data source with given type
     // and configuration. We mock the data source and don't create the
@@ -210,7 +220,7 @@ class ListTest : public ::testing::Test {
 public:
     ListTest() :
         // The empty list corresponds to a list with no elements inside
-        list_(new TestedList()),
+        list_(new TestedList(RRClass::IN())),
         config_elem_(Element::fromJSON("["
             "{"
             "   \"type\": \"test_type\","
@@ -498,6 +508,47 @@ TEST_F(ListTest, wrongConfig) {
          "{\"type\": \"x\", \"cache-enable\": true, \"cache-zones\": 13}]",
         "[{\"type\": \"test_type\", \"params\": 13}, "
          "{\"type\": \"x\", \"cache-enable\": true, \"cache-zones\": {}}]",
+        // Some bad inputs for MasterFiles special case
+
+        // It must have the cache enabled
+        "[{\"type\": \"test_type\", \"params\": 13}, "
+         "{\"type\": \"MasterFiles\", \"cache-enable\": false,"
+         "\"params\": {}}]",
+        // No cache-zones allowed here
+        "[{\"type\": \"test_type\", \"params\": 13}, "
+         "{\"type\": \"MasterFiles\", \"cache-enable\": true,"
+         "\"param\": {}, \"cache-zones\": []}]",
+        // Some bad types of params
+        "[{\"type\": \"test_type\", \"params\": 13}, "
+         "{\"type\": \"MasterFiles\", \"cache-enable\": false,"
+         "\"params\": []}]",
+        "[{\"type\": \"test_type\", \"params\": 13}, "
+         "{\"type\": \"MasterFiles\", \"cache-enable\": false,"
+         "\"params\": 13}]",
+        "[{\"type\": \"test_type\", \"params\": 13}, "
+         "{\"type\": \"MasterFiles\", \"cache-enable\": false,"
+         "\"params\": true}]",
+        "[{\"type\": \"test_type\", \"params\": 13}, "
+         "{\"type\": \"MasterFiles\", \"cache-enable\": false,"
+         "\"params\": null}]",
+        "[{\"type\": \"test_type\", \"params\": 13}, "
+         "{\"type\": \"MasterFiles\", \"cache-enable\": false,"
+         "\"params\": \"x\"}]",
+        "[{\"type\": \"test_type\", \"params\": 13}, "
+         "{\"type\": \"MasterFiles\", \"cache-enable\": false,"
+         "\"params\": {\".\": 13}}]",
+        "[{\"type\": \"test_type\", \"params\": 13}, "
+         "{\"type\": \"MasterFiles\", \"cache-enable\": false,"
+         "\"params\": {\".\": true}}]",
+        "[{\"type\": \"test_type\", \"params\": 13}, "
+         "{\"type\": \"MasterFiles\", \"cache-enable\": false,"
+         "\"params\": {\".\": null}}]",
+        "[{\"type\": \"test_type\", \"params\": 13}, "
+         "{\"type\": \"MasterFiles\", \"cache-enable\": false,"
+         "\"params\": {\".\": []}}]",
+        "[{\"type\": \"test_type\", \"params\": 13}, "
+         "{\"type\": \"MasterFiles\", \"cache-enable\": false,"
+         "\"params\": {\".\": {}}}]",
         NULL
     };
     // Put something inside to see it survives the exception
@@ -611,6 +662,8 @@ TEST_F(ListTest, cacheZones) {
     EXPECT_EQ(result::SUCCESS, cache->findZone(Name("example.org")).code);
     EXPECT_EQ(result::SUCCESS, cache->findZone(Name("example.com")).code);
     EXPECT_EQ(result::NOTFOUND, cache->findZone(Name("example.cz")).code);
+    EXPECT_EQ(RRClass::IN(),
+              cache->findZone(Name("example.org")).zone_finder->getClass());
 
     // These are cached and answered from the cache
     positiveResult(list_->find(Name("example.com.")), ds_[0],
@@ -670,4 +723,27 @@ TEST_F(ListTest, badCache) {
     checkDS(0, "test_type", "{}", false);
 }
 
+TEST_F(ListTest, masterFiles) {
+    const ConstElementPtr elem(Element::fromJSON("["
+        "{"
+        "   \"type\": \"MasterFiles\","
+        "   \"cache-enable\": true,"
+        "   \"params\": {"
+        "       \".\": \"" TEST_DATA_DIR "/root.zone\""
+        "   }"
+        "}]"));
+    list_->configure(*elem, true);
+
+    // It has only the cache
+    EXPECT_EQ(NULL, list_->getDataSources()[0].data_src_client_);
+
+    // And it can search
+    positiveResult(list_->find(Name(".")), ds_[0], Name("."), true, "com",
+                   true);
+
+    // If cache is not enabled, nothing is loaded
+    list_->configure(*elem, false);
+    EXPECT_EQ(0, list_->getDataSources().size());
+}
+
 }



More information about the bind10-changes mailing list