1 /* 2 * libjingle 3 * Copyright 2004--2005, Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #ifndef TALK_BASE_NETWORK_H_ 29 #define TALK_BASE_NETWORK_H_ 30 31 #include <deque> 32 #include <map> 33 #include <string> 34 #include <vector> 35 36 #include "talk/base/basictypes.h" 37 #include "talk/base/ipaddress.h" 38 #include "talk/base/messagehandler.h" 39 #include "talk/base/sigslot.h" 40 41 #if defined(POSIX) 42 struct ifaddrs; 43 #endif // defined(POSIX) 44 45 namespace talk_base { 46 47 class Network; 48 class Thread; 49 50 enum AdapterType { 51 // This enum resembles the one in Chromium net::ConnectionType. 52 ADAPTER_TYPE_UNKNOWN = 0, 53 ADAPTER_TYPE_ETHERNET = 1, 54 ADAPTER_TYPE_WIFI = 2, 55 ADAPTER_TYPE_CELLULAR = 3, 56 ADAPTER_TYPE_VPN = 4 57 }; 58 59 // Makes a string key for this network. Used in the network manager's maps. 60 // Network objects are keyed on interface name, network prefix and the 61 // length of that prefix. 62 std::string MakeNetworkKey(const std::string& name, const IPAddress& prefix, 63 int prefix_length); 64 65 // Generic network manager interface. It provides list of local 66 // networks. 67 class NetworkManager { 68 public: 69 typedef std::vector<Network*> NetworkList; 70 71 NetworkManager(); 72 virtual ~NetworkManager(); 73 74 // Called when network list is updated. 75 sigslot::signal0<> SignalNetworksChanged; 76 77 // Indicates a failure when getting list of network interfaces. 78 sigslot::signal0<> SignalError; 79 80 // Start/Stop monitoring of network interfaces 81 // list. SignalNetworksChanged or SignalError is emitted immidiately 82 // after StartUpdating() is called. After that SignalNetworksChanged 83 // is emitted wheneven list of networks changes. 84 virtual void StartUpdating() = 0; 85 virtual void StopUpdating() = 0; 86 87 // Returns the current list of networks available on this machine. 88 // UpdateNetworks() must be called before this method is called. 89 // It makes sure that repeated calls return the same object for a 90 // given network, so that quality is tracked appropriately. Does not 91 // include ignored networks. 92 virtual void GetNetworks(NetworkList* networks) const = 0; 93 94 // Dumps a list of networks available to LS_INFO. DumpNetworks(bool include_ignored)95 virtual void DumpNetworks(bool include_ignored) {} 96 }; 97 98 // Base class for NetworkManager implementations. 99 class NetworkManagerBase : public NetworkManager { 100 public: 101 NetworkManagerBase(); 102 virtual ~NetworkManagerBase(); 103 104 virtual void GetNetworks(std::vector<Network*>* networks) const; ipv6_enabled()105 bool ipv6_enabled() const { return ipv6_enabled_; } set_ipv6_enabled(bool enabled)106 void set_ipv6_enabled(bool enabled) { ipv6_enabled_ = enabled; } 107 108 protected: 109 typedef std::map<std::string, Network*> NetworkMap; 110 // Updates |networks_| with the networks listed in |list|. If 111 // |network_map_| already has a Network object for a network listed 112 // in the |list| then it is reused. Accept ownership of the Network 113 // objects in the |list|. |changed| will be set to true if there is 114 // any change in the network list. 115 void MergeNetworkList(const NetworkList& list, bool* changed); 116 117 private: 118 friend class NetworkTest; 119 void DoUpdateNetworks(); 120 121 NetworkList networks_; 122 NetworkMap networks_map_; 123 bool ipv6_enabled_; 124 }; 125 126 // Basic implementation of the NetworkManager interface that gets list 127 // of networks using OS APIs. 128 class BasicNetworkManager : public NetworkManagerBase, 129 public MessageHandler { 130 public: 131 BasicNetworkManager(); 132 virtual ~BasicNetworkManager(); 133 134 virtual void StartUpdating(); 135 virtual void StopUpdating(); 136 137 // Logs the available networks. 138 virtual void DumpNetworks(bool include_ignored); 139 140 // MessageHandler interface. 141 virtual void OnMessage(Message* msg); started()142 bool started() { return start_count_ > 0; } 143 144 // Sets the network ignore list, which is empty by default. Any network on 145 // the ignore list will be filtered from network enumeration results. set_network_ignore_list(const std::vector<std::string> & list)146 void set_network_ignore_list(const std::vector<std::string>& list) { 147 network_ignore_list_ = list; 148 } 149 #if defined(ANDROID) || defined(LINUX) 150 // Sets the flag for ignoring non-default routes. set_ignore_non_default_routes(bool value)151 void set_ignore_non_default_routes(bool value) { 152 ignore_non_default_routes_ = true; 153 } 154 #endif 155 156 protected: 157 #if defined(POSIX) 158 // Separated from CreateNetworks for tests. 159 void ConvertIfAddrs(ifaddrs* interfaces, 160 bool include_ignored, 161 NetworkList* networks) const; 162 #endif // defined(POSIX) 163 164 // Creates a network object for each network available on the machine. 165 bool CreateNetworks(bool include_ignored, NetworkList* networks) const; 166 167 // Determines if a network should be ignored. 168 bool IsIgnoredNetwork(const Network& network) const; 169 170 private: 171 friend class NetworkTest; 172 173 void DoUpdateNetworks(); 174 175 Thread* thread_; 176 bool sent_first_update_; 177 int start_count_; 178 std::vector<std::string> network_ignore_list_; 179 bool ignore_non_default_routes_; 180 }; 181 182 // Represents a Unix-type network interface, with a name and single address. 183 class Network { 184 public: 185 Network(const std::string& name, const std::string& description, 186 const IPAddress& prefix, int prefix_length); 187 188 Network(const std::string& name, const std::string& description, 189 const IPAddress& prefix, int prefix_length, AdapterType type); 190 191 // Returns the name of the interface this network is associated wtih. name()192 const std::string& name() const { return name_; } 193 194 // Returns the OS-assigned name for this network. This is useful for 195 // debugging but should not be sent over the wire (for privacy reasons). description()196 const std::string& description() const { return description_; } 197 198 // Returns the prefix for this network. prefix()199 const IPAddress& prefix() const { return prefix_; } 200 // Returns the length, in bits, of this network's prefix. prefix_length()201 int prefix_length() const { return prefix_length_; } 202 203 // |key_| has unique value per network interface. Used in sorting network 204 // interfaces. Key is derived from interface name and it's prefix. key()205 std::string key() const { return key_; } 206 207 // Returns the Network's current idea of the 'best' IP it has. 208 // 'Best' currently means the first one added. 209 // TODO: We should be preferring temporary addresses. 210 // Returns an unset IP if this network has no active addresses. ip()211 IPAddress ip() const { 212 if (ips_.size() == 0) { 213 return IPAddress(); 214 } 215 return ips_.at(0); 216 } 217 // Adds an active IP address to this network. Does not check for duplicates. AddIP(const IPAddress & ip)218 void AddIP(const IPAddress& ip) { ips_.push_back(ip); } 219 220 // Sets the network's IP address list. Returns true if new IP addresses were 221 // detected. Passing true to already_changed skips this check. 222 bool SetIPs(const std::vector<IPAddress>& ips, bool already_changed); 223 // Get the list of IP Addresses associated with this network. GetIPs()224 const std::vector<IPAddress>& GetIPs() { return ips_;} 225 // Clear the network's list of addresses. ClearIPs()226 void ClearIPs() { ips_.clear(); } 227 228 // Returns the scope-id of the network's address. 229 // Should only be relevant for link-local IPv6 addresses. scope_id()230 int scope_id() const { return scope_id_; } set_scope_id(int id)231 void set_scope_id(int id) { scope_id_ = id; } 232 233 // Indicates whether this network should be ignored, perhaps because 234 // the IP is 0, or the interface is one we know is invalid. ignored()235 bool ignored() const { return ignored_; } set_ignored(bool ignored)236 void set_ignored(bool ignored) { ignored_ = ignored; } 237 type()238 AdapterType type() const { return type_; } preference()239 int preference() const { return preference_; } set_preference(int preference)240 void set_preference(int preference) { preference_ = preference; } 241 242 // Debugging description of this network 243 std::string ToString() const; 244 245 private: 246 std::string name_; 247 std::string description_; 248 IPAddress prefix_; 249 int prefix_length_; 250 std::string key_; 251 std::vector<IPAddress> ips_; 252 int scope_id_; 253 bool ignored_; 254 AdapterType type_; 255 int preference_; 256 257 friend class NetworkManager; 258 }; 259 260 } // namespace talk_base 261 262 #endif // TALK_BASE_NETWORK_H_ 263