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_P2P_BASE_PORTALLOCATOR_H_
     12 #define WEBRTC_P2P_BASE_PORTALLOCATOR_H_
     13 
     14 #include <string>
     15 #include <vector>
     16 
     17 #include "webrtc/p2p/base/port.h"
     18 #include "webrtc/p2p/base/portinterface.h"
     19 #include "webrtc/base/helpers.h"
     20 #include "webrtc/base/proxyinfo.h"
     21 #include "webrtc/base/sigslot.h"
     22 
     23 namespace cricket {
     24 
     25 // PortAllocator is responsible for allocating Port types for a given
     26 // P2PSocket. It also handles port freeing.
     27 //
     28 // Clients can override this class to control port allocation, including
     29 // what kinds of ports are allocated.
     30 
     31 enum {
     32   // Disable local UDP ports. This doesn't impact how we connect to relay
     33   // servers.
     34   PORTALLOCATOR_DISABLE_UDP = 0x01,
     35   PORTALLOCATOR_DISABLE_STUN = 0x02,
     36   PORTALLOCATOR_DISABLE_RELAY = 0x04,
     37   // Disable local TCP ports. This doesn't impact how we connect to relay
     38   // servers.
     39   PORTALLOCATOR_DISABLE_TCP = 0x08,
     40   PORTALLOCATOR_ENABLE_SHAKER = 0x10,
     41   PORTALLOCATOR_ENABLE_IPV6 = 0x40,
     42   // TODO(pthatcher): Remove this once it's no longer used in:
     43   // remoting/client/plugin/pepper_port_allocator.cc
     44   // remoting/protocol/chromium_port_allocator.cc
     45   // remoting/test/fake_port_allocator.cc
     46   // It's a no-op and is no longer needed.
     47   PORTALLOCATOR_ENABLE_SHARED_UFRAG = 0x80,
     48   PORTALLOCATOR_ENABLE_SHARED_SOCKET = 0x100,
     49   PORTALLOCATOR_ENABLE_STUN_RETRANSMIT_ATTRIBUTE = 0x200,
     50   // When specified, we'll only allocate the STUN candidate for the public
     51   // interface as seen by regular http traffic and the HOST candidate associated
     52   // with the default local interface.
     53   PORTALLOCATOR_DISABLE_ADAPTER_ENUMERATION = 0x400,
     54   // When specified along with PORTALLOCATOR_DISABLE_ADAPTER_ENUMERATION, the
     55   // default local candidate mentioned above will not be allocated. Only the
     56   // STUN candidate will be.
     57   PORTALLOCATOR_DISABLE_DEFAULT_LOCAL_CANDIDATE = 0x800,
     58   // Disallow use of UDP when connecting to a relay server. Since proxy servers
     59   // usually don't handle UDP, using UDP will leak the IP address.
     60   PORTALLOCATOR_DISABLE_UDP_RELAY = 0x1000,
     61 };
     62 
     63 const uint32_t kDefaultPortAllocatorFlags = 0;
     64 
     65 const uint32_t kDefaultStepDelay = 1000;  // 1 sec step delay.
     66 // As per RFC 5245 Appendix B.1, STUN transactions need to be paced at certain
     67 // internal. Less than 20ms is not acceptable. We choose 50ms as our default.
     68 const uint32_t kMinimumStepDelay = 50;
     69 
     70 // CF = CANDIDATE FILTER
     71 enum {
     72   CF_NONE = 0x0,
     73   CF_HOST = 0x1,
     74   CF_REFLEXIVE = 0x2,
     75   CF_RELAY = 0x4,
     76   CF_ALL = 0x7,
     77 };
     78 
     79 // TODO(deadbeef): Rename to TurnCredentials (and username to ufrag).
     80 struct RelayCredentials {
     81   RelayCredentials() {}
     82   RelayCredentials(const std::string& username, const std::string& password)
     83       : username(username), password(password) {}
     84 
     85   std::string username;
     86   std::string password;
     87 };
     88 
     89 typedef std::vector<ProtocolAddress> PortList;
     90 // TODO(deadbeef): Rename to TurnServerConfig.
     91 struct RelayServerConfig {
     92   RelayServerConfig(RelayType type) : type(type), priority(0) {}
     93 
     94   RelayServerConfig(const std::string& address,
     95                     int port,
     96                     const std::string& username,
     97                     const std::string& password,
     98                     ProtocolType proto,
     99                     bool secure)
    100       : type(RELAY_TURN), credentials(username, password) {
    101     ports.push_back(
    102         ProtocolAddress(rtc::SocketAddress(address, port), proto, secure));
    103   }
    104 
    105   RelayType type;
    106   PortList ports;
    107   RelayCredentials credentials;
    108   int priority;
    109 };
    110 
    111 class PortAllocatorSession : public sigslot::has_slots<> {
    112  public:
    113   // Content name passed in mostly for logging and debugging.
    114   PortAllocatorSession(const std::string& content_name,
    115                        int component,
    116                        const std::string& ice_ufrag,
    117                        const std::string& ice_pwd,
    118                        uint32_t flags);
    119 
    120   // Subclasses should clean up any ports created.
    121   virtual ~PortAllocatorSession() {}
    122 
    123   uint32_t flags() const { return flags_; }
    124   void set_flags(uint32_t flags) { flags_ = flags; }
    125   std::string content_name() const { return content_name_; }
    126   int component() const { return component_; }
    127 
    128   // Starts gathering STUN and Relay configurations.
    129   virtual void StartGettingPorts() = 0;
    130   virtual void StopGettingPorts() = 0;
    131   // Only stop the existing gathering process but may start new ones if needed.
    132   virtual void ClearGettingPorts() = 0;
    133   // Whether the process of getting ports has been stopped.
    134   virtual bool IsGettingPorts() = 0;
    135 
    136   sigslot::signal2<PortAllocatorSession*, PortInterface*> SignalPortReady;
    137   sigslot::signal2<PortAllocatorSession*,
    138                    const std::vector<Candidate>&> SignalCandidatesReady;
    139   sigslot::signal1<PortAllocatorSession*> SignalCandidatesAllocationDone;
    140 
    141   virtual uint32_t generation() { return generation_; }
    142   virtual void set_generation(uint32_t generation) { generation_ = generation; }
    143   sigslot::signal1<PortAllocatorSession*> SignalDestroyed;
    144 
    145   const std::string& ice_ufrag() const { return ice_ufrag_; }
    146   const std::string& ice_pwd() const { return ice_pwd_; }
    147 
    148  protected:
    149   // TODO(deadbeef): Get rid of these when everyone switches to ice_ufrag and
    150   // ice_pwd.
    151   const std::string& username() const { return ice_ufrag_; }
    152   const std::string& password() const { return ice_pwd_; }
    153 
    154   std::string content_name_;
    155   int component_;
    156 
    157  private:
    158   uint32_t flags_;
    159   uint32_t generation_;
    160   std::string ice_ufrag_;
    161   std::string ice_pwd_;
    162 };
    163 
    164 class PortAllocator : public sigslot::has_slots<> {
    165  public:
    166   PortAllocator() :
    167       flags_(kDefaultPortAllocatorFlags),
    168       min_port_(0),
    169       max_port_(0),
    170       step_delay_(kDefaultStepDelay),
    171       allow_tcp_listen_(true),
    172       candidate_filter_(CF_ALL) {
    173     // This will allow us to have old behavior on non webrtc clients.
    174   }
    175   virtual ~PortAllocator() {}
    176 
    177   // Set STUN and TURN servers to be used in future sessions.
    178   virtual void SetIceServers(
    179       const ServerAddresses& stun_servers,
    180       const std::vector<RelayServerConfig>& turn_servers) = 0;
    181 
    182   // Sets the network types to ignore.
    183   // Values are defined by the AdapterType enum.
    184   // For instance, calling this with
    185   // ADAPTER_TYPE_ETHERNET | ADAPTER_TYPE_LOOPBACK will ignore Ethernet and
    186   // loopback interfaces.
    187   virtual void SetNetworkIgnoreMask(int network_ignore_mask) = 0;
    188 
    189   PortAllocatorSession* CreateSession(
    190       const std::string& sid,
    191       const std::string& content_name,
    192       int component,
    193       const std::string& ice_ufrag,
    194       const std::string& ice_pwd);
    195 
    196   uint32_t flags() const { return flags_; }
    197   void set_flags(uint32_t flags) { flags_ = flags; }
    198 
    199   const std::string& user_agent() const { return agent_; }
    200   const rtc::ProxyInfo& proxy() const { return proxy_; }
    201   void set_proxy(const std::string& agent, const rtc::ProxyInfo& proxy) {
    202     agent_ = agent;
    203     proxy_ = proxy;
    204   }
    205 
    206   // Gets/Sets the port range to use when choosing client ports.
    207   int min_port() const { return min_port_; }
    208   int max_port() const { return max_port_; }
    209   bool SetPortRange(int min_port, int max_port) {
    210     if (min_port > max_port) {
    211       return false;
    212     }
    213 
    214     min_port_ = min_port;
    215     max_port_ = max_port;
    216     return true;
    217   }
    218 
    219   uint32_t step_delay() const { return step_delay_; }
    220   void set_step_delay(uint32_t delay) { step_delay_ = delay; }
    221 
    222   bool allow_tcp_listen() const { return allow_tcp_listen_; }
    223   void set_allow_tcp_listen(bool allow_tcp_listen) {
    224     allow_tcp_listen_ = allow_tcp_listen;
    225   }
    226 
    227   uint32_t candidate_filter() { return candidate_filter_; }
    228   bool set_candidate_filter(uint32_t filter) {
    229     // TODO(mallinath) - Do transition check?
    230     candidate_filter_ = filter;
    231     return true;
    232   }
    233 
    234   // Gets/Sets the Origin value used for WebRTC STUN requests.
    235   const std::string& origin() const { return origin_; }
    236   void set_origin(const std::string& origin) { origin_ = origin; }
    237 
    238  protected:
    239   virtual PortAllocatorSession* CreateSessionInternal(
    240       const std::string& content_name,
    241       int component,
    242       const std::string& ice_ufrag,
    243       const std::string& ice_pwd) = 0;
    244 
    245   uint32_t flags_;
    246   std::string agent_;
    247   rtc::ProxyInfo proxy_;
    248   int min_port_;
    249   int max_port_;
    250   uint32_t step_delay_;
    251   bool allow_tcp_listen_;
    252   uint32_t candidate_filter_;
    253   std::string origin_;
    254 };
    255 
    256 }  // namespace cricket
    257 
    258 #endif  // WEBRTC_P2P_BASE_PORTALLOCATOR_H_
    259