Home | History | Annotate | Download | only in base
      1 /*
      2  * libjingle
      3  * Copyright 2012, Google Inc.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions are met:
      7  *
      8  *  1. Redistributions of source code must retain the above copyright notice,
      9  *     this list of conditions and the following disclaimer.
     10  *  2. Redistributions in binary form must reproduce the above copyright notice,
     11  *     this list of conditions and the following disclaimer in the documentation
     12  *     and/or other materials provided with the distribution.
     13  *  3. The name of the author may not be used to endorse or promote products
     14  *     derived from this software without specific prior written permission.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
     17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     18  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
     19  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
     25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26  */
     27 
     28 #include "talk/p2p/base/turnport.h"
     29 
     30 #include <functional>
     31 
     32 #include "talk/base/asyncpacketsocket.h"
     33 #include "talk/base/byteorder.h"
     34 #include "talk/base/common.h"
     35 #include "talk/base/logging.h"
     36 #include "talk/base/nethelpers.h"
     37 #include "talk/base/socketaddress.h"
     38 #include "talk/base/stringencode.h"
     39 #include "talk/p2p/base/common.h"
     40 #include "talk/p2p/base/stun.h"
     41 
     42 namespace cricket {
     43 
     44 // TODO(juberti): Move to stun.h when relay messages have been renamed.
     45 static const int TURN_ALLOCATE_REQUEST = STUN_ALLOCATE_REQUEST;
     46 
     47 // TODO(juberti): Extract to turnmessage.h
     48 static const int TURN_DEFAULT_PORT = 3478;
     49 static const int TURN_CHANNEL_NUMBER_START = 0x4000;
     50 static const int TURN_PERMISSION_TIMEOUT = 5 * 60 * 1000;  // 5 minutes
     51 
     52 static const size_t TURN_CHANNEL_HEADER_SIZE = 4U;
     53 
     54 inline bool IsTurnChannelData(uint16 msg_type) {
     55   return ((msg_type & 0xC000) == 0x4000);  // MSB are 0b01
     56 }
     57 
     58 static int GetRelayPreference(cricket::ProtocolType proto, bool secure) {
     59   int relay_preference = ICE_TYPE_PREFERENCE_RELAY;
     60   if (proto == cricket::PROTO_TCP) {
     61     relay_preference -= 1;
     62     if (secure)
     63       relay_preference -= 1;
     64   }
     65 
     66   ASSERT(relay_preference >= 0);
     67   return relay_preference;
     68 }
     69 
     70 class TurnAllocateRequest : public StunRequest {
     71  public:
     72   explicit TurnAllocateRequest(TurnPort* port);
     73   virtual void Prepare(StunMessage* request);
     74   virtual void OnResponse(StunMessage* response);
     75   virtual void OnErrorResponse(StunMessage* response);
     76   virtual void OnTimeout();
     77 
     78  private:
     79   // Handles authentication challenge from the server.
     80   void OnAuthChallenge(StunMessage* response, int code);
     81   void OnUnknownAttribute(StunMessage* response);
     82 
     83   TurnPort* port_;
     84 };
     85 
     86 class TurnRefreshRequest : public StunRequest {
     87  public:
     88   explicit TurnRefreshRequest(TurnPort* port);
     89   virtual void Prepare(StunMessage* request);
     90   virtual void OnResponse(StunMessage* response);
     91   virtual void OnErrorResponse(StunMessage* response);
     92   virtual void OnTimeout();
     93 
     94  private:
     95   TurnPort* port_;
     96 };
     97 
     98 class TurnCreatePermissionRequest : public StunRequest,
     99                                     public sigslot::has_slots<> {
    100  public:
    101   TurnCreatePermissionRequest(TurnPort* port, TurnEntry* entry,
    102                               const talk_base::SocketAddress& ext_addr);
    103   virtual void Prepare(StunMessage* request);
    104   virtual void OnResponse(StunMessage* response);
    105   virtual void OnErrorResponse(StunMessage* response);
    106   virtual void OnTimeout();
    107 
    108  private:
    109   void OnEntryDestroyed(TurnEntry* entry);
    110 
    111   TurnPort* port_;
    112   TurnEntry* entry_;
    113   talk_base::SocketAddress ext_addr_;
    114 };
    115 
    116 class TurnChannelBindRequest : public StunRequest,
    117                                public sigslot::has_slots<> {
    118  public:
    119   TurnChannelBindRequest(TurnPort* port, TurnEntry* entry, int channel_id,
    120                          const talk_base::SocketAddress& ext_addr);
    121   virtual void Prepare(StunMessage* request);
    122   virtual void OnResponse(StunMessage* response);
    123   virtual void OnErrorResponse(StunMessage* response);
    124   virtual void OnTimeout();
    125 
    126  private:
    127   void OnEntryDestroyed(TurnEntry* entry);
    128 
    129   TurnPort* port_;
    130   TurnEntry* entry_;
    131   int channel_id_;
    132   talk_base::SocketAddress ext_addr_;
    133 };
    134 
    135 // Manages a "connection" to a remote destination. We will attempt to bring up
    136 // a channel for this remote destination to reduce the overhead of sending data.
    137 class TurnEntry : public sigslot::has_slots<> {
    138  public:
    139   enum BindState { STATE_UNBOUND, STATE_BINDING, STATE_BOUND };
    140   TurnEntry(TurnPort* port, int channel_id,
    141             const talk_base::SocketAddress& ext_addr);
    142 
    143   TurnPort* port() { return port_; }
    144 
    145   int channel_id() const { return channel_id_; }
    146   const talk_base::SocketAddress& address() const { return ext_addr_; }
    147   BindState state() const { return state_; }
    148 
    149   // Helper methods to send permission and channel bind requests.
    150   void SendCreatePermissionRequest();
    151   void SendChannelBindRequest(int delay);
    152   // Sends a packet to the given destination address.
    153   // This will wrap the packet in STUN if necessary.
    154   int Send(const void* data, size_t size, bool payload,
    155            const talk_base::PacketOptions& options);
    156 
    157   void OnCreatePermissionSuccess();
    158   void OnCreatePermissionError(StunMessage* response, int code);
    159   void OnChannelBindSuccess();
    160   void OnChannelBindError(StunMessage* response, int code);
    161   // Signal sent when TurnEntry is destroyed.
    162   sigslot::signal1<TurnEntry*> SignalDestroyed;
    163 
    164  private:
    165   TurnPort* port_;
    166   int channel_id_;
    167   talk_base::SocketAddress ext_addr_;
    168   BindState state_;
    169 };
    170 
    171 TurnPort::TurnPort(talk_base::Thread* thread,
    172                    talk_base::PacketSocketFactory* factory,
    173                    talk_base::Network* network,
    174                    talk_base::AsyncPacketSocket* socket,
    175                    const std::string& username,
    176                    const std::string& password,
    177                    const ProtocolAddress& server_address,
    178                    const RelayCredentials& credentials)
    179     : Port(thread, factory, network, socket->GetLocalAddress().ipaddr(),
    180            username, password),
    181       server_address_(server_address),
    182       credentials_(credentials),
    183       socket_(socket),
    184       resolver_(NULL),
    185       error_(0),
    186       request_manager_(thread),
    187       next_channel_number_(TURN_CHANNEL_NUMBER_START),
    188       connected_(false) {
    189   request_manager_.SignalSendPacket.connect(this, &TurnPort::OnSendStunPacket);
    190 }
    191 
    192 TurnPort::TurnPort(talk_base::Thread* thread,
    193                    talk_base::PacketSocketFactory* factory,
    194                    talk_base::Network* network,
    195                    const talk_base::IPAddress& ip,
    196                    int min_port, int max_port,
    197                    const std::string& username,
    198                    const std::string& password,
    199                    const ProtocolAddress& server_address,
    200                    const RelayCredentials& credentials)
    201     : Port(thread, RELAY_PORT_TYPE, factory, network, ip, min_port, max_port,
    202            username, password),
    203       server_address_(server_address),
    204       credentials_(credentials),
    205       socket_(NULL),
    206       resolver_(NULL),
    207       error_(0),
    208       request_manager_(thread),
    209       next_channel_number_(TURN_CHANNEL_NUMBER_START),
    210       connected_(false) {
    211   request_manager_.SignalSendPacket.connect(this, &TurnPort::OnSendStunPacket);
    212 }
    213 
    214 TurnPort::~TurnPort() {
    215   // TODO(juberti): Should this even be necessary?
    216   while (!entries_.empty()) {
    217     DestroyEntry(entries_.front()->address());
    218   }
    219   if (resolver_) {
    220     resolver_->Destroy(false);
    221   }
    222   if (!SharedSocket()) {
    223     delete socket_;
    224   }
    225 }
    226 
    227 void TurnPort::PrepareAddress() {
    228   if (credentials_.username.empty() ||
    229       credentials_.password.empty()) {
    230     LOG(LS_ERROR) << "Allocation can't be started without setting the"
    231                   << " TURN server credentials for the user.";
    232     OnAllocateError();
    233     return;
    234   }
    235 
    236   if (!server_address_.address.port()) {
    237     // We will set default TURN port, if no port is set in the address.
    238     server_address_.address.SetPort(TURN_DEFAULT_PORT);
    239   }
    240 
    241   if (server_address_.address.IsUnresolved()) {
    242     ResolveTurnAddress(server_address_.address);
    243   } else {
    244     // If protocol family of server address doesn't match with local, return.
    245     if (!IsCompatibleAddress(server_address_.address)) {
    246       LOG(LS_ERROR) << "Server IP address family does not match with "
    247                     << "local host address family type";
    248       OnAllocateError();
    249       return;
    250     }
    251 
    252     LOG_J(LS_INFO, this) << "Trying to connect to TURN server via "
    253                          << ProtoToString(server_address_.proto) << " @ "
    254                          << server_address_.address.ToSensitiveString();
    255     if (server_address_.proto == PROTO_UDP && !SharedSocket()) {
    256       socket_ = socket_factory()->CreateUdpSocket(
    257           talk_base::SocketAddress(ip(), 0), min_port(), max_port());
    258     } else if (server_address_.proto == PROTO_TCP) {
    259       ASSERT(!SharedSocket());
    260       int opts = talk_base::PacketSocketFactory::OPT_STUN;
    261       // If secure bit is enabled in server address, use TLS over TCP.
    262       if (server_address_.secure) {
    263         opts |= talk_base::PacketSocketFactory::OPT_TLS;
    264       }
    265       socket_ = socket_factory()->CreateClientTcpSocket(
    266           talk_base::SocketAddress(ip(), 0), server_address_.address,
    267           proxy(), user_agent(), opts);
    268     }
    269 
    270     if (!socket_) {
    271       OnAllocateError();
    272       return;
    273     }
    274 
    275     // Apply options if any.
    276     for (SocketOptionsMap::iterator iter = socket_options_.begin();
    277          iter != socket_options_.end(); ++iter) {
    278       socket_->SetOption(iter->first, iter->second);
    279     }
    280 
    281     if (!SharedSocket()) {
    282       // If socket is shared, AllocationSequence will receive the packet.
    283       socket_->SignalReadPacket.connect(this, &TurnPort::OnReadPacket);
    284     }
    285 
    286     socket_->SignalReadyToSend.connect(this, &TurnPort::OnReadyToSend);
    287 
    288     if (server_address_.proto == PROTO_TCP) {
    289       socket_->SignalConnect.connect(this, &TurnPort::OnSocketConnect);
    290       socket_->SignalClose.connect(this, &TurnPort::OnSocketClose);
    291     } else {
    292       // If its UDP, send AllocateRequest now.
    293       // For TCP and TLS AllcateRequest will be sent by OnSocketConnect.
    294       SendRequest(new TurnAllocateRequest(this), 0);
    295     }
    296   }
    297 }
    298 
    299 void TurnPort::OnSocketConnect(talk_base::AsyncPacketSocket* socket) {
    300   ASSERT(server_address_.proto == PROTO_TCP);
    301   // Do not use this port if the socket bound to a different address than
    302   // the one we asked for. This is seen in Chrome, where TCP sockets cannot be
    303   // given a binding address, and the platform is expected to pick the
    304   // correct local address.
    305   if (socket->GetLocalAddress().ipaddr() != ip()) {
    306     LOG(LS_WARNING) << "Socket is bound to a different address then the "
    307                     << "local port. Discarding TURN port.";
    308     OnAllocateError();
    309     return;
    310   }
    311 
    312   LOG(LS_INFO) << "TurnPort connected to " << socket->GetRemoteAddress()
    313                << " using tcp.";
    314   SendRequest(new TurnAllocateRequest(this), 0);
    315 }
    316 
    317 void TurnPort::OnSocketClose(talk_base::AsyncPacketSocket* socket, int error) {
    318   LOG_J(LS_WARNING, this) << "Connection with server failed, error=" << error;
    319   if (!connected_) {
    320     OnAllocateError();
    321   }
    322 }
    323 
    324 Connection* TurnPort::CreateConnection(const Candidate& address,
    325                                        CandidateOrigin origin) {
    326   // TURN-UDP can only connect to UDP candidates.
    327   if (address.protocol() != UDP_PROTOCOL_NAME) {
    328     return NULL;
    329   }
    330 
    331   if (!IsCompatibleAddress(address.address())) {
    332     return NULL;
    333   }
    334 
    335   // Create an entry, if needed, so we can get our permissions set up correctly.
    336   CreateEntry(address.address());
    337 
    338   // A TURN port will have two candiates, STUN and TURN. STUN may not
    339   // present in all cases. If present stun candidate will be added first
    340   // and TURN candidate later.
    341   for (size_t index = 0; index < Candidates().size(); ++index) {
    342     if (Candidates()[index].type() == RELAY_PORT_TYPE) {
    343       ProxyConnection* conn = new ProxyConnection(this, index, address);
    344       conn->SignalDestroyed.connect(this, &TurnPort::OnConnectionDestroyed);
    345       AddConnection(conn);
    346       return conn;
    347     }
    348   }
    349   return NULL;
    350 }
    351 
    352 int TurnPort::SetOption(talk_base::Socket::Option opt, int value) {
    353   if (!socket_) {
    354     // If socket is not created yet, these options will be applied during socket
    355     // creation.
    356     socket_options_[opt] = value;
    357     return 0;
    358   }
    359   return socket_->SetOption(opt, value);
    360 }
    361 
    362 int TurnPort::GetOption(talk_base::Socket::Option opt, int* value) {
    363   if (!socket_) {
    364     SocketOptionsMap::const_iterator it = socket_options_.find(opt);
    365     if (it == socket_options_.end()) {
    366       return -1;
    367     }
    368     *value = it->second;
    369     return 0;
    370   }
    371 
    372   return socket_->GetOption(opt, value);
    373 }
    374 
    375 int TurnPort::GetError() {
    376   return error_;
    377 }
    378 
    379 int TurnPort::SendTo(const void* data, size_t size,
    380                      const talk_base::SocketAddress& addr,
    381                      const talk_base::PacketOptions& options,
    382                      bool payload) {
    383   // Try to find an entry for this specific address; we should have one.
    384   TurnEntry* entry = FindEntry(addr);
    385   ASSERT(entry != NULL);
    386   if (!entry) {
    387     return 0;
    388   }
    389 
    390   if (!connected()) {
    391     error_ = EWOULDBLOCK;
    392     return SOCKET_ERROR;
    393   }
    394 
    395   // Send the actual contents to the server using the usual mechanism.
    396   int sent = entry->Send(data, size, payload, options);
    397   if (sent <= 0) {
    398     return SOCKET_ERROR;
    399   }
    400 
    401   // The caller of the function is expecting the number of user data bytes,
    402   // rather than the size of the packet.
    403   return static_cast<int>(size);
    404 }
    405 
    406 void TurnPort::OnReadPacket(
    407     talk_base::AsyncPacketSocket* socket, const char* data, size_t size,
    408     const talk_base::SocketAddress& remote_addr,
    409     const talk_base::PacketTime& packet_time) {
    410   ASSERT(socket == socket_);
    411   ASSERT(remote_addr == server_address_.address);
    412 
    413   // The message must be at least the size of a channel header.
    414   if (size < TURN_CHANNEL_HEADER_SIZE) {
    415     LOG_J(LS_WARNING, this) << "Received TURN message that was too short";
    416     return;
    417   }
    418 
    419   // Check the message type, to see if is a Channel Data message.
    420   // The message will either be channel data, a TURN data indication, or
    421   // a response to a previous request.
    422   uint16 msg_type = talk_base::GetBE16(data);
    423   if (IsTurnChannelData(msg_type)) {
    424     HandleChannelData(msg_type, data, size, packet_time);
    425   } else if (msg_type == TURN_DATA_INDICATION) {
    426     HandleDataIndication(data, size, packet_time);
    427   } else {
    428     // This must be a response for one of our requests.
    429     // Check success responses, but not errors, for MESSAGE-INTEGRITY.
    430     if (IsStunSuccessResponseType(msg_type) &&
    431         !StunMessage::ValidateMessageIntegrity(data, size, hash())) {
    432       LOG_J(LS_WARNING, this) << "Received TURN message with invalid "
    433                               << "message integrity, msg_type=" << msg_type;
    434       return;
    435     }
    436     request_manager_.CheckResponse(data, size);
    437   }
    438 }
    439 
    440 void TurnPort::OnReadyToSend(talk_base::AsyncPacketSocket* socket) {
    441   if (connected_) {
    442     Port::OnReadyToSend();
    443   }
    444 }
    445 
    446 void TurnPort::ResolveTurnAddress(const talk_base::SocketAddress& address) {
    447   if (resolver_)
    448     return;
    449 
    450   resolver_ = socket_factory()->CreateAsyncResolver();
    451   resolver_->SignalDone.connect(this, &TurnPort::OnResolveResult);
    452   resolver_->Start(address);
    453 }
    454 
    455 void TurnPort::OnResolveResult(talk_base::AsyncResolverInterface* resolver) {
    456   ASSERT(resolver == resolver_);
    457   // Copy the original server address in |resolved_address|. For TLS based
    458   // sockets we need hostname along with resolved address.
    459   talk_base::SocketAddress resolved_address = server_address_.address;
    460   if (resolver_->GetError() != 0 ||
    461       !resolver_->GetResolvedAddress(ip().family(), &resolved_address)) {
    462     LOG_J(LS_WARNING, this) << "TURN host lookup received error "
    463                             << resolver_->GetError();
    464     OnAllocateError();
    465     return;
    466   }
    467   // Signal needs both resolved and unresolved address. After signal is sent
    468   // we can copy resolved address back into |server_address_|.
    469   SignalResolvedServerAddress(this, server_address_.address,
    470                               resolved_address);
    471   server_address_.address = resolved_address;
    472   PrepareAddress();
    473 }
    474 
    475 void TurnPort::OnSendStunPacket(const void* data, size_t size,
    476                                 StunRequest* request) {
    477   talk_base::PacketOptions options(DefaultDscpValue());
    478   if (Send(data, size, options) < 0) {
    479     LOG_J(LS_ERROR, this) << "Failed to send TURN message, err="
    480                           << socket_->GetError();
    481   }
    482 }
    483 
    484 void TurnPort::OnStunAddress(const talk_base::SocketAddress& address) {
    485   // STUN Port will discover STUN candidate, as it's supplied with first TURN
    486   // server address.
    487   // Why not using this address? - P2PTransportChannel will start creating
    488   // connections after first candidate, which means it could start creating the
    489   // connections before TURN candidate added. For that to handle, we need to
    490   // supply STUN candidate from this port to UDPPort, and TurnPort should have
    491   // handle to UDPPort to pass back the address.
    492 }
    493 
    494 void TurnPort::OnAllocateSuccess(const talk_base::SocketAddress& address,
    495                                  const talk_base::SocketAddress& stun_address) {
    496   connected_ = true;
    497   // For relayed candidate, Base is the candidate itself.
    498   AddAddress(address,  // Candidate address.
    499              address,  // Base address.
    500              stun_address,  // Related address.
    501              UDP_PROTOCOL_NAME,
    502              RELAY_PORT_TYPE,
    503              GetRelayPreference(server_address_.proto, server_address_.secure),
    504              true);
    505 }
    506 
    507 void TurnPort::OnAllocateError() {
    508   // We will send SignalPortError asynchronously as this can be sent during
    509   // port initialization. This way it will not be blocking other port
    510   // creation.
    511   thread()->Post(this, MSG_ERROR);
    512 }
    513 
    514 void TurnPort::OnMessage(talk_base::Message* message) {
    515   if (message->message_id == MSG_ERROR) {
    516     SignalPortError(this);
    517     return;
    518   }
    519 
    520   Port::OnMessage(message);
    521 }
    522 
    523 void TurnPort::OnAllocateRequestTimeout() {
    524   OnAllocateError();
    525 }
    526 
    527 void TurnPort::HandleDataIndication(const char* data, size_t size,
    528                                     const talk_base::PacketTime& packet_time) {
    529   // Read in the message, and process according to RFC5766, Section 10.4.
    530   talk_base::ByteBuffer buf(data, size);
    531   TurnMessage msg;
    532   if (!msg.Read(&buf)) {
    533     LOG_J(LS_WARNING, this) << "Received invalid TURN data indication";
    534     return;
    535   }
    536 
    537   // Check mandatory attributes.
    538   const StunAddressAttribute* addr_attr =
    539       msg.GetAddress(STUN_ATTR_XOR_PEER_ADDRESS);
    540   if (!addr_attr) {
    541     LOG_J(LS_WARNING, this) << "Missing STUN_ATTR_XOR_PEER_ADDRESS attribute "
    542                             << "in data indication.";
    543     return;
    544   }
    545 
    546   const StunByteStringAttribute* data_attr =
    547       msg.GetByteString(STUN_ATTR_DATA);
    548   if (!data_attr) {
    549     LOG_J(LS_WARNING, this) << "Missing STUN_ATTR_DATA attribute in "
    550                             << "data indication.";
    551     return;
    552   }
    553 
    554   // Verify that the data came from somewhere we think we have a permission for.
    555   talk_base::SocketAddress ext_addr(addr_attr->GetAddress());
    556   if (!HasPermission(ext_addr.ipaddr())) {
    557     LOG_J(LS_WARNING, this) << "Received TURN data indication with invalid "
    558                             << "peer address, addr="
    559                             << ext_addr.ToSensitiveString();
    560     return;
    561   }
    562 
    563   DispatchPacket(data_attr->bytes(), data_attr->length(), ext_addr,
    564                  PROTO_UDP, packet_time);
    565 }
    566 
    567 void TurnPort::HandleChannelData(int channel_id, const char* data,
    568                                  size_t size,
    569                                  const talk_base::PacketTime& packet_time) {
    570   // Read the message, and process according to RFC5766, Section 11.6.
    571   //    0                   1                   2                   3
    572   //    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
    573   //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    574   //   |         Channel Number        |            Length             |
    575   //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    576   //   |                                                               |
    577   //   /                       Application Data                        /
    578   //   /                                                               /
    579   //   |                                                               |
    580   //   |                               +-------------------------------+
    581   //   |                               |
    582   //   +-------------------------------+
    583 
    584   // Extract header fields from the message.
    585   uint16 len = talk_base::GetBE16(data + 2);
    586   if (len > size - TURN_CHANNEL_HEADER_SIZE) {
    587     LOG_J(LS_WARNING, this) << "Received TURN channel data message with "
    588                             << "incorrect length, len=" << len;
    589     return;
    590   }
    591   // Allowing messages larger than |len|, as ChannelData can be padded.
    592 
    593   TurnEntry* entry = FindEntry(channel_id);
    594   if (!entry) {
    595     LOG_J(LS_WARNING, this) << "Received TURN channel data message for invalid "
    596                             << "channel, channel_id=" << channel_id;
    597     return;
    598   }
    599 
    600   DispatchPacket(data + TURN_CHANNEL_HEADER_SIZE, len, entry->address(),
    601                  PROTO_UDP, packet_time);
    602 }
    603 
    604 void TurnPort::DispatchPacket(const char* data, size_t size,
    605     const talk_base::SocketAddress& remote_addr,
    606     ProtocolType proto, const talk_base::PacketTime& packet_time) {
    607   if (Connection* conn = GetConnection(remote_addr)) {
    608     conn->OnReadPacket(data, size, packet_time);
    609   } else {
    610     Port::OnReadPacket(data, size, remote_addr, proto);
    611   }
    612 }
    613 
    614 bool TurnPort::ScheduleRefresh(int lifetime) {
    615   // Lifetime is in seconds; we schedule a refresh for one minute less.
    616   if (lifetime < 2 * 60) {
    617     LOG_J(LS_WARNING, this) << "Received response with lifetime that was "
    618                             << "too short, lifetime=" << lifetime;
    619     return false;
    620   }
    621 
    622   SendRequest(new TurnRefreshRequest(this), (lifetime - 60) * 1000);
    623   return true;
    624 }
    625 
    626 void TurnPort::SendRequest(StunRequest* req, int delay) {
    627   request_manager_.SendDelayed(req, delay);
    628 }
    629 
    630 void TurnPort::AddRequestAuthInfo(StunMessage* msg) {
    631   // If we've gotten the necessary data from the server, add it to our request.
    632   VERIFY(!hash_.empty());
    633   VERIFY(msg->AddAttribute(new StunByteStringAttribute(
    634       STUN_ATTR_USERNAME, credentials_.username)));
    635   VERIFY(msg->AddAttribute(new StunByteStringAttribute(
    636       STUN_ATTR_REALM, realm_)));
    637   VERIFY(msg->AddAttribute(new StunByteStringAttribute(
    638       STUN_ATTR_NONCE, nonce_)));
    639   VERIFY(msg->AddMessageIntegrity(hash()));
    640 }
    641 
    642 int TurnPort::Send(const void* data, size_t len,
    643                    const talk_base::PacketOptions& options) {
    644   return socket_->SendTo(data, len, server_address_.address, options);
    645 }
    646 
    647 void TurnPort::UpdateHash() {
    648   VERIFY(ComputeStunCredentialHash(credentials_.username, realm_,
    649                                    credentials_.password, &hash_));
    650 }
    651 
    652 bool TurnPort::UpdateNonce(StunMessage* response) {
    653   // When stale nonce error received, we should update
    654   // hash and store realm and nonce.
    655   // Check the mandatory attributes.
    656   const StunByteStringAttribute* realm_attr =
    657       response->GetByteString(STUN_ATTR_REALM);
    658   if (!realm_attr) {
    659     LOG(LS_ERROR) << "Missing STUN_ATTR_REALM attribute in "
    660                   << "stale nonce error response.";
    661     return false;
    662   }
    663   set_realm(realm_attr->GetString());
    664 
    665   const StunByteStringAttribute* nonce_attr =
    666       response->GetByteString(STUN_ATTR_NONCE);
    667   if (!nonce_attr) {
    668     LOG(LS_ERROR) << "Missing STUN_ATTR_NONCE attribute in "
    669                   << "stale nonce error response.";
    670     return false;
    671   }
    672   set_nonce(nonce_attr->GetString());
    673   return true;
    674 }
    675 
    676 static bool MatchesIP(TurnEntry* e, talk_base::IPAddress ipaddr) {
    677   return e->address().ipaddr() == ipaddr;
    678 }
    679 bool TurnPort::HasPermission(const talk_base::IPAddress& ipaddr) const {
    680   return (std::find_if(entries_.begin(), entries_.end(),
    681       std::bind2nd(std::ptr_fun(MatchesIP), ipaddr)) != entries_.end());
    682 }
    683 
    684 static bool MatchesAddress(TurnEntry* e, talk_base::SocketAddress addr) {
    685   return e->address() == addr;
    686 }
    687 TurnEntry* TurnPort::FindEntry(const talk_base::SocketAddress& addr) const {
    688   EntryList::const_iterator it = std::find_if(entries_.begin(), entries_.end(),
    689       std::bind2nd(std::ptr_fun(MatchesAddress), addr));
    690   return (it != entries_.end()) ? *it : NULL;
    691 }
    692 
    693 static bool MatchesChannelId(TurnEntry* e, int id) {
    694   return e->channel_id() == id;
    695 }
    696 TurnEntry* TurnPort::FindEntry(int channel_id) const {
    697   EntryList::const_iterator it = std::find_if(entries_.begin(), entries_.end(),
    698       std::bind2nd(std::ptr_fun(MatchesChannelId), channel_id));
    699   return (it != entries_.end()) ? *it : NULL;
    700 }
    701 
    702 TurnEntry* TurnPort::CreateEntry(const talk_base::SocketAddress& addr) {
    703   ASSERT(FindEntry(addr) == NULL);
    704   TurnEntry* entry = new TurnEntry(this, next_channel_number_++, addr);
    705   entries_.push_back(entry);
    706   return entry;
    707 }
    708 
    709 void TurnPort::DestroyEntry(const talk_base::SocketAddress& addr) {
    710   TurnEntry* entry = FindEntry(addr);
    711   ASSERT(entry != NULL);
    712   entry->SignalDestroyed(entry);
    713   entries_.remove(entry);
    714   delete entry;
    715 }
    716 
    717 void TurnPort::OnConnectionDestroyed(Connection* conn) {
    718   // Destroying TurnEntry for the connection, which is already destroyed.
    719   DestroyEntry(conn->remote_candidate().address());
    720 }
    721 
    722 TurnAllocateRequest::TurnAllocateRequest(TurnPort* port)
    723     : StunRequest(new TurnMessage()),
    724       port_(port) {
    725 }
    726 
    727 void TurnAllocateRequest::Prepare(StunMessage* request) {
    728   // Create the request as indicated in RFC 5766, Section 6.1.
    729   request->SetType(TURN_ALLOCATE_REQUEST);
    730   StunUInt32Attribute* transport_attr = StunAttribute::CreateUInt32(
    731       STUN_ATTR_REQUESTED_TRANSPORT);
    732   transport_attr->SetValue(IPPROTO_UDP << 24);
    733   VERIFY(request->AddAttribute(transport_attr));
    734   if (!port_->hash().empty()) {
    735     port_->AddRequestAuthInfo(request);
    736   }
    737 }
    738 
    739 void TurnAllocateRequest::OnResponse(StunMessage* response) {
    740   // Check mandatory attributes as indicated in RFC5766, Section 6.3.
    741   const StunAddressAttribute* mapped_attr =
    742       response->GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
    743   if (!mapped_attr) {
    744     LOG_J(LS_WARNING, port_) << "Missing STUN_ATTR_XOR_MAPPED_ADDRESS "
    745                              << "attribute in allocate success response";
    746     return;
    747   }
    748   // Using XOR-Mapped-Address for stun.
    749   port_->OnStunAddress(mapped_attr->GetAddress());
    750 
    751   const StunAddressAttribute* relayed_attr =
    752       response->GetAddress(STUN_ATTR_XOR_RELAYED_ADDRESS);
    753   if (!relayed_attr) {
    754     LOG_J(LS_WARNING, port_) << "Missing STUN_ATTR_XOR_RELAYED_ADDRESS "
    755                              << "attribute in allocate success response";
    756     return;
    757   }
    758 
    759   const StunUInt32Attribute* lifetime_attr =
    760       response->GetUInt32(STUN_ATTR_TURN_LIFETIME);
    761   if (!lifetime_attr) {
    762     LOG_J(LS_WARNING, port_) << "Missing STUN_ATTR_TURN_LIFETIME attribute in "
    763                              << "allocate success response";
    764     return;
    765   }
    766   // Notify the port the allocate succeeded, and schedule a refresh request.
    767   port_->OnAllocateSuccess(relayed_attr->GetAddress(),
    768                            mapped_attr->GetAddress());
    769   port_->ScheduleRefresh(lifetime_attr->value());
    770 }
    771 
    772 void TurnAllocateRequest::OnErrorResponse(StunMessage* response) {
    773   // Process error response according to RFC5766, Section 6.4.
    774   const StunErrorCodeAttribute* error_code = response->GetErrorCode();
    775   switch (error_code->code()) {
    776     case STUN_ERROR_UNAUTHORIZED:       // Unauthrorized.
    777       OnAuthChallenge(response, error_code->code());
    778       break;
    779     default:
    780       LOG_J(LS_WARNING, port_) << "Allocate response error, code="
    781                                << error_code->code();
    782       port_->OnAllocateError();
    783   }
    784 }
    785 
    786 void TurnAllocateRequest::OnTimeout() {
    787   LOG_J(LS_WARNING, port_) << "Allocate request timeout";
    788   port_->OnAllocateRequestTimeout();
    789 }
    790 
    791 void TurnAllocateRequest::OnAuthChallenge(StunMessage* response, int code) {
    792   // If we failed to authenticate even after we sent our credentials, fail hard.
    793   if (code == STUN_ERROR_UNAUTHORIZED && !port_->hash().empty()) {
    794     LOG_J(LS_WARNING, port_) << "Failed to authenticate with the server "
    795                              << "after challenge.";
    796     port_->OnAllocateError();
    797     return;
    798   }
    799 
    800   // Check the mandatory attributes.
    801   const StunByteStringAttribute* realm_attr =
    802       response->GetByteString(STUN_ATTR_REALM);
    803   if (!realm_attr) {
    804     LOG_J(LS_WARNING, port_) << "Missing STUN_ATTR_REALM attribute in "
    805                              << "allocate unauthorized response.";
    806     return;
    807   }
    808   port_->set_realm(realm_attr->GetString());
    809 
    810   const StunByteStringAttribute* nonce_attr =
    811       response->GetByteString(STUN_ATTR_NONCE);
    812   if (!nonce_attr) {
    813     LOG_J(LS_WARNING, port_) << "Missing STUN_ATTR_NONCE attribute in "
    814                              << "allocate unauthorized response.";
    815     return;
    816   }
    817   port_->set_nonce(nonce_attr->GetString());
    818 
    819   // Send another allocate request, with the received realm and nonce values.
    820   port_->SendRequest(new TurnAllocateRequest(port_), 0);
    821 }
    822 
    823 TurnRefreshRequest::TurnRefreshRequest(TurnPort* port)
    824     : StunRequest(new TurnMessage()),
    825       port_(port) {
    826 }
    827 
    828 void TurnRefreshRequest::Prepare(StunMessage* request) {
    829   // Create the request as indicated in RFC 5766, Section 7.1.
    830   // No attributes need to be included.
    831   request->SetType(TURN_REFRESH_REQUEST);
    832   port_->AddRequestAuthInfo(request);
    833 }
    834 
    835 void TurnRefreshRequest::OnResponse(StunMessage* response) {
    836   // Check mandatory attributes as indicated in RFC5766, Section 7.3.
    837   const StunUInt32Attribute* lifetime_attr =
    838       response->GetUInt32(STUN_ATTR_TURN_LIFETIME);
    839   if (!lifetime_attr) {
    840     LOG_J(LS_WARNING, port_) << "Missing STUN_ATTR_TURN_LIFETIME attribute in "
    841                              << "refresh success response.";
    842     return;
    843   }
    844 
    845   // Schedule a refresh based on the returned lifetime value.
    846   port_->ScheduleRefresh(lifetime_attr->value());
    847 }
    848 
    849 void TurnRefreshRequest::OnErrorResponse(StunMessage* response) {
    850   // TODO(juberti): Handle 437 error response as a success.
    851   const StunErrorCodeAttribute* error_code = response->GetErrorCode();
    852   LOG_J(LS_WARNING, port_) << "Refresh response error, code="
    853                            << error_code->code();
    854 
    855   if (error_code->code() == STUN_ERROR_STALE_NONCE) {
    856     if (port_->UpdateNonce(response)) {
    857       // Send RefreshRequest immediately.
    858       port_->SendRequest(new TurnRefreshRequest(port_), 0);
    859     }
    860   }
    861 }
    862 
    863 void TurnRefreshRequest::OnTimeout() {
    864 }
    865 
    866 TurnCreatePermissionRequest::TurnCreatePermissionRequest(
    867     TurnPort* port, TurnEntry* entry,
    868     const talk_base::SocketAddress& ext_addr)
    869     : StunRequest(new TurnMessage()),
    870       port_(port),
    871       entry_(entry),
    872       ext_addr_(ext_addr) {
    873   entry_->SignalDestroyed.connect(
    874       this, &TurnCreatePermissionRequest::OnEntryDestroyed);
    875 }
    876 
    877 void TurnCreatePermissionRequest::Prepare(StunMessage* request) {
    878   // Create the request as indicated in RFC5766, Section 9.1.
    879   request->SetType(TURN_CREATE_PERMISSION_REQUEST);
    880   VERIFY(request->AddAttribute(new StunXorAddressAttribute(
    881       STUN_ATTR_XOR_PEER_ADDRESS, ext_addr_)));
    882   port_->AddRequestAuthInfo(request);
    883 }
    884 
    885 void TurnCreatePermissionRequest::OnResponse(StunMessage* response) {
    886   if (entry_) {
    887     entry_->OnCreatePermissionSuccess();
    888   }
    889 }
    890 
    891 void TurnCreatePermissionRequest::OnErrorResponse(StunMessage* response) {
    892   if (entry_) {
    893     const StunErrorCodeAttribute* error_code = response->GetErrorCode();
    894     entry_->OnCreatePermissionError(response, error_code->code());
    895   }
    896 }
    897 
    898 void TurnCreatePermissionRequest::OnTimeout() {
    899   LOG_J(LS_WARNING, port_) << "Create permission timeout";
    900 }
    901 
    902 void TurnCreatePermissionRequest::OnEntryDestroyed(TurnEntry* entry) {
    903   ASSERT(entry_ == entry);
    904   entry_ = NULL;
    905 }
    906 
    907 TurnChannelBindRequest::TurnChannelBindRequest(
    908     TurnPort* port, TurnEntry* entry,
    909     int channel_id, const talk_base::SocketAddress& ext_addr)
    910     : StunRequest(new TurnMessage()),
    911       port_(port),
    912       entry_(entry),
    913       channel_id_(channel_id),
    914       ext_addr_(ext_addr) {
    915   entry_->SignalDestroyed.connect(
    916       this, &TurnChannelBindRequest::OnEntryDestroyed);
    917 }
    918 
    919 void TurnChannelBindRequest::Prepare(StunMessage* request) {
    920   // Create the request as indicated in RFC5766, Section 11.1.
    921   request->SetType(TURN_CHANNEL_BIND_REQUEST);
    922   VERIFY(request->AddAttribute(new StunUInt32Attribute(
    923       STUN_ATTR_CHANNEL_NUMBER, channel_id_ << 16)));
    924   VERIFY(request->AddAttribute(new StunXorAddressAttribute(
    925       STUN_ATTR_XOR_PEER_ADDRESS, ext_addr_)));
    926   port_->AddRequestAuthInfo(request);
    927 }
    928 
    929 void TurnChannelBindRequest::OnResponse(StunMessage* response) {
    930   if (entry_) {
    931     entry_->OnChannelBindSuccess();
    932     // Refresh the channel binding just under the permission timeout
    933     // threshold. The channel binding has a longer lifetime, but
    934     // this is the easiest way to keep both the channel and the
    935     // permission from expiring.
    936     entry_->SendChannelBindRequest(TURN_PERMISSION_TIMEOUT - 60 * 1000);
    937   }
    938 }
    939 
    940 void TurnChannelBindRequest::OnErrorResponse(StunMessage* response) {
    941   if (entry_) {
    942     const StunErrorCodeAttribute* error_code = response->GetErrorCode();
    943     entry_->OnChannelBindError(response, error_code->code());
    944   }
    945 }
    946 
    947 void TurnChannelBindRequest::OnTimeout() {
    948   LOG_J(LS_WARNING, port_) << "Channel bind timeout";
    949 }
    950 
    951 void TurnChannelBindRequest::OnEntryDestroyed(TurnEntry* entry) {
    952   ASSERT(entry_ == entry);
    953   entry_ = NULL;
    954 }
    955 
    956 TurnEntry::TurnEntry(TurnPort* port, int channel_id,
    957                      const talk_base::SocketAddress& ext_addr)
    958     : port_(port),
    959       channel_id_(channel_id),
    960       ext_addr_(ext_addr),
    961       state_(STATE_UNBOUND) {
    962   // Creating permission for |ext_addr_|.
    963   SendCreatePermissionRequest();
    964 }
    965 
    966 void TurnEntry::SendCreatePermissionRequest() {
    967   port_->SendRequest(new TurnCreatePermissionRequest(
    968       port_, this, ext_addr_), 0);
    969 }
    970 
    971 void TurnEntry::SendChannelBindRequest(int delay) {
    972   port_->SendRequest(new TurnChannelBindRequest(
    973       port_, this, channel_id_, ext_addr_), delay);
    974 }
    975 
    976 int TurnEntry::Send(const void* data, size_t size, bool payload,
    977                     const talk_base::PacketOptions& options) {
    978   talk_base::ByteBuffer buf;
    979   if (state_ != STATE_BOUND) {
    980     // If we haven't bound the channel yet, we have to use a Send Indication.
    981     TurnMessage msg;
    982     msg.SetType(TURN_SEND_INDICATION);
    983     msg.SetTransactionID(
    984         talk_base::CreateRandomString(kStunTransactionIdLength));
    985     VERIFY(msg.AddAttribute(new StunXorAddressAttribute(
    986         STUN_ATTR_XOR_PEER_ADDRESS, ext_addr_)));
    987     VERIFY(msg.AddAttribute(new StunByteStringAttribute(
    988         STUN_ATTR_DATA, data, size)));
    989     VERIFY(msg.Write(&buf));
    990 
    991     // If we're sending real data, request a channel bind that we can use later.
    992     if (state_ == STATE_UNBOUND && payload) {
    993       SendChannelBindRequest(0);
    994       state_ = STATE_BINDING;
    995     }
    996   } else {
    997     // If the channel is bound, we can send the data as a Channel Message.
    998     buf.WriteUInt16(channel_id_);
    999     buf.WriteUInt16(static_cast<uint16>(size));
   1000     buf.WriteBytes(reinterpret_cast<const char*>(data), size);
   1001   }
   1002   return port_->Send(buf.Data(), buf.Length(), options);
   1003 }
   1004 
   1005 void TurnEntry::OnCreatePermissionSuccess() {
   1006   LOG_J(LS_INFO, port_) << "Create permission for "
   1007                         << ext_addr_.ToSensitiveString()
   1008                         << " succeeded";
   1009   // For success result code will be 0.
   1010   port_->SignalCreatePermissionResult(port_, ext_addr_, 0);
   1011 }
   1012 
   1013 void TurnEntry::OnCreatePermissionError(StunMessage* response, int code) {
   1014   LOG_J(LS_WARNING, port_) << "Create permission for "
   1015                            << ext_addr_.ToSensitiveString()
   1016                            << " failed, code=" << code;
   1017   if (code == STUN_ERROR_STALE_NONCE) {
   1018     if (port_->UpdateNonce(response)) {
   1019       SendCreatePermissionRequest();
   1020     }
   1021   } else {
   1022     // Send signal with error code.
   1023     port_->SignalCreatePermissionResult(port_, ext_addr_, code);
   1024   }
   1025 }
   1026 
   1027 void TurnEntry::OnChannelBindSuccess() {
   1028   LOG_J(LS_INFO, port_) << "Channel bind for " << ext_addr_.ToSensitiveString()
   1029                         << " succeeded";
   1030   ASSERT(state_ == STATE_BINDING || state_ == STATE_BOUND);
   1031   state_ = STATE_BOUND;
   1032 }
   1033 
   1034 void TurnEntry::OnChannelBindError(StunMessage* response, int code) {
   1035   // TODO(mallinath) - Implement handling of error response for channel
   1036   // bind request as per http://tools.ietf.org/html/rfc5766#section-11.3
   1037   LOG_J(LS_WARNING, port_) << "Channel bind for "
   1038                            << ext_addr_.ToSensitiveString()
   1039                            << " failed, code=" << code;
   1040   if (code == STUN_ERROR_STALE_NONCE) {
   1041     if (port_->UpdateNonce(response)) {
   1042       // Send channel bind request with fresh nonce.
   1043       SendChannelBindRequest(0);
   1044     }
   1045   }
   1046 }
   1047 
   1048 }  // namespace cricket
   1049