blob: c8bcad21a9d36e2b620a2d418f58bf189815983f [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
17#include "webrtc/p2p/base/port.h"
18#include "webrtc/p2p/base/portallocator.h"
19#include "webrtc/base/messagequeue.h"
20#include "webrtc/base/network.h"
21#include "webrtc/base/scoped_ptr.h"
22#include "webrtc/base/thread.h"
23
24namespace cricket {
25
26struct RelayCredentials {
27 RelayCredentials() {}
28 RelayCredentials(const std::string& username,
29 const std::string& password)
30 : username(username),
31 password(password) {
32 }
33
34 std::string username;
35 std::string password;
36};
37
38typedef std::vector<ProtocolAddress> PortList;
39struct RelayServerConfig {
40 RelayServerConfig(RelayType type) : type(type), priority(0) {}
41
42 RelayType type;
43 PortList ports;
44 RelayCredentials credentials;
45 int priority;
46};
47
48class BasicPortAllocator : public PortAllocator {
49 public:
50 BasicPortAllocator(rtc::NetworkManager* network_manager,
51 rtc::PacketSocketFactory* socket_factory);
52 explicit BasicPortAllocator(rtc::NetworkManager* network_manager);
53 BasicPortAllocator(rtc::NetworkManager* network_manager,
54 rtc::PacketSocketFactory* socket_factory,
55 const ServerAddresses& stun_servers);
56 BasicPortAllocator(rtc::NetworkManager* network_manager,
57 const ServerAddresses& stun_servers,
58 const rtc::SocketAddress& relay_server_udp,
59 const rtc::SocketAddress& relay_server_tcp,
60 const rtc::SocketAddress& relay_server_ssl);
61 virtual ~BasicPortAllocator();
62
63 rtc::NetworkManager* network_manager() { return network_manager_; }
64
65 // If socket_factory() is set to NULL each PortAllocatorSession
66 // creates its own socket factory.
67 rtc::PacketSocketFactory* socket_factory() { return socket_factory_; }
68
69 const ServerAddresses& stun_servers() const {
70 return stun_servers_;
71 }
72
73 const std::vector<RelayServerConfig>& relays() const {
74 return relays_;
75 }
76 virtual void AddRelay(const RelayServerConfig& relay) {
77 relays_.push_back(relay);
78 }
79
80 virtual PortAllocatorSession* CreateSessionInternal(
81 const std::string& content_name,
82 int component,
83 const std::string& ice_ufrag,
84 const std::string& ice_pwd);
85
86 private:
87 void Construct();
88
89 rtc::NetworkManager* network_manager_;
90 rtc::PacketSocketFactory* socket_factory_;
91 const ServerAddresses stun_servers_;
92 std::vector<RelayServerConfig> relays_;
93 bool allow_tcp_listen_;
94};
95
96struct PortConfiguration;
97class AllocationSequence;
98
99class BasicPortAllocatorSession : public PortAllocatorSession,
100 public rtc::MessageHandler {
101 public:
102 BasicPortAllocatorSession(BasicPortAllocator* allocator,
103 const std::string& content_name,
104 int component,
105 const std::string& ice_ufrag,
106 const std::string& ice_pwd);
107 ~BasicPortAllocatorSession();
108
109 virtual BasicPortAllocator* allocator() { return allocator_; }
110 rtc::Thread* network_thread() { return network_thread_; }
111 rtc::PacketSocketFactory* socket_factory() { return socket_factory_; }
112
113 virtual void StartGettingPorts();
114 virtual void StopGettingPorts();
honghaiz98db68f2015-09-29 07:58:17 -0700115 virtual void ClearGettingPorts();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000116 virtual bool IsGettingPorts() { return running_; }
117
118 protected:
119 // Starts the process of getting the port configurations.
120 virtual void GetPortConfigurations();
121
122 // Adds a port configuration that is now ready. Once we have one for each
123 // network (or a timeout occurs), we will start allocating ports.
124 virtual void ConfigReady(PortConfiguration* config);
125
126 // MessageHandler. Can be overriden if message IDs do not conflict.
127 virtual void OnMessage(rtc::Message *message);
128
129 private:
130 class PortData {
131 public:
132 PortData() : port_(NULL), sequence_(NULL), state_(STATE_INIT) {}
133 PortData(Port* port, AllocationSequence* seq)
134 : port_(port), sequence_(seq), state_(STATE_INIT) {
135 }
136
137 Port* port() { return port_; }
138 AllocationSequence* sequence() { return sequence_; }
139 bool ready() const { return state_ == STATE_READY; }
140 bool complete() const {
141 // Returns true if candidate allocation has completed one way or another.
142 return ((state_ == STATE_COMPLETE) || (state_ == STATE_ERROR));
143 }
144
145 void set_ready() { ASSERT(state_ == STATE_INIT); state_ = STATE_READY; }
146 void set_complete() {
147 state_ = STATE_COMPLETE;
148 }
149 void set_error() {
150 ASSERT(state_ == STATE_INIT || state_ == STATE_READY);
151 state_ = STATE_ERROR;
152 }
153
154 private:
155 enum State {
156 STATE_INIT, // No candidates allocated yet.
157 STATE_READY, // At least one candidate is ready for process.
158 STATE_COMPLETE, // All candidates allocated and ready for process.
159 STATE_ERROR // Error in gathering candidates.
160 };
161 Port* port_;
162 AllocationSequence* sequence_;
163 State state_;
164 };
165
166 void OnConfigReady(PortConfiguration* config);
167 void OnConfigStop();
168 void AllocatePorts();
169 void OnAllocate();
170 void DoAllocate();
171 void OnNetworksChanged();
172 void OnAllocationSequenceObjectsCreated();
173 void DisableEquivalentPhases(rtc::Network* network,
Peter Boström0c4e06b2015-10-07 12:23:21 +0200174 PortConfiguration* config,
175 uint32_t* flags);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000176 void AddAllocatedPort(Port* port, AllocationSequence* seq,
177 bool prepare_address);
178 void OnCandidateReady(Port* port, const Candidate& c);
179 void OnPortComplete(Port* port);
180 void OnPortError(Port* port);
181 void OnProtocolEnabled(AllocationSequence* seq, ProtocolType proto);
182 void OnPortDestroyed(PortInterface* port);
183 void OnShake();
184 void MaybeSignalCandidatesAllocationDone();
185 void OnPortAllocationComplete(AllocationSequence* seq);
186 PortData* FindPort(Port* port);
honghaiz8c404fa2015-09-28 07:59:43 -0700187 void GetNetworks(std::vector<rtc::Network*>* networks);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000188
189 bool CheckCandidateFilter(const Candidate& c);
190
191 BasicPortAllocator* allocator_;
192 rtc::Thread* network_thread_;
193 rtc::scoped_ptr<rtc::PacketSocketFactory> owned_socket_factory_;
194 rtc::PacketSocketFactory* socket_factory_;
195 bool allocation_started_;
196 bool network_manager_started_;
197 bool running_; // set when StartGetAllPorts is called
198 bool allocation_sequences_created_;
199 std::vector<PortConfiguration*> configs_;
200 std::vector<AllocationSequence*> sequences_;
201 std::vector<PortData> ports_;
202
203 friend class AllocationSequence;
204};
205
206// Records configuration information useful in creating ports.
207struct PortConfiguration : public rtc::MessageData {
208 // TODO(jiayl): remove |stun_address| when Chrome is updated.
209 rtc::SocketAddress stun_address;
210 ServerAddresses stun_servers;
211 std::string username;
212 std::string password;
213
214 typedef std::vector<RelayServerConfig> RelayList;
215 RelayList relays;
216
217 // TODO(jiayl): remove this ctor when Chrome is updated.
218 PortConfiguration(const rtc::SocketAddress& stun_address,
219 const std::string& username,
220 const std::string& password);
221
222 PortConfiguration(const ServerAddresses& stun_servers,
223 const std::string& username,
224 const std::string& password);
225
deadbeefc5d0d952015-07-16 10:22:21 -0700226 // Returns addresses of both the explicitly configured STUN servers,
227 // and TURN servers that should be used as STUN servers.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000228 ServerAddresses StunServers();
229
230 // Adds another relay server, with the given ports and modifier, to the list.
231 void AddRelay(const RelayServerConfig& config);
232
233 // Determines whether the given relay server supports the given protocol.
234 bool SupportsProtocol(const RelayServerConfig& relay,
235 ProtocolType type) const;
236 bool SupportsProtocol(RelayType turn_type, ProtocolType type) const;
237 // Helper method returns the server addresses for the matching RelayType and
238 // Protocol type.
239 ServerAddresses GetRelayServerAddresses(
240 RelayType turn_type, ProtocolType type) const;
241};
242
honghaizf421bdc2015-07-17 16:21:55 -0700243class UDPPort;
244class TurnPort;
245
246// Performs the allocation of ports, in a sequenced (timed) manner, for a given
247// network and IP address.
248class AllocationSequence : public rtc::MessageHandler,
249 public sigslot::has_slots<> {
250 public:
251 enum State {
252 kInit, // Initial state.
253 kRunning, // Started allocating ports.
254 kStopped, // Stopped from running.
255 kCompleted, // All ports are allocated.
256
257 // kInit --> kRunning --> {kCompleted|kStopped}
258 };
259 AllocationSequence(BasicPortAllocatorSession* session,
260 rtc::Network* network,
261 PortConfiguration* config,
Peter Boström0c4e06b2015-10-07 12:23:21 +0200262 uint32_t flags);
honghaizf421bdc2015-07-17 16:21:55 -0700263 ~AllocationSequence();
264 bool Init();
265 void Clear();
honghaiz8c404fa2015-09-28 07:59:43 -0700266 void OnNetworkRemoved();
honghaizf421bdc2015-07-17 16:21:55 -0700267
268 State state() const { return state_; }
honghaiz8c404fa2015-09-28 07:59:43 -0700269 const rtc::Network* network() const { return network_; }
270 bool network_removed() const { return network_removed_; }
honghaizf421bdc2015-07-17 16:21:55 -0700271
272 // Disables the phases for a new sequence that this one already covers for an
273 // equivalent network setup.
274 void DisableEquivalentPhases(rtc::Network* network,
275 PortConfiguration* config,
Peter Boström0c4e06b2015-10-07 12:23:21 +0200276 uint32_t* flags);
honghaizf421bdc2015-07-17 16:21:55 -0700277
278 // Starts and stops the sequence. When started, it will continue allocating
279 // new ports on its own timed schedule.
280 void Start();
281 void Stop();
282
283 // MessageHandler
284 void OnMessage(rtc::Message* msg);
285
286 void EnableProtocol(ProtocolType proto);
287 bool ProtocolEnabled(ProtocolType proto) const;
288
289 // Signal from AllocationSequence, when it's done with allocating ports.
290 // This signal is useful, when port allocation fails which doesn't result
291 // in any candidates. Using this signal BasicPortAllocatorSession can send
292 // its candidate discovery conclusion signal. Without this signal,
293 // BasicPortAllocatorSession doesn't have any event to trigger signal. This
294 // can also be achieved by starting timer in BPAS.
295 sigslot::signal1<AllocationSequence*> SignalPortAllocationComplete;
296
297 protected:
298 // For testing.
299 void CreateTurnPort(const RelayServerConfig& config);
300
301 private:
302 typedef std::vector<ProtocolType> ProtocolList;
303
Peter Boström0c4e06b2015-10-07 12:23:21 +0200304 bool IsFlagSet(uint32_t flag) { return ((flags_ & flag) != 0); }
honghaizf421bdc2015-07-17 16:21:55 -0700305 void CreateUDPPorts();
306 void CreateTCPPorts();
307 void CreateStunPorts();
308 void CreateRelayPorts();
309 void CreateGturnPort(const RelayServerConfig& config);
310
311 void OnReadPacket(rtc::AsyncPacketSocket* socket,
312 const char* data,
313 size_t size,
314 const rtc::SocketAddress& remote_addr,
315 const rtc::PacketTime& packet_time);
316
317 void OnPortDestroyed(PortInterface* port);
318
319 BasicPortAllocatorSession* session_;
honghaiz8c404fa2015-09-28 07:59:43 -0700320 bool network_removed_ = false;
honghaizf421bdc2015-07-17 16:21:55 -0700321 rtc::Network* network_;
322 rtc::IPAddress ip_;
323 PortConfiguration* config_;
324 State state_;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200325 uint32_t flags_;
honghaizf421bdc2015-07-17 16:21:55 -0700326 ProtocolList protocols_;
327 rtc::scoped_ptr<rtc::AsyncPacketSocket> udp_socket_;
328 // There will be only one udp port per AllocationSequence.
329 UDPPort* udp_port_;
330 std::vector<TurnPort*> turn_ports_;
331 int phase_;
332};
333
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000334} // namespace cricket
335
336#endif // WEBRTC_P2P_CLIENT_BASICPORTALLOCATOR_H_