• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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