Kea 2.7.6
ha_callouts.cc
Go to the documentation of this file.
1// Copyright (C) 2017-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// Functions accessed by the hooks framework use C linkage to avoid the name
8// mangling that accompanies use of the C++ compiler as well as to avoid
9// issues related to namespaces.
10
11#include <config.h>
12
13#include <ha_impl.h>
14#include <ha_log.h>
15#include <asiolink/io_service.h>
18#include <dhcpsrv/cfgmgr.h>
21#include <hooks/hooks.h>
22#include <process/daemon.h>
23
24#include <sstream>
25#include <string>
26
27namespace isc {
28namespace ha {
29
31
32} // end of namespace isc::ha
33} // end of namespace isc
34
35using namespace isc::asiolink;
36using namespace isc::config;
37using namespace isc::data;
38using namespace isc::dhcp;
39using namespace isc::ha;
40using namespace isc::hooks;
41using namespace isc::process;
42using namespace std;
43
44extern "C" {
45
50 try {
51 isc::dhcp::NetworkStatePtr network_state;
52 handle.getArgument("network_state", network_state);
53 impl->startServices(network_state, HAServerType::DHCPv4);
55
56 } catch (const std::exception& ex) {
58 .arg(ex.what());
60 ostringstream os;
61 os << "Error: " << ex.what();
62 string error(os.str());
63 handle.setArgument("error", error);
64 return (1);
65 }
66 return (0);
67}
68
74 if (status == CalloutHandle::NEXT_STEP_DROP) {
75 return (0);
76 }
77
78 try {
79 impl->buffer4Receive(handle);
80
81 } catch (const std::exception& ex) {
83 .arg(ex.what());
84 return (1);
85 }
86
87 return (0);
88}
89
95 if (status == CalloutHandle::NEXT_STEP_DROP) {
96 return (0);
97 }
98
99 try {
100 impl->subnet4Select(handle);
101
102 } catch (const std::exception& ex) {
104 .arg(ex.what());
105 return (1);
106 }
107
108 return (0);
109}
110
111
117 if (status == CalloutHandle::NEXT_STEP_DROP ||
119 return (0);
120 }
121
122 try {
123 impl->leases4Committed(handle);
124
125 } catch (const std::exception& ex) {
127 .arg(ex.what());
128 return (1);
129 }
130
131 return (0);
132}
133
139 if (status == CalloutHandle::NEXT_STEP_DROP ||
141 return (0);
142 }
143
144 try {
145 impl->lease4ServerDecline(handle);
146 } catch (const std::exception& ex) {
148 .arg(ex.what());
149 return (1);
150 }
151
152 return (0);
153}
154
155
160 try {
161 isc::dhcp::NetworkStatePtr network_state;
162 handle.getArgument("network_state", network_state);
163 impl->startServices(network_state, HAServerType::DHCPv6);
165
166 } catch (const std::exception& ex) {
168 .arg(ex.what());
170 ostringstream os;
171 os << "Error: " << ex.what();
172 string error(os.str());
173 handle.setArgument("error", error);
174 return (1);
175 }
176 return (0);
177}
178
184 if (status == CalloutHandle::NEXT_STEP_DROP ||
186 return (0);
187 }
188
189 try {
190 impl->buffer6Receive(handle);
191
192 } catch (const std::exception& ex) {
194 .arg(ex.what());
195 return (1);
196 }
197
198 return (0);
199}
200
206 if (status == CalloutHandle::NEXT_STEP_DROP) {
207 return (0);
208 }
209
210 try {
211 impl->subnet6Select(handle);
212
213 } catch (const std::exception& ex) {
215 .arg(ex.what());
216 return (1);
217 }
218
219 return (0);
220}
221
227 if (status == CalloutHandle::NEXT_STEP_DROP ||
229 return (0);
230 }
231
232 try {
233 impl->leases6Committed(handle);
234
235 } catch (const std::exception& ex) {
237 .arg(ex.what());
238 return (1);
239 }
240
241 return (0);
242}
243
248 try {
249 impl->commandProcessed(handle);
250
251 } catch (const std::exception& ex) {
253 .arg(ex.what());
254 return (1);
255 }
256
257 return (0);
258}
259
262 try {
263 impl->heartbeatHandler(handle);
264
265 } catch (const std::exception& ex) {
267 .arg(ex.what());
268 return (1);
269 }
270
271 return (0);
272}
273
276 try {
277 impl->synchronizeHandler(handle);
278
279 } catch (const std::exception& ex) {
281 .arg(ex.what());
282 }
283
284 return (0);
285}
286
289 try {
290 impl->scopesHandler(handle);
291
292 } catch (const std::exception& ex) {
294 .arg(ex.what());
295 }
296
297 return (0);
298}
299
302 try {
303 impl->continueHandler(handle);
304
305 } catch (const std::exception& ex) {
307 .arg(ex.what());
308 }
309
310 return (0);
311}
312
315 try {
316 impl->maintenanceNotifyHandler(handle);
317
318 } catch (const std::exception& ex) {
320 .arg(ex.what());
321 }
322
323 return (0);
324}
325
328 try {
329 impl->maintenanceStartHandler(handle);
330
331 } catch (const std::exception& ex) {
333 .arg(ex.what());
334 }
335
336 return (0);
337}
338
341 try {
342 impl->maintenanceCancelHandler(handle);
343
344 } catch (const std::exception& ex) {
346 .arg(ex.what());
347 }
348
349 return (0);
350}
351
354 try {
355 impl->haResetHandler(handle);
356
357 } catch (const std::exception& ex) {
359 .arg(ex.what());
360 }
361
362 return (0);
363}
364
367 try {
368 impl->syncCompleteNotifyHandler(handle);
369 } catch (const std::exception& ex) {
371 .arg(ex.what());
372 }
373
374 return (0);
375}
376
381int load(LibraryHandle& handle) {
382 ConstElementPtr config = handle.getParameter("high-availability");
383 if (!config) {
385 return (1);
386 }
387
388 try {
389 // Make the hook library not loadable by d2 or ca.
390 uint16_t family = CfgMgr::instance().getFamily();
391 const std::string& proc_name = Daemon::getProcName();
392 if (family == AF_INET) {
393 if (proc_name != "kea-dhcp4") {
394 isc_throw(isc::Unexpected, "Bad process name: " << proc_name
395 << ", expected kea-dhcp4");
396 }
397 } else {
398 if (proc_name != "kea-dhcp6") {
399 isc_throw(isc::Unexpected, "Bad process name: " << proc_name
400 << ", expected kea-dhcp6");
401 }
402 }
403
404 impl = boost::make_shared<HAImpl>();
405 impl->configure(config);
406
407 handle.registerCommandCallout("ha-heartbeat", heartbeat_command);
408 handle.registerCommandCallout("ha-sync", sync_command);
409 handle.registerCommandCallout("ha-scopes", scopes_command);
410 handle.registerCommandCallout("ha-continue", continue_command);
411 handle.registerCommandCallout("ha-maintenance-notify", maintenance_notify_command);
412 handle.registerCommandCallout("ha-maintenance-start", maintenance_start_command);
413 handle.registerCommandCallout("ha-maintenance-cancel", maintenance_cancel_command);
414 handle.registerCommandCallout("ha-reset", ha_reset_command);
415 handle.registerCommandCallout("ha-sync-complete-notify", sync_complete_notify_command);
416
417 } catch (const std::exception& ex) {
419 .arg(ex.what());
420 return (CONTROL_RESULT_ERROR);
421 }
422
424 return (0);
425}
426
430int unload() {
431 if (impl) {
433 impl.reset();
434 }
436 return (0);
437}
438
443 return (1);
444}
445
446} // end extern "C"
A generic exception that is thrown when an unexpected error condition occurs.
uint16_t getFamily() const
Returns address family.
Definition cfgmgr.h:235
static CfgMgr & instance()
returns a single instance of Configuration Manager
Definition cfgmgr.cc:28
Per-packet callout handle.
CalloutNextStep
Specifies allowed next steps.
@ NEXT_STEP_DROP
drop the packet
@ NEXT_STEP_SKIP
skip the next processing step
CalloutNextStep getStatus() const
Returns the next processing step.
void setStatus(const CalloutNextStep next)
Sets the next processing step.
void getArgument(const std::string &name, T &value) const
Get argument.
void setArgument(const std::string &name, T value)
Set argument.
isc::data::ConstElementPtr getParameter(const std::string &name)
Returns configuration parameter for the library.
void registerCommandCallout(const std::string &command_name, CalloutPtr callout)
Register control command handler.
static std::string getProcName()
returns the process name This value is used as when forming the default PID file name
Definition daemon.cc:129
This file contains several functions and constants that are used for handling commands and responses ...
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
int lease4_server_decline(CalloutHandle &handle)
lease4_server_decline callout implementation.
int subnet4_select(CalloutHandle &handle)
subnet4_select callout implementation.
int maintenance_cancel_command(CalloutHandle &handle)
ha-maintenance-cancel command handler implementation.
int dhcp4_srv_configured(CalloutHandle &handle)
dhcp4_srv_configured callout implementation.
int leases6_committed(CalloutHandle &handle)
leases6_committed callout implementation.
int sync_complete_notify_command(CalloutHandle &handle)
ha-sync-complete-notify command handler implementation.
int scopes_command(CalloutHandle &handle)
ha-scopes command handler implementation.
int heartbeat_command(CalloutHandle &handle)
Heartbeat command handler implementation.
int command_processed(CalloutHandle &handle)
command_processed callout implementation.
int leases4_committed(CalloutHandle &handle)
leases4_committed callout implementation.
int multi_threading_compatible()
This function is called to retrieve the multi-threading compatibility.
int maintenance_notify_command(CalloutHandle &handle)
ha-maintenance-notify command handler implementation.
int subnet6_select(CalloutHandle &handle)
subnet6_select callout implementation.
int unload()
This function is called when the library is unloaded.
int dhcp6_srv_configured(CalloutHandle &handle)
dhcp6_srv_configured callout implementation.
int buffer4_receive(CalloutHandle &handle)
buffer4_receive callout implementation.
int continue_command(CalloutHandle &handle)
ha-continue command handler implementation.
int ha_reset_command(CalloutHandle &handle)
ha-reset command handler implementation.
int maintenance_start_command(CalloutHandle &handle)
ha-maintenance-start command handler implementation.
int buffer6_receive(CalloutHandle &handle)
buffer6_receive callout implementation.
int sync_command(CalloutHandle &handle)
ha-sync command handler implementation.
int load(LibraryHandle &handle)
This function is called when the library is loaded.
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
Definition macros.h:32
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
Definition macros.h:20
const int CONTROL_RESULT_ERROR
Status code indicating a general failure.
boost::shared_ptr< const Element > ConstElementPtr
Definition data.h:29
@ error
Definition db_log.h:118
boost::shared_ptr< NetworkState > NetworkStatePtr
Pointer to the NetworkState object.
const isc::log::MessageID HA_BUFFER4_RECEIVE_FAILED
Definition ha_messages.h:11
boost::shared_ptr< HAImpl > HAImplPtr
Pointer to the High Availability hooks library implementation.
Definition ha_impl.h:251
const isc::log::MessageID HA_DEINIT_OK
Definition ha_messages.h:37
const isc::log::MessageID HA_COMMAND_PROCESSED_FAILED
Definition ha_messages.h:19
const isc::log::MessageID HA_LEASES4_COMMITTED_FAILED
Definition ha_messages.h:54
const isc::log::MessageID HA_CONTINUE_HANDLER_FAILED
Definition ha_messages.h:36
const isc::log::MessageID HA_MAINTENANCE_CANCEL_HANDLER_FAILED
Definition ha_messages.h:84
const isc::log::MessageID HA_HEARTBEAT_HANDLER_FAILED
Definition ha_messages.h:46
isc::log::Logger ha_logger("ha-hooks")
Definition ha_log.h:17
const isc::log::MessageID HA_RESET_HANDLER_FAILED
Definition ha_messages.h:99
const isc::log::MessageID HA_DHCP6_START_SERVICE_FAILED
Definition ha_messages.h:39
const isc::log::MessageID HA_MAINTENANCE_START_HANDLER_FAILED
Definition ha_messages.h:93
const isc::log::MessageID HA_BUFFER6_RECEIVE_FAILED
Definition ha_messages.h:15
const isc::log::MessageID HA_SYNC_COMPLETE_NOTIFY_HANDLER_FAILED
const isc::log::MessageID HA_SUBNET6_SELECT_FAILED
HAImplPtr impl
const isc::log::MessageID HA_LEASE4_SERVER_DECLINE_FAILED
Definition ha_messages.h:53
const isc::log::MessageID HA_INIT_OK
Definition ha_messages.h:49
const isc::log::MessageID HA_SUBNET4_SELECT_FAILED
const isc::log::MessageID HA_MISSING_CONFIGURATION
Definition ha_messages.h:94
const isc::log::MessageID HA_LEASES6_COMMITTED_FAILED
Definition ha_messages.h:57
const isc::log::MessageID HA_DHCP4_START_SERVICE_FAILED
Definition ha_messages.h:38
const isc::log::MessageID HA_CONFIGURATION_FAILED
Definition ha_messages.h:25
const isc::log::MessageID HA_MAINTENANCE_NOTIFY_HANDLER_FAILED
Definition ha_messages.h:89
const isc::log::MessageID HA_SYNC_HANDLER_FAILED
const isc::log::MessageID HA_SCOPES_HANDLER_FAILED
Defines the logger used by the top-level component of kea-lfc.