#include <arpa/inet.h>
#include <netinet/in.h>
+#include <sys/ioctl.h>
#include <string.h>
using namespace std;
/// @todo: marginal performance optimization. We could create the set once
/// and then use its copy for select(). Please note that select() modifies
/// provided set to indicated which sockets have something to read.
- /// @note: this can be achieved with FDEventHandler (initialize only if max_fd_ is 0)
- /// and do not clear the state.
+ /// @note: this can be achieved with FDEventHandler (initialize only if
+ /// max_fd_ is 0) and do not clear the state.
for (const IfacePtr& iface : ifaces_) {
for (const SocketInfo& s : iface->getSockets()) {
// Only deal with IPv4 addresses.
/// @todo: marginal performance optimization. We could create the set once
/// and then use its copy for select(). Please note that select() modifies
/// provided set to indicated which sockets have something to read.
- /// @note: this can be achieved with FDEventHandler (initialize only if max_fd_ is 0)
- /// and do not clear the state.
+ /// @note: this can be achieved with FDEventHandler (initialize only if
+ /// max_fd_ is 0) and do not clear the state.
for (const IfacePtr& iface : ifaces_) {
for (const SocketInfo& s : iface->getSockets()) {
// Only deal with IPv6 addresses.
errno = 0;
// Select with null timeouts to wait indefinitely an event
- int result = receiver_fd_event_handler_->waitEvent(0, 0);
+ int result = receiver_fd_event_handler_->waitEvent(0, 0, false);
// Re-check the watch socket.
if (dhcp_receiver_->shouldTerminate()) {
errno = 0;
// Select with null timeouts to wait indefinitely an event
- int result = receiver_fd_event_handler_->waitEvent(0, 0);
+ int result = receiver_fd_event_handler_->waitEvent(0, 0, false);
// Re-check the watch socket.
if (dhcp_receiver_->shouldTerminate()) {
// 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;
}
}
/// @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 unsigned int timeout_sec, bool read_check, bool write_check);
+ int selectCheck(const unsigned int timeout_sec, bool read_check,
+ bool write_check);
/// @brief Retains the fd of the open socket
int socket_fd_;
/// @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
+ /// @param timeout_usec The wait timeout in micro seconds.
+ /// @param use_timeout Flag which indicates if function should wait
+ /// with no timeout (wait forever).
/// @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;
+ virtual int waitEvent(uint32_t timeout_sec, uint32_t timeout_usec = 0,
+ bool use_timeout = true) = 0;
/// @brief Check if file descriptor is ready for read operation.
///
/// @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);
+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
#include <exceptions/exceptions.h>
#include <util/select_event_handler.h>
+#include <cstring>
+
#ifndef FD_COPY
#define FD_COPY(orig, copy) \
do { \
}
}
-int SelectEventHandler::waitEvent(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */) {
+int SelectEventHandler::waitEvent(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */,
+ bool use_timeout /* = true */) {
// 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;
+ struct timeval* select_timeout_p = 0;
+ if (use_timeout) {
+ select_timeout.tv_sec = timeout_sec;
+ select_timeout.tv_usec = timeout_usec;
+ select_timeout_p = &select_timeout;
+ }
FD_COPY(&read_fd_set_, &read_fd_set_data_);
FD_COPY(&write_fd_set_, &write_fd_set_data_);
- return (select(max_fd_ + 1, &read_fd_set_data_, &write_fd_set_data_, 0, &select_timeout));
+ return (select(max_fd_ + 1, &read_fd_set_data_, &write_fd_set_data_, 0, select_timeout_p));
}
bool SelectEventHandler::readReady(int fd) {
/// @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
+ /// @param timeout_usec The wait timeout in micro seconds.
+ /// @param use_timeout Flag which indicates if function should wait
+ /// with no timeout (wait forever).
/// @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);
+ int waitEvent(uint32_t timeout_sec, uint32_t timeout_usec = 0,
+ bool use_timeout = true);
/// @brief Check if file descriptor is ready for read operation.
///