Kea 2.5.8
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>
17#include <dhcpsrv/cfgmgr.h>
20#include <hooks/hooks.h>
21#include <process/daemon.h>
22
23#include <sstream>
24#include <string>
25
26namespace isc {
27namespace ha {
28
30
31} // end of namespace isc::ha
32} // end of namespace isc
33
34using namespace isc::config;
35using namespace isc::data;
36using namespace isc::dhcp;
37using namespace isc::ha;
38using namespace isc::hooks;
39using namespace isc::process;
40using namespace std;
41
42extern "C" {
43
48 try {
50 handle.getArgument("io_context", io_service);
51 if (!io_service) {
52 // Should not happen!
54 const string error("Error: io_context is null");
55 handle.setArgument("error", error);
56 return (1);
57 }
58 isc::dhcp::NetworkStatePtr network_state;
59 handle.getArgument("network_state", network_state);
60 impl->startServices(io_service, network_state, HAServerType::DHCPv4);
61
62 } catch (const std::exception& ex) {
64 .arg(ex.what());
66 ostringstream os;
67 os << "Error: " << ex.what();
68 string error(os.str());
69 handle.setArgument("error", error);
70 return (1);
71 }
72 return (0);
73}
74
80 if (status == CalloutHandle::NEXT_STEP_DROP) {
81 return (0);
82 }
83
84 try {
85 impl->buffer4Receive(handle);
86
87 } catch (const std::exception& ex) {
89 .arg(ex.what());
90 return (1);
91 }
92
93 return (0);
94}
95
101 if (status == CalloutHandle::NEXT_STEP_DROP) {
102 return (0);
103 }
104
105 try {
106 impl->subnet4Select(handle);
107
108 } catch (const std::exception& ex) {
110 .arg(ex.what());
111 return (1);
112 }
113
114 return (0);
115}
116
117
123 if (status == CalloutHandle::NEXT_STEP_DROP ||
125 return (0);
126 }
127
128 try {
129 impl->leases4Committed(handle);
130
131 } catch (const std::exception& ex) {
133 .arg(ex.what());
134 return (1);
135 }
136
137 return (0);
138}
139
145 if (status == CalloutHandle::NEXT_STEP_DROP ||
147 return (0);
148 }
149
150 try {
151 impl->lease4ServerDecline(handle);
152 } catch (const std::exception& ex) {
154 .arg(ex.what());
155 return (1);
156 }
157
158 return (0);
159}
160
161
166 try {
168 handle.getArgument("io_context", io_service);
169 if (!io_service) {
170 // Should not happen!
172 const string error("Error: io_context is null");
173 handle.setArgument("error", error);
174 return (1);
175 }
176 isc::dhcp::NetworkStatePtr network_state;
177 handle.getArgument("network_state", network_state);
178 impl->startServices(io_service, network_state, HAServerType::DHCPv6);
179
180 } catch (const std::exception& ex) {
182 .arg(ex.what());
184 ostringstream os;
185 os << "Error: " << ex.what();
186 string error(os.str());
187 handle.setArgument("error", error);
188 return (1);
189 }
190 return (0);
191}
192
198 if (status == CalloutHandle::NEXT_STEP_DROP ||
200 return (0);
201 }
202
203 try {
204 impl->buffer6Receive(handle);
205
206 } catch (const std::exception& ex) {
208 .arg(ex.what());
209 return (1);
210 }
211
212 return (0);
213}
214
220 if (status == CalloutHandle::NEXT_STEP_DROP) {
221 return (0);
222 }
223
224 try {
225 impl->subnet6Select(handle);
226
227 } catch (const std::exception& ex) {
229 .arg(ex.what());
230 return (1);
231 }
232
233 return (0);
234}
235
241 if (status == CalloutHandle::NEXT_STEP_DROP ||
243 return (0);
244 }
245
246 try {
247 impl->leases6Committed(handle);
248
249 } catch (const std::exception& ex) {
251 .arg(ex.what());
252 return (1);
253 }
254
255 return (0);
256}
257
262 try {
263 impl->commandProcessed(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->heartbeatHandler(handle);
278
279 } catch (const std::exception& ex) {
281 .arg(ex.what());
282 return (1);
283 }
284
285 return (0);
286}
287
290 try {
291 impl->synchronizeHandler(handle);
292
293 } catch (const std::exception& ex) {
295 .arg(ex.what());
296 }
297
298 return (0);
299}
300
303 try {
304 impl->scopesHandler(handle);
305
306 } catch (const std::exception& ex) {
308 .arg(ex.what());
309 }
310
311 return (0);
312}
313
316 try {
317 impl->continueHandler(handle);
318
319 } catch (const std::exception& ex) {
321 .arg(ex.what());
322 }
323
324 return (0);
325}
326
329 try {
330 impl->maintenanceNotifyHandler(handle);
331
332 } catch (const std::exception& ex) {
334 .arg(ex.what());
335 }
336
337 return (0);
338}
339
342 try {
343 impl->maintenanceStartHandler(handle);
344
345 } catch (const std::exception& ex) {
347 .arg(ex.what());
348 }
349
350 return (0);
351}
352
355 try {
356 impl->maintenanceCancelHandler(handle);
357
358 } catch (const std::exception& ex) {
360 .arg(ex.what());
361 }
362
363 return (0);
364}
365
368 try {
369 impl->haResetHandler(handle);
370
371 } catch (const std::exception& ex) {
373 .arg(ex.what());
374 }
375
376 return (0);
377}
378
381 try {
382 impl->syncCompleteNotifyHandler(handle);
383 } catch (const std::exception& ex) {
385 .arg(ex.what());
386 }
387
388 return (0);
389}
390
395int load(LibraryHandle& handle) {
396 ConstElementPtr config = handle.getParameter("high-availability");
397 if (!config) {
399 return (1);
400 }
401
402 try {
403 // Make the hook library not loadable by d2 or ca.
404 uint16_t family = CfgMgr::instance().getFamily();
405 const std::string& proc_name = Daemon::getProcName();
406 if (family == AF_INET) {
407 if (proc_name != "kea-dhcp4") {
408 isc_throw(isc::Unexpected, "Bad process name: " << proc_name
409 << ", expected kea-dhcp4");
410 }
411 } else {
412 if (proc_name != "kea-dhcp6") {
413 isc_throw(isc::Unexpected, "Bad process name: " << proc_name
414 << ", expected kea-dhcp6");
415 }
416 }
417
418 impl = boost::make_shared<HAImpl>();
419 impl->configure(config);
420
421 handle.registerCommandCallout("ha-heartbeat", heartbeat_command);
422 handle.registerCommandCallout("ha-sync", sync_command);
423 handle.registerCommandCallout("ha-scopes", scopes_command);
424 handle.registerCommandCallout("ha-continue", continue_command);
425 handle.registerCommandCallout("ha-maintenance-notify", maintenance_notify_command);
426 handle.registerCommandCallout("ha-maintenance-start", maintenance_start_command);
427 handle.registerCommandCallout("ha-maintenance-cancel", maintenance_cancel_command);
428 handle.registerCommandCallout("ha-reset", ha_reset_command);
429 handle.registerCommandCallout("ha-sync-complete-notify", sync_complete_notify_command);
430
431 } catch (const std::exception& ex) {
433 .arg(ex.what());
434 return (CONTROL_RESULT_ERROR);
435 }
436
438 return (0);
439}
440
444int unload() {
445 impl.reset();
447 return (0);
448}
449
454 return (1);
455}
456
457} // 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:280
static CfgMgr & instance()
returns a single instance of Configuration Manager
Definition: cfgmgr.cc:25
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.
Definition: ha_callouts.cc:143
int subnet4_select(CalloutHandle &handle)
subnet4_select callout implementation.
Definition: ha_callouts.cc:99
int maintenance_cancel_command(CalloutHandle &handle)
ha-maintenance-cancel command handler implementation.
Definition: ha_callouts.cc:354
int dhcp4_srv_configured(CalloutHandle &handle)
dhcp4_srv_configured callout implementation.
Definition: ha_callouts.cc:47
int leases6_committed(CalloutHandle &handle)
leases6_committed callout implementation.
Definition: ha_callouts.cc:239
int sync_complete_notify_command(CalloutHandle &handle)
ha-sync-complete-notify command handler implementation.
Definition: ha_callouts.cc:380
int scopes_command(CalloutHandle &handle)
ha-scopes command handler implementation.
Definition: ha_callouts.cc:302
int heartbeat_command(CalloutHandle &handle)
Heartbeat command handler implementation.
Definition: ha_callouts.cc:275
int command_processed(CalloutHandle &handle)
command_processed callout implementation.
Definition: ha_callouts.cc:261
int leases4_committed(CalloutHandle &handle)
leases4_committed callout implementation.
Definition: ha_callouts.cc:121
int multi_threading_compatible()
This function is called to retrieve the multi-threading compatibility.
Definition: ha_callouts.cc:453
int maintenance_notify_command(CalloutHandle &handle)
ha-maintenance-notify command handler implementation.
Definition: ha_callouts.cc:328
int subnet6_select(CalloutHandle &handle)
subnet6_select callout implementation.
Definition: ha_callouts.cc:218
int unload()
This function is called when the library is unloaded.
Definition: ha_callouts.cc:444
int dhcp6_srv_configured(CalloutHandle &handle)
dhcp6_srv_configured callout implementation.
Definition: ha_callouts.cc:165
int buffer4_receive(CalloutHandle &handle)
buffer4_receive callout implementation.
Definition: ha_callouts.cc:78
int continue_command(CalloutHandle &handle)
ha-continue command handler implementation.
Definition: ha_callouts.cc:315
int ha_reset_command(CalloutHandle &handle)
ha-reset command handler implementation.
Definition: ha_callouts.cc:367
int maintenance_start_command(CalloutHandle &handle)
ha-maintenance-start command handler implementation.
Definition: ha_callouts.cc:341
int buffer6_receive(CalloutHandle &handle)
buffer6_receive callout implementation.
Definition: ha_callouts.cc:196
int sync_command(CalloutHandle &handle)
ha-sync command handler implementation.
Definition: ha_callouts.cc:289
int load(LibraryHandle &handle)
This function is called when the library is loaded.
Definition: ha_callouts.cc:395
#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:237
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
Definition: ha_messages.h:121
const isc::log::MessageID HA_SUBNET6_SELECT_FAILED
Definition: ha_messages.h:113
HAImplPtr impl
Definition: ha_callouts.cc:29
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
Definition: ha_messages.h:107
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
Definition: ha_messages.h:123
const isc::log::MessageID HA_SCOPES_HANDLER_FAILED
Definition: ha_messages.h:101
Defines the logger used by the top-level component of kea-lfc.