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