• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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