diff --git a/configure.ac b/configure.ac
index ff543128c8..1b9ce607df 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1402,8 +1402,8 @@ AC_OUTPUT([doc/version.ent
src/lib/cc/session_config.h.pre
src/lib/cc/tests/session_unittests_config.h
src/lib/datasrc/datasrc_config.h.pre
- src/lib/hooks/tests/library_manager_unittest.cc
src/lib/hooks/tests/marker_file.h
+ src/lib/hooks/tests/test_libraries.h
src/lib/log/tests/console_test.sh
src/lib/log/tests/destination_test.sh
src/lib/log/tests/init_logger_test.sh
diff --git a/doc/Doxyfile b/doc/Doxyfile
index bcb9285073..57c6ce19d2 100644
--- a/doc/Doxyfile
+++ b/doc/Doxyfile
@@ -679,6 +679,7 @@ INPUT = ../src/lib/exceptions \
../src/lib/cache \
../src/lib/server_common/ \
../src/bin/sockcreator/ \
+ ../src/lib/hooks/ \
../src/lib/util/ \
../src/lib/util/io/ \
../src/lib/util/threads/ \
diff --git a/doc/devel/mainpage.dox b/doc/devel/mainpage.dox
index 50d0cbe06b..8eb31e8aac 100644
--- a/doc/devel/mainpage.dox
+++ b/doc/devel/mainpage.dox
@@ -1,11 +1,33 @@
+// Copyright (C) 2012-2013 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
/**
- *
* @mainpage BIND10 Developer's Guide
*
* Welcome to BIND10 Developer's Guide. This documentation is addressed
- * at existing and prospecting developers and programmers, who would like
- * to gain insight into internal workings of BIND 10. It could also be useful
- * for existing and prospective contributors.
+ * at existing and prospecting developers and programmers and provides
+ * information needed to both extend and maintain BIND 10.
+ *
+ * If you wish to write "hook" code - code that is loaded by BIND 10 at
+ * run-time and modifies its behavior you should read the section
+ * @ref hookDevelopersGuide.
+ *
+ * BIND 10 maintanenace information is divided into a number of sections
+ * depending on focus. DNS-specific issues are covered in the
+ * @ref dnsMaintenanceGuide while information on DHCP-specific topics can
+ * be found in the @ref dhcpMaintenanceGuide. General BIND 10 topics, not
+ * specific to any protocol, are discussed in @ref miscellaneousTopics.
*
* If you are a user or system administrator, rather than software engineer,
* you should read BIND10
@@ -13,13 +35,15 @@
*
* Regardless of your field of expertise, you are encouraged to visit
* BIND10 webpage (http://bind10.isc.org)
+ * @section hooksFramework Hooks Framework
+ * - @subpage hooksComponentDeveloperGuide
*
- * @section DNS
+ * @section dnsMaintenanceGuide DNS Maintenance Guide
* - Authoritative DNS (todo)
* - Recursive resolver (todo)
* - @subpage DataScrubbing
*
- * @section DHCP
+ * @section dhcpMaintenanceGuide DHCP Maintenance Guide
* - @subpage dhcp4
* - @subpage dhcpv4Session
* - @subpage dhcpv4ConfigParser
@@ -40,7 +64,7 @@
* - @subpage dhcpDatabaseBackends
* - @subpage perfdhcpInternals
*
- * @section misc Miscellaneous topics
+ * @section miscellaneousTopics Miscellaneous topics
* - @subpage LoggingApi
* - @subpage LoggingApiOverview
* - @subpage LoggingApiLoggerNames
@@ -48,7 +72,10 @@
* - @subpage SocketSessionUtility
* - Documentation warnings and errors
*
- * @todo: Move this logo to the right (and possibly up). Not sure what
- * is the best way to do it in Doxygen, without using CSS hacks.
* @image html isc-logo.png
*/
+/*
+ * @todo: Move the logo to the right (and possibly up). Not sure what
+ * is the best way to do it in Doxygen, without using CSS hacks.
+ */
+
diff --git a/src/bin/dhcp6/dhcp6_srv.cc b/src/bin/dhcp6/dhcp6_srv.cc
index 926cf11f4d..57497c8874 100644
--- a/src/bin/dhcp6/dhcp6_srv.cc
+++ b/src/bin/dhcp6/dhcp6_srv.cc
@@ -37,7 +37,6 @@
#include
#include
#include
-#include
#include
#include
@@ -113,13 +112,13 @@ Dhcpv6Srv::Dhcpv6Srv(uint16_t port)
alloc_engine_.reset(new AllocEngine(AllocEngine::ALLOC_ITERATIVE, 100));
// Register hook points
- hook_index_pkt6_receive_ = ServerHooks::getServerHooks().registerHook("pkt6_receive");
- hook_index_subnet6_select_ = ServerHooks::getServerHooks().registerHook("subnet6_select");
- hook_index_pkt6_send_ = ServerHooks::getServerHooks().registerHook("pkt6_send");
+ hook_index_pkt6_receive_ = HooksManager::registerHook("pkt6_receive");
+ hook_index_subnet6_select_ = HooksManager::registerHook("subnet6_select");
+ hook_index_pkt6_send_ = HooksManager::registerHook("pkt6_send");
/// @todo call loadLibraries() when handling configuration changes
vector libraries; // no libraries at this time
- HooksManager::getHooksManager().loadLibraries(libraries);
+ HooksManager::loadLibraries(libraries);
} catch (const std::exception &e) {
LOG_ERROR(dhcp6_logger, DHCP6_SRV_CONSTRUCT_ERROR).arg(e.what());
diff --git a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
index b40122d176..99b703e5b0 100644
--- a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
+++ b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc
@@ -36,7 +36,6 @@
#include
#include
-#include
#include
#include
@@ -1912,9 +1911,6 @@ public:
// clear static buffers
resetCalloutBuffers();
-
- // Let's pretent we're the library 0
- EXPECT_NO_THROW(HooksManager::getCalloutManager()->setLibraryIndex(0));
}
~HooksDhcpv6SrvTest() {
@@ -2116,8 +2112,8 @@ vector HooksDhcpv6SrvTest::callback_argument_names_;
TEST_F(HooksDhcpv6SrvTest, simple_pkt6_receive) {
// Install pkt6_receive_callout
- EXPECT_NO_THROW(HooksManager::getCalloutManager()->registerCallout("pkt6_receive",
- pkt6_receive_callout));
+ EXPECT_NO_THROW(HooksManager::preCalloutsLibraryHandle().registerCallout(
+ "pkt6_receive", pkt6_receive_callout));
// Let's create a simple SOLICIT
Pkt6Ptr sol = Pkt6Ptr(captureSimpleSolicit());
@@ -2149,8 +2145,8 @@ TEST_F(HooksDhcpv6SrvTest, simple_pkt6_receive) {
TEST_F(HooksDhcpv6SrvTest, valueChange_pkt6_receive) {
// Install pkt6_receive_callout
- EXPECT_NO_THROW(HooksManager::getCalloutManager()->registerCallout("pkt6_receive",
- pkt6_receive_change_clientid));
+ EXPECT_NO_THROW(HooksManager::preCalloutsLibraryHandle().registerCallout(
+ "pkt6_receive", pkt6_receive_change_clientid));
// Let's create a simple SOLICIT
Pkt6Ptr sol = Pkt6Ptr(captureSimpleSolicit());
@@ -2185,8 +2181,8 @@ TEST_F(HooksDhcpv6SrvTest, valueChange_pkt6_receive) {
TEST_F(HooksDhcpv6SrvTest, deleteClientId_pkt6_receive) {
// Install pkt6_receive_callout
- EXPECT_NO_THROW(HooksManager::getCalloutManager()->registerCallout("pkt6_receive",
- pkt6_receive_delete_clientid));
+ EXPECT_NO_THROW(HooksManager::preCalloutsLibraryHandle().registerCallout(
+ "pkt6_receive", pkt6_receive_delete_clientid));
// Let's create a simple SOLICIT
Pkt6Ptr sol = Pkt6Ptr(captureSimpleSolicit());
@@ -2209,8 +2205,8 @@ TEST_F(HooksDhcpv6SrvTest, deleteClientId_pkt6_receive) {
TEST_F(HooksDhcpv6SrvTest, skip_pkt6_receive) {
// Install pkt6_receive_callout
- EXPECT_NO_THROW(HooksManager::getCalloutManager()->registerCallout("pkt6_receive",
- pkt6_receive_skip));
+ EXPECT_NO_THROW(HooksManager::preCalloutsLibraryHandle().registerCallout(
+ "pkt6_receive", pkt6_receive_skip));
// Let's create a simple SOLICIT
Pkt6Ptr sol = Pkt6Ptr(captureSimpleSolicit());
@@ -2234,8 +2230,8 @@ TEST_F(HooksDhcpv6SrvTest, skip_pkt6_receive) {
TEST_F(HooksDhcpv6SrvTest, simple_pkt6_send) {
// Install pkt6_receive_callout
- EXPECT_NO_THROW(HooksManager::getCalloutManager()->registerCallout("pkt6_send",
- pkt6_send_callout));
+ EXPECT_NO_THROW(HooksManager::preCalloutsLibraryHandle().registerCallout(
+ "pkt6_send", pkt6_send_callout));
// Let's create a simple SOLICIT
Pkt6Ptr sol = Pkt6Ptr(captureSimpleSolicit());
@@ -2270,8 +2266,8 @@ TEST_F(HooksDhcpv6SrvTest, simple_pkt6_send) {
TEST_F(HooksDhcpv6SrvTest, valueChange_pkt6_send) {
// Install pkt6_receive_callout
- EXPECT_NO_THROW(HooksManager::getCalloutManager()->registerCallout("pkt6_send",
- pkt6_send_change_serverid));
+ EXPECT_NO_THROW(HooksManager::preCalloutsLibraryHandle().registerCallout(
+ "pkt6_send", pkt6_send_change_serverid));
// Let's create a simple SOLICIT
Pkt6Ptr sol = Pkt6Ptr(captureSimpleSolicit());
@@ -2307,8 +2303,8 @@ TEST_F(HooksDhcpv6SrvTest, valueChange_pkt6_send) {
TEST_F(HooksDhcpv6SrvTest, deleteServerId_pkt6_send) {
// Install pkt6_receive_callout
- EXPECT_NO_THROW(HooksManager::getCalloutManager()->registerCallout("pkt6_send",
- pkt6_send_delete_serverid));
+ EXPECT_NO_THROW(HooksManager::preCalloutsLibraryHandle().registerCallout(
+ "pkt6_send", pkt6_send_delete_serverid));
// Let's create a simple SOLICIT
Pkt6Ptr sol = Pkt6Ptr(captureSimpleSolicit());
@@ -2338,8 +2334,8 @@ TEST_F(HooksDhcpv6SrvTest, deleteServerId_pkt6_send) {
TEST_F(HooksDhcpv6SrvTest, skip_pkt6_send) {
// Install pkt6_receive_callout
- EXPECT_NO_THROW(HooksManager::getCalloutManager()->registerCallout("pkt6_send",
- pkt6_send_skip));
+ EXPECT_NO_THROW(HooksManager::preCalloutsLibraryHandle().registerCallout(
+ "pkt6_send", pkt6_send_skip));
// Let's create a simple REQUEST
Pkt6Ptr sol = Pkt6Ptr(captureSimpleSolicit());
@@ -2362,8 +2358,8 @@ TEST_F(HooksDhcpv6SrvTest, skip_pkt6_send) {
TEST_F(HooksDhcpv6SrvTest, subnet6_select) {
// Install pkt6_receive_callout
- EXPECT_NO_THROW(HooksManager::getCalloutManager()->registerCallout("subnet6_select",
- subnet6_select_callout));
+ EXPECT_NO_THROW(HooksManager::preCalloutsLibraryHandle().registerCallout(
+ "subnet6_select", subnet6_select_callout));
// Configure 2 subnets, both directly reachable over local interface
// (let's not complicate the matter with relays)
@@ -2430,8 +2426,8 @@ TEST_F(HooksDhcpv6SrvTest, subnet6_select) {
TEST_F(HooksDhcpv6SrvTest, subnet_select_change) {
// Install pkt6_receive_callout
- EXPECT_NO_THROW(HooksManager::getCalloutManager()->registerCallout("subnet6_select",
- subnet6_select_different_subnet_callout));
+ EXPECT_NO_THROW(HooksManager::preCalloutsLibraryHandle().registerCallout(
+ "subnet6_select", subnet6_select_different_subnet_callout));
// Configure 2 subnets, both directly reachable over local interface
// (let's not complicate the matter with relays)
diff --git a/src/lib/dhcpsrv/tests/alloc_engine_unittest.cc b/src/lib/dhcpsrv/tests/alloc_engine_unittest.cc
index cf520c9d54..b71ef98866 100644
--- a/src/lib/dhcpsrv/tests/alloc_engine_unittest.cc
+++ b/src/lib/dhcpsrv/tests/alloc_engine_unittest.cc
@@ -1154,10 +1154,8 @@ TEST_F(HookAllocEngine6Test, lease6_select) {
HooksManager::getHooksManager().loadLibraries(libraries);
// Install pkt6_receive_callout
- ASSERT_TRUE(HooksManager::getCalloutManager());
- EXPECT_NO_THROW(HooksManager::getCalloutManager()->setLibraryIndex(0));
- EXPECT_NO_THROW(HooksManager::getCalloutManager()->registerCallout("lease6_select",
- lease6_select_callout));
+ EXPECT_NO_THROW(HooksManager::preCalloutsLibraryHandle().registerCallout(
+ "lease6_select", lease6_select_callout));
CalloutHandlePtr callout_handle = HooksManager::getHooksManager().createCalloutHandle();
@@ -1217,10 +1215,8 @@ TEST_F(HookAllocEngine6Test, change_lease6_select) {
HooksManager::getHooksManager().loadLibraries(libraries);
// Install a callout
- ASSERT_TRUE(HooksManager::getCalloutManager());
- EXPECT_NO_THROW(HooksManager::getCalloutManager()->setLibraryIndex(0));
- EXPECT_NO_THROW(HooksManager::getCalloutManager()->registerCallout("lease6_select",
- lease6_select_different_callout));
+ EXPECT_NO_THROW(HooksManager::preCalloutsLibraryHandle().registerCallout(
+ "lease6_select", lease6_select_different_callout));
// Normally, dhcpv6_srv would passed the handle when calling allocateAddress6,
// but in tests we need to create it on our own.
diff --git a/src/lib/hooks/Makefile.am b/src/lib/hooks/Makefile.am
index 1d19551358..08863be2d0 100644
--- a/src/lib/hooks/Makefile.am
+++ b/src/lib/hooks/Makefile.am
@@ -31,10 +31,11 @@ libb10_hooks_la_SOURCES += callout_handle.cc callout_handle.h
libb10_hooks_la_SOURCES += callout_manager.cc callout_manager.h
libb10_hooks_la_SOURCES += hooks.h
libb10_hooks_la_SOURCES += hooks_log.cc hooks_log.h
+libb10_hooks_la_SOURCES += hooks_manager.cc hooks_manager.h
libb10_hooks_la_SOURCES += library_handle.cc library_handle.h
libb10_hooks_la_SOURCES += library_manager.cc library_manager.h
+libb10_hooks_la_SOURCES += library_manager_collection.cc library_manager_collection.h
libb10_hooks_la_SOURCES += server_hooks.cc server_hooks.h
-libb10_hooks_la_SOURCES += hooks_manager.cc hooks_manager.h
nodist_libb10_hooks_la_SOURCES = hooks_messages.cc hooks_messages.h
diff --git a/src/lib/hooks/callout_handle.cc b/src/lib/hooks/callout_handle.cc
index 27d76d7be7..ce9ef8241d 100644
--- a/src/lib/hooks/callout_handle.cc
+++ b/src/lib/hooks/callout_handle.cc
@@ -27,8 +27,10 @@ namespace isc {
namespace hooks {
// Constructor.
-CalloutHandle::CalloutHandle(const boost::shared_ptr& manager)
- : arguments_(), context_collection_(), manager_(manager), skip_(false) {
+CalloutHandle::CalloutHandle(const boost::shared_ptr& manager,
+ const boost::shared_ptr& lmcoll)
+ : lm_collection_(lmcoll), arguments_(), context_collection_(),
+ manager_(manager), skip_(false) {
// Call the "context_create" hook. We should be OK doing this - although
// the constructor has not finished running, all the member variables
@@ -43,6 +45,24 @@ CalloutHandle::~CalloutHandle() {
// the destructor is being called, all the member variables are still in
// existence.
manager_->callCallouts(ServerHooks::CONTEXT_DESTROY, *this);
+
+ // Explicitly clear the argument and context objects. This should free up
+ // all memory that could have been allocated by libraries that were loaded.
+ arguments_.clear();
+ context_collection_.clear();
+
+ // Normal destruction of the remaining variables will include the
+ // destruction of lm_collection_, an action that decrements the reference
+ // count on the library manager collection (which holds the libraries that
+ // could have allocated memory in the argument and context members.) When
+ // that goes to zero, the libraries will be unloaded: at that point nothing
+ // in the hooks framework will be pointing to memory in the libraries'
+ // address space.
+ //
+ // It is possible that some other data structure in the server (the program
+ // using the hooks library) still references the address space and attempts
+ // to access it causing a segmentation fault. That issue is outside the
+ // scope of this framework and is not addressed by it.
}
// Return the name of all argument items.
@@ -130,8 +150,9 @@ CalloutHandle::getHookName() const {
try {
hook = ServerHooks::getServerHooks().getName(index);
} catch (const NoSuchHook&) {
- // Hook index is invalid, so probably called outside of a callout.
- // This is a no-op.
+ // Hook index is invalid, so this methods probably called from outside
+ // a callout being executed via a call to CalloutManager::callCallouts.
+ // In this case, the empty string is returned.
}
return (hook);
diff --git a/src/lib/hooks/callout_handle.h b/src/lib/hooks/callout_handle.h
index e85877ea5f..eb57fd46a7 100644
--- a/src/lib/hooks/callout_handle.h
+++ b/src/lib/hooks/callout_handle.h
@@ -54,6 +54,7 @@ public:
class CalloutManager;
class LibraryHandle;
+class LibraryManagerCollection;
/// @brief Per-packet callout handle
///
@@ -79,11 +80,11 @@ class LibraryHandle;
/// "context_destroy" callout. The information is accessed through the
/// {get,set}Context() methods.
///
-/// - Per-library handle. Allows the callout to dynamically register and
-/// deregister callouts. (In the latter case, only functions registered by
-/// functions in the same library as the callout doing the deregistration
-/// can be removed: callouts registered by other libraries cannot be
-/// modified.)
+/// - Per-library handle (LibraryHandle). The library handle allows the
+/// callout to dynamically register and deregister callouts. In the latter
+/// case, only functions registered by functions in the same library as the
+/// callout doing the deregistration can be removed: callouts registered by
+/// other libraries cannot be modified.
class CalloutHandle {
public:
@@ -110,12 +111,27 @@ public:
/// Creates the object and calls the callouts on the "context_create"
/// hook.
///
+ /// Of the two arguments passed, only the pointer to the callout manager is
+ /// actively used. The second argument, the pointer to the library manager
+ /// collection, is used for lifetime control: after use, the callout handle
+ /// may contain pointers to memory allocated by the loaded libraries. The
+ /// used of a shared pointer to the collection of library managers means
+ /// that the libraries that could have allocated memory in a callout handle
+ /// will not be unloaded until all such handles have been destroyed. This
+ /// issue is discussed in more detail in the documentation for
+ /// isc::hooks::LibraryManager.
+ ///
/// @param manager Pointer to the callout manager object.
- CalloutHandle(const boost::shared_ptr& manager);
+ /// @param lmcoll Pointer to the library manager collection. This has a
+ /// null default for testing purposes.
+ CalloutHandle(const boost::shared_ptr& manager,
+ const boost::shared_ptr& lmcoll =
+ boost::shared_ptr());
/// @brief Destructor
///
/// Calls the context_destroy callback to release any per-packet context.
+ /// It also clears stored data to avoid problems during member destruction.
~CalloutHandle();
/// @brief Set argument
@@ -152,7 +168,7 @@ public:
value = boost::any_cast(element_ptr->second);
}
-
+
/// @brief Get argument names
///
/// Returns a vector holding the names of arguments in the argument
@@ -257,7 +273,7 @@ public:
value = boost::any_cast(element_ptr->second);
}
-
+
/// @brief Get context names
///
/// Returns a vector holding the names of items in the context associated
@@ -340,6 +356,10 @@ private:
// Member variables
+ /// Pointer to the collection of libraries for which this handle has been
+ /// created.
+ boost::shared_ptr lm_collection_;
+
/// Collection of arguments passed to the callouts
ElementCollection arguments_;
@@ -353,10 +373,10 @@ private:
bool skip_;
};
-/// a shared pointer to CalloutHandle object
+/// A shared pointer to a CalloutHandle object.
typedef boost::shared_ptr CalloutHandlePtr;
-} // namespace util
+} // namespace hooks
} // namespace isc
diff --git a/src/lib/hooks/callout_manager.cc b/src/lib/hooks/callout_manager.cc
index 69027ae2e9..0b75b1b50f 100644
--- a/src/lib/hooks/callout_manager.cc
+++ b/src/lib/hooks/callout_manager.cc
@@ -19,6 +19,7 @@
#include
#include
+#include
#include
#include
@@ -27,12 +28,41 @@ using namespace std;
namespace isc {
namespace hooks {
+// Check that the index of a library is valid. It can range from 1 - n
+// (n is the number of libraries), 0 (pre-user library callouts), or INT_MAX
+// (post-user library callouts). It can also be -1 to indicate an invalid
+// value.
+
+void
+CalloutManager::checkLibraryIndex(int library_index) const {
+ if (((library_index >= -1) && (library_index <= num_libraries_)) ||
+ (library_index == INT_MAX)) {
+ return;
+ }
+
+ isc_throw(NoSuchLibrary, "library index " << library_index <<
+ " is not valid for the number of loaded libraries (" <<
+ num_libraries_ << ")");
+}
+
+// Set the number of libraries handled by the CalloutManager.
+
+void
+CalloutManager::setNumLibraries(int num_libraries) {
+ if (num_libraries < 0) {
+ isc_throw(isc::BadValue, "number of libraries passed to the "
+ "CalloutManager must be >= 0");
+ }
+
+ num_libraries_ = num_libraries;
+}
+
// Register a callout for the current library.
void
CalloutManager::registerCallout(const std::string& name, CalloutPtr callout) {
// Note the registration.
- LOG_DEBUG(hooks_logger, HOOKS_DBG_CALLS, HOOKS_REGISTER_CALLOUT)
+ LOG_DEBUG(hooks_logger, HOOKS_DBG_CALLS, HOOKS_CALLOUT_REGISTRATION)
.arg(current_library_).arg(name);
// Sanity check that the current library index is set to a valid value.
@@ -108,15 +138,24 @@ CalloutManager::callCallouts(int hook_index, CalloutHandle& callout_handle) {
current_library_ = i->first;
// Call the callout
- // @todo Log the return status if non-zero
- int status = (*i->second)(callout_handle);
- if (status == 0) {
- LOG_DEBUG(hooks_logger, HOOKS_DBG_EXTENDED_CALLS, HOOKS_CALLOUT)
- .arg(current_library_)
- .arg(ServerHooks::getServerHooks().getName(current_hook_))
- .arg(reinterpret_cast(i->second));
- } else {
- LOG_WARN(hooks_logger, HOOKS_CALLOUT_ERROR)
+ try {
+ int status = (*i->second)(callout_handle);
+ if (status == 0) {
+ LOG_DEBUG(hooks_logger, HOOKS_DBG_EXTENDED_CALLS,
+ HOOKS_CALLOUT_CALLED).arg(current_library_)
+ .arg(ServerHooks::getServerHooks()
+ .getName(current_hook_))
+ .arg(reinterpret_cast(i->second));
+ } else {
+ LOG_ERROR(hooks_logger, HOOKS_CALLOUT_ERROR)
+ .arg(current_library_)
+ .arg(ServerHooks::getServerHooks()
+ .getName(current_hook_))
+ .arg(reinterpret_cast(i->second));
+ }
+ } catch (...) {
+ // Any exception, not just ones based on isc::Exception
+ LOG_ERROR(hooks_logger, HOOKS_CALLOUT_EXCEPTION)
.arg(current_library_)
.arg(ServerHooks::getServerHooks().getName(current_hook_))
.arg(reinterpret_cast(i->second));
@@ -170,7 +209,7 @@ CalloutManager::deregisterCallout(const std::string& name, CalloutPtr callout) {
bool removed = initial_size != hook_vector_[hook_index].size();
if (removed) {
LOG_DEBUG(hooks_logger, HOOKS_DBG_EXTENDED_CALLS,
- HOOKS_DEREGISTER_CALLOUT).arg(current_library_).arg(name);
+ HOOKS_CALLOUT_DEREGISTERED).arg(current_library_).arg(name);
}
return (removed);
@@ -205,7 +244,7 @@ CalloutManager::deregisterAllCallouts(const std::string& name) {
bool removed = initial_size != hook_vector_[hook_index].size();
if (removed) {
LOG_DEBUG(hooks_logger, HOOKS_DBG_EXTENDED_CALLS,
- HOOKS_DEREGISTER_ALL_CALLOUTS).arg(current_library_)
+ HOOKS_ALL_CALLOUTS_DEREGISTERED).arg(current_library_)
.arg(name);
}
diff --git a/src/lib/hooks/callout_manager.h b/src/lib/hooks/callout_manager.h
index f28bc1cf8a..4619006595 100644
--- a/src/lib/hooks/callout_manager.h
+++ b/src/lib/hooks/callout_manager.h
@@ -21,6 +21,7 @@
#include
+#include
#include