now configureDataSource() can take time.
// This is a trivial specialization for the commonly used version.
// Defined in .cc to avoid accidental creation of multiple copies.
-void
+AuthSrv::DataSrcClientListsPtr
configureDataSource(AuthSrv& server, const isc::data::ConstElementPtr& config)
{
return (configureDataSourceGeneric<AuthSrv,
#include "auth_srv.h"
-#include <util/threads/lock.h>
-
#include <cc/data.h>
#include <datasrc/client_list.h>
/// \param config The configuration value to parse. It is in the form
/// as an update from the config manager.
template<class Server, class List>
-void
-configureDataSourceGeneric(Server& server,
+boost::shared_ptr<std::map<isc::dns::RRClass,
+ boost::shared_ptr<List> > > // = ListMap below
+configureDataSourceGeneric(Server& /*server*/,
const isc::data::ConstElementPtr& config)
{
typedef boost::shared_ptr<List> ListPtr;
list));
}
- // Replace the server's lists. By ignoring the return value we let the
- // old lists be destroyed. Lock will be released immediately after the
- // swap.
- {
- isc::util::thread::Mutex::Locker locker(server.getClientListMutex());
- server.swapDataSrcClientLists(new_lists);
- }
+ return (new_lists);
}
/// \brief Concrete version of configureDataSource() for the
/// use with authoritative server implementation.
-void
+AuthSrv::DataSrcClientListsPtr
configureDataSource(AuthSrv& server, const isc::data::ConstElementPtr& config);
#endif // DATASRC_CONFIG_H
#include <util/buffer.h>
#include <util/io/socketsession.h>
+#include <util/threads/lock.h>
#include <dns/message.h>
#include <dns/messagerenderer.h>
{
assert(server != NULL);
if (config->contains("classes")) {
+ AuthSrv::DataSrcClientListsPtr lists;
+
if (*first_time) {
// HACK: The default is not passed to the handler in the first
// callback. This one will get the default (or, current value).
// Further updates will work the usual way.
assert(config_session != NULL);
*first_time = false;
- configureDataSource(*auth_server,
- config_session->getRemoteConfigValue(
- "data_sources", "classes"));
+ lists = configureDataSource(
+ *auth_server,
+ config_session->getRemoteConfigValue("data_sources",
+ "classes"));
} else {
- configureDataSource(*server, config->get("classes"));
+ lists = configureDataSource(*server, config->get("classes"));
+ }
+
+ // Replace the server's lists. By ignoring the return value we let the
+ // old lists be destroyed. Lock will be released immediately after the
+ // swap.
+ {
+ isc::util::thread::Mutex::Locker locker(
+ server->getClientListMutex());
+ lists = server->swapDataSrcClientLists(lists);
}
+ // The previous lists are destroyed here. Note that it's outside
+ // of the critical section protected by the locker. So this can
+ // take time if running on a separate thread.
}
}
EXPECT_FALSE(dnsserv.hasAnswer());
}
+void
+installDataSrcClientLists(AuthSrv& server,
+ AuthSrv::DataSrcClientListsPtr lists)
+{
+ thread::Mutex::Locker locker(server.getClientListMutex());
+ server.swapDataSrcClientLists(lists);
+}
+
void
updateDatabase(AuthSrv& server, const char* params) {
const ConstElementPtr config(Element::fromJSON("{"
" \"type\": \"sqlite3\","
" \"params\": " + string(params) +
"}]}"));
- configureDataSource(server, config);
+ installDataSrcClientLists(server, configureDataSource(server, config));
}
void
" \"type\": \"static\","
" \"params\": \"" + string(STATIC_DSRC_FILE) + "\""
"}]}"));
- configureDataSource(server, config);
+ installDataSrcClientLists(server, configureDataSource(server, config));
}
void
" \"type\": \"static\","
" \"params\": \"" + string(STATIC_DSRC_FILE) + "\""
"}]}"));
- configureDataSource(server, config);
+ installDataSrcClientLists(server, configureDataSource(server, config));
}
// Try giving the server a TSIG signed request and see it can anwer signed as
" \"params\": {},"
" \"cache-enable\": true"
"}]}"));
- configureDataSource(server, config);
+ installDataSrcClientLists(server, configureDataSource(server, config));
// after successful configuration, we should have one (with empty zoneset).
// The memory data source is empty, should return REFUSED rcode.
find(Name("ns.test2.example"), RRType::AAAA())->code);
}
+void
+installDataSrcClientLists(AuthSrv& server,
+ AuthSrv::DataSrcClientListsPtr lists)
+{
+ isc::util::thread::Mutex::Locker locker(server.getClientListMutex());
+ server.swapDataSrcClientLists(lists);
+}
+
void
configureZones(AuthSrv& server) {
ASSERT_EQ(0, system(INSTALL_PROG " -c " TEST_DATA_DIR "/test1.zone.in "
" \"cache-enable\": true"
"}]}"));
- configureDataSource(server, config);
+ installDataSrcClientLists(server, configureDataSource(server, config));
zoneChecks(server);
}
" \"cache-enable\": true,"
" \"cache-zones\": [\"example.org\"]"
"}]}"));
- configureDataSource(server_, config);
+ installDataSrcClientLists(server_, configureDataSource(server_, config));
{
isc::util::thread::Mutex::Locker locker(server_.getClientListMutex());
typedef shared_ptr<FakeList> ListPtr;
+// Forward declaration. We need precise definition of DatasrcConfigTest
+// to complete this function.
void
testConfigureDataSource(DatasrcConfigTest& test,
- const isc::data::ConstElementPtr& config)
-{
- // We use the test fixture for the Server type. This makes it possible
- // to easily fake all needed methods and look that they were called.
- configureDataSourceGeneric<DatasrcConfigTest, FakeList>(test, config);
-}
+ const isc::data::ConstElementPtr& config);
void
datasrcConfigHandler(DatasrcConfigTest* fake_server, const std::string&,
mutable isc::util::thread::Mutex mutex_;
};
+void
+testConfigureDataSource(DatasrcConfigTest& test,
+ const isc::data::ConstElementPtr& config)
+{
+ // We use the test fixture for the Server type. This makes it possible
+ // to easily fake all needed methods and look that they were called.
+ shared_ptr<std::map<dns::RRClass, ListPtr> > lists =
+ configureDataSourceGeneric<DatasrcConfigTest, FakeList>(test, config);
+ test.swapDataSrcClientLists(lists);
+}
+
// Push there a configuration with a single list.
TEST_F(DatasrcConfigTest, createList) {
initializeINList();