Kea  2.5.3
hooks_manager.cc
Go to the documentation of this file.
1 // Copyright (C) 2013-2023 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 <hooks/callout_handle.h>
10 #include <hooks/callout_manager.h>
11 #include <hooks/library_handle.h>
13 #include <hooks/hooks_manager.h>
14 #include <hooks/server_hooks.h>
15 
16 #include <boost/shared_ptr.hpp>
17 #include <boost/weak_ptr.hpp>
18 
19 #include <string>
20 #include <vector>
21 
22 using namespace std;
23 
24 namespace isc {
25 namespace hooks {
26 
27 // Constructor
28 
29 HooksManager::HooksManager() : test_mode_(false) {
30  // Nothing present, so create the collection with any empty set of
31  // libraries, and get the CalloutManager.
32  HookLibsCollection libraries;
33  lm_collection_.reset(new LibraryManagerCollection(libraries));
34  lm_collection_->loadLibraries(false);
35  callout_manager_ = lm_collection_->getCalloutManager();
36 }
37 
38 // Return reference to singleton hooks manager.
39 
40 HooksManager&
41 HooksManager::getHooksManager() {
42  static HooksManager manager;
43  return (manager);
44 }
45 
46 // Are callouts present?
47 
48 bool
49 HooksManager::calloutsPresentInternal(int index) {
50  return (callout_manager_->calloutsPresent(index));
51 }
52 
53 bool
54 HooksManager::calloutsPresent(int index) {
55  return (getHooksManager().calloutsPresentInternal(index));
56 }
57 
58 bool
59 HooksManager::commandHandlersPresentInternal(const std::string& command_name) {
60  return (callout_manager_->commandHandlersPresent(command_name));
61 }
62 
63 bool
64 HooksManager::commandHandlersPresent(const std::string& command_name) {
65  return (getHooksManager().commandHandlersPresentInternal(command_name));
66 }
67 
68 // Call the callouts
69 
70 void
71 HooksManager::callCalloutsInternal(int index, CalloutHandle& handle) {
72  callout_manager_->callCallouts(index, handle);
73 }
74 
75 void
76 HooksManager::callCallouts(int index, CalloutHandle& handle) {
77  getHooksManager().callCalloutsInternal(index, handle);
78 }
79 
80 void
81 HooksManager::callCommandHandlersInternal(const std::string& command_name,
82  CalloutHandle& handle) {
83  callout_manager_->callCommandHandlers(command_name, handle);
84 }
85 
86 void
87 HooksManager::callCommandHandlers(const std::string& command_name,
88  CalloutHandle& handle) {
89  getHooksManager().callCommandHandlersInternal(command_name, handle);
90 }
91 
92 // Load the libraries. This will delete the previously-loaded libraries
93 // (if present) and load new ones. If loading libraries fails, initialize with
94 // empty list.
95 
96 bool
97 HooksManager::loadLibrariesInternal(const HookLibsCollection& libraries,
98  bool multi_threading_enabled) {
99  if (test_mode_) {
100  return (true);
101  }
102 
103  ServerHooks::getServerHooks().getParkingLotsPtr()->clear();
104 
105  // Keep a weak pointer on the existing library manager collection.
106  boost::weak_ptr<LibraryManagerCollection> weak_lmc(lm_collection_);
107 
108  // Create the library manager collection.
109  lm_collection_.reset(new LibraryManagerCollection(libraries));
110 
111  // If there was another owner the previous library manager collection
112  // was not destroyed and libraries not closed.
113  if (!weak_lmc.expired()) {
114  isc_throw(LibrariesStillOpened, "some libraries are still opened");
115  }
116 
117  // Load the libraries.
118  bool status = lm_collection_->loadLibraries(multi_threading_enabled);
119 
120  if (status) {
121  // ... and obtain the callout manager for them if successful.
122  callout_manager_ = lm_collection_->getCalloutManager();
123  } else {
124  // Unable to load libraries, reset to state before this function was
125  // called.
126  static_cast<void>(unloadLibrariesInternal());
127  }
128 
129  return (status);
130 }
131 
132 bool
133 HooksManager::loadLibraries(const HookLibsCollection& libraries,
134  bool multi_threading_enabled) {
135  return (getHooksManager().loadLibrariesInternal(libraries,
136  multi_threading_enabled));
137 }
138 
139 // Unload the libraries. This just deletes all internal objects (which will
140 // cause the libraries to be unloaded) and initializes them with empty list if
141 // requested.
142 
143 bool
144 HooksManager::unloadLibrariesInternal() {
145  if (test_mode_) {
146  return (true);
147  }
148 
149  ServerHooks::getServerHooks().getParkingLotsPtr()->clear();
150 
151  // Keep a weak pointer on the existing library manager collection.
152  boost::weak_ptr<LibraryManagerCollection> weak_lmc(lm_collection_);
153 
154  // Create the collection with any empty set of libraries.
155  HookLibsCollection libraries;
156  lm_collection_.reset(new LibraryManagerCollection(libraries));
157 
158  // If there was another owner the previous library manager collection
159  // was not destroyed and libraries not closed.
160  boost::shared_ptr<LibraryManagerCollection> still_here = weak_lmc.lock();
161  if (still_here) {
162  // Restore the library manager collection.
163  lm_collection_ = still_here;
164  return (false);
165  }
166 
167  // Load the empty set of libraries.
168  lm_collection_->loadLibraries(false);
169 
170  // Get the CalloutManager.
171  callout_manager_ = lm_collection_->getCalloutManager();
172 
173  return (true);
174 }
175 
176 bool
177 HooksManager::unloadLibraries() {
178  return (getHooksManager().unloadLibrariesInternal());
179 }
180 
181 void
182 HooksManager::prepareUnloadLibrariesInternal() {
183  if (test_mode_) {
184  return;
185  }
186 
187  static_cast<void>(lm_collection_->prepareUnloadLibraries());
188 }
189 
190 void
191 HooksManager::prepareUnloadLibraries() {
192  getHooksManager().prepareUnloadLibrariesInternal();
193 }
194 
195 // Create a callout handle
196 
197 boost::shared_ptr<CalloutHandle>
198 HooksManager::createCalloutHandleInternal() {
199  return (boost::make_shared<CalloutHandle>(callout_manager_, lm_collection_));
200 }
201 
202 boost::shared_ptr<CalloutHandle>
203 HooksManager::createCalloutHandle() {
204  return (getHooksManager().createCalloutHandleInternal());
205 }
206 
207 // Get the list of the names of loaded libraries.
208 
209 std::vector<std::string>
210 HooksManager::getLibraryNamesInternal() const {
211  return (lm_collection_->getLibraryNames());
212 }
213 
215 HooksManager::getLibraryInfoInternal() const {
216  return (lm_collection_->getLibraryInfo());
217 }
218 
219 std::vector<std::string>
220 HooksManager::getLibraryNames() {
221  return (getHooksManager().getLibraryNamesInternal());
222 }
223 
225 HooksManager::getLibraryInfo() {
226  return (getHooksManager().getLibraryInfoInternal());
227 }
228 
229 // Shell around ServerHooks::registerHook()
230 
231 int
232 HooksManager::registerHook(const std::string& name) {
233  return (ServerHooks::getServerHooks().registerHook(name));
234 }
235 
236 // Return pre- and post- library handles.
237 
239 HooksManager::preCalloutsLibraryHandleInternal() {
240  return (callout_manager_->getPreLibraryHandle());
241 }
242 
244 HooksManager::preCalloutsLibraryHandle() {
245  return (getHooksManager().preCalloutsLibraryHandleInternal());
246 }
247 
249 HooksManager::postCalloutsLibraryHandleInternal() {
250  return (callout_manager_->getPostLibraryHandle());
251 }
252 
254 HooksManager::postCalloutsLibraryHandle() {
255  return (getHooksManager().postCalloutsLibraryHandleInternal());
256 }
257 
258 // Validate libraries
259 
260 std::vector<std::string>
261 HooksManager::validateLibraries(const std::vector<std::string>& libraries,
262  bool multi_threading_enabled) {
263  return (LibraryManagerCollection::validateLibraries(libraries,
264  multi_threading_enabled));
265 }
266 
267 // Test mode
268 
269 void
270 HooksManager::setTestMode(bool mode) {
271  getHooksManager().test_mode_ = mode;
272 }
273 
274 bool
275 HooksManager::getTestMode() {
276  return (getHooksManager().test_mode_);
277 }
278 
279 } // namespace util
280 } // namespace isc
Per-packet callout handle.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
std::vector< HookLibInfo > HookLibsCollection
A storage for information about hook libraries.
Definition: libinfo.h:31
Defines the logger used by the top-level component of kea-lfc.