--- /dev/null
+// Copyright (C) 2011-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 <fd_event_handler.h>
+
+namespace isc {
+namespace dhcp {
+
+FDEventHandler::FDEventHandler(HandlerType type) : type_(type) {
+}
+
+FDEventHandler::HandlerType FDEventHandler::type() {
+ return (type_);
+}
+
+} // end of namespace isc::dhcp
+} // end of namespace isc
--- /dev/null
+// Copyright (C) 2010-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 FD_EVENT_HANDLER_H
+#define FD_EVENT_HANDLER_H
+
+#include <boost/shared_ptr.hpp>
+#include <stdint.h>
+
+namespace isc {
+namespace dhcp {
+
+/// @brief File descriptor event handler class handles events for registered
+/// file descriptors.
+class FDEventHandler {
+public:
+ enum HandlerType : uint16_t {
+ TYPE_UNKNOWN = 0,
+ TYPE_SELECT = 1,
+ TYPE_EPOLL = 2, // Linux OS (Linux like OS) only
+ TYPE_KQUEUE = 3, // BSD (BSD like OS) only
+ };
+
+ // @brief Constructor.
+ //
+ // @param type The file descriptor event handler type.
+ FDEventHandler(HandlerType type = TYPE_UNKNOWN);
+
+ // @brief Destructor.
+ virtual ~FDEventHandler() = default;
+
+ // @brief Add file descriptor to watch for events.
+ //
+ // @param fd The file descriptor.
+ // @param read The flag indicating if the file descriptor should be
+ // registered for read ready events.
+ // @param write The flag indicating if the file descriptor should be
+ // registered for write ready events.
+ virtual void addFD(int fd, bool read = true, bool write = false) = 0;
+
+ // @brief Wait for events on registered file descriptors.
+ //
+ // @param timeout_sec The wait timeout in seconds.
+ // @param timeout_usec The wait timeout in micro seconds
+ // @return -1 on error, 0 if no data is available (timeout expired),
+ // 1 if data is ready.
+ virtual int waitEvent(uint32_t timeout_sec, uint32_t timeout_usec = 0) = 0;
+
+ // @brief Check if file descriptor is ready for read operation.
+ //
+ // @param fd The file descriptor.
+ //
+ // @return True if file descriptor is ready for reading.
+ virtual bool readReadyFD(int fd) = 0;
+
+ // @brief Check if file descriptor is ready for write operation.
+ //
+ // @param fd The file descriptor.
+ //
+ // @return True if file descriptor is ready for writing.
+ virtual bool writeReady(int fd) = 0;
+
+ // @brief Clear registered file descriptors.
+ virtual void clear() = 0;
+
+ // @brief Return the event handler type.
+ HandlerType type();
+
+private:
+ // @brief The event handler type.
+ HandlerType type_;
+};
+
+/// @brief Shared pointer to an FD event handler.
+typedef boost::shared_ptr<FDEventHandler> FDEventHandlerPtr;
+
+} // namespace isc::dhcp
+} // namespace isc
+
+#endif // FD_EVENT_HANDLER_H
'classify.cc',
'duid.cc',
'duid_factory.cc',
+ 'fd_event_handler.cc',
'hwaddr.cc',
'iface_mgr.cc',
iface_mgr,
'pkt_filter_inet6.cc',
pkt_filter_cc,
'protocol_util.cc',
+ 'select_event_handler.cc',
include_directories: [include_directories('.')] + INCLUDES,
install: true,
install_dir: LIBDIR,
'docsis3_option_defs.h',
'duid.h',
'duid_factory.h',
+ 'fd_event_handler.h',
'hwaddr.h',
'iface_mgr.h',
'iface_mgr_error_handler.h',
'pkt_filter_lpf.h',
'pkt_template.h',
'protocol_util.h',
+ 'select_event_handler.h',
'socket_info.h',
'std_option_defs.h',
]
--- /dev/null
+// Copyright (C) 2011-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 <exceptions/exceptions.h>
+#include <select_event_handler.h>
+
+namespace isc {
+namespace dhcp {
+
+SelectEventHandler::SelectEventHandler() : FDEventHandler(TYPE_SELECT), max_fd_(0) {
+ clear();
+}
+
+void SelectEventHandler::add(int fd, bool read /* = true */, bool write /* = false */) {
+ if (fd < 0) {
+ isc_throw(BadValue, "invalid negative value for fd");
+ }
+ if (fd >= FD_SETSIZE) {
+ isc_throw(BadValue, "invalid value for fd exceeds maximum allowed " << FD_SETSIZE);
+ }
+ if (read) {
+ // Add this socket to read set
+ FD_SET(fd, &read_fd_set_);
+ }
+ if (write) {
+ // Add this socket to write set
+ FD_SET(fd, &write_fd_set_);
+ }
+}
+
+// @brief Wait for events on registered file descriptors.
+int SelectEventHandler::waitEvent(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */) {
+ // Sanity check for microsecond timeout.
+ if (timeout_usec >= 1000000) {
+ isc_throw(BadValue, "fractional timeout must be shorter than"
+ " one million microseconds");
+ }
+ struct timeval select_timeout;
+ select_timeout.tv_sec = timeout_sec;
+ select_timeout.tv_usec = timeout_usec;
+
+ return (select(max_fd_ + 1, &read_fd_set_, &write_fd_set_, 0, &select_timeout));
+}
+
+// @brief Check if file descriptor is ready for read operation.
+//
+// @param fd The file descriptor.
+//
+// @return True if file descriptor is ready for reading.
+bool SelectEventHandler::readReady(int fd) {
+ return (FD_ISSET(fd, &read_fd_set_));
+}
+
+// @brief Check if file descriptor is ready for write operation.
+//
+// @param fd The file descriptor.
+//
+// @return True if file descriptor is ready for writing.
+bool SelectEventHandler::writeReady(int fd) {
+ return (FD_ISSET(fd, &write_fd_set_));
+}
+
+void SelectEventHandler::clear() {
+ FD_ZERO(&read_fd_set_);
+ FD_ZERO(&write_fd_set_);
+ max_fd_ = 0;
+}
+
+} // end of namespace isc::dhcp
+} // end of namespace isc
--- /dev/null
+// Copyright (C) 2010-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 SELECT_EVENT_HANDLER_H
+#define SELECT_EVENT_HANDLER_H
+
+#include <fd_event_handler.h>
+
+#include <sys/select.h>
+
+namespace isc {
+namespace dhcp {
+
+/// @brief File descriptor event handler class handles events for registered
+/// file descriptors. This class uses the OS select syscall for event handling.
+class SelectEventHandler : public FDEventHandler {
+public:
+ // @brief Constructor.
+ SelectEventHandler();
+
+ // @brief Destructor.
+ virtual ~SelectEventHandler() = default;
+
+ // @brief Add file descriptor to watch for events.
+ //
+ // @param fd The file descriptor.
+ // @param read The flag indicating if the file descriptor should be
+ // registered for read ready events.
+ // @param write The flag indicating if the file descriptor should be
+ // registered for write ready events.
+ void add(int fd, bool read = true, bool write = false);
+
+ // @brief Wait for events on registered file descriptors.
+ //
+ // @param timeout_sec The wait timeout in seconds.
+ // @param timeout_usec The wait timeout in micro seconds
+ // @return -1 on error, 0 if no data is available (timeout expired),
+ // 1 if data is ready.
+ int waitEvent(uint32_t timeout_sec, uint32_t timeout_usec = 0);
+
+ // @brief Check if file descriptor is ready for read operation.
+ //
+ // @param fd The file descriptor.
+ //
+ // @return True if file descriptor is ready for reading.
+ bool readReady(int fd);
+
+ // @brief Check if file descriptor is ready for write operation.
+ //
+ // @param fd The file descriptor.
+ //
+ // @return True if file descriptor is ready for writing.
+ bool writeReady(int fd);
+
+ // @brief Clear registered file descriptors.
+ void clear();
+
+private:
+ // @brief The maximum value of registered file descriptors.
+ int max_fd_;
+
+ // @brief The read event FD set.
+ fd_set read_fd_set_;
+
+ // @brief The write event FD set.
+ fd_set write_fd_set_;
+};
+
+} // namespace isc::dhcp
+} // namespace isc
+
+#endif // SELECT_EVENT_HANDLER_H