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 {
RelayCredentialsRelayCredentials81   RelayCredentials() {}
RelayCredentialsRelayCredentials82   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 {
RelayServerConfigRelayServerConfig92   RelayServerConfig(RelayType type) : type(type), priority(0) {}
93 
RelayServerConfigRelayServerConfig94   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.
~PortAllocatorSession()121   virtual ~PortAllocatorSession() {}
122 
flags()123   uint32_t flags() const { return flags_; }
set_flags(uint32_t flags)124   void set_flags(uint32_t flags) { flags_ = flags; }
content_name()125   std::string content_name() const { return content_name_; }
component()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 
generation()141   virtual uint32_t generation() { return generation_; }
set_generation(uint32_t generation)142   virtual void set_generation(uint32_t generation) { generation_ = generation; }
143   sigslot::signal1<PortAllocatorSession*> SignalDestroyed;
144 
ice_ufrag()145   const std::string& ice_ufrag() const { return ice_ufrag_; }
ice_pwd()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.
username()151   const std::string& username() const { return ice_ufrag_; }
password()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:
PortAllocator()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   }
~PortAllocator()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 
flags()196   uint32_t flags() const { return flags_; }
set_flags(uint32_t flags)197   void set_flags(uint32_t flags) { flags_ = flags; }
198 
user_agent()199   const std::string& user_agent() const { return agent_; }
proxy()200   const rtc::ProxyInfo& proxy() const { return proxy_; }
set_proxy(const std::string & agent,const rtc::ProxyInfo & 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.
min_port()207   int min_port() const { return min_port_; }
max_port()208   int max_port() const { return max_port_; }
SetPortRange(int min_port,int 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 
step_delay()219   uint32_t step_delay() const { return step_delay_; }
set_step_delay(uint32_t delay)220   void set_step_delay(uint32_t delay) { step_delay_ = delay; }
221 
allow_tcp_listen()222   bool allow_tcp_listen() const { return allow_tcp_listen_; }
set_allow_tcp_listen(bool allow_tcp_listen)223   void set_allow_tcp_listen(bool allow_tcp_listen) {
224     allow_tcp_listen_ = allow_tcp_listen;
225   }
226 
candidate_filter()227   uint32_t candidate_filter() { return candidate_filter_; }
set_candidate_filter(uint32_t 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.
origin()235   const std::string& origin() const { return origin_; }
set_origin(const std::string & 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