Kea 3.0.0
flex_id/load_unload.cc
Go to the documentation of this file.
1// Copyright (C) 2017-2025 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
8
9#include <config.h>
10
11#include <cc/data.h>
12#include <dhcp/option.h>
13#include <dhcpsrv/cfgmgr.h>
14#include <eval/token.h>
15#include <eval/eval_context.h>
16#include <hooks/hooks.h>
17#include <process/daemon.h>
18#include <flex_id.h>
19#include <flex_id_log.h>
20
21using namespace isc;
22using namespace hooks;
23using namespace flex_id;
24using namespace isc::data;
25using namespace isc::dhcp;
26using namespace isc::process;
27
28namespace { // anonymous namespace.
29
34bool checkExpression(bool v6, const std::string& expr) {
35 try {
36 EvalContext eval_ctx(v6 ? Option::V6 : Option::V4);
37 eval_ctx.parseString(expr, EvalContext::PARSER_STRING);
38 return (true);
39 } catch (const std::exception& ex) {
41 .arg(expr)
42 .arg(ex.what());
43 return (false);
44 }
45}
46
47} // end of anonymous namespace.
48
49// Functions accessed by the hooks framework use C linkage to avoid the name
50// mangling that accompanies use of the C++ compiler as well as to avoid
51// issues related to namespaces.
52extern "C" {
53
60int load(LibraryHandle& handle) {
61 // non-zero indicates an error.
62 int ret_val = 0;
63
64 try {
65 // Make the hook library not loadable by d2 or ca.
66 bool v6 = (CfgMgr::instance().getFamily() == AF_INET6);
67 const std::string& proc_name = Daemon::getProcName();
68 const std::string& expected_proc_name =
69 (v6 ? "kea-dhcp6" : "kea-dhcp4");
70 if (proc_name != expected_proc_name) {
71 isc_throw(Unexpected, "Bad process name: " << proc_name
72 << ", expected " << expected_proc_name);
73 }
74
75 // identifier-expression is mandatory
76 data::ConstElementPtr param = handle.getParameter("identifier-expression");
77 if (!param) {
79 return (1);
80 }
81
82 // It must be a string...
83 if (param->getType() != Element::string) {
85 .arg(Element::typeToName(param->getType()));
86 return (1);
87 }
88
89 // ... and shouldn't be empty.
90 std::string expr = param->stringValue();
91 if (expr.empty()) {
92 // Ok, we can continue without the expression, but it's just useless
93 // to have this lib loaded. Nevertheless, there may be cases when
94 // user temporarily changes the expression to empty string to
95 // troubleshoot something.
97 } else if (!checkExpression(v6, expr)) {
98 // The error was logged.
99 return (1);
100 }
101
102 // replace-client-id indicates if flexible identifier should be used to
103 // replace original client identifier (or DUID) within the client query.
104 bool replace_client_id = false;
105 data::ConstElementPtr param_replace = handle.getParameter("replace-client-id");
106 if (param_replace) {
107 // It must be a boolean value.
108 if (param_replace->getType() != Element::boolean) {
110 .arg(Element::typeToName(param_replace->getType()));
111 return (1);
112 }
113
114 replace_client_id = param_replace->boolValue();
115 }
116
117 // ignore-iaid indicates if iaid should be ignored.
118 bool ignore_iaid = false;
119 if (v6) {
120 data::ConstElementPtr param_ignore = handle.getParameter("ignore-iaid");
121 if (param_ignore) {
122 // It must be a boolean value.
123 if (param_ignore->getType() != Element::boolean) {
125 .arg(Element::typeToName(param_ignore->getType()));
126 return (1);
127 }
128
129 ignore_iaid = param_ignore->boolValue();
130 }
131 }
132
133 // Remove any old expressions that may have been stored.
135
136 // Store specified expression.
137 storeConfiguration(v6, expr, replace_client_id, ignore_iaid);
138
139 if (ignore_iaid) {
141 }
142 } catch (const std::exception& ex) {
143 // Log the error and return failure.
145 .arg(ex.what());
146 ret_val = 1;
147 }
148
149 return (ret_val);
150}
151
155int unload() {
157 return (0);
158}
159
164 return (1);
165}
166
167}
static std::string typeToName(Element::types type)
Returns the name of the given type as a string.
Definition data.cc:651
@ boolean
Definition data.h:142
@ string
Definition data.h:144
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
Evaluation context, an interface to the expression evaluation.
@ PARSER_STRING
expression is expected to evaluate to string
isc::data::ConstElementPtr getParameter(const std::string &name)
Returns configuration parameter for the library.
static std::string getProcName()
returns the process name This value is used as when forming the default PID file name
Definition daemon.cc:151
#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 unload()
Called by the Hooks library manager when the library is unloaded.
int load(LibraryHandle &handle)
Called by the Hooks library manager when the library is loaded.
const isc::log::MessageID FLEX_ID_IGNORE_IAID_JSON_TYPE
const isc::log::MessageID FLEX_ID_UNLOAD
const isc::log::MessageID FLEX_ID_EXPRESSION_PARSE_FAILED
const isc::log::MessageID FLEX_ID_EXPRESSION_NOT_DEFINED
const isc::log::MessageID FLEX_ID_IGNORE_IAID_ENABLED
const isc::log::MessageID FLEX_ID_LOAD_ERROR
const isc::log::MessageID FLEX_ID_EXPRESSION_EMPTY
const isc::log::MessageID FLEX_ID_REPLACE_CLIENT_ID_JSON_TYPE
const isc::log::MessageID FLEX_ID_EXPRESSION_INVALID_JSON_TYPE
#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
#define LOG_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
Definition macros.h:26
boost::shared_ptr< const Element > ConstElementPtr
Definition data.h:29
isc::log::Logger flex_id_logger("flex-id-hooks")
Flexible Identifier Logger.
Definition flex_id_log.h:22
void clearConfiguration()
Clears stored configuration.
Definition callouts.cc:74
void storeConfiguration(bool v6, const std::string &expr, const bool apply_to_leases, const bool ignore_iaid)
Stores expression.
Definition callouts.cc:64
Defines the logger used by the top-level component of kea-lfc.