Kea  2.3.4-git
ha_callouts.cc
Go to the documentation of this file.
1 // Copyright (C) 2017-2021 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>
16 #include <cc/command_interpreter.h>
17 #include <dhcpsrv/cfgmgr.h>
18 #include <dhcpsrv/network_state.h>
19 #include <exceptions/exceptions.h>
20 #include <hooks/hooks.h>
21 #include <process/daemon.h>
22 
23 namespace isc {
24 namespace ha {
25 
27 
28 } // end of namespace isc::ha
29 } // end of namespace isc
30 
31 using namespace isc::config;
32 using namespace isc::data;
33 using namespace isc::dhcp;
34 using namespace isc::ha;
35 using namespace isc::hooks;
36 using namespace isc::process;
37 
38 extern "C" {
39 
44  try {
45  isc::asiolink::IOServicePtr io_service;
46  handle.getArgument("io_context", io_service);
47  isc::dhcp::NetworkStatePtr network_state;
48  handle.getArgument("network_state", network_state);
49  impl->startService(io_service, network_state, HAServerType::DHCPv4);
50 
51  } catch (const std::exception& ex) {
53  .arg(ex.what());
54  return (1);
55  }
56  return (0);
57 }
58 
63  CalloutHandle::CalloutNextStep status = handle.getStatus();
64  if (status == CalloutHandle::NEXT_STEP_DROP) {
65  return (0);
66  }
67 
68  try {
69  impl->buffer4Receive(handle);
70 
71  } catch (const std::exception& ex) {
73  .arg(ex.what());
74  return (1);
75  }
76 
77  return (0);
78 }
79 
84  CalloutHandle::CalloutNextStep status = handle.getStatus();
85  if (status == CalloutHandle::NEXT_STEP_DROP ||
86  status == CalloutHandle::NEXT_STEP_SKIP) {
87  return (0);
88  }
89 
90  try {
91  impl->leases4Committed(handle);
92 
93  } catch (const std::exception& ex) {
95  .arg(ex.what());
96  return (1);
97  }
98 
99  return (0);
100 }
101 
106  try {
107  isc::asiolink::IOServicePtr io_service;
108  handle.getArgument("io_context", io_service);
109  isc::dhcp::NetworkStatePtr network_state;
110  handle.getArgument("network_state", network_state);
111  impl->startService(io_service, network_state, HAServerType::DHCPv6);
112 
113  } catch (const std::exception& ex) {
115  .arg(ex.what());
116  return (1);
117  }
118  return (0);
119 }
120 
125  CalloutHandle::CalloutNextStep status = handle.getStatus();
126  if (status == CalloutHandle::NEXT_STEP_DROP ||
127  status == CalloutHandle::NEXT_STEP_SKIP) {
128  return (0);
129  }
130 
131  try {
132  impl->buffer6Receive(handle);
133 
134  } catch (const std::exception& ex) {
136  .arg(ex.what());
137  return (1);
138  }
139 
140  return (0);
141 }
142 
147  CalloutHandle::CalloutNextStep status = handle.getStatus();
148  if (status == CalloutHandle::NEXT_STEP_DROP ||
149  status == CalloutHandle::NEXT_STEP_SKIP) {
150  return (0);
151  }
152 
153  try {
154  impl->leases6Committed(handle);
155 
156  } catch (const std::exception& ex) {
158  .arg(ex.what());
159  return (1);
160  }
161 
162  return (0);
163 }
164 
169  try {
170  impl->commandProcessed(handle);
171 
172  } catch (const std::exception& ex) {
174  .arg(ex.what());
175  return (1);
176  }
177 
178  return (0);
179 }
180 
183  try {
184  impl->heartbeatHandler(handle);
185 
186  } catch (const std::exception& ex) {
188  .arg(ex.what());
189  return (1);
190  }
191 
192  return (0);
193 }
194 
197  try {
198  impl->synchronizeHandler(handle);
199 
200  } catch (const std::exception& ex) {
202  .arg(ex.what());
203  }
204 
205  return (0);
206 }
207 
210  try {
211  impl->scopesHandler(handle);
212 
213  } catch (const std::exception& ex) {
215  .arg(ex.what());
216  }
217 
218  return (0);
219 }
220 
223  try {
224  impl->continueHandler(handle);
225 
226  } catch (const std::exception& ex) {
228  .arg(ex.what());
229  }
230 
231  return (0);
232 }
233 
236  try {
237  impl->maintenanceNotifyHandler(handle);
238 
239  } catch (const std::exception& ex) {
241  .arg(ex.what());
242  }
243 
244  return (0);
245 }
246 
249  try {
250  impl->maintenanceStartHandler(handle);
251 
252  } catch (const std::exception& ex) {
254  .arg(ex.what());
255  }
256 
257  return (0);
258 }
259 
262  try {
263  impl->maintenanceCancelHandler(handle);
264 
265  } catch (const std::exception& ex) {
267  .arg(ex.what());
268  }
269 
270  return (0);
271 }
272 
275  try {
276  impl->haResetHandler(handle);
277 
278  } catch (const std::exception& ex) {
280  .arg(ex.what());
281  }
282 
283  return (0);
284 }
285 
288  try {
289  impl->syncCompleteNotifyHandler(handle);
290  } catch (const std::exception& ex) {
292  .arg(ex.what());
293  }
294 
295  return (0);
296 }
297 
302 int load(LibraryHandle& handle) {
303  ConstElementPtr config = handle.getParameter("high-availability");
304  if (!config) {
306  return (1);
307  }
308 
309  try {
310  // Make the hook library not loadable by d2 or ca.
311  uint16_t family = CfgMgr::instance().getFamily();
312  const std::string& proc_name = Daemon::getProcName();
313  if (family == AF_INET) {
314  if (proc_name != "kea-dhcp4") {
315  isc_throw(isc::Unexpected, "Bad process name: " << proc_name
316  << ", expected kea-dhcp4");
317  }
318  } else {
319  if (proc_name != "kea-dhcp6") {
320  isc_throw(isc::Unexpected, "Bad process name: " << proc_name
321  << ", expected kea-dhcp6");
322  }
323  }
324 
325  impl = boost::make_shared<HAImpl>();
326  impl->configure(config);
327 
328  handle.registerCommandCallout("ha-heartbeat", heartbeat_command);
329  handle.registerCommandCallout("ha-sync", sync_command);
330  handle.registerCommandCallout("ha-scopes", scopes_command);
331  handle.registerCommandCallout("ha-continue", continue_command);
332  handle.registerCommandCallout("ha-maintenance-notify", maintenance_notify_command);
333  handle.registerCommandCallout("ha-maintenance-start", maintenance_start_command);
334  handle.registerCommandCallout("ha-maintenance-cancel", maintenance_cancel_command);
335  handle.registerCommandCallout("ha-reset", ha_reset_command);
336  handle.registerCommandCallout("ha-sync-complete-notify", sync_complete_notify_command);
337 
338  } catch (const std::exception& ex) {
340  .arg(ex.what());
341  return (CONTROL_RESULT_ERROR);
342  }
343 
345  return (0);
346 }
347 
351 int unload() {
352  impl.reset();
354  return (0);
355 }
356 
361  return (1);
362 }
363 
364 } // end extern "C"
const isc::log::MessageID HA_SYNC_COMPLETE_NOTIFY_HANDLER_FAILED
Definition: ha_messages.h:105
int buffer4_receive(CalloutHandle &handle)
buffer4_receive callout implementation.
Definition: ha_callouts.cc:62
int sync_complete_notify_command(CalloutHandle &handle)
ha-sync-complete-notify command handler implementation.
Definition: ha_callouts.cc:287
int maintenance_notify_command(CalloutHandle &handle)
ha-maintenance-notify command handler implementation.
Definition: ha_callouts.cc:235
int continue_command(CalloutHandle &handle)
ha-continue command handler implementation.
Definition: ha_callouts.cc:222
const isc::log::MessageID HA_BUFFER6_RECEIVE_FAILED
Definition: ha_messages.h:15
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
Definition: macros.h:20
const isc::log::MessageID HA_CONTINUE_HANDLER_FAILED
Definition: ha_messages.h:36
const isc::log::MessageID HA_COMMAND_PROCESSED_FAILED
Definition: ha_messages.h:19
boost::shared_ptr< HAImpl > HAImplPtr
Pointer to the High Availability hooks library implementation.
Definition: ha_impl.h:183
int load(LibraryHandle &handle)
This function is called when the library is loaded.
Definition: ha_callouts.cc:302
CalloutNextStep getStatus() const
Returns the next processing step.
const isc::log::MessageID HA_CONFIGURATION_FAILED
Definition: ha_messages.h:25
const isc::log::MessageID HA_LEASES6_COMMITTED_FAILED
Definition: ha_messages.h:55
const isc::log::MessageID HA_SYNC_HANDLER_FAILED
Definition: ha_messages.h:107
int unload()
This function is called when the library is unloaded.
Definition: ha_callouts.cc:351
#define LOG_ERROR(LOGGER, MESSAGE)
Macro to conveniently test error output and log it.
Definition: macros.h:32
const int CONTROL_RESULT_ERROR
Status code indicating a general failure.
const isc::log::MessageID HA_HEARTBEAT_HANDLER_FAILED
Definition: ha_messages.h:46
void registerCommandCallout(const std::string &command_name, CalloutPtr callout)
Register control command handler.
int scopes_command(CalloutHandle &handle)
ha-scopes command handler implementation.
Definition: ha_callouts.cc:209
int maintenance_start_command(CalloutHandle &handle)
ha-maintenance-start command handler implementation.
Definition: ha_callouts.cc:248
int ha_reset_command(CalloutHandle &handle)
ha-reset command handler implementation.
Definition: ha_callouts.cc:274
int buffer6_receive(CalloutHandle &handle)
buffer6_receive callout implementation.
Definition: ha_callouts.cc:124
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
int heartbeat_command(CalloutHandle &handle)
Heartbeat command handler implementation.
Definition: ha_callouts.cc:182
const isc::log::MessageID HA_DEINIT_OK
Definition: ha_messages.h:37
int leases4_committed(CalloutHandle &handle)
leases4_committed callout implementation.
Definition: ha_callouts.cc:83
Per-packet callout handle.
const isc::log::MessageID HA_INIT_OK
Definition: ha_messages.h:49
A generic exception that is thrown when an unexpected error condition occurs.
int dhcp6_srv_configured(CalloutHandle &handle)
dhcp6_srv_configured callout implementation.
Definition: ha_callouts.cc:105
const isc::log::MessageID HA_DHCP4_START_SERVICE_FAILED
Definition: ha_messages.h:38
CalloutNextStep
Specifies allowed next steps.
boost::shared_ptr< const Element > ConstElementPtr
Definition: data.h:27
HAImplPtr impl
Definition: ha_callouts.cc:26
const isc::log::MessageID HA_SCOPES_HANDLER_FAILED
Definition: ha_messages.h:97
int dhcp4_srv_configured(CalloutHandle &handle)
dhcp4_srv_configured callout implementation.
Definition: ha_callouts.cc:43
const isc::log::MessageID HA_BUFFER4_RECEIVE_FAILED
Definition: ha_messages.h:11
Defines the logger used by the top-level component of kea-lfc.
const isc::log::MessageID HA_MAINTENANCE_NOTIFY_HANDLER_FAILED
Definition: ha_messages.h:85
const isc::log::MessageID HA_MAINTENANCE_CANCEL_HANDLER_FAILED
Definition: ha_messages.h:80
const isc::log::MessageID HA_MAINTENANCE_START_HANDLER_FAILED
Definition: ha_messages.h:89
int maintenance_cancel_command(CalloutHandle &handle)
ha-maintenance-cancel command handler implementation.
Definition: ha_callouts.cc:261
void getArgument(const std::string &name, T &value) const
Get argument.
This file contains several functions and constants that are used for handling commands and responses ...
int leases6_committed(CalloutHandle &handle)
leases6_committed callout implementation.
Definition: ha_callouts.cc:146
int multi_threading_compatible()
This function is called to retrieve the multi-threading compatibility.
Definition: ha_callouts.cc:360
isc::data::ConstElementPtr getParameter(const std::string &name)
Returns configuration parameter for the library.
boost::shared_ptr< NetworkState > NetworkStatePtr
Pointer to the NetworkState object.
const isc::log::MessageID HA_LEASES4_COMMITTED_FAILED
Definition: ha_messages.h:53
isc::log::Logger ha_logger("ha-hooks")
Definition: ha_log.h:17
const isc::log::MessageID HA_MISSING_CONFIGURATION
Definition: ha_messages.h:90
const isc::log::MessageID HA_RESET_HANDLER_FAILED
Definition: ha_messages.h:95
int command_processed(CalloutHandle &handle)
command_processed callout implementation.
Definition: ha_callouts.cc:168
int sync_command(CalloutHandle &handle)
ha-sync command handler implementation.
Definition: ha_callouts.cc:196
const isc::log::MessageID HA_DHCP6_START_SERVICE_FAILED
Definition: ha_messages.h:39