isc_throw(BadValue, "Attempted to install callback for invalid socket "
<< socketfd);
}
+ std::lock_guard<std::mutex> lock(callbacks_mutex_);
BOOST_FOREACH(SocketCallbackInfo s, callbacks_) {
// There's such a socket description there already.
// Update the callback and we're done
void
IfaceMgr::deleteExternalSocket(int socketfd) {
+ std::lock_guard<std::mutex> lock(callbacks_mutex_);
+ deleteExternalSocketInternal(socketfd);
+}
+
+void
+IfaceMgr::deleteExternalSocketInternal(int socketfd) {
for (SocketCallbackInfoContainer::iterator s = callbacks_.begin();
s != callbacks_.end(); ++s) {
if (s->socket_ == socketfd) {
int
IfaceMgr::purgeBadSockets() {
+ std::lock_guard<std::mutex> lock(callbacks_mutex_);
std::vector<int> bad_fds;
for (SocketCallbackInfo s : callbacks_) {
errno = 0;
}
for (auto bad_fd : bad_fds) {
- deleteExternalSocket(bad_fd);
+ deleteExternalSocketInternal(bad_fd);
}
return (bad_fds.size());
void
IfaceMgr::deleteAllExternalSockets() {
+ std::lock_guard<std::mutex> lock(callbacks_mutex_);
callbacks_.clear();
}
FD_ZERO(&sockets);
// if there are any callbacks for external sockets registered...
- if (!callbacks_.empty()) {
- BOOST_FOREACH(SocketCallbackInfo s, callbacks_) {
- addFDtoSet(s.socket_, maxfd, &sockets);
+ {
+ std::lock_guard<std::mutex> lock(callbacks_mutex_);
+ if (!callbacks_.empty()) {
+ BOOST_FOREACH(SocketCallbackInfo s, callbacks_) {
+ addFDtoSet(s.socket_, maxfd, &sockets);
+ }
}
}
}
// Let's find out which external socket has the data
+ std::lock_guard<std::mutex> lock(callbacks_mutex_);
BOOST_FOREACH(SocketCallbackInfo s, callbacks_) {
if (!FD_ISSET(s.socket_, &sockets)) {
continue;
}
// if there are any callbacks for external sockets registered...
- if (!callbacks_.empty()) {
- BOOST_FOREACH(SocketCallbackInfo s, callbacks_) {
- // Add this socket to listening set
- addFDtoSet(s.socket_, maxfd, &sockets);
+ {
+ std::lock_guard<std::mutex> lock(callbacks_mutex_);
+ if (!callbacks_.empty()) {
+ BOOST_FOREACH(SocketCallbackInfo s, callbacks_) {
+ // Add this socket to listening set
+ addFDtoSet(s.socket_, maxfd, &sockets);
+ }
}
}
}
// Let's find out which socket has the data
- BOOST_FOREACH(SocketCallbackInfo s, callbacks_) {
- if (!FD_ISSET(s.socket_, &sockets)) {
- continue;
- }
+ {
+ std::lock_guard<std::mutex> lock(callbacks_mutex_);
+ BOOST_FOREACH(SocketCallbackInfo s, callbacks_) {
+ if (!FD_ISSET(s.socket_, &sockets)) {
+ continue;
+ }
- // something received over external socket
+ // something received over external socket
- // Calling the external socket's callback provides its service
- // layer access without integrating any specific features
- // in IfaceMgr
- if (s.callback_) {
- s.callback_(s.socket_);
- }
+ // Calling the external socket's callback provides its service
+ // layer access without integrating any specific features
+ // in IfaceMgr
+ if (s.callback_) {
+ s.callback_(s.socket_);
+ }
- return (Pkt4Ptr());
+ return (Pkt4Ptr());
+ }
}
// Let's find out which interface/socket has the data
}
// if there are any callbacks for external sockets registered...
- if (!callbacks_.empty()) {
- BOOST_FOREACH(SocketCallbackInfo s, callbacks_) {
- // Add it to the set as well
- addFDtoSet(s.socket_, maxfd, &sockets);
+ {
+ std::lock_guard<std::mutex> lock(callbacks_mutex_);
+ if (!callbacks_.empty()) {
+ BOOST_FOREACH(SocketCallbackInfo s, callbacks_) {
+ // Add it to the set as well
+ addFDtoSet(s.socket_, maxfd, &sockets);
+ }
}
}
}
// Let's find out which socket has the data
- BOOST_FOREACH(SocketCallbackInfo s, callbacks_) {
- if (!FD_ISSET(s.socket_, &sockets)) {
- continue;
- }
+ {
+ std::lock_guard<std::mutex> lock(callbacks_mutex_);
+ BOOST_FOREACH(SocketCallbackInfo s, callbacks_) {
+ if (!FD_ISSET(s.socket_, &sockets)) {
+ continue;
+ }
+
+ // something received over external socket
- // something received over external socket
+ // Calling the external socket's callback provides its service
+ // layer access without integrating any specific features
+ // in IfaceMgr
+ if (s.callback_) {
+ s.callback_(s.socket_);
+ }
- // Calling the external socket's callback provides its service
- // layer access without integrating any specific features
- // in IfaceMgr
- if (s.callback_) {
- s.callback_(s.socket_);
+ return (Pkt6Ptr());
}
-
- return (Pkt6Ptr());
}
// Let's find out which interface/socket has the data
FD_ZERO(&sockets);
// if there are any callbacks for external sockets registered...
- if (!callbacks_.empty()) {
- BOOST_FOREACH(SocketCallbackInfo s, callbacks_) {
- // Add it to the set as well
- addFDtoSet(s.socket_, maxfd, &sockets);
+ {
+ std::lock_guard<std::mutex> lock(callbacks_mutex_);
+ if (!callbacks_.empty()) {
+ BOOST_FOREACH(SocketCallbackInfo s, callbacks_) {
+ // Add it to the set as well
+ addFDtoSet(s.socket_, maxfd, &sockets);
+ }
}
}
}
// Let's find out which external socket has the data
+ std::lock_guard<std::mutex> lock(callbacks_mutex_);
BOOST_FOREACH(SocketCallbackInfo s, callbacks_) {
if (!FD_ISSET(s.socket_, &sockets)) {
continue;
-// Copyright (C) 2011-2019 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2011-2020 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
#include <list>
#include <vector>
+#include <mutex>
namespace isc {
void addExternalSocket(int socketfd, SocketCallback callback);
/// @brief Deletes external socket
+ ///
+ /// @param socketfd socket descriptor
void deleteExternalSocket(int socketfd);
/// @brief Scans registered socket set and removes any that are invalid.
/// @param socket_info structure holding socket information
void receiveDHCP6Packet(const SocketInfo& socket_info);
+ /// @brief Deletes external socket with the callbacks_mutex_ taken
+ ///
+ /// @param socketfd socket descriptor
+ void deleteExternalSocketInternal(int socketfd);
+
/// Holds instance of a class derived from PktFilter, used by the
/// IfaceMgr to open sockets and send/receive packets through these
/// sockets. It is possible to supply custom object using
/// @brief Contains list of callbacks for external sockets
SocketCallbackInfoContainer callbacks_;
+ /// @brief Mutex to protect callbacks_ against concurrent access
+ std::mutex callbacks_mutex_;
+
/// @brief Indicates if the IfaceMgr is in the test mode.
bool test_mode_;