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. 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 61 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 82 int id() const { return id_; } 83 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 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 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 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 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 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 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 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 167 void TurnServer::OnNewInternalConnection(rtc::AsyncSocket* socket) { 168 ASSERT(server_listen_sockets_.find(socket) != server_listen_sockets_.end()); 169 AcceptConnection(socket); 170 } 171 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 187 void TurnServer::OnInternalSocketClose(rtc::AsyncPacketSocket* socket, 188 int err) { 189 DestroyInternalSocket(socket); 190 } 191 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 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 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 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 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 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 395 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 405 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 430 TurnServerAllocation* TurnServer::FindAllocation(TurnServerConnection* conn) { 431 AllocationMap::const_iterator it = allocations_.find(*conn); 432 return (it != allocations_.end()) ? it->second : NULL; 433 } 434 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 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 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 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 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 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 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 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 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 538 bool TurnServerConnection::operator==(const TurnServerConnection& c) const { 539 return src_ == c.src_ && dst_ == c.dst_ && proto_ == c.proto_; 540 } 541 542 bool TurnServerConnection::operator<(const TurnServerConnection& c) const { 543 return src_ < c.src_ || dst_ < c.dst_ || proto_ < c.proto_; 544 } 545 546 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 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 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 582 std::string TurnServerAllocation::ToString() const { 583 std::ostringstream ost; 584 ost << "Alloc[" << conn_.ToString() << "]"; 585 return ost.str(); 586 } 587 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 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 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 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 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 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 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 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 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 823 bool TurnServerAllocation::HasPermission(const rtc::IPAddress& addr) { 824 return (FindPermission(addr) != NULL); 825 } 826 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 839 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 849 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 859 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 869 void TurnServerAllocation::SendResponse(TurnMessage* msg) { 870 // Success responses always have M-I. 871 msg->AddMessageIntegrity(key_); 872 server_->SendStun(&conn_, msg); 873 } 874 875 void TurnServerAllocation::SendBadRequestResponse(const TurnMessage* req) { 876 SendErrorResponse(req, STUN_ERROR_BAD_REQUEST, STUN_ERROR_REASON_BAD_REQUEST); 877 } 878 879 void TurnServerAllocation::SendErrorResponse(const TurnMessage* req, int code, 880 const std::string& reason) { 881 server_->SendErrorResponse(&conn_, req, code, reason); 882 } 883 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 890 void TurnServerAllocation::OnMessage(rtc::Message* msg) { 891 ASSERT(msg->message_id == MSG_ALLOCATION_TIMEOUT); 892 SignalDestroyed(this); 893 delete this; 894 } 895 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 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 909 TurnServerAllocation::Permission::Permission(rtc::Thread* thread, 910 const rtc::IPAddress& peer) 911 : thread_(thread), peer_(peer) { 912 Refresh(); 913 } 914 915 TurnServerAllocation::Permission::~Permission() { 916 thread_->Clear(this, MSG_ALLOCATION_TIMEOUT); 917 } 918 919 void TurnServerAllocation::Permission::Refresh() { 920 thread_->Clear(this, MSG_ALLOCATION_TIMEOUT); 921 thread_->PostDelayed(kPermissionTimeout, this, MSG_ALLOCATION_TIMEOUT); 922 } 923 924 void TurnServerAllocation::Permission::OnMessage(rtc::Message* msg) { 925 ASSERT(msg->message_id == MSG_ALLOCATION_TIMEOUT); 926 SignalDestroyed(this); 927 delete this; 928 } 929 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 936 TurnServerAllocation::Channel::~Channel() { 937 thread_->Clear(this, MSG_ALLOCATION_TIMEOUT); 938 } 939 940 void TurnServerAllocation::Channel::Refresh() { 941 thread_->Clear(this, MSG_ALLOCATION_TIMEOUT); 942 thread_->PostDelayed(kChannelTimeout, this, MSG_ALLOCATION_TIMEOUT); 943 } 944 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