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