Home | History | Annotate | Download | only in base
      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 
     43 inline bool IsTurnChannelData(uint16_t msg_type) {
     44   return ((msg_type & 0xC000) == 0x4000);  // MSB are 0b01
     45 }
     46 
     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;
     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 
    139   TurnPort* port() { return port_; }
    140 
    141   int channel_id() const { return channel_id_; }
    142   // For testing only.
    143   void set_channel_id(int channel_id) { channel_id_ = channel_id; }
    144 
    145   const rtc::SocketAddress& address() const { return ext_addr_; }
    146   BindState state() const { return state_; }
    147 
    148   uint32_t destruction_timestamp() { return 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 
    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 
    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 
    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 
    269 rtc::SocketAddress TurnPort::GetLocalAddress() const {
    270   return socket_ ? socket_->GetLocalAddress() : rtc::SocketAddress();
    271 }
    272 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    504 int TurnPort::GetError() {
    505   return error_;
    506 }
    507 
    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 
    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 
    587 void TurnPort::OnSentPacket(rtc::AsyncPacketSocket* socket,
    588                             const rtc::SentPacket& sent_packet) {
    589   PortInterface::SignalSentPacket(sent_packet);
    590 }
    591 
    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.
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    775 void TurnPort::OnAllocateRequestTimeout() {
    776   OnAllocateError();
    777 }
    778 
    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 
    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 
    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 
    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 
    880 void TurnPort::SendRequest(StunRequest* req, int delay) {
    881   request_manager_.SendDelayed(req, delay);
    882 }
    883 
    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 
    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 
    901 void TurnPort::UpdateHash() {
    902   VERIFY(ComputeStunCredentialHash(credentials_.username, realm_,
    903                                    credentials_.password, &hash_));
    904 }
    905 
    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 
    930 static bool MatchesIP(TurnEntry* e, rtc::IPAddress ipaddr) {
    931   return e->address().ipaddr() == ipaddr;
    932 }
    933 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 
    938 static bool MatchesAddress(TurnEntry* e, rtc::SocketAddress addr) {
    939   return e->address() == addr;
    940 }
    941 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 
    947 static bool MatchesChannelId(TurnEntry* e, int id) {
    948   return e->channel_id() == id;
    949 }
    950 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 
    956 bool TurnPort::EntryExists(TurnEntry* e) {
    957   auto it = std::find(entries_.begin(), entries_.end(), e);
    958   return it != entries_.end();
    959 }
    960 
    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 
    973 void TurnPort::DestroyEntry(TurnEntry* entry) {
    974   ASSERT(entry != NULL);
    975   entry->SignalDestroyed(entry);
    976   entries_.remove(entry);
    977   delete entry;
    978 }
    979 
    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 
    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 
   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 
   1010 void TurnPort::CancelEntryDestruction(TurnEntry* entry) {
   1011   ASSERT(entry->destruction_timestamp() != 0);
   1012   entry->set_destruction_timestamp(0);
   1013 }
   1014 
   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 
   1025 TurnAllocateRequest::TurnAllocateRequest(TurnPort* port)
   1026     : StunRequest(new TurnMessage()),
   1027       port_(port) {
   1028 }
   1029 
   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 
   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 
   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 
   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 
   1116 void TurnAllocateRequest::OnTimeout() {
   1117   LOG_J(LS_WARNING, port_) << "TURN allocate request "
   1118                            << rtc::hex_encode(id()) << " timout";
   1119   port_->OnAllocateRequestTimeout();
   1120 }
   1121 
   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 
   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 
   1197 TurnRefreshRequest::TurnRefreshRequest(TurnPort* port)
   1198     : StunRequest(new TurnMessage()),
   1199       port_(port),
   1200       lifetime_(-1) {
   1201 }
   1202 
   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 
   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 
   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 
   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 
   1259 void TurnRefreshRequest::OnTimeout() {
   1260   LOG_J(LS_WARNING, port_) << "TURN refresh timeout " << rtc::hex_encode(id());
   1261   port_->OnTurnRefreshError();
   1262 }
   1263 
   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 
   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 
   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 
   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 
   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 
   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 
   1319 void TurnCreatePermissionRequest::OnEntryDestroyed(TurnEntry* entry) {
   1320   ASSERT(entry_ == entry);
   1321   entry_ = NULL;
   1322 }
   1323 
   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 
   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 
   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 
   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 
   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 
   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 
   1389 void TurnChannelBindRequest::OnEntryDestroyed(TurnEntry* entry) {
   1390   ASSERT(entry_ == entry);
   1391   entry_ = NULL;
   1392 }
   1393 
   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 
   1404 void TurnEntry::SendCreatePermissionRequest(int delay) {
   1405   port_->SendRequest(new TurnCreatePermissionRequest(port_, this, ext_addr_),
   1406                      delay);
   1407 }
   1408 
   1409 void TurnEntry::SendChannelBindRequest(int delay) {
   1410   port_->SendRequest(new TurnChannelBindRequest(
   1411       port_, this, channel_id_, ext_addr_), delay);
   1412 }
   1413 
   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 
   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 
   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 
   1480 void TurnEntry::OnCreatePermissionTimeout() {
   1481   port_->DestroyConnection(ext_addr_);
   1482 }
   1483 
   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 
   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 }
   1505 void TurnEntry::OnChannelBindTimeout() {
   1506   state_ = STATE_UNBOUND;
   1507   port_->DestroyConnection(ext_addr_);
   1508 }
   1509 }  // namespace cricket
   1510