Browse Source

[1976] Let the auth server hold multiple lists

There are multiple lists, for multiple classes.
Michal 'vorner' Vaner 13 years ago
parent
commit
f7de4b58b2
3 changed files with 74 additions and 38 deletions
  1. 27 12
      src/bin/auth/auth_srv.cc
  2. 20 10
      src/bin/auth/auth_srv.h
  3. 27 16
      src/bin/auth/tests/auth_srv_unittest.cc

+ 27 - 12
src/bin/auth/auth_srv.cc

@@ -46,7 +46,6 @@
 #include <datasrc/memory_datasrc.h>
 #include <datasrc/memory_datasrc.h>
 #include <datasrc/static_datasrc.h>
 #include <datasrc/static_datasrc.h>
 #include <datasrc/sqlite3_datasrc.h>
 #include <datasrc/sqlite3_datasrc.h>
-#include <datasrc/client_list.h>
 
 
 #include <xfr/xfrout_client.h>
 #include <xfr/xfrout_client.h>
 
 
@@ -268,7 +267,7 @@ public:
     const boost::shared_ptr<TSIGKeyRing>* keyring_;
     const boost::shared_ptr<TSIGKeyRing>* keyring_;
 
 
     /// The client list
     /// The client list
-    boost::shared_ptr<ClientList> client_list_;
+    map<RRClass, boost::shared_ptr<ClientList> > client_lists_;
 
 
     /// Bind the ModuleSpec object in config_session_ with
     /// Bind the ModuleSpec object in config_session_ with
     /// isc:config::ModuleSpec::validateStatistics.
     /// isc:config::ModuleSpec::validateStatistics.
@@ -335,9 +334,6 @@ AuthSrvImpl::AuthSrvImpl(const bool use_cache,
 
 
     // enable or disable the cache
     // enable or disable the cache
     cache_.setEnabled(use_cache);
     cache_.setEnabled(use_cache);
-
-    // Create the (yet empty) data source list
-    client_list_.reset(new ConfigurableClientList());
 }
 }
 
 
 AuthSrvImpl::~AuthSrvImpl() {
 AuthSrvImpl::~AuthSrvImpl() {
@@ -1033,14 +1029,33 @@ AuthSrv::setTSIGKeyRing(const boost::shared_ptr<TSIGKeyRing>* keyring) {
 }
 }
 
 
 void
 void
-AuthSrv::setClientList(const boost::shared_ptr<ClientList>& list) {
-    if (!list) {
-        isc_throw(BadValue, "The client list must not be NULL");
+AuthSrv::setClientList(const RRClass& rrclass,
+                       const boost::shared_ptr<ClientList>& list) {
+    if (list) {
+        impl_->client_lists_[rrclass] = list;
+    } else {
+        impl_->client_lists_.erase(rrclass);
     }
     }
-    impl_->client_list_ = list;
 }
 }
 
 
-const ClientList&
-AuthSrv::getClientList() const {
-    return (*impl_->client_list_);
+boost::shared_ptr<const ClientList>
+AuthSrv::getClientList(const RRClass& rrclass) const {
+    const map<RRClass, boost::shared_ptr<ClientList> >::const_iterator
+        it(impl_->client_lists_.find(rrclass));
+    if (it == impl_->client_lists_.end()) {
+        return (boost::shared_ptr<const ClientList>());
+    } else {
+        return (it->second);
+    }
+}
+
+vector<RRClass>
+AuthSrv::getClientListClasses() const {
+    vector<RRClass> result;
+    for (map<RRClass, boost::shared_ptr<ClientList> >::const_iterator
+         it(impl_->client_lists_.begin()); it != impl_->client_lists_.end();
+         ++ it) {
+        result.push_back(it->first);
+    }
+    return (result);
 }
 }

+ 20 - 10
src/bin/auth/auth_srv.h

@@ -419,21 +419,31 @@ public:
     void setTSIGKeyRing(const boost::shared_ptr<isc::dns::TSIGKeyRing>*
     void setTSIGKeyRing(const boost::shared_ptr<isc::dns::TSIGKeyRing>*
                         keyring);
                         keyring);
 
 
-    /// \brief Replaces the current client list with a different one.
+    /// \brief Sets the currently used list for data sources of given
+    ///     class.
     ///
     ///
-    /// Replaces the internally used client list with a new one.
-    //
-    /// \param list Shared pointer to the client list. Must not be NULL.
+    /// Replaces the internally used client list with a new one. Other
+    /// classes are not changed.
     ///
     ///
-    /// \throw BadValue if it is NULL.
-    void setClientList(const boost::shared_ptr<isc::datasrc::ClientList>&
+    /// \param rrclass The class to modify.
+    /// \param list Shared pointer to the client list. If it is NULL,
+    ///     the list is removed instead.
+    void setClientList(const isc::dns::RRClass& rrclass,
+                       const boost::shared_ptr<isc::datasrc::ClientList>&
                        list);
                        list);
 
 
-    /// \brief Returns the currently used client list.
+    /// \brief Returns the currently used client list for the class.
     ///
     ///
-    /// Note that the server is constructed with an empty one, so this
-    /// is always valid, even before calling setClientList.
-    const isc::datasrc::ClientList& getClientList() const;
+    /// \param rrclass The class for which to get the list.
+    /// \return The list, or NULL if no list is set for the class.
+    boost::shared_ptr<const isc::datasrc::ClientList>
+        getClientList(const isc::dns::RRClass& rrclass) const;
+
+    /// \brief Returns a list of classes that have a client list.
+    ///
+    /// \return List of classes for which a non-NULL client list
+    ///     has been set by setClientList.
+    std::vector<isc::dns::RRClass> getClientListClasses() const;
 
 
 private:
 private:
     AuthSrvImpl* impl_;
     AuthSrvImpl* impl_;

+ 27 - 16
src/bin/auth/tests/auth_srv_unittest.cc

@@ -1647,23 +1647,34 @@ TEST_F(AuthSrvTest, DDNSForwardClose) {
 
 
 // Check the client list accessors
 // Check the client list accessors
 TEST_F(AuthSrvTest, clientList) {
 TEST_F(AuthSrvTest, clientList) {
-    // The server is created with a working client list. So calling the
-    // function will not crash.
-    server.getClientList();
-    // It is the correct type
-    EXPECT_NO_THROW(dynamic_cast<const isc::datasrc::ConfigurableClientList&>(
-        server.getClientList())) << "The client list has a wrong type";
-    // Now prepare a new client list and replace it
-    boost::shared_ptr<isc::datasrc::ConfigurableClientList>
+    // The lists don't exist. Therefore, the list of RRClasses is empty.
+    // We also have no IN list.
+    EXPECT_TRUE(server.getClientListClasses().empty());
+    EXPECT_EQ(boost::shared_ptr<const isc::datasrc::ClientList>(),
+              server.getClientList(RRClass::IN()));
+    // Put something in.
+    const boost::shared_ptr<isc::datasrc::ConfigurableClientList>
         list(new isc::datasrc::ConfigurableClientList());
         list(new isc::datasrc::ConfigurableClientList());
-    server.setClientList(list);
-    // And it is kept there.
-    EXPECT_EQ(list.get(), &server.getClientList());
-    // But putting NULL there would not work and the original is preserved
-    EXPECT_THROW(server.setClientList(
-        boost::shared_ptr<isc::datasrc::ConfigurableClientList>()),
-                 isc::BadValue);
-    EXPECT_EQ(list.get(), &server.getClientList());
+    const boost::shared_ptr<isc::datasrc::ConfigurableClientList>
+        list2(new isc::datasrc::ConfigurableClientList());
+    server.setClientList(RRClass::IN(), list);
+    server.setClientList(RRClass::CH(), list2);
+    // There are two things in the list and they are IN and CH
+    vector<RRClass> classes(server.getClientListClasses());
+    ASSERT_EQ(2, classes.size());
+    EXPECT_EQ(RRClass::IN(), classes[0]);
+    EXPECT_EQ(RRClass::CH(), classes[1]);
+    // And the lists can be retrieved.
+    EXPECT_EQ(list, server.getClientList(RRClass::IN()));
+    EXPECT_EQ(list2, server.getClientList(RRClass::CH()));
+    // Remove one of them
+    server.setClientList(RRClass::CH(),
+        boost::shared_ptr<isc::datasrc::ConfigurableClientList>());
+    // This really got deleted, including the class.
+    classes = server.getClientListClasses();
+    ASSERT_EQ(1, classes.size());
+    EXPECT_EQ(RRClass::IN(), classes[0]);
+    EXPECT_EQ(list, server.getClientList(RRClass::IN()));
 }
 }
 
 
 }
 }