blob: 5eddf1f6b85a950abc79fb7f829e655af779239d [file] [log] [blame]
Alexander Afanasyeve6c65e22015-01-28 19:56:03 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesavento4d0d0962017-12-19 22:23:14 -05002/*
Junxiao Shi68b53852018-07-25 13:56:38 -06003 * Copyright (c) 2013-2018 Regents of the University of California.
Alexander Afanasyeve6c65e22015-01-28 19:56:03 -08004 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6 *
7 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
Davide Pesavento2bf35a62017-04-02 00:41:06 -040020 *
21 * @author Alexander Afanasyev <alexander.afanasyev@ucla.edu>
22 * @author Davide Pesavento <davide.pesavento@lip6.fr>
Alexander Afanasyeve6c65e22015-01-28 19:56:03 -080023 */
24
Junxiao Shi25467942017-06-30 02:53:14 +000025#ifndef NDN_NET_NETWORK_MONITOR_HPP
26#define NDN_NET_NETWORK_MONITOR_HPP
Alexander Afanasyeve6c65e22015-01-28 19:56:03 -080027
Davide Pesavento4d0d0962017-12-19 22:23:14 -050028#include "asio-fwd.hpp"
Junxiao Shi2dc416d2017-07-03 04:46:16 +000029#include "network-interface.hpp"
Davide Pesavento2bf35a62017-04-02 00:41:06 -040030
Davide Pesavento4d0d0962017-12-19 22:23:14 -050031#include <vector>
Alexander Afanasyeve6c65e22015-01-28 19:56:03 -080032
33namespace ndn {
Junxiao Shi25467942017-06-30 02:53:14 +000034namespace net {
Alexander Afanasyeve6c65e22015-01-28 19:56:03 -080035
Junxiao Shi2dc416d2017-07-03 04:46:16 +000036class NetworkMonitorImpl;
Davide Pesavento2bf35a62017-04-02 00:41:06 -040037
Alexander Afanasyeve6c65e22015-01-28 19:56:03 -080038/**
Davide Pesavento474c3b22018-08-25 16:24:43 -040039 * @brief Network interface monitor.
Alexander Afanasyeve6c65e22015-01-28 19:56:03 -080040 *
Davide Pesavento2bf35a62017-04-02 00:41:06 -040041 * Maintains an up-to-date view of every system network interface and notifies when an interface
42 * is added or removed.
Alexander Afanasyeve6c65e22015-01-28 19:56:03 -080043 *
Davide Pesavento43462902017-07-05 02:06:07 -040044 * @note The implementation of this class is highly platform dependent, and not all platform
45 * backends provide all the features. On macOS, @e SystemConfiguration and
46 * @e CFNotificationCenterAddObserver are used (notification of MTU change is not supported).
Davide Pesavento474c3b22018-08-25 16:24:43 -040047 * On Linux, @e netlink notifications from the kernel are used. See getCapabilities() for
Davide Pesavento43462902017-07-05 02:06:07 -040048 * the detailed set of capabilities supported by the platform backend currently in use.
Alexander Afanasyeve6c65e22015-01-28 19:56:03 -080049 */
Davide Pesavento2bf35a62017-04-02 00:41:06 -040050class NetworkMonitor : noncopyable
Alexander Afanasyeve6c65e22015-01-28 19:56:03 -080051{
52public:
53 class Error : public std::runtime_error
54 {
55 public:
Junxiao Shi68b53852018-07-25 13:56:38 -060056 using std::runtime_error::runtime_error;
Alexander Afanasyeve6c65e22015-01-28 19:56:03 -080057 };
58
59 /**
Davide Pesavento2bf35a62017-04-02 00:41:06 -040060 * @brief Construct instance, request enumeration of all network interfaces, and start
Davide Pesavento474c3b22018-08-25 16:24:43 -040061 * monitoring for network state changes.
Davide Pesavento43462902017-07-05 02:06:07 -040062 * @param io io_service instance that will dispatch events
Alexander Afanasyeve6c65e22015-01-28 19:56:03 -080063 */
64 explicit
65 NetworkMonitor(boost::asio::io_service& io);
66
Junxiao Shif4c1eb32017-05-30 17:05:10 +000067 enum Capability : uint32_t {
68 /// NetworkMonitor is not supported and is a no-op
69 CAP_NONE = 0,
70 /// listNetworkInterfaces() and getNetworkInterface() are supported
71 CAP_ENUM = 1 << 0,
72 /// NetworkMonitor onInterfaceAdded and onInterfaceRemoved signals are supported
73 CAP_IF_ADD_REMOVE = 1 << 1,
74 /// NetworkInterface onStateChanged signal is supported
75 CAP_STATE_CHANGE = 1 << 2,
76 /// NetworkInterface onMtuChanged signal is supported
77 CAP_MTU_CHANGE = 1 << 3,
78 /// NetworkInterface onAddressAdded and onAddressRemoved signals are supported
79 CAP_ADDR_ADD_REMOVE = 1 << 4
80 };
81
Davide Pesavento474c3b22018-08-25 16:24:43 -040082 /// Returns a bitwise OR'ed set of #Capability flags supported on the current platform.
Junxiao Shif4c1eb32017-05-30 17:05:10 +000083 uint32_t
84 getCapabilities() const;
85
Davide Pesavento474c3b22018-08-25 16:24:43 -040086 /// Returns the NetworkInterface with the given name, or @c nullptr if it does not exist.
Junxiao Shi2dc416d2017-07-03 04:46:16 +000087 shared_ptr<const NetworkInterface>
Davide Pesavento2bf35a62017-04-02 00:41:06 -040088 getNetworkInterface(const std::string& ifname) const;
89
Davide Pesavento43462902017-07-05 02:06:07 -040090 /**
Davide Pesavento474c3b22018-08-25 16:24:43 -040091 * @brief Lists all network interfaces currently available on the system.
Davide Pesavento43462902017-07-05 02:06:07 -040092 * @warning May return incomplete results if called before the
93 * #onEnumerationCompleted signal has been emitted.
94 */
Junxiao Shi2dc416d2017-07-03 04:46:16 +000095 std::vector<shared_ptr<const NetworkInterface>>
Davide Pesavento2bf35a62017-04-02 00:41:06 -040096 listNetworkInterfaces() const;
97
Junxiao Shi2dc416d2017-07-03 04:46:16 +000098protected:
99 explicit
100 NetworkMonitor(unique_ptr<NetworkMonitorImpl> impl);
101
102 NetworkMonitorImpl&
103 getImpl()
104 {
105 return *m_impl;
106 }
107
108private:
109 const unique_ptr<NetworkMonitorImpl> m_impl;
110 // Intentional violation of code-style rule 1.4: m_impl must be assigned before its signals can
111 // be assigned to references below.
112
Davide Pesavento2bf35a62017-04-02 00:41:06 -0400113public: // signals
Davide Pesavento43462902017-07-05 02:06:07 -0400114 /// Fires when network interfaces enumeration is complete
Junxiao Shi2dc416d2017-07-03 04:46:16 +0000115 util::Signal<NetworkMonitorImpl>& onEnumerationCompleted;
Davide Pesavento2bf35a62017-04-02 00:41:06 -0400116
Davide Pesavento43462902017-07-05 02:06:07 -0400117 /// Fires when a new interface is added
Junxiao Shi2dc416d2017-07-03 04:46:16 +0000118 util::Signal<NetworkMonitorImpl, shared_ptr<const NetworkInterface>>& onInterfaceAdded;
Davide Pesavento2bf35a62017-04-02 00:41:06 -0400119
120 /**
121 * @brief Fires when an interface is removed
Davide Pesavento43462902017-07-05 02:06:07 -0400122 * @note The NetworkInterface object is no longer present in the internal list of
123 * network interfaces when this signal is emitted.
Davide Pesavento2bf35a62017-04-02 00:41:06 -0400124 */
Junxiao Shi2dc416d2017-07-03 04:46:16 +0000125 util::Signal<NetworkMonitorImpl, shared_ptr<const NetworkInterface>>& onInterfaceRemoved;
Davide Pesavento2bf35a62017-04-02 00:41:06 -0400126
Davide Pesavento43462902017-07-05 02:06:07 -0400127 /// @deprecated Only for backward compatibility
Junxiao Shi2dc416d2017-07-03 04:46:16 +0000128 util::Signal<NetworkMonitorImpl>& onNetworkStateChanged;
129};
Alexander Afanasyeve6c65e22015-01-28 19:56:03 -0800130
Junxiao Shi2dc416d2017-07-03 04:46:16 +0000131class NetworkMonitorImpl : noncopyable
132{
133public:
Davide Pesaventoa0b2a2c2018-07-19 01:01:06 -0400134 using Error = NetworkMonitor::Error;
135
Junxiao Shi2dc416d2017-07-03 04:46:16 +0000136 virtual
137 ~NetworkMonitorImpl() = default;
138
139 virtual uint32_t
140 getCapabilities() const = 0;
141
142 virtual shared_ptr<const NetworkInterface>
143 getNetworkInterface(const std::string&) const = 0;
144
145 virtual std::vector<shared_ptr<const NetworkInterface>>
146 listNetworkInterfaces() const = 0;
147
148protected:
149 static shared_ptr<NetworkInterface>
150 makeNetworkInterface();
151
152public:
153 util::Signal<NetworkMonitorImpl> onEnumerationCompleted;
154 util::Signal<NetworkMonitorImpl, shared_ptr<const NetworkInterface>> onInterfaceAdded;
155 util::Signal<NetworkMonitorImpl, shared_ptr<const NetworkInterface>> onInterfaceRemoved;
156 util::Signal<NetworkMonitorImpl> onNetworkStateChanged;
157
158protected:
159 DECLARE_SIGNAL_EMIT(onEnumerationCompleted)
160 DECLARE_SIGNAL_EMIT(onInterfaceAdded)
161 DECLARE_SIGNAL_EMIT(onInterfaceRemoved)
162 DECLARE_SIGNAL_EMIT(onNetworkStateChanged)
Alexander Afanasyeve6c65e22015-01-28 19:56:03 -0800163};
164
Junxiao Shi25467942017-06-30 02:53:14 +0000165} // namespace net
Davide Pesavento2bf35a62017-04-02 00:41:06 -0400166} // namespace ndn
Alexander Afanasyeve6c65e22015-01-28 19:56:03 -0800167
Junxiao Shi25467942017-06-30 02:53:14 +0000168#endif // NDN_NET_NETWORK_MONITOR_HPP