summaryrefslogtreecommitdiffstats
path: root/src/lib/hooks/library_handle.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/hooks/library_handle.h')
-rw-r--r--src/lib/hooks/library_handle.h242
1 files changed, 242 insertions, 0 deletions
diff --git a/src/lib/hooks/library_handle.h b/src/lib/hooks/library_handle.h
new file mode 100644
index 0000000..14af40c
--- /dev/null
+++ b/src/lib/hooks/library_handle.h
@@ -0,0 +1,242 @@
+// Copyright (C) 2013-2020 Internet Systems Consortium, Inc. ("ISC")
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef LIBRARY_HANDLE_H
+#define LIBRARY_HANDLE_H
+
+#include <string>
+#include <cc/data.h>
+
+namespace isc {
+namespace hooks {
+
+// Forward declarations
+class CalloutHandle;
+class CalloutManager;
+
+/// Typedef for a callout pointer. (Callouts must have "C" linkage.)
+extern "C" {
+ typedef int (*CalloutPtr)(CalloutHandle&);
+};
+
+/// @brief Library handle
+///
+/// This class is accessed by the user library when registering callouts,
+/// either by the library's load() function, or by one of the callouts
+/// themselves.
+///
+/// It is really little more than a shell around the CalloutManager. By
+/// presenting this object to the user-library callouts, callouts can manage
+/// the callout list for their own library, but cannot affect the callouts
+/// registered by other libraries.
+///
+/// (This restriction is achieved by the CalloutManager maintaining the concept
+/// of the "current library". When a callout is registered - either by the
+/// library's load() function, or by a callout in the library - the registration
+/// information includes the library active at the time. When that callout is
+/// called, the CalloutManager uses that information to set the "current
+/// library": the registration functions only operator on data whose
+/// associated library is equal to the "current library".)
+///
+/// As of Kea 1.3.0 release, the @ref LibraryHandle can be used by the hook
+/// libraries to install control command handlers and dynamically register
+/// hook points with which the handlers are associated. For example, if the
+/// hook library supports control-command 'foo-bar' it should register its
+/// handler similarly to this:
+/// @code
+/// int load(LibraryHandle& libhandle) {
+/// libhandle.registerCommandCallout("foo-bar", foo_bar_handler);
+/// return (0);
+/// }
+/// @endcode
+///
+/// which will result in automatic creation of the hook point for the command
+/// (if one doesn't exist) and associating the callout 'foo_bar_handler' with
+/// this hook point as a handler for the command.
+
+class LibraryHandle {
+public:
+
+ /// @brief Constructor
+ ///
+ /// @param manager Back reference to the containing CalloutManager.
+ /// This reference is used to access appropriate methods in that
+ /// object. Note that the reference is safe - the only instance
+ /// of the LibraryHandle in the system is as a member of the
+ /// CalloutManager to which it points.
+ ///
+ /// @param index Index of the library to which the LibraryHandle applies.
+ /// If negative, the library index as set in the CalloutManager is
+ /// used. Note: although -1 is a valid argument value for
+ /// @ref isc::hooks::CalloutManager::setLibraryIndex(), in this class
+ /// it is used as a sentinel to indicate that the library index in
+ /// @ref isc::hooks::CalloutManager should not be set or reset.
+ LibraryHandle(CalloutManager& manager, int index = -1)
+ : callout_manager_(manager), index_(index) {}
+
+ /// @brief Register a callout on a hook
+ ///
+ /// Registers a callout function with a given hook. The callout is added
+ /// to the end of the callouts for the current library that are associated
+ /// with that hook.
+ ///
+ /// @param name Name of the hook to which the callout is added.
+ /// @param callout Pointer to the callout function to be registered.
+ ///
+ /// @throw NoSuchHook The hook name is unrecognized.
+ /// @throw Unexpected The hook name is valid but an internal data structure
+ /// is of the wrong size.
+ void registerCallout(const std::string& name, CalloutPtr callout);
+
+ /// @brief Register control command handler
+ ///
+ /// Registers control command handler by creating a hook point for this
+ /// command (if it doesn't exist) and associating the callout as a command
+ /// handler. It is possible to register multiple command handlers for the
+ /// same control command because command handlers are implemented as callouts.
+ ///
+ /// @param command_name Command name for which handler should be installed.
+ /// @param callout Pointer to the command handler implemented as a callout.
+ void registerCommandCallout(const std::string& command_name, CalloutPtr callout);
+
+ /// @brief De-Register a callout on a hook
+ ///
+ /// Searches through the functions registered by the current library with
+ /// the named hook and removes all entries matching the callout. It does
+ /// not affect callouts registered by other libraries.
+ ///
+ /// @param name Name of the hook from which the callout is removed.
+ /// @param callout Pointer to the callout function to be removed.
+ ///
+ /// @return true if a one or more callouts were deregistered.
+ ///
+ /// @throw NoSuchHook The hook name is unrecognized.
+ /// @throw Unexpected The hook name is valid but an internal data structure
+ /// is of the wrong size.
+ bool deregisterCallout(const std::string& name, CalloutPtr callout);
+
+ /// @brief Removes all callouts on a hook
+ ///
+ /// Removes all callouts associated with a given hook that were registered.
+ /// by the current library. It does not affect callouts that were
+ /// registered by other libraries.
+ ///
+ /// @param name Name of the hook from which the callouts are removed.
+ ///
+ /// @return true if one or more callouts were deregistered.
+ ///
+ /// @throw NoSuchHook Thrown if the hook name is unrecognized.
+ bool deregisterAllCallouts(const std::string& name);
+
+
+ /// @brief Returns configuration parameter for the library.
+ ///
+ /// This method returns configuration parameters specified in the
+ /// configuration file. Here's the example. Let's assume that there
+ /// are two hook libraries configured:
+ ///
+ /// "hooks-libraries": [
+ /// {
+ /// "library": "/opt/charging.so",
+ /// "parameters": {}
+ /// },
+ /// {
+ /// "library": "/opt/local/notification.so",
+ /// "parameters": {
+ /// "mail": "alarm@example.com",
+ /// "floor": 42,
+ /// "debug": false,
+ /// "users": [ "alice", "bob", "charlie" ],
+ /// "header": {
+ /// "french": "bonjour",
+ /// "klingon": "yl'el"
+ /// }
+ /// }
+ /// }
+ ///]
+ ///
+ /// The first library has no parameters, so regardless of the name
+ /// specified, for that library getParameter will always return NULL.
+ ///
+ /// For the second parameter, depending the following calls will return:
+ /// - x = getParameter("mail") will return instance of
+ /// isc::data::StringElement. The content can be accessed with
+ /// x->stringValue() and will return std::string.
+ /// - x = getParameter("floor") will return an instance of isc::data::IntElement.
+ /// The content can be accessed with x->intValue() and will return int.
+ /// - x = getParameter("debug") will return an instance of isc::data::BoolElement.
+ /// Its value can be accessed with x->boolValue() and will return bool.
+ /// - x = getParameter("users") will return an instance of ListElement.
+ /// Its content can be accessed with the following methods:
+ /// x->size(), x->get(index)
+ /// - x = getParameter("header") will return an instance of isc::data::MapElement.
+ /// Its content can be accessed with the following methods:
+ /// x->find("klingon"), x->contains("french"), x->size()
+ ///
+ /// For more examples and complete API, see documentation for
+ /// @ref isc::data::Element class and its derivatives:
+ /// - @ref isc::data::IntElement
+ /// - @ref isc::data::DoubleElement
+ /// - @ref isc::data::BoolElement
+ /// - @ref isc::data::StringElement
+ /// - @ref isc::data::ListElement
+ /// - @ref isc::data::MapElement
+ ///
+ /// Another good way to learn how to use Element interface is to look at the
+ /// unittests in data_unittests.cc.
+ ///
+ /// @param name text name of the parameter.
+ /// @return ElementPtr representing requested parameter (may be null, if
+ /// there is no such parameter.)
+ isc::data::ConstElementPtr
+ getParameter(const std::string& name);
+
+ /// @brief Get configuration parameter common code.
+ ///
+ /// @return configuration parameters.
+ isc::data::ConstElementPtr getParameters();
+
+ /// @brief Returns names of configuration parameters for the library.
+ ///
+ /// This method returns a vector of strings reflecting names of
+ /// configuration parameters specified in the configuration file.
+ ///
+ /// @note: kept for backward compatibility.
+ /// @return a vector with parameter entry names.
+ std::vector<std::string> getParameterNames();
+
+private:
+ /// @brief Copy constructor
+ ///
+ /// Private (with no implementation) as it makes no sense to copy an object
+ /// of this type. All code receives a reference to an existing handle which
+ /// is tied to a particular CalloutManager. Creating a copy of that handle
+ /// runs the risk of a "dangling pointer" to the original handle's callout
+ /// manager.
+ ///
+ /// @param Unused - should be the object to copy.
+ LibraryHandle(const LibraryHandle&);
+
+ /// @brief Assignment operator
+ ///
+ /// Declared private like the copy constructor for the same reasons. It too
+ /// has no implementation.
+ ///
+ /// @param Unused - should be the object to copy.
+ LibraryHandle& operator=(const LibraryHandle&);
+
+ /// Back pointer to the collection object for the library
+ CalloutManager& callout_manager_;
+
+ /// Library index to which this handle applies. -1 indicates that it
+ /// applies to whatever index is current in the CalloutManager.
+ int index_;
+};
+
+} // namespace util
+} // namespace isc
+
+#endif // LIBRARY_HANDLE_H