Coverage Report

Created: 2026-02-14 07:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}