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