/src/kea/src/lib/hooks/hooks_config.cc
Line | Count | Source |
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 | | |
7 | | #include <config.h> |
8 | | |
9 | | #include <hooks/hooks_config.h> |
10 | | #include <hooks/hooks_manager.h> |
11 | | |
12 | | using namespace std; |
13 | | using namespace isc; |
14 | | using namespace isc::data; |
15 | | |
16 | | namespace isc { |
17 | | namespace hooks { |
18 | | |
19 | | void |
20 | | HooksConfig::add(const std::string& libname, |
21 | | isc::data::ConstElementPtr parameters, |
22 | 4.86k | const std::string& cfgname /* = "" */) { |
23 | 4.86k | HookLibInfo info(libname, parameters, cfgname); |
24 | 4.86k | libraries_.push_back(info); |
25 | 4.86k | } |
26 | | |
27 | | void |
28 | | HooksConfig::verifyLibraries(const Element::Position& position, |
29 | 291 | bool multi_threading_enabled) const { |
30 | | // The code used to follow this logic: |
31 | | // |
32 | | // Check if the list of libraries has changed. If not, nothing is done. |
33 | | // |
34 | | // We no longer rely on this. Parameters can change. And even if the |
35 | | // parameters stay the same, they could point to files that could |
36 | | // change. We can skip loading routines only if there were and there still |
37 | | // are no libraries specified. |
38 | 291 | vector<string> current_libraries = HooksManager::getLibraryNames(); |
39 | 291 | if (current_libraries.empty() && libraries_.empty()) { |
40 | 17 | return; |
41 | 17 | } |
42 | | |
43 | | // Library list has changed, validate each of the libraries specified. |
44 | 274 | vector<string> lib_names = isc::hooks::extractNames(libraries_); |
45 | 274 | vector<string> error_libs = HooksManager::validateLibraries(lib_names, |
46 | 274 | multi_threading_enabled); |
47 | 274 | if (!error_libs.empty()) { |
48 | | |
49 | | // Construct the list of libraries in error for the message. |
50 | 0 | string error_list = error_libs[0]; |
51 | 0 | for (size_t i = 1; i < error_libs.size(); ++i) { |
52 | 0 | error_list += (string(", ") + error_libs[i]); |
53 | 0 | } |
54 | 0 | isc_throw(InvalidHooksLibraries, |
55 | 0 | "hooks libraries failed to validate - " |
56 | 0 | "library or libraries in error are: " |
57 | 0 | << error_list << " (" << position << ")"); |
58 | 0 | } |
59 | 274 | } |
60 | | |
61 | | void |
62 | 22.8k | HooksConfig::loadLibraries(bool multi_threading_enabled) const { |
63 | | /// Commits the list of libraries to the configuration manager storage if |
64 | | /// the list of libraries has changed. |
65 | | /// @todo: Delete any stored CalloutHandles before reloading the |
66 | | /// libraries |
67 | 22.8k | if (!HooksManager::loadLibraries(libraries_, multi_threading_enabled)) { |
68 | 0 | isc_throw(InvalidHooksLibraries, |
69 | 0 | "One or more hook libraries failed to load"); |
70 | 0 | } |
71 | 22.8k | } |
72 | | |
73 | | bool |
74 | 0 | HooksConfig::equal(const HooksConfig& other) const { |
75 | | |
76 | | /// @todo: This comparision assumes that the library order is not relevant, |
77 | | /// so [ lib1, lib2 ] is equal to [ lib2, lib1 ]. However, this is not strictly |
78 | | /// true, because callouts execution is called in other they're loaded. Therefore |
79 | | /// changing the libraries order may change the server behavior. |
80 | | /// |
81 | | /// We don't have any libraries that are interacting (or would change their behavior |
82 | | /// depending on the order in which their callouts are executed), so the code is |
83 | | /// ok for now. |
84 | 0 | for (auto const& this_it : libraries_) { |
85 | 0 | bool match = false; |
86 | 0 | for (auto const& other_it : other.libraries_) { |
87 | 0 | if (this_it == other_it) { |
88 | 0 | match = true; |
89 | 0 | break; |
90 | 0 | } |
91 | 0 | } |
92 | | |
93 | | // No match found for the particular hooks library so return false. |
94 | 0 | if (!match) { |
95 | 0 | return(false); |
96 | 0 | } |
97 | 0 | } |
98 | | |
99 | 0 | return (true); |
100 | 0 | } |
101 | | |
102 | | ElementPtr |
103 | 20.8k | HooksConfig::toElement() const { |
104 | | // hooks-libraries is a list of maps |
105 | 20.8k | ElementPtr result = Element::createList(); |
106 | | // Iterate through libraries |
107 | 20.8k | for (auto const& hl : libraries_) { |
108 | | // Entries are maps |
109 | 0 | ElementPtr map = Element::createMap(); |
110 | | // Set the library name |
111 | 0 | map->set("library", Element::create(hl.cfgname_)); |
112 | | // Set parameters (not set vs set empty map) |
113 | 0 | if (!isNull(hl.parameters_)) { |
114 | 0 | map->set("parameters", hl.parameters_); |
115 | 0 | } |
116 | | // Push to the list |
117 | 0 | result->add(map); |
118 | 0 | } |
119 | 20.8k | return (result); |
120 | 20.8k | } |
121 | | |
122 | | } |
123 | | } |