• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright 2012 The WebRTC Project Authors. All rights reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "p2p/base/turn_server.h"
12 
13 #include <algorithm>
14 #include <memory>
15 #include <tuple>  // for std::tie
16 #include <utility>
17 
18 #include "absl/algorithm/container.h"
19 #include "absl/memory/memory.h"
20 #include "absl/strings/string_view.h"
21 #include "api/array_view.h"
22 #include "api/packet_socket_factory.h"
23 #include "api/task_queue/task_queue_base.h"
24 #include "api/transport/stun.h"
25 #include "p2p/base/async_stun_tcp_socket.h"
26 #include "rtc_base/byte_buffer.h"
27 #include "rtc_base/checks.h"
28 #include "rtc_base/helpers.h"
29 #include "rtc_base/logging.h"
30 #include "rtc_base/message_digest.h"
31 #include "rtc_base/socket_adapters.h"
32 #include "rtc_base/strings/string_builder.h"
33 
34 namespace cricket {
35 namespace {
36 using ::webrtc::TimeDelta;
37 
38 // TODO(juberti): Move this all to a future turnmessage.h
39 //  static const int IPPROTO_UDP = 17;
40 constexpr TimeDelta kNonceTimeout = TimeDelta::Minutes(60);
41 constexpr TimeDelta kDefaultAllocationTimeout = TimeDelta::Minutes(10);
42 constexpr TimeDelta kPermissionTimeout = TimeDelta::Minutes(5);
43 constexpr TimeDelta kChannelTimeout = TimeDelta::Minutes(10);
44 
45 constexpr int kMinChannelNumber = 0x4000;
46 constexpr int kMaxChannelNumber = 0x7FFF;
47 
48 constexpr size_t kNonceKeySize = 16;
49 constexpr size_t kNonceSize = 48;
50 
51 constexpr size_t TURN_CHANNEL_HEADER_SIZE = 4U;
52 
53 // TODO(mallinath) - Move these to a common place.
IsTurnChannelData(uint16_t msg_type)54 bool IsTurnChannelData(uint16_t msg_type) {
55   // The first two bits of a channel data message are 0b01.
56   return ((msg_type & 0xC000) == 0x4000);
57 }
58 
59 }  // namespace
60 
GetStunSuccessResponseTypeOrZero(const StunMessage & req)61 int GetStunSuccessResponseTypeOrZero(const StunMessage& req) {
62   const int resp_type = GetStunSuccessResponseType(req.type());
63   return resp_type == -1 ? 0 : resp_type;
64 }
65 
GetStunErrorResponseTypeOrZero(const StunMessage & req)66 int GetStunErrorResponseTypeOrZero(const StunMessage& req) {
67   const int resp_type = GetStunErrorResponseType(req.type());
68   return resp_type == -1 ? 0 : resp_type;
69 }
70 
InitErrorResponse(int code,absl::string_view reason,StunMessage * resp)71 static void InitErrorResponse(int code,
72                               absl::string_view reason,
73                               StunMessage* resp) {
74   resp->AddAttribute(std::make_unique<cricket::StunErrorCodeAttribute>(
75       STUN_ATTR_ERROR_CODE, code, std::string(reason)));
76 }
77 
TurnServer(webrtc::TaskQueueBase * thread)78 TurnServer::TurnServer(webrtc::TaskQueueBase* thread)
79     : thread_(thread),
80       nonce_key_(rtc::CreateRandomString(kNonceKeySize)),
81       auth_hook_(NULL),
82       redirect_hook_(NULL),
83       enable_otu_nonce_(false) {}
84 
~TurnServer()85 TurnServer::~TurnServer() {
86   RTC_DCHECK_RUN_ON(thread_);
87   for (InternalSocketMap::iterator it = server_sockets_.begin();
88        it != server_sockets_.end(); ++it) {
89     rtc::AsyncPacketSocket* socket = it->first;
90     delete socket;
91   }
92 
93   for (ServerSocketMap::iterator it = server_listen_sockets_.begin();
94        it != server_listen_sockets_.end(); ++it) {
95     rtc::Socket* socket = it->first;
96     delete socket;
97   }
98 }
99 
AddInternalSocket(rtc::AsyncPacketSocket * socket,ProtocolType proto)100 void TurnServer::AddInternalSocket(rtc::AsyncPacketSocket* socket,
101                                    ProtocolType proto) {
102   RTC_DCHECK_RUN_ON(thread_);
103   RTC_DCHECK(server_sockets_.end() == server_sockets_.find(socket));
104   server_sockets_[socket] = proto;
105   socket->SignalReadPacket.connect(this, &TurnServer::OnInternalPacket);
106 }
107 
AddInternalServerSocket(rtc::Socket * socket,ProtocolType proto,std::unique_ptr<rtc::SSLAdapterFactory> ssl_adapter_factory)108 void TurnServer::AddInternalServerSocket(
109     rtc::Socket* socket,
110     ProtocolType proto,
111     std::unique_ptr<rtc::SSLAdapterFactory> ssl_adapter_factory) {
112   RTC_DCHECK_RUN_ON(thread_);
113 
114   RTC_DCHECK(server_listen_sockets_.end() ==
115              server_listen_sockets_.find(socket));
116   server_listen_sockets_[socket] = {proto, std::move(ssl_adapter_factory)};
117   socket->SignalReadEvent.connect(this, &TurnServer::OnNewInternalConnection);
118 }
119 
SetExternalSocketFactory(rtc::PacketSocketFactory * factory,const rtc::SocketAddress & external_addr)120 void TurnServer::SetExternalSocketFactory(
121     rtc::PacketSocketFactory* factory,
122     const rtc::SocketAddress& external_addr) {
123   RTC_DCHECK_RUN_ON(thread_);
124   external_socket_factory_.reset(factory);
125   external_addr_ = external_addr;
126 }
127 
OnNewInternalConnection(rtc::Socket * socket)128 void TurnServer::OnNewInternalConnection(rtc::Socket* socket) {
129   RTC_DCHECK_RUN_ON(thread_);
130   RTC_DCHECK(server_listen_sockets_.find(socket) !=
131              server_listen_sockets_.end());
132   AcceptConnection(socket);
133 }
134 
AcceptConnection(rtc::Socket * server_socket)135 void TurnServer::AcceptConnection(rtc::Socket* server_socket) {
136   // Check if someone is trying to connect to us.
137   rtc::SocketAddress accept_addr;
138   rtc::Socket* accepted_socket = server_socket->Accept(&accept_addr);
139   if (accepted_socket != NULL) {
140     const ServerSocketInfo& info = server_listen_sockets_[server_socket];
141     if (info.ssl_adapter_factory) {
142       rtc::SSLAdapter* ssl_adapter =
143           info.ssl_adapter_factory->CreateAdapter(accepted_socket);
144       ssl_adapter->StartSSL("");
145       accepted_socket = ssl_adapter;
146     }
147     cricket::AsyncStunTCPSocket* tcp_socket =
148         new cricket::AsyncStunTCPSocket(accepted_socket);
149 
150     tcp_socket->SubscribeClose(this,
151                                [this](rtc::AsyncPacketSocket* s, int err) {
152                                  OnInternalSocketClose(s, err);
153                                });
154     // Finally add the socket so it can start communicating with the client.
155     AddInternalSocket(tcp_socket, info.proto);
156   }
157 }
158 
OnInternalSocketClose(rtc::AsyncPacketSocket * socket,int err)159 void TurnServer::OnInternalSocketClose(rtc::AsyncPacketSocket* socket,
160                                        int err) {
161   RTC_DCHECK_RUN_ON(thread_);
162   DestroyInternalSocket(socket);
163 }
164 
OnInternalPacket(rtc::AsyncPacketSocket * socket,const char * data,size_t size,const rtc::SocketAddress & addr,const int64_t &)165 void TurnServer::OnInternalPacket(rtc::AsyncPacketSocket* socket,
166                                   const char* data,
167                                   size_t size,
168                                   const rtc::SocketAddress& addr,
169                                   const int64_t& /* packet_time_us */) {
170   RTC_DCHECK_RUN_ON(thread_);
171   // Fail if the packet is too small to even contain a channel header.
172   if (size < TURN_CHANNEL_HEADER_SIZE) {
173     return;
174   }
175   InternalSocketMap::iterator iter = server_sockets_.find(socket);
176   RTC_DCHECK(iter != server_sockets_.end());
177   TurnServerConnection conn(addr, iter->second, socket);
178   uint16_t msg_type = rtc::GetBE16(data);
179   if (!IsTurnChannelData(msg_type)) {
180     // This is a STUN message.
181     HandleStunMessage(&conn, data, size);
182   } else {
183     // This is a channel message; let the allocation handle it.
184     TurnServerAllocation* allocation = FindAllocation(&conn);
185     if (allocation) {
186       allocation->HandleChannelData(data, size);
187     }
188     if (stun_message_observer_ != nullptr) {
189       stun_message_observer_->ReceivedChannelData(data, size);
190     }
191   }
192 }
193 
HandleStunMessage(TurnServerConnection * conn,const char * data,size_t size)194 void TurnServer::HandleStunMessage(TurnServerConnection* conn,
195                                    const char* data,
196                                    size_t size) {
197   TurnMessage msg;
198   rtc::ByteBufferReader buf(data, size);
199   if (!msg.Read(&buf) || (buf.Length() > 0)) {
200     RTC_LOG(LS_WARNING) << "Received invalid STUN message";
201     return;
202   }
203 
204   if (stun_message_observer_ != nullptr) {
205     stun_message_observer_->ReceivedMessage(&msg);
206   }
207 
208   // If it's a STUN binding request, handle that specially.
209   if (msg.type() == STUN_BINDING_REQUEST) {
210     HandleBindingRequest(conn, &msg);
211     return;
212   }
213 
214   if (redirect_hook_ != NULL && msg.type() == STUN_ALLOCATE_REQUEST) {
215     rtc::SocketAddress address;
216     if (redirect_hook_->ShouldRedirect(conn->src(), &address)) {
217       SendErrorResponseWithAlternateServer(conn, &msg, address);
218       return;
219     }
220   }
221 
222   // Look up the key that we'll use to validate the M-I. If we have an
223   // existing allocation, the key will already be cached.
224   TurnServerAllocation* allocation = FindAllocation(conn);
225   std::string key;
226   if (!allocation) {
227     GetKey(&msg, &key);
228   } else {
229     key = allocation->key();
230   }
231 
232   // Ensure the message is authorized; only needed for requests.
233   if (IsStunRequestType(msg.type())) {
234     if (!CheckAuthorization(conn, &msg, data, size, key)) {
235       return;
236     }
237   }
238 
239   if (!allocation && msg.type() == STUN_ALLOCATE_REQUEST) {
240     HandleAllocateRequest(conn, &msg, key);
241   } else if (allocation &&
242              (msg.type() != STUN_ALLOCATE_REQUEST ||
243               msg.transaction_id() == allocation->transaction_id())) {
244     // This is a non-allocate request, or a retransmit of an allocate.
245     // Check that the username matches the previous username used.
246     if (IsStunRequestType(msg.type()) &&
247         msg.GetByteString(STUN_ATTR_USERNAME)->string_view() !=
248             allocation->username()) {
249       SendErrorResponse(conn, &msg, STUN_ERROR_WRONG_CREDENTIALS,
250                         STUN_ERROR_REASON_WRONG_CREDENTIALS);
251       return;
252     }
253     allocation->HandleTurnMessage(&msg);
254   } else {
255     // Allocation mismatch.
256     SendErrorResponse(conn, &msg, STUN_ERROR_ALLOCATION_MISMATCH,
257                       STUN_ERROR_REASON_ALLOCATION_MISMATCH);
258   }
259 }
260 
GetKey(const StunMessage * msg,std::string * key)261 bool TurnServer::GetKey(const StunMessage* msg, std::string* key) {
262   const StunByteStringAttribute* username_attr =
263       msg->GetByteString(STUN_ATTR_USERNAME);
264   if (!username_attr) {
265     return false;
266   }
267 
268   return (auth_hook_ != NULL &&
269           auth_hook_->GetKey(std::string(username_attr->string_view()), realm_,
270                              key));
271 }
272 
CheckAuthorization(TurnServerConnection * conn,StunMessage * msg,const char * data,size_t size,absl::string_view key)273 bool TurnServer::CheckAuthorization(TurnServerConnection* conn,
274                                     StunMessage* msg,
275                                     const char* data,
276                                     size_t size,
277                                     absl::string_view key) {
278   // RFC 5389, 10.2.2.
279   RTC_DCHECK(IsStunRequestType(msg->type()));
280   const StunByteStringAttribute* mi_attr =
281       msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY);
282   const StunByteStringAttribute* username_attr =
283       msg->GetByteString(STUN_ATTR_USERNAME);
284   const StunByteStringAttribute* realm_attr =
285       msg->GetByteString(STUN_ATTR_REALM);
286   const StunByteStringAttribute* nonce_attr =
287       msg->GetByteString(STUN_ATTR_NONCE);
288 
289   // Fail if no MESSAGE_INTEGRITY.
290   if (!mi_attr) {
291     SendErrorResponseWithRealmAndNonce(conn, msg, STUN_ERROR_UNAUTHORIZED,
292                                        STUN_ERROR_REASON_UNAUTHORIZED);
293     return false;
294   }
295 
296   // Fail if there is MESSAGE_INTEGRITY but no username, nonce, or realm.
297   if (!username_attr || !realm_attr || !nonce_attr) {
298     SendErrorResponse(conn, msg, STUN_ERROR_BAD_REQUEST,
299                       STUN_ERROR_REASON_BAD_REQUEST);
300     return false;
301   }
302 
303   // Fail if bad nonce.
304   if (!ValidateNonce(nonce_attr->string_view())) {
305     SendErrorResponseWithRealmAndNonce(conn, msg, STUN_ERROR_STALE_NONCE,
306                                        STUN_ERROR_REASON_STALE_NONCE);
307     return false;
308   }
309 
310   // Fail if bad MESSAGE_INTEGRITY.
311   if (key.empty() || msg->ValidateMessageIntegrity(std::string(key)) !=
312                          StunMessage::IntegrityStatus::kIntegrityOk) {
313     SendErrorResponseWithRealmAndNonce(conn, msg, STUN_ERROR_UNAUTHORIZED,
314                                        STUN_ERROR_REASON_UNAUTHORIZED);
315     return false;
316   }
317 
318   // Fail if one-time-use nonce feature is enabled.
319   TurnServerAllocation* allocation = FindAllocation(conn);
320   if (enable_otu_nonce_ && allocation &&
321       allocation->last_nonce() == nonce_attr->string_view()) {
322     SendErrorResponseWithRealmAndNonce(conn, msg, STUN_ERROR_STALE_NONCE,
323                                        STUN_ERROR_REASON_STALE_NONCE);
324     return false;
325   }
326 
327   if (allocation) {
328     allocation->set_last_nonce(nonce_attr->string_view());
329   }
330   // Success.
331   return true;
332 }
333 
HandleBindingRequest(TurnServerConnection * conn,const StunMessage * req)334 void TurnServer::HandleBindingRequest(TurnServerConnection* conn,
335                                       const StunMessage* req) {
336   StunMessage response(GetStunSuccessResponseTypeOrZero(*req),
337                        req->transaction_id());
338   // Tell the user the address that we received their request from.
339   auto mapped_addr_attr = std::make_unique<StunXorAddressAttribute>(
340       STUN_ATTR_XOR_MAPPED_ADDRESS, conn->src());
341   response.AddAttribute(std::move(mapped_addr_attr));
342 
343   SendStun(conn, &response);
344 }
345 
HandleAllocateRequest(TurnServerConnection * conn,const TurnMessage * msg,absl::string_view key)346 void TurnServer::HandleAllocateRequest(TurnServerConnection* conn,
347                                        const TurnMessage* msg,
348                                        absl::string_view key) {
349   // Check the parameters in the request.
350   const StunUInt32Attribute* transport_attr =
351       msg->GetUInt32(STUN_ATTR_REQUESTED_TRANSPORT);
352   if (!transport_attr) {
353     SendErrorResponse(conn, msg, STUN_ERROR_BAD_REQUEST,
354                       STUN_ERROR_REASON_BAD_REQUEST);
355     return;
356   }
357 
358   // Only UDP is supported right now.
359   int proto = transport_attr->value() >> 24;
360   if (proto != IPPROTO_UDP) {
361     SendErrorResponse(conn, msg, STUN_ERROR_UNSUPPORTED_PROTOCOL,
362                       STUN_ERROR_REASON_UNSUPPORTED_PROTOCOL);
363     return;
364   }
365 
366   // Create the allocation and let it send the success response.
367   // If the actual socket allocation fails, send an internal error.
368   TurnServerAllocation* alloc = CreateAllocation(conn, proto, key);
369   if (alloc) {
370     alloc->HandleTurnMessage(msg);
371   } else {
372     SendErrorResponse(conn, msg, STUN_ERROR_SERVER_ERROR,
373                       "Failed to allocate socket");
374   }
375 }
376 
GenerateNonce(int64_t now) const377 std::string TurnServer::GenerateNonce(int64_t now) const {
378   // Generate a nonce of the form hex(now + HMAC-MD5(nonce_key_, now))
379   std::string input(reinterpret_cast<const char*>(&now), sizeof(now));
380   std::string nonce = rtc::hex_encode(input);
381   nonce += rtc::ComputeHmac(rtc::DIGEST_MD5, nonce_key_, input);
382   RTC_DCHECK(nonce.size() == kNonceSize);
383 
384   return nonce;
385 }
386 
ValidateNonce(absl::string_view nonce) const387 bool TurnServer::ValidateNonce(absl::string_view nonce) const {
388   // Check the size.
389   if (nonce.size() != kNonceSize) {
390     return false;
391   }
392 
393   // Decode the timestamp.
394   int64_t then;
395   char* p = reinterpret_cast<char*>(&then);
396   size_t len = rtc::hex_decode(rtc::ArrayView<char>(p, sizeof(then)),
397                                nonce.substr(0, sizeof(then) * 2));
398   if (len != sizeof(then)) {
399     return false;
400   }
401 
402   // Verify the HMAC.
403   if (nonce.substr(sizeof(then) * 2) !=
404       rtc::ComputeHmac(rtc::DIGEST_MD5, nonce_key_,
405                        std::string(p, sizeof(then)))) {
406     return false;
407   }
408 
409   // Validate the timestamp.
410   return TimeDelta::Millis(rtc::TimeMillis() - then) < kNonceTimeout;
411 }
412 
FindAllocation(TurnServerConnection * conn)413 TurnServerAllocation* TurnServer::FindAllocation(TurnServerConnection* conn) {
414   AllocationMap::const_iterator it = allocations_.find(*conn);
415   return (it != allocations_.end()) ? it->second.get() : nullptr;
416 }
417 
CreateAllocation(TurnServerConnection * conn,int proto,absl::string_view key)418 TurnServerAllocation* TurnServer::CreateAllocation(TurnServerConnection* conn,
419                                                    int proto,
420                                                    absl::string_view key) {
421   rtc::AsyncPacketSocket* external_socket =
422       (external_socket_factory_)
423           ? external_socket_factory_->CreateUdpSocket(external_addr_, 0, 0)
424           : NULL;
425   if (!external_socket) {
426     return NULL;
427   }
428 
429   // The Allocation takes ownership of the socket.
430   TurnServerAllocation* allocation =
431       new TurnServerAllocation(this, thread_, *conn, external_socket, key);
432   allocations_[*conn].reset(allocation);
433   return allocation;
434 }
435 
SendErrorResponse(TurnServerConnection * conn,const StunMessage * req,int code,absl::string_view reason)436 void TurnServer::SendErrorResponse(TurnServerConnection* conn,
437                                    const StunMessage* req,
438                                    int code,
439                                    absl::string_view reason) {
440   RTC_DCHECK_RUN_ON(thread_);
441   TurnMessage resp(GetStunErrorResponseTypeOrZero(*req), req->transaction_id());
442   InitErrorResponse(code, reason, &resp);
443 
444   RTC_LOG(LS_INFO) << "Sending error response, type=" << resp.type()
445                    << ", code=" << code << ", reason=" << reason;
446   SendStun(conn, &resp);
447 }
448 
SendErrorResponseWithRealmAndNonce(TurnServerConnection * conn,const StunMessage * msg,int code,absl::string_view reason)449 void TurnServer::SendErrorResponseWithRealmAndNonce(TurnServerConnection* conn,
450                                                     const StunMessage* msg,
451                                                     int code,
452                                                     absl::string_view reason) {
453   TurnMessage resp(GetStunErrorResponseTypeOrZero(*msg), msg->transaction_id());
454   InitErrorResponse(code, reason, &resp);
455 
456   int64_t timestamp = rtc::TimeMillis();
457   if (ts_for_next_nonce_) {
458     timestamp = ts_for_next_nonce_;
459     ts_for_next_nonce_ = 0;
460   }
461   resp.AddAttribute(std::make_unique<StunByteStringAttribute>(
462       STUN_ATTR_NONCE, GenerateNonce(timestamp)));
463   resp.AddAttribute(
464       std::make_unique<StunByteStringAttribute>(STUN_ATTR_REALM, realm_));
465   SendStun(conn, &resp);
466 }
467 
SendErrorResponseWithAlternateServer(TurnServerConnection * conn,const StunMessage * msg,const rtc::SocketAddress & addr)468 void TurnServer::SendErrorResponseWithAlternateServer(
469     TurnServerConnection* conn,
470     const StunMessage* msg,
471     const rtc::SocketAddress& addr) {
472   TurnMessage resp(GetStunErrorResponseTypeOrZero(*msg), msg->transaction_id());
473   InitErrorResponse(STUN_ERROR_TRY_ALTERNATE,
474                     STUN_ERROR_REASON_TRY_ALTERNATE_SERVER, &resp);
475   resp.AddAttribute(
476       std::make_unique<StunAddressAttribute>(STUN_ATTR_ALTERNATE_SERVER, addr));
477   SendStun(conn, &resp);
478 }
479 
SendStun(TurnServerConnection * conn,StunMessage * msg)480 void TurnServer::SendStun(TurnServerConnection* conn, StunMessage* msg) {
481   RTC_DCHECK_RUN_ON(thread_);
482   rtc::ByteBufferWriter buf;
483   // Add a SOFTWARE attribute if one is set.
484   if (!software_.empty()) {
485     msg->AddAttribute(std::make_unique<StunByteStringAttribute>(
486         STUN_ATTR_SOFTWARE, software_));
487   }
488   msg->Write(&buf);
489   Send(conn, buf);
490 }
491 
Send(TurnServerConnection * conn,const rtc::ByteBufferWriter & buf)492 void TurnServer::Send(TurnServerConnection* conn,
493                       const rtc::ByteBufferWriter& buf) {
494   RTC_DCHECK_RUN_ON(thread_);
495   rtc::PacketOptions options;
496   conn->socket()->SendTo(buf.Data(), buf.Length(), conn->src(), options);
497 }
498 
DestroyAllocation(TurnServerAllocation * allocation)499 void TurnServer::DestroyAllocation(TurnServerAllocation* allocation) {
500   // Removing the internal socket if the connection is not udp.
501   rtc::AsyncPacketSocket* socket = allocation->conn()->socket();
502   InternalSocketMap::iterator iter = server_sockets_.find(socket);
503   // Skip if the socket serving this allocation is UDP, as this will be shared
504   // by all allocations.
505   // Note: We may not find a socket if it's a TCP socket that was closed, and
506   // the allocation is only now timing out.
507   if (iter != server_sockets_.end() && iter->second != cricket::PROTO_UDP) {
508     DestroyInternalSocket(socket);
509   }
510 
511   allocations_.erase(*(allocation->conn()));
512 }
513 
DestroyInternalSocket(rtc::AsyncPacketSocket * socket)514 void TurnServer::DestroyInternalSocket(rtc::AsyncPacketSocket* socket) {
515   InternalSocketMap::iterator iter = server_sockets_.find(socket);
516   if (iter != server_sockets_.end()) {
517     rtc::AsyncPacketSocket* socket = iter->first;
518     socket->UnsubscribeClose(this);
519     socket->SignalReadPacket.disconnect(this);
520     server_sockets_.erase(iter);
521     std::unique_ptr<rtc::AsyncPacketSocket> socket_to_delete =
522         absl::WrapUnique(socket);
523     // We must destroy the socket async to avoid invalidating the sigslot
524     // callback list iterator inside a sigslot callback. (In other words,
525     // deleting an object from within a callback from that object).
526     thread_->PostTask([socket_to_delete = std::move(socket_to_delete)] {});
527   }
528 }
529 
TurnServerConnection(const rtc::SocketAddress & src,ProtocolType proto,rtc::AsyncPacketSocket * socket)530 TurnServerConnection::TurnServerConnection(const rtc::SocketAddress& src,
531                                            ProtocolType proto,
532                                            rtc::AsyncPacketSocket* socket)
533     : src_(src),
534       dst_(socket->GetRemoteAddress()),
535       proto_(proto),
536       socket_(socket) {}
537 
operator ==(const TurnServerConnection & c) const538 bool TurnServerConnection::operator==(const TurnServerConnection& c) const {
539   return src_ == c.src_ && dst_ == c.dst_ && proto_ == c.proto_;
540 }
541 
operator <(const TurnServerConnection & c) const542 bool TurnServerConnection::operator<(const TurnServerConnection& c) const {
543   return std::tie(src_, dst_, proto_) < std::tie(c.src_, c.dst_, c.proto_);
544 }
545 
ToString() const546 std::string TurnServerConnection::ToString() const {
547   const char* const kProtos[] = {"unknown", "udp", "tcp", "ssltcp"};
548   rtc::StringBuilder ost;
549   ost << src_.ToSensitiveString() << "-" << dst_.ToSensitiveString() << ":"
550       << kProtos[proto_];
551   return ost.Release();
552 }
553 
TurnServerAllocation(TurnServer * server,webrtc::TaskQueueBase * thread,const TurnServerConnection & conn,rtc::AsyncPacketSocket * socket,absl::string_view key)554 TurnServerAllocation::TurnServerAllocation(TurnServer* server,
555                                            webrtc::TaskQueueBase* thread,
556                                            const TurnServerConnection& conn,
557                                            rtc::AsyncPacketSocket* socket,
558                                            absl::string_view key)
559     : server_(server),
560       thread_(thread),
561       conn_(conn),
562       external_socket_(socket),
563       key_(key) {
564   external_socket_->SignalReadPacket.connect(
565       this, &TurnServerAllocation::OnExternalPacket);
566 }
567 
~TurnServerAllocation()568 TurnServerAllocation::~TurnServerAllocation() {
569   channels_.clear();
570   perms_.clear();
571   RTC_LOG(LS_INFO) << ToString() << ": Allocation destroyed";
572 }
573 
ToString() const574 std::string TurnServerAllocation::ToString() const {
575   rtc::StringBuilder ost;
576   ost << "Alloc[" << conn_.ToString() << "]";
577   return ost.Release();
578 }
579 
HandleTurnMessage(const TurnMessage * msg)580 void TurnServerAllocation::HandleTurnMessage(const TurnMessage* msg) {
581   RTC_DCHECK(msg != NULL);
582   switch (msg->type()) {
583     case STUN_ALLOCATE_REQUEST:
584       HandleAllocateRequest(msg);
585       break;
586     case TURN_REFRESH_REQUEST:
587       HandleRefreshRequest(msg);
588       break;
589     case TURN_SEND_INDICATION:
590       HandleSendIndication(msg);
591       break;
592     case TURN_CREATE_PERMISSION_REQUEST:
593       HandleCreatePermissionRequest(msg);
594       break;
595     case TURN_CHANNEL_BIND_REQUEST:
596       HandleChannelBindRequest(msg);
597       break;
598     default:
599       // Not sure what to do with this, just eat it.
600       RTC_LOG(LS_WARNING) << ToString()
601                           << ": Invalid TURN message type received: "
602                           << msg->type();
603   }
604 }
605 
HandleAllocateRequest(const TurnMessage * msg)606 void TurnServerAllocation::HandleAllocateRequest(const TurnMessage* msg) {
607   // Copy the important info from the allocate request.
608   transaction_id_ = msg->transaction_id();
609   const StunByteStringAttribute* username_attr =
610       msg->GetByteString(STUN_ATTR_USERNAME);
611   RTC_DCHECK(username_attr != NULL);
612   username_ = std::string(username_attr->string_view());
613 
614   // Figure out the lifetime and start the allocation timer.
615   TimeDelta lifetime = ComputeLifetime(*msg);
616   PostDeleteSelf(lifetime);
617 
618   RTC_LOG(LS_INFO) << ToString() << ": Created allocation with lifetime="
619                    << lifetime.seconds();
620 
621   // We've already validated all the important bits; just send a response here.
622   TurnMessage response(GetStunSuccessResponseTypeOrZero(*msg),
623                        msg->transaction_id());
624 
625   auto mapped_addr_attr = std::make_unique<StunXorAddressAttribute>(
626       STUN_ATTR_XOR_MAPPED_ADDRESS, conn_.src());
627   auto relayed_addr_attr = std::make_unique<StunXorAddressAttribute>(
628       STUN_ATTR_XOR_RELAYED_ADDRESS, external_socket_->GetLocalAddress());
629   auto lifetime_attr = std::make_unique<StunUInt32Attribute>(
630       STUN_ATTR_LIFETIME, lifetime.seconds());
631   response.AddAttribute(std::move(mapped_addr_attr));
632   response.AddAttribute(std::move(relayed_addr_attr));
633   response.AddAttribute(std::move(lifetime_attr));
634 
635   SendResponse(&response);
636 }
637 
HandleRefreshRequest(const TurnMessage * msg)638 void TurnServerAllocation::HandleRefreshRequest(const TurnMessage* msg) {
639   // Figure out the new lifetime.
640   TimeDelta lifetime = ComputeLifetime(*msg);
641 
642   // Reset the expiration timer.
643   safety_.reset();
644   PostDeleteSelf(lifetime);
645 
646   RTC_LOG(LS_INFO) << ToString()
647                    << ": Refreshed allocation, lifetime=" << lifetime.seconds();
648 
649   // Send a success response with a LIFETIME attribute.
650   TurnMessage response(GetStunSuccessResponseTypeOrZero(*msg),
651                        msg->transaction_id());
652 
653   auto lifetime_attr = std::make_unique<StunUInt32Attribute>(
654       STUN_ATTR_LIFETIME, lifetime.seconds());
655   response.AddAttribute(std::move(lifetime_attr));
656 
657   SendResponse(&response);
658 }
659 
HandleSendIndication(const TurnMessage * msg)660 void TurnServerAllocation::HandleSendIndication(const TurnMessage* msg) {
661   // Check mandatory attributes.
662   const StunByteStringAttribute* data_attr = msg->GetByteString(STUN_ATTR_DATA);
663   const StunAddressAttribute* peer_attr =
664       msg->GetAddress(STUN_ATTR_XOR_PEER_ADDRESS);
665   if (!data_attr || !peer_attr) {
666     RTC_LOG(LS_WARNING) << ToString() << ": Received invalid send indication";
667     return;
668   }
669 
670   // If a permission exists, send the data on to the peer.
671   if (HasPermission(peer_attr->GetAddress().ipaddr())) {
672     SendExternal(data_attr->bytes(), data_attr->length(),
673                  peer_attr->GetAddress());
674   } else {
675     RTC_LOG(LS_WARNING) << ToString()
676                         << ": Received send indication without permission"
677                            " peer="
678                         << peer_attr->GetAddress().ToSensitiveString();
679   }
680 }
681 
HandleCreatePermissionRequest(const TurnMessage * msg)682 void TurnServerAllocation::HandleCreatePermissionRequest(
683     const TurnMessage* msg) {
684   // Check mandatory attributes.
685   const StunAddressAttribute* peer_attr =
686       msg->GetAddress(STUN_ATTR_XOR_PEER_ADDRESS);
687   if (!peer_attr) {
688     SendBadRequestResponse(msg);
689     return;
690   }
691 
692   if (server_->reject_private_addresses_ &&
693       rtc::IPIsPrivate(peer_attr->GetAddress().ipaddr())) {
694     SendErrorResponse(msg, STUN_ERROR_FORBIDDEN, STUN_ERROR_REASON_FORBIDDEN);
695     return;
696   }
697 
698   // Add this permission.
699   AddPermission(peer_attr->GetAddress().ipaddr());
700 
701   RTC_LOG(LS_INFO) << ToString() << ": Created permission, peer="
702                    << peer_attr->GetAddress().ToSensitiveString();
703 
704   // Send a success response.
705   TurnMessage response(GetStunSuccessResponseTypeOrZero(*msg),
706                        msg->transaction_id());
707   SendResponse(&response);
708 }
709 
HandleChannelBindRequest(const TurnMessage * msg)710 void TurnServerAllocation::HandleChannelBindRequest(const TurnMessage* msg) {
711   // Check mandatory attributes.
712   const StunUInt32Attribute* channel_attr =
713       msg->GetUInt32(STUN_ATTR_CHANNEL_NUMBER);
714   const StunAddressAttribute* peer_attr =
715       msg->GetAddress(STUN_ATTR_XOR_PEER_ADDRESS);
716   if (!channel_attr || !peer_attr) {
717     SendBadRequestResponse(msg);
718     return;
719   }
720 
721   // Check that channel id is valid.
722   int channel_id = channel_attr->value() >> 16;
723   if (channel_id < kMinChannelNumber || channel_id > kMaxChannelNumber) {
724     SendBadRequestResponse(msg);
725     return;
726   }
727 
728   // Check that this channel id isn't bound to another transport address, and
729   // that this transport address isn't bound to another channel id.
730   auto channel1 = FindChannel(channel_id);
731   auto channel2 = FindChannel(peer_attr->GetAddress());
732   if (channel1 != channel2) {
733     SendBadRequestResponse(msg);
734     return;
735   }
736 
737   // Add or refresh this channel.
738   if (channel1 == channels_.end()) {
739     channel1 = channels_.insert(
740         channels_.end(), {.id = channel_id, .peer = peer_attr->GetAddress()});
741   } else {
742     channel1->pending_delete.reset();
743   }
744   thread_->PostDelayedTask(
745       SafeTask(channel1->pending_delete.flag(),
746                [this, channel1] { channels_.erase(channel1); }),
747       kChannelTimeout);
748 
749   // Channel binds also refresh permissions.
750   AddPermission(peer_attr->GetAddress().ipaddr());
751 
752   RTC_LOG(LS_INFO) << ToString() << ": Bound channel, id=" << channel_id
753                    << ", peer=" << peer_attr->GetAddress().ToSensitiveString();
754 
755   // Send a success response.
756   TurnMessage response(GetStunSuccessResponseTypeOrZero(*msg),
757                        msg->transaction_id());
758   SendResponse(&response);
759 }
760 
HandleChannelData(const char * data,size_t size)761 void TurnServerAllocation::HandleChannelData(const char* data, size_t size) {
762   // Extract the channel number from the data.
763   uint16_t channel_id = rtc::GetBE16(data);
764   auto channel = FindChannel(channel_id);
765   if (channel != channels_.end()) {
766     // Send the data to the peer address.
767     SendExternal(data + TURN_CHANNEL_HEADER_SIZE,
768                  size - TURN_CHANNEL_HEADER_SIZE, channel->peer);
769   } else {
770     RTC_LOG(LS_WARNING) << ToString()
771                         << ": Received channel data for invalid channel, id="
772                         << channel_id;
773   }
774 }
775 
OnExternalPacket(rtc::AsyncPacketSocket * socket,const char * data,size_t size,const rtc::SocketAddress & addr,const int64_t &)776 void TurnServerAllocation::OnExternalPacket(
777     rtc::AsyncPacketSocket* socket,
778     const char* data,
779     size_t size,
780     const rtc::SocketAddress& addr,
781     const int64_t& /* packet_time_us */) {
782   RTC_DCHECK(external_socket_.get() == socket);
783   auto channel = FindChannel(addr);
784   if (channel != channels_.end()) {
785     // There is a channel bound to this address. Send as a channel message.
786     rtc::ByteBufferWriter buf;
787     buf.WriteUInt16(channel->id);
788     buf.WriteUInt16(static_cast<uint16_t>(size));
789     buf.WriteBytes(data, size);
790     server_->Send(&conn_, buf);
791   } else if (!server_->enable_permission_checks_ ||
792              HasPermission(addr.ipaddr())) {
793     // No channel, but a permission exists. Send as a data indication.
794     TurnMessage msg(TURN_DATA_INDICATION);
795     msg.AddAttribute(std::make_unique<StunXorAddressAttribute>(
796         STUN_ATTR_XOR_PEER_ADDRESS, addr));
797     msg.AddAttribute(
798         std::make_unique<StunByteStringAttribute>(STUN_ATTR_DATA, data, size));
799     server_->SendStun(&conn_, &msg);
800   } else {
801     RTC_LOG(LS_WARNING)
802         << ToString() << ": Received external packet without permission, peer="
803         << addr.ToSensitiveString();
804   }
805 }
806 
ComputeLifetime(const TurnMessage & msg)807 TimeDelta TurnServerAllocation::ComputeLifetime(const TurnMessage& msg) {
808   if (const StunUInt32Attribute* attr = msg.GetUInt32(STUN_ATTR_LIFETIME)) {
809     return std::min(TimeDelta::Seconds(static_cast<int>(attr->value())),
810                     kDefaultAllocationTimeout);
811   }
812   return kDefaultAllocationTimeout;
813 }
814 
HasPermission(const rtc::IPAddress & addr)815 bool TurnServerAllocation::HasPermission(const rtc::IPAddress& addr) {
816   return FindPermission(addr) != perms_.end();
817 }
818 
AddPermission(const rtc::IPAddress & addr)819 void TurnServerAllocation::AddPermission(const rtc::IPAddress& addr) {
820   auto perm = FindPermission(addr);
821   if (perm == perms_.end()) {
822     perm = perms_.insert(perms_.end(), {.peer = addr});
823   } else {
824     perm->pending_delete.reset();
825   }
826   thread_->PostDelayedTask(SafeTask(perm->pending_delete.flag(),
827                                     [this, perm] { perms_.erase(perm); }),
828                            kPermissionTimeout);
829 }
830 
831 TurnServerAllocation::PermissionList::iterator
FindPermission(const rtc::IPAddress & addr)832 TurnServerAllocation::FindPermission(const rtc::IPAddress& addr) {
833   return absl::c_find_if(perms_,
834                          [&](const Permission& p) { return p.peer == addr; });
835 }
836 
FindChannel(int channel_id)837 TurnServerAllocation::ChannelList::iterator TurnServerAllocation::FindChannel(
838     int channel_id) {
839   return absl::c_find_if(channels_,
840                          [&](const Channel& c) { return c.id == channel_id; });
841 }
842 
FindChannel(const rtc::SocketAddress & addr)843 TurnServerAllocation::ChannelList::iterator TurnServerAllocation::FindChannel(
844     const rtc::SocketAddress& addr) {
845   return absl::c_find_if(channels_,
846                          [&](const Channel& c) { return c.peer == addr; });
847 }
848 
SendResponse(TurnMessage * msg)849 void TurnServerAllocation::SendResponse(TurnMessage* msg) {
850   // Success responses always have M-I.
851   msg->AddMessageIntegrity(key_);
852   server_->SendStun(&conn_, msg);
853 }
854 
SendBadRequestResponse(const TurnMessage * req)855 void TurnServerAllocation::SendBadRequestResponse(const TurnMessage* req) {
856   SendErrorResponse(req, STUN_ERROR_BAD_REQUEST, STUN_ERROR_REASON_BAD_REQUEST);
857 }
858 
SendErrorResponse(const TurnMessage * req,int code,absl::string_view reason)859 void TurnServerAllocation::SendErrorResponse(const TurnMessage* req,
860                                              int code,
861                                              absl::string_view reason) {
862   server_->SendErrorResponse(&conn_, req, code, reason);
863 }
864 
SendExternal(const void * data,size_t size,const rtc::SocketAddress & peer)865 void TurnServerAllocation::SendExternal(const void* data,
866                                         size_t size,
867                                         const rtc::SocketAddress& peer) {
868   rtc::PacketOptions options;
869   external_socket_->SendTo(data, size, peer, options);
870 }
871 
PostDeleteSelf(TimeDelta delay)872 void TurnServerAllocation::PostDeleteSelf(TimeDelta delay) {
873   auto delete_self = [this] {
874     RTC_DCHECK_RUN_ON(server_->thread_);
875     server_->DestroyAllocation(this);
876   };
877   thread_->PostDelayedTask(SafeTask(safety_.flag(), std::move(delete_self)),
878                            delay);
879 }
880 
881 }  // namespace cricket
882