// Copyright (C) 2013-2020 Internet Systems Consortium, Inc. ("ISC") // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at http://mozilla.org/MPL/2.0/. #include #include #include #include #include #include #include #include #include #include #include using namespace std; namespace isc { namespace hooks { // Constructor HooksManager::HooksManager() : test_mode_(false) { // Nothing present, so create the collection with any empty set of // libraries, and get the CalloutManager. HookLibsCollection libraries; lm_collection_.reset(new LibraryManagerCollection(libraries)); lm_collection_->loadLibraries(); callout_manager_ = lm_collection_->getCalloutManager(); } // Return reference to singleton hooks manager. HooksManager& HooksManager::getHooksManager() { static HooksManager manager; return (manager); } // Are callouts present? bool HooksManager::calloutsPresentInternal(int index) { return (callout_manager_->calloutsPresent(index)); } bool HooksManager::calloutsPresent(int index) { return (getHooksManager().calloutsPresentInternal(index)); } bool HooksManager::commandHandlersPresentInternal(const std::string& command_name) { return (callout_manager_->commandHandlersPresent(command_name)); } bool HooksManager::commandHandlersPresent(const std::string& command_name) { return (getHooksManager().commandHandlersPresentInternal(command_name)); } // Call the callouts void HooksManager::callCalloutsInternal(int index, CalloutHandle& handle) { callout_manager_->callCallouts(index, handle); } void HooksManager::callCallouts(int index, CalloutHandle& handle) { getHooksManager().callCalloutsInternal(index, handle); } void HooksManager::callCommandHandlersInternal(const std::string& command_name, CalloutHandle& handle) { callout_manager_->callCommandHandlers(command_name, handle); } void HooksManager::callCommandHandlers(const std::string& command_name, CalloutHandle& handle) { getHooksManager().callCommandHandlersInternal(command_name, handle); } // Load the libraries. This will delete the previously-loaded libraries // (if present) and load new ones. If loading libraries fails, initialize with // empty list. bool HooksManager::loadLibrariesInternal(const HookLibsCollection& libraries) { if (test_mode_) { return (true); } ServerHooks::getServerHooks().getParkingLotsPtr()->clear(); // Keep a weak pointer on the existing library manager collection. boost::weak_ptr weak_lmc(lm_collection_); // Create the library manager collection. lm_collection_.reset(new LibraryManagerCollection(libraries)); // If there was another owner the previous library manager collection // was not destroyed and libraries not closed. if (!weak_lmc.expired()) { isc_throw(LibrariesStillOpened, "some libraries are still opened"); } // Load the libraries. bool status = lm_collection_->loadLibraries(); if (status) { // ... and obtain the callout manager for them if successful. callout_manager_ = lm_collection_->getCalloutManager(); } else { // Unable to load libraries, reset to state before this function was // called. static_cast(unloadLibrariesInternal()); } return (status); } bool HooksManager::loadLibraries(const HookLibsCollection& libraries) { return (getHooksManager().loadLibrariesInternal(libraries)); } // Unload the libraries. This just deletes all internal objects (which will // cause the libraries to be unloaded) and initializes them with empty list if // requested. bool HooksManager::unloadLibrariesInternal() { if (test_mode_) { return (true); } ServerHooks::getServerHooks().getParkingLotsPtr()->clear(); // Keep a weak pointer on the existing library manager collection. boost::weak_ptr weak_lmc(lm_collection_); // Create the collection with any empty set of libraries. HookLibsCollection libraries; lm_collection_.reset(new LibraryManagerCollection(libraries)); // If there was another owner the previous library manager collection // was not destroyed and libraries not closed. boost::shared_ptr still_here = weak_lmc.lock(); if (still_here) { // Restore the library manager collection. lm_collection_ = still_here; return (false); } // Load the empty set of libraries. lm_collection_->loadLibraries(); // Get the CalloutManager. callout_manager_ = lm_collection_->getCalloutManager(); return (true); } bool HooksManager::unloadLibraries() { return (getHooksManager().unloadLibrariesInternal()); } void HooksManager::prepareUnloadLibrariesInternal() { if (test_mode_) { return; } static_cast(lm_collection_->prepareUnloadLibraries()); } void HooksManager::prepareUnloadLibraries() { getHooksManager().prepareUnloadLibrariesInternal(); } // Create a callout handle boost::shared_ptr HooksManager::createCalloutHandleInternal() { return (boost::make_shared(callout_manager_, lm_collection_)); } boost::shared_ptr HooksManager::createCalloutHandle() { return (getHooksManager().createCalloutHandleInternal()); } // Get the list of the names of loaded libraries. std::vector HooksManager::getLibraryNamesInternal() const { return (lm_collection_->getLibraryNames()); } HookLibsCollection HooksManager::getLibraryInfoInternal() const { return (lm_collection_->getLibraryInfo()); } std::vector HooksManager::getLibraryNames() { return (getHooksManager().getLibraryNamesInternal()); } HookLibsCollection HooksManager::getLibraryInfo() { return (getHooksManager().getLibraryInfoInternal()); } // Shell around ServerHooks::registerHook() int HooksManager::registerHook(const std::string& name) { return (ServerHooks::getServerHooks().registerHook(name)); } // Return pre- and post- library handles. isc::hooks::LibraryHandle& HooksManager::preCalloutsLibraryHandleInternal() { return (callout_manager_->getPreLibraryHandle()); } isc::hooks::LibraryHandle& HooksManager::preCalloutsLibraryHandle() { return (getHooksManager().preCalloutsLibraryHandleInternal()); } isc::hooks::LibraryHandle& HooksManager::postCalloutsLibraryHandleInternal() { return (callout_manager_->getPostLibraryHandle()); } isc::hooks::LibraryHandle& HooksManager::postCalloutsLibraryHandle() { return (getHooksManager().postCalloutsLibraryHandleInternal()); } // Validate libraries std::vector HooksManager::validateLibraries(const std::vector& libraries) { return (LibraryManagerCollection::validateLibraries(libraries)); } // Test mode void HooksManager::setTestMode(bool mode) { getHooksManager().test_mode_ = mode; } bool HooksManager::getTestMode() { return (getHooksManager().test_mode_); } } // namespace util } // namespace isc