1 /*
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 #include "webrtc/p2p/base/turnport.h"
12
13 #include <functional>
14
15 #include "webrtc/p2p/base/common.h"
16 #include "webrtc/p2p/base/stun.h"
17 #include "webrtc/base/asyncpacketsocket.h"
18 #include "webrtc/base/byteorder.h"
19 #include "webrtc/base/common.h"
20 #include "webrtc/base/logging.h"
21 #include "webrtc/base/nethelpers.h"
22 #include "webrtc/base/socketaddress.h"
23 #include "webrtc/base/stringencode.h"
24
25 namespace cricket {
26
27 // TODO(juberti): Move to stun.h when relay messages have been renamed.
28 static const int TURN_ALLOCATE_REQUEST = STUN_ALLOCATE_REQUEST;
29
30 // TODO(juberti): Extract to turnmessage.h
31 static const int TURN_DEFAULT_PORT = 3478;
32 static const int TURN_CHANNEL_NUMBER_START = 0x4000;
33 static const int TURN_PERMISSION_TIMEOUT = 5 * 60 * 1000; // 5 minutes
34
35 static const size_t TURN_CHANNEL_HEADER_SIZE = 4U;
36
37 // Retry at most twice (i.e. three different ALLOCATE requests) on
38 // STUN_ERROR_ALLOCATION_MISMATCH error per rfc5766.
39 static const size_t MAX_ALLOCATE_MISMATCH_RETRIES = 2;
40
41 static const int TURN_SUCCESS_RESULT_CODE = 0;
42
IsTurnChannelData(uint16_t msg_type)43 inline bool IsTurnChannelData(uint16_t msg_type) {
44 return ((msg_type & 0xC000) == 0x4000); // MSB are 0b01
45 }
46
GetRelayPreference(cricket::ProtocolType proto,bool secure)47 static int GetRelayPreference(cricket::ProtocolType proto, bool secure) {
48 int relay_preference = ICE_TYPE_PREFERENCE_RELAY;
49 if (proto == cricket::PROTO_TCP) {
50 relay_preference -= 1;
51 if (secure)
52 relay_preference -= 1;
53 }
54
55 ASSERT(relay_preference >= 0);
56 return relay_preference;
57 }
58
59 class TurnAllocateRequest : public StunRequest {
60 public:
61 explicit TurnAllocateRequest(TurnPort* port);
62 void Prepare(StunMessage* request) override;
63 void OnSent() override;
64 void OnResponse(StunMessage* response) override;
65 void OnErrorResponse(StunMessage* response) override;
66 void OnTimeout() override;
67
68 private:
69 // Handles authentication challenge from the server.
70 void OnAuthChallenge(StunMessage* response, int code);
71 void OnTryAlternate(StunMessage* response, int code);
72 void OnUnknownAttribute(StunMessage* response);
73
74 TurnPort* port_;
75 };
76
77 class TurnRefreshRequest : public StunRequest {
78 public:
79 explicit TurnRefreshRequest(TurnPort* port);
80 void Prepare(StunMessage* request) override;
81 void OnSent() override;
82 void OnResponse(StunMessage* response) override;
83 void OnErrorResponse(StunMessage* response) override;
84 void OnTimeout() override;
set_lifetime(int lifetime)85 void set_lifetime(int lifetime) { lifetime_ = lifetime; }
86
87 private:
88 TurnPort* port_;
89 int lifetime_;
90 };
91
92 class TurnCreatePermissionRequest : public StunRequest,
93 public sigslot::has_slots<> {
94 public:
95 TurnCreatePermissionRequest(TurnPort* port, TurnEntry* entry,
96 const rtc::SocketAddress& ext_addr);
97 void Prepare(StunMessage* request) override;
98 void OnSent() override;
99 void OnResponse(StunMessage* response) override;
100 void OnErrorResponse(StunMessage* response) override;
101 void OnTimeout() override;
102
103 private:
104 void OnEntryDestroyed(TurnEntry* entry);
105
106 TurnPort* port_;
107 TurnEntry* entry_;
108 rtc::SocketAddress ext_addr_;
109 };
110
111 class TurnChannelBindRequest : public StunRequest,
112 public sigslot::has_slots<> {
113 public:
114 TurnChannelBindRequest(TurnPort* port, TurnEntry* entry, int channel_id,
115 const rtc::SocketAddress& ext_addr);
116 void Prepare(StunMessage* request) override;
117 void OnSent() override;
118 void OnResponse(StunMessage* response) override;
119 void OnErrorResponse(StunMessage* response) override;
120 void OnTimeout() override;
121
122 private:
123 void OnEntryDestroyed(TurnEntry* entry);
124
125 TurnPort* port_;
126 TurnEntry* entry_;
127 int channel_id_;
128 rtc::SocketAddress ext_addr_;
129 };
130
131 // Manages a "connection" to a remote destination. We will attempt to bring up
132 // a channel for this remote destination to reduce the overhead of sending data.
133 class TurnEntry : public sigslot::has_slots<> {
134 public:
135 enum BindState { STATE_UNBOUND, STATE_BINDING, STATE_BOUND };
136 TurnEntry(TurnPort* port, int channel_id,
137 const rtc::SocketAddress& ext_addr);
138
port()139 TurnPort* port() { return port_; }
140
channel_id() const141 int channel_id() const { return channel_id_; }
142 // For testing only.
set_channel_id(int channel_id)143 void set_channel_id(int channel_id) { channel_id_ = channel_id; }
144
address() const145 const rtc::SocketAddress& address() const { return ext_addr_; }
state() const146 BindState state() const { return state_; }
147
destruction_timestamp()148 uint32_t destruction_timestamp() { return destruction_timestamp_; }
set_destruction_timestamp(uint32_t destruction_timestamp)149 void set_destruction_timestamp(uint32_t destruction_timestamp) {
150 destruction_timestamp_ = destruction_timestamp;
151 }
152
153 // Helper methods to send permission and channel bind requests.
154 void SendCreatePermissionRequest(int delay);
155 void SendChannelBindRequest(int delay);
156 // Sends a packet to the given destination address.
157 // This will wrap the packet in STUN if necessary.
158 int Send(const void* data, size_t size, bool payload,
159 const rtc::PacketOptions& options);
160
161 void OnCreatePermissionSuccess();
162 void OnCreatePermissionError(StunMessage* response, int code);
163 void OnCreatePermissionTimeout();
164 void OnChannelBindSuccess();
165 void OnChannelBindError(StunMessage* response, int code);
166 void OnChannelBindTimeout();
167 // Signal sent when TurnEntry is destroyed.
168 sigslot::signal1<TurnEntry*> SignalDestroyed;
169
170 private:
171 TurnPort* port_;
172 int channel_id_;
173 rtc::SocketAddress ext_addr_;
174 BindState state_;
175 // A non-zero value indicates that this entry is scheduled to be destroyed.
176 // It is also used as an ID of the event scheduling. When the destruction
177 // event actually fires, the TurnEntry will be destroyed only if the
178 // timestamp here matches the one in the firing event.
179 uint32_t destruction_timestamp_ = 0;
180 };
181
TurnPort(rtc::Thread * thread,rtc::PacketSocketFactory * factory,rtc::Network * network,rtc::AsyncPacketSocket * socket,const std::string & username,const std::string & password,const ProtocolAddress & server_address,const RelayCredentials & credentials,int server_priority,const std::string & origin)182 TurnPort::TurnPort(rtc::Thread* thread,
183 rtc::PacketSocketFactory* factory,
184 rtc::Network* network,
185 rtc::AsyncPacketSocket* socket,
186 const std::string& username,
187 const std::string& password,
188 const ProtocolAddress& server_address,
189 const RelayCredentials& credentials,
190 int server_priority,
191 const std::string& origin)
192 : Port(thread,
193 factory,
194 network,
195 socket->GetLocalAddress().ipaddr(),
196 username,
197 password),
198 server_address_(server_address),
199 credentials_(credentials),
200 socket_(socket),
201 resolver_(NULL),
202 error_(0),
203 request_manager_(thread),
204 next_channel_number_(TURN_CHANNEL_NUMBER_START),
205 state_(STATE_CONNECTING),
206 server_priority_(server_priority),
207 allocate_mismatch_retries_(0) {
208 request_manager_.SignalSendPacket.connect(this, &TurnPort::OnSendStunPacket);
209 request_manager_.set_origin(origin);
210 }
211
TurnPort(rtc::Thread * thread,rtc::PacketSocketFactory * factory,rtc::Network * network,const rtc::IPAddress & ip,uint16_t min_port,uint16_t max_port,const std::string & username,const std::string & password,const ProtocolAddress & server_address,const RelayCredentials & credentials,int server_priority,const std::string & origin)212 TurnPort::TurnPort(rtc::Thread* thread,
213 rtc::PacketSocketFactory* factory,
214 rtc::Network* network,
215 const rtc::IPAddress& ip,
216 uint16_t min_port,
217 uint16_t max_port,
218 const std::string& username,
219 const std::string& password,
220 const ProtocolAddress& server_address,
221 const RelayCredentials& credentials,
222 int server_priority,
223 const std::string& origin)
224 : Port(thread,
225 RELAY_PORT_TYPE,
226 factory,
227 network,
228 ip,
229 min_port,
230 max_port,
231 username,
232 password),
233 server_address_(server_address),
234 credentials_(credentials),
235 socket_(NULL),
236 resolver_(NULL),
237 error_(0),
238 request_manager_(thread),
239 next_channel_number_(TURN_CHANNEL_NUMBER_START),
240 state_(STATE_CONNECTING),
241 server_priority_(server_priority),
242 allocate_mismatch_retries_(0) {
243 request_manager_.SignalSendPacket.connect(this, &TurnPort::OnSendStunPacket);
244 request_manager_.set_origin(origin);
245 }
246
~TurnPort()247 TurnPort::~TurnPort() {
248 // TODO(juberti): Should this even be necessary?
249
250 // release the allocation by sending a refresh with
251 // lifetime 0.
252 if (ready()) {
253 TurnRefreshRequest bye(this);
254 bye.set_lifetime(0);
255 SendRequest(&bye, 0);
256 }
257
258 while (!entries_.empty()) {
259 DestroyEntry(entries_.front());
260 }
261 if (resolver_) {
262 resolver_->Destroy(false);
263 }
264 if (!SharedSocket()) {
265 delete socket_;
266 }
267 }
268
GetLocalAddress() const269 rtc::SocketAddress TurnPort::GetLocalAddress() const {
270 return socket_ ? socket_->GetLocalAddress() : rtc::SocketAddress();
271 }
272
PrepareAddress()273 void TurnPort::PrepareAddress() {
274 if (credentials_.username.empty() ||
275 credentials_.password.empty()) {
276 LOG(LS_ERROR) << "Allocation can't be started without setting the"
277 << " TURN server credentials for the user.";
278 OnAllocateError();
279 return;
280 }
281
282 if (!server_address_.address.port()) {
283 // We will set default TURN port, if no port is set in the address.
284 server_address_.address.SetPort(TURN_DEFAULT_PORT);
285 }
286
287 if (server_address_.address.IsUnresolvedIP()) {
288 ResolveTurnAddress(server_address_.address);
289 } else {
290 // If protocol family of server address doesn't match with local, return.
291 if (!IsCompatibleAddress(server_address_.address)) {
292 LOG(LS_ERROR) << "IP address family does not match: "
293 << "server: " << server_address_.address.family()
294 << "local: " << ip().family();
295 OnAllocateError();
296 return;
297 }
298
299 // Insert the current address to prevent redirection pingpong.
300 attempted_server_addresses_.insert(server_address_.address);
301
302 LOG_J(LS_INFO, this) << "Trying to connect to TURN server via "
303 << ProtoToString(server_address_.proto) << " @ "
304 << server_address_.address.ToSensitiveString();
305 if (!CreateTurnClientSocket()) {
306 LOG(LS_ERROR) << "Failed to create TURN client socket";
307 OnAllocateError();
308 return;
309 }
310 if (server_address_.proto == PROTO_UDP) {
311 // If its UDP, send AllocateRequest now.
312 // For TCP and TLS AllcateRequest will be sent by OnSocketConnect.
313 SendRequest(new TurnAllocateRequest(this), 0);
314 }
315 }
316 }
317
CreateTurnClientSocket()318 bool TurnPort::CreateTurnClientSocket() {
319 ASSERT(!socket_ || SharedSocket());
320
321 if (server_address_.proto == PROTO_UDP && !SharedSocket()) {
322 socket_ = socket_factory()->CreateUdpSocket(
323 rtc::SocketAddress(ip(), 0), min_port(), max_port());
324 } else if (server_address_.proto == PROTO_TCP) {
325 ASSERT(!SharedSocket());
326 int opts = rtc::PacketSocketFactory::OPT_STUN;
327 // If secure bit is enabled in server address, use TLS over TCP.
328 if (server_address_.secure) {
329 opts |= rtc::PacketSocketFactory::OPT_TLS;
330 }
331 socket_ = socket_factory()->CreateClientTcpSocket(
332 rtc::SocketAddress(ip(), 0), server_address_.address,
333 proxy(), user_agent(), opts);
334 }
335
336 if (!socket_) {
337 error_ = SOCKET_ERROR;
338 return false;
339 }
340
341 // Apply options if any.
342 for (SocketOptionsMap::iterator iter = socket_options_.begin();
343 iter != socket_options_.end(); ++iter) {
344 socket_->SetOption(iter->first, iter->second);
345 }
346
347 if (!SharedSocket()) {
348 // If socket is shared, AllocationSequence will receive the packet.
349 socket_->SignalReadPacket.connect(this, &TurnPort::OnReadPacket);
350 }
351
352 socket_->SignalReadyToSend.connect(this, &TurnPort::OnReadyToSend);
353
354 socket_->SignalSentPacket.connect(this, &TurnPort::OnSentPacket);
355
356 // TCP port is ready to send stun requests after the socket is connected,
357 // while UDP port is ready to do so once the socket is created.
358 if (server_address_.proto == PROTO_TCP) {
359 socket_->SignalConnect.connect(this, &TurnPort::OnSocketConnect);
360 socket_->SignalClose.connect(this, &TurnPort::OnSocketClose);
361 } else {
362 state_ = STATE_CONNECTED;
363 }
364 return true;
365 }
366
OnSocketConnect(rtc::AsyncPacketSocket * socket)367 void TurnPort::OnSocketConnect(rtc::AsyncPacketSocket* socket) {
368 ASSERT(server_address_.proto == PROTO_TCP);
369 // Do not use this port if the socket bound to a different address than
370 // the one we asked for. This is seen in Chrome, where TCP sockets cannot be
371 // given a binding address, and the platform is expected to pick the
372 // correct local address.
373
374 // However, there are two situations in which we allow the bound address to
375 // differ from the requested address: 1. The bound address is the loopback
376 // address. This happens when a proxy forces TCP to bind to only the
377 // localhost address (see issue 3927). 2. The bound address is the "any
378 // address". This happens when multiple_routes is disabled (see issue 4780).
379 if (socket->GetLocalAddress().ipaddr() != ip()) {
380 if (socket->GetLocalAddress().IsLoopbackIP()) {
381 LOG(LS_WARNING) << "Socket is bound to a different address:"
382 << socket->GetLocalAddress().ipaddr().ToString()
383 << ", rather then the local port:" << ip().ToString()
384 << ". Still allowing it since it's localhost.";
385 } else if (IPIsAny(ip())) {
386 LOG(LS_WARNING) << "Socket is bound to a different address:"
387 << socket->GetLocalAddress().ipaddr().ToString()
388 << ", rather then the local port:" << ip().ToString()
389 << ". Still allowing it since it's any address"
390 << ", possibly caused by multiple_routes being disabled.";
391 } else {
392 LOG(LS_WARNING) << "Socket is bound to a different address:"
393 << socket->GetLocalAddress().ipaddr().ToString()
394 << ", rather then the local port:" << ip().ToString()
395 << ". Discarding TURN port.";
396 OnAllocateError();
397 return;
398 }
399 }
400
401 state_ = STATE_CONNECTED; // It is ready to send stun requests.
402 if (server_address_.address.IsUnresolvedIP()) {
403 server_address_.address = socket_->GetRemoteAddress();
404 }
405
406 LOG(LS_INFO) << "TurnPort connected to " << socket->GetRemoteAddress()
407 << " using tcp.";
408 SendRequest(new TurnAllocateRequest(this), 0);
409 }
410
OnSocketClose(rtc::AsyncPacketSocket * socket,int error)411 void TurnPort::OnSocketClose(rtc::AsyncPacketSocket* socket, int error) {
412 LOG_J(LS_WARNING, this) << "Connection with server failed, error=" << error;
413 ASSERT(socket == socket_);
414 Close();
415 }
416
OnAllocateMismatch()417 void TurnPort::OnAllocateMismatch() {
418 if (allocate_mismatch_retries_ >= MAX_ALLOCATE_MISMATCH_RETRIES) {
419 LOG_J(LS_WARNING, this) << "Giving up on the port after "
420 << allocate_mismatch_retries_
421 << " retries for STUN_ERROR_ALLOCATION_MISMATCH";
422 OnAllocateError();
423 return;
424 }
425
426 LOG_J(LS_INFO, this) << "Allocating a new socket after "
427 << "STUN_ERROR_ALLOCATION_MISMATCH, retry = "
428 << allocate_mismatch_retries_ + 1;
429 if (SharedSocket()) {
430 ResetSharedSocket();
431 } else {
432 delete socket_;
433 }
434 socket_ = NULL;
435
436 PrepareAddress();
437 ++allocate_mismatch_retries_;
438 }
439
CreateConnection(const Candidate & address,CandidateOrigin origin)440 Connection* TurnPort::CreateConnection(const Candidate& address,
441 CandidateOrigin origin) {
442 // TURN-UDP can only connect to UDP candidates.
443 if (!SupportsProtocol(address.protocol())) {
444 return NULL;
445 }
446
447 if (!IsCompatibleAddress(address.address())) {
448 return NULL;
449 }
450
451 if (state_ == STATE_DISCONNECTED) {
452 return NULL;
453 }
454
455 // Create an entry, if needed, so we can get our permissions set up correctly.
456 CreateOrRefreshEntry(address.address());
457
458 // A TURN port will have two candiates, STUN and TURN. STUN may not
459 // present in all cases. If present stun candidate will be added first
460 // and TURN candidate later.
461 for (size_t index = 0; index < Candidates().size(); ++index) {
462 if (Candidates()[index].type() == RELAY_PORT_TYPE) {
463 ProxyConnection* conn = new ProxyConnection(this, index, address);
464 conn->SignalDestroyed.connect(this, &TurnPort::OnConnectionDestroyed);
465 AddConnection(conn);
466 return conn;
467 }
468 }
469 return NULL;
470 }
471
DestroyConnection(const rtc::SocketAddress & address)472 bool TurnPort::DestroyConnection(const rtc::SocketAddress& address) {
473 Connection* conn = GetConnection(address);
474 if (conn != nullptr) {
475 conn->Destroy();
476 return true;
477 }
478 return false;
479 }
480
SetOption(rtc::Socket::Option opt,int value)481 int TurnPort::SetOption(rtc::Socket::Option opt, int value) {
482 if (!socket_) {
483 // If socket is not created yet, these options will be applied during socket
484 // creation.
485 socket_options_[opt] = value;
486 return 0;
487 }
488 return socket_->SetOption(opt, value);
489 }
490
GetOption(rtc::Socket::Option opt,int * value)491 int TurnPort::GetOption(rtc::Socket::Option opt, int* value) {
492 if (!socket_) {
493 SocketOptionsMap::const_iterator it = socket_options_.find(opt);
494 if (it == socket_options_.end()) {
495 return -1;
496 }
497 *value = it->second;
498 return 0;
499 }
500
501 return socket_->GetOption(opt, value);
502 }
503
GetError()504 int TurnPort::GetError() {
505 return error_;
506 }
507
SendTo(const void * data,size_t size,const rtc::SocketAddress & addr,const rtc::PacketOptions & options,bool payload)508 int TurnPort::SendTo(const void* data, size_t size,
509 const rtc::SocketAddress& addr,
510 const rtc::PacketOptions& options,
511 bool payload) {
512 // Try to find an entry for this specific address; we should have one.
513 TurnEntry* entry = FindEntry(addr);
514 if (!entry) {
515 LOG(LS_ERROR) << "Did not find the TurnEntry for address " << addr;
516 return 0;
517 }
518
519 if (!ready()) {
520 error_ = EWOULDBLOCK;
521 return SOCKET_ERROR;
522 }
523
524 // Send the actual contents to the server using the usual mechanism.
525 int sent = entry->Send(data, size, payload, options);
526 if (sent <= 0) {
527 return SOCKET_ERROR;
528 }
529
530 // The caller of the function is expecting the number of user data bytes,
531 // rather than the size of the packet.
532 return static_cast<int>(size);
533 }
534
OnReadPacket(rtc::AsyncPacketSocket * socket,const char * data,size_t size,const rtc::SocketAddress & remote_addr,const rtc::PacketTime & packet_time)535 void TurnPort::OnReadPacket(
536 rtc::AsyncPacketSocket* socket, const char* data, size_t size,
537 const rtc::SocketAddress& remote_addr,
538 const rtc::PacketTime& packet_time) {
539 ASSERT(socket == socket_);
540
541 // This is to guard against a STUN response from previous server after
542 // alternative server redirection. TODO(guoweis): add a unit test for this
543 // race condition.
544 if (remote_addr != server_address_.address) {
545 LOG_J(LS_WARNING, this) << "Discarding TURN message from unknown address:"
546 << remote_addr.ToString()
547 << ", server_address_:"
548 << server_address_.address.ToString();
549 return;
550 }
551
552 // The message must be at least the size of a channel header.
553 if (size < TURN_CHANNEL_HEADER_SIZE) {
554 LOG_J(LS_WARNING, this) << "Received TURN message that was too short";
555 return;
556 }
557
558 // Check the message type, to see if is a Channel Data message.
559 // The message will either be channel data, a TURN data indication, or
560 // a response to a previous request.
561 uint16_t msg_type = rtc::GetBE16(data);
562 if (IsTurnChannelData(msg_type)) {
563 HandleChannelData(msg_type, data, size, packet_time);
564 } else if (msg_type == TURN_DATA_INDICATION) {
565 HandleDataIndication(data, size, packet_time);
566 } else {
567 if (SharedSocket() &&
568 (msg_type == STUN_BINDING_RESPONSE ||
569 msg_type == STUN_BINDING_ERROR_RESPONSE)) {
570 LOG_J(LS_VERBOSE, this) <<
571 "Ignoring STUN binding response message on shared socket.";
572 return;
573 }
574
575 // This must be a response for one of our requests.
576 // Check success responses, but not errors, for MESSAGE-INTEGRITY.
577 if (IsStunSuccessResponseType(msg_type) &&
578 !StunMessage::ValidateMessageIntegrity(data, size, hash())) {
579 LOG_J(LS_WARNING, this) << "Received TURN message with invalid "
580 << "message integrity, msg_type=" << msg_type;
581 return;
582 }
583 request_manager_.CheckResponse(data, size);
584 }
585 }
586
OnSentPacket(rtc::AsyncPacketSocket * socket,const rtc::SentPacket & sent_packet)587 void TurnPort::OnSentPacket(rtc::AsyncPacketSocket* socket,
588 const rtc::SentPacket& sent_packet) {
589 PortInterface::SignalSentPacket(sent_packet);
590 }
591
OnReadyToSend(rtc::AsyncPacketSocket * socket)592 void TurnPort::OnReadyToSend(rtc::AsyncPacketSocket* socket) {
593 if (ready()) {
594 Port::OnReadyToSend();
595 }
596 }
597
598
599 // Update current server address port with the alternate server address port.
SetAlternateServer(const rtc::SocketAddress & address)600 bool TurnPort::SetAlternateServer(const rtc::SocketAddress& address) {
601 // Check if we have seen this address before and reject if we did.
602 AttemptedServerSet::iterator iter = attempted_server_addresses_.find(address);
603 if (iter != attempted_server_addresses_.end()) {
604 LOG_J(LS_WARNING, this) << "Redirection to ["
605 << address.ToSensitiveString()
606 << "] ignored, allocation failed.";
607 return false;
608 }
609
610 // If protocol family of server address doesn't match with local, return.
611 if (!IsCompatibleAddress(address)) {
612 LOG(LS_WARNING) << "Server IP address family does not match with "
613 << "local host address family type";
614 return false;
615 }
616
617 LOG_J(LS_INFO, this) << "Redirecting from TURN server ["
618 << server_address_.address.ToSensitiveString()
619 << "] to TURN server ["
620 << address.ToSensitiveString()
621 << "]";
622 server_address_ = ProtocolAddress(address, server_address_.proto,
623 server_address_.secure);
624
625 // Insert the current address to prevent redirection pingpong.
626 attempted_server_addresses_.insert(server_address_.address);
627 return true;
628 }
629
ResolveTurnAddress(const rtc::SocketAddress & address)630 void TurnPort::ResolveTurnAddress(const rtc::SocketAddress& address) {
631 if (resolver_)
632 return;
633
634 LOG_J(LS_INFO, this) << "Starting TURN host lookup for "
635 << address.ToSensitiveString();
636 resolver_ = socket_factory()->CreateAsyncResolver();
637 resolver_->SignalDone.connect(this, &TurnPort::OnResolveResult);
638 resolver_->Start(address);
639 }
640
OnResolveResult(rtc::AsyncResolverInterface * resolver)641 void TurnPort::OnResolveResult(rtc::AsyncResolverInterface* resolver) {
642 ASSERT(resolver == resolver_);
643 // If DNS resolve is failed when trying to connect to the server using TCP,
644 // one of the reason could be due to DNS queries blocked by firewall.
645 // In such cases we will try to connect to the server with hostname, assuming
646 // socket layer will resolve the hostname through a HTTP proxy (if any).
647 if (resolver_->GetError() != 0 && server_address_.proto == PROTO_TCP) {
648 if (!CreateTurnClientSocket()) {
649 OnAllocateError();
650 }
651 return;
652 }
653
654 // Copy the original server address in |resolved_address|. For TLS based
655 // sockets we need hostname along with resolved address.
656 rtc::SocketAddress resolved_address = server_address_.address;
657 if (resolver_->GetError() != 0 ||
658 !resolver_->GetResolvedAddress(ip().family(), &resolved_address)) {
659 LOG_J(LS_WARNING, this) << "TURN host lookup received error "
660 << resolver_->GetError();
661 error_ = resolver_->GetError();
662 OnAllocateError();
663 return;
664 }
665 // Signal needs both resolved and unresolved address. After signal is sent
666 // we can copy resolved address back into |server_address_|.
667 SignalResolvedServerAddress(this, server_address_.address,
668 resolved_address);
669 server_address_.address = resolved_address;
670 PrepareAddress();
671 }
672
OnSendStunPacket(const void * data,size_t size,StunRequest * request)673 void TurnPort::OnSendStunPacket(const void* data, size_t size,
674 StunRequest* request) {
675 ASSERT(connected());
676 rtc::PacketOptions options(DefaultDscpValue());
677 if (Send(data, size, options) < 0) {
678 LOG_J(LS_ERROR, this) << "Failed to send TURN message, err="
679 << socket_->GetError();
680 }
681 }
682
OnStunAddress(const rtc::SocketAddress & address)683 void TurnPort::OnStunAddress(const rtc::SocketAddress& address) {
684 // STUN Port will discover STUN candidate, as it's supplied with first TURN
685 // server address.
686 // Why not using this address? - P2PTransportChannel will start creating
687 // connections after first candidate, which means it could start creating the
688 // connections before TURN candidate added. For that to handle, we need to
689 // supply STUN candidate from this port to UDPPort, and TurnPort should have
690 // handle to UDPPort to pass back the address.
691 }
692
OnAllocateSuccess(const rtc::SocketAddress & address,const rtc::SocketAddress & stun_address)693 void TurnPort::OnAllocateSuccess(const rtc::SocketAddress& address,
694 const rtc::SocketAddress& stun_address) {
695 state_ = STATE_READY;
696
697 rtc::SocketAddress related_address = stun_address;
698 if (!(candidate_filter() & CF_REFLEXIVE)) {
699 // If candidate filter only allows relay type of address, empty raddr to
700 // avoid local address leakage.
701 related_address = rtc::EmptySocketAddressWithFamily(stun_address.family());
702 }
703
704 // For relayed candidate, Base is the candidate itself.
705 AddAddress(address, // Candidate address.
706 address, // Base address.
707 related_address, // Related address.
708 UDP_PROTOCOL_NAME,
709 ProtoToString(server_address_.proto), // The first hop protocol.
710 "", // TCP canddiate type, empty for turn candidates.
711 RELAY_PORT_TYPE,
712 GetRelayPreference(server_address_.proto, server_address_.secure),
713 server_priority_, true);
714 }
715
OnAllocateError()716 void TurnPort::OnAllocateError() {
717 // We will send SignalPortError asynchronously as this can be sent during
718 // port initialization. This way it will not be blocking other port
719 // creation.
720 thread()->Post(this, MSG_ALLOCATE_ERROR);
721 }
722
OnTurnRefreshError()723 void TurnPort::OnTurnRefreshError() {
724 // Need to Close the port asynchronously because otherwise, the refresh
725 // request may be deleted twice: once at the end of the message processing
726 // and the other in Close().
727 thread()->Post(this, MSG_REFRESH_ERROR);
728 }
729
Close()730 void TurnPort::Close() {
731 if (!ready()) {
732 OnAllocateError();
733 }
734 request_manager_.Clear();
735 // Stop the port from creating new connections.
736 state_ = STATE_DISCONNECTED;
737 // Delete all existing connections; stop sending data.
738 for (auto kv : connections()) {
739 kv.second->Destroy();
740 }
741 }
742
OnMessage(rtc::Message * message)743 void TurnPort::OnMessage(rtc::Message* message) {
744 switch (message->message_id) {
745 case MSG_ALLOCATE_ERROR:
746 SignalPortError(this);
747 break;
748 case MSG_ALLOCATE_MISMATCH:
749 OnAllocateMismatch();
750 break;
751 case MSG_REFRESH_ERROR:
752 Close();
753 break;
754 case MSG_TRY_ALTERNATE_SERVER:
755 if (server_address().proto == PROTO_UDP) {
756 // Send another allocate request to alternate server, with the received
757 // realm and nonce values.
758 SendRequest(new TurnAllocateRequest(this), 0);
759 } else {
760 // Since it's TCP, we have to delete the connected socket and reconnect
761 // with the alternate server. PrepareAddress will send stun binding once
762 // the new socket is connected.
763 ASSERT(server_address().proto == PROTO_TCP);
764 ASSERT(!SharedSocket());
765 delete socket_;
766 socket_ = NULL;
767 PrepareAddress();
768 }
769 break;
770 default:
771 Port::OnMessage(message);
772 }
773 }
774
OnAllocateRequestTimeout()775 void TurnPort::OnAllocateRequestTimeout() {
776 OnAllocateError();
777 }
778
HandleDataIndication(const char * data,size_t size,const rtc::PacketTime & packet_time)779 void TurnPort::HandleDataIndication(const char* data, size_t size,
780 const rtc::PacketTime& packet_time) {
781 // Read in the message, and process according to RFC5766, Section 10.4.
782 rtc::ByteBuffer buf(data, size);
783 TurnMessage msg;
784 if (!msg.Read(&buf)) {
785 LOG_J(LS_WARNING, this) << "Received invalid TURN data indication";
786 return;
787 }
788
789 // Check mandatory attributes.
790 const StunAddressAttribute* addr_attr =
791 msg.GetAddress(STUN_ATTR_XOR_PEER_ADDRESS);
792 if (!addr_attr) {
793 LOG_J(LS_WARNING, this) << "Missing STUN_ATTR_XOR_PEER_ADDRESS attribute "
794 << "in data indication.";
795 return;
796 }
797
798 const StunByteStringAttribute* data_attr =
799 msg.GetByteString(STUN_ATTR_DATA);
800 if (!data_attr) {
801 LOG_J(LS_WARNING, this) << "Missing STUN_ATTR_DATA attribute in "
802 << "data indication.";
803 return;
804 }
805
806 // Verify that the data came from somewhere we think we have a permission for.
807 rtc::SocketAddress ext_addr(addr_attr->GetAddress());
808 if (!HasPermission(ext_addr.ipaddr())) {
809 LOG_J(LS_WARNING, this) << "Received TURN data indication with invalid "
810 << "peer address, addr="
811 << ext_addr.ToSensitiveString();
812 return;
813 }
814
815 DispatchPacket(data_attr->bytes(), data_attr->length(), ext_addr,
816 PROTO_UDP, packet_time);
817 }
818
HandleChannelData(int channel_id,const char * data,size_t size,const rtc::PacketTime & packet_time)819 void TurnPort::HandleChannelData(int channel_id, const char* data,
820 size_t size,
821 const rtc::PacketTime& packet_time) {
822 // Read the message, and process according to RFC5766, Section 11.6.
823 // 0 1 2 3
824 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
825 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
826 // | Channel Number | Length |
827 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
828 // | |
829 // / Application Data /
830 // / /
831 // | |
832 // | +-------------------------------+
833 // | |
834 // +-------------------------------+
835
836 // Extract header fields from the message.
837 uint16_t len = rtc::GetBE16(data + 2);
838 if (len > size - TURN_CHANNEL_HEADER_SIZE) {
839 LOG_J(LS_WARNING, this) << "Received TURN channel data message with "
840 << "incorrect length, len=" << len;
841 return;
842 }
843 // Allowing messages larger than |len|, as ChannelData can be padded.
844
845 TurnEntry* entry = FindEntry(channel_id);
846 if (!entry) {
847 LOG_J(LS_WARNING, this) << "Received TURN channel data message for invalid "
848 << "channel, channel_id=" << channel_id;
849 return;
850 }
851
852 DispatchPacket(data + TURN_CHANNEL_HEADER_SIZE, len, entry->address(),
853 PROTO_UDP, packet_time);
854 }
855
DispatchPacket(const char * data,size_t size,const rtc::SocketAddress & remote_addr,ProtocolType proto,const rtc::PacketTime & packet_time)856 void TurnPort::DispatchPacket(const char* data, size_t size,
857 const rtc::SocketAddress& remote_addr,
858 ProtocolType proto, const rtc::PacketTime& packet_time) {
859 if (Connection* conn = GetConnection(remote_addr)) {
860 conn->OnReadPacket(data, size, packet_time);
861 } else {
862 Port::OnReadPacket(data, size, remote_addr, proto);
863 }
864 }
865
ScheduleRefresh(int lifetime)866 bool TurnPort::ScheduleRefresh(int lifetime) {
867 // Lifetime is in seconds; we schedule a refresh for one minute less.
868 if (lifetime < 2 * 60) {
869 LOG_J(LS_WARNING, this) << "Received response with lifetime that was "
870 << "too short, lifetime=" << lifetime;
871 return false;
872 }
873
874 int delay = (lifetime - 60) * 1000;
875 SendRequest(new TurnRefreshRequest(this), delay);
876 LOG_J(LS_INFO, this) << "Scheduled refresh in " << delay << "ms.";
877 return true;
878 }
879
SendRequest(StunRequest * req,int delay)880 void TurnPort::SendRequest(StunRequest* req, int delay) {
881 request_manager_.SendDelayed(req, delay);
882 }
883
AddRequestAuthInfo(StunMessage * msg)884 void TurnPort::AddRequestAuthInfo(StunMessage* msg) {
885 // If we've gotten the necessary data from the server, add it to our request.
886 VERIFY(!hash_.empty());
887 VERIFY(msg->AddAttribute(new StunByteStringAttribute(
888 STUN_ATTR_USERNAME, credentials_.username)));
889 VERIFY(msg->AddAttribute(new StunByteStringAttribute(
890 STUN_ATTR_REALM, realm_)));
891 VERIFY(msg->AddAttribute(new StunByteStringAttribute(
892 STUN_ATTR_NONCE, nonce_)));
893 VERIFY(msg->AddMessageIntegrity(hash()));
894 }
895
Send(const void * data,size_t len,const rtc::PacketOptions & options)896 int TurnPort::Send(const void* data, size_t len,
897 const rtc::PacketOptions& options) {
898 return socket_->SendTo(data, len, server_address_.address, options);
899 }
900
UpdateHash()901 void TurnPort::UpdateHash() {
902 VERIFY(ComputeStunCredentialHash(credentials_.username, realm_,
903 credentials_.password, &hash_));
904 }
905
UpdateNonce(StunMessage * response)906 bool TurnPort::UpdateNonce(StunMessage* response) {
907 // When stale nonce error received, we should update
908 // hash and store realm and nonce.
909 // Check the mandatory attributes.
910 const StunByteStringAttribute* realm_attr =
911 response->GetByteString(STUN_ATTR_REALM);
912 if (!realm_attr) {
913 LOG(LS_ERROR) << "Missing STUN_ATTR_REALM attribute in "
914 << "stale nonce error response.";
915 return false;
916 }
917 set_realm(realm_attr->GetString());
918
919 const StunByteStringAttribute* nonce_attr =
920 response->GetByteString(STUN_ATTR_NONCE);
921 if (!nonce_attr) {
922 LOG(LS_ERROR) << "Missing STUN_ATTR_NONCE attribute in "
923 << "stale nonce error response.";
924 return false;
925 }
926 set_nonce(nonce_attr->GetString());
927 return true;
928 }
929
MatchesIP(TurnEntry * e,rtc::IPAddress ipaddr)930 static bool MatchesIP(TurnEntry* e, rtc::IPAddress ipaddr) {
931 return e->address().ipaddr() == ipaddr;
932 }
HasPermission(const rtc::IPAddress & ipaddr) const933 bool TurnPort::HasPermission(const rtc::IPAddress& ipaddr) const {
934 return (std::find_if(entries_.begin(), entries_.end(),
935 std::bind2nd(std::ptr_fun(MatchesIP), ipaddr)) != entries_.end());
936 }
937
MatchesAddress(TurnEntry * e,rtc::SocketAddress addr)938 static bool MatchesAddress(TurnEntry* e, rtc::SocketAddress addr) {
939 return e->address() == addr;
940 }
FindEntry(const rtc::SocketAddress & addr) const941 TurnEntry* TurnPort::FindEntry(const rtc::SocketAddress& addr) const {
942 EntryList::const_iterator it = std::find_if(entries_.begin(), entries_.end(),
943 std::bind2nd(std::ptr_fun(MatchesAddress), addr));
944 return (it != entries_.end()) ? *it : NULL;
945 }
946
MatchesChannelId(TurnEntry * e,int id)947 static bool MatchesChannelId(TurnEntry* e, int id) {
948 return e->channel_id() == id;
949 }
FindEntry(int channel_id) const950 TurnEntry* TurnPort::FindEntry(int channel_id) const {
951 EntryList::const_iterator it = std::find_if(entries_.begin(), entries_.end(),
952 std::bind2nd(std::ptr_fun(MatchesChannelId), channel_id));
953 return (it != entries_.end()) ? *it : NULL;
954 }
955
EntryExists(TurnEntry * e)956 bool TurnPort::EntryExists(TurnEntry* e) {
957 auto it = std::find(entries_.begin(), entries_.end(), e);
958 return it != entries_.end();
959 }
960
CreateOrRefreshEntry(const rtc::SocketAddress & addr)961 void TurnPort::CreateOrRefreshEntry(const rtc::SocketAddress& addr) {
962 TurnEntry* entry = FindEntry(addr);
963 if (entry == nullptr) {
964 entry = new TurnEntry(this, next_channel_number_++, addr);
965 entries_.push_back(entry);
966 } else {
967 // The channel binding request for the entry will be refreshed automatically
968 // until the entry is destroyed.
969 CancelEntryDestruction(entry);
970 }
971 }
972
DestroyEntry(TurnEntry * entry)973 void TurnPort::DestroyEntry(TurnEntry* entry) {
974 ASSERT(entry != NULL);
975 entry->SignalDestroyed(entry);
976 entries_.remove(entry);
977 delete entry;
978 }
979
DestroyEntryIfNotCancelled(TurnEntry * entry,uint32_t timestamp)980 void TurnPort::DestroyEntryIfNotCancelled(TurnEntry* entry,
981 uint32_t timestamp) {
982 if (!EntryExists(entry)) {
983 return;
984 }
985 bool cancelled = timestamp != entry->destruction_timestamp();
986 if (!cancelled) {
987 DestroyEntry(entry);
988 }
989 }
990
OnConnectionDestroyed(Connection * conn)991 void TurnPort::OnConnectionDestroyed(Connection* conn) {
992 // Schedule an event to destroy TurnEntry for the connection, which is
993 // already destroyed.
994 const rtc::SocketAddress& remote_address = conn->remote_candidate().address();
995 TurnEntry* entry = FindEntry(remote_address);
996 ASSERT(entry != NULL);
997 ScheduleEntryDestruction(entry);
998 }
999
ScheduleEntryDestruction(TurnEntry * entry)1000 void TurnPort::ScheduleEntryDestruction(TurnEntry* entry) {
1001 ASSERT(entry->destruction_timestamp() == 0);
1002 uint32_t timestamp = rtc::Time();
1003 entry->set_destruction_timestamp(timestamp);
1004 invoker_.AsyncInvokeDelayed<void>(
1005 thread(),
1006 rtc::Bind(&TurnPort::DestroyEntryIfNotCancelled, this, entry, timestamp),
1007 TURN_PERMISSION_TIMEOUT);
1008 }
1009
CancelEntryDestruction(TurnEntry * entry)1010 void TurnPort::CancelEntryDestruction(TurnEntry* entry) {
1011 ASSERT(entry->destruction_timestamp() != 0);
1012 entry->set_destruction_timestamp(0);
1013 }
1014
SetEntryChannelId(const rtc::SocketAddress & address,int channel_id)1015 bool TurnPort::SetEntryChannelId(const rtc::SocketAddress& address,
1016 int channel_id) {
1017 TurnEntry* entry = FindEntry(address);
1018 if (!entry) {
1019 return false;
1020 }
1021 entry->set_channel_id(channel_id);
1022 return true;
1023 }
1024
TurnAllocateRequest(TurnPort * port)1025 TurnAllocateRequest::TurnAllocateRequest(TurnPort* port)
1026 : StunRequest(new TurnMessage()),
1027 port_(port) {
1028 }
1029
Prepare(StunMessage * request)1030 void TurnAllocateRequest::Prepare(StunMessage* request) {
1031 // Create the request as indicated in RFC 5766, Section 6.1.
1032 request->SetType(TURN_ALLOCATE_REQUEST);
1033 StunUInt32Attribute* transport_attr = StunAttribute::CreateUInt32(
1034 STUN_ATTR_REQUESTED_TRANSPORT);
1035 transport_attr->SetValue(IPPROTO_UDP << 24);
1036 VERIFY(request->AddAttribute(transport_attr));
1037 if (!port_->hash().empty()) {
1038 port_->AddRequestAuthInfo(request);
1039 }
1040 }
1041
OnSent()1042 void TurnAllocateRequest::OnSent() {
1043 LOG_J(LS_INFO, port_) << "TURN allocate request sent"
1044 << ", id=" << rtc::hex_encode(id());
1045 StunRequest::OnSent();
1046 }
1047
OnResponse(StunMessage * response)1048 void TurnAllocateRequest::OnResponse(StunMessage* response) {
1049 LOG_J(LS_INFO, port_) << "TURN allocate requested successfully"
1050 << ", id=" << rtc::hex_encode(id())
1051 << ", code=0" // Makes logging easier to parse.
1052 << ", rtt=" << Elapsed();
1053
1054 // Check mandatory attributes as indicated in RFC5766, Section 6.3.
1055 const StunAddressAttribute* mapped_attr =
1056 response->GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
1057 if (!mapped_attr) {
1058 LOG_J(LS_WARNING, port_) << "Missing STUN_ATTR_XOR_MAPPED_ADDRESS "
1059 << "attribute in allocate success response";
1060 return;
1061 }
1062 // Using XOR-Mapped-Address for stun.
1063 port_->OnStunAddress(mapped_attr->GetAddress());
1064
1065 const StunAddressAttribute* relayed_attr =
1066 response->GetAddress(STUN_ATTR_XOR_RELAYED_ADDRESS);
1067 if (!relayed_attr) {
1068 LOG_J(LS_WARNING, port_) << "Missing STUN_ATTR_XOR_RELAYED_ADDRESS "
1069 << "attribute in allocate success response";
1070 return;
1071 }
1072
1073 const StunUInt32Attribute* lifetime_attr =
1074 response->GetUInt32(STUN_ATTR_TURN_LIFETIME);
1075 if (!lifetime_attr) {
1076 LOG_J(LS_WARNING, port_) << "Missing STUN_ATTR_TURN_LIFETIME attribute in "
1077 << "allocate success response";
1078 return;
1079 }
1080 // Notify the port the allocate succeeded, and schedule a refresh request.
1081 port_->OnAllocateSuccess(relayed_attr->GetAddress(),
1082 mapped_attr->GetAddress());
1083 port_->ScheduleRefresh(lifetime_attr->value());
1084 }
1085
OnErrorResponse(StunMessage * response)1086 void TurnAllocateRequest::OnErrorResponse(StunMessage* response) {
1087 // Process error response according to RFC5766, Section 6.4.
1088 const StunErrorCodeAttribute* error_code = response->GetErrorCode();
1089
1090 LOG_J(LS_INFO, port_) << "Received TURN allocate error response"
1091 << ", id=" << rtc::hex_encode(id())
1092 << ", code=" << error_code->code()
1093 << ", rtt=" << Elapsed();
1094
1095 switch (error_code->code()) {
1096 case STUN_ERROR_UNAUTHORIZED: // Unauthrorized.
1097 OnAuthChallenge(response, error_code->code());
1098 break;
1099 case STUN_ERROR_TRY_ALTERNATE:
1100 OnTryAlternate(response, error_code->code());
1101 break;
1102 case STUN_ERROR_ALLOCATION_MISMATCH:
1103 // We must handle this error async because trying to delete the socket in
1104 // OnErrorResponse will cause a deadlock on the socket.
1105 port_->thread()->Post(port_, TurnPort::MSG_ALLOCATE_MISMATCH);
1106 break;
1107 default:
1108 LOG_J(LS_WARNING, port_) << "Received TURN allocate error response"
1109 << ", id=" << rtc::hex_encode(id())
1110 << ", code=" << error_code->code()
1111 << ", rtt=" << Elapsed();
1112 port_->OnAllocateError();
1113 }
1114 }
1115
OnTimeout()1116 void TurnAllocateRequest::OnTimeout() {
1117 LOG_J(LS_WARNING, port_) << "TURN allocate request "
1118 << rtc::hex_encode(id()) << " timout";
1119 port_->OnAllocateRequestTimeout();
1120 }
1121
OnAuthChallenge(StunMessage * response,int code)1122 void TurnAllocateRequest::OnAuthChallenge(StunMessage* response, int code) {
1123 // If we failed to authenticate even after we sent our credentials, fail hard.
1124 if (code == STUN_ERROR_UNAUTHORIZED && !port_->hash().empty()) {
1125 LOG_J(LS_WARNING, port_) << "Failed to authenticate with the server "
1126 << "after challenge.";
1127 port_->OnAllocateError();
1128 return;
1129 }
1130
1131 // Check the mandatory attributes.
1132 const StunByteStringAttribute* realm_attr =
1133 response->GetByteString(STUN_ATTR_REALM);
1134 if (!realm_attr) {
1135 LOG_J(LS_WARNING, port_) << "Missing STUN_ATTR_REALM attribute in "
1136 << "allocate unauthorized response.";
1137 return;
1138 }
1139 port_->set_realm(realm_attr->GetString());
1140
1141 const StunByteStringAttribute* nonce_attr =
1142 response->GetByteString(STUN_ATTR_NONCE);
1143 if (!nonce_attr) {
1144 LOG_J(LS_WARNING, port_) << "Missing STUN_ATTR_NONCE attribute in "
1145 << "allocate unauthorized response.";
1146 return;
1147 }
1148 port_->set_nonce(nonce_attr->GetString());
1149
1150 // Send another allocate request, with the received realm and nonce values.
1151 port_->SendRequest(new TurnAllocateRequest(port_), 0);
1152 }
1153
OnTryAlternate(StunMessage * response,int code)1154 void TurnAllocateRequest::OnTryAlternate(StunMessage* response, int code) {
1155
1156 // According to RFC 5389 section 11, there are use cases where
1157 // authentication of response is not possible, we're not validating
1158 // message integrity.
1159
1160 // Get the alternate server address attribute value.
1161 const StunAddressAttribute* alternate_server_attr =
1162 response->GetAddress(STUN_ATTR_ALTERNATE_SERVER);
1163 if (!alternate_server_attr) {
1164 LOG_J(LS_WARNING, port_) << "Missing STUN_ATTR_ALTERNATE_SERVER "
1165 << "attribute in try alternate error response";
1166 port_->OnAllocateError();
1167 return;
1168 }
1169 if (!port_->SetAlternateServer(alternate_server_attr->GetAddress())) {
1170 port_->OnAllocateError();
1171 return;
1172 }
1173
1174 // Check the attributes.
1175 const StunByteStringAttribute* realm_attr =
1176 response->GetByteString(STUN_ATTR_REALM);
1177 if (realm_attr) {
1178 LOG_J(LS_INFO, port_) << "Applying STUN_ATTR_REALM attribute in "
1179 << "try alternate error response.";
1180 port_->set_realm(realm_attr->GetString());
1181 }
1182
1183 const StunByteStringAttribute* nonce_attr =
1184 response->GetByteString(STUN_ATTR_NONCE);
1185 if (nonce_attr) {
1186 LOG_J(LS_INFO, port_) << "Applying STUN_ATTR_NONCE attribute in "
1187 << "try alternate error response.";
1188 port_->set_nonce(nonce_attr->GetString());
1189 }
1190
1191 // For TCP, we can't close the original Tcp socket during handling a 300 as
1192 // we're still inside that socket's event handler. Doing so will cause
1193 // deadlock.
1194 port_->thread()->Post(port_, TurnPort::MSG_TRY_ALTERNATE_SERVER);
1195 }
1196
TurnRefreshRequest(TurnPort * port)1197 TurnRefreshRequest::TurnRefreshRequest(TurnPort* port)
1198 : StunRequest(new TurnMessage()),
1199 port_(port),
1200 lifetime_(-1) {
1201 }
1202
Prepare(StunMessage * request)1203 void TurnRefreshRequest::Prepare(StunMessage* request) {
1204 // Create the request as indicated in RFC 5766, Section 7.1.
1205 // No attributes need to be included.
1206 request->SetType(TURN_REFRESH_REQUEST);
1207 if (lifetime_ > -1) {
1208 VERIFY(request->AddAttribute(new StunUInt32Attribute(
1209 STUN_ATTR_LIFETIME, lifetime_)));
1210 }
1211
1212 port_->AddRequestAuthInfo(request);
1213 }
1214
OnSent()1215 void TurnRefreshRequest::OnSent() {
1216 LOG_J(LS_INFO, port_) << "TURN refresh request sent"
1217 << ", id=" << rtc::hex_encode(id());
1218 StunRequest::OnSent();
1219 }
1220
OnResponse(StunMessage * response)1221 void TurnRefreshRequest::OnResponse(StunMessage* response) {
1222 LOG_J(LS_INFO, port_) << "TURN refresh requested successfully"
1223 << ", id=" << rtc::hex_encode(id())
1224 << ", code=0" // Makes logging easier to parse.
1225 << ", rtt=" << Elapsed();
1226
1227 // Check mandatory attributes as indicated in RFC5766, Section 7.3.
1228 const StunUInt32Attribute* lifetime_attr =
1229 response->GetUInt32(STUN_ATTR_TURN_LIFETIME);
1230 if (!lifetime_attr) {
1231 LOG_J(LS_WARNING, port_) << "Missing STUN_ATTR_TURN_LIFETIME attribute in "
1232 << "refresh success response.";
1233 return;
1234 }
1235
1236 // Schedule a refresh based on the returned lifetime value.
1237 port_->ScheduleRefresh(lifetime_attr->value());
1238 port_->SignalTurnRefreshResult(port_, TURN_SUCCESS_RESULT_CODE);
1239 }
1240
OnErrorResponse(StunMessage * response)1241 void TurnRefreshRequest::OnErrorResponse(StunMessage* response) {
1242 const StunErrorCodeAttribute* error_code = response->GetErrorCode();
1243
1244 if (error_code->code() == STUN_ERROR_STALE_NONCE) {
1245 if (port_->UpdateNonce(response)) {
1246 // Send RefreshRequest immediately.
1247 port_->SendRequest(new TurnRefreshRequest(port_), 0);
1248 }
1249 } else {
1250 LOG_J(LS_WARNING, port_) << "Received TURN refresh error response"
1251 << ", id=" << rtc::hex_encode(id())
1252 << ", code=" << error_code->code()
1253 << ", rtt=" << Elapsed();
1254 port_->OnTurnRefreshError();
1255 port_->SignalTurnRefreshResult(port_, error_code->code());
1256 }
1257 }
1258
OnTimeout()1259 void TurnRefreshRequest::OnTimeout() {
1260 LOG_J(LS_WARNING, port_) << "TURN refresh timeout " << rtc::hex_encode(id());
1261 port_->OnTurnRefreshError();
1262 }
1263
TurnCreatePermissionRequest(TurnPort * port,TurnEntry * entry,const rtc::SocketAddress & ext_addr)1264 TurnCreatePermissionRequest::TurnCreatePermissionRequest(
1265 TurnPort* port, TurnEntry* entry,
1266 const rtc::SocketAddress& ext_addr)
1267 : StunRequest(new TurnMessage()),
1268 port_(port),
1269 entry_(entry),
1270 ext_addr_(ext_addr) {
1271 entry_->SignalDestroyed.connect(
1272 this, &TurnCreatePermissionRequest::OnEntryDestroyed);
1273 }
1274
Prepare(StunMessage * request)1275 void TurnCreatePermissionRequest::Prepare(StunMessage* request) {
1276 // Create the request as indicated in RFC5766, Section 9.1.
1277 request->SetType(TURN_CREATE_PERMISSION_REQUEST);
1278 VERIFY(request->AddAttribute(new StunXorAddressAttribute(
1279 STUN_ATTR_XOR_PEER_ADDRESS, ext_addr_)));
1280 port_->AddRequestAuthInfo(request);
1281 }
1282
OnSent()1283 void TurnCreatePermissionRequest::OnSent() {
1284 LOG_J(LS_INFO, port_) << "TURN create permission request sent"
1285 << ", id=" << rtc::hex_encode(id());
1286 StunRequest::OnSent();
1287 }
1288
OnResponse(StunMessage * response)1289 void TurnCreatePermissionRequest::OnResponse(StunMessage* response) {
1290 LOG_J(LS_INFO, port_) << "TURN permission requested successfully"
1291 << ", id=" << rtc::hex_encode(id())
1292 << ", code=0" // Makes logging easier to parse.
1293 << ", rtt=" << Elapsed();
1294
1295 if (entry_) {
1296 entry_->OnCreatePermissionSuccess();
1297 }
1298 }
1299
OnErrorResponse(StunMessage * response)1300 void TurnCreatePermissionRequest::OnErrorResponse(StunMessage* response) {
1301 const StunErrorCodeAttribute* error_code = response->GetErrorCode();
1302 LOG_J(LS_WARNING, port_) << "Received TURN create permission error response"
1303 << ", id=" << rtc::hex_encode(id())
1304 << ", code=" << error_code->code()
1305 << ", rtt=" << Elapsed();
1306 if (entry_) {
1307 entry_->OnCreatePermissionError(response, error_code->code());
1308 }
1309 }
1310
OnTimeout()1311 void TurnCreatePermissionRequest::OnTimeout() {
1312 LOG_J(LS_WARNING, port_) << "TURN create permission timeout "
1313 << rtc::hex_encode(id());
1314 if (entry_) {
1315 entry_->OnCreatePermissionTimeout();
1316 }
1317 }
1318
OnEntryDestroyed(TurnEntry * entry)1319 void TurnCreatePermissionRequest::OnEntryDestroyed(TurnEntry* entry) {
1320 ASSERT(entry_ == entry);
1321 entry_ = NULL;
1322 }
1323
TurnChannelBindRequest(TurnPort * port,TurnEntry * entry,int channel_id,const rtc::SocketAddress & ext_addr)1324 TurnChannelBindRequest::TurnChannelBindRequest(
1325 TurnPort* port, TurnEntry* entry,
1326 int channel_id, const rtc::SocketAddress& ext_addr)
1327 : StunRequest(new TurnMessage()),
1328 port_(port),
1329 entry_(entry),
1330 channel_id_(channel_id),
1331 ext_addr_(ext_addr) {
1332 entry_->SignalDestroyed.connect(
1333 this, &TurnChannelBindRequest::OnEntryDestroyed);
1334 }
1335
Prepare(StunMessage * request)1336 void TurnChannelBindRequest::Prepare(StunMessage* request) {
1337 // Create the request as indicated in RFC5766, Section 11.1.
1338 request->SetType(TURN_CHANNEL_BIND_REQUEST);
1339 VERIFY(request->AddAttribute(new StunUInt32Attribute(
1340 STUN_ATTR_CHANNEL_NUMBER, channel_id_ << 16)));
1341 VERIFY(request->AddAttribute(new StunXorAddressAttribute(
1342 STUN_ATTR_XOR_PEER_ADDRESS, ext_addr_)));
1343 port_->AddRequestAuthInfo(request);
1344 }
1345
OnSent()1346 void TurnChannelBindRequest::OnSent() {
1347 LOG_J(LS_INFO, port_) << "TURN channel bind request sent"
1348 << ", id=" << rtc::hex_encode(id());
1349 StunRequest::OnSent();
1350 }
1351
OnResponse(StunMessage * response)1352 void TurnChannelBindRequest::OnResponse(StunMessage* response) {
1353 LOG_J(LS_INFO, port_) << "TURN channel bind requested successfully"
1354 << ", id=" << rtc::hex_encode(id())
1355 << ", code=0" // Makes logging easier to parse.
1356 << ", rtt=" << Elapsed();
1357
1358 if (entry_) {
1359 entry_->OnChannelBindSuccess();
1360 // Refresh the channel binding just under the permission timeout
1361 // threshold. The channel binding has a longer lifetime, but
1362 // this is the easiest way to keep both the channel and the
1363 // permission from expiring.
1364 int delay = TURN_PERMISSION_TIMEOUT - 60000;
1365 entry_->SendChannelBindRequest(delay);
1366 LOG_J(LS_INFO, port_) << "Scheduled channel bind in " << delay << "ms.";
1367 }
1368 }
1369
OnErrorResponse(StunMessage * response)1370 void TurnChannelBindRequest::OnErrorResponse(StunMessage* response) {
1371 const StunErrorCodeAttribute* error_code = response->GetErrorCode();
1372 LOG_J(LS_WARNING, port_) << "Received TURN channel bind error response"
1373 << ", id=" << rtc::hex_encode(id())
1374 << ", code=" << error_code->code()
1375 << ", rtt=" << Elapsed();
1376 if (entry_) {
1377 entry_->OnChannelBindError(response, error_code->code());
1378 }
1379 }
1380
OnTimeout()1381 void TurnChannelBindRequest::OnTimeout() {
1382 LOG_J(LS_WARNING, port_) << "TURN channel bind timeout "
1383 << rtc::hex_encode(id());
1384 if (entry_) {
1385 entry_->OnChannelBindTimeout();
1386 }
1387 }
1388
OnEntryDestroyed(TurnEntry * entry)1389 void TurnChannelBindRequest::OnEntryDestroyed(TurnEntry* entry) {
1390 ASSERT(entry_ == entry);
1391 entry_ = NULL;
1392 }
1393
TurnEntry(TurnPort * port,int channel_id,const rtc::SocketAddress & ext_addr)1394 TurnEntry::TurnEntry(TurnPort* port, int channel_id,
1395 const rtc::SocketAddress& ext_addr)
1396 : port_(port),
1397 channel_id_(channel_id),
1398 ext_addr_(ext_addr),
1399 state_(STATE_UNBOUND) {
1400 // Creating permission for |ext_addr_|.
1401 SendCreatePermissionRequest(0);
1402 }
1403
SendCreatePermissionRequest(int delay)1404 void TurnEntry::SendCreatePermissionRequest(int delay) {
1405 port_->SendRequest(new TurnCreatePermissionRequest(port_, this, ext_addr_),
1406 delay);
1407 }
1408
SendChannelBindRequest(int delay)1409 void TurnEntry::SendChannelBindRequest(int delay) {
1410 port_->SendRequest(new TurnChannelBindRequest(
1411 port_, this, channel_id_, ext_addr_), delay);
1412 }
1413
Send(const void * data,size_t size,bool payload,const rtc::PacketOptions & options)1414 int TurnEntry::Send(const void* data, size_t size, bool payload,
1415 const rtc::PacketOptions& options) {
1416 rtc::ByteBuffer buf;
1417 if (state_ != STATE_BOUND) {
1418 // If we haven't bound the channel yet, we have to use a Send Indication.
1419 TurnMessage msg;
1420 msg.SetType(TURN_SEND_INDICATION);
1421 msg.SetTransactionID(
1422 rtc::CreateRandomString(kStunTransactionIdLength));
1423 VERIFY(msg.AddAttribute(new StunXorAddressAttribute(
1424 STUN_ATTR_XOR_PEER_ADDRESS, ext_addr_)));
1425 VERIFY(msg.AddAttribute(new StunByteStringAttribute(
1426 STUN_ATTR_DATA, data, size)));
1427 VERIFY(msg.Write(&buf));
1428
1429 // If we're sending real data, request a channel bind that we can use later.
1430 if (state_ == STATE_UNBOUND && payload) {
1431 SendChannelBindRequest(0);
1432 state_ = STATE_BINDING;
1433 }
1434 } else {
1435 // If the channel is bound, we can send the data as a Channel Message.
1436 buf.WriteUInt16(channel_id_);
1437 buf.WriteUInt16(static_cast<uint16_t>(size));
1438 buf.WriteBytes(reinterpret_cast<const char*>(data), size);
1439 }
1440 return port_->Send(buf.Data(), buf.Length(), options);
1441 }
1442
OnCreatePermissionSuccess()1443 void TurnEntry::OnCreatePermissionSuccess() {
1444 LOG_J(LS_INFO, port_) << "Create permission for "
1445 << ext_addr_.ToSensitiveString()
1446 << " succeeded";
1447 port_->SignalCreatePermissionResult(port_, ext_addr_,
1448 TURN_SUCCESS_RESULT_CODE);
1449
1450 // If |state_| is STATE_BOUND, the permission will be refreshed
1451 // by ChannelBindRequest.
1452 if (state_ != STATE_BOUND) {
1453 // Refresh the permission request about 1 minute before the permission
1454 // times out.
1455 int delay = TURN_PERMISSION_TIMEOUT - 60000;
1456 SendCreatePermissionRequest(delay);
1457 LOG_J(LS_INFO, port_) << "Scheduled create-permission-request in "
1458 << delay << "ms.";
1459 }
1460 }
1461
OnCreatePermissionError(StunMessage * response,int code)1462 void TurnEntry::OnCreatePermissionError(StunMessage* response, int code) {
1463 if (code == STUN_ERROR_STALE_NONCE) {
1464 if (port_->UpdateNonce(response)) {
1465 SendCreatePermissionRequest(0);
1466 }
1467 } else {
1468 port_->DestroyConnection(ext_addr_);
1469 // Send signal with error code.
1470 port_->SignalCreatePermissionResult(port_, ext_addr_, code);
1471 Connection* c = port_->GetConnection(ext_addr_);
1472 if (c) {
1473 LOG_J(LS_ERROR, c) << "Received TURN CreatePermission error response, "
1474 << "code=" << code << "; killing connection.";
1475 c->FailAndDestroy();
1476 }
1477 }
1478 }
1479
OnCreatePermissionTimeout()1480 void TurnEntry::OnCreatePermissionTimeout() {
1481 port_->DestroyConnection(ext_addr_);
1482 }
1483
OnChannelBindSuccess()1484 void TurnEntry::OnChannelBindSuccess() {
1485 LOG_J(LS_INFO, port_) << "Channel bind for " << ext_addr_.ToSensitiveString()
1486 << " succeeded";
1487 ASSERT(state_ == STATE_BINDING || state_ == STATE_BOUND);
1488 state_ = STATE_BOUND;
1489 }
1490
OnChannelBindError(StunMessage * response,int code)1491 void TurnEntry::OnChannelBindError(StunMessage* response, int code) {
1492 // If the channel bind fails due to errors other than STATE_NONCE,
1493 // we just destroy the connection and rely on ICE restart to re-establish
1494 // the connection.
1495 if (code == STUN_ERROR_STALE_NONCE) {
1496 if (port_->UpdateNonce(response)) {
1497 // Send channel bind request with fresh nonce.
1498 SendChannelBindRequest(0);
1499 }
1500 } else {
1501 state_ = STATE_UNBOUND;
1502 port_->DestroyConnection(ext_addr_);
1503 }
1504 }
OnChannelBindTimeout()1505 void TurnEntry::OnChannelBindTimeout() {
1506 state_ = STATE_UNBOUND;
1507 port_->DestroyConnection(ext_addr_);
1508 }
1509 } // namespace cricket
1510