Home | History | Annotate | Download | only in base
      1 /*
      2  *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 #ifndef WEBRTC_BASE_NETWORK_H_
     12 #define WEBRTC_BASE_NETWORK_H_
     13 
     14 #include <deque>
     15 #include <map>
     16 #include <string>
     17 #include <vector>
     18 
     19 #include "webrtc/base/basictypes.h"
     20 #include "webrtc/base/ipaddress.h"
     21 #include "webrtc/base/messagehandler.h"
     22 #include "webrtc/base/sigslot.h"
     23 
     24 #if defined(WEBRTC_POSIX)
     25 struct ifaddrs;
     26 #endif  // defined(WEBRTC_POSIX)
     27 
     28 namespace rtc {
     29 
     30 class Network;
     31 class Thread;
     32 
     33 enum AdapterType {
     34   // This enum resembles the one in Chromium net::ConnectionType.
     35   ADAPTER_TYPE_UNKNOWN = 0,
     36   ADAPTER_TYPE_ETHERNET = 1,
     37   ADAPTER_TYPE_WIFI = 2,
     38   ADAPTER_TYPE_CELLULAR = 3,
     39   ADAPTER_TYPE_VPN = 4
     40 };
     41 
     42 // Makes a string key for this network. Used in the network manager's maps.
     43 // Network objects are keyed on interface name, network prefix and the
     44 // length of that prefix.
     45 std::string MakeNetworkKey(const std::string& name, const IPAddress& prefix,
     46                            int prefix_length);
     47 
     48 // Generic network manager interface. It provides list of local
     49 // networks.
     50 class NetworkManager {
     51  public:
     52   typedef std::vector<Network*> NetworkList;
     53 
     54   NetworkManager();
     55   virtual ~NetworkManager();
     56 
     57   // Called when network list is updated.
     58   sigslot::signal0<> SignalNetworksChanged;
     59 
     60   // Indicates a failure when getting list of network interfaces.
     61   sigslot::signal0<> SignalError;
     62 
     63   // Start/Stop monitoring of network interfaces
     64   // list. SignalNetworksChanged or SignalError is emitted immidiately
     65   // after StartUpdating() is called. After that SignalNetworksChanged
     66   // is emitted wheneven list of networks changes.
     67   virtual void StartUpdating() = 0;
     68   virtual void StopUpdating() = 0;
     69 
     70   // Returns the current list of networks available on this machine.
     71   // UpdateNetworks() must be called before this method is called.
     72   // It makes sure that repeated calls return the same object for a
     73   // given network, so that quality is tracked appropriately. Does not
     74   // include ignored networks.
     75   virtual void GetNetworks(NetworkList* networks) const = 0;
     76 
     77   // Dumps a list of networks available to LS_INFO.
     78   virtual void DumpNetworks(bool include_ignored) {}
     79 };
     80 
     81 // Base class for NetworkManager implementations.
     82 class NetworkManagerBase : public NetworkManager {
     83  public:
     84   NetworkManagerBase();
     85   virtual ~NetworkManagerBase();
     86 
     87   virtual void GetNetworks(std::vector<Network*>* networks) const;
     88   bool ipv6_enabled() const { return ipv6_enabled_; }
     89   void set_ipv6_enabled(bool enabled) { ipv6_enabled_ = enabled; }
     90 
     91  protected:
     92   typedef std::map<std::string, Network*> NetworkMap;
     93   // Updates |networks_| with the networks listed in |list|. If
     94   // |network_map_| already has a Network object for a network listed
     95   // in the |list| then it is reused. Accept ownership of the Network
     96   // objects in the |list|. |changed| will be set to true if there is
     97   // any change in the network list.
     98   void MergeNetworkList(const NetworkList& list, bool* changed);
     99 
    100  private:
    101   friend class NetworkTest;
    102   void DoUpdateNetworks();
    103 
    104   NetworkList networks_;
    105   NetworkMap networks_map_;
    106   bool ipv6_enabled_;
    107 };
    108 
    109 // Basic implementation of the NetworkManager interface that gets list
    110 // of networks using OS APIs.
    111 class BasicNetworkManager : public NetworkManagerBase,
    112                             public MessageHandler {
    113  public:
    114   BasicNetworkManager();
    115   virtual ~BasicNetworkManager();
    116 
    117   virtual void StartUpdating();
    118   virtual void StopUpdating();
    119 
    120   // Logs the available networks.
    121   virtual void DumpNetworks(bool include_ignored);
    122 
    123   // MessageHandler interface.
    124   virtual void OnMessage(Message* msg);
    125   bool started() { return start_count_ > 0; }
    126 
    127   // Sets the network ignore list, which is empty by default. Any network on
    128   // the ignore list will be filtered from network enumeration results.
    129   void set_network_ignore_list(const std::vector<std::string>& list) {
    130     network_ignore_list_ = list;
    131   }
    132 #if defined(WEBRTC_LINUX)
    133   // Sets the flag for ignoring non-default routes.
    134   void set_ignore_non_default_routes(bool value) {
    135     ignore_non_default_routes_ = true;
    136   }
    137 #endif
    138 
    139  protected:
    140 #if defined(WEBRTC_POSIX)
    141   // Separated from CreateNetworks for tests.
    142   void ConvertIfAddrs(ifaddrs* interfaces,
    143                       bool include_ignored,
    144                       NetworkList* networks) const;
    145 #endif  // defined(WEBRTC_POSIX)
    146 
    147   // Creates a network object for each network available on the machine.
    148   bool CreateNetworks(bool include_ignored, NetworkList* networks) const;
    149 
    150   // Determines if a network should be ignored.
    151   bool IsIgnoredNetwork(const Network& network) const;
    152 
    153  private:
    154   friend class NetworkTest;
    155 
    156   void DoUpdateNetworks();
    157 
    158   Thread* thread_;
    159   bool sent_first_update_;
    160   int start_count_;
    161   std::vector<std::string> network_ignore_list_;
    162   bool ignore_non_default_routes_;
    163 };
    164 
    165 // Represents a Unix-type network interface, with a name and single address.
    166 class Network {
    167  public:
    168   Network(const std::string& name, const std::string& description,
    169           const IPAddress& prefix, int prefix_length);
    170 
    171   Network(const std::string& name, const std::string& description,
    172           const IPAddress& prefix, int prefix_length, AdapterType type);
    173 
    174   // Returns the name of the interface this network is associated wtih.
    175   const std::string& name() const { return name_; }
    176 
    177   // Returns the OS-assigned name for this network. This is useful for
    178   // debugging but should not be sent over the wire (for privacy reasons).
    179   const std::string& description() const { return description_; }
    180 
    181   // Returns the prefix for this network.
    182   const IPAddress& prefix() const { return prefix_; }
    183   // Returns the length, in bits, of this network's prefix.
    184   int prefix_length() const { return prefix_length_; }
    185 
    186   // |key_| has unique value per network interface. Used in sorting network
    187   // interfaces. Key is derived from interface name and it's prefix.
    188   std::string key() const { return key_; }
    189 
    190   // Returns the Network's current idea of the 'best' IP it has.
    191   // Or return an unset IP if this network has no active addresses.
    192   // Here is the rule on how we mark the IPv6 address as ignorable for WebRTC.
    193   // 1) return all global temporary dynamic and non-deprecrated ones.
    194   // 2) if #1 not available, return global ones.
    195   // 3) if #2 not available, use ULA ipv6 as last resort. (ULA stands
    196   // for unique local address, which is not route-able in open
    197   // internet but might be useful for a close WebRTC deployment.
    198 
    199   // TODO(guoweis): rule #3 actually won't happen at current
    200   // implementation. The reason being that ULA address starting with
    201   // 0xfc 0r 0xfd will be grouped into its own Network. The result of
    202   // that is WebRTC will have one extra Network to generate candidates
    203   // but the lack of rule #3 shouldn't prevent turning on IPv6 since
    204   // ULA should only be tried in a close deployment anyway.
    205 
    206   // Note that when not specifying any flag, it's treated as case global
    207   // IPv6 address
    208   IPAddress GetBestIP() const;
    209 
    210   // Keep the original function here for now.
    211   // TODO(guoweis): Remove this when all callers are migrated to GetBestIP().
    212   IPAddress ip() const { return GetBestIP(); }
    213 
    214   // Adds an active IP address to this network. Does not check for duplicates.
    215   void AddIP(const InterfaceAddress& ip) { ips_.push_back(ip); }
    216 
    217   // Sets the network's IP address list. Returns true if new IP addresses were
    218   // detected. Passing true to already_changed skips this check.
    219   bool SetIPs(const std::vector<InterfaceAddress>& ips, bool already_changed);
    220   // Get the list of IP Addresses associated with this network.
    221   const std::vector<InterfaceAddress>& GetIPs() const { return ips_;}
    222   // Clear the network's list of addresses.
    223   void ClearIPs() { ips_.clear(); }
    224 
    225   // Returns the scope-id of the network's address.
    226   // Should only be relevant for link-local IPv6 addresses.
    227   int scope_id() const { return scope_id_; }
    228   void set_scope_id(int id) { scope_id_ = id; }
    229 
    230   // Indicates whether this network should be ignored, perhaps because
    231   // the IP is 0, or the interface is one we know is invalid.
    232   bool ignored() const { return ignored_; }
    233   void set_ignored(bool ignored) { ignored_ = ignored; }
    234 
    235   AdapterType type() const { return type_; }
    236   int preference() const { return preference_; }
    237   void set_preference(int preference) { preference_ = preference; }
    238 
    239   // Debugging description of this network
    240   std::string ToString() const;
    241 
    242  private:
    243   std::string name_;
    244   std::string description_;
    245   IPAddress prefix_;
    246   int prefix_length_;
    247   std::string key_;
    248   std::vector<InterfaceAddress> ips_;
    249   int scope_id_;
    250   bool ignored_;
    251   AdapterType type_;
    252   int preference_;
    253 
    254   friend class NetworkManager;
    255 };
    256 
    257 }  // namespace rtc
    258 
    259 #endif  // WEBRTC_BASE_NETWORK_H_
    260