1 /* 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "webrtc/p2p/base/p2ptransportchannel.h" 12 13 #include <algorithm> 14 #include <set> 15 #include "webrtc/p2p/base/common.h" 16 #include "webrtc/p2p/base/relayport.h" // For RELAY_PORT_TYPE. 17 #include "webrtc/p2p/base/stunport.h" // For STUN_PORT_TYPE. 18 #include "webrtc/base/common.h" 19 #include "webrtc/base/crc32.h" 20 #include "webrtc/base/logging.h" 21 #include "webrtc/base/stringencode.h" 22 #include "webrtc/system_wrappers/include/field_trial.h" 23 24 namespace { 25 26 // messages for queuing up work for ourselves 27 enum { MSG_SORT = 1, MSG_CHECK_AND_PING }; 28 29 // The minimum improvement in RTT that justifies a switch. 30 static const double kMinImprovement = 10; 31 32 cricket::PortInterface::CandidateOrigin GetOrigin(cricket::PortInterface* port, 33 cricket::PortInterface* origin_port) { 34 if (!origin_port) 35 return cricket::PortInterface::ORIGIN_MESSAGE; 36 else if (port == origin_port) 37 return cricket::PortInterface::ORIGIN_THIS_PORT; 38 else 39 return cricket::PortInterface::ORIGIN_OTHER_PORT; 40 } 41 42 // Compares two connections based only on static information about them. 43 int CompareConnectionCandidates(cricket::Connection* a, 44 cricket::Connection* b) { 45 // Compare connection priority. Lower values get sorted last. 46 if (a->priority() > b->priority()) 47 return 1; 48 if (a->priority() < b->priority()) 49 return -1; 50 51 // If we're still tied at this point, prefer a younger generation. 52 return (a->remote_candidate().generation() + a->port()->generation()) - 53 (b->remote_candidate().generation() + b->port()->generation()); 54 } 55 56 // Compare two connections based on their writing, receiving, and connected 57 // states. 58 int CompareConnectionStates(cricket::Connection* a, cricket::Connection* b) { 59 // Sort based on write-state. Better states have lower values. 60 if (a->write_state() < b->write_state()) 61 return 1; 62 if (a->write_state() > b->write_state()) 63 return -1; 64 65 // We prefer a receiving connection to a non-receiving, higher-priority 66 // connection when sorting connections and choosing which connection to 67 // switch to. 68 if (a->receiving() && !b->receiving()) 69 return 1; 70 if (!a->receiving() && b->receiving()) 71 return -1; 72 73 // WARNING: Some complexity here about TCP reconnecting. 74 // When a TCP connection fails because of a TCP socket disconnecting, the 75 // active side of the connection will attempt to reconnect for 5 seconds while 76 // pretending to be writable (the connection is not set to the unwritable 77 // state). On the passive side, the connection also remains writable even 78 // though it is disconnected, and a new connection is created when the active 79 // side connects. At that point, there are two TCP connections on the passive 80 // side: 1. the old, disconnected one that is pretending to be writable, and 81 // 2. the new, connected one that is maybe not yet writable. For purposes of 82 // pruning, pinging, and selecting the best connection, we want to treat the 83 // new connection as "better" than the old one. We could add a method called 84 // something like Connection::ImReallyBadEvenThoughImWritable, but that is 85 // equivalent to the existing Connection::connected(), which we already have. 86 // So, in code throughout this file, we'll check whether the connection is 87 // connected() or not, and if it is not, treat it as "worse" than a connected 88 // one, even though it's writable. In the code below, we're doing so to make 89 // sure we treat a new writable connection as better than an old disconnected 90 // connection. 91 92 // In the case where we reconnect TCP connections, the original best 93 // connection is disconnected without changing to WRITE_TIMEOUT. In this case, 94 // the new connection, when it becomes writable, should have higher priority. 95 if (a->write_state() == cricket::Connection::STATE_WRITABLE && 96 b->write_state() == cricket::Connection::STATE_WRITABLE) { 97 if (a->connected() && !b->connected()) { 98 return 1; 99 } 100 if (!a->connected() && b->connected()) { 101 return -1; 102 } 103 } 104 return 0; 105 } 106 107 int CompareConnections(cricket::Connection* a, cricket::Connection* b) { 108 int state_cmp = CompareConnectionStates(a, b); 109 if (state_cmp != 0) { 110 return state_cmp; 111 } 112 // Compare the candidate information. 113 return CompareConnectionCandidates(a, b); 114 } 115 116 // Wraps the comparison connection into a less than operator that puts higher 117 // priority writable connections first. 118 class ConnectionCompare { 119 public: 120 bool operator()(const cricket::Connection *ca, 121 const cricket::Connection *cb) { 122 cricket::Connection* a = const_cast<cricket::Connection*>(ca); 123 cricket::Connection* b = const_cast<cricket::Connection*>(cb); 124 125 // Compare first on writability and static preferences. 126 int cmp = CompareConnections(a, b); 127 if (cmp > 0) 128 return true; 129 if (cmp < 0) 130 return false; 131 132 // Otherwise, sort based on latency estimate. 133 return a->rtt() < b->rtt(); 134 135 // Should we bother checking for the last connection that last received 136 // data? It would help rendezvous on the connection that is also receiving 137 // packets. 138 // 139 // TODO: Yes we should definitely do this. The TCP protocol gains 140 // efficiency by being used bidirectionally, as opposed to two separate 141 // unidirectional streams. This test should probably occur before 142 // comparison of local prefs (assuming combined prefs are the same). We 143 // need to be careful though, not to bounce back and forth with both sides 144 // trying to rendevous with the other. 145 } 146 }; 147 148 // Determines whether we should switch between two connections, based first on 149 // connection states, static preferences, and then (if those are equal) on 150 // latency estimates. 151 bool ShouldSwitch(cricket::Connection* a_conn, 152 cricket::Connection* b_conn, 153 cricket::IceRole ice_role) { 154 if (a_conn == b_conn) 155 return false; 156 157 if (!a_conn || !b_conn) // don't think the latter should happen 158 return true; 159 160 // We prefer to switch to a writable and receiving connection over a 161 // non-writable or non-receiving connection, even if the latter has 162 // been nominated by the controlling side. 163 int state_cmp = CompareConnectionStates(a_conn, b_conn); 164 if (state_cmp != 0) { 165 return state_cmp < 0; 166 } 167 if (ice_role == cricket::ICEROLE_CONTROLLED && a_conn->nominated()) { 168 LOG(LS_VERBOSE) << "Controlled side did not switch due to nominated status"; 169 return false; 170 } 171 172 int prefs_cmp = CompareConnectionCandidates(a_conn, b_conn); 173 if (prefs_cmp != 0) { 174 return prefs_cmp < 0; 175 } 176 177 return b_conn->rtt() <= a_conn->rtt() + kMinImprovement; 178 } 179 180 } // unnamed namespace 181 182 namespace cricket { 183 184 // When the socket is unwritable, we will use 10 Kbps (ignoring IP+UDP headers) 185 // for pinging. When the socket is writable, we will use only 1 Kbps because 186 // we don't want to degrade the quality on a modem. These numbers should work 187 // well on a 28.8K modem, which is the slowest connection on which the voice 188 // quality is reasonable at all. 189 static const uint32_t PING_PACKET_SIZE = 60 * 8; 190 // TODO(honghaiz): Change the word DELAY to INTERVAL whenever appropriate. 191 // STRONG_PING_DELAY (480ms) is applied when the best connection is both 192 // writable and receiving. 193 static const uint32_t STRONG_PING_DELAY = 1000 * PING_PACKET_SIZE / 1000; 194 // WEAK_PING_DELAY (48ms) is applied when the best connection is either not 195 // writable or not receiving. 196 const uint32_t WEAK_PING_DELAY = 1000 * PING_PACKET_SIZE / 10000; 197 198 // If the current best connection is both writable and receiving, then we will 199 // also try hard to make sure it is pinged at this rate (a little less than 200 // 2 * STRONG_PING_DELAY). 201 static const uint32_t MAX_CURRENT_STRONG_DELAY = 900; 202 203 static const int MIN_CHECK_RECEIVING_DELAY = 50; // ms 204 205 P2PTransportChannel::P2PTransportChannel(const std::string& transport_name, 206 int component, 207 P2PTransport* transport, 208 PortAllocator* allocator) 209 : TransportChannelImpl(transport_name, component), 210 transport_(transport), 211 allocator_(allocator), 212 worker_thread_(rtc::Thread::Current()), 213 incoming_only_(false), 214 error_(0), 215 best_connection_(NULL), 216 pending_best_connection_(NULL), 217 sort_dirty_(false), 218 remote_ice_mode_(ICEMODE_FULL), 219 ice_role_(ICEROLE_UNKNOWN), 220 tiebreaker_(0), 221 gathering_state_(kIceGatheringNew), 222 check_receiving_delay_(MIN_CHECK_RECEIVING_DELAY * 5), 223 receiving_timeout_(MIN_CHECK_RECEIVING_DELAY * 50), 224 backup_connection_ping_interval_(0) { 225 uint32_t weak_ping_delay = ::strtoul( 226 webrtc::field_trial::FindFullName("WebRTC-StunInterPacketDelay").c_str(), 227 nullptr, 10); 228 if (weak_ping_delay) { 229 weak_ping_delay_ = weak_ping_delay; 230 } 231 } 232 233 P2PTransportChannel::~P2PTransportChannel() { 234 ASSERT(worker_thread_ == rtc::Thread::Current()); 235 236 for (size_t i = 0; i < allocator_sessions_.size(); ++i) 237 delete allocator_sessions_[i]; 238 } 239 240 // Add the allocator session to our list so that we know which sessions 241 // are still active. 242 void P2PTransportChannel::AddAllocatorSession(PortAllocatorSession* session) { 243 ASSERT(worker_thread_ == rtc::Thread::Current()); 244 245 session->set_generation(static_cast<uint32_t>(allocator_sessions_.size())); 246 allocator_sessions_.push_back(session); 247 248 // We now only want to apply new candidates that we receive to the ports 249 // created by this new session because these are replacing those of the 250 // previous sessions. 251 ports_.clear(); 252 253 session->SignalPortReady.connect(this, &P2PTransportChannel::OnPortReady); 254 session->SignalCandidatesReady.connect( 255 this, &P2PTransportChannel::OnCandidatesReady); 256 session->SignalCandidatesAllocationDone.connect( 257 this, &P2PTransportChannel::OnCandidatesAllocationDone); 258 session->StartGettingPorts(); 259 } 260 261 void P2PTransportChannel::AddConnection(Connection* connection) { 262 connections_.push_back(connection); 263 connection->set_remote_ice_mode(remote_ice_mode_); 264 connection->set_receiving_timeout(receiving_timeout_); 265 connection->SignalReadPacket.connect( 266 this, &P2PTransportChannel::OnReadPacket); 267 connection->SignalReadyToSend.connect( 268 this, &P2PTransportChannel::OnReadyToSend); 269 connection->SignalStateChange.connect( 270 this, &P2PTransportChannel::OnConnectionStateChange); 271 connection->SignalDestroyed.connect( 272 this, &P2PTransportChannel::OnConnectionDestroyed); 273 connection->SignalNominated.connect(this, &P2PTransportChannel::OnNominated); 274 had_connection_ = true; 275 } 276 277 void P2PTransportChannel::SetIceRole(IceRole ice_role) { 278 ASSERT(worker_thread_ == rtc::Thread::Current()); 279 if (ice_role_ != ice_role) { 280 ice_role_ = ice_role; 281 for (std::vector<PortInterface *>::iterator it = ports_.begin(); 282 it != ports_.end(); ++it) { 283 (*it)->SetIceRole(ice_role); 284 } 285 } 286 } 287 288 void P2PTransportChannel::SetIceTiebreaker(uint64_t tiebreaker) { 289 ASSERT(worker_thread_ == rtc::Thread::Current()); 290 if (!ports_.empty()) { 291 LOG(LS_ERROR) 292 << "Attempt to change tiebreaker after Port has been allocated."; 293 return; 294 } 295 296 tiebreaker_ = tiebreaker; 297 } 298 299 TransportChannelState P2PTransportChannel::GetState() const { 300 return state_; 301 } 302 303 // A channel is considered ICE completed once there is at most one active 304 // connection per network and at least one active connection. 305 TransportChannelState P2PTransportChannel::ComputeState() const { 306 if (!had_connection_) { 307 return TransportChannelState::STATE_INIT; 308 } 309 310 std::vector<Connection*> active_connections; 311 for (Connection* connection : connections_) { 312 if (connection->active()) { 313 active_connections.push_back(connection); 314 } 315 } 316 if (active_connections.empty()) { 317 return TransportChannelState::STATE_FAILED; 318 } 319 320 std::set<rtc::Network*> networks; 321 for (Connection* connection : active_connections) { 322 rtc::Network* network = connection->port()->Network(); 323 if (networks.find(network) == networks.end()) { 324 networks.insert(network); 325 } else { 326 LOG_J(LS_VERBOSE, this) << "Ice not completed yet for this channel as " 327 << network->ToString() 328 << " has more than 1 connection."; 329 return TransportChannelState::STATE_CONNECTING; 330 } 331 } 332 333 LOG_J(LS_VERBOSE, this) << "Ice is completed for this channel."; 334 return TransportChannelState::STATE_COMPLETED; 335 } 336 337 void P2PTransportChannel::SetIceCredentials(const std::string& ice_ufrag, 338 const std::string& ice_pwd) { 339 ASSERT(worker_thread_ == rtc::Thread::Current()); 340 ice_ufrag_ = ice_ufrag; 341 ice_pwd_ = ice_pwd; 342 // Note: Candidate gathering will restart when MaybeStartGathering is next 343 // called. 344 } 345 346 void P2PTransportChannel::SetRemoteIceCredentials(const std::string& ice_ufrag, 347 const std::string& ice_pwd) { 348 ASSERT(worker_thread_ == rtc::Thread::Current()); 349 IceParameters* current_ice = remote_ice(); 350 IceParameters new_ice(ice_ufrag, ice_pwd); 351 if (!current_ice || *current_ice != new_ice) { 352 // Keep the ICE credentials so that newer connections 353 // are prioritized over the older ones. 354 remote_ice_parameters_.push_back(new_ice); 355 } 356 357 // Update the pwd of remote candidate if needed. 358 for (RemoteCandidate& candidate : remote_candidates_) { 359 if (candidate.username() == ice_ufrag && candidate.password().empty()) { 360 candidate.set_password(ice_pwd); 361 } 362 } 363 // We need to update the credentials for any peer reflexive candidates. 364 for (Connection* conn : connections_) { 365 conn->MaybeSetRemoteIceCredentials(ice_ufrag, ice_pwd); 366 } 367 } 368 369 void P2PTransportChannel::SetRemoteIceMode(IceMode mode) { 370 remote_ice_mode_ = mode; 371 } 372 373 void P2PTransportChannel::SetIceConfig(const IceConfig& config) { 374 gather_continually_ = config.gather_continually; 375 LOG(LS_INFO) << "Set gather_continually to " << gather_continually_; 376 377 if (config.backup_connection_ping_interval >= 0 && 378 backup_connection_ping_interval_ != 379 config.backup_connection_ping_interval) { 380 backup_connection_ping_interval_ = config.backup_connection_ping_interval; 381 LOG(LS_INFO) << "Set backup connection ping interval to " 382 << backup_connection_ping_interval_ << " milliseconds."; 383 } 384 385 if (config.receiving_timeout_ms >= 0 && 386 receiving_timeout_ != config.receiving_timeout_ms) { 387 receiving_timeout_ = config.receiving_timeout_ms; 388 check_receiving_delay_ = 389 std::max(MIN_CHECK_RECEIVING_DELAY, receiving_timeout_ / 10); 390 391 for (Connection* connection : connections_) { 392 connection->set_receiving_timeout(receiving_timeout_); 393 } 394 LOG(LS_INFO) << "Set ICE receiving timeout to " << receiving_timeout_ 395 << " milliseconds"; 396 } 397 } 398 399 // Go into the state of processing candidates, and running in general 400 void P2PTransportChannel::Connect() { 401 ASSERT(worker_thread_ == rtc::Thread::Current()); 402 if (ice_ufrag_.empty() || ice_pwd_.empty()) { 403 ASSERT(false); 404 LOG(LS_ERROR) << "P2PTransportChannel::Connect: The ice_ufrag_ and the " 405 << "ice_pwd_ are not set."; 406 return; 407 } 408 409 // Start checking and pinging as the ports come in. 410 thread()->Post(this, MSG_CHECK_AND_PING); 411 } 412 413 void P2PTransportChannel::MaybeStartGathering() { 414 // Start gathering if we never started before, or if an ICE restart occurred. 415 if (allocator_sessions_.empty() || 416 IceCredentialsChanged(allocator_sessions_.back()->ice_ufrag(), 417 allocator_sessions_.back()->ice_pwd(), ice_ufrag_, 418 ice_pwd_)) { 419 if (gathering_state_ != kIceGatheringGathering) { 420 gathering_state_ = kIceGatheringGathering; 421 SignalGatheringState(this); 422 } 423 // Time for a new allocator 424 AddAllocatorSession(allocator_->CreateSession( 425 SessionId(), transport_name(), component(), ice_ufrag_, ice_pwd_)); 426 } 427 } 428 429 // A new port is available, attempt to make connections for it 430 void P2PTransportChannel::OnPortReady(PortAllocatorSession *session, 431 PortInterface* port) { 432 ASSERT(worker_thread_ == rtc::Thread::Current()); 433 434 // Set in-effect options on the new port 435 for (OptionMap::const_iterator it = options_.begin(); 436 it != options_.end(); 437 ++it) { 438 int val = port->SetOption(it->first, it->second); 439 if (val < 0) { 440 LOG_J(LS_WARNING, port) << "SetOption(" << it->first 441 << ", " << it->second 442 << ") failed: " << port->GetError(); 443 } 444 } 445 446 // Remember the ports and candidates, and signal that candidates are ready. 447 // The session will handle this, and send an initiate/accept/modify message 448 // if one is pending. 449 450 port->SetIceRole(ice_role_); 451 port->SetIceTiebreaker(tiebreaker_); 452 ports_.push_back(port); 453 port->SignalUnknownAddress.connect( 454 this, &P2PTransportChannel::OnUnknownAddress); 455 port->SignalDestroyed.connect(this, &P2PTransportChannel::OnPortDestroyed); 456 port->SignalRoleConflict.connect( 457 this, &P2PTransportChannel::OnRoleConflict); 458 port->SignalSentPacket.connect(this, &P2PTransportChannel::OnSentPacket); 459 460 // Attempt to create a connection from this new port to all of the remote 461 // candidates that we were given so far. 462 463 std::vector<RemoteCandidate>::iterator iter; 464 for (iter = remote_candidates_.begin(); iter != remote_candidates_.end(); 465 ++iter) { 466 CreateConnection(port, *iter, iter->origin_port()); 467 } 468 469 SortConnections(); 470 } 471 472 // A new candidate is available, let listeners know 473 void P2PTransportChannel::OnCandidatesReady( 474 PortAllocatorSession* session, 475 const std::vector<Candidate>& candidates) { 476 ASSERT(worker_thread_ == rtc::Thread::Current()); 477 for (size_t i = 0; i < candidates.size(); ++i) { 478 SignalCandidateGathered(this, candidates[i]); 479 } 480 } 481 482 void P2PTransportChannel::OnCandidatesAllocationDone( 483 PortAllocatorSession* session) { 484 ASSERT(worker_thread_ == rtc::Thread::Current()); 485 gathering_state_ = kIceGatheringComplete; 486 LOG(LS_INFO) << "P2PTransportChannel: " << transport_name() << ", component " 487 << component() << " gathering complete"; 488 SignalGatheringState(this); 489 } 490 491 // Handle stun packets 492 void P2PTransportChannel::OnUnknownAddress( 493 PortInterface* port, 494 const rtc::SocketAddress& address, ProtocolType proto, 495 IceMessage* stun_msg, const std::string &remote_username, 496 bool port_muxed) { 497 ASSERT(worker_thread_ == rtc::Thread::Current()); 498 499 // Port has received a valid stun packet from an address that no Connection 500 // is currently available for. See if we already have a candidate with the 501 // address. If it isn't we need to create new candidate for it. 502 503 // Determine if the remote candidates use shared ufrag. 504 bool ufrag_per_port = false; 505 std::vector<RemoteCandidate>::iterator it; 506 if (remote_candidates_.size() > 0) { 507 it = remote_candidates_.begin(); 508 std::string username = it->username(); 509 for (; it != remote_candidates_.end(); ++it) { 510 if (it->username() != username) { 511 ufrag_per_port = true; 512 break; 513 } 514 } 515 } 516 517 const Candidate* candidate = NULL; 518 std::string remote_password; 519 for (it = remote_candidates_.begin(); it != remote_candidates_.end(); ++it) { 520 if (it->username() == remote_username) { 521 remote_password = it->password(); 522 if (ufrag_per_port || 523 (it->address() == address && 524 it->protocol() == ProtoToString(proto))) { 525 candidate = &(*it); 526 break; 527 } 528 // We don't want to break here because we may find a match of the address 529 // later. 530 } 531 } 532 533 uint32_t remote_generation = 0; 534 // The STUN binding request may arrive after setRemoteDescription and before 535 // adding remote candidate, so we need to set the password to the shared 536 // password if the user name matches. 537 if (remote_password.empty()) { 538 const IceParameters* ice_param = 539 FindRemoteIceFromUfrag(remote_username, &remote_generation); 540 // Note: if not found, the remote_generation will still be 0. 541 if (ice_param != nullptr) { 542 remote_password = ice_param->pwd; 543 } 544 } 545 546 Candidate remote_candidate; 547 bool remote_candidate_is_new = (candidate == nullptr); 548 if (!remote_candidate_is_new) { 549 remote_candidate = *candidate; 550 if (ufrag_per_port) { 551 remote_candidate.set_address(address); 552 } 553 } else { 554 // Create a new candidate with this address. 555 int remote_candidate_priority; 556 557 // The priority of the candidate is set to the PRIORITY attribute 558 // from the request. 559 const StunUInt32Attribute* priority_attr = 560 stun_msg->GetUInt32(STUN_ATTR_PRIORITY); 561 if (!priority_attr) { 562 LOG(LS_WARNING) << "P2PTransportChannel::OnUnknownAddress - " 563 << "No STUN_ATTR_PRIORITY found in the " 564 << "stun request message"; 565 port->SendBindingErrorResponse(stun_msg, address, STUN_ERROR_BAD_REQUEST, 566 STUN_ERROR_REASON_BAD_REQUEST); 567 return; 568 } 569 remote_candidate_priority = priority_attr->value(); 570 571 // RFC 5245 572 // If the source transport address of the request does not match any 573 // existing remote candidates, it represents a new peer reflexive remote 574 // candidate. 575 remote_candidate = Candidate(component(), ProtoToString(proto), address, 0, 576 remote_username, remote_password, 577 PRFLX_PORT_TYPE, remote_generation, ""); 578 579 // From RFC 5245, section-7.2.1.3: 580 // The foundation of the candidate is set to an arbitrary value, different 581 // from the foundation for all other remote candidates. 582 remote_candidate.set_foundation( 583 rtc::ToString<uint32_t>(rtc::ComputeCrc32(remote_candidate.id()))); 584 585 remote_candidate.set_priority(remote_candidate_priority); 586 } 587 588 // RFC5245, the agent constructs a pair whose local candidate is equal to 589 // the transport address on which the STUN request was received, and a 590 // remote candidate equal to the source transport address where the 591 // request came from. 592 593 // There shouldn't be an existing connection with this remote address. 594 // When ports are muxed, this channel might get multiple unknown address 595 // signals. In that case if the connection is already exists, we should 596 // simply ignore the signal otherwise send server error. 597 if (port->GetConnection(remote_candidate.address())) { 598 if (port_muxed) { 599 LOG(LS_INFO) << "Connection already exists for peer reflexive " 600 << "candidate: " << remote_candidate.ToString(); 601 return; 602 } else { 603 ASSERT(false); 604 port->SendBindingErrorResponse(stun_msg, address, 605 STUN_ERROR_SERVER_ERROR, 606 STUN_ERROR_REASON_SERVER_ERROR); 607 return; 608 } 609 } 610 611 Connection* connection = port->CreateConnection( 612 remote_candidate, cricket::PortInterface::ORIGIN_THIS_PORT); 613 if (!connection) { 614 ASSERT(false); 615 port->SendBindingErrorResponse(stun_msg, address, STUN_ERROR_SERVER_ERROR, 616 STUN_ERROR_REASON_SERVER_ERROR); 617 return; 618 } 619 620 LOG(LS_INFO) << "Adding connection from " 621 << (remote_candidate_is_new ? "peer reflexive" : "resurrected") 622 << " candidate: " << remote_candidate.ToString(); 623 AddConnection(connection); 624 connection->HandleBindingRequest(stun_msg); 625 626 // Update the list of connections since we just added another. We do this 627 // after sending the response since it could (in principle) delete the 628 // connection in question. 629 SortConnections(); 630 } 631 632 void P2PTransportChannel::OnRoleConflict(PortInterface* port) { 633 SignalRoleConflict(this); // STUN ping will be sent when SetRole is called 634 // from Transport. 635 } 636 637 const IceParameters* P2PTransportChannel::FindRemoteIceFromUfrag( 638 const std::string& ufrag, 639 uint32_t* generation) { 640 const auto& params = remote_ice_parameters_; 641 auto it = std::find_if( 642 params.rbegin(), params.rend(), 643 [ufrag](const IceParameters& param) { return param.ufrag == ufrag; }); 644 if (it == params.rend()) { 645 // Not found. 646 return nullptr; 647 } 648 *generation = params.rend() - it - 1; 649 return &(*it); 650 } 651 652 void P2PTransportChannel::OnNominated(Connection* conn) { 653 ASSERT(worker_thread_ == rtc::Thread::Current()); 654 ASSERT(ice_role_ == ICEROLE_CONTROLLED); 655 656 if (conn->write_state() == Connection::STATE_WRITABLE) { 657 if (best_connection_ != conn) { 658 pending_best_connection_ = NULL; 659 LOG(LS_INFO) << "Switching best connection on controlled side: " 660 << conn->ToString(); 661 SwitchBestConnectionTo(conn); 662 // Now we have selected the best connection, time to prune other existing 663 // connections and update the read/write state of the channel. 664 RequestSort(); 665 } 666 } else { 667 LOG(LS_INFO) << "Not switching the best connection on controlled side yet," 668 << " because it's not writable: " << conn->ToString(); 669 pending_best_connection_ = conn; 670 } 671 } 672 673 void P2PTransportChannel::AddRemoteCandidate(const Candidate& candidate) { 674 ASSERT(worker_thread_ == rtc::Thread::Current()); 675 676 uint32_t generation = GetRemoteCandidateGeneration(candidate); 677 // If a remote candidate with a previous generation arrives, drop it. 678 if (generation < remote_ice_generation()) { 679 LOG(LS_WARNING) << "Dropping a remote candidate because its ufrag " 680 << candidate.username() 681 << " indicates it was for a previous generation."; 682 return; 683 } 684 685 Candidate new_remote_candidate(candidate); 686 new_remote_candidate.set_generation(generation); 687 // ICE candidates don't need to have username and password set, but 688 // the code below this (specifically, ConnectionRequest::Prepare in 689 // port.cc) uses the remote candidates's username. So, we set it 690 // here. 691 if (remote_ice()) { 692 if (candidate.username().empty()) { 693 new_remote_candidate.set_username(remote_ice()->ufrag); 694 } 695 if (new_remote_candidate.username() == remote_ice()->ufrag) { 696 if (candidate.password().empty()) { 697 new_remote_candidate.set_password(remote_ice()->pwd); 698 } 699 } else { 700 // The candidate belongs to the next generation. Its pwd will be set 701 // when the new remote ICE credentials arrive. 702 LOG(LS_WARNING) << "A remote candidate arrives with an unknown ufrag: " 703 << candidate.username(); 704 } 705 } 706 707 // Create connections to this remote candidate. 708 CreateConnections(new_remote_candidate, NULL); 709 710 // Resort the connections list, which may have new elements. 711 SortConnections(); 712 } 713 714 // Creates connections from all of the ports that we care about to the given 715 // remote candidate. The return value is true if we created a connection from 716 // the origin port. 717 bool P2PTransportChannel::CreateConnections(const Candidate& remote_candidate, 718 PortInterface* origin_port) { 719 ASSERT(worker_thread_ == rtc::Thread::Current()); 720 721 // If we've already seen the new remote candidate (in the current candidate 722 // generation), then we shouldn't try creating connections for it. 723 // We either already have a connection for it, or we previously created one 724 // and then later pruned it. If we don't return, the channel will again 725 // re-create any connections that were previously pruned, which will then 726 // immediately be re-pruned, churning the network for no purpose. 727 // This only applies to candidates received over signaling (i.e. origin_port 728 // is NULL). 729 if (!origin_port && IsDuplicateRemoteCandidate(remote_candidate)) { 730 // return true to indicate success, without creating any new connections. 731 return true; 732 } 733 734 // Add a new connection for this candidate to every port that allows such a 735 // connection (i.e., if they have compatible protocols) and that does not 736 // already have a connection to an equivalent candidate. We must be careful 737 // to make sure that the origin port is included, even if it was pruned, 738 // since that may be the only port that can create this connection. 739 bool created = false; 740 std::vector<PortInterface *>::reverse_iterator it; 741 for (it = ports_.rbegin(); it != ports_.rend(); ++it) { 742 if (CreateConnection(*it, remote_candidate, origin_port)) { 743 if (*it == origin_port) 744 created = true; 745 } 746 } 747 748 if ((origin_port != NULL) && 749 std::find(ports_.begin(), ports_.end(), origin_port) == ports_.end()) { 750 if (CreateConnection(origin_port, remote_candidate, origin_port)) 751 created = true; 752 } 753 754 // Remember this remote candidate so that we can add it to future ports. 755 RememberRemoteCandidate(remote_candidate, origin_port); 756 757 return created; 758 } 759 760 // Setup a connection object for the local and remote candidate combination. 761 // And then listen to connection object for changes. 762 bool P2PTransportChannel::CreateConnection(PortInterface* port, 763 const Candidate& remote_candidate, 764 PortInterface* origin_port) { 765 if (!port->SupportsProtocol(remote_candidate.protocol())) { 766 return false; 767 } 768 // Look for an existing connection with this remote address. If one is not 769 // found, then we can create a new connection for this address. 770 Connection* connection = port->GetConnection(remote_candidate.address()); 771 if (connection != NULL) { 772 connection->MaybeUpdatePeerReflexiveCandidate(remote_candidate); 773 774 // It is not legal to try to change any of the parameters of an existing 775 // connection; however, the other side can send a duplicate candidate. 776 if (!remote_candidate.IsEquivalent(connection->remote_candidate())) { 777 LOG(INFO) << "Attempt to change a remote candidate." 778 << " Existing remote candidate: " 779 << connection->remote_candidate().ToString() 780 << "New remote candidate: " 781 << remote_candidate.ToString(); 782 return false; 783 } 784 } else { 785 PortInterface::CandidateOrigin origin = GetOrigin(port, origin_port); 786 787 // Don't create connection if this is a candidate we received in a 788 // message and we are not allowed to make outgoing connections. 789 if (origin == cricket::PortInterface::ORIGIN_MESSAGE && incoming_only_) 790 return false; 791 792 connection = port->CreateConnection(remote_candidate, origin); 793 if (!connection) 794 return false; 795 796 AddConnection(connection); 797 798 LOG_J(LS_INFO, this) << "Created connection with origin=" << origin << ", (" 799 << connections_.size() << " total)"; 800 } 801 802 return true; 803 } 804 805 bool P2PTransportChannel::FindConnection( 806 cricket::Connection* connection) const { 807 std::vector<Connection*>::const_iterator citer = 808 std::find(connections_.begin(), connections_.end(), connection); 809 return citer != connections_.end(); 810 } 811 812 uint32_t P2PTransportChannel::GetRemoteCandidateGeneration( 813 const Candidate& candidate) { 814 // If the candidate has a ufrag, use it to find the generation. 815 if (!candidate.username().empty()) { 816 uint32_t generation = 0; 817 if (!FindRemoteIceFromUfrag(candidate.username(), &generation)) { 818 // If the ufrag is not found, assume the next/future generation. 819 generation = static_cast<uint32_t>(remote_ice_parameters_.size()); 820 } 821 return generation; 822 } 823 // If candidate generation is set, use that. 824 if (candidate.generation() > 0) { 825 return candidate.generation(); 826 } 827 // Otherwise, assume the generation from remote ice parameters. 828 return remote_ice_generation(); 829 } 830 831 // Check if remote candidate is already cached. 832 bool P2PTransportChannel::IsDuplicateRemoteCandidate( 833 const Candidate& candidate) { 834 for (size_t i = 0; i < remote_candidates_.size(); ++i) { 835 if (remote_candidates_[i].IsEquivalent(candidate)) { 836 return true; 837 } 838 } 839 return false; 840 } 841 842 // Maintain our remote candidate list, adding this new remote one. 843 void P2PTransportChannel::RememberRemoteCandidate( 844 const Candidate& remote_candidate, PortInterface* origin_port) { 845 // Remove any candidates whose generation is older than this one. The 846 // presence of a new generation indicates that the old ones are not useful. 847 size_t i = 0; 848 while (i < remote_candidates_.size()) { 849 if (remote_candidates_[i].generation() < remote_candidate.generation()) { 850 LOG(INFO) << "Pruning candidate from old generation: " 851 << remote_candidates_[i].address().ToSensitiveString(); 852 remote_candidates_.erase(remote_candidates_.begin() + i); 853 } else { 854 i += 1; 855 } 856 } 857 858 // Make sure this candidate is not a duplicate. 859 if (IsDuplicateRemoteCandidate(remote_candidate)) { 860 LOG(INFO) << "Duplicate candidate: " << remote_candidate.ToString(); 861 return; 862 } 863 864 // Try this candidate for all future ports. 865 remote_candidates_.push_back(RemoteCandidate(remote_candidate, origin_port)); 866 } 867 868 // Set options on ourselves is simply setting options on all of our available 869 // port objects. 870 int P2PTransportChannel::SetOption(rtc::Socket::Option opt, int value) { 871 ASSERT(worker_thread_ == rtc::Thread::Current()); 872 OptionMap::iterator it = options_.find(opt); 873 if (it == options_.end()) { 874 options_.insert(std::make_pair(opt, value)); 875 } else if (it->second == value) { 876 return 0; 877 } else { 878 it->second = value; 879 } 880 881 for (size_t i = 0; i < ports_.size(); ++i) { 882 int val = ports_[i]->SetOption(opt, value); 883 if (val < 0) { 884 // Because this also occurs deferred, probably no point in reporting an 885 // error 886 LOG(WARNING) << "SetOption(" << opt << ", " << value << ") failed: " 887 << ports_[i]->GetError(); 888 } 889 } 890 return 0; 891 } 892 893 bool P2PTransportChannel::GetOption(rtc::Socket::Option opt, int* value) { 894 ASSERT(worker_thread_ == rtc::Thread::Current()); 895 896 const auto& found = options_.find(opt); 897 if (found == options_.end()) { 898 return false; 899 } 900 *value = found->second; 901 return true; 902 } 903 904 // Send data to the other side, using our best connection. 905 int P2PTransportChannel::SendPacket(const char *data, size_t len, 906 const rtc::PacketOptions& options, 907 int flags) { 908 ASSERT(worker_thread_ == rtc::Thread::Current()); 909 if (flags != 0) { 910 error_ = EINVAL; 911 return -1; 912 } 913 if (best_connection_ == NULL) { 914 error_ = EWOULDBLOCK; 915 return -1; 916 } 917 918 int sent = best_connection_->Send(data, len, options); 919 if (sent <= 0) { 920 ASSERT(sent < 0); 921 error_ = best_connection_->GetError(); 922 } 923 return sent; 924 } 925 926 bool P2PTransportChannel::GetStats(ConnectionInfos *infos) { 927 ASSERT(worker_thread_ == rtc::Thread::Current()); 928 // Gather connection infos. 929 infos->clear(); 930 931 std::vector<Connection *>::const_iterator it; 932 for (Connection* connection : connections_) { 933 ConnectionInfo info; 934 info.best_connection = (best_connection_ == connection); 935 info.receiving = connection->receiving(); 936 info.writable = 937 (connection->write_state() == Connection::STATE_WRITABLE); 938 info.timeout = 939 (connection->write_state() == Connection::STATE_WRITE_TIMEOUT); 940 info.new_connection = !connection->reported(); 941 connection->set_reported(true); 942 info.rtt = connection->rtt(); 943 info.sent_total_bytes = connection->sent_total_bytes(); 944 info.sent_bytes_second = connection->sent_bytes_second(); 945 info.sent_discarded_packets = connection->sent_discarded_packets(); 946 info.sent_total_packets = connection->sent_total_packets(); 947 info.recv_total_bytes = connection->recv_total_bytes(); 948 info.recv_bytes_second = connection->recv_bytes_second(); 949 info.local_candidate = connection->local_candidate(); 950 info.remote_candidate = connection->remote_candidate(); 951 info.key = connection; 952 infos->push_back(info); 953 } 954 955 return true; 956 } 957 958 rtc::DiffServCodePoint P2PTransportChannel::DefaultDscpValue() const { 959 OptionMap::const_iterator it = options_.find(rtc::Socket::OPT_DSCP); 960 if (it == options_.end()) { 961 return rtc::DSCP_NO_CHANGE; 962 } 963 return static_cast<rtc::DiffServCodePoint> (it->second); 964 } 965 966 // Monitor connection states. 967 void P2PTransportChannel::UpdateConnectionStates() { 968 uint32_t now = rtc::Time(); 969 970 // We need to copy the list of connections since some may delete themselves 971 // when we call UpdateState. 972 for (size_t i = 0; i < connections_.size(); ++i) 973 connections_[i]->UpdateState(now); 974 } 975 976 // Prepare for best candidate sorting. 977 void P2PTransportChannel::RequestSort() { 978 if (!sort_dirty_) { 979 worker_thread_->Post(this, MSG_SORT); 980 sort_dirty_ = true; 981 } 982 } 983 984 // Sort the available connections to find the best one. We also monitor 985 // the number of available connections and the current state. 986 void P2PTransportChannel::SortConnections() { 987 ASSERT(worker_thread_ == rtc::Thread::Current()); 988 989 // Make sure the connection states are up-to-date since this affects how they 990 // will be sorted. 991 UpdateConnectionStates(); 992 993 // Any changes after this point will require a re-sort. 994 sort_dirty_ = false; 995 996 // Find the best alternative connection by sorting. It is important to note 997 // that amongst equal preference, writable connections, this will choose the 998 // one whose estimated latency is lowest. So it is the only one that we 999 // need to consider switching to. 1000 ConnectionCompare cmp; 1001 std::stable_sort(connections_.begin(), connections_.end(), cmp); 1002 LOG(LS_VERBOSE) << "Sorting " << connections_.size() 1003 << " available connections:"; 1004 for (size_t i = 0; i < connections_.size(); ++i) { 1005 LOG(LS_VERBOSE) << connections_[i]->ToString(); 1006 } 1007 1008 Connection* top_connection = 1009 (connections_.size() > 0) ? connections_[0] : nullptr; 1010 1011 // If necessary, switch to the new choice. 1012 // Note that |top_connection| doesn't have to be writable to become the best 1013 // connection although it will have higher priority if it is writable. 1014 if (ShouldSwitch(best_connection_, top_connection, ice_role_)) { 1015 LOG(LS_INFO) << "Switching best connection: " << top_connection->ToString(); 1016 SwitchBestConnectionTo(top_connection); 1017 } 1018 1019 // Controlled side can prune only if the best connection has been nominated. 1020 // because otherwise it may delete the connection that will be selected by 1021 // the controlling side. 1022 if (ice_role_ == ICEROLE_CONTROLLING || best_nominated_connection()) { 1023 PruneConnections(); 1024 } 1025 1026 // Check if all connections are timedout. 1027 bool all_connections_timedout = true; 1028 for (size_t i = 0; i < connections_.size(); ++i) { 1029 if (connections_[i]->write_state() != Connection::STATE_WRITE_TIMEOUT) { 1030 all_connections_timedout = false; 1031 break; 1032 } 1033 } 1034 1035 // Now update the writable state of the channel with the information we have 1036 // so far. 1037 if (all_connections_timedout) { 1038 HandleAllTimedOut(); 1039 } 1040 1041 // Update the state of this channel. This method is called whenever the 1042 // state of any connection changes, so this is a good place to do this. 1043 UpdateState(); 1044 } 1045 1046 Connection* P2PTransportChannel::best_nominated_connection() const { 1047 return (best_connection_ && best_connection_->nominated()) ? best_connection_ 1048 : nullptr; 1049 } 1050 1051 void P2PTransportChannel::PruneConnections() { 1052 // We can prune any connection for which there is a connected, writable 1053 // connection on the same network with better or equal priority. We leave 1054 // those with better priority just in case they become writable later (at 1055 // which point, we would prune out the current best connection). We leave 1056 // connections on other networks because they may not be using the same 1057 // resources and they may represent very distinct paths over which we can 1058 // switch. If the |premier| connection is not connected, we may be 1059 // reconnecting a TCP connection and temporarily do not prune connections in 1060 // this network. See the big comment in CompareConnections. 1061 1062 // Get a list of the networks that we are using. 1063 std::set<rtc::Network*> networks; 1064 for (const Connection* conn : connections_) { 1065 networks.insert(conn->port()->Network()); 1066 } 1067 for (rtc::Network* network : networks) { 1068 Connection* premier = GetBestConnectionOnNetwork(network); 1069 // Do not prune connections if the current best connection is weak on this 1070 // network. Otherwise, it may delete connections prematurely. 1071 if (!premier || premier->weak()) { 1072 continue; 1073 } 1074 1075 for (Connection* conn : connections_) { 1076 if ((conn != premier) && (conn->port()->Network() == network) && 1077 (CompareConnectionCandidates(premier, conn) >= 0)) { 1078 conn->Prune(); 1079 } 1080 } 1081 } 1082 } 1083 1084 // Track the best connection, and let listeners know 1085 void P2PTransportChannel::SwitchBestConnectionTo(Connection* conn) { 1086 // Note: if conn is NULL, the previous best_connection_ has been destroyed, 1087 // so don't use it. 1088 Connection* old_best_connection = best_connection_; 1089 best_connection_ = conn; 1090 if (best_connection_) { 1091 if (old_best_connection) { 1092 LOG_J(LS_INFO, this) << "Previous best connection: " 1093 << old_best_connection->ToString(); 1094 } 1095 LOG_J(LS_INFO, this) << "New best connection: " 1096 << best_connection_->ToString(); 1097 SignalRouteChange(this, best_connection_->remote_candidate()); 1098 } else { 1099 LOG_J(LS_INFO, this) << "No best connection"; 1100 } 1101 } 1102 1103 // Warning: UpdateState should eventually be called whenever a connection 1104 // is added, deleted, or the write state of any connection changes so that the 1105 // transport controller will get the up-to-date channel state. However it 1106 // should not be called too often; in the case that multiple connection states 1107 // change, it should be called after all the connection states have changed. For 1108 // example, we call this at the end of SortConnections. 1109 void P2PTransportChannel::UpdateState() { 1110 state_ = ComputeState(); 1111 1112 bool writable = best_connection_ && best_connection_->writable(); 1113 set_writable(writable); 1114 1115 bool receiving = false; 1116 for (const Connection* connection : connections_) { 1117 if (connection->receiving()) { 1118 receiving = true; 1119 break; 1120 } 1121 } 1122 set_receiving(receiving); 1123 } 1124 1125 void P2PTransportChannel::MaybeStopPortAllocatorSessions() { 1126 if (!IsGettingPorts()) { 1127 return; 1128 } 1129 1130 for (PortAllocatorSession* session : allocator_sessions_) { 1131 if (!session->IsGettingPorts()) { 1132 continue; 1133 } 1134 // If gathering continually, keep the last session running so that it 1135 // will gather candidates if the networks change. 1136 if (gather_continually_ && session == allocator_sessions_.back()) { 1137 session->ClearGettingPorts(); 1138 break; 1139 } 1140 session->StopGettingPorts(); 1141 } 1142 } 1143 1144 // If all connections timed out, delete them all. 1145 void P2PTransportChannel::HandleAllTimedOut() { 1146 for (Connection* connection : connections_) { 1147 connection->Destroy(); 1148 } 1149 } 1150 1151 bool P2PTransportChannel::weak() const { 1152 return !best_connection_ || best_connection_->weak(); 1153 } 1154 1155 // If we have a best connection, return it, otherwise return top one in the 1156 // list (later we will mark it best). 1157 Connection* P2PTransportChannel::GetBestConnectionOnNetwork( 1158 rtc::Network* network) const { 1159 // If the best connection is on this network, then it wins. 1160 if (best_connection_ && (best_connection_->port()->Network() == network)) 1161 return best_connection_; 1162 1163 // Otherwise, we return the top-most in sorted order. 1164 for (size_t i = 0; i < connections_.size(); ++i) { 1165 if (connections_[i]->port()->Network() == network) 1166 return connections_[i]; 1167 } 1168 1169 return NULL; 1170 } 1171 1172 // Handle any queued up requests 1173 void P2PTransportChannel::OnMessage(rtc::Message *pmsg) { 1174 switch (pmsg->message_id) { 1175 case MSG_SORT: 1176 OnSort(); 1177 break; 1178 case MSG_CHECK_AND_PING: 1179 OnCheckAndPing(); 1180 break; 1181 default: 1182 ASSERT(false); 1183 break; 1184 } 1185 } 1186 1187 // Handle queued up sort request 1188 void P2PTransportChannel::OnSort() { 1189 // Resort the connections based on the new statistics. 1190 SortConnections(); 1191 } 1192 1193 // Handle queued up check-and-ping request 1194 void P2PTransportChannel::OnCheckAndPing() { 1195 // Make sure the states of the connections are up-to-date (since this affects 1196 // which ones are pingable). 1197 UpdateConnectionStates(); 1198 // When the best connection is either not receiving or not writable, 1199 // switch to weak ping delay. 1200 int ping_delay = weak() ? weak_ping_delay_ : STRONG_PING_DELAY; 1201 if (rtc::Time() >= last_ping_sent_ms_ + ping_delay) { 1202 Connection* conn = FindNextPingableConnection(); 1203 if (conn) { 1204 PingConnection(conn); 1205 } 1206 } 1207 int check_delay = std::min(ping_delay, check_receiving_delay_); 1208 thread()->PostDelayed(check_delay, this, MSG_CHECK_AND_PING); 1209 } 1210 1211 // A connection is considered a backup connection if the channel state 1212 // is completed, the connection is not the best connection and it is active. 1213 bool P2PTransportChannel::IsBackupConnection(Connection* conn) const { 1214 return state_ == STATE_COMPLETED && conn != best_connection_ && 1215 conn->active(); 1216 } 1217 1218 // Is the connection in a state for us to even consider pinging the other side? 1219 // We consider a connection pingable even if it's not connected because that's 1220 // how a TCP connection is kicked into reconnecting on the active side. 1221 bool P2PTransportChannel::IsPingable(Connection* conn, uint32_t now) { 1222 const Candidate& remote = conn->remote_candidate(); 1223 // We should never get this far with an empty remote ufrag. 1224 ASSERT(!remote.username().empty()); 1225 if (remote.username().empty() || remote.password().empty()) { 1226 // If we don't have an ICE ufrag and pwd, there's no way we can ping. 1227 return false; 1228 } 1229 1230 // An never connected connection cannot be written to at all, so pinging is 1231 // out of the question. However, if it has become WRITABLE, it is in the 1232 // reconnecting state so ping is needed. 1233 if (!conn->connected() && !conn->writable()) { 1234 return false; 1235 } 1236 1237 // If the channel is weakly connected, ping all connections. 1238 if (weak()) { 1239 return true; 1240 } 1241 1242 // Always ping active connections regardless whether the channel is completed 1243 // or not, but backup connections are pinged at a slower rate. 1244 if (IsBackupConnection(conn)) { 1245 return (now >= conn->last_ping_response_received() + 1246 backup_connection_ping_interval_); 1247 } 1248 return conn->active(); 1249 } 1250 1251 // Returns the next pingable connection to ping. This will be the oldest 1252 // pingable connection unless we have a connected, writable connection that is 1253 // past the maximum acceptable ping delay. When reconnecting a TCP connection, 1254 // the best connection is disconnected, although still WRITABLE while 1255 // reconnecting. The newly created connection should be selected as the ping 1256 // target to become writable instead. See the big comment in CompareConnections. 1257 Connection* P2PTransportChannel::FindNextPingableConnection() { 1258 uint32_t now = rtc::Time(); 1259 if (best_connection_ && best_connection_->connected() && 1260 best_connection_->writable() && 1261 (best_connection_->last_ping_sent() + MAX_CURRENT_STRONG_DELAY <= now)) { 1262 return best_connection_; 1263 } 1264 1265 // First, find "triggered checks". We ping first those connections 1266 // that have received a ping but have not sent a ping since receiving 1267 // it (last_received_ping > last_sent_ping). But we shouldn't do 1268 // triggered checks if the connection is already writable. 1269 Connection* oldest_needing_triggered_check = nullptr; 1270 Connection* oldest = nullptr; 1271 for (Connection* conn : connections_) { 1272 if (!IsPingable(conn, now)) { 1273 continue; 1274 } 1275 bool needs_triggered_check = 1276 (!conn->writable() && 1277 conn->last_ping_received() > conn->last_ping_sent()); 1278 if (needs_triggered_check && 1279 (!oldest_needing_triggered_check || 1280 (conn->last_ping_received() < 1281 oldest_needing_triggered_check->last_ping_received()))) { 1282 oldest_needing_triggered_check = conn; 1283 } 1284 if (!oldest || (conn->last_ping_sent() < oldest->last_ping_sent())) { 1285 oldest = conn; 1286 } 1287 } 1288 1289 if (oldest_needing_triggered_check) { 1290 LOG(LS_INFO) << "Selecting connection for triggered check: " << 1291 oldest_needing_triggered_check->ToString(); 1292 return oldest_needing_triggered_check; 1293 } 1294 return oldest; 1295 } 1296 1297 // Apart from sending ping from |conn| this method also updates 1298 // |use_candidate_attr| flag. The criteria to update this flag is 1299 // explained below. 1300 // Set USE-CANDIDATE if doing ICE AND this channel is in CONTROLLING AND 1301 // a) Channel is in FULL ICE AND 1302 // a.1) |conn| is the best connection OR 1303 // a.2) there is no best connection OR 1304 // a.3) the best connection is unwritable OR 1305 // a.4) |conn| has higher priority than best_connection. 1306 // b) we're doing LITE ICE AND 1307 // b.1) |conn| is the best_connection AND 1308 // b.2) |conn| is writable. 1309 void P2PTransportChannel::PingConnection(Connection* conn) { 1310 bool use_candidate = false; 1311 if (remote_ice_mode_ == ICEMODE_FULL && ice_role_ == ICEROLE_CONTROLLING) { 1312 use_candidate = (conn == best_connection_) || (best_connection_ == NULL) || 1313 (!best_connection_->writable()) || 1314 (conn->priority() > best_connection_->priority()); 1315 } else if (remote_ice_mode_ == ICEMODE_LITE && conn == best_connection_) { 1316 use_candidate = best_connection_->writable(); 1317 } 1318 conn->set_use_candidate_attr(use_candidate); 1319 last_ping_sent_ms_ = rtc::Time(); 1320 conn->Ping(last_ping_sent_ms_); 1321 } 1322 1323 // When a connection's state changes, we need to figure out who to use as 1324 // the best connection again. It could have become usable, or become unusable. 1325 void P2PTransportChannel::OnConnectionStateChange(Connection* connection) { 1326 ASSERT(worker_thread_ == rtc::Thread::Current()); 1327 1328 // Update the best connection if the state change is from pending best 1329 // connection and role is controlled. 1330 if (ice_role_ == ICEROLE_CONTROLLED) { 1331 if (connection == pending_best_connection_ && connection->writable()) { 1332 pending_best_connection_ = NULL; 1333 LOG(LS_INFO) << "Switching best connection on controlled side" 1334 << " because it's now writable: " << connection->ToString(); 1335 SwitchBestConnectionTo(connection); 1336 } 1337 } 1338 1339 // May stop the allocator session when at least one connection becomes 1340 // strongly connected after starting to get ports. It is not enough to check 1341 // that the connection becomes weakly connected because the connection may be 1342 // changing from (writable, receiving) to (writable, not receiving). 1343 if (!connection->weak()) { 1344 MaybeStopPortAllocatorSessions(); 1345 } 1346 1347 // We have to unroll the stack before doing this because we may be changing 1348 // the state of connections while sorting. 1349 RequestSort(); 1350 } 1351 1352 // When a connection is removed, edit it out, and then update our best 1353 // connection. 1354 void P2PTransportChannel::OnConnectionDestroyed(Connection* connection) { 1355 ASSERT(worker_thread_ == rtc::Thread::Current()); 1356 1357 // Note: the previous best_connection_ may be destroyed by now, so don't 1358 // use it. 1359 1360 // Remove this connection from the list. 1361 std::vector<Connection*>::iterator iter = 1362 std::find(connections_.begin(), connections_.end(), connection); 1363 ASSERT(iter != connections_.end()); 1364 connections_.erase(iter); 1365 1366 LOG_J(LS_INFO, this) << "Removed connection (" 1367 << static_cast<int>(connections_.size()) << " remaining)"; 1368 1369 if (pending_best_connection_ == connection) { 1370 pending_best_connection_ = NULL; 1371 } 1372 1373 // If this is currently the best connection, then we need to pick a new one. 1374 // The call to SortConnections will pick a new one. It looks at the current 1375 // best connection in order to avoid switching between fairly similar ones. 1376 // Since this connection is no longer an option, we can just set best to NULL 1377 // and re-choose a best assuming that there was no best connection. 1378 if (best_connection_ == connection) { 1379 LOG(LS_INFO) << "Best connection destroyed. Will choose a new one."; 1380 SwitchBestConnectionTo(NULL); 1381 RequestSort(); 1382 } 1383 1384 UpdateState(); 1385 // SignalConnectionRemoved should be called after the channel state is 1386 // updated because the receiver of the event may access the channel state. 1387 SignalConnectionRemoved(this); 1388 } 1389 1390 // When a port is destroyed remove it from our list of ports to use for 1391 // connection attempts. 1392 void P2PTransportChannel::OnPortDestroyed(PortInterface* port) { 1393 ASSERT(worker_thread_ == rtc::Thread::Current()); 1394 1395 // Remove this port from the list (if we didn't drop it already). 1396 std::vector<PortInterface*>::iterator iter = 1397 std::find(ports_.begin(), ports_.end(), port); 1398 if (iter != ports_.end()) 1399 ports_.erase(iter); 1400 1401 LOG(INFO) << "Removed port from p2p socket: " 1402 << static_cast<int>(ports_.size()) << " remaining"; 1403 } 1404 1405 // We data is available, let listeners know 1406 void P2PTransportChannel::OnReadPacket(Connection* connection, 1407 const char* data, 1408 size_t len, 1409 const rtc::PacketTime& packet_time) { 1410 ASSERT(worker_thread_ == rtc::Thread::Current()); 1411 1412 // Do not deliver, if packet doesn't belong to the correct transport channel. 1413 if (!FindConnection(connection)) 1414 return; 1415 1416 // Let the client know of an incoming packet 1417 SignalReadPacket(this, data, len, packet_time, 0); 1418 1419 // May need to switch the sending connection based on the receiving media path 1420 // if this is the controlled side. 1421 if (ice_role_ == ICEROLE_CONTROLLED && !best_nominated_connection() && 1422 connection->writable() && best_connection_ != connection) { 1423 SwitchBestConnectionTo(connection); 1424 } 1425 } 1426 1427 void P2PTransportChannel::OnSentPacket(const rtc::SentPacket& sent_packet) { 1428 ASSERT(worker_thread_ == rtc::Thread::Current()); 1429 1430 SignalSentPacket(this, sent_packet); 1431 } 1432 1433 void P2PTransportChannel::OnReadyToSend(Connection* connection) { 1434 if (connection == best_connection_ && writable()) { 1435 SignalReadyToSend(this); 1436 } 1437 } 1438 1439 } // namespace cricket 1440