59 #if defined(NDN_CXX_HAVE_COREFOUNDATION_COREFOUNDATION_H) 61 #include <CoreFoundation/CoreFoundation.h> 62 #include <SystemConfiguration/SystemConfiguration.h> 67 class NetworkMonitor::Impl
70 Impl(boost::asio::io_service& io)
72 , cfLoopEvent(scheduler)
80 cfLoopEvent = scheduler.scheduleEvent(time::seconds(1), bind(&Impl::pollCfLoop,
this));
84 afterNotificationCenterEvent(CFNotificationCenterRef center,
void *observer, CFStringRef
name,
85 const void *
object, CFDictionaryRef userInfo)
96 CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0,
true);
102 scheduler::ScopedEventId cfLoopEvent;
106 : m_impl(new Impl(io))
108 m_impl->scheduleCfLoop();
124 CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(),
125 static_cast<void*>(
this),
126 &NetworkMonitor::Impl::afterNotificationCenterEvent,
127 CFSTR(
"com.apple.system.config.network_change"),
129 CFNotificationSuspensionBehaviorDeliverImmediately);
132 NetworkMonitor::~NetworkMonitor()
134 CFNotificationCenterRemoveEveryObserver(CFNotificationCenterGetDarwinNotifyCenter(),
135 static_cast<void*>(
this));
142 #elif defined(NDN_CXX_HAVE_RTNETLINK) 144 #include <boost/asio.hpp> 146 #include <netinet/in.h> 147 #include <linux/netlink.h> 148 #include <linux/rtnetlink.h> 157 const size_t NETLINK_BUFFER_SIZE = 4096;
159 class NetworkMonitor::Impl
166 int fd = ::socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
168 BOOST_THROW_EXCEPTION(Error(std::string(
"Cannot create netlink socket (") +
169 std::strerror(errno) +
")"));
172 addr.nl_family = AF_NETLINK;
173 addr.nl_groups = RTMGRP_LINK |
174 RTMGRP_IPV4_IFADDR | RTMGRP_IPV4_ROUTE |
175 RTMGRP_IPV6_IFADDR | RTMGRP_IPV6_ROUTE;
177 if (::bind(fd, reinterpret_cast<sockaddr*>(&addr),
sizeof(addr)) == -1) {
178 BOOST_THROW_EXCEPTION(Error(std::string(
"Cannot bind on netlink socket (") +
179 std::strerror(errno) +
")"));
184 m_socket.async_read_some(boost::asio::buffer(m_buffer, NETLINK_BUFFER_SIZE),
185 bind(&Impl::onReceiveRtNetlink,
this, _1, _2));
190 onReceiveRtNetlink(
const boost::system::error_code& error,
size_t nBytesReceived)
196 const nlmsghdr* nlh =
reinterpret_cast<const nlmsghdr*
>(m_buffer);
197 while ((NLMSG_OK(nlh, nBytesReceived)) && (nlh->nlmsg_type != NLMSG_DONE)) {
198 if (nlh->nlmsg_type == RTM_NEWADDR || nlh->nlmsg_type == RTM_DELADDR ||
199 nlh->nlmsg_type == RTM_NEWLINK || nlh->nlmsg_type == RTM_DELLINK ||
200 nlh->nlmsg_type == RTM_NEWROUTE || nlh->nlmsg_type == RTM_DELROUTE) {
201 m_nm.onNetworkStateChanged();
204 nlh = NLMSG_NEXT(nlh, nBytesReceived);
207 m_socket.async_read_some(boost::asio::buffer(m_buffer, NETLINK_BUFFER_SIZE),
208 bind(&Impl::onReceiveRtNetlink,
this, _1, _2));
213 uint8_t m_buffer[NETLINK_BUFFER_SIZE];
215 boost::asio::posix::stream_descriptor m_socket;
221 : m_impl(new Impl(*this, io))
225 NetworkMonitor::~NetworkMonitor()
233 #else // do not support network monitoring operations 244 BOOST_THROW_EXCEPTION(
Error(
"Network monitoring is not supported on this platform"));
254 #endif // do not support network monitoring operations Copyright (c) 2011-2015 Regents of the University of California.
NetworkMonitor(boost::asio::io_service &io)
Construct instance and start monitoring for network state changes.
Signal< NetworkMonitor > onNetworkStateChanged
~NetworkMonitor()
Terminate network state monitoring.