blob: ac2cfbfc132ded4bc3e3bc1503f7c86ada72ef0d [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,
174 PortConfiguration* config, uint32* flags);
175 void AddAllocatedPort(Port* port, AllocationSequence* seq,
176 bool prepare_address);
177 void OnCandidateReady(Port* port, const Candidate& c);
178 void OnPortComplete(Port* port);
179 void OnPortError(Port* port);
180 void OnProtocolEnabled(AllocationSequence* seq, ProtocolType proto);
181 void OnPortDestroyed(PortInterface* port);
182 void OnShake();
183 void MaybeSignalCandidatesAllocationDone();
184 void OnPortAllocationComplete(AllocationSequence* seq);
185 PortData* FindPort(Port* port);
honghaiz8c404fa2015-09-28 07:59:43 -0700186 void GetNetworks(std::vector<rtc::Network*>* networks);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000187
188 bool CheckCandidateFilter(const Candidate& c);
189
190 BasicPortAllocator* allocator_;
191 rtc::Thread* network_thread_;
192 rtc::scoped_ptr<rtc::PacketSocketFactory> owned_socket_factory_;
193 rtc::PacketSocketFactory* socket_factory_;
194 bool allocation_started_;
195 bool network_manager_started_;
196 bool running_; // set when StartGetAllPorts is called
197 bool allocation_sequences_created_;
198 std::vector<PortConfiguration*> configs_;
199 std::vector<AllocationSequence*> sequences_;
200 std::vector<PortData> ports_;
201
202 friend class AllocationSequence;
203};
204
205// Records configuration information useful in creating ports.
206struct PortConfiguration : public rtc::MessageData {
207 // TODO(jiayl): remove |stun_address| when Chrome is updated.
208 rtc::SocketAddress stun_address;
209 ServerAddresses stun_servers;
210 std::string username;
211 std::string password;
212
213 typedef std::vector<RelayServerConfig> RelayList;
214 RelayList relays;
215
216 // TODO(jiayl): remove this ctor when Chrome is updated.
217 PortConfiguration(const rtc::SocketAddress& stun_address,
218 const std::string& username,
219 const std::string& password);
220
221 PortConfiguration(const ServerAddresses& stun_servers,
222 const std::string& username,
223 const std::string& password);
224
deadbeefc5d0d952015-07-16 10:22:21 -0700225 // Returns addresses of both the explicitly configured STUN servers,
226 // and TURN servers that should be used as STUN servers.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000227 ServerAddresses StunServers();
228
229 // Adds another relay server, with the given ports and modifier, to the list.
230 void AddRelay(const RelayServerConfig& config);
231
232 // Determines whether the given relay server supports the given protocol.
233 bool SupportsProtocol(const RelayServerConfig& relay,
234 ProtocolType type) const;
235 bool SupportsProtocol(RelayType turn_type, ProtocolType type) const;
236 // Helper method returns the server addresses for the matching RelayType and
237 // Protocol type.
238 ServerAddresses GetRelayServerAddresses(
239 RelayType turn_type, ProtocolType type) const;
240};
241
honghaizf421bdc2015-07-17 16:21:55 -0700242class UDPPort;
243class TurnPort;
244
245// Performs the allocation of ports, in a sequenced (timed) manner, for a given
246// network and IP address.
247class AllocationSequence : public rtc::MessageHandler,
248 public sigslot::has_slots<> {
249 public:
250 enum State {
251 kInit, // Initial state.
252 kRunning, // Started allocating ports.
253 kStopped, // Stopped from running.
254 kCompleted, // All ports are allocated.
255
256 // kInit --> kRunning --> {kCompleted|kStopped}
257 };
258 AllocationSequence(BasicPortAllocatorSession* session,
259 rtc::Network* network,
260 PortConfiguration* config,
261 uint32 flags);
262 ~AllocationSequence();
263 bool Init();
264 void Clear();
honghaiz8c404fa2015-09-28 07:59:43 -0700265 void OnNetworkRemoved();
honghaizf421bdc2015-07-17 16:21:55 -0700266
267 State state() const { return state_; }
honghaiz8c404fa2015-09-28 07:59:43 -0700268 const rtc::Network* network() const { return network_; }
269 bool network_removed() const { return network_removed_; }
honghaizf421bdc2015-07-17 16:21:55 -0700270
271 // Disables the phases for a new sequence that this one already covers for an
272 // equivalent network setup.
273 void DisableEquivalentPhases(rtc::Network* network,
274 PortConfiguration* config,
275 uint32* flags);
276
277 // Starts and stops the sequence. When started, it will continue allocating
278 // new ports on its own timed schedule.
279 void Start();
280 void Stop();
281
282 // MessageHandler
283 void OnMessage(rtc::Message* msg);
284
285 void EnableProtocol(ProtocolType proto);
286 bool ProtocolEnabled(ProtocolType proto) const;
287
288 // Signal from AllocationSequence, when it's done with allocating ports.
289 // This signal is useful, when port allocation fails which doesn't result
290 // in any candidates. Using this signal BasicPortAllocatorSession can send
291 // its candidate discovery conclusion signal. Without this signal,
292 // BasicPortAllocatorSession doesn't have any event to trigger signal. This
293 // can also be achieved by starting timer in BPAS.
294 sigslot::signal1<AllocationSequence*> SignalPortAllocationComplete;
295
296 protected:
297 // For testing.
298 void CreateTurnPort(const RelayServerConfig& config);
299
300 private:
301 typedef std::vector<ProtocolType> ProtocolList;
302
303 bool IsFlagSet(uint32 flag) { return ((flags_ & flag) != 0); }
304 void CreateUDPPorts();
305 void CreateTCPPorts();
306 void CreateStunPorts();
307 void CreateRelayPorts();
308 void CreateGturnPort(const RelayServerConfig& config);
309
310 void OnReadPacket(rtc::AsyncPacketSocket* socket,
311 const char* data,
312 size_t size,
313 const rtc::SocketAddress& remote_addr,
314 const rtc::PacketTime& packet_time);
315
316 void OnPortDestroyed(PortInterface* port);
317
318 BasicPortAllocatorSession* session_;
honghaiz8c404fa2015-09-28 07:59:43 -0700319 bool network_removed_ = false;
honghaizf421bdc2015-07-17 16:21:55 -0700320 rtc::Network* network_;
321 rtc::IPAddress ip_;
322 PortConfiguration* config_;
323 State state_;
324 uint32 flags_;
325 ProtocolList protocols_;
326 rtc::scoped_ptr<rtc::AsyncPacketSocket> udp_socket_;
327 // There will be only one udp port per AllocationSequence.
328 UDPPort* udp_port_;
329 std::vector<TurnPort*> turn_ports_;
330 int phase_;
331};
332
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000333} // namespace cricket
334
335#endif // WEBRTC_P2P_CLIENT_BASICPORTALLOCATOR_H_