From: Thomas Markwalder Date: Tue, 5 Dec 2023 20:12:50 +0000 (-0500) Subject: [#3107] Single-threaded mode for ping-check X-Git-Tag: Kea-2.5.5~97 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=49cdaab1a82f4d2c92c4f2d166abb9e2b742e42a;p=thirdparty%2Fkea.git [#3107] Single-threaded mode for ping-check doc/sphinx/arm/hooks-ping-check.rst Removed note about single-threaded mode Added ChangeLog src/lib/dhcp/iface_mgr.* IfaceMgr::isExternalSocket() - new function to facilitate UTs src/lib/dhcp/tests/iface_mgr_unittest.cc Updated tests --- diff --git a/ChangeLog b/ChangeLog index 329034afd8..6ee05c7da8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2196. [func] tmark + The ping-check hook library can now be used with kea-dhcp4 + in either multi-threaded or single-threaded mode. + (Gitlab #3107) + 2195. [func] tmark Added a new hook point to kea-dhcp4, "lease4_server_decline". DHCPv4 leases declined by ping-check hook library are now diff --git a/doc/sphinx/arm/hooks-ping-check.rst b/doc/sphinx/arm/hooks-ping-check.rst index c6139bbbda..efa2fef266 100644 --- a/doc/sphinx/arm/hooks-ping-check.rst +++ b/doc/sphinx/arm/hooks-ping-check.rst @@ -36,7 +36,7 @@ by adding it to the ``hooks-libraries`` element of the server's configuration: ... } -When the library is loaded :iscman:`kea-dhcp4` will conduct ping-check prior to +When the library is loaded :iscman:`kea-dhcp4` will conduct a ping-check prior to offering a lease to client if all of the following conditions are true: 1. Ping check hook library is loaded. @@ -124,7 +124,7 @@ that may be set at the global and subnet levels. Subnet values override global v The following parameter is only supported at the global level: -- `ping-channel-threads` - In multi-threaded mode, this is the number of threads in the channel's thread pool. The default is 0 which instructs the library to use the same number of threads as Kea core. +- `ping-channel-threads` - In multi-threaded mode, this is the number of threads in the channel's thread pool. The default is 0 which instructs the library to use the same number of threads as Kea core. The value is ignored if given when Kea is in single-threaded mode. The following configuration excerpt illustrates global level configuration: @@ -167,7 +167,3 @@ The following excerpt demonstrates subnet level configuration: Ping checking is an experimental feature. It is not currently recommended for production environments. - -.. note:: - - Ping checking is currently only supported when Kea is configured for multi-threaded operation. diff --git a/src/lib/dhcp/iface_mgr.cc b/src/lib/dhcp/iface_mgr.cc index c23a9e9836..e574df2a24 100644 --- a/src/lib/dhcp/iface_mgr.cc +++ b/src/lib/dhcp/iface_mgr.cc @@ -363,6 +363,18 @@ IfaceMgr::deleteExternalSocketInternal(int socketfd) { } } +bool +IfaceMgr::isExternalSocket(int fd) { + std::lock_guard lock(callbacks_mutex_); + for (SocketCallbackInfo s : callbacks_) { + if (s.socket_ == fd) { + return (true); + } + } + + return (false); +} + int IfaceMgr::purgeBadSockets() { std::lock_guard lock(callbacks_mutex_); diff --git a/src/lib/dhcp/iface_mgr.h b/src/lib/dhcp/iface_mgr.h index ca0a536096..c56b15ab1f 100644 --- a/src/lib/dhcp/iface_mgr.h +++ b/src/lib/dhcp/iface_mgr.h @@ -1146,6 +1146,11 @@ public: /// @param callback callback function void addExternalSocket(int socketfd, SocketCallback callback); + /// @brief Checks if socket's file description is registered. + /// + /// @return True if the fd is in the list of registered sockets. + bool isExternalSocket(int fd); + /// @brief Deletes external socket /// /// @param socketfd socket descriptor diff --git a/src/lib/dhcp/tests/iface_mgr_unittest.cc b/src/lib/dhcp/tests/iface_mgr_unittest.cc index ec411a87a0..82b877aca2 100644 --- a/src/lib/dhcp/tests/iface_mgr_unittest.cc +++ b/src/lib/dhcp/tests/iface_mgr_unittest.cc @@ -702,19 +702,22 @@ public: // Create first pipe and register it as extra socket int pipefd[2]; EXPECT_TRUE(pipe(pipefd) == 0); + ASSERT_FALSE(ifacemgr->isExternalSocket(pipefd[0])); EXPECT_NO_THROW(ifacemgr->addExternalSocket(pipefd[0], [&callback_ok, &pipefd](int fd) { callback_ok = (pipefd[0] == fd); })); - + ASSERT_TRUE(ifacemgr->isExternalSocket(pipefd[0])); // Let's create a second pipe and register it as well int secondpipe[2]; EXPECT_TRUE(pipe(secondpipe) == 0); + ASSERT_FALSE(ifacemgr->isExternalSocket(secondpipe[0])); EXPECT_NO_THROW(ifacemgr->addExternalSocket(secondpipe[0], [&callback2_ok, &secondpipe](int fd) { callback2_ok = (secondpipe[0] == fd); })); + ASSERT_TRUE(ifacemgr->isExternalSocket(secondpipe[0])); // Verify a call with no data and normal external sockets works ok. Pkt4Ptr pkt4; @@ -789,19 +792,22 @@ public: // Create first pipe and register it as extra socket int pipefd[2]; EXPECT_TRUE(pipe(pipefd) == 0); + ASSERT_FALSE(ifacemgr->isExternalSocket(pipefd[0])); EXPECT_NO_THROW(ifacemgr->addExternalSocket(pipefd[0], [&callback_ok, &pipefd](int fd) { callback_ok = (pipefd[0] == fd); })); - + ASSERT_TRUE(ifacemgr->isExternalSocket(pipefd[0])); // Let's create a second pipe and register it as well int secondpipe[2]; EXPECT_TRUE(pipe(secondpipe) == 0); + ASSERT_FALSE(ifacemgr->isExternalSocket(secondpipe[0])); EXPECT_NO_THROW(ifacemgr->addExternalSocket(secondpipe[0], [&callback2_ok, &secondpipe](int fd) { callback2_ok = (secondpipe[0] == fd); })); + ASSERT_TRUE(ifacemgr->isExternalSocket(secondpipe[0])); // Verify a call with no data and normal external sockets works ok. Pkt6Ptr pkt6;