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