blob: a091325523bcaa0ed4e8cf29c5b04960a2dc25d9 [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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "p2p/base/portallocator.h"
12#include "rtc_base/checks.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000013
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000014namespace cricket {
15
Steve Anton7995d8c2017-10-30 16:23:38 -070016RelayServerConfig::RelayServerConfig(RelayType type) : type(type) {}
17
18RelayServerConfig::RelayServerConfig(const rtc::SocketAddress& address,
19 const std::string& username,
20 const std::string& password,
21 ProtocolType proto)
22 : type(RELAY_TURN), credentials(username, password) {
23 ports.push_back(ProtocolAddress(address, proto));
24}
25
26RelayServerConfig::RelayServerConfig(const std::string& address,
27 int port,
28 const std::string& username,
29 const std::string& password,
30 ProtocolType proto)
31 : RelayServerConfig(rtc::SocketAddress(address, port),
32 username,
33 password,
34 proto) {}
35
36// Legacy constructor where "secure" and PROTO_TCP implies PROTO_TLS.
37RelayServerConfig::RelayServerConfig(const std::string& address,
38 int port,
39 const std::string& username,
40 const std::string& password,
41 ProtocolType proto,
42 bool secure)
43 : RelayServerConfig(address,
44 port,
45 username,
46 password,
47 (proto == PROTO_TCP && secure ? PROTO_TLS : proto)) {}
48
49RelayServerConfig::RelayServerConfig(const RelayServerConfig&) = default;
50
51RelayServerConfig::~RelayServerConfig() = default;
52
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000053PortAllocatorSession::PortAllocatorSession(const std::string& content_name,
54 int component,
55 const std::string& ice_ufrag,
56 const std::string& ice_pwd,
Peter Boström0c4e06b2015-10-07 12:23:21 +020057 uint32_t flags)
Taylor Brandstettera1c30352016-05-13 08:15:11 -070058 : flags_(flags),
deadbeefc55fb302016-05-12 12:51:38 -070059 generation_(0),
Taylor Brandstettera1c30352016-05-13 08:15:11 -070060 content_name_(content_name),
61 component_(component),
deadbeefcbecd352015-09-23 11:50:27 -070062 ice_ufrag_(ice_ufrag),
63 ice_pwd_(ice_pwd) {
Taylor Brandstettera1c30352016-05-13 08:15:11 -070064 // Pooled sessions are allowed to be created with empty content name,
65 // component, ufrag and password.
66 RTC_DCHECK(ice_ufrag.empty() == ice_pwd.empty());
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000067}
68
Steve Anton7995d8c2017-10-30 16:23:38 -070069PortAllocatorSession::~PortAllocatorSession() = default;
70
71bool PortAllocatorSession::IsCleared() const {
72 return false;
73}
74
75bool PortAllocatorSession::IsStopped() const {
76 return false;
77}
78
79uint32_t PortAllocatorSession::generation() {
80 return generation_;
81}
82
83void PortAllocatorSession::set_generation(uint32_t generation) {
84 generation_ = generation;
85}
86
87PortAllocator::PortAllocator()
88 : flags_(kDefaultPortAllocatorFlags),
89 min_port_(0),
90 max_port_(0),
91 max_ipv6_networks_(kDefaultMaxIPv6Networks),
92 step_delay_(kDefaultStepDelay),
93 allow_tcp_listen_(true),
94 candidate_filter_(CF_ALL) {}
95
96PortAllocator::~PortAllocator() = default;
97
deadbeef6de92f92016-12-12 18:49:32 -080098bool PortAllocator::SetConfiguration(
Taylor Brandstettera1c30352016-05-13 08:15:11 -070099 const ServerAddresses& stun_servers,
100 const std::vector<RelayServerConfig>& turn_servers,
Honghai Zhangb9e7b4a2016-06-30 20:52:02 -0700101 int candidate_pool_size,
Jonas Orelandbdcee282017-10-10 14:01:40 +0200102 bool prune_turn_ports,
103 webrtc::TurnCustomizer* turn_customizer) {
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700104 bool ice_servers_changed =
105 (stun_servers != stun_servers_ || turn_servers != turn_servers_);
106 stun_servers_ = stun_servers;
107 turn_servers_ = turn_servers;
Honghai Zhangb9e7b4a2016-06-30 20:52:02 -0700108 prune_turn_ports_ = prune_turn_ports;
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700109
deadbeef42a42632017-03-10 15:18:00 -0800110 if (candidate_pool_frozen_) {
111 if (candidate_pool_size != candidate_pool_size_) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100112 RTC_LOG(LS_ERROR)
113 << "Trying to change candidate pool size after pool was "
114 << "frozen.";
deadbeef42a42632017-03-10 15:18:00 -0800115 return false;
116 }
117 return true;
deadbeef6de92f92016-12-12 18:49:32 -0800118 }
deadbeef42a42632017-03-10 15:18:00 -0800119
deadbeef6de92f92016-12-12 18:49:32 -0800120 if (candidate_pool_size < 0) {
Mirko Bonadei675513b2017-11-09 11:09:25 +0100121 RTC_LOG(LS_ERROR) << "Can't set negative pool size.";
deadbeef6de92f92016-12-12 18:49:32 -0800122 return false;
123 }
deadbeef6de92f92016-12-12 18:49:32 -0800124
deadbeef42a42632017-03-10 15:18:00 -0800125 candidate_pool_size_ = candidate_pool_size;
deadbeef6de92f92016-12-12 18:49:32 -0800126
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700127 // If ICE servers changed, throw away any existing pooled sessions and create
128 // new ones.
129 if (ice_servers_changed) {
130 pooled_sessions_.clear();
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700131 }
132
Jonas Orelandbdcee282017-10-10 14:01:40 +0200133 turn_customizer_ = turn_customizer;
134
deadbeef42a42632017-03-10 15:18:00 -0800135 // If |candidate_pool_size_| is less than the number of pooled sessions, get
136 // rid of the extras.
137 while (candidate_pool_size_ < static_cast<int>(pooled_sessions_.size())) {
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700138 pooled_sessions_.front().reset(nullptr);
139 pooled_sessions_.pop_front();
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700140 }
deadbeef6de92f92016-12-12 18:49:32 -0800141
deadbeef42a42632017-03-10 15:18:00 -0800142 // If |candidate_pool_size_| is greater than the number of pooled sessions,
deadbeef6de92f92016-12-12 18:49:32 -0800143 // create new sessions.
deadbeef42a42632017-03-10 15:18:00 -0800144 while (static_cast<int>(pooled_sessions_.size()) < candidate_pool_size_) {
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700145 PortAllocatorSession* pooled_session = CreateSessionInternal("", 0, "", "");
146 pooled_session->StartGettingPorts();
147 pooled_sessions_.push_back(
148 std::unique_ptr<PortAllocatorSession>(pooled_session));
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700149 }
deadbeef6de92f92016-12-12 18:49:32 -0800150 return true;
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700151}
152
153std::unique_ptr<PortAllocatorSession> PortAllocator::CreateSession(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000154 const std::string& content_name,
155 int component,
156 const std::string& ice_ufrag,
157 const std::string& ice_pwd) {
Taylor Brandstetter417eebe2016-05-23 16:02:19 -0700158 auto session = std::unique_ptr<PortAllocatorSession>(
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700159 CreateSessionInternal(content_name, component, ice_ufrag, ice_pwd));
Taylor Brandstetter417eebe2016-05-23 16:02:19 -0700160 session->SetCandidateFilter(candidate_filter());
161 return session;
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700162}
163
164std::unique_ptr<PortAllocatorSession> PortAllocator::TakePooledSession(
165 const std::string& content_name,
166 int component,
167 const std::string& ice_ufrag,
168 const std::string& ice_pwd) {
169 RTC_DCHECK(!ice_ufrag.empty());
170 RTC_DCHECK(!ice_pwd.empty());
171 if (pooled_sessions_.empty()) {
172 return nullptr;
173 }
174 std::unique_ptr<PortAllocatorSession> ret =
175 std::move(pooled_sessions_.front());
176 ret->SetIceParameters(content_name, component, ice_ufrag, ice_pwd);
Taylor Brandstetter417eebe2016-05-23 16:02:19 -0700177 // According to JSEP, a pooled session should filter candidates only after
178 // it's taken out of the pool.
179 ret->SetCandidateFilter(candidate_filter());
Taylor Brandstettera1c30352016-05-13 08:15:11 -0700180 pooled_sessions_.pop_front();
181 return ret;
182}
183
184const PortAllocatorSession* PortAllocator::GetPooledSession() const {
185 if (pooled_sessions_.empty()) {
186 return nullptr;
187 }
188 return pooled_sessions_.front().get();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000189}
190
deadbeef42a42632017-03-10 15:18:00 -0800191void PortAllocator::FreezeCandidatePool() {
192 candidate_pool_frozen_ = true;
193}
194
195void PortAllocator::DiscardCandidatePool() {
196 pooled_sessions_.clear();
197}
198
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000199} // namespace cricket