Kea  2.3.7
flex_option_callouts.cc
Go to the documentation of this file.
1 // Copyright (C) 2019-2022 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 #include <config.h>
8 
9 #include <flex_option.h>
10 #include <flex_option_log.h>
11 #include <cc/command_interpreter.h>
12 #include <hooks/hooks.h>
13 #include <dhcp/pkt4.h>
14 #include <dhcp/pkt6.h>
15 #include <dhcpsrv/cfgmgr.h>
16 #include <process/daemon.h>
17 
18 namespace isc {
19 namespace flex_option {
20 
22 
23 } // end of namespace flex_option
24 } // end of namespace isc
25 
26 using namespace isc;
27 using namespace isc::data;
28 using namespace isc::dhcp;
29 using namespace isc::flex_option;
30 using namespace isc::hooks;
31 using namespace isc::process;
32 
33 // Functions accessed by the hooks framework use C linkage to avoid the name
34 // mangling that accompanies use of the C++ compiler as well as to avoid
35 // issues related to namespaces.
36 extern "C" {
37 
47 int pkt4_send(CalloutHandle& handle) {
48  CalloutHandle::CalloutNextStep status = handle.getStatus();
49  if (status == CalloutHandle::NEXT_STEP_DROP) {
50  return (0);
51  }
52 
53  // Sanity.
54  if (!impl) {
55  return (0);
56  }
57 
58  // Get the parameters.
59  Pkt4Ptr query;
60  Pkt4Ptr response;
61  handle.getArgument("query4", query);
62  handle.getArgument("response4", response);
63 
64  if (status == CalloutHandle::NEXT_STEP_SKIP) {
65  isc_throw(InvalidOperation, "packet pack already handled");
66  }
67 
68  try {
69  impl->process<Pkt4Ptr>(Option::V4, query, response);
70  } catch (const std::exception& ex) {
72  .arg(query->getLabel())
73  .arg(ex.what());
74  }
75 
76  return (0);
77 }
78 
88 int pkt6_send(CalloutHandle& handle) {
89  CalloutHandle::CalloutNextStep status = handle.getStatus();
90  if (status == CalloutHandle::NEXT_STEP_DROP) {
91  return (0);
92  }
93 
94  // Sanity.
95  if (!impl) {
96  return (0);
97  }
98 
99  if (status == CalloutHandle::NEXT_STEP_SKIP) {
100  isc_throw(InvalidOperation, "packet pack already handled");
101  }
102 
103  // Get the parameters.
104  Pkt6Ptr query;
105  Pkt6Ptr response;
106  handle.getArgument("query6", query);
107  handle.getArgument("response6", response);
108 
109  try {
110  impl->process<Pkt6Ptr>(Option::V6, query, response);
111  } catch (const std::exception& ex) {
113  .arg(query->getLabel())
114  .arg(ex.what());
115  }
116 
117  return (0);
118 }
119 
124 int load(LibraryHandle& handle) {
125  try {
126  // Make the hook library not loadable by d2 or ca.
127  uint16_t family = CfgMgr::instance().getFamily();
128  const std::string& proc_name = Daemon::getProcName();
129  if (family == AF_INET) {
130  if (proc_name != "kea-dhcp4") {
131  isc_throw(isc::Unexpected, "Bad process name: " << proc_name
132  << ", expected kea-dhcp4");
133  }
134  } else {
135  if (proc_name != "kea-dhcp6") {
136  isc_throw(isc::Unexpected, "Bad process name: " << proc_name
137  << ", expected kea-dhcp6");
138  }
139  }
140 
141  impl.reset(new FlexOptionImpl());
142  ConstElementPtr options = handle.getParameter("options");
143  impl->configure(options);
144  } catch (const std::exception& ex) {
146  .arg(ex.what());
147  return (1);
148  }
149 
150  return (0);
151 }
152 
156 int unload() {
157  impl.reset();
159  return (0);
160 }
161 
166  return (1);
167 }
168 
169 } // end extern "C"
A generic exception that is thrown if a function is called in a prohibited way.
A generic exception that is thrown when an unexpected error condition occurs.
Flex Option implementation.
Definition: flex_option.h:37
Per-packet callout handle.
CalloutNextStep
Specifies allowed next steps.
CalloutNextStep getStatus() const
Returns the next processing step.
void getArgument(const std::string &name, T &value) const
Get argument.
isc::data::ConstElementPtr getParameter(const std::string &name)
Returns configuration parameter for the library.
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 multi_threading_compatible()
This function is called to retrieve the multi-threading compatibility.
int pkt6_send(CalloutHandle &handle)
This callout is called at the "pkt6_send" hook.
int pkt4_send(CalloutHandle &handle)
This callout is called at the "pkt4_send" hook.
int unload()
This function is called when the library is unloaded.
int load(LibraryHandle &handle)
This function is called when the library is loaded.
const isc::log::MessageID FLEX_OPTION_PROCESS_ERROR
const isc::log::MessageID FLEX_OPTION_LOAD_ERROR
const isc::log::MessageID FLEX_OPTION_UNLOAD
#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
boost::shared_ptr< const Element > ConstElementPtr
Definition: data.h:27
boost::shared_ptr< Pkt4 > Pkt4Ptr
A pointer to Pkt4 object.
Definition: pkt4.h:547
boost::shared_ptr< Pkt6 > Pkt6Ptr
A pointer to Pkt6 packet.
Definition: pkt6.h:28
FlexOptionImplPtr impl
isc::log::Logger flex_option_logger("flex-option-hooks")
boost::shared_ptr< FlexOptionImpl > FlexOptionImplPtr
The type of shared pointers to Flex Option implementations.
Definition: flex_option.h:645
Defines the logger used by the top-level component of kea-lfc.