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