blob: 879657081a5372f1248178964523c0d5ed2d1539 [file] [log] [blame]
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001/*
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
Taylor Brandstetter48e9d052016-05-12 10:19:38 -070014#include <deque>
15#include <memory>
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000016#include <string>
17#include <vector>
18
deadbeef653b8e02015-11-11 12:55:10 -080019#include "webrtc/p2p/base/port.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000020#include "webrtc/p2p/base/portinterface.h"
21#include "webrtc/base/helpers.h"
22#include "webrtc/base/proxyinfo.h"
23#include "webrtc/base/sigslot.h"
Taylor Brandstetter48e9d052016-05-12 10:19:38 -070024#include "webrtc/base/thread.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000025
26namespace cricket {
27
28// PortAllocator is responsible for allocating Port types for a given
29// P2PSocket. It also handles port freeing.
30//
31// Clients can override this class to control port allocation, including
32// what kinds of ports are allocated.
33
34enum {
Guo-wei Shieh13d35f62015-08-26 15:32:56 -070035 // Disable local UDP ports. This doesn't impact how we connect to relay
36 // servers.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000037 PORTALLOCATOR_DISABLE_UDP = 0x01,
38 PORTALLOCATOR_DISABLE_STUN = 0x02,
39 PORTALLOCATOR_DISABLE_RELAY = 0x04,
Guo-wei Shieh13d35f62015-08-26 15:32:56 -070040 // Disable local TCP ports. This doesn't impact how we connect to relay
41 // servers.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000042 PORTALLOCATOR_DISABLE_TCP = 0x08,
43 PORTALLOCATOR_ENABLE_SHAKER = 0x10,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000044 PORTALLOCATOR_ENABLE_IPV6 = 0x40,
Peter Thatcher7cbd1882015-09-17 18:54:52 -070045 // TODO(pthatcher): Remove this once it's no longer used in:
46 // remoting/client/plugin/pepper_port_allocator.cc
47 // remoting/protocol/chromium_port_allocator.cc
48 // remoting/test/fake_port_allocator.cc
49 // It's a no-op and is no longer needed.
pthatcherfa301802015-08-11 04:12:56 -070050 PORTALLOCATOR_ENABLE_SHARED_UFRAG = 0x80,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000051 PORTALLOCATOR_ENABLE_SHARED_SOCKET = 0x100,
52 PORTALLOCATOR_ENABLE_STUN_RETRANSMIT_ATTRIBUTE = 0x200,
Guo-wei Shieh9af97f82015-11-10 14:47:39 -080053 // When specified, we'll only allocate the STUN candidate for the public
54 // interface as seen by regular http traffic and the HOST candidate associated
55 // with the default local interface.
guoweis@webrtc.orgf358aea2015-02-18 18:44:01 +000056 PORTALLOCATOR_DISABLE_ADAPTER_ENUMERATION = 0x400,
Guo-wei Shieh9af97f82015-11-10 14:47:39 -080057 // When specified along with PORTALLOCATOR_DISABLE_ADAPTER_ENUMERATION, the
58 // default local candidate mentioned above will not be allocated. Only the
59 // STUN candidate will be.
60 PORTALLOCATOR_DISABLE_DEFAULT_LOCAL_CANDIDATE = 0x800,
Guo-wei Shieh13d35f62015-08-26 15:32:56 -070061 // Disallow use of UDP when connecting to a relay server. Since proxy servers
62 // usually don't handle UDP, using UDP will leak the IP address.
63 PORTALLOCATOR_DISABLE_UDP_RELAY = 0x1000,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000064};
65
Peter Boström0c4e06b2015-10-07 12:23:21 +020066const uint32_t kDefaultPortAllocatorFlags = 0;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000067
Peter Boström0c4e06b2015-10-07 12:23:21 +020068const uint32_t kDefaultStepDelay = 1000; // 1 sec step delay.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000069// As per RFC 5245 Appendix B.1, STUN transactions need to be paced at certain
70// internal. Less than 20ms is not acceptable. We choose 50ms as our default.
Peter Boström0c4e06b2015-10-07 12:23:21 +020071const uint32_t kMinimumStepDelay = 50;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000072
73// CF = CANDIDATE FILTER
74enum {
75 CF_NONE = 0x0,
76 CF_HOST = 0x1,
77 CF_REFLEXIVE = 0x2,
78 CF_RELAY = 0x4,
79 CF_ALL = 0x7,
80};
81
deadbeef653b8e02015-11-11 12:55:10 -080082// TODO(deadbeef): Rename to TurnCredentials (and username to ufrag).
83struct RelayCredentials {
84 RelayCredentials() {}
85 RelayCredentials(const std::string& username, const std::string& password)
86 : username(username), password(password) {}
87
Taylor Brandstetter48e9d052016-05-12 10:19:38 -070088 bool operator==(const RelayCredentials& o) const {
89 return username == o.username && password == o.password;
90 }
91 bool operator!=(const RelayCredentials& o) const { return !(*this == o); }
92
deadbeef653b8e02015-11-11 12:55:10 -080093 std::string username;
94 std::string password;
95};
96
97typedef std::vector<ProtocolAddress> PortList;
98// TODO(deadbeef): Rename to TurnServerConfig.
99struct RelayServerConfig {
Taylor Brandstetter48e9d052016-05-12 10:19:38 -0700100 RelayServerConfig(RelayType type) : type(type) {}
deadbeef653b8e02015-11-11 12:55:10 -0800101
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800102 RelayServerConfig(const std::string& address,
103 int port,
104 const std::string& username,
105 const std::string& password,
106 ProtocolType proto,
107 bool secure)
108 : type(RELAY_TURN), credentials(username, password) {
109 ports.push_back(
110 ProtocolAddress(rtc::SocketAddress(address, port), proto, secure));
111 }
112
Taylor Brandstetter48e9d052016-05-12 10:19:38 -0700113 bool operator==(const RelayServerConfig& o) const {
114 return type == o.type && ports == o.ports && credentials == o.credentials &&
115 priority == o.priority;
116 }
117 bool operator!=(const RelayServerConfig& o) const { return !(*this == o); }
118
deadbeef653b8e02015-11-11 12:55:10 -0800119 RelayType type;
120 PortList ports;
121 RelayCredentials credentials;
Taylor Brandstetter48e9d052016-05-12 10:19:38 -0700122 int priority = 0;
deadbeef653b8e02015-11-11 12:55:10 -0800123};
124
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000125class PortAllocatorSession : public sigslot::has_slots<> {
126 public:
127 // Content name passed in mostly for logging and debugging.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000128 PortAllocatorSession(const std::string& content_name,
129 int component,
deadbeefcbecd352015-09-23 11:50:27 -0700130 const std::string& ice_ufrag,
131 const std::string& ice_pwd,
Peter Boström0c4e06b2015-10-07 12:23:21 +0200132 uint32_t flags);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000133
134 // Subclasses should clean up any ports created.
135 virtual ~PortAllocatorSession() {}
136
Peter Boström0c4e06b2015-10-07 12:23:21 +0200137 uint32_t flags() const { return flags_; }
138 void set_flags(uint32_t flags) { flags_ = flags; }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000139 std::string content_name() const { return content_name_; }
140 int component() const { return component_; }
Taylor Brandstetter48e9d052016-05-12 10:19:38 -0700141 const std::string& ice_ufrag() const { return ice_ufrag_; }
142 const std::string& ice_pwd() const { return ice_pwd_; }
143 bool pooled() const { return ice_ufrag_.empty(); }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000144
145 // Starts gathering STUN and Relay configurations.
146 virtual void StartGettingPorts() = 0;
147 virtual void StopGettingPorts() = 0;
honghaiz98db68f2015-09-29 07:58:17 -0700148 // Only stop the existing gathering process but may start new ones if needed.
149 virtual void ClearGettingPorts() = 0;
150 // Whether the process of getting ports has been stopped.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000151 virtual bool IsGettingPorts() = 0;
152
Taylor Brandstetter48e9d052016-05-12 10:19:38 -0700153 // Another way of getting the information provided by the signals below.
154 //
155 // Ports and candidates are not guaranteed to be in the same order as the
156 // signals were emitted in.
157 virtual std::vector<PortInterface*> ReadyPorts() const = 0;
158 virtual std::vector<Candidate> ReadyCandidates() const = 0;
159 virtual bool CandidatesAllocationDone() const = 0;
160
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000161 sigslot::signal2<PortAllocatorSession*, PortInterface*> SignalPortReady;
162 sigslot::signal2<PortAllocatorSession*,
163 const std::vector<Candidate>&> SignalCandidatesReady;
164 sigslot::signal1<PortAllocatorSession*> SignalCandidatesAllocationDone;
165
Peter Boström0c4e06b2015-10-07 12:23:21 +0200166 virtual uint32_t generation() { return generation_; }
167 virtual void set_generation(uint32_t generation) { generation_ = generation; }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000168 sigslot::signal1<PortAllocatorSession*> SignalDestroyed;
169
170 protected:
Taylor Brandstetter48e9d052016-05-12 10:19:38 -0700171 // This method is called when a pooled session (which doesn't have these
172 // properties initially) is returned by PortAllocator::TakePooledSession,
173 // and the content name, component, and ICE ufrag/pwd are updated.
174 //
175 // A subclass may need to override this method to perform additional actions,
176 // such as applying the updated information to ports and candidates.
177 virtual void UpdateIceParametersInternal() {}
178
deadbeefcbecd352015-09-23 11:50:27 -0700179 // TODO(deadbeef): Get rid of these when everyone switches to ice_ufrag and
180 // ice_pwd.
181 const std::string& username() const { return ice_ufrag_; }
182 const std::string& password() const { return ice_pwd_; }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000183
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000184 private:
Taylor Brandstetter48e9d052016-05-12 10:19:38 -0700185 void SetIceParameters(const std::string& content_name,
186 int component,
187 const std::string& ice_ufrag,
188 const std::string& ice_pwd) {
189 content_name_ = content_name;
190 component_ = component;
191 ice_ufrag_ = ice_ufrag;
192 ice_pwd_ = ice_pwd;
193 UpdateIceParametersInternal();
194 }
195
Peter Boström0c4e06b2015-10-07 12:23:21 +0200196 uint32_t flags_;
197 uint32_t generation_;
Taylor Brandstetter48e9d052016-05-12 10:19:38 -0700198 std::string content_name_;
199 int component_;
deadbeefcbecd352015-09-23 11:50:27 -0700200 std::string ice_ufrag_;
201 std::string ice_pwd_;
Taylor Brandstetter48e9d052016-05-12 10:19:38 -0700202
203 // SetIceParameters is an implementation detail which only PortAllocator
204 // should be able to call.
205 friend class PortAllocator;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000206};
207
Taylor Brandstetter48e9d052016-05-12 10:19:38 -0700208// Note that this class should only be used on one thread.
209// This includes calling the destructor.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000210class PortAllocator : public sigslot::has_slots<> {
211 public:
212 PortAllocator() :
213 flags_(kDefaultPortAllocatorFlags),
214 min_port_(0),
215 max_port_(0),
216 step_delay_(kDefaultStepDelay),
217 allow_tcp_listen_(true),
218 candidate_filter_(CF_ALL) {
219 // This will allow us to have old behavior on non webrtc clients.
220 }
Peter Thatcher73ba7a62015-04-14 09:26:03 -0700221 virtual ~PortAllocator() {}
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000222
Taylor Brandstetter48e9d052016-05-12 10:19:38 -0700223 // Set STUN and TURN servers to be used in future sessions, and set
224 // candidate pool size, as described in JSEP.
225 //
226 // If the servers are changing and the candidate pool size is nonzero,
227 // existing pooled sessions will be destroyed and new ones created.
228 //
229 // If the servers are not changing but the candidate pool size is,
230 // pooled sessions will be either created or destroyed as necessary.
231 void SetConfiguration(const ServerAddresses& stun_servers,
232 const std::vector<RelayServerConfig>& turn_servers,
233 int candidate_pool_size);
234
235 const ServerAddresses& stun_servers() const { return stun_servers_; }
236
237 const std::vector<RelayServerConfig>& turn_servers() const {
238 return turn_servers_;
239 }
240
241 int candidate_pool_size() const { return target_pooled_session_count_; }
deadbeef653b8e02015-11-11 12:55:10 -0800242
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -0800243 // Sets the network types to ignore.
244 // Values are defined by the AdapterType enum.
245 // For instance, calling this with
246 // ADAPTER_TYPE_ETHERNET | ADAPTER_TYPE_LOOPBACK will ignore Ethernet and
247 // loopback interfaces.
248 virtual void SetNetworkIgnoreMask(int network_ignore_mask) = 0;
249
Taylor Brandstetter48e9d052016-05-12 10:19:38 -0700250 std::unique_ptr<PortAllocatorSession> CreateSession(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000251 const std::string& sid,
252 const std::string& content_name,
253 int component,
254 const std::string& ice_ufrag,
255 const std::string& ice_pwd);
256
Taylor Brandstetter48e9d052016-05-12 10:19:38 -0700257 // Get an available pooled session and set the transport information on it.
258 //
259 // Caller takes ownership of the returned session.
260 //
261 // If no pooled sessions are available, returns null.
262 std::unique_ptr<PortAllocatorSession> TakePooledSession(
263 const std::string& content_name,
264 int component,
265 const std::string& ice_ufrag,
266 const std::string& ice_pwd);
267
268 // Returns the next session that would be returned by TakePooledSession.
269 const PortAllocatorSession* GetPooledSession() const;
270
Peter Boström0c4e06b2015-10-07 12:23:21 +0200271 uint32_t flags() const { return flags_; }
272 void set_flags(uint32_t flags) { flags_ = flags; }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000273
274 const std::string& user_agent() const { return agent_; }
275 const rtc::ProxyInfo& proxy() const { return proxy_; }
276 void set_proxy(const std::string& agent, const rtc::ProxyInfo& proxy) {
277 agent_ = agent;
278 proxy_ = proxy;
279 }
280
281 // Gets/Sets the port range to use when choosing client ports.
282 int min_port() const { return min_port_; }
283 int max_port() const { return max_port_; }
284 bool SetPortRange(int min_port, int max_port) {
285 if (min_port > max_port) {
286 return false;
287 }
288
289 min_port_ = min_port;
290 max_port_ = max_port;
291 return true;
292 }
293
Peter Boström0c4e06b2015-10-07 12:23:21 +0200294 uint32_t step_delay() const { return step_delay_; }
295 void set_step_delay(uint32_t delay) { step_delay_ = delay; }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000296
297 bool allow_tcp_listen() const { return allow_tcp_listen_; }
298 void set_allow_tcp_listen(bool allow_tcp_listen) {
299 allow_tcp_listen_ = allow_tcp_listen;
300 }
301
Peter Boström0c4e06b2015-10-07 12:23:21 +0200302 uint32_t candidate_filter() { return candidate_filter_; }
Taylor Brandstetter48e9d052016-05-12 10:19:38 -0700303 void set_candidate_filter(uint32_t filter) {
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000304 // TODO(mallinath) - Do transition check?
305 candidate_filter_ = filter;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000306 }
307
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000308 // Gets/Sets the Origin value used for WebRTC STUN requests.
309 const std::string& origin() const { return origin_; }
310 void set_origin(const std::string& origin) { origin_ = origin; }
311
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000312 protected:
313 virtual PortAllocatorSession* CreateSessionInternal(
314 const std::string& content_name,
315 int component,
316 const std::string& ice_ufrag,
317 const std::string& ice_pwd) = 0;
318
Peter Boström0c4e06b2015-10-07 12:23:21 +0200319 uint32_t flags_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000320 std::string agent_;
321 rtc::ProxyInfo proxy_;
322 int min_port_;
323 int max_port_;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200324 uint32_t step_delay_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000325 bool allow_tcp_listen_;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200326 uint32_t candidate_filter_;
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000327 std::string origin_;
Taylor Brandstetter48e9d052016-05-12 10:19:38 -0700328
329 private:
330 ServerAddresses stun_servers_;
331 std::vector<RelayServerConfig> turn_servers_;
332 // The last size passed into SetConfiguration.
333 int target_pooled_session_count_ = 0;
334 // This variable represents the total number of pooled sessions
335 // both owned by this class and taken by TakePooledSession.
336 int allocated_pooled_session_count_ = 0;
337 std::deque<std::unique_ptr<PortAllocatorSession>> pooled_sessions_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000338};
339
340} // namespace cricket
341
342#endif // WEBRTC_P2P_BASE_PORTALLOCATOR_H_