Kea 3.3.3
ha_callouts.cc
Go to the documentation of this file.
1// Copyright (C) 2017-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// 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 <asiolink/io_service.h>
16#include <dhcpsrv/cfgmgr.h>
20#include <hooks/hooks.h>
21#include <process/daemon.h>
22
23#include <sstream>
24#include <string>
25
26#include <ha_log.h>
27
28namespace isc {
29namespace ha {
30
32
33} // end of namespace isc::ha
34} // end of namespace isc
35
36using namespace isc::asiolink;
37using namespace isc::config;
38using namespace isc::data;
39using namespace isc::dhcp;
40using namespace isc::ha;
41using namespace isc::hooks;
42using namespace isc::process;
43using namespace std;
44
45extern "C" {
46
51 try {
52 isc::dhcp::NetworkStatePtr network_state;
53 handle.getArgument("network_state", network_state);
54 impl->startServices(network_state, HAServerType::DHCPv4);
56
57 } catch (const std::exception& ex) {
59 .arg(ex.what());
61 ostringstream os;
62 os << "Error: " << ex.what();
63 string error(os.str());
64 handle.setArgument("error", error);
65 return (1);
66 }
67 return (0);
68}
69
75 if (status == CalloutHandle::NEXT_STEP_DROP) {
76 return (0);
77 }
78
79 try {
80 impl->buffer4Receive(handle);
81
82 } catch (const std::exception& ex) {
84 .arg(ex.what());
85 return (1);
86 }
87
88 return (0);
89}
90
96 if (status == CalloutHandle::NEXT_STEP_DROP) {
97 return (0);
98 }
99
100 try {
101 impl->subnet4Select(handle);
102
103 } catch (const std::exception& ex) {
105 .arg(ex.what());
106 return (1);
107 }
108
109 return (0);
110}
111
112
118 if (status == CalloutHandle::NEXT_STEP_DROP ||
120 return (0);
121 }
122
123 try {
124 impl->leases4Committed(handle);
125
126 } catch (const std::exception& ex) {
128 .arg(ex.what());
129 return (1);
130 }
131
132 return (0);
133}
134
140 if (status == CalloutHandle::NEXT_STEP_DROP ||
142 return (0);
143 }
144
145 try {
146 impl->lease4ServerDecline(handle);
147 } catch (const std::exception& ex) {
149 .arg(ex.what());
150 return (1);
151 }
152
153 return (0);
154}
155
161 if (status == CalloutHandle::NEXT_STEP_SKIP) {
162 return (0);
163 }
164
165 try {
166 impl->lease4Expire(handle);
167 } catch (const std::exception& ex) {
169 .arg(ex.what());
170 return (1);
171 }
172
173 return (0);
174}
175
180 try {
181 isc::dhcp::NetworkStatePtr network_state;
182 handle.getArgument("network_state", network_state);
183 impl->startServices(network_state, HAServerType::DHCPv6);
185
186 } catch (const std::exception& ex) {
188 .arg(ex.what());
190 ostringstream os;
191 os << "Error: " << ex.what();
192 string error(os.str());
193 handle.setArgument("error", error);
194 return (1);
195 }
196 return (0);
197}
198
204 if (status == CalloutHandle::NEXT_STEP_DROP ||
206 return (0);
207 }
208
209 try {
210 impl->buffer6Receive(handle);
211
212 } catch (const std::exception& ex) {
214 .arg(ex.what());
215 return (1);
216 }
217
218 return (0);
219}
220
226 if (status == CalloutHandle::NEXT_STEP_DROP) {
227 return (0);
228 }
229
230 try {
231 impl->subnet6Select(handle);
232
233 } catch (const std::exception& ex) {
235 .arg(ex.what());
236 return (1);
237 }
238
239 return (0);
240}
241
247 if (status == CalloutHandle::NEXT_STEP_DROP ||
249 return (0);
250 }
251
252 try {
253 impl->leases6Committed(handle);
254
255 } catch (const std::exception& ex) {
257 .arg(ex.what());
258 return (1);
259 }
260
261 return (0);
262}
263
269 if (status == CalloutHandle::NEXT_STEP_SKIP) {
270 return (0);
271 }
272
273 try {
274 impl->lease6Expire(handle);
275 } catch (const std::exception& ex) {
277 .arg(ex.what());
278 return (1);
279 }
280
281 return (0);
282}
283
288 try {
289 impl->commandProcessed(handle);
290
291 } catch (const std::exception& ex) {
293 .arg(ex.what());
294 return (1);
295 }
296
297 return (0);
298}
299
302 try {
303 impl->heartbeatHandler(handle);
304
305 } catch (const std::exception& ex) {
307 .arg(ex.what());
308 return (1);
309 }
310
311 return (0);
312}
313
316 try {
317 impl->synchronizeHandler(handle);
318
319 } catch (const std::exception& ex) {
321 .arg(ex.what());
322 }
323
324 return (0);
325}
326
329 try {
330 impl->scopesHandler(handle);
331
332 } catch (const std::exception& ex) {
334 .arg(ex.what());
335 }
336
337 return (0);
338}
339
342 try {
343 impl->continueHandler(handle);
344
345 } catch (const std::exception& ex) {
347 .arg(ex.what());
348 }
349
350 return (0);
351}
352
355 try {
356 impl->maintenanceNotifyHandler(handle);
357
358 } catch (const std::exception& ex) {
360 .arg(ex.what());
361 }
362
363 return (0);
364}
365
368 try {
369 impl->maintenanceStartHandler(handle);
370
371 } catch (const std::exception& ex) {
373 .arg(ex.what());
374 }
375
376 return (0);
377}
378
381 try {
382 impl->maintenanceCancelHandler(handle);
383
384 } catch (const std::exception& ex) {
386 .arg(ex.what());
387 }
388
389 return (0);
390}
391
394 try {
395 impl->haResetHandler(handle);
396
397 } catch (const std::exception& ex) {
399 .arg(ex.what());
400 }
401
402 return (0);
403}
404
407 try {
408 impl->syncCompleteNotifyHandler(handle);
409 } catch (const std::exception& ex) {
411 .arg(ex.what());
412 }
413
414 return (0);
415}
416
421int load(LibraryHandle& handle) {
422 ConstElementPtr config = handle.getParameter("high-availability");
423 if (!config) {
425 return (1);
426 }
427
428 try {
429 // Make the hook library not loadable by d2.
430 uint16_t family = CfgMgr::instance().getFamily();
431 const std::string& proc_name = Daemon::getProcName();
432 if (family == AF_INET) {
433 if (proc_name != "kea-dhcp4") {
434 isc_throw(isc::Unexpected, "Bad process name: " << proc_name
435 << ", expected kea-dhcp4");
436 }
437 } else {
438 if (proc_name != "kea-dhcp6") {
439 isc_throw(isc::Unexpected, "Bad process name: " << proc_name
440 << ", expected kea-dhcp6");
441 }
442 }
443
444 impl = boost::make_shared<HAImpl>();
445 impl->configure(config);
446
447 handle.registerCommandCallout("ha-heartbeat", heartbeat_command);
448 handle.registerCommandCallout("ha-sync", sync_command);
449 handle.registerCommandCallout("ha-scopes", scopes_command);
450 handle.registerCommandCallout("ha-continue", continue_command);
451 handle.registerCommandCallout("ha-maintenance-notify", maintenance_notify_command);
452 handle.registerCommandCallout("ha-maintenance-start", maintenance_start_command);
453 handle.registerCommandCallout("ha-maintenance-cancel", maintenance_cancel_command);
454 handle.registerCommandCallout("ha-reset", ha_reset_command);
455 handle.registerCommandCallout("ha-sync-complete-notify", sync_complete_notify_command);
456
457 } catch (const std::exception& ex) {
459 .arg(ex.what());
460 return (CONTROL_RESULT_ERROR);
461 }
462
464 return (0);
465}
466
470int unload() {
471 if (impl) {
473 impl->stop();
474 impl.reset();
475 }
477 return (0);
478}
479
484 return (1);
485}
486
487} // end extern "C"
CalloutNextStep
Specifies allowed next steps.
@ NEXT_STEP_DROP
drop the packet
@ NEXT_STEP_SKIP
skip the next processing step
A generic exception that is thrown when an unexpected error condition occurs.
uint16_t getFamily() const
Returns address family.
Definition cfgmgr.h:246
static CfgMgr & instance()
returns a single instance of Configuration Manager
Definition cfgmgr.cc:29
Per-packet callout handle.
@ NEXT_STEP_DROP
drop the packet
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:156
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 lease6_expire(CalloutHandle &handle)
lease6_expire callout implementation.
int lease4_expire(CalloutHandle &handle)
lease4_expire 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:30
@ error
Definition db_log.h:127
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:292
const isc::log::MessageID HA_LEASE4_EXPIRE_FAILED
Definition ha_messages.h:53
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:60
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:92
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
const isc::log::MessageID HA_DHCP6_START_SERVICE_FAILED
Definition ha_messages.h:39
const isc::log::MessageID HA_MAINTENANCE_START_HANDLER_FAILED
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:56
const isc::log::MessageID HA_INIT_OK
Definition ha_messages.h:49
const isc::log::MessageID HA_LEASE6_EXPIRE_FAILED
Definition ha_messages.h:57
const isc::log::MessageID HA_SUBNET4_SELECT_FAILED
const isc::log::MessageID HA_MISSING_CONFIGURATION
const isc::log::MessageID HA_LEASES6_COMMITTED_FAILED
Definition ha_messages.h:63
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:97
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.