|
@@ -170,7 +170,6 @@ bool Iface::delSocket(const uint16_t sockfd) {
|
|
IfaceMgr::IfaceMgr()
|
|
IfaceMgr::IfaceMgr()
|
|
:control_buf_len_(CMSG_SPACE(sizeof(struct in6_pktinfo))),
|
|
:control_buf_len_(CMSG_SPACE(sizeof(struct in6_pktinfo))),
|
|
control_buf_(new char[control_buf_len_]),
|
|
control_buf_(new char[control_buf_len_]),
|
|
- session_socket_(INVALID_SOCKET), session_callback_(NULL),
|
|
|
|
packet_filter_(new PktFilterInet()),
|
|
packet_filter_(new PktFilterInet()),
|
|
packet_filter6_(new PktFilterInet6())
|
|
packet_filter6_(new PktFilterInet6())
|
|
{
|
|
{
|
|
@@ -228,6 +227,37 @@ IfaceMgr::isDirectResponseSupported() const {
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
void
|
|
|
|
+IfaceMgr::addExternalSocket(int socketfd, SessionCallback callback) {
|
|
|
|
+ for (SocketCallbackContainer::iterator s = callbacks_.begin();
|
|
|
|
+ s != callbacks_.end(); ++s) {
|
|
|
|
+
|
|
|
|
+ // There's such a socket description there already.
|
|
|
|
+ // Update the callback and we're done
|
|
|
|
+ if (s->socket_ == socketfd) {
|
|
|
|
+ s->callback_ = callback;
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Add a new entry to the callbacks vector
|
|
|
|
+ SocketCallback x;
|
|
|
|
+ x.socket_ = socketfd;
|
|
|
|
+ x.callback_ = callback;
|
|
|
|
+ callbacks_.push_back(x);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void
|
|
|
|
+IfaceMgr::deleteExternalSocket(int socketfd) {
|
|
|
|
+ for (SocketCallbackContainer::iterator s = callbacks_.begin();
|
|
|
|
+ s != callbacks_.end(); ++s) {
|
|
|
|
+ if (s->socket_ == socketfd) {
|
|
|
|
+ callbacks_.erase(s);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void
|
|
IfaceMgr::setPacketFilter(const PktFilterPtr& packet_filter) {
|
|
IfaceMgr::setPacketFilter(const PktFilterPtr& packet_filter) {
|
|
// Do not allow NULL pointer.
|
|
// Do not allow NULL pointer.
|
|
if (!packet_filter) {
|
|
if (!packet_filter) {
|
|
@@ -815,13 +845,16 @@ IfaceMgr::receive4(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */) {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- // if there is session socket registered...
|
|
|
|
- if (session_socket_ != INVALID_SOCKET) {
|
|
|
|
- // at it to the set as well
|
|
|
|
- FD_SET(session_socket_, &sockets);
|
|
|
|
- if (maxfd < session_socket_)
|
|
|
|
- maxfd = session_socket_;
|
|
|
|
- names << session_socket_ << "(session)";
|
|
|
|
|
|
+ // if there are any session sockets registered...
|
|
|
|
+ if (!callbacks_.empty()) {
|
|
|
|
+ for (SocketCallbackContainer::const_iterator s = callbacks_.begin();
|
|
|
|
+ s != callbacks_.end(); ++s) {
|
|
|
|
+ FD_SET(s->socket_, &sockets);
|
|
|
|
+ if (maxfd < s->socket_) {
|
|
|
|
+ maxfd = s->socket_;
|
|
|
|
+ }
|
|
|
|
+ names << s->socket_ << "(session)";
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
struct timeval select_timeout;
|
|
struct timeval select_timeout;
|
|
@@ -838,18 +871,24 @@ IfaceMgr::receive4(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */) {
|
|
}
|
|
}
|
|
|
|
|
|
// Let's find out which socket has the data
|
|
// Let's find out which socket has the data
|
|
- if ((session_socket_ != INVALID_SOCKET) && (FD_ISSET(session_socket_, &sockets))) {
|
|
|
|
|
|
+ for (SocketCallbackContainer::iterator s = callbacks_.begin();
|
|
|
|
+ s != callbacks_.end(); ++s) {
|
|
|
|
+ if (!FD_ISSET(s->socket_, &sockets)) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
// something received over session socket
|
|
// something received over session socket
|
|
- if (session_callback_) {
|
|
|
|
- // in theory we could call io_service.run_one() here, instead of
|
|
|
|
- // implementing callback mechanism, but that would introduce
|
|
|
|
- // asiolink dependency to libdhcp++ and that is something we want
|
|
|
|
- // to avoid (see CPE market and out long term plans for minimalistic
|
|
|
|
- // implementations.
|
|
|
|
- session_callback_();
|
|
|
|
|
|
+
|
|
|
|
+ // in theory we could call io_service.run_one() here, instead of
|
|
|
|
+ // implementing callback mechanism, but that would introduce
|
|
|
|
+ // asiolink dependency to libdhcp++ and that is something we want
|
|
|
|
+ // to avoid (see CPE market and out long term plans for minimalistic
|
|
|
|
+ // implementations.
|
|
|
|
+ if (s->callback_) {
|
|
|
|
+ s->callback_();
|
|
}
|
|
}
|
|
|
|
|
|
- return (Pkt4Ptr()); // NULL
|
|
|
|
|
|
+ return (Pkt4Ptr());
|
|
}
|
|
}
|
|
|
|
|
|
// Let's find out which interface/socket has the data
|
|
// Let's find out which interface/socket has the data
|
|
@@ -912,13 +951,18 @@ Pkt6Ptr IfaceMgr::receive6(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- // if there is session socket registered...
|
|
|
|
- if (session_socket_ != INVALID_SOCKET) {
|
|
|
|
- // at it to the set as well
|
|
|
|
- FD_SET(session_socket_, &sockets);
|
|
|
|
- if (maxfd < session_socket_)
|
|
|
|
- maxfd = session_socket_;
|
|
|
|
- names << session_socket_ << "(session)";
|
|
|
|
|
|
+ // if there are any session sockets registered...
|
|
|
|
+ if (!callbacks_.empty()) {
|
|
|
|
+ for (SocketCallbackContainer::const_iterator s = callbacks_.begin();
|
|
|
|
+ s != callbacks_.end(); ++s) {
|
|
|
|
+
|
|
|
|
+ // Add it to the set as well
|
|
|
|
+ FD_SET(s->socket_, &sockets);
|
|
|
|
+ if (maxfd < s->socket_) {
|
|
|
|
+ maxfd = s->socket_;
|
|
|
|
+ }
|
|
|
|
+ names << s->socket_ << "(session)";
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
struct timeval select_timeout;
|
|
struct timeval select_timeout;
|
|
@@ -935,18 +979,21 @@ Pkt6Ptr IfaceMgr::receive6(uint32_t timeout_sec, uint32_t timeout_usec /* = 0 */
|
|
}
|
|
}
|
|
|
|
|
|
// Let's find out which socket has the data
|
|
// Let's find out which socket has the data
|
|
- if ((session_socket_ != INVALID_SOCKET) && (FD_ISSET(session_socket_, &sockets))) {
|
|
|
|
- // something received over session socket
|
|
|
|
- if (session_callback_) {
|
|
|
|
- // in theory we could call io_service.run_one() here, instead of
|
|
|
|
- // implementing callback mechanism, but that would introduce
|
|
|
|
- // asiolink dependency to libdhcp++ and that is something we want
|
|
|
|
- // to avoid (see CPE market and out long term plans for minimalistic
|
|
|
|
- // implementations.
|
|
|
|
- session_callback_();
|
|
|
|
|
|
+ for (SocketCallbackContainer::iterator s = callbacks_.begin();
|
|
|
|
+ s != callbacks_.end(); ++s) {
|
|
|
|
+ if (FD_ISSET(s->socket_, &sockets)) {
|
|
|
|
+ // something received over session socket
|
|
|
|
+ if (s->callback_) {
|
|
|
|
+ // in theory we could call io_service.run_one() here, instead of
|
|
|
|
+ // implementing callback mechanism, but that would introduce
|
|
|
|
+ // asiolink dependency to libdhcp++ and that is something we want
|
|
|
|
+ // to avoid (see CPE market and out long term plans for minimalistic
|
|
|
|
+ // implementations.
|
|
|
|
+ s->callback_();
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
- return (Pkt6Ptr()); // NULL
|
|
|
|
|
|
+ return (Pkt6Ptr());
|
|
}
|
|
}
|
|
|
|
|
|
// Let's find out which interface/socket has the data
|
|
// Let's find out which interface/socket has the data
|