blob: ca1a23aaf2c84458e7bcbfbd08f58538c2154a97 [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_CLIENT_BASICPORTALLOCATOR_H_
12#define WEBRTC_P2P_CLIENT_BASICPORTALLOCATOR_H_
13
14#include <string>
15#include <vector>
16
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000017#include "webrtc/p2p/base/portallocator.h"
18#include "webrtc/base/messagequeue.h"
19#include "webrtc/base/network.h"
20#include "webrtc/base/scoped_ptr.h"
21#include "webrtc/base/thread.h"
22
23namespace cricket {
24
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000025class BasicPortAllocator : public PortAllocator {
26 public:
27 BasicPortAllocator(rtc::NetworkManager* network_manager,
28 rtc::PacketSocketFactory* socket_factory);
29 explicit BasicPortAllocator(rtc::NetworkManager* network_manager);
30 BasicPortAllocator(rtc::NetworkManager* network_manager,
31 rtc::PacketSocketFactory* socket_factory,
32 const ServerAddresses& stun_servers);
33 BasicPortAllocator(rtc::NetworkManager* network_manager,
34 const ServerAddresses& stun_servers,
35 const rtc::SocketAddress& relay_server_udp,
36 const rtc::SocketAddress& relay_server_tcp,
37 const rtc::SocketAddress& relay_server_ssl);
38 virtual ~BasicPortAllocator();
39
deadbeef653b8e02015-11-11 12:55:10 -080040 void SetIceServers(
41 const ServerAddresses& stun_servers,
42 const std::vector<RelayServerConfig>& turn_servers) override {
43 stun_servers_ = stun_servers;
44 turn_servers_ = turn_servers;
45 }
46
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -080047 // Set to kDefaultNetworkIgnoreMask by default.
48 void SetNetworkIgnoreMask(int network_ignore_mask) override {
49 // TODO(phoglund): implement support for other types than loopback.
50 // See https://code.google.com/p/webrtc/issues/detail?id=4288.
51 // Then remove set_network_ignore_list from NetworkManager.
52 network_ignore_mask_ = network_ignore_mask;
53 }
54
55 int network_ignore_mask() const { return network_ignore_mask_; }
56
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000057 rtc::NetworkManager* network_manager() { return network_manager_; }
58
59 // If socket_factory() is set to NULL each PortAllocatorSession
60 // creates its own socket factory.
61 rtc::PacketSocketFactory* socket_factory() { return socket_factory_; }
62
63 const ServerAddresses& stun_servers() const {
64 return stun_servers_;
65 }
66
deadbeef653b8e02015-11-11 12:55:10 -080067 const std::vector<RelayServerConfig>& turn_servers() const {
68 return turn_servers_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000069 }
deadbeef653b8e02015-11-11 12:55:10 -080070 virtual void AddTurnServer(const RelayServerConfig& turn_server) {
71 turn_servers_.push_back(turn_server);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000072 }
73
deadbeef653b8e02015-11-11 12:55:10 -080074 PortAllocatorSession* CreateSessionInternal(
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000075 const std::string& content_name,
76 int component,
77 const std::string& ice_ufrag,
deadbeef653b8e02015-11-11 12:55:10 -080078 const std::string& ice_pwd) override;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000079
80 private:
81 void Construct();
82
83 rtc::NetworkManager* network_manager_;
84 rtc::PacketSocketFactory* socket_factory_;
deadbeef653b8e02015-11-11 12:55:10 -080085 ServerAddresses stun_servers_;
86 std::vector<RelayServerConfig> turn_servers_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000087 bool allow_tcp_listen_;
Taylor Brandstetter0c7e9f52015-12-29 14:14:52 -080088 int network_ignore_mask_ = rtc::kDefaultNetworkIgnoreMask;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000089};
90
91struct PortConfiguration;
92class AllocationSequence;
93
94class BasicPortAllocatorSession : public PortAllocatorSession,
95 public rtc::MessageHandler {
96 public:
97 BasicPortAllocatorSession(BasicPortAllocator* allocator,
98 const std::string& content_name,
99 int component,
100 const std::string& ice_ufrag,
101 const std::string& ice_pwd);
102 ~BasicPortAllocatorSession();
103
104 virtual BasicPortAllocator* allocator() { return allocator_; }
105 rtc::Thread* network_thread() { return network_thread_; }
106 rtc::PacketSocketFactory* socket_factory() { return socket_factory_; }
107
deadbeef653b8e02015-11-11 12:55:10 -0800108 void StartGettingPorts() override;
109 void StopGettingPorts() override;
110 void ClearGettingPorts() override;
111 bool IsGettingPorts() override { return running_; }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000112
113 protected:
114 // Starts the process of getting the port configurations.
115 virtual void GetPortConfigurations();
116
117 // Adds a port configuration that is now ready. Once we have one for each
118 // network (or a timeout occurs), we will start allocating ports.
119 virtual void ConfigReady(PortConfiguration* config);
120
121 // MessageHandler. Can be overriden if message IDs do not conflict.
deadbeef653b8e02015-11-11 12:55:10 -0800122 void OnMessage(rtc::Message* message) override;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000123
124 private:
125 class PortData {
126 public:
127 PortData() : port_(NULL), sequence_(NULL), state_(STATE_INIT) {}
128 PortData(Port* port, AllocationSequence* seq)
129 : port_(port), sequence_(seq), state_(STATE_INIT) {
130 }
131
132 Port* port() { return port_; }
133 AllocationSequence* sequence() { return sequence_; }
134 bool ready() const { return state_ == STATE_READY; }
135 bool complete() const {
136 // Returns true if candidate allocation has completed one way or another.
137 return ((state_ == STATE_COMPLETE) || (state_ == STATE_ERROR));
138 }
139
140 void set_ready() { ASSERT(state_ == STATE_INIT); state_ = STATE_READY; }
141 void set_complete() {
142 state_ = STATE_COMPLETE;
143 }
144 void set_error() {
145 ASSERT(state_ == STATE_INIT || state_ == STATE_READY);
146 state_ = STATE_ERROR;
147 }
148
149 private:
150 enum State {
151 STATE_INIT, // No candidates allocated yet.
152 STATE_READY, // At least one candidate is ready for process.
153 STATE_COMPLETE, // All candidates allocated and ready for process.
154 STATE_ERROR // Error in gathering candidates.
155 };
156 Port* port_;
157 AllocationSequence* sequence_;
158 State state_;
159 };
160
161 void OnConfigReady(PortConfiguration* config);
162 void OnConfigStop();
163 void AllocatePorts();
164 void OnAllocate();
165 void DoAllocate();
166 void OnNetworksChanged();
167 void OnAllocationSequenceObjectsCreated();
168 void DisableEquivalentPhases(rtc::Network* network,
Peter Boström0c4e06b2015-10-07 12:23:21 +0200169 PortConfiguration* config,
170 uint32_t* flags);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000171 void AddAllocatedPort(Port* port, AllocationSequence* seq,
172 bool prepare_address);
173 void OnCandidateReady(Port* port, const Candidate& c);
174 void OnPortComplete(Port* port);
175 void OnPortError(Port* port);
176 void OnProtocolEnabled(AllocationSequence* seq, ProtocolType proto);
177 void OnPortDestroyed(PortInterface* port);
178 void OnShake();
179 void MaybeSignalCandidatesAllocationDone();
180 void OnPortAllocationComplete(AllocationSequence* seq);
181 PortData* FindPort(Port* port);
honghaiz8c404fa2015-09-28 07:59:43 -0700182 void GetNetworks(std::vector<rtc::Network*>* networks);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000183
184 bool CheckCandidateFilter(const Candidate& c);
185
186 BasicPortAllocator* allocator_;
187 rtc::Thread* network_thread_;
188 rtc::scoped_ptr<rtc::PacketSocketFactory> owned_socket_factory_;
189 rtc::PacketSocketFactory* socket_factory_;
190 bool allocation_started_;
191 bool network_manager_started_;
192 bool running_; // set when StartGetAllPorts is called
193 bool allocation_sequences_created_;
194 std::vector<PortConfiguration*> configs_;
195 std::vector<AllocationSequence*> sequences_;
196 std::vector<PortData> ports_;
197
198 friend class AllocationSequence;
199};
200
201// Records configuration information useful in creating ports.
deadbeef653b8e02015-11-11 12:55:10 -0800202// TODO(deadbeef): Rename "relay" to "turn_server" in this struct.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000203struct PortConfiguration : public rtc::MessageData {
204 // TODO(jiayl): remove |stun_address| when Chrome is updated.
205 rtc::SocketAddress stun_address;
206 ServerAddresses stun_servers;
207 std::string username;
208 std::string password;
209
210 typedef std::vector<RelayServerConfig> RelayList;
211 RelayList relays;
212
213 // TODO(jiayl): remove this ctor when Chrome is updated.
214 PortConfiguration(const rtc::SocketAddress& stun_address,
215 const std::string& username,
216 const std::string& password);
217
218 PortConfiguration(const ServerAddresses& stun_servers,
219 const std::string& username,
220 const std::string& password);
221
deadbeefc5d0d952015-07-16 10:22:21 -0700222 // Returns addresses of both the explicitly configured STUN servers,
223 // and TURN servers that should be used as STUN servers.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000224 ServerAddresses StunServers();
225
226 // Adds another relay server, with the given ports and modifier, to the list.
227 void AddRelay(const RelayServerConfig& config);
228
229 // Determines whether the given relay server supports the given protocol.
230 bool SupportsProtocol(const RelayServerConfig& relay,
231 ProtocolType type) const;
232 bool SupportsProtocol(RelayType turn_type, ProtocolType type) const;
233 // Helper method returns the server addresses for the matching RelayType and
234 // Protocol type.
235 ServerAddresses GetRelayServerAddresses(
236 RelayType turn_type, ProtocolType type) const;
237};
238
honghaizf421bdc2015-07-17 16:21:55 -0700239class UDPPort;
240class TurnPort;
241
242// Performs the allocation of ports, in a sequenced (timed) manner, for a given
243// network and IP address.
244class AllocationSequence : public rtc::MessageHandler,
245 public sigslot::has_slots<> {
246 public:
247 enum State {
248 kInit, // Initial state.
249 kRunning, // Started allocating ports.
250 kStopped, // Stopped from running.
251 kCompleted, // All ports are allocated.
252
253 // kInit --> kRunning --> {kCompleted|kStopped}
254 };
255 AllocationSequence(BasicPortAllocatorSession* session,
256 rtc::Network* network,
257 PortConfiguration* config,
Peter Boström0c4e06b2015-10-07 12:23:21 +0200258 uint32_t flags);
honghaizf421bdc2015-07-17 16:21:55 -0700259 ~AllocationSequence();
260 bool Init();
261 void Clear();
honghaiz8c404fa2015-09-28 07:59:43 -0700262 void OnNetworkRemoved();
honghaizf421bdc2015-07-17 16:21:55 -0700263
264 State state() const { return state_; }
honghaiz8c404fa2015-09-28 07:59:43 -0700265 const rtc::Network* network() const { return network_; }
266 bool network_removed() const { return network_removed_; }
honghaizf421bdc2015-07-17 16:21:55 -0700267
268 // Disables the phases for a new sequence that this one already covers for an
269 // equivalent network setup.
270 void DisableEquivalentPhases(rtc::Network* network,
271 PortConfiguration* config,
Peter Boström0c4e06b2015-10-07 12:23:21 +0200272 uint32_t* flags);
honghaizf421bdc2015-07-17 16:21:55 -0700273
274 // Starts and stops the sequence. When started, it will continue allocating
275 // new ports on its own timed schedule.
276 void Start();
277 void Stop();
278
279 // MessageHandler
280 void OnMessage(rtc::Message* msg);
281
282 void EnableProtocol(ProtocolType proto);
283 bool ProtocolEnabled(ProtocolType proto) const;
284
285 // Signal from AllocationSequence, when it's done with allocating ports.
286 // This signal is useful, when port allocation fails which doesn't result
287 // in any candidates. Using this signal BasicPortAllocatorSession can send
288 // its candidate discovery conclusion signal. Without this signal,
289 // BasicPortAllocatorSession doesn't have any event to trigger signal. This
290 // can also be achieved by starting timer in BPAS.
291 sigslot::signal1<AllocationSequence*> SignalPortAllocationComplete;
292
293 protected:
294 // For testing.
295 void CreateTurnPort(const RelayServerConfig& config);
296
297 private:
298 typedef std::vector<ProtocolType> ProtocolList;
299
Peter Boström0c4e06b2015-10-07 12:23:21 +0200300 bool IsFlagSet(uint32_t flag) { return ((flags_ & flag) != 0); }
honghaizf421bdc2015-07-17 16:21:55 -0700301 void CreateUDPPorts();
302 void CreateTCPPorts();
303 void CreateStunPorts();
304 void CreateRelayPorts();
305 void CreateGturnPort(const RelayServerConfig& config);
306
307 void OnReadPacket(rtc::AsyncPacketSocket* socket,
308 const char* data,
309 size_t size,
310 const rtc::SocketAddress& remote_addr,
311 const rtc::PacketTime& packet_time);
312
313 void OnPortDestroyed(PortInterface* port);
314
315 BasicPortAllocatorSession* session_;
honghaiz8c404fa2015-09-28 07:59:43 -0700316 bool network_removed_ = false;
honghaizf421bdc2015-07-17 16:21:55 -0700317 rtc::Network* network_;
318 rtc::IPAddress ip_;
319 PortConfiguration* config_;
320 State state_;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200321 uint32_t flags_;
honghaizf421bdc2015-07-17 16:21:55 -0700322 ProtocolList protocols_;
323 rtc::scoped_ptr<rtc::AsyncPacketSocket> udp_socket_;
324 // There will be only one udp port per AllocationSequence.
325 UDPPort* udp_port_;
326 std::vector<TurnPort*> turn_ports_;
327 int phase_;
328};
329
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000330} // namespace cricket
331
332#endif // WEBRTC_P2P_CLIENT_BASICPORTALLOCATOR_H_