Kea: lease_mgr_factory.cc Source File

| Kea 3.2.0-git

lease_mgr_factory.cc
Go to the documentation of this file.
1// Copyright (C) 2012-2026 Internet Systems Consortium, Inc. ("ISC")
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7#include <config.h>
8
9#include <dhcpsrv/cfgmgr.h>
10#include <dhcpsrv/dhcpsrv_log.h>
11#include <dhcpsrv/lease_mgr_factory.h>
12#include <dhcpsrv/memfile_lease_mgr.h>
13#include <boost/algorithm/string.hpp>
14
15#include <algorithm>
16#include <iostream>
17#include <iterator>
18#include <map>
19#include <sstream>
20#include <utility>
21
22using namespace isc::db;
23using namespace std;
24
25namespace isc {
26namespace dhcp {
27
28map<string, pair<LeaseMgrFactory::Factory, LeaseMgrFactory::DBVersion>> LeaseMgrFactory::map_;
29
30namespace {
31
33isc::dhcp::MemfileLeaseMgrInit memfile_init;
34
35}
36
37 TrackingLeaseMgrPtr&
38LeaseMgrFactory::getLeaseMgrPtr() {
39 static TrackingLeaseMgrPtr lease_mgr_ptr;
40 return (lease_mgr_ptr);
41}
42
43bool LeaseMgrFactory::init_allocators_ = false;
44
45void
46LeaseMgrFactory::initAllocators(bool use_staging /* = false */) {
47 if (!LeaseMgrFactory::init_allocators_) {
48 return;
49 }
50 auto cfg = (use_staging ? CfgMgr::instance().getStagingCfg()
51 : CfgMgr::instance().getCurrentCfg());
52 if (CfgMgr::instance().getFamily() == AF_INET) {
53 cfg->getCfgSubnets4()->initAllocatorsAfterConfigure();
54 } else {
55 cfg->getCfgSubnets6()->initAllocatorsAfterConfigure();
56 }
57 LeaseMgrFactory::init_allocators_ = false;
58}
59
60void
61LeaseMgrFactory::create(const std::string& dbaccess) {
62 const std::string type = "type";
63
64 // Parse the access string and create a redacted string for logging.
65 DatabaseConnection::ParameterMap parameters = DatabaseConnection::parse(dbaccess);
66 std::string redacted = DatabaseConnection::redactedAccessString(parameters);
67
68 // Get the database type and open the corresponding database.
69 DatabaseConnection::ParameterMap::iterator it = parameters.find(type);
70 if (it == parameters.end()) {
71 LOG_ERROR(dhcpsrv_logger, DHCPSRV_NOTYPE_DB).arg(dbaccess);
72 isc_throw(InvalidParameter, "Database configuration parameters do not "
73 "contain the 'type' keyword");
74 }
75
76 string db_type = it->second;
77 auto index = map_.find(db_type);
78
79 // No match?
80 if (index == map_.end()) {
81 if ((db_type == "mysql") || (db_type == "postgresql")) {
82 LOG_ERROR(dhcpsrv_logger, DHCPSRV_UNKNOWN_DB).arg(db_type);
83 string libdhcp(db_type == "postgresql" ? "pgsql" : db_type);
84 isc_throw(InvalidType, "The Kea server has not been compiled with "
85 "support for lease database type: " << db_type
86 << ". Did you forget to use -D "
87 << db_type << "=enabled during setup or to load libdhcp_"
88 << libdhcp << " hook library?");
89 }
90 // Get here on no match
91 LOG_ERROR(dhcpsrv_logger, DHCPSRV_UNKNOWN_DB).arg(parameters[type]);
92 isc_throw(InvalidType, "Database access parameter 'type' does "
93 "not specify a supported database backend: " << parameters[type]);
94 }
95
96 // Call the factory.
97 getLeaseMgrPtr() = index->second.first(parameters);
98
99 // Check the factory did not return null.
100 if (!getLeaseMgrPtr()) {
101 isc_throw(Unexpected, "Lease database " << db_type <<
102 " factory returned null");
103 }
104}
105
106void
107LeaseMgrFactory::destroy() {
108 // Destroy current lease manager. This is a no-op if no lease manager
109 // is available.
110 if (getLeaseMgrPtr()) {
111 LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE, DHCPSRV_CLOSE_DB)
112 .arg(getLeaseMgrPtr()->getType());
113 getLeaseMgrPtr().reset();
114 }
115}
116
117void
118LeaseMgrFactory::recreate(const std::string& dbaccess, bool preserve_callbacks) {
119 TrackingLeaseMgr::CallbackContainerPtr callbacks;
120 // Preserve the callbacks if needed.
121 if (preserve_callbacks && haveInstance()) {
122 callbacks = instance().callbacks_;
123 }
124
125 // Re-create the manager.
126 destroy();
127 create(dbaccess);
128
129 // Init lease allocators. We do this here for allocators which require
130 // the lease manager access (i.e. SFLQ and FLQ) for initialization.
131 // When preserve_callbacks is true the current configuration is used,
132 // if it is false the staging configuration is used.
133 LeaseMgrFactory::initAllocators(!preserve_callbacks);
134
135 if (callbacks) {
136 // Copy the callbacks to the new instance. It should be fast
137 // because we merely copy the pointer.
138 instance().callbacks_ = callbacks;
139 }
140}
141
142bool
143LeaseMgrFactory::haveInstance() {
144 return (!!getLeaseMgrPtr());
145}
146
147 TrackingLeaseMgr&
148LeaseMgrFactory::instance() {
149 TrackingLeaseMgr* lmptr = getLeaseMgrPtr().get();
150 if (!lmptr) {
151 isc_throw(NoLeaseManager, "no current lease manager is available");
152 }
153 return (*lmptr);
154}
155
156bool
157LeaseMgrFactory::registerFactory(const string& db_type,
158 const Factory& factory,
159 bool no_log,
160 DBVersion db_version) {
161 if (map_.count(db_type)) {
162 return (false);
163 }
164
165 static auto default_db_version = []() -> std::string {
166 return (std::string());
167 };
168
169 if (!db_version) {
170 db_version = default_db_version;
171 }
172
173 map_.insert(pair<string, pair<Factory, DBVersion>>(db_type, pair<Factory, DBVersion>(factory, db_version)));
174
175 // We are dealing here with static logger initialization fiasco.
176 // registerFactory may be called from constructors of static global
177 // objects for built in backends. The logging is not initialized yet,
178 // so the LOG_DEBUG would throw.
179 if (!no_log) {
180 LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE, DHCPSRV_LEASE_MGR_BACKEND_REGISTER)
181 .arg(db_type);
182 }
183 return (true);
184}
185
186bool
187LeaseMgrFactory::deregisterFactory(const string& db_type, bool no_log) {
188 auto index = map_.find(db_type);
189 if (index != map_.end()) {
190 map_.erase(index);
191 if (!no_log) {
192 LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE,
193 DHCPSRV_LEASE_MGR_BACKEND_DEREGISTER)
194 .arg(db_type);
195 }
196 return (true);
197 } else {
198 return (false);
199 }
200}
201
202bool
203LeaseMgrFactory::registeredFactory(const std::string& db_type) {
204 auto index = map_.find(db_type);
205 return (index != map_.end());
206}
207
208void
209LeaseMgrFactory::logRegistered() {
210 std::stringstream txt;
211
212 for (auto const& x : map_) {
213 if (!txt.str().empty()) {
214 txt << " ";
215 }
216 txt << x.first;
217 }
218
219 LOG_INFO(dhcpsrv_logger, DHCPSRV_LEASE_MGR_BACKENDS_REGISTERED)
220 .arg(txt.str());
221}
222
223std::list<std::string>
224LeaseMgrFactory::getDBVersions() {
225 std::list<std::string> result;
226 for (auto const& x : map_) {
227 auto version = x.second.second();
228 if (!version.empty()) {
229 result.push_back(version);
230 }
231 }
232
233 return (result);
234}
235
236} // namespace dhcp
237} // namespace isc
cfgmgr.h
isc::InvalidParameter
A generic exception that is thrown if a parameter given to a method or function is considered invalid...
Definition exceptions/exceptions.h:124
isc::Unexpected
A generic exception that is thrown when an unexpected error condition occurs.
Definition exceptions/exceptions.h:153
isc::db::DatabaseConnection::redactedAccessString
static std::string redactedAccessString(const ParameterMap &parameters)
Redact database access string.
Definition database_connection.cc:108
isc::db::DatabaseConnection::parse
static ParameterMap parse(const std::string &dbaccess)
Parse database access string.
Definition database_connection.cc:41
isc::db::DatabaseConnection::ParameterMap
std::map< std::string, std::string > ParameterMap
Database configuration parameter map.
Definition database_connection.h:137
isc::db::InvalidType
Invalid type exception.
Definition database_connection.h:62
isc::dhcp::CfgMgr::instance
static CfgMgr & instance()
returns a single instance of Configuration Manager
Definition cfgmgr.cc:29
isc::dhcp::CfgMgr::getStagingCfg
SrvConfigPtr getStagingCfg()
Returns a pointer to the staging configuration.
Definition cfgmgr.cc:121
isc::dhcp::CfgMgr::getCurrentCfg
SrvConfigPtr getCurrentCfg()
Returns a pointer to the current configuration.
Definition cfgmgr.cc:116
isc::dhcp::LeaseMgrFactory::create
static void create(const std::string &dbaccess)
Create an instance of a lease manager.
Definition lease_mgr_factory.cc:61
isc::dhcp::LeaseMgrFactory::instance
static TrackingLeaseMgr & instance()
Return current lease manager.
Definition lease_mgr_factory.cc:148
isc::dhcp::LeaseMgrFactory::registerFactory
static bool registerFactory(const std::string &db_type, const Factory &factory, bool no_log=false, DBVersion db_version=DBVersion())
Register a lease mgr factory.
Definition lease_mgr_factory.cc:157
isc::dhcp::LeaseMgrFactory::getDBVersions
static std::list< std::string > getDBVersions()
Return extended version info for registered backends.
Definition lease_mgr_factory.cc:224
isc::dhcp::LeaseMgrFactory::init_allocators_
static bool init_allocators_
Flag which indicates if allocators must be initialized.
Definition lease_mgr_factory.h:166
isc::dhcp::LeaseMgrFactory::Factory
std::function< TrackingLeaseMgrPtr(const db::DatabaseConnection::ParameterMap &)> Factory
Type of lease mgr factory.
Definition lease_mgr_factory.h:110
isc::dhcp::LeaseMgrFactory::destroy
static void destroy()
Destroy lease manager.
Definition lease_mgr_factory.cc:107
isc::dhcp::LeaseMgrFactory::registeredFactory
static bool registeredFactory(const std::string &db_type)
Check if a lease mgr factory was registered.
Definition lease_mgr_factory.cc:203
isc::dhcp::LeaseMgrFactory::DBVersion
std::function< std::string()> DBVersion
Type of lease mgr version.
Definition lease_mgr_factory.h:113
isc::dhcp::LeaseMgrFactory::initAllocators
static void initAllocators(bool use_staging=false)
Initializes the lease allocators for all subnets.
Definition lease_mgr_factory.cc:46
isc::dhcp::LeaseMgrFactory::haveInstance
static bool haveInstance()
Indicates if the lease manager has been instantiated.
Definition lease_mgr_factory.cc:143
isc::dhcp::LeaseMgrFactory::deregisterFactory
static bool deregisterFactory(const std::string &db_type, bool no_log=false)
Deregister a lease mgr factory.
Definition lease_mgr_factory.cc:187
isc::dhcp::LeaseMgrFactory::logRegistered
static void logRegistered()
Logs out all registered backends.
Definition lease_mgr_factory.cc:209
isc::dhcp::LeaseMgrFactory::recreate
static void recreate(const std::string &dbaccess, bool preserve_callbacks=true)
Recreate an instance of a lease manager with optionally preserving registered callbacks.
Definition lease_mgr_factory.cc:118
isc::dhcp::NoLeaseManager
No lease manager exception.
Definition lease_mgr_factory.h:25
isc::dhcp::TrackingLeaseMgr
Introduces callbacks into the LeaseMgr.
Definition tracking_lease_mgr.h:76
isc::dhcp::TrackingLeaseMgr::CallbackContainerPtr
boost::shared_ptr< CallbackContainer > CallbackContainerPtr
Pointer to the callback container.
Definition tracking_lease_mgr.h:153
isc::dhcp::TrackingLeaseMgr::callbacks_
CallbackContainerPtr callbacks_
The multi-index container holding registered callbacks.
Definition tracking_lease_mgr.h:296
version
int version()
returns Kea hooks version.
Definition d2/gss_tsig/version.cc:13
dhcpsrv_log.h
isc_throw
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Definition exceptions/exceptions.h:210
lease_mgr_factory.h
LOG_ERROR
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
Definition macros.h:32
LOG_INFO
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
Definition macros.h:20
LOG_DEBUG
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
Definition macros.h:14
memfile_lease_mgr.h
isc::db
Definition audit_entry.cc:14
isc::dhcp
Definition dhcp4/client_handler.cc:20
isc::dhcp::dhcpsrv_logger
isc::log::Logger dhcpsrv_logger("dhcpsrv")
DHCP server library Logger.
Definition dhcpsrv_log.h:56
isc::dhcp::DHCPSRV_LEASE_MGR_BACKENDS_REGISTERED
const isc::log::MessageID DHCPSRV_LEASE_MGR_BACKENDS_REGISTERED
Definition dhcpsrv_messages.h:80
isc::dhcp::DHCPSRV_LEASE_MGR_BACKEND_DEREGISTER
const isc::log::MessageID DHCPSRV_LEASE_MGR_BACKEND_DEREGISTER
Definition dhcpsrv_messages.h:81
isc::dhcp::DHCPSRV_CLOSE_DB
const isc::log::MessageID DHCPSRV_CLOSE_DB
Definition dhcpsrv_messages.h:53
isc::dhcp::DHCPSRV_UNKNOWN_DB
const isc::log::MessageID DHCPSRV_UNKNOWN_DB
Definition dhcpsrv_messages.h:185
isc::dhcp::DHCPSRV_LEASE_MGR_BACKEND_REGISTER
const isc::log::MessageID DHCPSRV_LEASE_MGR_BACKEND_REGISTER
Definition dhcpsrv_messages.h:82
isc::dhcp::DHCPSRV_NOTYPE_DB
const isc::log::MessageID DHCPSRV_NOTYPE_DB
Definition dhcpsrv_messages.h:158
isc::dhcp::TrackingLeaseMgrPtr
std::unique_ptr< TrackingLeaseMgr > TrackingLeaseMgrPtr
TrackingLeaseMgr pointer.
Definition tracking_lease_mgr.h:306
isc::dhcp::DHCPSRV_DBG_TRACE
const int DHCPSRV_DBG_TRACE
DHCP server library logging levels.
Definition dhcpsrv_log.h:26
isc
Defines the logger used by the top-level component of kea-lfc.
Definition check_exists_add.cc:18