• Home
  • History
  • Annotate
  • 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