1 /* 2 * libjingle 3 * Copyright 2004--2005, 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/port.h" 29 30 #include <algorithm> 31 #include <vector> 32 33 #include "talk/base/base64.h" 34 #include "talk/base/crc32.h" 35 #include "talk/base/helpers.h" 36 #include "talk/base/logging.h" 37 #include "talk/base/messagedigest.h" 38 #include "talk/base/scoped_ptr.h" 39 #include "talk/base/stringencode.h" 40 #include "talk/base/stringutils.h" 41 #include "talk/p2p/base/common.h" 42 43 namespace { 44 45 // Determines whether we have seen at least the given maximum number of 46 // pings fail to have a response. 47 inline bool TooManyFailures( 48 const std::vector<uint32>& pings_since_last_response, 49 uint32 maximum_failures, 50 uint32 rtt_estimate, 51 uint32 now) { 52 53 // If we haven't sent that many pings, then we can't have failed that many. 54 if (pings_since_last_response.size() < maximum_failures) 55 return false; 56 57 // Check if the window in which we would expect a response to the ping has 58 // already elapsed. 59 return pings_since_last_response[maximum_failures - 1] + rtt_estimate < now; 60 } 61 62 // Determines whether we have gone too long without seeing any response. 63 inline bool TooLongWithoutResponse( 64 const std::vector<uint32>& pings_since_last_response, 65 uint32 maximum_time, 66 uint32 now) { 67 68 if (pings_since_last_response.size() == 0) 69 return false; 70 71 return pings_since_last_response[0] + maximum_time < now; 72 } 73 74 // GICE(ICEPROTO_GOOGLE) requires different username for RTP and RTCP. 75 // This function generates a different username by +1 on the last character of 76 // the given username (|rtp_ufrag|). 77 std::string GetRtcpUfragFromRtpUfrag(const std::string& rtp_ufrag) { 78 ASSERT(!rtp_ufrag.empty()); 79 if (rtp_ufrag.empty()) { 80 return rtp_ufrag; 81 } 82 // Change the last character to the one next to it in the base64 table. 83 char new_last_char; 84 if (!talk_base::Base64::GetNextBase64Char(rtp_ufrag[rtp_ufrag.size() - 1], 85 &new_last_char)) { 86 // Should not be here. 87 ASSERT(false); 88 } 89 std::string rtcp_ufrag = rtp_ufrag; 90 rtcp_ufrag[rtcp_ufrag.size() - 1] = new_last_char; 91 ASSERT(rtcp_ufrag != rtp_ufrag); 92 return rtcp_ufrag; 93 } 94 95 // We will restrict RTT estimates (when used for determining state) to be 96 // within a reasonable range. 97 const uint32 MINIMUM_RTT = 100; // 0.1 seconds 98 const uint32 MAXIMUM_RTT = 3000; // 3 seconds 99 100 // When we don't have any RTT data, we have to pick something reasonable. We 101 // use a large value just in case the connection is really slow. 102 const uint32 DEFAULT_RTT = MAXIMUM_RTT; 103 104 // Computes our estimate of the RTT given the current estimate. 105 inline uint32 ConservativeRTTEstimate(uint32 rtt) { 106 return talk_base::_max(MINIMUM_RTT, talk_base::_min(MAXIMUM_RTT, 2 * rtt)); 107 } 108 109 // Weighting of the old rtt value to new data. 110 const int RTT_RATIO = 3; // 3 : 1 111 112 // The delay before we begin checking if this port is useless. 113 const int kPortTimeoutDelay = 30 * 1000; // 30 seconds 114 115 const uint32 MSG_CHECKTIMEOUT = 1; 116 const uint32 MSG_DELETE = 1; 117 } 118 119 namespace cricket { 120 121 // TODO(ronghuawu): Use "host", "srflx", "prflx" and "relay". But this requires 122 // the signaling part be updated correspondingly as well. 123 const char LOCAL_PORT_TYPE[] = "local"; 124 const char STUN_PORT_TYPE[] = "stun"; 125 const char PRFLX_PORT_TYPE[] = "prflx"; 126 const char RELAY_PORT_TYPE[] = "relay"; 127 128 const char UDP_PROTOCOL_NAME[] = "udp"; 129 const char TCP_PROTOCOL_NAME[] = "tcp"; 130 const char SSLTCP_PROTOCOL_NAME[] = "ssltcp"; 131 132 static const char* const PROTO_NAMES[] = { UDP_PROTOCOL_NAME, 133 TCP_PROTOCOL_NAME, 134 SSLTCP_PROTOCOL_NAME }; 135 136 const char* ProtoToString(ProtocolType proto) { 137 return PROTO_NAMES[proto]; 138 } 139 140 bool StringToProto(const char* value, ProtocolType* proto) { 141 for (size_t i = 0; i <= PROTO_LAST; ++i) { 142 if (_stricmp(PROTO_NAMES[i], value) == 0) { 143 *proto = static_cast<ProtocolType>(i); 144 return true; 145 } 146 } 147 return false; 148 } 149 150 // Foundation: An arbitrary string that is the same for two candidates 151 // that have the same type, base IP address, protocol (UDP, TCP, 152 // etc.), and STUN or TURN server. If any of these are different, 153 // then the foundation will be different. Two candidate pairs with 154 // the same foundation pairs are likely to have similar network 155 // characteristics. Foundations are used in the frozen algorithm. 156 static std::string ComputeFoundation( 157 const std::string& type, 158 const std::string& protocol, 159 const talk_base::SocketAddress& base_address) { 160 std::ostringstream ost; 161 ost << type << base_address.ipaddr().ToString() << protocol; 162 return talk_base::ToString<uint32>(talk_base::ComputeCrc32(ost.str())); 163 } 164 165 Port::Port(talk_base::Thread* thread, talk_base::Network* network, 166 const talk_base::IPAddress& ip, 167 const std::string& username_fragment, const std::string& password) 168 : thread_(thread), 169 factory_(NULL), 170 send_retransmit_count_attribute_(false), 171 network_(network), 172 ip_(ip), 173 min_port_(0), 174 max_port_(0), 175 component_(ICE_CANDIDATE_COMPONENT_DEFAULT), 176 generation_(0), 177 ice_username_fragment_(username_fragment), 178 password_(password), 179 lifetime_(LT_PRESTART), 180 enable_port_packets_(false), 181 ice_protocol_(ICEPROTO_GOOGLE), 182 ice_role_(ICEROLE_UNKNOWN), 183 tiebreaker_(0), 184 shared_socket_(true) { 185 Construct(); 186 } 187 188 Port::Port(talk_base::Thread* thread, const std::string& type, 189 talk_base::PacketSocketFactory* factory, 190 talk_base::Network* network, const talk_base::IPAddress& ip, 191 int min_port, int max_port, const std::string& username_fragment, 192 const std::string& password) 193 : thread_(thread), 194 factory_(factory), 195 type_(type), 196 send_retransmit_count_attribute_(false), 197 network_(network), 198 ip_(ip), 199 min_port_(min_port), 200 max_port_(max_port), 201 component_(ICE_CANDIDATE_COMPONENT_DEFAULT), 202 generation_(0), 203 ice_username_fragment_(username_fragment), 204 password_(password), 205 lifetime_(LT_PRESTART), 206 enable_port_packets_(false), 207 ice_protocol_(ICEPROTO_GOOGLE), 208 ice_role_(ICEROLE_UNKNOWN), 209 tiebreaker_(0), 210 shared_socket_(false) { 211 ASSERT(factory_ != NULL); 212 Construct(); 213 } 214 215 void Port::Construct() { 216 // If the username_fragment and password are empty, we should just create one. 217 if (ice_username_fragment_.empty()) { 218 ASSERT(password_.empty()); 219 ice_username_fragment_ = talk_base::CreateRandomString(ICE_UFRAG_LENGTH); 220 password_ = talk_base::CreateRandomString(ICE_PWD_LENGTH); 221 } 222 LOG_J(LS_INFO, this) << "Port created"; 223 } 224 225 Port::~Port() { 226 // Delete all of the remaining connections. We copy the list up front 227 // because each deletion will cause it to be modified. 228 229 std::vector<Connection*> list; 230 231 AddressMap::iterator iter = connections_.begin(); 232 while (iter != connections_.end()) { 233 list.push_back(iter->second); 234 ++iter; 235 } 236 237 for (uint32 i = 0; i < list.size(); i++) 238 delete list[i]; 239 } 240 241 Connection* Port::GetConnection(const talk_base::SocketAddress& remote_addr) { 242 AddressMap::const_iterator iter = connections_.find(remote_addr); 243 if (iter != connections_.end()) 244 return iter->second; 245 else 246 return NULL; 247 } 248 249 void Port::AddAddress(const talk_base::SocketAddress& address, 250 const talk_base::SocketAddress& base_address, 251 const std::string& protocol, 252 const std::string& type, 253 uint32 type_preference, 254 bool final) { 255 Candidate c; 256 c.set_id(talk_base::CreateRandomString(8)); 257 c.set_component(component_); 258 c.set_type(type); 259 c.set_protocol(protocol); 260 c.set_address(address); 261 c.set_priority(c.GetPriority(type_preference)); 262 c.set_username(username_fragment()); 263 c.set_password(password_); 264 c.set_network_name(network_->name()); 265 c.set_generation(generation_); 266 c.set_related_address(related_address_); 267 c.set_foundation(ComputeFoundation(type, protocol, base_address)); 268 candidates_.push_back(c); 269 SignalCandidateReady(this, c); 270 271 if (final) { 272 SignalPortComplete(this); 273 } 274 } 275 276 void Port::AddConnection(Connection* conn) { 277 connections_[conn->remote_candidate().address()] = conn; 278 conn->SignalDestroyed.connect(this, &Port::OnConnectionDestroyed); 279 SignalConnectionCreated(this, conn); 280 } 281 282 void Port::OnReadPacket( 283 const char* data, size_t size, const talk_base::SocketAddress& addr, 284 ProtocolType proto) { 285 // If the user has enabled port packets, just hand this over. 286 if (enable_port_packets_) { 287 SignalReadPacket(this, data, size, addr); 288 return; 289 } 290 291 // If this is an authenticated STUN request, then signal unknown address and 292 // send back a proper binding response. 293 talk_base::scoped_ptr<IceMessage> msg; 294 std::string remote_username; 295 if (!GetStunMessage(data, size, addr, msg.accept(), &remote_username)) { 296 LOG_J(LS_ERROR, this) << "Received non-STUN packet from unknown address (" 297 << addr.ToSensitiveString() << ")"; 298 } else if (!msg) { 299 // STUN message handled already 300 } else if (msg->type() == STUN_BINDING_REQUEST) { 301 // Check for role conflicts. 302 if (IsStandardIce() && 303 !MaybeIceRoleConflict(addr, msg.get(), remote_username)) { 304 LOG(LS_INFO) << "Received conflicting role from the peer."; 305 return; 306 } 307 308 SignalUnknownAddress(this, addr, proto, msg.get(), remote_username, false); 309 } else { 310 // NOTE(tschmelcher): STUN_BINDING_RESPONSE is benign. It occurs if we 311 // pruned a connection for this port while it had STUN requests in flight, 312 // because we then get back responses for them, which this code correctly 313 // does not handle. 314 if (msg->type() != STUN_BINDING_RESPONSE) { 315 LOG_J(LS_ERROR, this) << "Received unexpected STUN message type (" 316 << msg->type() << ") from unknown address (" 317 << addr.ToSensitiveString() << ")"; 318 } 319 } 320 } 321 322 void Port::OnReadyToSend() { 323 AddressMap::iterator iter = connections_.begin(); 324 for (; iter != connections_.end(); ++iter) { 325 iter->second->OnReadyToSend(); 326 } 327 } 328 329 size_t Port::AddPrflxCandidate(const Candidate& local) { 330 candidates_.push_back(local); 331 return (candidates_.size() - 1); 332 } 333 334 bool Port::IsStandardIce() const { 335 return (ice_protocol_ == ICEPROTO_RFC5245); 336 } 337 338 bool Port::IsGoogleIce() const { 339 return (ice_protocol_ == ICEPROTO_GOOGLE); 340 } 341 342 bool Port::GetStunMessage(const char* data, size_t size, 343 const talk_base::SocketAddress& addr, 344 IceMessage** out_msg, std::string* out_username) { 345 // NOTE: This could clearly be optimized to avoid allocating any memory. 346 // However, at the data rates we'll be looking at on the client side, 347 // this probably isn't worth worrying about. 348 ASSERT(out_msg != NULL); 349 ASSERT(out_username != NULL); 350 *out_msg = NULL; 351 out_username->clear(); 352 353 // Don't bother parsing the packet if we can tell it's not STUN. 354 // In ICE mode, all STUN packets will have a valid fingerprint. 355 if (IsStandardIce() && !StunMessage::ValidateFingerprint(data, size)) { 356 return false; 357 } 358 359 // Parse the request message. If the packet is not a complete and correct 360 // STUN message, then ignore it. 361 talk_base::scoped_ptr<IceMessage> stun_msg(new IceMessage()); 362 talk_base::ByteBuffer buf(data, size); 363 if (!stun_msg->Read(&buf) || (buf.Length() > 0)) { 364 return false; 365 } 366 367 if (stun_msg->type() == STUN_BINDING_REQUEST) { 368 // Check for the presence of USERNAME and MESSAGE-INTEGRITY (if ICE) first. 369 // If not present, fail with a 400 Bad Request. 370 if (!stun_msg->GetByteString(STUN_ATTR_USERNAME) || 371 (IsStandardIce() && 372 !stun_msg->GetByteString(STUN_ATTR_MESSAGE_INTEGRITY))) { 373 LOG_J(LS_ERROR, this) << "Received STUN request without username/M-I " 374 << "from " << addr.ToSensitiveString(); 375 SendBindingErrorResponse(stun_msg.get(), addr, STUN_ERROR_BAD_REQUEST, 376 STUN_ERROR_REASON_BAD_REQUEST); 377 return true; 378 } 379 380 // If the username is bad or unknown, fail with a 401 Unauthorized. 381 std::string local_ufrag; 382 std::string remote_ufrag; 383 if (!ParseStunUsername(stun_msg.get(), &local_ufrag, &remote_ufrag) || 384 local_ufrag != username_fragment()) { 385 LOG_J(LS_ERROR, this) << "Received STUN request with bad local username " 386 << local_ufrag << " from " 387 << addr.ToSensitiveString(); 388 SendBindingErrorResponse(stun_msg.get(), addr, STUN_ERROR_UNAUTHORIZED, 389 STUN_ERROR_REASON_UNAUTHORIZED); 390 return true; 391 } 392 393 // If ICE, and the MESSAGE-INTEGRITY is bad, fail with a 401 Unauthorized 394 if (IsStandardIce() && 395 !stun_msg->ValidateMessageIntegrity(data, size, password_)) { 396 LOG_J(LS_ERROR, this) << "Received STUN request with bad M-I " 397 << "from " << addr.ToSensitiveString(); 398 SendBindingErrorResponse(stun_msg.get(), addr, STUN_ERROR_UNAUTHORIZED, 399 STUN_ERROR_REASON_UNAUTHORIZED); 400 return true; 401 } 402 out_username->assign(remote_ufrag); 403 } else if ((stun_msg->type() == STUN_BINDING_RESPONSE) || 404 (stun_msg->type() == STUN_BINDING_ERROR_RESPONSE)) { 405 if (stun_msg->type() == STUN_BINDING_ERROR_RESPONSE) { 406 if (const StunErrorCodeAttribute* error_code = stun_msg->GetErrorCode()) { 407 LOG_J(LS_ERROR, this) << "Received STUN binding error:" 408 << " class=" << error_code->eclass() 409 << " number=" << error_code->number() 410 << " reason='" << error_code->reason() << "'" 411 << " from " << addr.ToSensitiveString(); 412 // Return message to allow error-specific processing 413 } else { 414 LOG_J(LS_ERROR, this) << "Received STUN binding error without a error " 415 << "code from " << addr.ToSensitiveString(); 416 return true; 417 } 418 } 419 // NOTE: Username should not be used in verifying response messages. 420 out_username->clear(); 421 } else if (stun_msg->type() == STUN_BINDING_INDICATION) { 422 LOG_J(LS_VERBOSE, this) << "Received STUN binding indication:" 423 << " from " << addr.ToSensitiveString(); 424 out_username->clear(); 425 // No stun attributes will be verified, if it's stun indication message. 426 // Returning from end of the this method. 427 } else { 428 LOG_J(LS_ERROR, this) << "Received STUN packet with invalid type (" 429 << stun_msg->type() << ") from " 430 << addr.ToSensitiveString(); 431 return true; 432 } 433 434 // Return the STUN message found. 435 *out_msg = stun_msg.release(); 436 return true; 437 } 438 439 bool Port::IsCompatibleAddress(const talk_base::SocketAddress& addr) { 440 int family = ip().family(); 441 // We use single-stack sockets, so families must match. 442 if (addr.family() != family) { 443 return false; 444 } 445 // Link-local IPv6 ports can only connect to other link-local IPv6 ports. 446 if (family == AF_INET6 && (IPIsPrivate(ip()) != IPIsPrivate(addr.ipaddr()))) { 447 return false; 448 } 449 return true; 450 } 451 452 bool Port::ParseStunUsername(const StunMessage* stun_msg, 453 std::string* local_ufrag, 454 std::string* remote_ufrag) const { 455 // The packet must include a username that either begins or ends with our 456 // fragment. It should begin with our fragment if it is a request and it 457 // should end with our fragment if it is a response. 458 local_ufrag->clear(); 459 remote_ufrag->clear(); 460 const StunByteStringAttribute* username_attr = 461 stun_msg->GetByteString(STUN_ATTR_USERNAME); 462 if (username_attr == NULL) 463 return false; 464 465 const std::string username_attr_str = username_attr->GetString(); 466 if (IsStandardIce()) { 467 size_t colon_pos = username_attr_str.find(":"); 468 if (colon_pos != std::string::npos) { // RFRAG:LFRAG 469 *local_ufrag = username_attr_str.substr(0, colon_pos); 470 *remote_ufrag = username_attr_str.substr( 471 colon_pos + 1, username_attr_str.size()); 472 } else { 473 return false; 474 } 475 } else if (IsGoogleIce()) { 476 int remote_frag_len = static_cast<int>(username_attr_str.size()); 477 remote_frag_len -= static_cast<int>(username_fragment().size()); 478 if (remote_frag_len < 0) 479 return false; 480 481 *local_ufrag = username_attr_str.substr(0, username_fragment().size()); 482 *remote_ufrag = username_attr_str.substr( 483 username_fragment().size(), username_attr_str.size()); 484 } 485 return true; 486 } 487 488 bool Port::MaybeIceRoleConflict( 489 const talk_base::SocketAddress& addr, IceMessage* stun_msg, 490 const std::string& remote_ufrag) { 491 // Validate ICE_CONTROLLING or ICE_CONTROLLED attributes. 492 bool ret = true; 493 IceRole remote_ice_role = ICEROLE_UNKNOWN; 494 uint64 remote_tiebreaker = 0; 495 const StunUInt64Attribute* stun_attr = 496 stun_msg->GetUInt64(STUN_ATTR_ICE_CONTROLLING); 497 if (stun_attr) { 498 remote_ice_role = ICEROLE_CONTROLLING; 499 remote_tiebreaker = stun_attr->value(); 500 } 501 502 // If |remote_ufrag| is same as port local username fragment and 503 // tie breaker value received in the ping message matches port 504 // tiebreaker value this must be a loopback call. 505 // We will treat this as valid scenario. 506 if (remote_ice_role == ICEROLE_CONTROLLING && 507 username_fragment() == remote_ufrag && 508 remote_tiebreaker == IceTiebreaker()) { 509 return true; 510 } 511 512 stun_attr = stun_msg->GetUInt64(STUN_ATTR_ICE_CONTROLLED); 513 if (stun_attr) { 514 remote_ice_role = ICEROLE_CONTROLLED; 515 remote_tiebreaker = stun_attr->value(); 516 } 517 518 switch (ice_role_) { 519 case ICEROLE_CONTROLLING: 520 if (ICEROLE_CONTROLLING == remote_ice_role) { 521 if (remote_tiebreaker >= tiebreaker_) { 522 SignalRoleConflict(this); 523 } else { 524 // Send Role Conflict (487) error response. 525 SendBindingErrorResponse(stun_msg, addr, 526 STUN_ERROR_ROLE_CONFLICT, STUN_ERROR_REASON_ROLE_CONFLICT); 527 ret = false; 528 } 529 } 530 break; 531 case ICEROLE_CONTROLLED: 532 if (ICEROLE_CONTROLLED == remote_ice_role) { 533 if (remote_tiebreaker < tiebreaker_) { 534 SignalRoleConflict(this); 535 } else { 536 // Send Role Conflict (487) error response. 537 SendBindingErrorResponse(stun_msg, addr, 538 STUN_ERROR_ROLE_CONFLICT, STUN_ERROR_REASON_ROLE_CONFLICT); 539 ret = false; 540 } 541 } 542 break; 543 default: 544 ASSERT(false); 545 } 546 return ret; 547 } 548 549 void Port::CreateStunUsername(const std::string& remote_username, 550 std::string* stun_username_attr_str) const { 551 stun_username_attr_str->clear(); 552 *stun_username_attr_str = remote_username; 553 if (IsStandardIce()) { 554 // Connectivity checks from L->R will have username RFRAG:LFRAG. 555 stun_username_attr_str->append(":"); 556 } 557 stun_username_attr_str->append(username_fragment()); 558 } 559 560 void Port::SendBindingResponse(StunMessage* request, 561 const talk_base::SocketAddress& addr) { 562 ASSERT(request->type() == STUN_BINDING_REQUEST); 563 564 // Retrieve the username from the request. 565 const StunByteStringAttribute* username_attr = 566 request->GetByteString(STUN_ATTR_USERNAME); 567 ASSERT(username_attr != NULL); 568 if (username_attr == NULL) { 569 // No valid username, skip the response. 570 return; 571 } 572 573 // Fill in the response message. 574 StunMessage response; 575 response.SetType(STUN_BINDING_RESPONSE); 576 response.SetTransactionID(request->transaction_id()); 577 const StunUInt32Attribute* retransmit_attr = 578 request->GetUInt32(STUN_ATTR_RETRANSMIT_COUNT); 579 if (retransmit_attr) { 580 // Inherit the incoming retransmit value in the response so the other side 581 // can see our view of lost pings. 582 response.AddAttribute(new StunUInt32Attribute( 583 STUN_ATTR_RETRANSMIT_COUNT, retransmit_attr->value())); 584 585 if (retransmit_attr->value() > CONNECTION_WRITE_CONNECT_FAILURES) { 586 LOG_J(LS_INFO, this) 587 << "Received a remote ping with high retransmit count: " 588 << retransmit_attr->value(); 589 } 590 } 591 592 // Only GICE messages have USERNAME and MAPPED-ADDRESS in the response. 593 // ICE messages use XOR-MAPPED-ADDRESS, and add MESSAGE-INTEGRITY. 594 if (IsStandardIce()) { 595 response.AddAttribute( 596 new StunXorAddressAttribute(STUN_ATTR_XOR_MAPPED_ADDRESS, addr)); 597 response.AddMessageIntegrity(password_); 598 response.AddFingerprint(); 599 } else if (IsGoogleIce()) { 600 response.AddAttribute( 601 new StunAddressAttribute(STUN_ATTR_MAPPED_ADDRESS, addr)); 602 response.AddAttribute(new StunByteStringAttribute( 603 STUN_ATTR_USERNAME, username_attr->GetString())); 604 } 605 606 // Send the response message. 607 talk_base::ByteBuffer buf; 608 response.Write(&buf); 609 if (SendTo(buf.Data(), buf.Length(), addr, false) < 0) { 610 LOG_J(LS_ERROR, this) << "Failed to send STUN ping response to " 611 << addr.ToSensitiveString(); 612 } 613 614 // The fact that we received a successful request means that this connection 615 // (if one exists) should now be readable. 616 Connection* conn = GetConnection(addr); 617 ASSERT(conn != NULL); 618 if (conn) 619 conn->ReceivedPing(); 620 } 621 622 void Port::SendBindingErrorResponse(StunMessage* request, 623 const talk_base::SocketAddress& addr, 624 int error_code, const std::string& reason) { 625 ASSERT(request->type() == STUN_BINDING_REQUEST); 626 627 // Fill in the response message. 628 StunMessage response; 629 response.SetType(STUN_BINDING_ERROR_RESPONSE); 630 response.SetTransactionID(request->transaction_id()); 631 632 // When doing GICE, we need to write out the error code incorrectly to 633 // maintain backwards compatiblility. 634 StunErrorCodeAttribute* error_attr = StunAttribute::CreateErrorCode(); 635 if (IsStandardIce()) { 636 error_attr->SetCode(error_code); 637 } else if (IsGoogleIce()) { 638 error_attr->SetClass(error_code / 256); 639 error_attr->SetNumber(error_code % 256); 640 } 641 error_attr->SetReason(reason); 642 response.AddAttribute(error_attr); 643 644 if (IsStandardIce()) { 645 // Per Section 10.1.2, certain error cases don't get a MESSAGE-INTEGRITY, 646 // because we don't have enough information to determine the shared secret. 647 if (error_code != STUN_ERROR_BAD_REQUEST && 648 error_code != STUN_ERROR_UNAUTHORIZED) 649 response.AddMessageIntegrity(password_); 650 response.AddFingerprint(); 651 } else if (IsGoogleIce()) { 652 // GICE responses include a username, if one exists. 653 const StunByteStringAttribute* username_attr = 654 request->GetByteString(STUN_ATTR_USERNAME); 655 if (username_attr) 656 response.AddAttribute(new StunByteStringAttribute( 657 STUN_ATTR_USERNAME, username_attr->GetString())); 658 } 659 660 // Send the response message. 661 talk_base::ByteBuffer buf; 662 response.Write(&buf); 663 SendTo(buf.Data(), buf.Length(), addr, false); 664 LOG_J(LS_INFO, this) << "Sending STUN binding error: reason=" << reason 665 << " to " << addr.ToSensitiveString(); 666 } 667 668 void Port::OnMessage(talk_base::Message *pmsg) { 669 ASSERT(pmsg->message_id == MSG_CHECKTIMEOUT); 670 ASSERT(lifetime_ == LT_PRETIMEOUT); 671 lifetime_ = LT_POSTTIMEOUT; 672 CheckTimeout(); 673 } 674 675 std::string Port::ToString() const { 676 std::stringstream ss; 677 ss << "Port[" << content_name_ << ":" << component_ 678 << ":" << generation_ << ":" << type_ 679 << ":" << network_->ToString() << "]"; 680 return ss.str(); 681 } 682 683 void Port::EnablePortPackets() { 684 enable_port_packets_ = true; 685 } 686 687 void Port::Start() { 688 // The port sticks around for a minimum lifetime, after which 689 // we destroy it when it drops to zero connections. 690 if (lifetime_ == LT_PRESTART) { 691 lifetime_ = LT_PRETIMEOUT; 692 thread_->PostDelayed(kPortTimeoutDelay, this, MSG_CHECKTIMEOUT); 693 } else { 694 LOG_J(LS_WARNING, this) << "Port restart attempted"; 695 } 696 } 697 698 void Port::OnConnectionDestroyed(Connection* conn) { 699 AddressMap::iterator iter = 700 connections_.find(conn->remote_candidate().address()); 701 ASSERT(iter != connections_.end()); 702 connections_.erase(iter); 703 704 CheckTimeout(); 705 } 706 707 void Port::Destroy() { 708 ASSERT(connections_.empty()); 709 LOG_J(LS_INFO, this) << "Port deleted"; 710 SignalDestroyed(this); 711 delete this; 712 } 713 714 void Port::CheckTimeout() { 715 // If this port has no connections, then there's no reason to keep it around. 716 // When the connections time out (both read and write), they will delete 717 // themselves, so if we have any connections, they are either readable or 718 // writable (or still connecting). 719 if ((lifetime_ == LT_POSTTIMEOUT) && connections_.empty()) { 720 Destroy(); 721 } 722 } 723 724 const std::string Port::username_fragment() const { 725 if (IsGoogleIce() && 726 component_ == ICE_CANDIDATE_COMPONENT_RTCP) { 727 // In GICE mode, we should adjust username fragment for rtcp component. 728 return GetRtcpUfragFromRtpUfrag(ice_username_fragment_); 729 } else { 730 return ice_username_fragment_; 731 } 732 } 733 734 // A ConnectionRequest is a simple STUN ping used to determine writability. 735 class ConnectionRequest : public StunRequest { 736 public: 737 explicit ConnectionRequest(Connection* connection) 738 : StunRequest(new IceMessage()), 739 connection_(connection) { 740 } 741 742 virtual ~ConnectionRequest() { 743 } 744 745 virtual void Prepare(StunMessage* request) { 746 request->SetType(STUN_BINDING_REQUEST); 747 std::string username; 748 connection_->port()->CreateStunUsername( 749 connection_->remote_candidate().username(), &username); 750 request->AddAttribute( 751 new StunByteStringAttribute(STUN_ATTR_USERNAME, username)); 752 753 // connection_ already holds this ping, so subtract one from count. 754 if (connection_->port()->send_retransmit_count_attribute()) { 755 request->AddAttribute(new StunUInt32Attribute( 756 STUN_ATTR_RETRANSMIT_COUNT, 757 static_cast<uint32>( 758 connection_->pings_since_last_response_.size() - 1))); 759 } 760 761 // Adding ICE-specific attributes to the STUN request message. 762 if (connection_->port()->IsStandardIce()) { 763 // Adding ICE_CONTROLLED or ICE_CONTROLLING attribute based on the role. 764 if (connection_->port()->GetIceRole() == ICEROLE_CONTROLLING) { 765 request->AddAttribute(new StunUInt64Attribute( 766 STUN_ATTR_ICE_CONTROLLING, connection_->port()->IceTiebreaker())); 767 // Since we are trying aggressive nomination, sending USE-CANDIDATE 768 // attribute in every ping. 769 // If we are dealing with a ice-lite end point, nomination flag 770 // in Connection will be set to false by default. Once the connection 771 // becomes "best connection", nomination flag will be turned on. 772 if (connection_->use_candidate_attr()) { 773 request->AddAttribute(new StunByteStringAttribute( 774 STUN_ATTR_USE_CANDIDATE)); 775 } 776 } else if (connection_->port()->GetIceRole() == ICEROLE_CONTROLLED) { 777 request->AddAttribute(new StunUInt64Attribute( 778 STUN_ATTR_ICE_CONTROLLED, connection_->port()->IceTiebreaker())); 779 } else { 780 ASSERT(false); 781 } 782 783 // Adding PRIORITY Attribute. 784 // Changing the type preference to Peer Reflexive and local preference 785 // and component id information is unchanged from the original priority. 786 // priority = (2^24)*(type preference) + 787 // (2^8)*(local preference) + 788 // (2^0)*(256 - component ID) 789 uint32 prflx_priority = ICE_TYPE_PREFERENCE_PRFLX << 24 | 790 (connection_->local_candidate().priority() & 0x00FFFFFF); 791 request->AddAttribute( 792 new StunUInt32Attribute(STUN_ATTR_PRIORITY, prflx_priority)); 793 794 // Adding Message Integrity attribute. 795 request->AddMessageIntegrity(connection_->remote_candidate().password()); 796 // Adding Fingerprint. 797 request->AddFingerprint(); 798 } 799 } 800 801 virtual void OnResponse(StunMessage* response) { 802 connection_->OnConnectionRequestResponse(this, response); 803 } 804 805 virtual void OnErrorResponse(StunMessage* response) { 806 connection_->OnConnectionRequestErrorResponse(this, response); 807 } 808 809 virtual void OnTimeout() { 810 connection_->OnConnectionRequestTimeout(this); 811 } 812 813 virtual int GetNextDelay() { 814 // Each request is sent only once. After a single delay , the request will 815 // time out. 816 timeout_ = true; 817 return CONNECTION_RESPONSE_TIMEOUT; 818 } 819 820 private: 821 Connection* connection_; 822 }; 823 824 // 825 // Connection 826 // 827 828 Connection::Connection(Port* port, size_t index, 829 const Candidate& remote_candidate) 830 : port_(port), local_candidate_index_(index), 831 remote_candidate_(remote_candidate), read_state_(STATE_READ_INIT), 832 write_state_(STATE_WRITE_INIT), connected_(true), pruned_(false), 833 use_candidate_attr_(false), remote_ice_mode_(ICEMODE_FULL), 834 requests_(port->thread()), rtt_(DEFAULT_RTT), last_ping_sent_(0), 835 last_ping_received_(0), last_data_received_(0), 836 last_ping_response_received_(0), reported_(false), state_(STATE_WAITING) { 837 // All of our connections start in WAITING state. 838 // TODO(mallinath) - Start connections from STATE_FROZEN. 839 // Wire up to send stun packets 840 requests_.SignalSendPacket.connect(this, &Connection::OnSendStunPacket); 841 LOG_J(LS_INFO, this) << "Connection created"; 842 } 843 844 Connection::~Connection() { 845 } 846 847 const Candidate& Connection::local_candidate() const { 848 ASSERT(local_candidate_index_ < port_->Candidates().size()); 849 return port_->Candidates()[local_candidate_index_]; 850 } 851 852 uint64 Connection::priority() const { 853 uint64 priority = 0; 854 // RFC 5245 - 5.7.2. Computing Pair Priority and Ordering Pairs 855 // Let G be the priority for the candidate provided by the controlling 856 // agent. Let D be the priority for the candidate provided by the 857 // controlled agent. 858 // pair priority = 2^32*MIN(G,D) + 2*MAX(G,D) + (G>D?1:0) 859 IceRole role = port_->GetIceRole(); 860 if (role != ICEROLE_UNKNOWN) { 861 uint32 g = 0; 862 uint32 d = 0; 863 if (role == ICEROLE_CONTROLLING) { 864 g = local_candidate().priority(); 865 d = remote_candidate_.priority(); 866 } else { 867 g = remote_candidate_.priority(); 868 d = local_candidate().priority(); 869 } 870 priority = talk_base::_min(g, d); 871 priority = priority << 32; 872 priority += 2 * talk_base::_max(g, d) + (g > d ? 1 : 0); 873 } 874 return priority; 875 } 876 877 void Connection::set_read_state(ReadState value) { 878 ReadState old_value = read_state_; 879 read_state_ = value; 880 if (value != old_value) { 881 LOG_J(LS_VERBOSE, this) << "set_read_state"; 882 SignalStateChange(this); 883 CheckTimeout(); 884 } 885 } 886 887 void Connection::set_write_state(WriteState value) { 888 WriteState old_value = write_state_; 889 write_state_ = value; 890 if (value != old_value) { 891 LOG_J(LS_VERBOSE, this) << "set_write_state"; 892 SignalStateChange(this); 893 CheckTimeout(); 894 } 895 } 896 897 void Connection::set_state(State state) { 898 State old_state = state_; 899 state_ = state; 900 if (state != old_state) { 901 LOG_J(LS_VERBOSE, this) << "set_state"; 902 } 903 } 904 905 void Connection::set_connected(bool value) { 906 bool old_value = connected_; 907 connected_ = value; 908 if (value != old_value) { 909 LOG_J(LS_VERBOSE, this) << "set_connected"; 910 } 911 } 912 913 void Connection::set_use_candidate_attr(bool enable) { 914 use_candidate_attr_ = enable; 915 } 916 917 void Connection::OnSendStunPacket(const void* data, size_t size, 918 StunRequest* req) { 919 if (port_->SendTo(data, size, remote_candidate_.address(), false) < 0) { 920 LOG_J(LS_WARNING, this) << "Failed to send STUN ping " << req->id(); 921 } 922 } 923 924 void Connection::OnReadPacket(const char* data, size_t size) { 925 talk_base::scoped_ptr<IceMessage> msg; 926 std::string remote_ufrag; 927 const talk_base::SocketAddress& addr(remote_candidate_.address()); 928 if (!port_->GetStunMessage(data, size, addr, msg.accept(), &remote_ufrag)) { 929 // The packet did not parse as a valid STUN message 930 931 // If this connection is readable, then pass along the packet. 932 if (read_state_ == STATE_READABLE) { 933 // readable means data from this address is acceptable 934 // Send it on! 935 936 last_data_received_ = talk_base::Time(); 937 recv_rate_tracker_.Update(size); 938 SignalReadPacket(this, data, size); 939 940 // If timed out sending writability checks, start up again 941 if (!pruned_ && (write_state_ == STATE_WRITE_TIMEOUT)) { 942 LOG(LS_WARNING) << "Received a data packet on a timed-out Connection. " 943 << "Resetting state to STATE_WRITE_INIT."; 944 set_write_state(STATE_WRITE_INIT); 945 } 946 } else { 947 // Not readable means the remote address hasn't sent a valid 948 // binding request yet. 949 950 LOG_J(LS_WARNING, this) 951 << "Received non-STUN packet from an unreadable connection."; 952 } 953 } else if (!msg) { 954 // The packet was STUN, but failed a check and was handled internally. 955 } else { 956 // The packet is STUN and passed the Port checks. 957 // Perform our own checks to ensure this packet is valid. 958 // If this is a STUN request, then update the readable bit and respond. 959 // If this is a STUN response, then update the writable bit. 960 switch (msg->type()) { 961 case STUN_BINDING_REQUEST: 962 if (remote_ufrag == remote_candidate_.username()) { 963 // Check for role conflicts. 964 if (port_->IsStandardIce() && 965 !port_->MaybeIceRoleConflict(addr, msg.get(), remote_ufrag)) { 966 // Received conflicting role from the peer. 967 LOG(LS_INFO) << "Received conflicting role from the peer."; 968 return; 969 } 970 971 // Incoming, validated stun request from remote peer. 972 // This call will also set the connection readable. 973 port_->SendBindingResponse(msg.get(), addr); 974 975 // If timed out sending writability checks, start up again 976 if (!pruned_ && (write_state_ == STATE_WRITE_TIMEOUT)) 977 set_write_state(STATE_WRITE_INIT); 978 979 if ((port_->IsStandardIce()) && 980 (port_->GetIceRole() == ICEROLE_CONTROLLED)) { 981 const StunByteStringAttribute* use_candidate_attr = 982 msg->GetByteString(STUN_ATTR_USE_CANDIDATE); 983 if (use_candidate_attr) 984 SignalUseCandidate(this); 985 } 986 } else { 987 // The packet had the right local username, but the remote username 988 // was not the right one for the remote address. 989 LOG_J(LS_ERROR, this) 990 << "Received STUN request with bad remote username " 991 << remote_ufrag; 992 port_->SendBindingErrorResponse(msg.get(), addr, 993 STUN_ERROR_UNAUTHORIZED, 994 STUN_ERROR_REASON_UNAUTHORIZED); 995 996 } 997 break; 998 999 // Response from remote peer. Does it match request sent? 1000 // This doesn't just check, it makes callbacks if transaction 1001 // id's match. 1002 case STUN_BINDING_RESPONSE: 1003 case STUN_BINDING_ERROR_RESPONSE: 1004 if (port_->IceProtocol() == ICEPROTO_GOOGLE || 1005 msg->ValidateMessageIntegrity( 1006 data, size, remote_candidate().password())) { 1007 requests_.CheckResponse(msg.get()); 1008 } 1009 // Otherwise silently discard the response message. 1010 break; 1011 1012 // Remote end point sent an STUN indication instead of regular 1013 // binding request. In this case |last_ping_received_| will be updated. 1014 // Otherwise we can mark connection to read timeout. No response will be 1015 // sent in this scenario. 1016 case STUN_BINDING_INDICATION: 1017 if (port_->IsStandardIce() && read_state_ == STATE_READABLE) { 1018 ReceivedPing(); 1019 } else { 1020 LOG_J(LS_WARNING, this) << "Received STUN binding indication " 1021 << "from an unreadable connection."; 1022 } 1023 break; 1024 1025 default: 1026 ASSERT(false); 1027 break; 1028 } 1029 } 1030 } 1031 1032 void Connection::OnReadyToSend() { 1033 if (write_state_ == STATE_WRITABLE) { 1034 SignalReadyToSend(this); 1035 } 1036 } 1037 1038 void Connection::Prune() { 1039 if (!pruned_) { 1040 LOG_J(LS_VERBOSE, this) << "Connection pruned"; 1041 pruned_ = true; 1042 requests_.Clear(); 1043 set_write_state(STATE_WRITE_TIMEOUT); 1044 } 1045 } 1046 1047 void Connection::Destroy() { 1048 LOG_J(LS_VERBOSE, this) << "Connection destroyed"; 1049 set_read_state(STATE_READ_TIMEOUT); 1050 set_write_state(STATE_WRITE_TIMEOUT); 1051 } 1052 1053 void Connection::UpdateState(uint32 now) { 1054 uint32 rtt = ConservativeRTTEstimate(rtt_); 1055 1056 std::string pings; 1057 for (size_t i = 0; i < pings_since_last_response_.size(); ++i) { 1058 char buf[32]; 1059 talk_base::sprintfn(buf, sizeof(buf), "%u", 1060 pings_since_last_response_[i]); 1061 pings.append(buf).append(" "); 1062 } 1063 LOG_J(LS_VERBOSE, this) << "UpdateState(): pings_since_last_response_=" << 1064 pings << ", rtt=" << rtt << ", now=" << now; 1065 1066 // Check the readable state. 1067 // 1068 // Since we don't know how many pings the other side has attempted, the best 1069 // test we can do is a simple window. 1070 // If other side has not sent ping after connection has become readable, use 1071 // |last_data_received_| as the indication. 1072 if ((read_state_ == STATE_READABLE) && 1073 (last_ping_received_ + CONNECTION_READ_TIMEOUT <= now) && 1074 (last_data_received_ + CONNECTION_READ_TIMEOUT <= now)) { 1075 LOG_J(LS_INFO, this) << "Unreadable after " 1076 << now - last_ping_received_ 1077 << " ms without a ping," 1078 << " ms since last received response=" 1079 << now - last_ping_response_received_ 1080 << " ms since last received data=" 1081 << now - last_data_received_ 1082 << " rtt=" << rtt; 1083 set_read_state(STATE_READ_TIMEOUT); 1084 } 1085 1086 // Check the writable state. (The order of these checks is important.) 1087 // 1088 // Before becoming unwritable, we allow for a fixed number of pings to fail 1089 // (i.e., receive no response). We also have to give the response time to 1090 // get back, so we include a conservative estimate of this. 1091 // 1092 // Before timing out writability, we give a fixed amount of time. This is to 1093 // allow for changes in network conditions. 1094 1095 if ((write_state_ == STATE_WRITABLE) && 1096 TooManyFailures(pings_since_last_response_, 1097 CONNECTION_WRITE_CONNECT_FAILURES, 1098 rtt, 1099 now) && 1100 TooLongWithoutResponse(pings_since_last_response_, 1101 CONNECTION_WRITE_CONNECT_TIMEOUT, 1102 now)) { 1103 uint32 max_pings = CONNECTION_WRITE_CONNECT_FAILURES; 1104 LOG_J(LS_INFO, this) << "Unwritable after " << max_pings 1105 << " ping failures and " 1106 << now - pings_since_last_response_[0] 1107 << " ms without a response," 1108 << " ms since last received ping=" 1109 << now - last_ping_received_ 1110 << " ms since last received data=" 1111 << now - last_data_received_ 1112 << " rtt=" << rtt; 1113 set_write_state(STATE_WRITE_UNRELIABLE); 1114 } 1115 1116 if ((write_state_ == STATE_WRITE_UNRELIABLE || 1117 write_state_ == STATE_WRITE_INIT) && 1118 TooLongWithoutResponse(pings_since_last_response_, 1119 CONNECTION_WRITE_TIMEOUT, 1120 now)) { 1121 LOG_J(LS_INFO, this) << "Timed out after " 1122 << now - pings_since_last_response_[0] 1123 << " ms without a response, rtt=" << rtt; 1124 set_write_state(STATE_WRITE_TIMEOUT); 1125 } 1126 } 1127 1128 void Connection::Ping(uint32 now) { 1129 ASSERT(connected_); 1130 last_ping_sent_ = now; 1131 pings_since_last_response_.push_back(now); 1132 ConnectionRequest *req = new ConnectionRequest(this); 1133 LOG_J(LS_VERBOSE, this) << "Sending STUN ping " << req->id() << " at " << now; 1134 requests_.Send(req); 1135 state_ = STATE_INPROGRESS; 1136 } 1137 1138 void Connection::ReceivedPing() { 1139 last_ping_received_ = talk_base::Time(); 1140 set_read_state(STATE_READABLE); 1141 } 1142 1143 std::string Connection::ToString() const { 1144 const char CONNECT_STATE_ABBREV[2] = { 1145 '-', // not connected (false) 1146 'C', // connected (true) 1147 }; 1148 const char READ_STATE_ABBREV[3] = { 1149 '-', // STATE_READ_INIT 1150 'R', // STATE_READABLE 1151 'x', // STATE_READ_TIMEOUT 1152 }; 1153 const char WRITE_STATE_ABBREV[4] = { 1154 'W', // STATE_WRITABLE 1155 'w', // STATE_WRITE_UNRELIABLE 1156 '-', // STATE_WRITE_INIT 1157 'x', // STATE_WRITE_TIMEOUT 1158 }; 1159 const std::string ICESTATE[4] = { 1160 "W", // STATE_WAITING 1161 "I", // STATE_INPROGRESS 1162 "S", // STATE_SUCCEEDED 1163 "F" // STATE_FAILED 1164 }; 1165 const Candidate& local = local_candidate(); 1166 const Candidate& remote = remote_candidate(); 1167 std::stringstream ss; 1168 ss << "Conn[" << port_->content_name() 1169 << ":" << local.id() << ":" << local.component() 1170 << ":" << local.generation() 1171 << ":" << local.type() << ":" << local.protocol() 1172 << ":" << local.address().ToSensitiveString() 1173 << "->" << remote.id() << ":" << remote.component() 1174 << ":" << remote.generation() 1175 << ":" << remote.type() << ":" 1176 << remote.protocol() << ":" << remote.address().ToSensitiveString() 1177 << "|" 1178 << CONNECT_STATE_ABBREV[connected()] 1179 << READ_STATE_ABBREV[read_state()] 1180 << WRITE_STATE_ABBREV[write_state()] 1181 << ICESTATE[state()] 1182 << "|"; 1183 if (rtt_ < DEFAULT_RTT) { 1184 ss << rtt_ << "]"; 1185 } else { 1186 ss << "-]"; 1187 } 1188 return ss.str(); 1189 } 1190 1191 std::string Connection::ToSensitiveString() const { 1192 return ToString(); 1193 } 1194 1195 void Connection::OnConnectionRequestResponse(ConnectionRequest* request, 1196 StunMessage* response) { 1197 // We've already validated that this is a STUN binding response with 1198 // the correct local and remote username for this connection. 1199 // So if we're not already, become writable. We may be bringing a pruned 1200 // connection back to life, but if we don't really want it, we can always 1201 // prune it again. 1202 uint32 rtt = request->Elapsed(); 1203 set_write_state(STATE_WRITABLE); 1204 set_state(STATE_SUCCEEDED); 1205 1206 if (remote_ice_mode_ == ICEMODE_LITE) { 1207 // A ice-lite end point never initiates ping requests. This will allow 1208 // us to move to STATE_READABLE. 1209 ReceivedPing(); 1210 } 1211 1212 std::string pings; 1213 for (size_t i = 0; i < pings_since_last_response_.size(); ++i) { 1214 char buf[32]; 1215 talk_base::sprintfn(buf, sizeof(buf), "%u", 1216 pings_since_last_response_[i]); 1217 pings.append(buf).append(" "); 1218 } 1219 1220 talk_base::LoggingSeverity level = 1221 (pings_since_last_response_.size() > CONNECTION_WRITE_CONNECT_FAILURES) ? 1222 talk_base::LS_INFO : talk_base::LS_VERBOSE; 1223 1224 LOG_JV(level, this) << "Received STUN ping response " << request->id() 1225 << ", pings_since_last_response_=" << pings 1226 << ", rtt=" << rtt; 1227 1228 pings_since_last_response_.clear(); 1229 last_ping_response_received_ = talk_base::Time(); 1230 rtt_ = (RTT_RATIO * rtt_ + rtt) / (RTT_RATIO + 1); 1231 1232 // Peer reflexive candidate is only for RFC 5245 ICE. 1233 if (port_->IsStandardIce()) { 1234 MaybeAddPrflxCandidate(request, response); 1235 } 1236 } 1237 1238 void Connection::OnConnectionRequestErrorResponse(ConnectionRequest* request, 1239 StunMessage* response) { 1240 const StunErrorCodeAttribute* error_attr = response->GetErrorCode(); 1241 int error_code = STUN_ERROR_GLOBAL_FAILURE; 1242 if (error_attr) { 1243 if (port_->IsGoogleIce()) { 1244 // When doing GICE, the error code is written out incorrectly, so we need 1245 // to unmunge it here. 1246 error_code = error_attr->eclass() * 256 + error_attr->number(); 1247 } else { 1248 error_code = error_attr->code(); 1249 } 1250 } 1251 1252 if (error_code == STUN_ERROR_UNKNOWN_ATTRIBUTE || 1253 error_code == STUN_ERROR_SERVER_ERROR || 1254 error_code == STUN_ERROR_UNAUTHORIZED) { 1255 // Recoverable error, retry 1256 } else if (error_code == STUN_ERROR_STALE_CREDENTIALS) { 1257 // Race failure, retry 1258 } else if (error_code == STUN_ERROR_ROLE_CONFLICT) { 1259 HandleRoleConflictFromPeer(); 1260 } else { 1261 // This is not a valid connection. 1262 LOG_J(LS_ERROR, this) << "Received STUN error response, code=" 1263 << error_code << "; killing connection"; 1264 set_state(STATE_FAILED); 1265 set_write_state(STATE_WRITE_TIMEOUT); 1266 } 1267 } 1268 1269 void Connection::OnConnectionRequestTimeout(ConnectionRequest* request) { 1270 // Log at LS_INFO if we miss a ping on a writable connection. 1271 talk_base::LoggingSeverity sev = (write_state_ == STATE_WRITABLE) ? 1272 talk_base::LS_INFO : talk_base::LS_VERBOSE; 1273 LOG_JV(sev, this) << "Timing-out STUN ping " << request->id() 1274 << " after " << request->Elapsed() << " ms"; 1275 } 1276 1277 void Connection::CheckTimeout() { 1278 // If both read and write have timed out or read has never initialized, then 1279 // this connection can contribute no more to p2p socket unless at some later 1280 // date readability were to come back. However, we gave readability a long 1281 // time to timeout, so at this point, it seems fair to get rid of this 1282 // connection. 1283 if ((read_state_ == STATE_READ_TIMEOUT || 1284 read_state_ == STATE_READ_INIT) && 1285 write_state_ == STATE_WRITE_TIMEOUT) { 1286 port_->thread()->Post(this, MSG_DELETE); 1287 } 1288 } 1289 1290 void Connection::HandleRoleConflictFromPeer() { 1291 port_->SignalRoleConflict(port_); 1292 } 1293 1294 void Connection::OnMessage(talk_base::Message *pmsg) { 1295 ASSERT(pmsg->message_id == MSG_DELETE); 1296 1297 LOG_J(LS_INFO, this) << "Connection deleted"; 1298 SignalDestroyed(this); 1299 delete this; 1300 } 1301 1302 size_t Connection::recv_bytes_second() { 1303 return recv_rate_tracker_.units_second(); 1304 } 1305 1306 size_t Connection::recv_total_bytes() { 1307 return recv_rate_tracker_.total_units(); 1308 } 1309 1310 size_t Connection::sent_bytes_second() { 1311 return send_rate_tracker_.units_second(); 1312 } 1313 1314 size_t Connection::sent_total_bytes() { 1315 return send_rate_tracker_.total_units(); 1316 } 1317 1318 void Connection::MaybeAddPrflxCandidate(ConnectionRequest* request, 1319 StunMessage* response) { 1320 // RFC 5245 1321 // The agent checks the mapped address from the STUN response. If the 1322 // transport address does not match any of the local candidates that the 1323 // agent knows about, the mapped address represents a new candidate -- a 1324 // peer reflexive candidate. 1325 const StunAddressAttribute* addr = 1326 response->GetAddress(STUN_ATTR_XOR_MAPPED_ADDRESS); 1327 if (!addr) { 1328 LOG(LS_WARNING) << "Connection::OnConnectionRequestResponse - " 1329 << "No MAPPED-ADDRESS or XOR-MAPPED-ADDRESS found in the " 1330 << "stun response message"; 1331 return; 1332 } 1333 1334 bool known_addr = false; 1335 for (size_t i = 0; i < port_->Candidates().size(); ++i) { 1336 if (port_->Candidates()[i].address() == addr->GetAddress()) { 1337 known_addr = true; 1338 break; 1339 } 1340 } 1341 if (known_addr) { 1342 return; 1343 } 1344 1345 // RFC 5245 1346 // Its priority is set equal to the value of the PRIORITY attribute 1347 // in the Binding request. 1348 const StunUInt32Attribute* priority_attr = 1349 request->msg()->GetUInt32(STUN_ATTR_PRIORITY); 1350 if (!priority_attr) { 1351 LOG(LS_WARNING) << "Connection::OnConnectionRequestResponse - " 1352 << "No STUN_ATTR_PRIORITY found in the " 1353 << "stun response message"; 1354 return; 1355 } 1356 const uint32 priority = priority_attr->value(); 1357 std::string id = talk_base::CreateRandomString(8); 1358 1359 Candidate new_local_candidate; 1360 new_local_candidate.set_id(id); 1361 new_local_candidate.set_component(local_candidate().component()); 1362 new_local_candidate.set_type(PRFLX_PORT_TYPE); 1363 new_local_candidate.set_protocol(local_candidate().protocol()); 1364 new_local_candidate.set_address(addr->GetAddress()); 1365 new_local_candidate.set_priority(priority); 1366 new_local_candidate.set_username(local_candidate().username()); 1367 new_local_candidate.set_password(local_candidate().password()); 1368 new_local_candidate.set_network_name(local_candidate().network_name()); 1369 new_local_candidate.set_related_address(local_candidate().address()); 1370 new_local_candidate.set_foundation( 1371 ComputeFoundation(PRFLX_PORT_TYPE, local_candidate().protocol(), 1372 local_candidate().address())); 1373 1374 // Change the local candidate of this Connection to the new prflx candidate. 1375 local_candidate_index_ = port_->AddPrflxCandidate(new_local_candidate); 1376 1377 // SignalStateChange to force a re-sort in P2PTransportChannel as this 1378 // Connection's local candidate has changed. 1379 SignalStateChange(this); 1380 } 1381 1382 ProxyConnection::ProxyConnection(Port* port, size_t index, 1383 const Candidate& candidate) 1384 : Connection(port, index, candidate), error_(0) { 1385 } 1386 1387 int ProxyConnection::Send(const void* data, size_t size) { 1388 if (write_state_ == STATE_WRITE_INIT || write_state_ == STATE_WRITE_TIMEOUT) { 1389 error_ = EWOULDBLOCK; 1390 return SOCKET_ERROR; 1391 } 1392 int sent = port_->SendTo(data, size, remote_candidate_.address(), true); 1393 if (sent <= 0) { 1394 ASSERT(sent < 0); 1395 error_ = port_->GetError(); 1396 } else { 1397 send_rate_tracker_.Update(sent); 1398 } 1399 return sent; 1400 } 1401 1402 } // namespace cricket 1403