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 "p2p/base/turn_port.h"
12 
13 #include <functional>
14 #include <memory>
15 #include <utility>
16 #include <vector>
17 
18 #include "absl/algorithm/container.h"
19 #include "absl/strings/match.h"
20 #include "absl/types/optional.h"
21 #include "api/transport/stun.h"
22 #include "p2p/base/connection.h"
23 #include "p2p/base/p2p_constants.h"
24 #include "rtc_base/async_packet_socket.h"
25 #include "rtc_base/byte_order.h"
26 #include "rtc_base/checks.h"
27 #include "rtc_base/logging.h"
28 #include "rtc_base/net_helpers.h"
29 #include "rtc_base/socket_address.h"
30 #include "rtc_base/strings/string_builder.h"
31 #include "rtc_base/task_utils/to_queued_task.h"
32 #include "system_wrappers/include/field_trial.h"
33 
34 namespace cricket {
35 
36 // TODO(juberti): Move to stun.h when relay messages have been renamed.
37 static const int TURN_ALLOCATE_REQUEST = STUN_ALLOCATE_REQUEST;
38 
39 // Attributes in comprehension-optional range,
40 // ignored by TURN server that doesn't know about them.
41 // https://tools.ietf.org/html/rfc5389#section-18.2
42 static const int STUN_ATTR_MULTI_MAPPING = 0xff04;
43 const int STUN_ATTR_TURN_LOGGING_ID = 0xff05;
44 
45 // TODO(juberti): Extract to turnmessage.h
46 static const int TURN_DEFAULT_PORT = 3478;
47 static const int TURN_CHANNEL_NUMBER_START = 0x4000;
48 static const int TURN_PERMISSION_TIMEOUT = 5 * 60 * 1000;  // 5 minutes
49 
50 static const size_t TURN_CHANNEL_HEADER_SIZE = 4U;
51 
52 // Retry at most twice (i.e. three different ALLOCATE requests) on
53 // STUN_ERROR_ALLOCATION_MISMATCH error per rfc5766.
54 static const size_t MAX_ALLOCATE_MISMATCH_RETRIES = 2;
55 
56 static const int TURN_SUCCESS_RESULT_CODE = 0;
57 
IsTurnChannelData(uint16_t msg_type)58 inline bool IsTurnChannelData(uint16_t msg_type) {
59   return ((msg_type & 0xC000) == 0x4000);  // MSB are 0b01
60 }
61 
GetRelayPreference(cricket::ProtocolType proto)62 static int GetRelayPreference(cricket::ProtocolType proto) {
63   switch (proto) {
64     case cricket::PROTO_TCP:
65       return ICE_TYPE_PREFERENCE_RELAY_TCP;
66     case cricket::PROTO_TLS:
67       return ICE_TYPE_PREFERENCE_RELAY_TLS;
68     default:
69       RTC_DCHECK(proto == PROTO_UDP);
70       return ICE_TYPE_PREFERENCE_RELAY_UDP;
71   }
72 }
73 
74 class TurnAllocateRequest : public StunRequest {
75  public:
76   explicit TurnAllocateRequest(TurnPort* port);
77   void Prepare(StunMessage* request) override;
78   void OnSent() override;
79   void OnResponse(StunMessage* response) override;
80   void OnErrorResponse(StunMessage* response) override;
81   void OnTimeout() override;
82 
83  private:
84   // Handles authentication challenge from the server.
85   void OnAuthChallenge(StunMessage* response, int code);
86   void OnTryAlternate(StunMessage* response, int code);
87   void OnUnknownAttribute(StunMessage* response);
88 
89   TurnPort* port_;
90 };
91 
92 class TurnRefreshRequest : public StunRequest {
93  public:
94   explicit TurnRefreshRequest(TurnPort* port);
95   void Prepare(StunMessage* request) override;
96   void OnSent() override;
97   void OnResponse(StunMessage* response) override;
98   void OnErrorResponse(StunMessage* response) override;
99   void OnTimeout() override;
set_lifetime(int lifetime)100   void set_lifetime(int lifetime) { lifetime_ = lifetime; }
101 
102  private:
103   TurnPort* port_;
104   int lifetime_;
105 };
106 
107 class TurnCreatePermissionRequest : public StunRequest,
108                                     public sigslot::has_slots<> {
109  public:
110   TurnCreatePermissionRequest(TurnPort* port,
111                               TurnEntry* entry,
112                               const rtc::SocketAddress& ext_addr,
113                               const std::string& remote_ufrag);
114   void Prepare(StunMessage* request) override;
115   void OnSent() override;
116   void OnResponse(StunMessage* response) override;
117   void OnErrorResponse(StunMessage* response) override;
118   void OnTimeout() override;
119 
120  private:
121   void OnEntryDestroyed(TurnEntry* entry);
122 
123   TurnPort* port_;
124   TurnEntry* entry_;
125   rtc::SocketAddress ext_addr_;
126   std::string remote_ufrag_;
127 };
128 
129 class TurnChannelBindRequest : public StunRequest, public sigslot::has_slots<> {
130  public:
131   TurnChannelBindRequest(TurnPort* port,
132                          TurnEntry* entry,
133                          int channel_id,
134                          const rtc::SocketAddress& ext_addr);
135   void Prepare(StunMessage* request) override;
136   void OnSent() override;
137   void OnResponse(StunMessage* response) override;
138   void OnErrorResponse(StunMessage* response) override;
139   void OnTimeout() override;
140 
141  private:
142   void OnEntryDestroyed(TurnEntry* entry);
143 
144   TurnPort* port_;
145   TurnEntry* entry_;
146   int channel_id_;
147   rtc::SocketAddress ext_addr_;
148 };
149 
150 // Manages a "connection" to a remote destination. We will attempt to bring up
151 // a channel for this remote destination to reduce the overhead of sending data.
152 class TurnEntry : public sigslot::has_slots<> {
153  public:
154   enum BindState { STATE_UNBOUND, STATE_BINDING, STATE_BOUND };
155   TurnEntry(TurnPort* port,
156             int channel_id,
157             const rtc::SocketAddress& ext_addr,
158             const std::string remote_ufrag);
159 
port()160   TurnPort* port() { return port_; }
161 
channel_id() const162   int channel_id() const { return channel_id_; }
163   // For testing only.
set_channel_id(int channel_id)164   void set_channel_id(int channel_id) { channel_id_ = channel_id; }
165 
address() const166   const rtc::SocketAddress& address() const { return ext_addr_; }
state() const167   BindState state() const { return state_; }
168 
169   // If the destruction timestamp is set, that means destruction has been
170   // scheduled (will occur TURN_PERMISSION_TIMEOUT after it's scheduled).
destruction_timestamp()171   absl::optional<int64_t> destruction_timestamp() {
172     return destruction_timestamp_;
173   }
set_destruction_timestamp(int64_t destruction_timestamp)174   void set_destruction_timestamp(int64_t destruction_timestamp) {
175     destruction_timestamp_.emplace(destruction_timestamp);
176   }
reset_destruction_timestamp()177   void reset_destruction_timestamp() { destruction_timestamp_.reset(); }
178 
179   // Helper methods to send permission and channel bind requests.
180   void SendCreatePermissionRequest(int delay);
181   void SendChannelBindRequest(int delay);
182   // Sends a packet to the given destination address.
183   // This will wrap the packet in STUN if necessary.
184   int Send(const void* data,
185            size_t size,
186            bool payload,
187            const rtc::PacketOptions& options);
188 
189   void OnCreatePermissionSuccess();
190   void OnCreatePermissionError(StunMessage* response, int code);
191   void OnCreatePermissionTimeout();
192   void OnChannelBindSuccess();
193   void OnChannelBindError(StunMessage* response, int code);
194   void OnChannelBindTimeout();
195   // Signal sent when TurnEntry is destroyed.
196   sigslot::signal1<TurnEntry*> SignalDestroyed;
197 
get_remote_ufrag() const198   const std::string& get_remote_ufrag() const { return remote_ufrag_; }
set_remote_ufrag(const std::string & remote_ufrag)199   void set_remote_ufrag(const std::string& remote_ufrag) {
200     remote_ufrag_ = remote_ufrag;
201   }
202 
203  private:
204   TurnPort* port_;
205   int channel_id_;
206   rtc::SocketAddress ext_addr_;
207   BindState state_;
208   // An unset value indicates that this entry is scheduled to be destroyed. It
209   // is also used as an ID of the event scheduling. When the destruction event
210   // actually fires, the TurnEntry will be destroyed only if the timestamp here
211   // matches the one in the firing event.
212   absl::optional<int64_t> destruction_timestamp_;
213 
214   std::string remote_ufrag_;
215 };
216 
TurnPort(rtc::Thread * thread,rtc::PacketSocketFactory * factory,rtc::Network * network,rtc::AsyncPacketSocket * socket,const std::string & username,const std::string & password,const ProtocolAddress & server_address,const RelayCredentials & credentials,int server_priority,const std::string & origin,webrtc::TurnCustomizer * customizer)217 TurnPort::TurnPort(rtc::Thread* thread,
218                    rtc::PacketSocketFactory* factory,
219                    rtc::Network* network,
220                    rtc::AsyncPacketSocket* socket,
221                    const std::string& username,
222                    const std::string& password,
223                    const ProtocolAddress& server_address,
224                    const RelayCredentials& credentials,
225                    int server_priority,
226                    const std::string& origin,
227                    webrtc::TurnCustomizer* customizer)
228     : Port(thread, RELAY_PORT_TYPE, factory, network, username, password),
229       server_address_(server_address),
230       tls_cert_verifier_(nullptr),
231       credentials_(credentials),
232       socket_(socket),
233       resolver_(NULL),
234       error_(0),
235       stun_dscp_value_(rtc::DSCP_NO_CHANGE),
236       request_manager_(thread),
237       next_channel_number_(TURN_CHANNEL_NUMBER_START),
238       state_(STATE_CONNECTING),
239       server_priority_(server_priority),
240       allocate_mismatch_retries_(0),
241       turn_customizer_(customizer) {
242   request_manager_.SignalSendPacket.connect(this, &TurnPort::OnSendStunPacket);
243   request_manager_.set_origin(origin);
244 }
245 
TurnPort(rtc::Thread * thread,rtc::PacketSocketFactory * factory,rtc::Network * network,uint16_t min_port,uint16_t max_port,const std::string & username,const std::string & password,const ProtocolAddress & server_address,const RelayCredentials & credentials,int server_priority,const std::string & origin,const std::vector<std::string> & tls_alpn_protocols,const std::vector<std::string> & tls_elliptic_curves,webrtc::TurnCustomizer * customizer,rtc::SSLCertificateVerifier * tls_cert_verifier)246 TurnPort::TurnPort(rtc::Thread* thread,
247                    rtc::PacketSocketFactory* factory,
248                    rtc::Network* network,
249                    uint16_t min_port,
250                    uint16_t max_port,
251                    const std::string& username,
252                    const std::string& password,
253                    const ProtocolAddress& server_address,
254                    const RelayCredentials& credentials,
255                    int server_priority,
256                    const std::string& origin,
257                    const std::vector<std::string>& tls_alpn_protocols,
258                    const std::vector<std::string>& tls_elliptic_curves,
259                    webrtc::TurnCustomizer* customizer,
260                    rtc::SSLCertificateVerifier* tls_cert_verifier)
261     : Port(thread,
262            RELAY_PORT_TYPE,
263            factory,
264            network,
265            min_port,
266            max_port,
267            username,
268            password),
269       server_address_(server_address),
270       tls_alpn_protocols_(tls_alpn_protocols),
271       tls_elliptic_curves_(tls_elliptic_curves),
272       tls_cert_verifier_(tls_cert_verifier),
273       credentials_(credentials),
274       socket_(NULL),
275       resolver_(NULL),
276       error_(0),
277       stun_dscp_value_(rtc::DSCP_NO_CHANGE),
278       request_manager_(thread),
279       next_channel_number_(TURN_CHANNEL_NUMBER_START),
280       state_(STATE_CONNECTING),
281       server_priority_(server_priority),
282       allocate_mismatch_retries_(0),
283       turn_customizer_(customizer) {
284   request_manager_.SignalSendPacket.connect(this, &TurnPort::OnSendStunPacket);
285   request_manager_.set_origin(origin);
286 }
287 
~TurnPort()288 TurnPort::~TurnPort() {
289   // TODO(juberti): Should this even be necessary?
290 
291   // release the allocation by sending a refresh with
292   // lifetime 0.
293   if (ready()) {
294     Release();
295   }
296 
297   while (!entries_.empty()) {
298     DestroyEntry(entries_.front());
299   }
300   if (resolver_) {
301     resolver_->Destroy(false);
302   }
303   if (!SharedSocket()) {
304     delete socket_;
305   }
306 }
307 
GetLocalAddress() const308 rtc::SocketAddress TurnPort::GetLocalAddress() const {
309   return socket_ ? socket_->GetLocalAddress() : rtc::SocketAddress();
310 }
311 
GetProtocol() const312 ProtocolType TurnPort::GetProtocol() const {
313   return server_address_.proto;
314 }
315 
GetTlsCertPolicy() const316 TlsCertPolicy TurnPort::GetTlsCertPolicy() const {
317   return tls_cert_policy_;
318 }
319 
SetTlsCertPolicy(TlsCertPolicy tls_cert_policy)320 void TurnPort::SetTlsCertPolicy(TlsCertPolicy tls_cert_policy) {
321   tls_cert_policy_ = tls_cert_policy;
322 }
323 
SetTurnLoggingId(const std::string & turn_logging_id)324 void TurnPort::SetTurnLoggingId(const std::string& turn_logging_id) {
325   turn_logging_id_ = turn_logging_id;
326 }
327 
GetTlsAlpnProtocols() const328 std::vector<std::string> TurnPort::GetTlsAlpnProtocols() const {
329   return tls_alpn_protocols_;
330 }
331 
GetTlsEllipticCurves() const332 std::vector<std::string> TurnPort::GetTlsEllipticCurves() const {
333   return tls_elliptic_curves_;
334 }
335 
PrepareAddress()336 void TurnPort::PrepareAddress() {
337   if (credentials_.username.empty() || credentials_.password.empty()) {
338     RTC_LOG(LS_ERROR) << "Allocation can't be started without setting the"
339                          " TURN server credentials for the user.";
340     OnAllocateError(STUN_ERROR_UNAUTHORIZED,
341                     "Missing TURN server credentials.");
342     return;
343   }
344 
345   if (!server_address_.address.port()) {
346     // We will set default TURN port, if no port is set in the address.
347     server_address_.address.SetPort(TURN_DEFAULT_PORT);
348   }
349 
350   if (!AllowedTurnPort(server_address_.address.port())) {
351     // This can only happen after a 300 ALTERNATE SERVER, since the port can't
352     // be created with a disallowed port number.
353     RTC_LOG(LS_ERROR) << "Attempt to start allocation with disallowed port# "
354                       << server_address_.address.port();
355     OnAllocateError(STUN_ERROR_SERVER_ERROR,
356                     "Attempt to start allocation to a disallowed port");
357     return;
358   }
359   if (server_address_.address.IsUnresolvedIP()) {
360     ResolveTurnAddress(server_address_.address);
361   } else {
362     // If protocol family of server address doesn't match with local, return.
363     if (!IsCompatibleAddress(server_address_.address)) {
364       RTC_LOG(LS_ERROR) << "IP address family does not match. server: "
365                         << server_address_.address.family()
366                         << " local: " << Network()->GetBestIP().family();
367       OnAllocateError(STUN_ERROR_GLOBAL_FAILURE,
368                       "IP address family does not match.");
369       return;
370     }
371 
372     // Insert the current address to prevent redirection pingpong.
373     attempted_server_addresses_.insert(server_address_.address);
374 
375     RTC_LOG(LS_INFO) << ToString() << ": Trying to connect to TURN server via "
376                      << ProtoToString(server_address_.proto) << " @ "
377                      << server_address_.address.ToSensitiveString();
378     if (!CreateTurnClientSocket()) {
379       RTC_LOG(LS_ERROR) << "Failed to create TURN client socket";
380       OnAllocateError(SERVER_NOT_REACHABLE_ERROR,
381                       "Failed to create TURN client socket.");
382       return;
383     }
384     if (server_address_.proto == PROTO_UDP) {
385       // If its UDP, send AllocateRequest now.
386       // For TCP and TLS AllcateRequest will be sent by OnSocketConnect.
387       SendRequest(new TurnAllocateRequest(this), 0);
388     }
389   }
390 }
391 
CreateTurnClientSocket()392 bool TurnPort::CreateTurnClientSocket() {
393   RTC_DCHECK(!socket_ || SharedSocket());
394 
395   if (server_address_.proto == PROTO_UDP && !SharedSocket()) {
396     socket_ = socket_factory()->CreateUdpSocket(
397         rtc::SocketAddress(Network()->GetBestIP(), 0), min_port(), max_port());
398   } else if (server_address_.proto == PROTO_TCP ||
399              server_address_.proto == PROTO_TLS) {
400     RTC_DCHECK(!SharedSocket());
401     int opts = rtc::PacketSocketFactory::OPT_STUN;
402 
403     // Apply server address TLS and insecure bits to options.
404     if (server_address_.proto == PROTO_TLS) {
405       if (tls_cert_policy_ ==
406           TlsCertPolicy::TLS_CERT_POLICY_INSECURE_NO_CHECK) {
407         opts |= rtc::PacketSocketFactory::OPT_TLS_INSECURE;
408       } else {
409         opts |= rtc::PacketSocketFactory::OPT_TLS;
410       }
411     }
412 
413     rtc::PacketSocketTcpOptions tcp_options;
414     tcp_options.opts = opts;
415     tcp_options.tls_alpn_protocols = tls_alpn_protocols_;
416     tcp_options.tls_elliptic_curves = tls_elliptic_curves_;
417     tcp_options.tls_cert_verifier = tls_cert_verifier_;
418     socket_ = socket_factory()->CreateClientTcpSocket(
419         rtc::SocketAddress(Network()->GetBestIP(), 0), server_address_.address,
420         proxy(), user_agent(), tcp_options);
421   }
422 
423   if (!socket_) {
424     error_ = SOCKET_ERROR;
425     return false;
426   }
427 
428   // Apply options if any.
429   for (SocketOptionsMap::iterator iter = socket_options_.begin();
430        iter != socket_options_.end(); ++iter) {
431     socket_->SetOption(iter->first, iter->second);
432   }
433 
434   if (!SharedSocket()) {
435     // If socket is shared, AllocationSequence will receive the packet.
436     socket_->SignalReadPacket.connect(this, &TurnPort::OnReadPacket);
437   }
438 
439   socket_->SignalReadyToSend.connect(this, &TurnPort::OnReadyToSend);
440 
441   socket_->SignalSentPacket.connect(this, &TurnPort::OnSentPacket);
442 
443   // TCP port is ready to send stun requests after the socket is connected,
444   // while UDP port is ready to do so once the socket is created.
445   if (server_address_.proto == PROTO_TCP ||
446       server_address_.proto == PROTO_TLS) {
447     socket_->SignalConnect.connect(this, &TurnPort::OnSocketConnect);
448     socket_->SignalClose.connect(this, &TurnPort::OnSocketClose);
449   } else {
450     state_ = STATE_CONNECTED;
451   }
452   return true;
453 }
454 
OnSocketConnect(rtc::AsyncPacketSocket * socket)455 void TurnPort::OnSocketConnect(rtc::AsyncPacketSocket* socket) {
456   // This slot should only be invoked if we're using a connection-oriented
457   // protocol.
458   RTC_DCHECK(server_address_.proto == PROTO_TCP ||
459              server_address_.proto == PROTO_TLS);
460 
461   // Do not use this port if the socket bound to an address not associated with
462   // the desired network interface. This is seen in Chrome, where TCP sockets
463   // cannot be given a binding address, and the platform is expected to pick
464   // the correct local address.
465   //
466   // However, there are two situations in which we allow the bound address to
467   // not be one of the addresses of the requested interface:
468   // 1. The bound address is the loopback address. This happens when a proxy
469   // forces TCP to bind to only the localhost address (see issue 3927).
470   // 2. The bound address is the "any address". This happens when
471   // multiple_routes is disabled (see issue 4780).
472   //
473   // Note that, aside from minor differences in log statements, this logic is
474   // identical to that in TcpPort.
475   const rtc::SocketAddress& socket_address = socket->GetLocalAddress();
476   if (absl::c_none_of(Network()->GetIPs(),
477                       [socket_address](const rtc::InterfaceAddress& addr) {
478                         return socket_address.ipaddr() == addr;
479                       })) {
480     if (socket->GetLocalAddress().IsLoopbackIP()) {
481       RTC_LOG(LS_WARNING) << "Socket is bound to the address:"
482                           << socket_address.ipaddr().ToSensitiveString()
483                           << ", rather than an address associated with network:"
484                           << Network()->ToString()
485                           << ". Still allowing it since it's localhost.";
486     } else if (IPIsAny(Network()->GetBestIP())) {
487       RTC_LOG(LS_WARNING)
488           << "Socket is bound to the address:"
489           << socket_address.ipaddr().ToSensitiveString()
490           << ", rather than an address associated with network:"
491           << Network()->ToString()
492           << ". Still allowing it since it's the 'any' address"
493              ", possibly caused by multiple_routes being disabled.";
494     } else {
495       RTC_LOG(LS_WARNING) << "Socket is bound to the address:"
496                           << socket_address.ipaddr().ToSensitiveString()
497                           << ", rather than an address associated with network:"
498                           << Network()->ToString() << ". Discarding TURN port.";
499       OnAllocateError(
500           STUN_ERROR_GLOBAL_FAILURE,
501           "Address not associated with the desired network interface.");
502       return;
503     }
504   }
505 
506   state_ = STATE_CONNECTED;  // It is ready to send stun requests.
507   if (server_address_.address.IsUnresolvedIP()) {
508     server_address_.address = socket_->GetRemoteAddress();
509   }
510 
511   RTC_LOG(LS_INFO) << "TurnPort connected to "
512                    << socket->GetRemoteAddress().ToSensitiveString()
513                    << " using tcp.";
514   SendRequest(new TurnAllocateRequest(this), 0);
515 }
516 
OnSocketClose(rtc::AsyncPacketSocket * socket,int error)517 void TurnPort::OnSocketClose(rtc::AsyncPacketSocket* socket, int error) {
518   RTC_LOG(LS_WARNING) << ToString()
519                       << ": Connection with server failed with error: "
520                       << error;
521   RTC_DCHECK(socket == socket_);
522   Close();
523 }
524 
OnAllocateMismatch()525 void TurnPort::OnAllocateMismatch() {
526   if (allocate_mismatch_retries_ >= MAX_ALLOCATE_MISMATCH_RETRIES) {
527     RTC_LOG(LS_WARNING) << ToString() << ": Giving up on the port after "
528                         << allocate_mismatch_retries_
529                         << " retries for STUN_ERROR_ALLOCATION_MISMATCH";
530     OnAllocateError(STUN_ERROR_ALLOCATION_MISMATCH,
531                     "Maximum retries reached for allocation mismatch.");
532     return;
533   }
534 
535   RTC_LOG(LS_INFO) << ToString()
536                    << ": Allocating a new socket after "
537                       "STUN_ERROR_ALLOCATION_MISMATCH, retry: "
538                    << allocate_mismatch_retries_ + 1;
539   if (SharedSocket()) {
540     ResetSharedSocket();
541   } else {
542     delete socket_;
543   }
544   socket_ = NULL;
545 
546   ResetNonce();
547   PrepareAddress();
548   ++allocate_mismatch_retries_;
549 }
550 
CreateConnection(const Candidate & remote_candidate,CandidateOrigin origin)551 Connection* TurnPort::CreateConnection(const Candidate& remote_candidate,
552                                        CandidateOrigin origin) {
553   // TURN-UDP can only connect to UDP candidates.
554   if (!SupportsProtocol(remote_candidate.protocol())) {
555     return nullptr;
556   }
557 
558   if (state_ == STATE_DISCONNECTED || state_ == STATE_RECEIVEONLY) {
559     return nullptr;
560   }
561 
562   // If the remote endpoint signaled us an mDNS candidate, we do not form a pair
563   // with the relay candidate to avoid IP leakage in the CreatePermission
564   // request.
565   if (absl::EndsWith(remote_candidate.address().hostname(), LOCAL_TLD)) {
566     return nullptr;
567   }
568 
569   // A TURN port will have two candiates, STUN and TURN. STUN may not
570   // present in all cases. If present stun candidate will be added first
571   // and TURN candidate later.
572   for (size_t index = 0; index < Candidates().size(); ++index) {
573     const Candidate& local_candidate = Candidates()[index];
574     if (local_candidate.type() == RELAY_PORT_TYPE &&
575         local_candidate.address().family() ==
576             remote_candidate.address().family()) {
577       // Create an entry, if needed, so we can get our permissions set up
578       // correctly.
579       if (CreateOrRefreshEntry(remote_candidate.address(), next_channel_number_,
580                                remote_candidate.username())) {
581         // An entry was created.
582         next_channel_number_++;
583       }
584       ProxyConnection* conn =
585           new ProxyConnection(this, index, remote_candidate);
586       AddOrReplaceConnection(conn);
587       return conn;
588     }
589   }
590   return nullptr;
591 }
592 
FailAndPruneConnection(const rtc::SocketAddress & address)593 bool TurnPort::FailAndPruneConnection(const rtc::SocketAddress& address) {
594   Connection* conn = GetConnection(address);
595   if (conn != nullptr) {
596     conn->FailAndPrune();
597     return true;
598   }
599   return false;
600 }
601 
SetOption(rtc::Socket::Option opt,int value)602 int TurnPort::SetOption(rtc::Socket::Option opt, int value) {
603   // Remember the last requested DSCP value, for STUN traffic.
604   if (opt == rtc::Socket::OPT_DSCP)
605     stun_dscp_value_ = static_cast<rtc::DiffServCodePoint>(value);
606 
607   if (!socket_) {
608     // If socket is not created yet, these options will be applied during socket
609     // creation.
610     socket_options_[opt] = value;
611     return 0;
612   }
613   return socket_->SetOption(opt, value);
614 }
615 
GetOption(rtc::Socket::Option opt,int * value)616 int TurnPort::GetOption(rtc::Socket::Option opt, int* value) {
617   if (!socket_) {
618     SocketOptionsMap::const_iterator it = socket_options_.find(opt);
619     if (it == socket_options_.end()) {
620       return -1;
621     }
622     *value = it->second;
623     return 0;
624   }
625 
626   return socket_->GetOption(opt, value);
627 }
628 
GetError()629 int TurnPort::GetError() {
630   return error_;
631 }
632 
SendTo(const void * data,size_t size,const rtc::SocketAddress & addr,const rtc::PacketOptions & options,bool payload)633 int TurnPort::SendTo(const void* data,
634                      size_t size,
635                      const rtc::SocketAddress& addr,
636                      const rtc::PacketOptions& options,
637                      bool payload) {
638   // Try to find an entry for this specific address; we should have one.
639   TurnEntry* entry = FindEntry(addr);
640   if (!entry) {
641     RTC_LOG(LS_ERROR) << "Did not find the TurnEntry for address "
642                       << addr.ToSensitiveString();
643     return 0;
644   }
645 
646   if (!ready()) {
647     error_ = ENOTCONN;
648     return SOCKET_ERROR;
649   }
650 
651   // Send the actual contents to the server using the usual mechanism.
652   rtc::PacketOptions modified_options(options);
653   CopyPortInformationToPacketInfo(&modified_options.info_signaled_after_sent);
654   int sent = entry->Send(data, size, payload, modified_options);
655   if (sent <= 0) {
656     return SOCKET_ERROR;
657   }
658 
659   // The caller of the function is expecting the number of user data bytes,
660   // rather than the size of the packet.
661   return static_cast<int>(size);
662 }
663 
CanHandleIncomingPacketsFrom(const rtc::SocketAddress & addr) const664 bool TurnPort::CanHandleIncomingPacketsFrom(
665     const rtc::SocketAddress& addr) const {
666   return server_address_.address == addr;
667 }
668 
HandleIncomingPacket(rtc::AsyncPacketSocket * socket,const char * data,size_t size,const rtc::SocketAddress & remote_addr,int64_t packet_time_us)669 bool TurnPort::HandleIncomingPacket(rtc::AsyncPacketSocket* socket,
670                                     const char* data,
671                                     size_t size,
672                                     const rtc::SocketAddress& remote_addr,
673                                     int64_t packet_time_us) {
674   if (socket != socket_) {
675     // The packet was received on a shared socket after we've allocated a new
676     // socket for this TURN port.
677     return false;
678   }
679 
680   // This is to guard against a STUN response from previous server after
681   // alternative server redirection. TODO(guoweis): add a unit test for this
682   // race condition.
683   if (remote_addr != server_address_.address) {
684     RTC_LOG(LS_WARNING) << ToString()
685                         << ": Discarding TURN message from unknown address: "
686                         << remote_addr.ToSensitiveString()
687                         << " server_address_: "
688                         << server_address_.address.ToSensitiveString();
689     return false;
690   }
691 
692   // The message must be at least the size of a channel header.
693   if (size < TURN_CHANNEL_HEADER_SIZE) {
694     RTC_LOG(LS_WARNING) << ToString()
695                         << ": Received TURN message that was too short";
696     return false;
697   }
698 
699   if (state_ == STATE_DISCONNECTED) {
700     RTC_LOG(LS_WARNING)
701         << ToString()
702         << ": Received TURN message while the TURN port is disconnected";
703     return false;
704   }
705 
706   // Check the message type, to see if is a Channel Data message.
707   // The message will either be channel data, a TURN data indication, or
708   // a response to a previous request.
709   uint16_t msg_type = rtc::GetBE16(data);
710   if (IsTurnChannelData(msg_type)) {
711     HandleChannelData(msg_type, data, size, packet_time_us);
712     return true;
713   }
714 
715   if (msg_type == TURN_DATA_INDICATION) {
716     HandleDataIndication(data, size, packet_time_us);
717     return true;
718   }
719 
720   if (SharedSocket() && (msg_type == STUN_BINDING_RESPONSE ||
721                          msg_type == STUN_BINDING_ERROR_RESPONSE)) {
722     RTC_LOG(LS_VERBOSE)
723         << ToString()
724         << ": Ignoring STUN binding response message on shared socket.";
725     return false;
726   }
727 
728   request_manager_.CheckResponse(data, size);
729 
730   return true;
731 }
732 
OnReadPacket(rtc::AsyncPacketSocket * socket,const char * data,size_t size,const rtc::SocketAddress & remote_addr,const int64_t & packet_time_us)733 void TurnPort::OnReadPacket(rtc::AsyncPacketSocket* socket,
734                             const char* data,
735                             size_t size,
736                             const rtc::SocketAddress& remote_addr,
737                             const int64_t& packet_time_us) {
738   HandleIncomingPacket(socket, data, size, remote_addr, packet_time_us);
739 }
740 
OnSentPacket(rtc::AsyncPacketSocket * socket,const rtc::SentPacket & sent_packet)741 void TurnPort::OnSentPacket(rtc::AsyncPacketSocket* socket,
742                             const rtc::SentPacket& sent_packet) {
743   PortInterface::SignalSentPacket(sent_packet);
744 }
745 
OnReadyToSend(rtc::AsyncPacketSocket * socket)746 void TurnPort::OnReadyToSend(rtc::AsyncPacketSocket* socket) {
747   if (ready()) {
748     Port::OnReadyToSend();
749   }
750 }
751 
SupportsProtocol(const std::string & protocol) const752 bool TurnPort::SupportsProtocol(const std::string& protocol) const {
753   // Turn port only connects to UDP candidates.
754   return protocol == UDP_PROTOCOL_NAME;
755 }
756 
757 // Update current server address port with the alternate server address port.
SetAlternateServer(const rtc::SocketAddress & address)758 bool TurnPort::SetAlternateServer(const rtc::SocketAddress& address) {
759   // Check if we have seen this address before and reject if we did.
760   AttemptedServerSet::iterator iter = attempted_server_addresses_.find(address);
761   if (iter != attempted_server_addresses_.end()) {
762     RTC_LOG(LS_WARNING) << ToString() << ": Redirection to ["
763                         << address.ToSensitiveString()
764                         << "] ignored, allocation failed.";
765     return false;
766   }
767 
768   // If protocol family of server address doesn't match with local, return.
769   if (!IsCompatibleAddress(address)) {
770     RTC_LOG(LS_WARNING) << "Server IP address family does not match with "
771                            "local host address family type";
772     return false;
773   }
774 
775   // Block redirects to a loopback address.
776   // See: https://bugs.chromium.org/p/chromium/issues/detail?id=649118
777   if (address.IsLoopbackIP()) {
778     RTC_LOG(LS_WARNING) << ToString()
779                         << ": Blocking attempted redirect to loopback address.";
780     return false;
781   }
782 
783   RTC_LOG(LS_INFO) << ToString() << ": Redirecting from TURN server ["
784                    << server_address_.address.ToSensitiveString()
785                    << "] to TURN server [" << address.ToSensitiveString()
786                    << "]";
787   server_address_ = ProtocolAddress(address, server_address_.proto);
788 
789   // Insert the current address to prevent redirection pingpong.
790   attempted_server_addresses_.insert(server_address_.address);
791   return true;
792 }
793 
ResolveTurnAddress(const rtc::SocketAddress & address)794 void TurnPort::ResolveTurnAddress(const rtc::SocketAddress& address) {
795   if (resolver_)
796     return;
797 
798   RTC_LOG(LS_INFO) << ToString() << ": Starting TURN host lookup for "
799                    << address.ToSensitiveString();
800   resolver_ = socket_factory()->CreateAsyncResolver();
801   resolver_->SignalDone.connect(this, &TurnPort::OnResolveResult);
802   resolver_->Start(address);
803 }
804 
OnResolveResult(rtc::AsyncResolverInterface * resolver)805 void TurnPort::OnResolveResult(rtc::AsyncResolverInterface* resolver) {
806   RTC_DCHECK(resolver == resolver_);
807   // If DNS resolve is failed when trying to connect to the server using TCP,
808   // one of the reason could be due to DNS queries blocked by firewall.
809   // In such cases we will try to connect to the server with hostname, assuming
810   // socket layer will resolve the hostname through a HTTP proxy (if any).
811   if (resolver_->GetError() != 0 && (server_address_.proto == PROTO_TCP ||
812                                      server_address_.proto == PROTO_TLS)) {
813     if (!CreateTurnClientSocket()) {
814       OnAllocateError(SERVER_NOT_REACHABLE_ERROR,
815                       "TURN host lookup received error.");
816     }
817     return;
818   }
819 
820   // Copy the original server address in |resolved_address|. For TLS based
821   // sockets we need hostname along with resolved address.
822   rtc::SocketAddress resolved_address = server_address_.address;
823   if (resolver_->GetError() != 0 ||
824       !resolver_->GetResolvedAddress(Network()->GetBestIP().family(),
825                                      &resolved_address)) {
826     RTC_LOG(LS_WARNING) << ToString() << ": TURN host lookup received error "
827                         << resolver_->GetError();
828     error_ = resolver_->GetError();
829     OnAllocateError(SERVER_NOT_REACHABLE_ERROR,
830                     "TURN host lookup received error.");
831     return;
832   }
833   // Signal needs both resolved and unresolved address. After signal is sent
834   // we can copy resolved address back into |server_address_|.
835   SignalResolvedServerAddress(this, server_address_.address, resolved_address);
836   server_address_.address = resolved_address;
837   PrepareAddress();
838 }
839 
OnSendStunPacket(const void * data,size_t size,StunRequest * request)840 void TurnPort::OnSendStunPacket(const void* data,
841                                 size_t size,
842                                 StunRequest* request) {
843   RTC_DCHECK(connected());
844   rtc::PacketOptions options(StunDscpValue());
845   options.info_signaled_after_sent.packet_type = rtc::PacketType::kTurnMessage;
846   CopyPortInformationToPacketInfo(&options.info_signaled_after_sent);
847   if (Send(data, size, options) < 0) {
848     RTC_LOG(LS_ERROR) << ToString() << ": Failed to send TURN message, error: "
849                       << socket_->GetError();
850   }
851 }
852 
OnStunAddress(const rtc::SocketAddress & address)853 void TurnPort::OnStunAddress(const rtc::SocketAddress& address) {
854   // STUN Port will discover STUN candidate, as it's supplied with first TURN
855   // server address.
856   // Why not using this address? - P2PTransportChannel will start creating
857   // connections after first candidate, which means it could start creating the
858   // connections before TURN candidate added. For that to handle, we need to
859   // supply STUN candidate from this port to UDPPort, and TurnPort should have
860   // handle to UDPPort to pass back the address.
861 }
862 
OnAllocateSuccess(const rtc::SocketAddress & address,const rtc::SocketAddress & stun_address)863 void TurnPort::OnAllocateSuccess(const rtc::SocketAddress& address,
864                                  const rtc::SocketAddress& stun_address) {
865   state_ = STATE_READY;
866 
867   rtc::SocketAddress related_address = stun_address;
868 
869   // For relayed candidate, Base is the candidate itself.
870   AddAddress(address,          // Candidate address.
871              address,          // Base address.
872              related_address,  // Related address.
873              UDP_PROTOCOL_NAME,
874              ProtoToString(server_address_.proto),  // The first hop protocol.
875              "",  // TCP canddiate type, empty for turn candidates.
876              RELAY_PORT_TYPE, GetRelayPreference(server_address_.proto),
877              server_priority_, ReconstructedServerUrl(false /* use_hostname */),
878              true);
879 }
880 
OnAllocateError(int error_code,const std::string & reason)881 void TurnPort::OnAllocateError(int error_code, const std::string& reason) {
882   // We will send SignalPortError asynchronously as this can be sent during
883   // port initialization. This way it will not be blocking other port
884   // creation.
885   thread()->Post(RTC_FROM_HERE, this, MSG_ALLOCATE_ERROR);
886   std::string address = GetLocalAddress().HostAsSensitiveURIString();
887   int port = GetLocalAddress().port();
888   if (server_address_.proto == PROTO_TCP &&
889       server_address_.address.IsPrivateIP()) {
890     address.clear();
891     port = 0;
892   }
893   SignalCandidateError(
894       this, IceCandidateErrorEvent(
895                 address, port, ReconstructedServerUrl(true /* use_hostname */),
896                 error_code, reason));
897 }
898 
OnRefreshError()899 void TurnPort::OnRefreshError() {
900   // Need to clear the requests asynchronously because otherwise, the refresh
901   // request may be deleted twice: once at the end of the message processing
902   // and the other in HandleRefreshError().
903   thread()->Post(RTC_FROM_HERE, this, MSG_REFRESH_ERROR);
904 }
905 
HandleRefreshError()906 void TurnPort::HandleRefreshError() {
907   request_manager_.Clear();
908   state_ = STATE_RECEIVEONLY;
909   // Fail and prune all connections; stop sending data.
910   for (auto kv : connections()) {
911     kv.second->FailAndPrune();
912   }
913 }
914 
Release()915 void TurnPort::Release() {
916   // Remove any pending refresh requests.
917   request_manager_.Clear();
918 
919   // Send refresh with lifetime 0.
920   TurnRefreshRequest* req = new TurnRefreshRequest(this);
921   req->set_lifetime(0);
922   SendRequest(req, 0);
923 
924   state_ = STATE_RECEIVEONLY;
925 }
926 
Close()927 void TurnPort::Close() {
928   if (!ready()) {
929     OnAllocateError(SERVER_NOT_REACHABLE_ERROR, "");
930   }
931   request_manager_.Clear();
932   // Stop the port from creating new connections.
933   state_ = STATE_DISCONNECTED;
934   // Delete all existing connections; stop sending data.
935   for (auto kv : connections()) {
936     kv.second->Destroy();
937   }
938 
939   SignalTurnPortClosed(this);
940 }
941 
StunDscpValue() const942 rtc::DiffServCodePoint TurnPort::StunDscpValue() const {
943   return stun_dscp_value_;
944 }
945 
946 // static
AllowedTurnPort(int port)947 bool TurnPort::AllowedTurnPort(int port) {
948   // Port 53, 80 and 443 are used for existing deployments.
949   // Ports above 1024 are assumed to be OK to use.
950   if (port == 53 || port == 80 || port == 443 || port >= 1024) {
951     return true;
952   }
953   // Allow any port if relevant field trial is set. This allows disabling the
954   // check.
955   if (webrtc::field_trial::IsEnabled("WebRTC-Turn-AllowSystemPorts")) {
956     return true;
957   }
958   return false;
959 }
960 
OnMessage(rtc::Message * message)961 void TurnPort::OnMessage(rtc::Message* message) {
962   switch (message->message_id) {
963     case MSG_ALLOCATE_ERROR:
964       SignalPortError(this);
965       break;
966     case MSG_ALLOCATE_MISMATCH:
967       OnAllocateMismatch();
968       break;
969     case MSG_REFRESH_ERROR:
970       HandleRefreshError();
971       break;
972     case MSG_TRY_ALTERNATE_SERVER:
973       if (server_address().proto == PROTO_UDP) {
974         // Send another allocate request to alternate server, with the received
975         // realm and nonce values.
976         SendRequest(new TurnAllocateRequest(this), 0);
977       } else {
978         // Since it's TCP, we have to delete the connected socket and reconnect
979         // with the alternate server. PrepareAddress will send stun binding once
980         // the new socket is connected.
981         RTC_DCHECK(server_address().proto == PROTO_TCP ||
982                    server_address().proto == PROTO_TLS);
983         RTC_DCHECK(!SharedSocket());
984         delete socket_;
985         socket_ = NULL;
986         PrepareAddress();
987       }
988       break;
989     case MSG_ALLOCATION_RELEASED:
990       Close();
991       break;
992     default:
993       Port::OnMessage(message);
994   }
995 }
996 
OnAllocateRequestTimeout()997 void TurnPort::OnAllocateRequestTimeout() {
998   OnAllocateError(SERVER_NOT_REACHABLE_ERROR,
999                   "TURN allocate request timed out.");
1000 }
1001 
HandleDataIndication(const char * data,size_t size,int64_t packet_time_us)1002 void TurnPort::HandleDataIndication(const char* data,
1003                                     size_t size,
1004                                     int64_t packet_time_us) {
1005   // Read in the message, and process according to RFC5766, Section 10.4.
1006   rtc::ByteBufferReader buf(data, size);
1007   TurnMessage msg;
1008   if (!msg.Read(&buf)) {
1009     RTC_LOG(LS_WARNING) << ToString()
1010                         << ": Received invalid TURN data indication";
1011     return;
1012   }
1013 
1014   // Check mandatory attributes.
1015   const StunAddressAttribute* addr_attr =
1016       msg.GetAddress(STUN_ATTR_XOR_PEER_ADDRESS);
1017   if (!addr_attr) {
1018     RTC_LOG(LS_WARNING) << ToString()
1019                         << ": Missing STUN_ATTR_XOR_PEER_ADDRESS attribute "
1020                            "in data indication.";
1021     return;
1022   }
1023 
1024   const StunByteStringAttribute* data_attr = msg.GetByteString(STUN_ATTR_DATA);
1025   if (!data_attr) {
1026     RTC_LOG(LS_WARNING) << ToString()
1027                         << ": Missing STUN_ATTR_DATA attribute in "
1028                            "data indication.";
1029     return;
1030   }
1031 
1032   // Log a warning if the data didn't come from an address that we think we have
1033   // a permission for.
1034   rtc::SocketAddress ext_addr(addr_attr->GetAddress());
1035   if (!HasPermission(ext_addr.ipaddr())) {
1036     RTC_LOG(LS_WARNING) << ToString()
1037                         << ": Received TURN data indication with unknown "
1038                            "peer address, addr: "
1039                         << ext_addr.ToSensitiveString();
1040   }
1041 
1042   DispatchPacket(data_attr->bytes(), data_attr->length(), ext_addr, PROTO_UDP,
1043                  packet_time_us);
1044 }
1045 
HandleChannelData(int channel_id,const char * data,size_t size,int64_t packet_time_us)1046 void TurnPort::HandleChannelData(int channel_id,
1047                                  const char* data,
1048                                  size_t size,
1049                                  int64_t packet_time_us) {
1050   // Read the message, and process according to RFC5766, Section 11.6.
1051   //    0                   1                   2                   3
1052   //    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
1053   //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1054   //   |         Channel Number        |            Length             |
1055   //   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1056   //   |                                                               |
1057   //   /                       Application Data                        /
1058   //   /                                                               /
1059   //   |                                                               |
1060   //   |                               +-------------------------------+
1061   //   |                               |
1062   //   +-------------------------------+
1063 
1064   // Extract header fields from the message.
1065   uint16_t len = rtc::GetBE16(data + 2);
1066   if (len > size - TURN_CHANNEL_HEADER_SIZE) {
1067     RTC_LOG(LS_WARNING) << ToString()
1068                         << ": Received TURN channel data message with "
1069                            "incorrect length, len: "
1070                         << len;
1071     return;
1072   }
1073   // Allowing messages larger than |len|, as ChannelData can be padded.
1074 
1075   TurnEntry* entry = FindEntry(channel_id);
1076   if (!entry) {
1077     RTC_LOG(LS_WARNING) << ToString()
1078                         << ": Received TURN channel data message for invalid "
1079                            "channel, channel_id: "
1080                         << channel_id;
1081     return;
1082   }
1083 
1084   DispatchPacket(data + TURN_CHANNEL_HEADER_SIZE, len, entry->address(),
1085                  PROTO_UDP, packet_time_us);
1086 }
1087 
DispatchPacket(const char * data,size_t size,const rtc::SocketAddress & remote_addr,ProtocolType proto,int64_t packet_time_us)1088 void TurnPort::DispatchPacket(const char* data,
1089                               size_t size,
1090                               const rtc::SocketAddress& remote_addr,
1091                               ProtocolType proto,
1092                               int64_t packet_time_us) {
1093   if (Connection* conn = GetConnection(remote_addr)) {
1094     conn->OnReadPacket(data, size, packet_time_us);
1095   } else {
1096     Port::OnReadPacket(data, size, remote_addr, proto);
1097   }
1098 }
1099 
ScheduleRefresh(uint32_t lifetime)1100 bool TurnPort::ScheduleRefresh(uint32_t lifetime) {
1101   // Lifetime is in seconds, delay is in milliseconds.
1102   int delay = 1 * 60 * 1000;
1103 
1104   // Cutoff lifetime bigger than 1h.
1105   constexpr uint32_t max_lifetime = 60 * 60;
1106 
1107   if (lifetime < 2 * 60) {
1108     // The RFC does not mention a lower limit on lifetime.
1109     // So if server sends a value less than 2 minutes, we schedule a refresh
1110     // for half lifetime.
1111     RTC_LOG(LS_WARNING) << ToString()
1112                         << ": Received response with short lifetime: "
1113                         << lifetime << " seconds.";
1114     delay = (lifetime * 1000) / 2;
1115   } else if (lifetime > max_lifetime) {
1116     // Make 1 hour largest delay, and then sce
1117     // we schedule a refresh for one minute less than max lifetime.
1118     RTC_LOG(LS_WARNING) << ToString()
1119                         << ": Received response with long lifetime: "
1120                         << lifetime << " seconds.";
1121     delay = (max_lifetime - 60) * 1000;
1122   } else {
1123     // Normal case,
1124     // we schedule a refresh for one minute less than requested lifetime.
1125     delay = (lifetime - 60) * 1000;
1126   }
1127 
1128   SendRequest(new TurnRefreshRequest(this), delay);
1129   RTC_LOG(LS_INFO) << ToString() << ": Scheduled refresh in " << delay << "ms.";
1130   return true;
1131 }
1132 
SendRequest(StunRequest * req,int delay)1133 void TurnPort::SendRequest(StunRequest* req, int delay) {
1134   request_manager_.SendDelayed(req, delay);
1135 }
1136 
AddRequestAuthInfo(StunMessage * msg)1137 void TurnPort::AddRequestAuthInfo(StunMessage* msg) {
1138   // If we've gotten the necessary data from the server, add it to our request.
1139   RTC_DCHECK(!hash_.empty());
1140   msg->AddAttribute(std::make_unique<StunByteStringAttribute>(
1141       STUN_ATTR_USERNAME, credentials_.username));
1142   msg->AddAttribute(
1143       std::make_unique<StunByteStringAttribute>(STUN_ATTR_REALM, realm_));
1144   msg->AddAttribute(
1145       std::make_unique<StunByteStringAttribute>(STUN_ATTR_NONCE, nonce_));
1146   const bool success = msg->AddMessageIntegrity(hash());
1147   RTC_DCHECK(success);
1148 }
1149 
Send(const void * data,size_t len,const rtc::PacketOptions & options)1150 int TurnPort::Send(const void* data,
1151                    size_t len,
1152                    const rtc::PacketOptions& options) {
1153   return socket_->SendTo(data, len, server_address_.address, options);
1154 }
1155 
UpdateHash()1156 void TurnPort::UpdateHash() {
1157   const bool success = ComputeStunCredentialHash(credentials_.username, realm_,
1158                                                  credentials_.password, &hash_);
1159   RTC_DCHECK(success);
1160 }
1161 
UpdateNonce(StunMessage * response)1162 bool TurnPort::UpdateNonce(StunMessage* response) {
1163   // When stale nonce error received, we should update
1164   // hash and store realm and nonce.
1165   // Check the mandatory attributes.
1166   const StunByteStringAttribute* realm_attr =
1167       response->GetByteString(STUN_ATTR_REALM);
1168   if (!realm_attr) {
1169     RTC_LOG(LS_ERROR) << "Missing STUN_ATTR_REALM attribute in "
1170                          "stale nonce error response.";
1171     return false;
1172   }
1173   set_realm(realm_attr->GetString());
1174 
1175   const StunByteStringAttribute* nonce_attr =
1176       response->GetByteString(STUN_ATTR_NONCE);
1177   if (!nonce_attr) {
1178     RTC_LOG(LS_ERROR) << "Missing STUN_ATTR_NONCE attribute in "
1179                          "stale nonce error response.";
1180     return false;
1181   }
1182   set_nonce(nonce_attr->GetString());
1183   return true;
1184 }
1185 
ResetNonce()1186 void TurnPort::ResetNonce() {
1187   hash_.clear();
1188   nonce_.clear();
1189   realm_.clear();
1190 }
1191 
HasPermission(const rtc::IPAddress & ipaddr) const1192 bool TurnPort::HasPermission(const rtc::IPAddress& ipaddr) const {
1193   return absl::c_any_of(entries_, [&ipaddr](const TurnEntry* e) {
1194     return e->address().ipaddr() == ipaddr;
1195   });
1196 }
1197 
FindEntry(const rtc::SocketAddress & addr) const1198 TurnEntry* TurnPort::FindEntry(const rtc::SocketAddress& addr) const {
1199   auto it = absl::c_find_if(
1200       entries_, [&addr](const TurnEntry* e) { return e->address() == addr; });
1201   return (it != entries_.end()) ? *it : NULL;
1202 }
1203 
FindEntry(int channel_id) const1204 TurnEntry* TurnPort::FindEntry(int channel_id) const {
1205   auto it = absl::c_find_if(entries_, [&channel_id](const TurnEntry* e) {
1206     return e->channel_id() == channel_id;
1207   });
1208   return (it != entries_.end()) ? *it : NULL;
1209 }
1210 
EntryExists(TurnEntry * e)1211 bool TurnPort::EntryExists(TurnEntry* e) {
1212   return absl::c_linear_search(entries_, e);
1213 }
1214 
CreateOrRefreshEntry(const rtc::SocketAddress & addr,int channel_number)1215 bool TurnPort::CreateOrRefreshEntry(const rtc::SocketAddress& addr,
1216                                     int channel_number) {
1217   return CreateOrRefreshEntry(addr, channel_number, "");
1218 }
1219 
CreateOrRefreshEntry(const rtc::SocketAddress & addr,int channel_number,const std::string & remote_ufrag)1220 bool TurnPort::CreateOrRefreshEntry(const rtc::SocketAddress& addr,
1221                                     int channel_number,
1222                                     const std::string& remote_ufrag) {
1223   TurnEntry* entry = FindEntry(addr);
1224   if (entry == nullptr) {
1225     entry = new TurnEntry(this, channel_number, addr, remote_ufrag);
1226     entries_.push_back(entry);
1227     return true;
1228   } else {
1229     if (entry->destruction_timestamp()) {
1230       // Destruction should have only been scheduled (indicated by
1231       // destruction_timestamp being set) if there were no connections using
1232       // this address.
1233       RTC_DCHECK(!GetConnection(addr));
1234       // Resetting the destruction timestamp will ensure that any queued
1235       // destruction tasks, when executed, will see that the timestamp doesn't
1236       // match and do nothing. We do this because (currently) there's not a
1237       // convenient way to cancel queued tasks.
1238       entry->reset_destruction_timestamp();
1239     } else {
1240       // The only valid reason for destruction not being scheduled is that
1241       // there's still one connection.
1242       RTC_DCHECK(GetConnection(addr));
1243     }
1244 
1245     if (webrtc::field_trial::IsEnabled("WebRTC-TurnAddMultiMapping")) {
1246       if (entry->get_remote_ufrag() != remote_ufrag) {
1247         RTC_LOG(LS_INFO) << ToString()
1248                          << ": remote ufrag updated."
1249                             " Sending new permission request";
1250         entry->set_remote_ufrag(remote_ufrag);
1251         entry->SendCreatePermissionRequest(0);
1252       }
1253     }
1254   }
1255   return false;
1256 }
1257 
DestroyEntry(TurnEntry * entry)1258 void TurnPort::DestroyEntry(TurnEntry* entry) {
1259   RTC_DCHECK(entry != NULL);
1260   entry->SignalDestroyed(entry);
1261   entries_.remove(entry);
1262   delete entry;
1263 }
1264 
DestroyEntryIfNotCancelled(TurnEntry * entry,int64_t timestamp)1265 void TurnPort::DestroyEntryIfNotCancelled(TurnEntry* entry, int64_t timestamp) {
1266   if (!EntryExists(entry)) {
1267     return;
1268   }
1269   // The destruction timestamp is used to manage pending destructions. Proceed
1270   // with destruction if it's set, and matches the timestamp from the posted
1271   // task. Note that CreateOrRefreshEntry will unset the timestamp, canceling
1272   // destruction.
1273   if (entry->destruction_timestamp() &&
1274       timestamp == *entry->destruction_timestamp()) {
1275     DestroyEntry(entry);
1276   }
1277 }
1278 
HandleConnectionDestroyed(Connection * conn)1279 void TurnPort::HandleConnectionDestroyed(Connection* conn) {
1280   // Schedule an event to destroy TurnEntry for the connection, which is
1281   // already destroyed.
1282   const rtc::SocketAddress& remote_address = conn->remote_candidate().address();
1283   TurnEntry* entry = FindEntry(remote_address);
1284   RTC_DCHECK(entry != NULL);
1285   ScheduleEntryDestruction(entry);
1286 }
1287 
ScheduleEntryDestruction(TurnEntry * entry)1288 void TurnPort::ScheduleEntryDestruction(TurnEntry* entry) {
1289   RTC_DCHECK(!entry->destruction_timestamp().has_value());
1290   int64_t timestamp = rtc::TimeMillis();
1291   entry->set_destruction_timestamp(timestamp);
1292   thread()->PostDelayedTask(ToQueuedTask(task_safety_.flag(),
1293                                          [this, entry, timestamp] {
1294                                            DestroyEntryIfNotCancelled(
1295                                                entry, timestamp);
1296                                          }),
1297                             TURN_PERMISSION_TIMEOUT);
1298 }
1299 
SetEntryChannelId(const rtc::SocketAddress & address,int channel_id)1300 bool TurnPort::SetEntryChannelId(const rtc::SocketAddress& address,
1301                                  int channel_id) {
1302   TurnEntry* entry = FindEntry(address);
1303   if (!entry) {
1304     return false;
1305   }
1306   entry->set_channel_id(channel_id);
1307   return true;
1308 }
1309 
ReconstructedServerUrl(bool use_hostname)1310 std::string TurnPort::ReconstructedServerUrl(bool use_hostname) {
1311   // draft-petithuguenin-behave-turn-uris-01
1312   // turnURI       = scheme ":" turn-host [ ":" turn-port ]
1313   //                 [ "?transport=" transport ]
1314   // scheme        = "turn" / "turns"
1315   // transport     = "udp" / "tcp" / transport-ext
1316   // transport-ext = 1*unreserved
1317   // turn-host     = IP-literal / IPv4address / reg-name
1318   // turn-port     = *DIGIT
1319   std::string scheme = "turn";
1320   std::string transport = "tcp";
1321   switch (server_address_.proto) {
1322     case PROTO_SSLTCP:
1323     case PROTO_TLS:
1324       scheme = "turns";
1325       break;
1326     case PROTO_UDP:
1327       transport = "udp";
1328       break;
1329     case PROTO_TCP:
1330       break;
1331   }
1332   rtc::StringBuilder url;
1333   url << scheme << ":"
1334       << (use_hostname ? server_address_.address.hostname()
1335                        : server_address_.address.ipaddr().ToString())
1336       << ":" << server_address_.address.port() << "?transport=" << transport;
1337   return url.Release();
1338 }
1339 
TurnCustomizerMaybeModifyOutgoingStunMessage(StunMessage * message)1340 void TurnPort::TurnCustomizerMaybeModifyOutgoingStunMessage(
1341     StunMessage* message) {
1342   if (turn_customizer_ == nullptr) {
1343     return;
1344   }
1345 
1346   turn_customizer_->MaybeModifyOutgoingStunMessage(this, message);
1347 }
1348 
TurnCustomizerAllowChannelData(const void * data,size_t size,bool payload)1349 bool TurnPort::TurnCustomizerAllowChannelData(const void* data,
1350                                               size_t size,
1351                                               bool payload) {
1352   if (turn_customizer_ == nullptr) {
1353     return true;
1354   }
1355 
1356   return turn_customizer_->AllowChannelData(this, data, size, payload);
1357 }
1358 
MaybeAddTurnLoggingId(StunMessage * msg)1359 void TurnPort::MaybeAddTurnLoggingId(StunMessage* msg) {
1360   if (!turn_logging_id_.empty()) {
1361     msg->AddAttribute(std::make_unique<StunByteStringAttribute>(
1362         STUN_ATTR_TURN_LOGGING_ID, turn_logging_id_));
1363   }
1364 }
1365 
TurnAllocateRequest(TurnPort * port)1366 TurnAllocateRequest::TurnAllocateRequest(TurnPort* port)
1367     : StunRequest(new TurnMessage()), port_(port) {}
1368 
Prepare(StunMessage * request)1369 void TurnAllocateRequest::Prepare(StunMessage* request) {
1370   // Create the request as indicated in RFC 5766, Section 6.1.
1371   request->SetType(TURN_ALLOCATE_REQUEST);
1372   auto transport_attr =
1373       StunAttribute::CreateUInt32(STUN_ATTR_REQUESTED_TRANSPORT);
1374   transport_attr->SetValue(IPPROTO_UDP << 24);
1375   request->AddAttribute(std::move(transport_attr));
1376   if (!port_->hash().empty()) {
1377     port_->AddRequestAuthInfo(request);
1378   }
1379   port_->MaybeAddTurnLoggingId(request);
1380   port_->TurnCustomizerMaybeModifyOutgoingStunMessage(request);
1381 }
1382 
OnSent()1383 void TurnAllocateRequest::OnSent() {
1384   RTC_LOG(LS_INFO) << port_->ToString() << ": TURN allocate request sent, id="
1385                    << rtc::hex_encode(id());
1386   StunRequest::OnSent();
1387 }
1388 
OnResponse(StunMessage * response)1389 void TurnAllocateRequest::OnResponse(StunMessage* response) {
1390   RTC_LOG(LS_INFO) << port_->ToString()
1391                    << ": TURN allocate requested successfully, id="
1392                    << rtc::hex_encode(id())
1393                    << ", code=0"  // Makes logging easier to parse.
1394                       ", rtt="
1395                    << Elapsed();
1396 
1397   // Check mandatory attributes as indicated in RFC5766, Section 6.3.
1398   const StunAddressAttribute* mapped_attr =
1399       response->GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS);
1400   if (!mapped_attr) {
1401     RTC_LOG(LS_WARNING) << port_->ToString()
1402                         << ": Missing STUN_ATTR_XOR_MAPPED_ADDRESS "
1403                            "attribute in allocate success response";
1404     return;
1405   }
1406   // Using XOR-Mapped-Address for stun.
1407   port_->OnStunAddress(mapped_attr->GetAddress());
1408 
1409   const StunAddressAttribute* relayed_attr =
1410       response->GetAddress(STUN_ATTR_XOR_RELAYED_ADDRESS);
1411   if (!relayed_attr) {
1412     RTC_LOG(LS_WARNING) << port_->ToString()
1413                         << ": Missing STUN_ATTR_XOR_RELAYED_ADDRESS "
1414                            "attribute in allocate success response";
1415     return;
1416   }
1417 
1418   const StunUInt32Attribute* lifetime_attr =
1419       response->GetUInt32(STUN_ATTR_TURN_LIFETIME);
1420   if (!lifetime_attr) {
1421     RTC_LOG(LS_WARNING) << port_->ToString()
1422                         << ": Missing STUN_ATTR_TURN_LIFETIME attribute in "
1423                            "allocate success response";
1424     return;
1425   }
1426   // Notify the port the allocate succeeded, and schedule a refresh request.
1427   port_->OnAllocateSuccess(relayed_attr->GetAddress(),
1428                            mapped_attr->GetAddress());
1429   port_->ScheduleRefresh(lifetime_attr->value());
1430 }
1431 
OnErrorResponse(StunMessage * response)1432 void TurnAllocateRequest::OnErrorResponse(StunMessage* response) {
1433   // Process error response according to RFC5766, Section 6.4.
1434   int error_code = response->GetErrorCodeValue();
1435 
1436   RTC_LOG(LS_INFO) << port_->ToString()
1437                    << ": Received TURN allocate error response, id="
1438                    << rtc::hex_encode(id()) << ", code=" << error_code
1439                    << ", rtt=" << Elapsed();
1440 
1441   switch (error_code) {
1442     case STUN_ERROR_UNAUTHORIZED:  // Unauthrorized.
1443       OnAuthChallenge(response, error_code);
1444       break;
1445     case STUN_ERROR_TRY_ALTERNATE:
1446       OnTryAlternate(response, error_code);
1447       break;
1448     case STUN_ERROR_ALLOCATION_MISMATCH:
1449       // We must handle this error async because trying to delete the socket in
1450       // OnErrorResponse will cause a deadlock on the socket.
1451       port_->thread()->Post(RTC_FROM_HERE, port_,
1452                             TurnPort::MSG_ALLOCATE_MISMATCH);
1453       break;
1454     default:
1455       RTC_LOG(LS_WARNING) << port_->ToString()
1456                           << ": Received TURN allocate error response, id="
1457                           << rtc::hex_encode(id()) << ", code=" << error_code
1458                           << ", rtt=" << Elapsed();
1459       const StunErrorCodeAttribute* attr = response->GetErrorCode();
1460       port_->OnAllocateError(error_code, attr ? attr->reason() : "");
1461   }
1462 }
1463 
OnTimeout()1464 void TurnAllocateRequest::OnTimeout() {
1465   RTC_LOG(LS_WARNING) << port_->ToString() << ": TURN allocate request "
1466                       << rtc::hex_encode(id()) << " timeout";
1467   port_->OnAllocateRequestTimeout();
1468 }
1469 
OnAuthChallenge(StunMessage * response,int code)1470 void TurnAllocateRequest::OnAuthChallenge(StunMessage* response, int code) {
1471   // If we failed to authenticate even after we sent our credentials, fail hard.
1472   if (code == STUN_ERROR_UNAUTHORIZED && !port_->hash().empty()) {
1473     RTC_LOG(LS_WARNING) << port_->ToString()
1474                         << ": Failed to authenticate with the server "
1475                            "after challenge.";
1476     const StunErrorCodeAttribute* attr = response->GetErrorCode();
1477     port_->OnAllocateError(STUN_ERROR_UNAUTHORIZED, attr ? attr->reason() : "");
1478     return;
1479   }
1480 
1481   // Check the mandatory attributes.
1482   const StunByteStringAttribute* realm_attr =
1483       response->GetByteString(STUN_ATTR_REALM);
1484   if (!realm_attr) {
1485     RTC_LOG(LS_WARNING) << port_->ToString()
1486                         << ": Missing STUN_ATTR_REALM attribute in "
1487                            "allocate unauthorized response.";
1488     return;
1489   }
1490   port_->set_realm(realm_attr->GetString());
1491 
1492   const StunByteStringAttribute* nonce_attr =
1493       response->GetByteString(STUN_ATTR_NONCE);
1494   if (!nonce_attr) {
1495     RTC_LOG(LS_WARNING) << port_->ToString()
1496                         << ": Missing STUN_ATTR_NONCE attribute in "
1497                            "allocate unauthorized response.";
1498     return;
1499   }
1500   port_->set_nonce(nonce_attr->GetString());
1501 
1502   // Send another allocate request, with the received realm and nonce values.
1503   port_->SendRequest(new TurnAllocateRequest(port_), 0);
1504 }
1505 
OnTryAlternate(StunMessage * response,int code)1506 void TurnAllocateRequest::OnTryAlternate(StunMessage* response, int code) {
1507   // According to RFC 5389 section 11, there are use cases where
1508   // authentication of response is not possible, we're not validating
1509   // message integrity.
1510   const StunErrorCodeAttribute* error_code_attr = response->GetErrorCode();
1511   // Get the alternate server address attribute value.
1512   const StunAddressAttribute* alternate_server_attr =
1513       response->GetAddress(STUN_ATTR_ALTERNATE_SERVER);
1514   if (!alternate_server_attr) {
1515     RTC_LOG(LS_WARNING) << port_->ToString()
1516                         << ": Missing STUN_ATTR_ALTERNATE_SERVER "
1517                            "attribute in try alternate error response";
1518     port_->OnAllocateError(STUN_ERROR_TRY_ALTERNATE,
1519                            error_code_attr ? error_code_attr->reason() : "");
1520     return;
1521   }
1522   if (!port_->SetAlternateServer(alternate_server_attr->GetAddress())) {
1523     port_->OnAllocateError(STUN_ERROR_TRY_ALTERNATE,
1524                            error_code_attr ? error_code_attr->reason() : "");
1525     return;
1526   }
1527 
1528   // Check the attributes.
1529   const StunByteStringAttribute* realm_attr =
1530       response->GetByteString(STUN_ATTR_REALM);
1531   if (realm_attr) {
1532     RTC_LOG(LS_INFO) << port_->ToString()
1533                      << ": Applying STUN_ATTR_REALM attribute in "
1534                         "try alternate error response.";
1535     port_->set_realm(realm_attr->GetString());
1536   }
1537 
1538   const StunByteStringAttribute* nonce_attr =
1539       response->GetByteString(STUN_ATTR_NONCE);
1540   if (nonce_attr) {
1541     RTC_LOG(LS_INFO) << port_->ToString()
1542                      << ": Applying STUN_ATTR_NONCE attribute in "
1543                         "try alternate error response.";
1544     port_->set_nonce(nonce_attr->GetString());
1545   }
1546 
1547   // For TCP, we can't close the original Tcp socket during handling a 300 as
1548   // we're still inside that socket's event handler. Doing so will cause
1549   // deadlock.
1550   port_->thread()->Post(RTC_FROM_HERE, port_,
1551                         TurnPort::MSG_TRY_ALTERNATE_SERVER);
1552 }
1553 
TurnRefreshRequest(TurnPort * port)1554 TurnRefreshRequest::TurnRefreshRequest(TurnPort* port)
1555     : StunRequest(new TurnMessage()), port_(port), lifetime_(-1) {}
1556 
Prepare(StunMessage * request)1557 void TurnRefreshRequest::Prepare(StunMessage* request) {
1558   // Create the request as indicated in RFC 5766, Section 7.1.
1559   // No attributes need to be included.
1560   request->SetType(TURN_REFRESH_REQUEST);
1561   if (lifetime_ > -1) {
1562     request->AddAttribute(
1563         std::make_unique<StunUInt32Attribute>(STUN_ATTR_LIFETIME, lifetime_));
1564   }
1565 
1566   port_->AddRequestAuthInfo(request);
1567   port_->TurnCustomizerMaybeModifyOutgoingStunMessage(request);
1568 }
1569 
OnSent()1570 void TurnRefreshRequest::OnSent() {
1571   RTC_LOG(LS_INFO) << port_->ToString() << ": TURN refresh request sent, id="
1572                    << rtc::hex_encode(id());
1573   StunRequest::OnSent();
1574 }
1575 
OnResponse(StunMessage * response)1576 void TurnRefreshRequest::OnResponse(StunMessage* response) {
1577   RTC_LOG(LS_INFO) << port_->ToString()
1578                    << ": TURN refresh requested successfully, id="
1579                    << rtc::hex_encode(id())
1580                    << ", code=0"  // Makes logging easier to parse.
1581                       ", rtt="
1582                    << Elapsed();
1583 
1584   // Check mandatory attributes as indicated in RFC5766, Section 7.3.
1585   const StunUInt32Attribute* lifetime_attr =
1586       response->GetUInt32(STUN_ATTR_TURN_LIFETIME);
1587   if (!lifetime_attr) {
1588     RTC_LOG(LS_WARNING) << port_->ToString()
1589                         << ": Missing STUN_ATTR_TURN_LIFETIME attribute in "
1590                            "refresh success response.";
1591     return;
1592   }
1593 
1594   if (lifetime_attr->value() > 0) {
1595     // Schedule a refresh based on the returned lifetime value.
1596     port_->ScheduleRefresh(lifetime_attr->value());
1597   } else {
1598     // If we scheduled a refresh with lifetime 0, we're releasing this
1599     // allocation; see TurnPort::Release.
1600     port_->thread()->Post(RTC_FROM_HERE, port_,
1601                           TurnPort::MSG_ALLOCATION_RELEASED);
1602   }
1603 
1604   port_->SignalTurnRefreshResult(port_, TURN_SUCCESS_RESULT_CODE);
1605 }
1606 
OnErrorResponse(StunMessage * response)1607 void TurnRefreshRequest::OnErrorResponse(StunMessage* response) {
1608   int error_code = response->GetErrorCodeValue();
1609 
1610   if (error_code == STUN_ERROR_STALE_NONCE) {
1611     if (port_->UpdateNonce(response)) {
1612       // Send RefreshRequest immediately.
1613       port_->SendRequest(new TurnRefreshRequest(port_), 0);
1614     }
1615   } else {
1616     RTC_LOG(LS_WARNING) << port_->ToString()
1617                         << ": Received TURN refresh error response, id="
1618                         << rtc::hex_encode(id()) << ", code=" << error_code
1619                         << ", rtt=" << Elapsed();
1620     port_->OnRefreshError();
1621     port_->SignalTurnRefreshResult(port_, error_code);
1622   }
1623 }
1624 
OnTimeout()1625 void TurnRefreshRequest::OnTimeout() {
1626   RTC_LOG(LS_WARNING) << port_->ToString() << ": TURN refresh timeout "
1627                       << rtc::hex_encode(id());
1628   port_->OnRefreshError();
1629 }
1630 
TurnCreatePermissionRequest(TurnPort * port,TurnEntry * entry,const rtc::SocketAddress & ext_addr,const std::string & remote_ufrag)1631 TurnCreatePermissionRequest::TurnCreatePermissionRequest(
1632     TurnPort* port,
1633     TurnEntry* entry,
1634     const rtc::SocketAddress& ext_addr,
1635     const std::string& remote_ufrag)
1636     : StunRequest(new TurnMessage()),
1637       port_(port),
1638       entry_(entry),
1639       ext_addr_(ext_addr),
1640       remote_ufrag_(remote_ufrag) {
1641   entry_->SignalDestroyed.connect(
1642       this, &TurnCreatePermissionRequest::OnEntryDestroyed);
1643 }
1644 
Prepare(StunMessage * request)1645 void TurnCreatePermissionRequest::Prepare(StunMessage* request) {
1646   // Create the request as indicated in RFC5766, Section 9.1.
1647   request->SetType(TURN_CREATE_PERMISSION_REQUEST);
1648   request->AddAttribute(std::make_unique<StunXorAddressAttribute>(
1649       STUN_ATTR_XOR_PEER_ADDRESS, ext_addr_));
1650   if (webrtc::field_trial::IsEnabled("WebRTC-TurnAddMultiMapping")) {
1651     request->AddAttribute(std::make_unique<cricket::StunByteStringAttribute>(
1652         STUN_ATTR_MULTI_MAPPING, remote_ufrag_));
1653   }
1654   port_->AddRequestAuthInfo(request);
1655   port_->TurnCustomizerMaybeModifyOutgoingStunMessage(request);
1656 }
1657 
OnSent()1658 void TurnCreatePermissionRequest::OnSent() {
1659   RTC_LOG(LS_INFO) << port_->ToString()
1660                    << ": TURN create permission request sent, id="
1661                    << rtc::hex_encode(id());
1662   StunRequest::OnSent();
1663 }
1664 
OnResponse(StunMessage * response)1665 void TurnCreatePermissionRequest::OnResponse(StunMessage* response) {
1666   RTC_LOG(LS_INFO) << port_->ToString()
1667                    << ": TURN permission requested successfully, id="
1668                    << rtc::hex_encode(id())
1669                    << ", code=0"  // Makes logging easier to parse.
1670                       ", rtt="
1671                    << Elapsed();
1672 
1673   if (entry_) {
1674     entry_->OnCreatePermissionSuccess();
1675   }
1676 }
1677 
OnErrorResponse(StunMessage * response)1678 void TurnCreatePermissionRequest::OnErrorResponse(StunMessage* response) {
1679   int error_code = response->GetErrorCodeValue();
1680   RTC_LOG(LS_WARNING) << port_->ToString()
1681                       << ": Received TURN create permission error response, id="
1682                       << rtc::hex_encode(id()) << ", code=" << error_code
1683                       << ", rtt=" << Elapsed();
1684   if (entry_) {
1685     entry_->OnCreatePermissionError(response, error_code);
1686   }
1687 }
1688 
OnTimeout()1689 void TurnCreatePermissionRequest::OnTimeout() {
1690   RTC_LOG(LS_WARNING) << port_->ToString()
1691                       << ": TURN create permission timeout "
1692                       << rtc::hex_encode(id());
1693   if (entry_) {
1694     entry_->OnCreatePermissionTimeout();
1695   }
1696 }
1697 
OnEntryDestroyed(TurnEntry * entry)1698 void TurnCreatePermissionRequest::OnEntryDestroyed(TurnEntry* entry) {
1699   RTC_DCHECK(entry_ == entry);
1700   entry_ = NULL;
1701 }
1702 
TurnChannelBindRequest(TurnPort * port,TurnEntry * entry,int channel_id,const rtc::SocketAddress & ext_addr)1703 TurnChannelBindRequest::TurnChannelBindRequest(
1704     TurnPort* port,
1705     TurnEntry* entry,
1706     int channel_id,
1707     const rtc::SocketAddress& ext_addr)
1708     : StunRequest(new TurnMessage()),
1709       port_(port),
1710       entry_(entry),
1711       channel_id_(channel_id),
1712       ext_addr_(ext_addr) {
1713   entry_->SignalDestroyed.connect(this,
1714                                   &TurnChannelBindRequest::OnEntryDestroyed);
1715 }
1716 
Prepare(StunMessage * request)1717 void TurnChannelBindRequest::Prepare(StunMessage* request) {
1718   // Create the request as indicated in RFC5766, Section 11.1.
1719   request->SetType(TURN_CHANNEL_BIND_REQUEST);
1720   request->AddAttribute(std::make_unique<StunUInt32Attribute>(
1721       STUN_ATTR_CHANNEL_NUMBER, channel_id_ << 16));
1722   request->AddAttribute(std::make_unique<StunXorAddressAttribute>(
1723       STUN_ATTR_XOR_PEER_ADDRESS, ext_addr_));
1724   port_->AddRequestAuthInfo(request);
1725   port_->TurnCustomizerMaybeModifyOutgoingStunMessage(request);
1726 }
1727 
OnSent()1728 void TurnChannelBindRequest::OnSent() {
1729   RTC_LOG(LS_INFO) << port_->ToString()
1730                    << ": TURN channel bind request sent, id="
1731                    << rtc::hex_encode(id());
1732   StunRequest::OnSent();
1733 }
1734 
OnResponse(StunMessage * response)1735 void TurnChannelBindRequest::OnResponse(StunMessage* response) {
1736   RTC_LOG(LS_INFO) << port_->ToString()
1737                    << ": TURN channel bind requested successfully, id="
1738                    << rtc::hex_encode(id())
1739                    << ", code=0"  // Makes logging easier to parse.
1740                       ", rtt="
1741                    << Elapsed();
1742 
1743   if (entry_) {
1744     entry_->OnChannelBindSuccess();
1745     // Refresh the channel binding just under the permission timeout
1746     // threshold. The channel binding has a longer lifetime, but
1747     // this is the easiest way to keep both the channel and the
1748     // permission from expiring.
1749     int delay = TURN_PERMISSION_TIMEOUT - 60000;
1750     entry_->SendChannelBindRequest(delay);
1751     RTC_LOG(LS_INFO) << port_->ToString() << ": Scheduled channel bind in "
1752                      << delay << "ms.";
1753   }
1754 }
1755 
OnErrorResponse(StunMessage * response)1756 void TurnChannelBindRequest::OnErrorResponse(StunMessage* response) {
1757   int error_code = response->GetErrorCodeValue();
1758   RTC_LOG(LS_WARNING) << port_->ToString()
1759                       << ": Received TURN channel bind error response, id="
1760                       << rtc::hex_encode(id()) << ", code=" << error_code
1761                       << ", rtt=" << Elapsed();
1762   if (entry_) {
1763     entry_->OnChannelBindError(response, error_code);
1764   }
1765 }
1766 
OnTimeout()1767 void TurnChannelBindRequest::OnTimeout() {
1768   RTC_LOG(LS_WARNING) << port_->ToString() << ": TURN channel bind timeout "
1769                       << rtc::hex_encode(id());
1770   if (entry_) {
1771     entry_->OnChannelBindTimeout();
1772   }
1773 }
1774 
OnEntryDestroyed(TurnEntry * entry)1775 void TurnChannelBindRequest::OnEntryDestroyed(TurnEntry* entry) {
1776   RTC_DCHECK(entry_ == entry);
1777   entry_ = NULL;
1778 }
1779 
TurnEntry(TurnPort * port,int channel_id,const rtc::SocketAddress & ext_addr,const std::string remote_ufrag)1780 TurnEntry::TurnEntry(TurnPort* port,
1781                      int channel_id,
1782                      const rtc::SocketAddress& ext_addr,
1783                      const std::string remote_ufrag)
1784     : port_(port),
1785       channel_id_(channel_id),
1786       ext_addr_(ext_addr),
1787       state_(STATE_UNBOUND),
1788       remote_ufrag_(remote_ufrag) {
1789   // Creating permission for |ext_addr_|.
1790   SendCreatePermissionRequest(0);
1791 }
1792 
SendCreatePermissionRequest(int delay)1793 void TurnEntry::SendCreatePermissionRequest(int delay) {
1794   port_->SendRequest(
1795       new TurnCreatePermissionRequest(port_, this, ext_addr_, remote_ufrag_),
1796       delay);
1797 }
1798 
SendChannelBindRequest(int delay)1799 void TurnEntry::SendChannelBindRequest(int delay) {
1800   port_->SendRequest(
1801       new TurnChannelBindRequest(port_, this, channel_id_, ext_addr_), delay);
1802 }
1803 
Send(const void * data,size_t size,bool payload,const rtc::PacketOptions & options)1804 int TurnEntry::Send(const void* data,
1805                     size_t size,
1806                     bool payload,
1807                     const rtc::PacketOptions& options) {
1808   rtc::ByteBufferWriter buf;
1809   if (state_ != STATE_BOUND ||
1810       !port_->TurnCustomizerAllowChannelData(data, size, payload)) {
1811     // If we haven't bound the channel yet, we have to use a Send Indication.
1812     // The turn_customizer_ can also make us use Send Indication.
1813     TurnMessage msg;
1814     msg.SetType(TURN_SEND_INDICATION);
1815     msg.SetTransactionID(rtc::CreateRandomString(kStunTransactionIdLength));
1816     msg.AddAttribute(std::make_unique<StunXorAddressAttribute>(
1817         STUN_ATTR_XOR_PEER_ADDRESS, ext_addr_));
1818     msg.AddAttribute(
1819         std::make_unique<StunByteStringAttribute>(STUN_ATTR_DATA, data, size));
1820 
1821     port_->TurnCustomizerMaybeModifyOutgoingStunMessage(&msg);
1822 
1823     const bool success = msg.Write(&buf);
1824     RTC_DCHECK(success);
1825 
1826     // If we're sending real data, request a channel bind that we can use later.
1827     if (state_ == STATE_UNBOUND && payload) {
1828       SendChannelBindRequest(0);
1829       state_ = STATE_BINDING;
1830     }
1831   } else {
1832     // If the channel is bound, we can send the data as a Channel Message.
1833     buf.WriteUInt16(channel_id_);
1834     buf.WriteUInt16(static_cast<uint16_t>(size));
1835     buf.WriteBytes(reinterpret_cast<const char*>(data), size);
1836   }
1837   rtc::PacketOptions modified_options(options);
1838   modified_options.info_signaled_after_sent.turn_overhead_bytes =
1839       buf.Length() - size;
1840   return port_->Send(buf.Data(), buf.Length(), modified_options);
1841 }
1842 
OnCreatePermissionSuccess()1843 void TurnEntry::OnCreatePermissionSuccess() {
1844   RTC_LOG(LS_INFO) << port_->ToString() << ": Create permission for "
1845                    << ext_addr_.ToSensitiveString() << " succeeded";
1846   port_->SignalCreatePermissionResult(port_, ext_addr_,
1847                                       TURN_SUCCESS_RESULT_CODE);
1848 
1849   // If |state_| is STATE_BOUND, the permission will be refreshed
1850   // by ChannelBindRequest.
1851   if (state_ != STATE_BOUND) {
1852     // Refresh the permission request about 1 minute before the permission
1853     // times out.
1854     int delay = TURN_PERMISSION_TIMEOUT - 60000;
1855     SendCreatePermissionRequest(delay);
1856     RTC_LOG(LS_INFO) << port_->ToString()
1857                      << ": Scheduled create-permission-request in " << delay
1858                      << "ms.";
1859   }
1860 }
1861 
OnCreatePermissionError(StunMessage * response,int code)1862 void TurnEntry::OnCreatePermissionError(StunMessage* response, int code) {
1863   if (code == STUN_ERROR_STALE_NONCE) {
1864     if (port_->UpdateNonce(response)) {
1865       SendCreatePermissionRequest(0);
1866     }
1867   } else {
1868     bool found = port_->FailAndPruneConnection(ext_addr_);
1869     if (found) {
1870       RTC_LOG(LS_ERROR) << "Received TURN CreatePermission error response, "
1871                            "code="
1872                         << code << "; pruned connection.";
1873     }
1874     // Send signal with error code.
1875     port_->SignalCreatePermissionResult(port_, ext_addr_, code);
1876   }
1877 }
1878 
OnCreatePermissionTimeout()1879 void TurnEntry::OnCreatePermissionTimeout() {
1880   port_->FailAndPruneConnection(ext_addr_);
1881 }
1882 
OnChannelBindSuccess()1883 void TurnEntry::OnChannelBindSuccess() {
1884   RTC_LOG(LS_INFO) << port_->ToString() << ": Successful channel bind for "
1885                    << ext_addr_.ToSensitiveString();
1886   RTC_DCHECK(state_ == STATE_BINDING || state_ == STATE_BOUND);
1887   state_ = STATE_BOUND;
1888 }
1889 
OnChannelBindError(StunMessage * response,int code)1890 void TurnEntry::OnChannelBindError(StunMessage* response, int code) {
1891   // If the channel bind fails due to errors other than STATE_NONCE,
1892   // we will fail and prune the connection and rely on ICE restart to
1893   // re-establish a new connection if needed.
1894   if (code == STUN_ERROR_STALE_NONCE) {
1895     if (port_->UpdateNonce(response)) {
1896       // Send channel bind request with fresh nonce.
1897       SendChannelBindRequest(0);
1898     }
1899   } else {
1900     state_ = STATE_UNBOUND;
1901     port_->FailAndPruneConnection(ext_addr_);
1902   }
1903 }
OnChannelBindTimeout()1904 void TurnEntry::OnChannelBindTimeout() {
1905   state_ = STATE_UNBOUND;
1906   port_->FailAndPruneConnection(ext_addr_);
1907 }
1908 }  // namespace cricket
1909