blob: f45c4d534ae31f49bfd861a46cc8abbc4515393b [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/*
Davide Pesaventofcd3e442023-03-10 18:44:11 -05003 * Copyright (c) 2013-2023 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
Davide Pesavento09904412021-03-24 16:40:53 -040025#ifndef NDN_CXX_NET_NETWORK_MONITOR_HPP
26#define NDN_CXX_NET_NETWORK_MONITOR_HPP
Alexander Afanasyeve6c65e22015-01-28 19:56:03 -080027
Junxiao Shi1d23ff92018-12-17 13:21:08 -070028#include "ndn-cxx/detail/asio-fwd.hpp"
Davide Pesavento7e780642018-11-24 15:51:34 -050029#include "ndn-cxx/net/network-interface.hpp"
Davide Pesavento47ce2ee2023-05-09 01:33:33 -040030#include "ndn-cxx/util/signal/emit.hpp"
31#include "ndn-cxx/util/signal/signal.hpp"
Davide Pesavento2bf35a62017-04-02 00:41:06 -040032
Davide Pesavento4d0d0962017-12-19 22:23:14 -050033#include <vector>
Alexander Afanasyeve6c65e22015-01-28 19:56:03 -080034
Davide Pesavento47ce2ee2023-05-09 01:33:33 -040035namespace ndn::net {
Alexander Afanasyeve6c65e22015-01-28 19:56:03 -080036
Junxiao Shi2dc416d2017-07-03 04:46:16 +000037class NetworkMonitorImpl;
Davide Pesavento2bf35a62017-04-02 00:41:06 -040038
Alexander Afanasyeve6c65e22015-01-28 19:56:03 -080039/**
Davide Pesavento474c3b22018-08-25 16:24:43 -040040 * @brief Network interface monitor.
Alexander Afanasyeve6c65e22015-01-28 19:56:03 -080041 *
Davide Pesavento2bf35a62017-04-02 00:41:06 -040042 * Maintains an up-to-date view of every system network interface and notifies when an interface
43 * is added or removed.
Alexander Afanasyeve6c65e22015-01-28 19:56:03 -080044 *
Davide Pesavento43462902017-07-05 02:06:07 -040045 * @note The implementation of this class is highly platform dependent, and not all platform
46 * backends provide all the features. On macOS, @e SystemConfiguration and
47 * @e CFNotificationCenterAddObserver are used (notification of MTU change is not supported).
Davide Pesavento474c3b22018-08-25 16:24:43 -040048 * On Linux, @e netlink notifications from the kernel are used. See getCapabilities() for
Davide Pesavento43462902017-07-05 02:06:07 -040049 * the detailed set of capabilities supported by the platform backend currently in use.
Alexander Afanasyeve6c65e22015-01-28 19:56:03 -080050 */
Davide Pesavento2bf35a62017-04-02 00:41:06 -040051class NetworkMonitor : noncopyable
Alexander Afanasyeve6c65e22015-01-28 19:56:03 -080052{
53public:
54 class Error : public std::runtime_error
55 {
56 public:
Junxiao Shi68b53852018-07-25 13:56:38 -060057 using std::runtime_error::runtime_error;
Alexander Afanasyeve6c65e22015-01-28 19:56:03 -080058 };
59
60 /**
Davide Pesavento2bf35a62017-04-02 00:41:06 -040061 * @brief Construct instance, request enumeration of all network interfaces, and start
Davide Pesavento474c3b22018-08-25 16:24:43 -040062 * monitoring for network state changes.
Davide Pesavento43462902017-07-05 02:06:07 -040063 * @param io io_service instance that will dispatch events
Alexander Afanasyeve6c65e22015-01-28 19:56:03 -080064 */
65 explicit
66 NetworkMonitor(boost::asio::io_service& io);
67
Junxiao Shif4c1eb32017-05-30 17:05:10 +000068 enum Capability : uint32_t {
69 /// NetworkMonitor is not supported and is a no-op
70 CAP_NONE = 0,
71 /// listNetworkInterfaces() and getNetworkInterface() are supported
72 CAP_ENUM = 1 << 0,
73 /// NetworkMonitor onInterfaceAdded and onInterfaceRemoved signals are supported
74 CAP_IF_ADD_REMOVE = 1 << 1,
75 /// NetworkInterface onStateChanged signal is supported
76 CAP_STATE_CHANGE = 1 << 2,
77 /// NetworkInterface onMtuChanged signal is supported
78 CAP_MTU_CHANGE = 1 << 3,
79 /// NetworkInterface onAddressAdded and onAddressRemoved signals are supported
80 CAP_ADDR_ADD_REMOVE = 1 << 4
81 };
82
Davide Pesavento474c3b22018-08-25 16:24:43 -040083 /// Returns a bitwise OR'ed set of #Capability flags supported on the current platform.
Junxiao Shif4c1eb32017-05-30 17:05:10 +000084 uint32_t
85 getCapabilities() const;
86
Davide Pesavento474c3b22018-08-25 16:24:43 -040087 /// Returns the NetworkInterface with the given name, or @c nullptr if it does not exist.
Junxiao Shi2dc416d2017-07-03 04:46:16 +000088 shared_ptr<const NetworkInterface>
Davide Pesavento2bf35a62017-04-02 00:41:06 -040089 getNetworkInterface(const std::string& ifname) const;
90
Davide Pesavento43462902017-07-05 02:06:07 -040091 /**
Davide Pesavento474c3b22018-08-25 16:24:43 -040092 * @brief Lists all network interfaces currently available on the system.
Davide Pesavento43462902017-07-05 02:06:07 -040093 * @warning May return incomplete results if called before the
94 * #onEnumerationCompleted signal has been emitted.
95 */
Davide Pesaventofcd3e442023-03-10 18:44:11 -050096 [[nodiscard]] std::vector<shared_ptr<const NetworkInterface>>
Davide Pesavento2bf35a62017-04-02 00:41:06 -040097 listNetworkInterfaces() const;
98
Junxiao Shi2dc416d2017-07-03 04:46:16 +000099protected:
100 explicit
101 NetworkMonitor(unique_ptr<NetworkMonitorImpl> impl);
102
103 NetworkMonitorImpl&
104 getImpl()
105 {
106 return *m_impl;
107 }
108
109private:
110 const unique_ptr<NetworkMonitorImpl> m_impl;
111 // Intentional violation of code-style rule 1.4: m_impl must be assigned before its signals can
112 // be assigned to references below.
113
Davide Pesavento2bf35a62017-04-02 00:41:06 -0400114public: // signals
Davide Pesaventoc9650e42019-04-30 17:57:26 -0400115 /// Fires when the enumeration of all network interfaces on the system is complete.
Davide Pesavento47ce2ee2023-05-09 01:33:33 -0400116 signal::Signal<NetworkMonitorImpl>& onEnumerationCompleted;
Davide Pesavento2bf35a62017-04-02 00:41:06 -0400117
Davide Pesaventoc9650e42019-04-30 17:57:26 -0400118 /// Fires whenever a new interface is detected on the system.
Davide Pesavento47ce2ee2023-05-09 01:33:33 -0400119 signal::Signal<NetworkMonitorImpl, shared_ptr<const NetworkInterface>>& onInterfaceAdded;
Davide Pesavento2bf35a62017-04-02 00:41:06 -0400120
121 /**
Davide Pesaventoc9650e42019-04-30 17:57:26 -0400122 * @brief Fires whenever an interface disappears from the system.
123 * @note The NetworkInterface object has already been removed from the list
124 * returned by listNetworkInterfaces() when this signal is emitted.
Davide Pesavento2bf35a62017-04-02 00:41:06 -0400125 */
Davide Pesavento47ce2ee2023-05-09 01:33:33 -0400126 signal::Signal<NetworkMonitorImpl, shared_ptr<const NetworkInterface>>& onInterfaceRemoved;
Davide Pesavento2bf35a62017-04-02 00:41:06 -0400127
Davide Pesavento43462902017-07-05 02:06:07 -0400128 /// @deprecated Only for backward compatibility
Davide Pesavento47ce2ee2023-05-09 01:33:33 -0400129 signal::Signal<NetworkMonitorImpl>& onNetworkStateChanged;
Junxiao Shi2dc416d2017-07-03 04:46:16 +0000130};
Alexander Afanasyeve6c65e22015-01-28 19:56:03 -0800131
Junxiao Shi2dc416d2017-07-03 04:46:16 +0000132class NetworkMonitorImpl : noncopyable
133{
134public:
Davide Pesaventoa0b2a2c2018-07-19 01:01:06 -0400135 using Error = NetworkMonitor::Error;
136
Junxiao Shi2dc416d2017-07-03 04:46:16 +0000137 virtual
138 ~NetworkMonitorImpl() = default;
139
140 virtual uint32_t
141 getCapabilities() const = 0;
142
143 virtual shared_ptr<const NetworkInterface>
144 getNetworkInterface(const std::string&) const = 0;
145
146 virtual std::vector<shared_ptr<const NetworkInterface>>
147 listNetworkInterfaces() const = 0;
148
149protected:
150 static shared_ptr<NetworkInterface>
151 makeNetworkInterface();
152
153public:
Davide Pesavento47ce2ee2023-05-09 01:33:33 -0400154 signal::Signal<NetworkMonitorImpl> onEnumerationCompleted;
155 signal::Signal<NetworkMonitorImpl, shared_ptr<const NetworkInterface>> onInterfaceAdded;
156 signal::Signal<NetworkMonitorImpl, shared_ptr<const NetworkInterface>> onInterfaceRemoved;
157 signal::Signal<NetworkMonitorImpl> onNetworkStateChanged;
Junxiao Shi2dc416d2017-07-03 04:46:16 +0000158
159protected:
160 DECLARE_SIGNAL_EMIT(onEnumerationCompleted)
161 DECLARE_SIGNAL_EMIT(onInterfaceAdded)
162 DECLARE_SIGNAL_EMIT(onInterfaceRemoved)
163 DECLARE_SIGNAL_EMIT(onNetworkStateChanged)
Alexander Afanasyeve6c65e22015-01-28 19:56:03 -0800164};
165
Davide Pesavento47ce2ee2023-05-09 01:33:33 -0400166} // namespace ndn::net
Alexander Afanasyeve6c65e22015-01-28 19:56:03 -0800167
Davide Pesavento09904412021-03-24 16:40:53 -0400168#endif // NDN_CXX_NET_NETWORK_MONITOR_HPP