// Copyright (C) 2018-2024 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/. // Functions accessed by the hooks framework use C linkage to avoid the name // mangling that accompanies use of the C++ compiler as well as to avoid // issues related to namespaces. #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace isc::asiolink; using namespace isc::cb; using namespace isc::dhcp; using namespace isc::hooks; using namespace isc::log; using namespace isc::process; using namespace std; extern "C" { /// @brief This function is called when the library is loaded. /// /// @param handle library handle /// @return 0 when initialization is successful, 1 otherwise int load(LibraryHandle& /* handle */) { // Make the hook library not loadable by d2 or ca. uint16_t family = CfgMgr::instance().getFamily(); const std::string& proc_name = Daemon::getProcName(); if (family == AF_INET) { if (proc_name != "kea-dhcp4") { isc_throw(isc::Unexpected, "Bad process name: " << proc_name << ", expected kea-dhcp4"); } } else { if (proc_name != "kea-dhcp6") { isc_throw(isc::Unexpected, "Bad process name: " << proc_name << ", expected kea-dhcp6"); } } // Register MySQL CB factories with CB Managers isc::dhcp::MySqlConfigBackendDHCPv4::registerBackendType(); isc::dhcp::MySqlConfigBackendDHCPv6::registerBackendType(); LOG_INFO(mysql_cb_logger, MYSQL_CB_INIT_OK); // Register MySQL HB factories with Host Managers HostDataSourceFactory::registerFactory("mysql", MySqlHostDataSource::factory, true, MySqlHostDataSource::getDBVersion); LOG_INFO(mysql_hb_logger, MYSQL_HB_INIT_OK); // Register MySQL LB factories with Lease Managers LeaseMgrFactory::registerFactory("mysql", MySqlLeaseMgr::factory, true, MySqlLeaseMgr::getDBVersion); LOG_INFO(mysql_lb_logger, MYSQL_LB_INIT_OK); return (0); } /// @brief This function is called by the DHCPv4 server when it is configured. /// /// The only purpose of this callout is to retrieve io_service_ reference. /// /// @param handle callout handle passed to the callout. /// @return 0 on success, 1 otherwise. int dhcp4_srv_configured(CalloutHandle& /* handle */) { isc::dhcp::MySqlConfigBackendImpl::setIOService(IOServicePtr(new IOService())); IOServiceMgr::instance().registerIOService(isc::dhcp::MySqlConfigBackendImpl::getIOService()); return (0); } /// @brief This function is called by the DHCPv6 server when it is configured. /// /// The only purpose of this callout is to retrieve io_service_ reference. /// /// @param handle callout handle passed to the callout. /// @return 0 on success, 1 otherwise. int dhcp6_srv_configured(CalloutHandle& /* handle */) { isc::dhcp::MySqlConfigBackendImpl::setIOService(IOServicePtr(new IOService())); IOServiceMgr::instance().registerIOService(isc::dhcp::MySqlConfigBackendImpl::getIOService()); return (0); } /// @brief This function is called when the library is unloaded. /// /// @return 0 if deregistration was successful, 1 otherwise int unload() { // Unregister the factories and remove MySQL backends isc::dhcp::MySqlConfigBackendDHCPv4::unregisterBackendType(); isc::dhcp::MySqlConfigBackendDHCPv6::unregisterBackendType(); IOServicePtr io_service = isc::dhcp::MySqlConfigBackendImpl::getIOService(); if (io_service) { IOServiceMgr::instance().unregisterIOService(io_service); io_service->stopAndPoll(); isc::dhcp::MySqlConfigBackendImpl::setIOService(IOServicePtr()); } LOG_INFO(mysql_cb_logger, MYSQL_CB_DEINIT_OK); // Unregister the factories and remove MySQL backends HostDataSourceFactory::deregisterFactory("mysql", true); LOG_INFO(mysql_hb_logger, MYSQL_HB_DEINIT_OK); // Unregister the factories and remove MySQL backends LeaseMgrFactory::deregisterFactory("mysql", true); LOG_INFO(mysql_lb_logger, MYSQL_LB_DEINIT_OK); return (0); } /// @brief This function is called to retrieve the multi-threading compatibility. /// /// @note: the compatibility is based on the assumption this hook library /// is always called from the main thread. /// /// @return 1 which means compatible with multi-threading. int multi_threading_compatible() { return (1); } } // end extern "C"