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
25namespace cricket {
26
27// TODO(juberti): Move to stun.h when relay messages have been renamed.
28static const int TURN_ALLOCATE_REQUEST = STUN_ALLOCATE_REQUEST;
29
30// TODO(juberti): Extract to turnmessage.h
31static const int TURN_DEFAULT_PORT = 3478;
32static const int TURN_CHANNEL_NUMBER_START = 0x4000;
33static const int TURN_PERMISSION_TIMEOUT = 5 * 60 * 1000;  // 5 minutes
34
35static 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.
39static const size_t MAX_ALLOCATE_MISMATCH_RETRIES = 2;
40
41static const int TURN_SUCCESS_RESULT_CODE = 0;
42
43inline bool IsTurnChannelData(uint16_t msg_type) {
44  return ((msg_type & 0xC000) == 0x4000);  // MSB are 0b01
45}
46
47static 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
59class 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
77class 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
92class 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
111class 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.
133class 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
182TurnPort::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
212TurnPort::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
247TurnPort::~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
269rtc::SocketAddress TurnPort::GetLocalAddress() const {
270  return socket_ ? socket_->GetLocalAddress() : rtc::SocketAddress();
271}
272
273void 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
318bool 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
367void 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
411void 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
417void 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
440Connection* 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
472bool 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
481int 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
491int 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
504int TurnPort::GetError() {
505  return error_;
506}
507
508int 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
535void 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
587void TurnPort::OnSentPacket(rtc::AsyncPacketSocket* socket,
588                            const rtc::SentPacket& sent_packet) {
589  PortInterface::SignalSentPacket(sent_packet);
590}
591
592void 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.
600bool 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
630void 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
641void 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
673void 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
683void 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
693void 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
716void 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
723void 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
730void 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
743void 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
775void TurnPort::OnAllocateRequestTimeout() {
776  OnAllocateError();
777}
778
779void 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
819void 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
856void 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
866bool 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
880void TurnPort::SendRequest(StunRequest* req, int delay) {
881  request_manager_.SendDelayed(req, delay);
882}
883
884void 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
896int 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
901void TurnPort::UpdateHash() {
902  VERIFY(ComputeStunCredentialHash(credentials_.username, realm_,
903                                   credentials_.password, &hash_));
904}
905
906bool 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
930static bool MatchesIP(TurnEntry* e, rtc::IPAddress ipaddr) {
931  return e->address().ipaddr() == ipaddr;
932}
933bool 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
938static bool MatchesAddress(TurnEntry* e, rtc::SocketAddress addr) {
939  return e->address() == addr;
940}
941TurnEntry* 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
947static bool MatchesChannelId(TurnEntry* e, int id) {
948  return e->channel_id() == id;
949}
950TurnEntry* 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
956bool TurnPort::EntryExists(TurnEntry* e) {
957  auto it = std::find(entries_.begin(), entries_.end(), e);
958  return it != entries_.end();
959}
960
961void 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
973void TurnPort::DestroyEntry(TurnEntry* entry) {
974  ASSERT(entry != NULL);
975  entry->SignalDestroyed(entry);
976  entries_.remove(entry);
977  delete entry;
978}
979
980void 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
991void 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
1000void 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
1010void TurnPort::CancelEntryDestruction(TurnEntry* entry) {
1011  ASSERT(entry->destruction_timestamp() != 0);
1012  entry->set_destruction_timestamp(0);
1013}
1014
1015bool 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
1025TurnAllocateRequest::TurnAllocateRequest(TurnPort* port)
1026    : StunRequest(new TurnMessage()),
1027      port_(port) {
1028}
1029
1030void 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
1042void TurnAllocateRequest::OnSent() {
1043  LOG_J(LS_INFO, port_) << "TURN allocate request sent"
1044                        << ", id=" << rtc::hex_encode(id());
1045  StunRequest::OnSent();
1046}
1047
1048void 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
1086void 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
1116void TurnAllocateRequest::OnTimeout() {
1117  LOG_J(LS_WARNING, port_) << "TURN allocate request "
1118                           << rtc::hex_encode(id()) << " timout";
1119  port_->OnAllocateRequestTimeout();
1120}
1121
1122void 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
1154void 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
1197TurnRefreshRequest::TurnRefreshRequest(TurnPort* port)
1198    : StunRequest(new TurnMessage()),
1199      port_(port),
1200      lifetime_(-1) {
1201}
1202
1203void 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
1215void TurnRefreshRequest::OnSent() {
1216  LOG_J(LS_INFO, port_) << "TURN refresh request sent"
1217                        << ", id=" << rtc::hex_encode(id());
1218  StunRequest::OnSent();
1219}
1220
1221void 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
1241void 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
1259void TurnRefreshRequest::OnTimeout() {
1260  LOG_J(LS_WARNING, port_) << "TURN refresh timeout " << rtc::hex_encode(id());
1261  port_->OnTurnRefreshError();
1262}
1263
1264TurnCreatePermissionRequest::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
1275void 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
1283void TurnCreatePermissionRequest::OnSent() {
1284  LOG_J(LS_INFO, port_) << "TURN create permission request sent"
1285                        << ", id=" << rtc::hex_encode(id());
1286  StunRequest::OnSent();
1287}
1288
1289void 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
1300void 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
1311void 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
1319void TurnCreatePermissionRequest::OnEntryDestroyed(TurnEntry* entry) {
1320  ASSERT(entry_ == entry);
1321  entry_ = NULL;
1322}
1323
1324TurnChannelBindRequest::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
1336void 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
1346void TurnChannelBindRequest::OnSent() {
1347  LOG_J(LS_INFO, port_) << "TURN channel bind request sent"
1348                        << ", id=" << rtc::hex_encode(id());
1349  StunRequest::OnSent();
1350}
1351
1352void 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
1370void 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
1381void 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
1389void TurnChannelBindRequest::OnEntryDestroyed(TurnEntry* entry) {
1390  ASSERT(entry_ == entry);
1391  entry_ = NULL;
1392}
1393
1394TurnEntry::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
1404void TurnEntry::SendCreatePermissionRequest(int delay) {
1405  port_->SendRequest(new TurnCreatePermissionRequest(port_, this, ext_addr_),
1406                     delay);
1407}
1408
1409void TurnEntry::SendChannelBindRequest(int delay) {
1410  port_->SendRequest(new TurnChannelBindRequest(
1411      port_, this, channel_id_, ext_addr_), delay);
1412}
1413
1414int 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
1443void 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
1462void 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
1480void TurnEntry::OnCreatePermissionTimeout() {
1481  port_->DestroyConnection(ext_addr_);
1482}
1483
1484void 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
1491void 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}
1505void TurnEntry::OnChannelBindTimeout() {
1506  state_ = STATE_UNBOUND;
1507  port_->DestroyConnection(ext_addr_);
1508}
1509}  // namespace cricket
1510