}
struct timeval tm;
tm.tv_sec = tm.tv_usec = 0;
+ // r4z: should move to epoll/kqueue?
int n = select(nfd + 1, &fds, 0, 0, &tm);
if ((n < 0) && (errno == EINTR)) {
cerr << "interrupted" << endl;
for (unsigned i = 0; i < mac_len_; i++) {
tmp.width(2);
tmp << static_cast<int>(mac_[i]);
- if (i < mac_len_-1) {
+ if (i < mac_len_ - 1) {
tmp << ":";
}
}
<< " filter when there are open IPv6 sockets - need"
<< " to close them first");
}
-
+ // Everything is fine, so replace packet filter.
packet_filter6_ = packet_filter;
}
// allowed
if (iface->flag_loopback_ && !allow_loopback_) {
IFACEMGR_ERROR(SocketConfigError, error_handler, iface,
- "must not open socket on the loopback"
- " interface " << iface->getName());
+ "must not open socket on the loopback"
+ " interface " << iface->getName());
continue;
}
if (!iface->flag_up_) {
IFACEMGR_ERROR(SocketConfigError, error_handler, iface,
- "the interface " << iface->getName()
- << " is down");
+ "the interface " << iface->getName()
+ << " is down");
continue;
}
if (!iface->flag_running_) {
IFACEMGR_ERROR(SocketConfigError, error_handler, iface,
- "the interface " << iface->getName()
- << " is not running");
+ "the interface " << iface->getName()
+ << " is not running");
continue;
}
IOAddress out_address("0.0.0.0");
if (!iface->getAddress4(out_address)) {
IFACEMGR_ERROR(SocketConfigError, error_handler, iface,
- "the interface " << iface->getName()
- << " has no usable IPv4 addresses configured");
+ "the interface " << iface->getName()
+ << " has no usable IPv4 addresses configured");
continue;
}
isc_throw(BadValue, "addFDtoSet: sockets can't be null");
}
+ if (fd >= FD_SETSIZE) {
+ isc_throw(BadValue, "addFDtoSet: sockets fd too large: " << fd << " >= " << FD_SETSIZE);
+ }
+
FD_SET(fd, sockets);
if (maxfd < fd) {
maxfd = fd;
// If we want to send something to link-local and the socket is
// bound to link-local or we want to send to global and the socket
// is bound to global, then use it as candidate
- if ( (pkt->getRemoteAddr().isV6LinkLocal() &&
- s->addr_.isV6LinkLocal()) ||
- (!pkt->getRemoteAddr().isV6LinkLocal() &&
- !s->addr_.isV6LinkLocal()) ) {
+ if ((pkt->getRemoteAddr().isV6LinkLocal() && s->addr_.isV6LinkLocal()) ||
+ (!pkt->getRemoteAddr().isV6LinkLocal() && !s->addr_.isV6LinkLocal())) {
candidate = s;
}
}
#include <dhcp/protocol_util.h>
#include <dhcp/tests/pkt_filter_test_utils.h>
#include <util/buffer.h>
+#include <util/ready_check.h>
#include <testutils/gtest_utils.h>
#include <gtest/gtest.h>
testPktEvents(test_message_, start_time_, std::list<std::string>{PktEvent::RESPONSE_SENT});
// Read the data from socket.
- fd_set readfds;
- FD_ZERO(&readfds);
- FD_SET(sock_info_.sockfd_, &readfds);
-
- struct timeval timeout;
- timeout.tv_sec = 5;
- timeout.tv_usec = 0;
- int result = select(sock_info_.sockfd_ + 1, &readfds, NULL, NULL, &timeout);
+ int result = selectCheck(sock_info_.sockfd_, 5);
// We should receive some data from loopback interface.
ASSERT_GT(result, 0);
// Perform select on the socket to make sure that the packet has
// been dropped.
- fd_set readfds;
- FD_ZERO(&readfds);
- FD_SET(sock_info_.sockfd_, &readfds);
-
- struct timeval timeout;
- timeout.tv_sec = 1;
- timeout.tv_usec = 0;
- int result = select(sock_info_.sockfd_ + 1, &readfds, NULL, NULL, &timeout);
+ int result = selectCheck(sock_info_.sockfd_, 1);
ASSERT_LE(result, 0);
}
#include <dhcp/pkt6.h>
#include <dhcp/pkt_filter_inet6.h>
#include <dhcp/tests/pkt_filter6_test_utils.h>
+#include <util/ready_check.h>
#include <gtest/gtest.h>
using namespace isc::asiolink;
using namespace isc::dhcp;
+using namespace isc::util;
namespace {
testPktEvents(test_message_, start_time_, std::list<std::string>{PktEvent::RESPONSE_SENT});
// Read the data from socket.
- fd_set readfds;
- FD_ZERO(&readfds);
- FD_SET(sock_info_.sockfd_, &readfds);
-
- struct timeval timeout;
- timeout.tv_sec = 5;
- timeout.tv_usec = 0;
- result = select(sock_info_.sockfd_ + 1, &readfds, NULL, NULL, &timeout);
+ result = selectCheck(sock_info_.sockfd_, 5);
// We should receive some data from loopback interface.
ASSERT_GT(result, 0);
#include <dhcp/pkt4.h>
#include <dhcp/pkt_filter_inet.h>
#include <dhcp/tests/pkt_filter_test_utils.h>
+#include <util/ready_check.h>
#include <gtest/gtest.h>
using namespace isc::asiolink;
using namespace isc::dhcp;
+using namespace isc::util;
namespace {
testPktEvents(test_message_, start_time_, std::list<std::string>{PktEvent::RESPONSE_SENT});
// Read the data from socket.
- fd_set readfds;
- FD_ZERO(&readfds);
- FD_SET(sock_info_.sockfd_, &readfds);
-
- struct timeval timeout;
- timeout.tv_sec = 5;
- timeout.tv_usec = 0;
- result = select(sock_info_.sockfd_ + 1, &readfds, NULL, NULL, &timeout);
+ result = selectCheck(sock_info_.sockfd_, 5);
// We should receive some data from loopback interface.
ASSERT_GT(result, 0);
#include <dhcp/protocol_util.h>
#include <dhcp/tests/pkt_filter_test_utils.h>
#include <util/buffer.h>
+#include <util/ready_check.h>
#include <testutils/gtest_utils.h>
#include <gtest/gtest.h>
testPktEvents(test_message_, start_time_, std::list<std::string>{PktEvent::RESPONSE_SENT});
// Read the data from socket.
- fd_set readfds;
- FD_ZERO(&readfds);
- FD_SET(sock_info_.sockfd_, &readfds);
-
- struct timeval timeout;
- timeout.tv_sec = 5;
- timeout.tv_usec = 0;
- int result = select(sock_info_.sockfd_ + 1, &readfds, NULL, NULL, &timeout);
+ int result = selectCheck(sock_info_.sockfd_, 5);
// We should receive some data from loopback interface.
ASSERT_GT(result, 0);
// Perform select on the socket to make sure that the packet has
// been dropped.
- fd_set readfds;
- FD_ZERO(&readfds);
- FD_SET(sock_info_.sockfd_, &readfds);
-
- struct timeval timeout;
- timeout.tv_sec = 1;
- timeout.tv_usec = 0;
- int result = select(sock_info_.sockfd_ + 1, &readfds, NULL, NULL, &timeout);
+ int result = selectCheck(sock_info_.sockfd_, 1);
ASSERT_LE(result, 0);
}
'ncr_udp_unittests.cc',
'ncr_unittests.cc',
'run_unittests.cc',
- 'test_utils.cc',
dependencies: [GTEST_DEP],
include_directories: [include_directories('.')] + INCLUDES,
link_with: [kea_testutils_lib, kea_util_unittests_lib] + LIBS_BUILT_SO_FAR,
#include <dhcp_ddns/ncr_io.h>
#include <dhcp_ddns/ncr_udp.h>
#include <util/multi_threading_mgr.h>
-#include <test_utils.h>
+#include <util/ready_check.h>
#include <boost/asio/ip/udp.hpp>
+++ /dev/null
-// Copyright (C) 2014-2024 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/.
-
-#include <config.h>
-
-#include <gtest/gtest.h>
-
-#include <sys/select.h>
-#include <sys/ioctl.h>
-
-using namespace std;
-
-namespace isc {
-namespace dhcp_ddns {
-
-int selectCheck(int fd_to_check) {
- fd_set read_fds;
- int maxfd = 0;
-
- FD_ZERO(&read_fds);
-
- // Add this socket to listening set
- FD_SET(fd_to_check, &read_fds);
- maxfd = fd_to_check;
-
- struct timeval select_timeout;
- select_timeout.tv_sec = 0;
- select_timeout.tv_usec = 0;
-
- return (select(maxfd + 1, &read_fds, NULL, NULL, &select_timeout));
-}
-
-} // namespace isc::d2
-} // namespace isc
+++ /dev/null
-// Copyright (C) 2014-2024 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 TEST_UTILS_H
-#define TEST_UTILS_H
-
-/// @file test_utils.h Common dhcp_ddns testing elements
-
-#include <gtest/gtest.h>
-
-
-namespace isc {
-namespace dhcp_ddns {
-
-/// @brief Returns the result of select() given an fd to check for read status.
-///
-/// @param fd_to_check The file descriptor to test
-///
-/// @return Returns less than one on an error, 0 if the fd is not ready to
-/// read, > 0 if it is ready to read.
-int selectCheck(int fd_to_check);
-
-} // namespace isc::dhcp_ddns;
-} // namespace isc;
-
-#endif
#include <dhcp/iface_mgr.h>
#include <dhcpsrv/d2_client_mgr.h>
#include <exceptions/exceptions.h>
+#include <util/ready_check.h>
#include <gtest/gtest.h>
/// @param expect_ready Expected state of readiness (True if expecting
/// a ready to ready result, false if expecting otherwise).
void selectCheck(bool expect_ready) {
- fd_set read_fds;
- int maxfd = 0;
-
- FD_ZERO(&read_fds);
// cppcheck-suppress redundantAssignment
int select_fd = -1;
select_fd = handle_->getSelectFd()
);
- FD_SET(select_fd, &read_fds);
- maxfd = select_fd;
-
- struct timeval select_timeout;
- select_timeout.tv_sec = 0;
- select_timeout.tv_usec = 0;
-
- int result = (select(maxfd + 1, &read_fds, NULL, NULL,
- &select_timeout));
+ int result = util::selectCheck(select_fd);
if (result < 0) {
const char *errstr = strerror(errno);
if (count1 > count2) {
count1 = count2;
}
- for (uint8_t i = 0; i < count1; ++i) {
+ for (size_t i = 0; i < count1; ++i) {
if (host1_i[i] != host2_i[i]) {
return (host1_i[i] < host2_i[i]);
}
#include <gtest/gtest.h>
#include <testutils/unix_control_client.h>
+#include <util/ready_check.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
bool write_check) {
if (socket_fd_ < 0) {
ADD_FAILURE() << "select check with closed socket";
- return -1;
+ return (-1);
}
- if (socket_fd_ > 1023) {
+ if (socket_fd_ >= FD_SETSIZE) {
ADD_FAILURE() << "select check with out of bound socket";
- return -1;
+ return (-1);
}
- int maxfd = 0;
- fd_set read_fds;
- FD_ZERO(&read_fds);
-
- fd_set write_fds;
- FD_ZERO(&write_fds);
-
- maxfd = socket_fd_;
-
- // Add this socket to read set
- FD_SET(socket_fd_, &read_fds);
-
- // Add this socket to write set
- FD_SET(socket_fd_, &write_fds);
-
- struct timeval select_timeout;
- select_timeout.tv_sec = static_cast<time_t>(timeout_sec);
- select_timeout.tv_usec = 0;
-
- fd_set* read_p = 0;
- fd_set* write_p = 0;
-
- if (read_check) {
- read_p = &read_fds;
- }
-
- if (write_check) {
- write_p = &write_fds;
- }
-
- return (select(maxfd + 1, read_p, write_p, NULL, &select_timeout));
+ return (util::selectCheck(socket_fd_, timeout_sec, read_check, write_check));
}
}
/// @param timeout_sec Select timeout in seconds
/// @param read_check flag to check socket for read ready state
/// @param write_check flag to check socket for write ready state
- /// @return -1 on error, 0 if no data is available, 1 if data is ready
+ /// @return -1 on error, 0 if no data is available, 1 if data is ready
int selectCheck(const unsigned int timeout_sec, bool read_check, bool write_check);
/// @brief Retains the fd of the open socket
'memory_segment_local.cc',
'multi_threading_mgr.cc',
'pid_file.cc',
+ 'ready_check.cc',
'reconnect_ctl.cc',
'state_model.cc',
'stopwatch.cc',
'pointer_util.h',
'range_utilities.h',
'readwrite_mutex.h',
+ 'ready_check.h',
'reconnect_ctl.h',
'staged_value.h',
'state_model.h',
--- /dev/null
+// Copyright (C) 2025 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/.
+
+#include <config.h>
+
+#include <sys/select.h>
+#include <sys/ioctl.h>
+
+namespace isc {
+namespace util {
+
+int selectCheck(const int fd_to_check, const unsigned int timeout_sec,
+ bool read_check, bool write_check) {
+ if (fd_to_check < 0) {
+ return (-1);
+ }
+ if (fd_to_check >= FD_SETSIZE) {
+ return (-1);
+ }
+ int maxfd = 0;
+
+ fd_set read_fds;
+ FD_ZERO(&read_fds);
+
+ fd_set write_fds;
+ FD_ZERO(&write_fds);
+
+ maxfd = fd_to_check;
+
+ // Add this socket to read set
+ FD_SET(fd_to_check, &read_fds);
+
+ // Add this socket to write set
+ FD_SET(fd_to_check, &write_fds);
+
+ struct timeval select_timeout;
+ select_timeout.tv_sec = static_cast<time_t>(timeout_sec);
+ select_timeout.tv_usec = 0;
+
+ fd_set* read_p = 0;
+ fd_set* write_p = 0;
+
+ if (read_check) {
+ read_p = &read_fds;
+ }
+
+ if (write_check) {
+ write_p = &write_fds;
+ }
+
+ return (select(maxfd + 1, read_p, write_p, 0, &select_timeout));
+}
+
+} // end of isc::util namespace
+} // end of isc namespace
--- /dev/null
+// Copyright (C) 2025 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 READY_CHECK_H
+#define READY_CHECK_H
+
+namespace isc {
+namespace util {
+
+/// @param fd_to_check The file descriptor to test
+/// @param timeout_sec Select timeout in seconds
+/// @param read_check flag to check socket for read ready state
+/// @param write_check flag to check socket for write ready state
+/// @return -1 on error, 0 if no data is available, 1 if data is ready
+int selectCheck(const int fd_to_check, const unsigned int timeout_sec = 0, bool read_check = true, bool write_check = false);
+
+} // end of isc::util namespace
+} // end of isc namespace
+
+#endif // READY_CHECK_H
// 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/.
#include <config.h>
-#include <util/watch_socket.h>
-#include <gtest/gtest.h>
+#include <util/ready_check.h>
+#include <util/watch_socket.h>
-#include <sys/select.h>
#include <sys/ioctl.h>
+#include <gtest/gtest.h>
#ifdef HAVE_SYS_FILIO_H
// FIONREAD is here on Solaris
namespace {
-/// @brief Returns the result of select() given an fd to check for read status.
-///
-/// @param fd_to_check The file descriptor to test
-///
-/// @return Returns less than one on an error, 0 if the fd is not ready to
-/// read, > 0 if it is ready to read.
-int selectCheck(int fd_to_check) {
- fd_set read_fds;
- int maxfd = 0;
-
- FD_ZERO(&read_fds);
-
- // Add this socket to listening set
- FD_SET(fd_to_check, &read_fds);
- maxfd = fd_to_check;
-
- struct timeval select_timeout;
- select_timeout.tv_sec = 0;
- select_timeout.tv_usec = 0;
-
- return (select(maxfd + 1, &read_fds, NULL, NULL, &select_timeout));
-}
-
/// @brief Tests the basic functionality of WatchSocket.
TEST(WatchSocketTest, basics) {
WatchSocketPtr watch;
#include <config.h>
+#include <util/ready_check.h>
+
#include <gtest/gtest.h>
-#include <sys/select.h>
#include <cstddef>
namespace isc {
unsigned char
parentReadState(int fd) {
- unsigned char result = 0xff;
-
- fd_set rfds;
- FD_ZERO(&rfds);
- FD_SET(fd, &rfds);
-
- struct timeval tv = {5, 0};
+ unsigned char result = 0xff;
- const int nfds = select(fd + 1, &rfds, NULL, NULL, &tv);
- EXPECT_EQ(1, nfds);
+ const int nfds = util::selectCheck(fd, 5);
+ EXPECT_EQ(1, nfds);
- if (nfds == 1) {
- // Read status
- const ssize_t bytes_read = read(fd, &result, sizeof(result));
- EXPECT_EQ(static_cast<ssize_t>(sizeof(result)), bytes_read);
- }
+ if (nfds == 1) {
+ // Read status
+ const ssize_t bytes_read = read(fd, &result, sizeof(result));
+ EXPECT_EQ(static_cast<ssize_t>(sizeof(result)), bytes_read);
+ }
- return (result);
+ return (result);
}
}