Kea 2.5.6
server_hooks.cc
Go to the documentation of this file.
1// Copyright (C) 2013-2024 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
10#include <hooks/hooks_log.h>
11#include <hooks/server_hooks.h>
12
13#include <algorithm>
14#include <utility>
15#include <vector>
16
17using namespace std;
18using namespace isc;
19
20namespace isc {
21namespace hooks {
22
23// Constructor - register the pre-defined hooks and check that the indexes
24// assigned to them are as expected.
25//
26// Note that there are no logging messages here or in registerHooks(). The
27// recommended way to initialize hook names is to use static initialization.
28// Here, a static object is declared in a file outside of any function or
29// method. As a result, it is instantiated and its constructor run before the
30// program starts. By putting calls to ServerHooks::registerHook() in there,
31// hooks names are already registered when the program runs. However, at that
32// point, the logging system is not initialized, so messages are unable to
33// be output.
34
35ServerHooks::ServerHooks() {
36 initialize();
37}
38
39// Register a hook. The index assigned to the hook is the current number
40// of entries in the collection, so ensuring that hook indexes are unique
41// and non-negative.
42
43int
44ServerHooks::registerHook(const string& name) {
45
46 // Determine index for the new element and insert.
47 int index = hooks_.size();
48 pair<HookCollection::iterator, bool> result =
49 hooks_.insert(make_pair(name, index));
50
55
56 if (!result.second) {
57
58 // There's a problem with hook libraries that need to be linked with
59 // libdhcpsrv. For example host_cmds hook library requires host
60 // parser, so it needs to be linked with libdhcpsrv. However, when
61 // unit-tests are started, the hook points are not registered.
62 // When the library is loaded new hook points are registered.
63 // This causes issues in the hooks framework, especially when
64 // LibraryManager::unloadLibrary() iterates through all hooks
65 // and then calls deregisterAllCallouts. This method gets
66 // hook_index that is greater than number of elements in
67 // hook_vector_ and then we have a read past the array boundary.
69 return (getIndex(name));
70
71 // New element was not inserted because an element with the same name
72 // already existed.
73 //isc_throw(DuplicateHook, "hook with name " << name <<
74 // " is already registered");
75 }
76
77 // Element was inserted, so add to the inverse hooks collection.
78 inverse_hooks_[index] = name;
79
80 // ... and return numeric index.
81 return (index);
82}
83
84// Set ServerHooks object to initial state.
85
86void
87ServerHooks::initialize() {
88
89 // Clear out the name->index and index->name maps.
90 hooks_.clear();
91 inverse_hooks_.clear();
92 parking_lots_.reset(new ParkingLots());
93
94 // Register the pre-defined hooks.
95 int create = registerHook("context_create");
96 int destroy = registerHook("context_destroy");
97
98 // Check registration went as expected.
99 if ((create != CONTEXT_CREATE) || (destroy != CONTEXT_DESTROY)) {
100 isc_throw(Unexpected, "pre-defined hook indexes are not as expected. "
101 "context_create: expected = " << CONTEXT_CREATE <<
102 ", actual = " << create <<
103 ". context_destroy: expected = " << CONTEXT_DESTROY <<
104 ", actual = " << destroy);
105 }
106}
107
108// Reset ServerHooks object to initial state.
109
110void
112
113 // Clear all hooks then initialize the pre-defined ones.
114 initialize();
115
116 // Log a warning - although this is done during testing, it should never be
117 // seen in a production system.
119}
120
121// Find the name associated with a hook index.
122
123std::string
124ServerHooks::getName(int index) const {
125
126 // Get iterator to matching element.
127 InverseHookCollection::const_iterator i = inverse_hooks_.find(index);
128 if (i == inverse_hooks_.end()) {
129 isc_throw(NoSuchHook, "hook index " << index << " is not recognized");
130 }
131
132 return (i->second);
133}
134
135// Find the index associated with a hook name.
136
137int
138ServerHooks::getIndex(const string& name) const {
139
140 // Get iterator to matching element.
141 HookCollection::const_iterator i = hooks_.find(name);
142 if (i == hooks_.end()) {
143 isc_throw(NoSuchHook, "hook name " << name << " is not recognized");
144 }
145
146 return (i->second);
147}
148
149int
150ServerHooks::findIndex(const std::string& name) const {
151 // Get iterator to matching element.
152 auto i = hooks_.find(name);
153 return ((i == hooks_.end()) ? -1 : i->second);
154}
155
156// Return vector of hook names. The names are not sorted - it is up to the
157// caller to perform sorting if required.
158
159vector<string>
161 vector<string> names;
162 for (auto const& i : hooks_) {
163 names.push_back(i.first);
164 }
165
166 return (names);
167}
168
169// Return global ServerHooks object
170
173 return (*getServerHooksPtr());
174}
175
178 static ServerHooksPtr hooks(new ServerHooks());
179 return (hooks);
180}
181
184 return (parking_lots_);
185}
186
188ServerHooks::getParkingLotPtr(const int hook_index) {
189 return (parking_lots_->getParkingLotPtr(hook_index));
190}
191
193ServerHooks::getParkingLotPtr(const std::string& hook_name) {
194 return (parking_lots_->getParkingLotPtr(getServerHooks().getIndex(hook_name)));
195}
196
197std::string
198ServerHooks::commandToHookName(const std::string& command_name) {
199 // Prefix the command name with a dollar sign.
200 std::string hook_name = std::string("$") + command_name;
201 // Replace all hyphens with underscores.
202 std::replace(hook_name.begin(), hook_name.end(), '-', '_');
203 return (hook_name);
204}
205
206std::string
207ServerHooks::hookToCommandName(const std::string& hook_name) {
208 if (!hook_name.empty() && hook_name.front() == '$') {
209 std::string command_name = hook_name.substr(1);
210 std::replace(command_name.begin(), command_name.end(), '_', '-');
211 return (command_name);
212 }
213 return ("");
214}
215
216} // namespace hooks
217} // namespace isc
A generic exception that is thrown when an unexpected error condition occurs.
Collection of parking lots for various hook points.
Definition: parking_lots.h:384
Server hook collection.
Definition: server_hooks.h:62
static ServerHooksPtr getServerHooksPtr()
Returns pointer to ServerHooks object.
ParkingLotPtr getParkingLotPtr(const int hook_index)
Returns pointer to the ParkingLot for the specified hook index.
int getIndex(const std::string &name) const
Get hook index.
static ServerHooks & getServerHooks()
Return ServerHooks object.
static const int CONTEXT_DESTROY
Definition: server_hooks.h:67
ParkingLotsPtr getParkingLotsPtr() const
Returns pointer to all parking lots.
int findIndex(const std::string &name) const
Find hook index.
void reset()
Reset to Initial State.
static std::string hookToCommandName(const std::string &hook_name)
Returns command name for a specified hook name.
static std::string commandToHookName(const std::string &command_name)
Generates hook point name for the given control command name.
static const int CONTEXT_CREATE
Index numbers for pre-defined hooks.
Definition: server_hooks.h:66
int registerHook(const std::string &name)
Register a hook.
Definition: server_hooks.cc:44
std::vector< std::string > getHookNames() const
Get hook names.
std::string getName(int index) const
Get hook name.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
#define LOG_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
Definition: macros.h:26
boost::shared_ptr< ParkingLots > ParkingLotsPtr
Type of the pointer to the parking lots.
Definition: parking_lots.h:421
const isc::log::MessageID HOOKS_HOOK_LIST_RESET
boost::shared_ptr< ServerHooks > ServerHooksPtr
Definition: server_hooks.h:43
isc::log::Logger hooks_logger("hooks")
Hooks Logger.
Definition: hooks_log.h:37
boost::shared_ptr< ParkingLot > ParkingLotPtr
Type of the pointer to the parking lot.
Definition: parking_lots.h:294
Defines the logger used by the top-level component of kea-lfc.