blob: 4d9a81164435a5572a989eb40bde4b8ab0a75fc6 [file] [log] [blame]
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +00001/*
2 * Copyright 2012 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_TURNPORT_H_
12#define WEBRTC_P2P_BASE_TURNPORT_H_
13
14#include <stdio.h>
15#include <list>
16#include <set>
17#include <string>
18
19#include "webrtc/p2p/base/port.h"
20#include "webrtc/p2p/client/basicportallocator.h"
Edward Lemurc20978e2017-07-06 19:44:34 +020021#include "webrtc/rtc_base/asyncinvoker.h"
22#include "webrtc/rtc_base/asyncpacketsocket.h"
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000023
24namespace rtc {
25class AsyncResolver;
26class SignalThread;
27}
28
29namespace cricket {
30
31extern const char TURN_PORT_TYPE[];
32class TurnAllocateRequest;
33class TurnEntry;
34
35class TurnPort : public Port {
36 public:
honghaizb19eba32015-08-03 10:23:31 -070037 enum PortState {
38 STATE_CONNECTING, // Initial state, cannot send any packets.
39 STATE_CONNECTED, // Socket connected, ready to send stun requests.
40 STATE_READY, // Received allocate success, can send any packets.
honghaiz079a7a12016-06-22 16:26:29 -070041 STATE_RECEIVEONLY, // Had REFRESH_REQUEST error, cannot send any packets.
42 STATE_DISCONNECTED, // TCP connection died, cannot send/receive any
43 // packets.
honghaizb19eba32015-08-03 10:23:31 -070044 };
deadbeef5c3c1042017-08-04 15:01:57 -070045 // Create a TURN port using the shared UDP socket, |socket|.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000046 static TurnPort* Create(rtc::Thread* thread,
47 rtc::PacketSocketFactory* factory,
48 rtc::Network* network,
49 rtc::AsyncPacketSocket* socket,
50 const std::string& username, // ice username.
51 const std::string& password, // ice password.
52 const ProtocolAddress& server_address,
53 const RelayCredentials& credentials,
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +000054 int server_priority,
maxmorine9ef9072017-08-29 04:49:00 -070055 const std::string& origin) {
pkasting@chromium.org332331f2014-11-06 20:19:22 +000056 return new TurnPort(thread, factory, network, socket, username, password,
maxmorine9ef9072017-08-29 04:49:00 -070057 server_address, credentials, server_priority, origin);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000058 }
59
deadbeef5c3c1042017-08-04 15:01:57 -070060 // Create a TURN port that will use a new socket, bound to |network| and
61 // using a port in the range between |min_port| and |max_port|.
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000062 static TurnPort* Create(rtc::Thread* thread,
63 rtc::PacketSocketFactory* factory,
64 rtc::Network* network,
Peter Boström0c4e06b2015-10-07 12:23:21 +020065 uint16_t min_port,
66 uint16_t max_port,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000067 const std::string& username, // ice username.
68 const std::string& password, // ice password.
69 const ProtocolAddress& server_address,
70 const RelayCredentials& credentials,
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +000071 int server_priority,
Diogo Real1dca9d52017-08-29 12:18:32 -070072 const std::string& origin,
Diogo Real7bd1f1b2017-09-08 12:50:41 -070073 const std::vector<std::string>& tls_alpn_protocols,
74 const std::vector<std::string>& tls_elliptic_curves) {
deadbeef5c3c1042017-08-04 15:01:57 -070075 return new TurnPort(thread, factory, network, min_port, max_port, username,
76 password, server_address, credentials, server_priority,
Diogo Real7bd1f1b2017-09-08 12:50:41 -070077 origin, tls_alpn_protocols, tls_elliptic_curves);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000078 }
79
80 virtual ~TurnPort();
81
82 const ProtocolAddress& server_address() const { return server_address_; }
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +000083 // Returns an empty address if the local address has not been assigned.
84 rtc::SocketAddress GetLocalAddress() const;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000085
honghaizb19eba32015-08-03 10:23:31 -070086 bool ready() const { return state_ == STATE_READY; }
87 bool connected() const {
88 return state_ == STATE_READY || state_ == STATE_CONNECTED;
89 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +000090 const RelayCredentials& credentials() const { return credentials_; }
91
Honghai Zhangb9e7b4a2016-06-30 20:52:02 -070092 virtual ProtocolType GetProtocol() const { return server_address_.proto; }
93
hnsl04833622017-01-09 08:35:45 -080094 virtual TlsCertPolicy GetTlsCertPolicy() const { return tls_cert_policy_; }
95
96 virtual void SetTlsCertPolicy(TlsCertPolicy tls_cert_policy) {
97 tls_cert_policy_ = tls_cert_policy;
98 }
99
Diogo Real1dca9d52017-08-29 12:18:32 -0700100 virtual std::vector<std::string> GetTlsAlpnProtocols() const {
101 return tls_alpn_protocols_;
102 }
103
Diogo Real7bd1f1b2017-09-08 12:50:41 -0700104 virtual std::vector<std::string> GetTlsEllipticCurves() const {
105 return tls_elliptic_curves_;
106 }
107
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000108 virtual void PrepareAddress();
109 virtual Connection* CreateConnection(
110 const Candidate& c, PortInterface::CandidateOrigin origin);
111 virtual int SendTo(const void* data, size_t size,
112 const rtc::SocketAddress& addr,
113 const rtc::PacketOptions& options,
114 bool payload);
115 virtual int SetOption(rtc::Socket::Option opt, int value);
116 virtual int GetOption(rtc::Socket::Option opt, int* value);
117 virtual int GetError();
118
Sergey Ulanov17fa6722016-05-10 10:20:47 -0700119 virtual bool HandleIncomingPacket(rtc::AsyncPacketSocket* socket,
120 const char* data, size_t size,
121 const rtc::SocketAddress& remote_addr,
122 const rtc::PacketTime& packet_time);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000123 virtual void OnReadPacket(rtc::AsyncPacketSocket* socket,
124 const char* data, size_t size,
125 const rtc::SocketAddress& remote_addr,
126 const rtc::PacketTime& packet_time);
127
Stefan Holmer55674ff2016-01-14 15:49:16 +0100128 virtual void OnSentPacket(rtc::AsyncPacketSocket* socket,
129 const rtc::SentPacket& sent_packet);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000130 virtual void OnReadyToSend(rtc::AsyncPacketSocket* socket);
Honghai Zhangf9945b22015-12-15 12:20:13 -0800131 virtual bool SupportsProtocol(const std::string& protocol) const {
132 // Turn port only connects to UDP candidates.
133 return protocol == UDP_PROTOCOL_NAME;
134 }
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000135
136 void OnSocketConnect(rtc::AsyncPacketSocket* socket);
137 void OnSocketClose(rtc::AsyncPacketSocket* socket, int error);
138
139
140 const std::string& hash() const { return hash_; }
141 const std::string& nonce() const { return nonce_; }
142
143 int error() const { return error_; }
144
145 void OnAllocateMismatch();
146
147 rtc::AsyncPacketSocket* socket() const {
148 return socket_;
149 }
150
honghaiz32f39962015-11-17 11:36:31 -0800151 // For testing only.
152 rtc::AsyncInvoker* invoker() { return &invoker_; }
153
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000154 // Signal with resolved server address.
155 // Parameters are port, server address and resolved server address.
156 // This signal will be sent only if server address is resolved successfully.
157 sigslot::signal3<TurnPort*,
158 const rtc::SocketAddress&,
159 const rtc::SocketAddress&> SignalResolvedServerAddress;
160
Honghai Zhangf67c5482015-12-11 15:16:54 -0800161 // All public methods/signals below are for testing only.
162 sigslot::signal2<TurnPort*, int> SignalTurnRefreshResult;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000163 sigslot::signal3<TurnPort*, const rtc::SocketAddress&, int>
164 SignalCreatePermissionResult;
honghaiz6b9ab922016-01-05 09:06:12 -0800165 void FlushRequests(int msg_type) { request_manager_.Flush(msg_type); }
166 bool HasRequests() { return !request_manager_.empty(); }
Honghai Zhangf67c5482015-12-11 15:16:54 -0800167 void set_credentials(RelayCredentials& credentials) {
168 credentials_ = credentials;
169 }
170 // Finds the turn entry with |address| and sets its channel id.
171 // Returns true if the entry is found.
172 bool SetEntryChannelId(const rtc::SocketAddress& address, int channel_id);
honghaiz9dfed792016-01-29 13:22:31 -0800173 // Visible for testing.
174 // Shuts down the turn port, usually because of some fatal errors.
175 void Close();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000176
177 protected:
178 TurnPort(rtc::Thread* thread,
179 rtc::PacketSocketFactory* factory,
180 rtc::Network* network,
181 rtc::AsyncPacketSocket* socket,
182 const std::string& username,
183 const std::string& password,
184 const ProtocolAddress& server_address,
185 const RelayCredentials& credentials,
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000186 int server_priority,
maxmorine9ef9072017-08-29 04:49:00 -0700187 const std::string& origin);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000188
189 TurnPort(rtc::Thread* thread,
190 rtc::PacketSocketFactory* factory,
191 rtc::Network* network,
Peter Boström0c4e06b2015-10-07 12:23:21 +0200192 uint16_t min_port,
193 uint16_t max_port,
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000194 const std::string& username,
195 const std::string& password,
196 const ProtocolAddress& server_address,
197 const RelayCredentials& credentials,
pthatcher@webrtc.org0ba15332015-01-10 00:47:02 +0000198 int server_priority,
Diogo Real1dca9d52017-08-29 12:18:32 -0700199 const std::string& origin,
Diogo Real7bd1f1b2017-09-08 12:50:41 -0700200 const std::vector<std::string>& tls_alpn_protocols,
201 const std::vector<std::string>& tls_elliptic_curves);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000202
203 private:
204 enum {
Honghai Zhangf67c5482015-12-11 15:16:54 -0800205 MSG_ALLOCATE_ERROR = MSG_FIRST_AVAILABLE,
guoweis@webrtc.org19e4e8d2015-01-10 02:41:32 +0000206 MSG_ALLOCATE_MISMATCH,
honghaiz6b9ab922016-01-05 09:06:12 -0800207 MSG_TRY_ALTERNATE_SERVER,
208 MSG_REFRESH_ERROR
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000209 };
210
211 typedef std::list<TurnEntry*> EntryList;
212 typedef std::map<rtc::Socket::Option, int> SocketOptionsMap;
213 typedef std::set<rtc::SocketAddress> AttemptedServerSet;
214
215 virtual void OnMessage(rtc::Message* pmsg);
honghaiz36f50e82016-06-01 15:57:03 -0700216 virtual void HandleConnectionDestroyed(Connection* conn);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000217
218 bool CreateTurnClientSocket();
219
220 void set_nonce(const std::string& nonce) { nonce_ = nonce; }
221 void set_realm(const std::string& realm) {
222 if (realm != realm_) {
223 realm_ = realm;
224 UpdateHash();
225 }
226 }
227
honghaiz079a7a12016-06-22 16:26:29 -0700228 void OnRefreshError();
229 void HandleRefreshError();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000230 bool SetAlternateServer(const rtc::SocketAddress& address);
231 void ResolveTurnAddress(const rtc::SocketAddress& address);
232 void OnResolveResult(rtc::AsyncResolverInterface* resolver);
233
234 void AddRequestAuthInfo(StunMessage* msg);
235 void OnSendStunPacket(const void* data, size_t size, StunRequest* request);
236 // Stun address from allocate success response.
237 // Currently used only for testing.
238 void OnStunAddress(const rtc::SocketAddress& address);
239 void OnAllocateSuccess(const rtc::SocketAddress& address,
240 const rtc::SocketAddress& stun_address);
241 void OnAllocateError();
242 void OnAllocateRequestTimeout();
243
244 void HandleDataIndication(const char* data, size_t size,
245 const rtc::PacketTime& packet_time);
246 void HandleChannelData(int channel_id, const char* data, size_t size,
247 const rtc::PacketTime& packet_time);
248 void DispatchPacket(const char* data, size_t size,
249 const rtc::SocketAddress& remote_addr,
250 ProtocolType proto, const rtc::PacketTime& packet_time);
251
252 bool ScheduleRefresh(int lifetime);
253 void SendRequest(StunRequest* request, int delay);
254 int Send(const void* data, size_t size,
255 const rtc::PacketOptions& options);
256 void UpdateHash();
257 bool UpdateNonce(StunMessage* response);
honghaizc463e202016-02-01 15:19:08 -0800258 void ResetNonce();
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000259
260 bool HasPermission(const rtc::IPAddress& ipaddr) const;
261 TurnEntry* FindEntry(const rtc::SocketAddress& address) const;
262 TurnEntry* FindEntry(int channel_id) const;
honghaizc3e0fe72015-12-02 16:43:25 -0800263 bool EntryExists(TurnEntry* e);
honghaiz32f39962015-11-17 11:36:31 -0800264 void CreateOrRefreshEntry(const rtc::SocketAddress& address);
265 void DestroyEntry(TurnEntry* entry);
266 // Destroys the entry only if |timestamp| matches the destruction timestamp
267 // in |entry|.
honghaiz34b11eb2016-03-16 08:55:44 -0700268 void DestroyEntryIfNotCancelled(TurnEntry* entry, int64_t timestamp);
honghaiz32f39962015-11-17 11:36:31 -0800269 void ScheduleEntryDestruction(TurnEntry* entry);
270 void CancelEntryDestruction(TurnEntry* entry);
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000271
honghaiz079a7a12016-06-22 16:26:29 -0700272 // Marks the connection with remote address |address| failed and
273 // pruned (a.k.a. write-timed-out). Returns true if a connection is found.
274 bool FailAndPruneConnection(const rtc::SocketAddress& address);
Honghai Zhangf67c5482015-12-11 15:16:54 -0800275
zhihuang26d99c22017-02-13 12:47:27 -0800276 // Reconstruct the URL of the server which the candidate is gathered from.
277 std::string ReconstructedServerUrl();
278
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000279 ProtocolAddress server_address_;
hnsl04833622017-01-09 08:35:45 -0800280 TlsCertPolicy tls_cert_policy_ = TlsCertPolicy::TLS_CERT_POLICY_SECURE;
Diogo Real1dca9d52017-08-29 12:18:32 -0700281 std::vector<std::string> tls_alpn_protocols_;
Diogo Real7bd1f1b2017-09-08 12:50:41 -0700282 std::vector<std::string> tls_elliptic_curves_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000283 RelayCredentials credentials_;
284 AttemptedServerSet attempted_server_addresses_;
285
286 rtc::AsyncPacketSocket* socket_;
287 SocketOptionsMap socket_options_;
288 rtc::AsyncResolverInterface* resolver_;
289 int error_;
290
291 StunRequestManager request_manager_;
292 std::string realm_; // From 401/438 response message.
293 std::string nonce_; // From 401/438 response message.
294 std::string hash_; // Digest of username:realm:password
295
296 int next_channel_number_;
297 EntryList entries_;
298
honghaizb19eba32015-08-03 10:23:31 -0700299 PortState state_;
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000300 // By default the value will be set to 0. This value will be used in
301 // calculating the candidate priority.
302 int server_priority_;
303
304 // The number of retries made due to allocate mismatch error.
305 size_t allocate_mismatch_retries_;
306
honghaiz32f39962015-11-17 11:36:31 -0800307 rtc::AsyncInvoker invoker_;
308
henrike@webrtc.org269fb4b2014-10-28 22:20:11 +0000309 friend class TurnEntry;
310 friend class TurnAllocateRequest;
311 friend class TurnRefreshRequest;
312 friend class TurnCreatePermissionRequest;
313 friend class TurnChannelBindRequest;
314};
315
316} // namespace cricket
317
318#endif // WEBRTC_P2P_BASE_TURNPORT_H_