1 /* 2 * libjingle 3 * Copyright 2012, Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #include "talk/p2p/base/turnport.h" 29 30 #include <functional> 31 32 #include "talk/base/asyncpacketsocket.h" 33 #include "talk/base/byteorder.h" 34 #include "talk/base/common.h" 35 #include "talk/base/logging.h" 36 #include "talk/base/nethelpers.h" 37 #include "talk/base/socketaddress.h" 38 #include "talk/base/stringencode.h" 39 #include "talk/p2p/base/common.h" 40 #include "talk/p2p/base/stun.h" 41 42 namespace cricket { 43 44 // TODO(juberti): Move to stun.h when relay messages have been renamed. 45 static const int TURN_ALLOCATE_REQUEST = STUN_ALLOCATE_REQUEST; 46 47 // TODO(juberti): Extract to turnmessage.h 48 static const int TURN_DEFAULT_PORT = 3478; 49 static const int TURN_CHANNEL_NUMBER_START = 0x4000; 50 static const int TURN_PERMISSION_TIMEOUT = 5 * 60 * 1000; // 5 minutes 51 52 static const size_t TURN_CHANNEL_HEADER_SIZE = 4U; 53 54 inline bool IsTurnChannelData(uint16 msg_type) { 55 return ((msg_type & 0xC000) == 0x4000); // MSB are 0b01 56 } 57 58 static int GetRelayPreference(cricket::ProtocolType proto, bool secure) { 59 int relay_preference = ICE_TYPE_PREFERENCE_RELAY; 60 if (proto == cricket::PROTO_TCP) { 61 relay_preference -= 1; 62 if (secure) 63 relay_preference -= 1; 64 } 65 66 ASSERT(relay_preference >= 0); 67 return relay_preference; 68 } 69 70 class TurnAllocateRequest : public StunRequest { 71 public: 72 explicit TurnAllocateRequest(TurnPort* port); 73 virtual void Prepare(StunMessage* request); 74 virtual void OnResponse(StunMessage* response); 75 virtual void OnErrorResponse(StunMessage* response); 76 virtual void OnTimeout(); 77 78 private: 79 // Handles authentication challenge from the server. 80 void OnAuthChallenge(StunMessage* response, int code); 81 void OnUnknownAttribute(StunMessage* response); 82 83 TurnPort* port_; 84 }; 85 86 class TurnRefreshRequest : public StunRequest { 87 public: 88 explicit TurnRefreshRequest(TurnPort* port); 89 virtual void Prepare(StunMessage* request); 90 virtual void OnResponse(StunMessage* response); 91 virtual void OnErrorResponse(StunMessage* response); 92 virtual void OnTimeout(); 93 94 private: 95 TurnPort* port_; 96 }; 97 98 class TurnCreatePermissionRequest : public StunRequest, 99 public sigslot::has_slots<> { 100 public: 101 TurnCreatePermissionRequest(TurnPort* port, TurnEntry* entry, 102 const talk_base::SocketAddress& ext_addr); 103 virtual void Prepare(StunMessage* request); 104 virtual void OnResponse(StunMessage* response); 105 virtual void OnErrorResponse(StunMessage* response); 106 virtual void OnTimeout(); 107 108 private: 109 void OnEntryDestroyed(TurnEntry* entry); 110 111 TurnPort* port_; 112 TurnEntry* entry_; 113 talk_base::SocketAddress ext_addr_; 114 }; 115 116 class TurnChannelBindRequest : public StunRequest, 117 public sigslot::has_slots<> { 118 public: 119 TurnChannelBindRequest(TurnPort* port, TurnEntry* entry, int channel_id, 120 const talk_base::SocketAddress& ext_addr); 121 virtual void Prepare(StunMessage* request); 122 virtual void OnResponse(StunMessage* response); 123 virtual void OnErrorResponse(StunMessage* response); 124 virtual void OnTimeout(); 125 126 private: 127 void OnEntryDestroyed(TurnEntry* entry); 128 129 TurnPort* port_; 130 TurnEntry* entry_; 131 int channel_id_; 132 talk_base::SocketAddress ext_addr_; 133 }; 134 135 // Manages a "connection" to a remote destination. We will attempt to bring up 136 // a channel for this remote destination to reduce the overhead of sending data. 137 class TurnEntry : public sigslot::has_slots<> { 138 public: 139 enum BindState { STATE_UNBOUND, STATE_BINDING, STATE_BOUND }; 140 TurnEntry(TurnPort* port, int channel_id, 141 const talk_base::SocketAddress& ext_addr); 142 143 TurnPort* port() { return port_; } 144 145 int channel_id() const { return channel_id_; } 146 const talk_base::SocketAddress& address() const { return ext_addr_; } 147 BindState state() const { return state_; } 148 149 // Helper methods to send permission and channel bind requests. 150 void SendCreatePermissionRequest(); 151 void SendChannelBindRequest(int delay); 152 // Sends a packet to the given destination address. 153 // This will wrap the packet in STUN if necessary. 154 int Send(const void* data, size_t size, bool payload, 155 const talk_base::PacketOptions& options); 156 157 void OnCreatePermissionSuccess(); 158 void OnCreatePermissionError(StunMessage* response, int code); 159 void OnChannelBindSuccess(); 160 void OnChannelBindError(StunMessage* response, int code); 161 // Signal sent when TurnEntry is destroyed. 162 sigslot::signal1<TurnEntry*> SignalDestroyed; 163 164 private: 165 TurnPort* port_; 166 int channel_id_; 167 talk_base::SocketAddress ext_addr_; 168 BindState state_; 169 }; 170 171 TurnPort::TurnPort(talk_base::Thread* thread, 172 talk_base::PacketSocketFactory* factory, 173 talk_base::Network* network, 174 talk_base::AsyncPacketSocket* socket, 175 const std::string& username, 176 const std::string& password, 177 const ProtocolAddress& server_address, 178 const RelayCredentials& credentials) 179 : Port(thread, factory, network, socket->GetLocalAddress().ipaddr(), 180 username, password), 181 server_address_(server_address), 182 credentials_(credentials), 183 socket_(socket), 184 resolver_(NULL), 185 error_(0), 186 request_manager_(thread), 187 next_channel_number_(TURN_CHANNEL_NUMBER_START), 188 connected_(false) { 189 request_manager_.SignalSendPacket.connect(this, &TurnPort::OnSendStunPacket); 190 } 191 192 TurnPort::TurnPort(talk_base::Thread* thread, 193 talk_base::PacketSocketFactory* factory, 194 talk_base::Network* network, 195 const talk_base::IPAddress& ip, 196 int min_port, int max_port, 197 const std::string& username, 198 const std::string& password, 199 const ProtocolAddress& server_address, 200 const RelayCredentials& credentials) 201 : Port(thread, RELAY_PORT_TYPE, factory, network, ip, min_port, max_port, 202 username, password), 203 server_address_(server_address), 204 credentials_(credentials), 205 socket_(NULL), 206 resolver_(NULL), 207 error_(0), 208 request_manager_(thread), 209 next_channel_number_(TURN_CHANNEL_NUMBER_START), 210 connected_(false) { 211 request_manager_.SignalSendPacket.connect(this, &TurnPort::OnSendStunPacket); 212 } 213 214 TurnPort::~TurnPort() { 215 // TODO(juberti): Should this even be necessary? 216 while (!entries_.empty()) { 217 DestroyEntry(entries_.front()->address()); 218 } 219 if (resolver_) { 220 resolver_->Destroy(false); 221 } 222 if (!SharedSocket()) { 223 delete socket_; 224 } 225 } 226 227 void TurnPort::PrepareAddress() { 228 if (credentials_.username.empty() || 229 credentials_.password.empty()) { 230 LOG(LS_ERROR) << "Allocation can't be started without setting the" 231 << " TURN server credentials for the user."; 232 OnAllocateError(); 233 return; 234 } 235 236 if (!server_address_.address.port()) { 237 // We will set default TURN port, if no port is set in the address. 238 server_address_.address.SetPort(TURN_DEFAULT_PORT); 239 } 240 241 if (server_address_.address.IsUnresolved()) { 242 ResolveTurnAddress(server_address_.address); 243 } else { 244 // If protocol family of server address doesn't match with local, return. 245 if (!IsCompatibleAddress(server_address_.address)) { 246 LOG(LS_ERROR) << "Server IP address family does not match with " 247 << "local host address family type"; 248 OnAllocateError(); 249 return; 250 } 251 252 LOG_J(LS_INFO, this) << "Trying to connect to TURN server via " 253 << ProtoToString(server_address_.proto) << " @ " 254 << server_address_.address.ToSensitiveString(); 255 if (server_address_.proto == PROTO_UDP && !SharedSocket()) { 256 socket_ = socket_factory()->CreateUdpSocket( 257 talk_base::SocketAddress(ip(), 0), min_port(), max_port()); 258 } else if (server_address_.proto == PROTO_TCP) { 259 ASSERT(!SharedSocket()); 260 int opts = talk_base::PacketSocketFactory::OPT_STUN; 261 // If secure bit is enabled in server address, use TLS over TCP. 262 if (server_address_.secure) { 263 opts |= talk_base::PacketSocketFactory::OPT_TLS; 264 } 265 socket_ = socket_factory()->CreateClientTcpSocket( 266 talk_base::SocketAddress(ip(), 0), server_address_.address, 267 proxy(), user_agent(), opts); 268 } 269 270 if (!socket_) { 271 OnAllocateError(); 272 return; 273 } 274 275 // Apply options if any. 276 for (SocketOptionsMap::iterator iter = socket_options_.begin(); 277 iter != socket_options_.end(); ++iter) { 278 socket_->SetOption(iter->first, iter->second); 279 } 280 281 if (!SharedSocket()) { 282 // If socket is shared, AllocationSequence will receive the packet. 283 socket_->SignalReadPacket.connect(this, &TurnPort::OnReadPacket); 284 } 285 286 socket_->SignalReadyToSend.connect(this, &TurnPort::OnReadyToSend); 287 288 if (server_address_.proto == PROTO_TCP) { 289 socket_->SignalConnect.connect(this, &TurnPort::OnSocketConnect); 290 socket_->SignalClose.connect(this, &TurnPort::OnSocketClose); 291 } else { 292 // If its UDP, send AllocateRequest now. 293 // For TCP and TLS AllcateRequest will be sent by OnSocketConnect. 294 SendRequest(new TurnAllocateRequest(this), 0); 295 } 296 } 297 } 298 299 void TurnPort::OnSocketConnect(talk_base::AsyncPacketSocket* socket) { 300 ASSERT(server_address_.proto == PROTO_TCP); 301 // Do not use this port if the socket bound to a different address than 302 // the one we asked for. This is seen in Chrome, where TCP sockets cannot be 303 // given a binding address, and the platform is expected to pick the 304 // correct local address. 305 if (socket->GetLocalAddress().ipaddr() != ip()) { 306 LOG(LS_WARNING) << "Socket is bound to a different address then the " 307 << "local port. Discarding TURN port."; 308 OnAllocateError(); 309 return; 310 } 311 312 LOG(LS_INFO) << "TurnPort connected to " << socket->GetRemoteAddress() 313 << " using tcp."; 314 SendRequest(new TurnAllocateRequest(this), 0); 315 } 316 317 void TurnPort::OnSocketClose(talk_base::AsyncPacketSocket* socket, int error) { 318 LOG_J(LS_WARNING, this) << "Connection with server failed, error=" << error; 319 if (!connected_) { 320 OnAllocateError(); 321 } 322 } 323 324 Connection* TurnPort::CreateConnection(const Candidate& address, 325 CandidateOrigin origin) { 326 // TURN-UDP can only connect to UDP candidates. 327 if (address.protocol() != UDP_PROTOCOL_NAME) { 328 return NULL; 329 } 330 331 if (!IsCompatibleAddress(address.address())) { 332 return NULL; 333 } 334 335 // Create an entry, if needed, so we can get our permissions set up correctly. 336 CreateEntry(address.address()); 337 338 // A TURN port will have two candiates, STUN and TURN. STUN may not 339 // present in all cases. If present stun candidate will be added first 340 // and TURN candidate later. 341 for (size_t index = 0; index < Candidates().size(); ++index) { 342 if (Candidates()[index].type() == RELAY_PORT_TYPE) { 343 ProxyConnection* conn = new ProxyConnection(this, index, address); 344 conn->SignalDestroyed.connect(this, &TurnPort::OnConnectionDestroyed); 345 AddConnection(conn); 346 return conn; 347 } 348 } 349 return NULL; 350 } 351 352 int TurnPort::SetOption(talk_base::Socket::Option opt, int value) { 353 if (!socket_) { 354 // If socket is not created yet, these options will be applied during socket 355 // creation. 356 socket_options_[opt] = value; 357 return 0; 358 } 359 return socket_->SetOption(opt, value); 360 } 361 362 int TurnPort::GetOption(talk_base::Socket::Option opt, int* value) { 363 if (!socket_) { 364 SocketOptionsMap::const_iterator it = socket_options_.find(opt); 365 if (it == socket_options_.end()) { 366 return -1; 367 } 368 *value = it->second; 369 return 0; 370 } 371 372 return socket_->GetOption(opt, value); 373 } 374 375 int TurnPort::GetError() { 376 return error_; 377 } 378 379 int TurnPort::SendTo(const void* data, size_t size, 380 const talk_base::SocketAddress& addr, 381 const talk_base::PacketOptions& options, 382 bool payload) { 383 // Try to find an entry for this specific address; we should have one. 384 TurnEntry* entry = FindEntry(addr); 385 ASSERT(entry != NULL); 386 if (!entry) { 387 return 0; 388 } 389 390 if (!connected()) { 391 error_ = EWOULDBLOCK; 392 return SOCKET_ERROR; 393 } 394 395 // Send the actual contents to the server using the usual mechanism. 396 int sent = entry->Send(data, size, payload, options); 397 if (sent <= 0) { 398 return SOCKET_ERROR; 399 } 400 401 // The caller of the function is expecting the number of user data bytes, 402 // rather than the size of the packet. 403 return static_cast<int>(size); 404 } 405 406 void TurnPort::OnReadPacket( 407 talk_base::AsyncPacketSocket* socket, const char* data, size_t size, 408 const talk_base::SocketAddress& remote_addr, 409 const talk_base::PacketTime& packet_time) { 410 ASSERT(socket == socket_); 411 ASSERT(remote_addr == server_address_.address); 412 413 // The message must be at least the size of a channel header. 414 if (size < TURN_CHANNEL_HEADER_SIZE) { 415 LOG_J(LS_WARNING, this) << "Received TURN message that was too short"; 416 return; 417 } 418 419 // Check the message type, to see if is a Channel Data message. 420 // The message will either be channel data, a TURN data indication, or 421 // a response to a previous request. 422 uint16 msg_type = talk_base::GetBE16(data); 423 if (IsTurnChannelData(msg_type)) { 424 HandleChannelData(msg_type, data, size, packet_time); 425 } else if (msg_type == TURN_DATA_INDICATION) { 426 HandleDataIndication(data, size, packet_time); 427 } else { 428 // This must be a response for one of our requests. 429 // Check success responses, but not errors, for MESSAGE-INTEGRITY. 430 if (IsStunSuccessResponseType(msg_type) && 431 !StunMessage::ValidateMessageIntegrity(data, size, hash())) { 432 LOG_J(LS_WARNING, this) << "Received TURN message with invalid " 433 << "message integrity, msg_type=" << msg_type; 434 return; 435 } 436 request_manager_.CheckResponse(data, size); 437 } 438 } 439 440 void TurnPort::OnReadyToSend(talk_base::AsyncPacketSocket* socket) { 441 if (connected_) { 442 Port::OnReadyToSend(); 443 } 444 } 445 446 void TurnPort::ResolveTurnAddress(const talk_base::SocketAddress& address) { 447 if (resolver_) 448 return; 449 450 resolver_ = socket_factory()->CreateAsyncResolver(); 451 resolver_->SignalDone.connect(this, &TurnPort::OnResolveResult); 452 resolver_->Start(address); 453 } 454 455 void TurnPort::OnResolveResult(talk_base::AsyncResolverInterface* resolver) { 456 ASSERT(resolver == resolver_); 457 // Copy the original server address in |resolved_address|. For TLS based 458 // sockets we need hostname along with resolved address. 459 talk_base::SocketAddress resolved_address = server_address_.address; 460 if (resolver_->GetError() != 0 || 461 !resolver_->GetResolvedAddress(ip().family(), &resolved_address)) { 462 LOG_J(LS_WARNING, this) << "TURN host lookup received error " 463 << resolver_->GetError(); 464 OnAllocateError(); 465 return; 466 } 467 // Signal needs both resolved and unresolved address. After signal is sent 468 // we can copy resolved address back into |server_address_|. 469 SignalResolvedServerAddress(this, server_address_.address, 470 resolved_address); 471 server_address_.address = resolved_address; 472 PrepareAddress(); 473 } 474 475 void TurnPort::OnSendStunPacket(const void* data, size_t size, 476 StunRequest* request) { 477 talk_base::PacketOptions options(DefaultDscpValue()); 478 if (Send(data, size, options) < 0) { 479 LOG_J(LS_ERROR, this) << "Failed to send TURN message, err=" 480 << socket_->GetError(); 481 } 482 } 483 484 void TurnPort::OnStunAddress(const talk_base::SocketAddress& address) { 485 // STUN Port will discover STUN candidate, as it's supplied with first TURN 486 // server address. 487 // Why not using this address? - P2PTransportChannel will start creating 488 // connections after first candidate, which means it could start creating the 489 // connections before TURN candidate added. For that to handle, we need to 490 // supply STUN candidate from this port to UDPPort, and TurnPort should have 491 // handle to UDPPort to pass back the address. 492 } 493 494 void TurnPort::OnAllocateSuccess(const talk_base::SocketAddress& address, 495 const talk_base::SocketAddress& stun_address) { 496 connected_ = true; 497 // For relayed candidate, Base is the candidate itself. 498 AddAddress(address, // Candidate address. 499 address, // Base address. 500 stun_address, // Related address. 501 UDP_PROTOCOL_NAME, 502 RELAY_PORT_TYPE, 503 GetRelayPreference(server_address_.proto, server_address_.secure), 504 true); 505 } 506 507 void TurnPort::OnAllocateError() { 508 // We will send SignalPortError asynchronously as this can be sent during 509 // port initialization. This way it will not be blocking other port 510 // creation. 511 thread()->Post(this, MSG_ERROR); 512 } 513 514 void TurnPort::OnMessage(talk_base::Message* message) { 515 if (message->message_id == MSG_ERROR) { 516 SignalPortError(this); 517 return; 518 } 519 520 Port::OnMessage(message); 521 } 522 523 void TurnPort::OnAllocateRequestTimeout() { 524 OnAllocateError(); 525 } 526 527 void TurnPort::HandleDataIndication(const char* data, size_t size, 528 const talk_base::PacketTime& packet_time) { 529 // Read in the message, and process according to RFC5766, Section 10.4. 530 talk_base::ByteBuffer buf(data, size); 531 TurnMessage msg; 532 if (!msg.Read(&buf)) { 533 LOG_J(LS_WARNING, this) << "Received invalid TURN data indication"; 534 return; 535 } 536 537 // Check mandatory attributes. 538 const StunAddressAttribute* addr_attr = 539 msg.GetAddress(STUN_ATTR_XOR_PEER_ADDRESS); 540 if (!addr_attr) { 541 LOG_J(LS_WARNING, this) << "Missing STUN_ATTR_XOR_PEER_ADDRESS attribute " 542 << "in data indication."; 543 return; 544 } 545 546 const StunByteStringAttribute* data_attr = 547 msg.GetByteString(STUN_ATTR_DATA); 548 if (!data_attr) { 549 LOG_J(LS_WARNING, this) << "Missing STUN_ATTR_DATA attribute in " 550 << "data indication."; 551 return; 552 } 553 554 // Verify that the data came from somewhere we think we have a permission for. 555 talk_base::SocketAddress ext_addr(addr_attr->GetAddress()); 556 if (!HasPermission(ext_addr.ipaddr())) { 557 LOG_J(LS_WARNING, this) << "Received TURN data indication with invalid " 558 << "peer address, addr=" 559 << ext_addr.ToSensitiveString(); 560 return; 561 } 562 563 DispatchPacket(data_attr->bytes(), data_attr->length(), ext_addr, 564 PROTO_UDP, packet_time); 565 } 566 567 void TurnPort::HandleChannelData(int channel_id, const char* data, 568 size_t size, 569 const talk_base::PacketTime& packet_time) { 570 // Read the message, and process according to RFC5766, Section 11.6. 571 // 0 1 2 3 572 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 573 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 574 // | Channel Number | Length | 575 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 576 // | | 577 // / Application Data / 578 // / / 579 // | | 580 // | +-------------------------------+ 581 // | | 582 // +-------------------------------+ 583 584 // Extract header fields from the message. 585 uint16 len = talk_base::GetBE16(data + 2); 586 if (len > size - TURN_CHANNEL_HEADER_SIZE) { 587 LOG_J(LS_WARNING, this) << "Received TURN channel data message with " 588 << "incorrect length, len=" << len; 589 return; 590 } 591 // Allowing messages larger than |len|, as ChannelData can be padded. 592 593 TurnEntry* entry = FindEntry(channel_id); 594 if (!entry) { 595 LOG_J(LS_WARNING, this) << "Received TURN channel data message for invalid " 596 << "channel, channel_id=" << channel_id; 597 return; 598 } 599 600 DispatchPacket(data + TURN_CHANNEL_HEADER_SIZE, len, entry->address(), 601 PROTO_UDP, packet_time); 602 } 603 604 void TurnPort::DispatchPacket(const char* data, size_t size, 605 const talk_base::SocketAddress& remote_addr, 606 ProtocolType proto, const talk_base::PacketTime& packet_time) { 607 if (Connection* conn = GetConnection(remote_addr)) { 608 conn->OnReadPacket(data, size, packet_time); 609 } else { 610 Port::OnReadPacket(data, size, remote_addr, proto); 611 } 612 } 613 614 bool TurnPort::ScheduleRefresh(int lifetime) { 615 // Lifetime is in seconds; we schedule a refresh for one minute less. 616 if (lifetime < 2 * 60) { 617 LOG_J(LS_WARNING, this) << "Received response with lifetime that was " 618 << "too short, lifetime=" << lifetime; 619 return false; 620 } 621 622 SendRequest(new TurnRefreshRequest(this), (lifetime - 60) * 1000); 623 return true; 624 } 625 626 void TurnPort::SendRequest(StunRequest* req, int delay) { 627 request_manager_.SendDelayed(req, delay); 628 } 629 630 void TurnPort::AddRequestAuthInfo(StunMessage* msg) { 631 // If we've gotten the necessary data from the server, add it to our request. 632 VERIFY(!hash_.empty()); 633 VERIFY(msg->AddAttribute(new StunByteStringAttribute( 634 STUN_ATTR_USERNAME, credentials_.username))); 635 VERIFY(msg->AddAttribute(new StunByteStringAttribute( 636 STUN_ATTR_REALM, realm_))); 637 VERIFY(msg->AddAttribute(new StunByteStringAttribute( 638 STUN_ATTR_NONCE, nonce_))); 639 VERIFY(msg->AddMessageIntegrity(hash())); 640 } 641 642 int TurnPort::Send(const void* data, size_t len, 643 const talk_base::PacketOptions& options) { 644 return socket_->SendTo(data, len, server_address_.address, options); 645 } 646 647 void TurnPort::UpdateHash() { 648 VERIFY(ComputeStunCredentialHash(credentials_.username, realm_, 649 credentials_.password, &hash_)); 650 } 651 652 bool TurnPort::UpdateNonce(StunMessage* response) { 653 // When stale nonce error received, we should update 654 // hash and store realm and nonce. 655 // Check the mandatory attributes. 656 const StunByteStringAttribute* realm_attr = 657 response->GetByteString(STUN_ATTR_REALM); 658 if (!realm_attr) { 659 LOG(LS_ERROR) << "Missing STUN_ATTR_REALM attribute in " 660 << "stale nonce error response."; 661 return false; 662 } 663 set_realm(realm_attr->GetString()); 664 665 const StunByteStringAttribute* nonce_attr = 666 response->GetByteString(STUN_ATTR_NONCE); 667 if (!nonce_attr) { 668 LOG(LS_ERROR) << "Missing STUN_ATTR_NONCE attribute in " 669 << "stale nonce error response."; 670 return false; 671 } 672 set_nonce(nonce_attr->GetString()); 673 return true; 674 } 675 676 static bool MatchesIP(TurnEntry* e, talk_base::IPAddress ipaddr) { 677 return e->address().ipaddr() == ipaddr; 678 } 679 bool TurnPort::HasPermission(const talk_base::IPAddress& ipaddr) const { 680 return (std::find_if(entries_.begin(), entries_.end(), 681 std::bind2nd(std::ptr_fun(MatchesIP), ipaddr)) != entries_.end()); 682 } 683 684 static bool MatchesAddress(TurnEntry* e, talk_base::SocketAddress addr) { 685 return e->address() == addr; 686 } 687 TurnEntry* TurnPort::FindEntry(const talk_base::SocketAddress& addr) const { 688 EntryList::const_iterator it = std::find_if(entries_.begin(), entries_.end(), 689 std::bind2nd(std::ptr_fun(MatchesAddress), addr)); 690 return (it != entries_.end()) ? *it : NULL; 691 } 692 693 static bool MatchesChannelId(TurnEntry* e, int id) { 694 return e->channel_id() == id; 695 } 696 TurnEntry* TurnPort::FindEntry(int channel_id) const { 697 EntryList::const_iterator it = std::find_if(entries_.begin(), entries_.end(), 698 std::bind2nd(std::ptr_fun(MatchesChannelId), channel_id)); 699 return (it != entries_.end()) ? *it : NULL; 700 } 701 702 TurnEntry* TurnPort::CreateEntry(const talk_base::SocketAddress& addr) { 703 ASSERT(FindEntry(addr) == NULL); 704 TurnEntry* entry = new TurnEntry(this, next_channel_number_++, addr); 705 entries_.push_back(entry); 706 return entry; 707 } 708 709 void TurnPort::DestroyEntry(const talk_base::SocketAddress& addr) { 710 TurnEntry* entry = FindEntry(addr); 711 ASSERT(entry != NULL); 712 entry->SignalDestroyed(entry); 713 entries_.remove(entry); 714 delete entry; 715 } 716 717 void TurnPort::OnConnectionDestroyed(Connection* conn) { 718 // Destroying TurnEntry for the connection, which is already destroyed. 719 DestroyEntry(conn->remote_candidate().address()); 720 } 721 722 TurnAllocateRequest::TurnAllocateRequest(TurnPort* port) 723 : StunRequest(new TurnMessage()), 724 port_(port) { 725 } 726 727 void TurnAllocateRequest::Prepare(StunMessage* request) { 728 // Create the request as indicated in RFC 5766, Section 6.1. 729 request->SetType(TURN_ALLOCATE_REQUEST); 730 StunUInt32Attribute* transport_attr = StunAttribute::CreateUInt32( 731 STUN_ATTR_REQUESTED_TRANSPORT); 732 transport_attr->SetValue(IPPROTO_UDP << 24); 733 VERIFY(request->AddAttribute(transport_attr)); 734 if (!port_->hash().empty()) { 735 port_->AddRequestAuthInfo(request); 736 } 737 } 738 739 void TurnAllocateRequest::OnResponse(StunMessage* response) { 740 // Check mandatory attributes as indicated in RFC5766, Section 6.3. 741 const StunAddressAttribute* mapped_attr = 742 response->GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS); 743 if (!mapped_attr) { 744 LOG_J(LS_WARNING, port_) << "Missing STUN_ATTR_XOR_MAPPED_ADDRESS " 745 << "attribute in allocate success response"; 746 return; 747 } 748 // Using XOR-Mapped-Address for stun. 749 port_->OnStunAddress(mapped_attr->GetAddress()); 750 751 const StunAddressAttribute* relayed_attr = 752 response->GetAddress(STUN_ATTR_XOR_RELAYED_ADDRESS); 753 if (!relayed_attr) { 754 LOG_J(LS_WARNING, port_) << "Missing STUN_ATTR_XOR_RELAYED_ADDRESS " 755 << "attribute in allocate success response"; 756 return; 757 } 758 759 const StunUInt32Attribute* lifetime_attr = 760 response->GetUInt32(STUN_ATTR_TURN_LIFETIME); 761 if (!lifetime_attr) { 762 LOG_J(LS_WARNING, port_) << "Missing STUN_ATTR_TURN_LIFETIME attribute in " 763 << "allocate success response"; 764 return; 765 } 766 // Notify the port the allocate succeeded, and schedule a refresh request. 767 port_->OnAllocateSuccess(relayed_attr->GetAddress(), 768 mapped_attr->GetAddress()); 769 port_->ScheduleRefresh(lifetime_attr->value()); 770 } 771 772 void TurnAllocateRequest::OnErrorResponse(StunMessage* response) { 773 // Process error response according to RFC5766, Section 6.4. 774 const StunErrorCodeAttribute* error_code = response->GetErrorCode(); 775 switch (error_code->code()) { 776 case STUN_ERROR_UNAUTHORIZED: // Unauthrorized. 777 OnAuthChallenge(response, error_code->code()); 778 break; 779 default: 780 LOG_J(LS_WARNING, port_) << "Allocate response error, code=" 781 << error_code->code(); 782 port_->OnAllocateError(); 783 } 784 } 785 786 void TurnAllocateRequest::OnTimeout() { 787 LOG_J(LS_WARNING, port_) << "Allocate request timeout"; 788 port_->OnAllocateRequestTimeout(); 789 } 790 791 void TurnAllocateRequest::OnAuthChallenge(StunMessage* response, int code) { 792 // If we failed to authenticate even after we sent our credentials, fail hard. 793 if (code == STUN_ERROR_UNAUTHORIZED && !port_->hash().empty()) { 794 LOG_J(LS_WARNING, port_) << "Failed to authenticate with the server " 795 << "after challenge."; 796 port_->OnAllocateError(); 797 return; 798 } 799 800 // Check the mandatory attributes. 801 const StunByteStringAttribute* realm_attr = 802 response->GetByteString(STUN_ATTR_REALM); 803 if (!realm_attr) { 804 LOG_J(LS_WARNING, port_) << "Missing STUN_ATTR_REALM attribute in " 805 << "allocate unauthorized response."; 806 return; 807 } 808 port_->set_realm(realm_attr->GetString()); 809 810 const StunByteStringAttribute* nonce_attr = 811 response->GetByteString(STUN_ATTR_NONCE); 812 if (!nonce_attr) { 813 LOG_J(LS_WARNING, port_) << "Missing STUN_ATTR_NONCE attribute in " 814 << "allocate unauthorized response."; 815 return; 816 } 817 port_->set_nonce(nonce_attr->GetString()); 818 819 // Send another allocate request, with the received realm and nonce values. 820 port_->SendRequest(new TurnAllocateRequest(port_), 0); 821 } 822 823 TurnRefreshRequest::TurnRefreshRequest(TurnPort* port) 824 : StunRequest(new TurnMessage()), 825 port_(port) { 826 } 827 828 void TurnRefreshRequest::Prepare(StunMessage* request) { 829 // Create the request as indicated in RFC 5766, Section 7.1. 830 // No attributes need to be included. 831 request->SetType(TURN_REFRESH_REQUEST); 832 port_->AddRequestAuthInfo(request); 833 } 834 835 void TurnRefreshRequest::OnResponse(StunMessage* response) { 836 // Check mandatory attributes as indicated in RFC5766, Section 7.3. 837 const StunUInt32Attribute* lifetime_attr = 838 response->GetUInt32(STUN_ATTR_TURN_LIFETIME); 839 if (!lifetime_attr) { 840 LOG_J(LS_WARNING, port_) << "Missing STUN_ATTR_TURN_LIFETIME attribute in " 841 << "refresh success response."; 842 return; 843 } 844 845 // Schedule a refresh based on the returned lifetime value. 846 port_->ScheduleRefresh(lifetime_attr->value()); 847 } 848 849 void TurnRefreshRequest::OnErrorResponse(StunMessage* response) { 850 // TODO(juberti): Handle 437 error response as a success. 851 const StunErrorCodeAttribute* error_code = response->GetErrorCode(); 852 LOG_J(LS_WARNING, port_) << "Refresh response error, code=" 853 << error_code->code(); 854 855 if (error_code->code() == STUN_ERROR_STALE_NONCE) { 856 if (port_->UpdateNonce(response)) { 857 // Send RefreshRequest immediately. 858 port_->SendRequest(new TurnRefreshRequest(port_), 0); 859 } 860 } 861 } 862 863 void TurnRefreshRequest::OnTimeout() { 864 } 865 866 TurnCreatePermissionRequest::TurnCreatePermissionRequest( 867 TurnPort* port, TurnEntry* entry, 868 const talk_base::SocketAddress& ext_addr) 869 : StunRequest(new TurnMessage()), 870 port_(port), 871 entry_(entry), 872 ext_addr_(ext_addr) { 873 entry_->SignalDestroyed.connect( 874 this, &TurnCreatePermissionRequest::OnEntryDestroyed); 875 } 876 877 void TurnCreatePermissionRequest::Prepare(StunMessage* request) { 878 // Create the request as indicated in RFC5766, Section 9.1. 879 request->SetType(TURN_CREATE_PERMISSION_REQUEST); 880 VERIFY(request->AddAttribute(new StunXorAddressAttribute( 881 STUN_ATTR_XOR_PEER_ADDRESS, ext_addr_))); 882 port_->AddRequestAuthInfo(request); 883 } 884 885 void TurnCreatePermissionRequest::OnResponse(StunMessage* response) { 886 if (entry_) { 887 entry_->OnCreatePermissionSuccess(); 888 } 889 } 890 891 void TurnCreatePermissionRequest::OnErrorResponse(StunMessage* response) { 892 if (entry_) { 893 const StunErrorCodeAttribute* error_code = response->GetErrorCode(); 894 entry_->OnCreatePermissionError(response, error_code->code()); 895 } 896 } 897 898 void TurnCreatePermissionRequest::OnTimeout() { 899 LOG_J(LS_WARNING, port_) << "Create permission timeout"; 900 } 901 902 void TurnCreatePermissionRequest::OnEntryDestroyed(TurnEntry* entry) { 903 ASSERT(entry_ == entry); 904 entry_ = NULL; 905 } 906 907 TurnChannelBindRequest::TurnChannelBindRequest( 908 TurnPort* port, TurnEntry* entry, 909 int channel_id, const talk_base::SocketAddress& ext_addr) 910 : StunRequest(new TurnMessage()), 911 port_(port), 912 entry_(entry), 913 channel_id_(channel_id), 914 ext_addr_(ext_addr) { 915 entry_->SignalDestroyed.connect( 916 this, &TurnChannelBindRequest::OnEntryDestroyed); 917 } 918 919 void TurnChannelBindRequest::Prepare(StunMessage* request) { 920 // Create the request as indicated in RFC5766, Section 11.1. 921 request->SetType(TURN_CHANNEL_BIND_REQUEST); 922 VERIFY(request->AddAttribute(new StunUInt32Attribute( 923 STUN_ATTR_CHANNEL_NUMBER, channel_id_ << 16))); 924 VERIFY(request->AddAttribute(new StunXorAddressAttribute( 925 STUN_ATTR_XOR_PEER_ADDRESS, ext_addr_))); 926 port_->AddRequestAuthInfo(request); 927 } 928 929 void TurnChannelBindRequest::OnResponse(StunMessage* response) { 930 if (entry_) { 931 entry_->OnChannelBindSuccess(); 932 // Refresh the channel binding just under the permission timeout 933 // threshold. The channel binding has a longer lifetime, but 934 // this is the easiest way to keep both the channel and the 935 // permission from expiring. 936 entry_->SendChannelBindRequest(TURN_PERMISSION_TIMEOUT - 60 * 1000); 937 } 938 } 939 940 void TurnChannelBindRequest::OnErrorResponse(StunMessage* response) { 941 if (entry_) { 942 const StunErrorCodeAttribute* error_code = response->GetErrorCode(); 943 entry_->OnChannelBindError(response, error_code->code()); 944 } 945 } 946 947 void TurnChannelBindRequest::OnTimeout() { 948 LOG_J(LS_WARNING, port_) << "Channel bind timeout"; 949 } 950 951 void TurnChannelBindRequest::OnEntryDestroyed(TurnEntry* entry) { 952 ASSERT(entry_ == entry); 953 entry_ = NULL; 954 } 955 956 TurnEntry::TurnEntry(TurnPort* port, int channel_id, 957 const talk_base::SocketAddress& ext_addr) 958 : port_(port), 959 channel_id_(channel_id), 960 ext_addr_(ext_addr), 961 state_(STATE_UNBOUND) { 962 // Creating permission for |ext_addr_|. 963 SendCreatePermissionRequest(); 964 } 965 966 void TurnEntry::SendCreatePermissionRequest() { 967 port_->SendRequest(new TurnCreatePermissionRequest( 968 port_, this, ext_addr_), 0); 969 } 970 971 void TurnEntry::SendChannelBindRequest(int delay) { 972 port_->SendRequest(new TurnChannelBindRequest( 973 port_, this, channel_id_, ext_addr_), delay); 974 } 975 976 int TurnEntry::Send(const void* data, size_t size, bool payload, 977 const talk_base::PacketOptions& options) { 978 talk_base::ByteBuffer buf; 979 if (state_ != STATE_BOUND) { 980 // If we haven't bound the channel yet, we have to use a Send Indication. 981 TurnMessage msg; 982 msg.SetType(TURN_SEND_INDICATION); 983 msg.SetTransactionID( 984 talk_base::CreateRandomString(kStunTransactionIdLength)); 985 VERIFY(msg.AddAttribute(new StunXorAddressAttribute( 986 STUN_ATTR_XOR_PEER_ADDRESS, ext_addr_))); 987 VERIFY(msg.AddAttribute(new StunByteStringAttribute( 988 STUN_ATTR_DATA, data, size))); 989 VERIFY(msg.Write(&buf)); 990 991 // If we're sending real data, request a channel bind that we can use later. 992 if (state_ == STATE_UNBOUND && payload) { 993 SendChannelBindRequest(0); 994 state_ = STATE_BINDING; 995 } 996 } else { 997 // If the channel is bound, we can send the data as a Channel Message. 998 buf.WriteUInt16(channel_id_); 999 buf.WriteUInt16(static_cast<uint16>(size)); 1000 buf.WriteBytes(reinterpret_cast<const char*>(data), size); 1001 } 1002 return port_->Send(buf.Data(), buf.Length(), options); 1003 } 1004 1005 void TurnEntry::OnCreatePermissionSuccess() { 1006 LOG_J(LS_INFO, port_) << "Create permission for " 1007 << ext_addr_.ToSensitiveString() 1008 << " succeeded"; 1009 // For success result code will be 0. 1010 port_->SignalCreatePermissionResult(port_, ext_addr_, 0); 1011 } 1012 1013 void TurnEntry::OnCreatePermissionError(StunMessage* response, int code) { 1014 LOG_J(LS_WARNING, port_) << "Create permission for " 1015 << ext_addr_.ToSensitiveString() 1016 << " failed, code=" << code; 1017 if (code == STUN_ERROR_STALE_NONCE) { 1018 if (port_->UpdateNonce(response)) { 1019 SendCreatePermissionRequest(); 1020 } 1021 } else { 1022 // Send signal with error code. 1023 port_->SignalCreatePermissionResult(port_, ext_addr_, code); 1024 } 1025 } 1026 1027 void TurnEntry::OnChannelBindSuccess() { 1028 LOG_J(LS_INFO, port_) << "Channel bind for " << ext_addr_.ToSensitiveString() 1029 << " succeeded"; 1030 ASSERT(state_ == STATE_BINDING || state_ == STATE_BOUND); 1031 state_ = STATE_BOUND; 1032 } 1033 1034 void TurnEntry::OnChannelBindError(StunMessage* response, int code) { 1035 // TODO(mallinath) - Implement handling of error response for channel 1036 // bind request as per http://tools.ietf.org/html/rfc5766#section-11.3 1037 LOG_J(LS_WARNING, port_) << "Channel bind for " 1038 << ext_addr_.ToSensitiveString() 1039 << " failed, code=" << code; 1040 if (code == STUN_ERROR_STALE_NONCE) { 1041 if (port_->UpdateNonce(response)) { 1042 // Send channel bind request with fresh nonce. 1043 SendChannelBindRequest(0); 1044 } 1045 } 1046 } 1047 1048 } // namespace cricket 1049