Kea  2.5.2
ha_callouts.cc
Go to the documentation of this file.
1 // Copyright (C) 2017-2023 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 #include <sstream>
24 #include <string>
25 
26 namespace isc {
27 namespace ha {
28 
30 
31 } // end of namespace isc::ha
32 } // end of namespace isc
33 
34 using namespace isc::config;
35 using namespace isc::data;
36 using namespace isc::dhcp;
37 using namespace isc::ha;
38 using namespace isc::hooks;
39 using namespace isc::process;
40 using namespace std;
41 
42 extern "C" {
43 
48  try {
49  isc::asiolink::IOServicePtr io_service;
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->startService(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 
79  CalloutHandle::CalloutNextStep status = handle.getStatus();
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 
100  CalloutHandle::CalloutNextStep status = handle.getStatus();
101  if (status == CalloutHandle::NEXT_STEP_DROP ||
102  status == CalloutHandle::NEXT_STEP_SKIP) {
103  return (0);
104  }
105 
106  try {
107  impl->leases4Committed(handle);
108 
109  } catch (const std::exception& ex) {
111  .arg(ex.what());
112  return (1);
113  }
114 
115  return (0);
116 }
117 
122  try {
123  isc::asiolink::IOServicePtr io_service;
124  handle.getArgument("io_context", io_service);
125  if (!io_service) {
126  // Should not happen!
128  const string error("Error: io_context is null");
129  handle.setArgument("error", error);
130  return (1);
131  }
132  isc::dhcp::NetworkStatePtr network_state;
133  handle.getArgument("network_state", network_state);
134  impl->startService(io_service, network_state, HAServerType::DHCPv6);
135 
136  } catch (const std::exception& ex) {
138  .arg(ex.what());
140  ostringstream os;
141  os << "Error: " << ex.what();
142  string error(os.str());
143  handle.setArgument("error", error);
144  return (1);
145  }
146  return (0);
147 }
148 
153  CalloutHandle::CalloutNextStep status = handle.getStatus();
154  if (status == CalloutHandle::NEXT_STEP_DROP ||
155  status == CalloutHandle::NEXT_STEP_SKIP) {
156  return (0);
157  }
158 
159  try {
160  impl->buffer6Receive(handle);
161 
162  } catch (const std::exception& ex) {
164  .arg(ex.what());
165  return (1);
166  }
167 
168  return (0);
169 }
170 
175  CalloutHandle::CalloutNextStep status = handle.getStatus();
176  if (status == CalloutHandle::NEXT_STEP_DROP ||
177  status == CalloutHandle::NEXT_STEP_SKIP) {
178  return (0);
179  }
180 
181  try {
182  impl->leases6Committed(handle);
183 
184  } catch (const std::exception& ex) {
186  .arg(ex.what());
187  return (1);
188  }
189 
190  return (0);
191 }
192 
197  try {
198  impl->commandProcessed(handle);
199 
200  } catch (const std::exception& ex) {
202  .arg(ex.what());
203  return (1);
204  }
205 
206  return (0);
207 }
208 
211  try {
212  impl->heartbeatHandler(handle);
213 
214  } catch (const std::exception& ex) {
216  .arg(ex.what());
217  return (1);
218  }
219 
220  return (0);
221 }
222 
225  try {
226  impl->synchronizeHandler(handle);
227 
228  } catch (const std::exception& ex) {
230  .arg(ex.what());
231  }
232 
233  return (0);
234 }
235 
238  try {
239  impl->scopesHandler(handle);
240 
241  } catch (const std::exception& ex) {
243  .arg(ex.what());
244  }
245 
246  return (0);
247 }
248 
251  try {
252  impl->continueHandler(handle);
253 
254  } catch (const std::exception& ex) {
256  .arg(ex.what());
257  }
258 
259  return (0);
260 }
261 
264  try {
265  impl->maintenanceNotifyHandler(handle);
266 
267  } catch (const std::exception& ex) {
269  .arg(ex.what());
270  }
271 
272  return (0);
273 }
274 
277  try {
278  impl->maintenanceStartHandler(handle);
279 
280  } catch (const std::exception& ex) {
282  .arg(ex.what());
283  }
284 
285  return (0);
286 }
287 
290  try {
291  impl->maintenanceCancelHandler(handle);
292 
293  } catch (const std::exception& ex) {
295  .arg(ex.what());
296  }
297 
298  return (0);
299 }
300 
303  try {
304  impl->haResetHandler(handle);
305 
306  } catch (const std::exception& ex) {
308  .arg(ex.what());
309  }
310 
311  return (0);
312 }
313 
316  try {
317  impl->syncCompleteNotifyHandler(handle);
318  } catch (const std::exception& ex) {
320  .arg(ex.what());
321  }
322 
323  return (0);
324 }
325 
330 int load(LibraryHandle& handle) {
331  ConstElementPtr config = handle.getParameter("high-availability");
332  if (!config) {
334  return (1);
335  }
336 
337  try {
338  // Make the hook library not loadable by d2 or ca.
339  uint16_t family = CfgMgr::instance().getFamily();
340  const std::string& proc_name = Daemon::getProcName();
341  if (family == AF_INET) {
342  if (proc_name != "kea-dhcp4") {
343  isc_throw(isc::Unexpected, "Bad process name: " << proc_name
344  << ", expected kea-dhcp4");
345  }
346  } else {
347  if (proc_name != "kea-dhcp6") {
348  isc_throw(isc::Unexpected, "Bad process name: " << proc_name
349  << ", expected kea-dhcp6");
350  }
351  }
352 
353  impl = boost::make_shared<HAImpl>();
354  impl->configure(config);
355 
356  handle.registerCommandCallout("ha-heartbeat", heartbeat_command);
357  handle.registerCommandCallout("ha-sync", sync_command);
358  handle.registerCommandCallout("ha-scopes", scopes_command);
359  handle.registerCommandCallout("ha-continue", continue_command);
360  handle.registerCommandCallout("ha-maintenance-notify", maintenance_notify_command);
361  handle.registerCommandCallout("ha-maintenance-start", maintenance_start_command);
362  handle.registerCommandCallout("ha-maintenance-cancel", maintenance_cancel_command);
363  handle.registerCommandCallout("ha-reset", ha_reset_command);
364  handle.registerCommandCallout("ha-sync-complete-notify", sync_complete_notify_command);
365 
366  } catch (const std::exception& ex) {
368  .arg(ex.what());
369  return (CONTROL_RESULT_ERROR);
370  }
371 
373  return (0);
374 }
375 
379 int unload() {
380  impl.reset();
382  return (0);
383 }
384 
389  return (1);
390 }
391 
392 } // end extern "C"
A generic exception that is thrown when an unexpected error condition occurs.
Per-packet callout handle.
CalloutNextStep
Specifies allowed next steps.
@ 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.
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 maintenance_cancel_command(CalloutHandle &handle)
ha-maintenance-cancel command handler implementation.
Definition: ha_callouts.cc:289
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:174
int sync_complete_notify_command(CalloutHandle &handle)
ha-sync-complete-notify command handler implementation.
Definition: ha_callouts.cc:315
int scopes_command(CalloutHandle &handle)
ha-scopes command handler implementation.
Definition: ha_callouts.cc:237
int heartbeat_command(CalloutHandle &handle)
Heartbeat command handler implementation.
Definition: ha_callouts.cc:210
int command_processed(CalloutHandle &handle)
command_processed callout implementation.
Definition: ha_callouts.cc:196
int leases4_committed(CalloutHandle &handle)
leases4_committed callout implementation.
Definition: ha_callouts.cc:99
int multi_threading_compatible()
This function is called to retrieve the multi-threading compatibility.
Definition: ha_callouts.cc:388
int maintenance_notify_command(CalloutHandle &handle)
ha-maintenance-notify command handler implementation.
Definition: ha_callouts.cc:263
int unload()
This function is called when the library is unloaded.
Definition: ha_callouts.cc:379
int dhcp6_srv_configured(CalloutHandle &handle)
dhcp6_srv_configured callout implementation.
Definition: ha_callouts.cc:121
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:250
int ha_reset_command(CalloutHandle &handle)
ha-reset command handler implementation.
Definition: ha_callouts.cc:302
int maintenance_start_command(CalloutHandle &handle)
ha-maintenance-start command handler implementation.
Definition: ha_callouts.cc:276
int buffer6_receive(CalloutHandle &handle)
buffer6_receive callout implementation.
Definition: ha_callouts.cc:152
int sync_command(CalloutHandle &handle)
ha-sync command handler implementation.
Definition: ha_callouts.cc:224
int load(LibraryHandle &handle)
This function is called when the library is loaded.
Definition: ha_callouts.cc:330
#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:116
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:183
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:53
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:80
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:95
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:89
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:105
HAImplPtr impl
Definition: ha_callouts.cc:29
const isc::log::MessageID HA_INIT_OK
Definition: ha_messages.h:49
const isc::log::MessageID HA_MISSING_CONFIGURATION
Definition: ha_messages.h:90
const isc::log::MessageID HA_LEASES6_COMMITTED_FAILED
Definition: ha_messages.h:55
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:85
const isc::log::MessageID HA_SYNC_HANDLER_FAILED
Definition: ha_messages.h:107
const isc::log::MessageID HA_SCOPES_HANDLER_FAILED
Definition: ha_messages.h:97
Defines the logger used by the top-level component of kea-lfc.