Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(762)

Side by Side Diff: webrtc/p2p/base/p2ptransportchannel.cc

Issue 1303393002: Reland "Remove GICE (gone forever!) and PORTALLOCATOR_ENABLE_SHARED_UFRAG (enabled forever)." becau… (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Add memcheck suppression Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/p2p/base/p2ptransportchannel.h ('k') | webrtc/p2p/base/p2ptransportchannel_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 117
118 // Wraps the comparison connection into a less than operator that puts higher 118 // Wraps the comparison connection into a less than operator that puts higher
119 // priority writable connections first. 119 // priority writable connections first.
120 class ConnectionCompare { 120 class ConnectionCompare {
121 public: 121 public:
122 bool operator()(const cricket::Connection *ca, 122 bool operator()(const cricket::Connection *ca,
123 const cricket::Connection *cb) { 123 const cricket::Connection *cb) {
124 cricket::Connection* a = const_cast<cricket::Connection*>(ca); 124 cricket::Connection* a = const_cast<cricket::Connection*>(ca);
125 cricket::Connection* b = const_cast<cricket::Connection*>(cb); 125 cricket::Connection* b = const_cast<cricket::Connection*>(cb);
126 126
127 // The IceProtocol is initialized to ICEPROTO_HYBRID and can be updated to
128 // GICE or RFC5245 when an answer SDP is set, or when a STUN message is
129 // received. So the port receiving the STUN message may have a different
130 // IceProtocol if the answer SDP is not set yet.
131 ASSERT(a->port()->IceProtocol() == b->port()->IceProtocol() ||
132 a->port()->IceProtocol() == cricket::ICEPROTO_HYBRID ||
133 b->port()->IceProtocol() == cricket::ICEPROTO_HYBRID);
134
135 // Compare first on writability and static preferences. 127 // Compare first on writability and static preferences.
136 int cmp = CompareConnections(a, b); 128 int cmp = CompareConnections(a, b);
137 if (cmp > 0) 129 if (cmp > 0)
138 return true; 130 return true;
139 if (cmp < 0) 131 if (cmp < 0)
140 return false; 132 return false;
141 133
142 // Otherwise, sort based on latency estimate. 134 // Otherwise, sort based on latency estimate.
143 return a->rtt() < b->rtt(); 135 return a->rtt() < b->rtt();
144 136
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
185 transport_(transport), 177 transport_(transport),
186 allocator_(allocator), 178 allocator_(allocator),
187 worker_thread_(rtc::Thread::Current()), 179 worker_thread_(rtc::Thread::Current()),
188 incoming_only_(false), 180 incoming_only_(false),
189 waiting_for_signaling_(false), 181 waiting_for_signaling_(false),
190 error_(0), 182 error_(0),
191 best_connection_(NULL), 183 best_connection_(NULL),
192 pending_best_connection_(NULL), 184 pending_best_connection_(NULL),
193 sort_dirty_(false), 185 sort_dirty_(false),
194 was_writable_(false), 186 was_writable_(false),
195 protocol_type_(ICEPROTO_HYBRID),
196 remote_ice_mode_(ICEMODE_FULL), 187 remote_ice_mode_(ICEMODE_FULL),
197 ice_role_(ICEROLE_UNKNOWN), 188 ice_role_(ICEROLE_UNKNOWN),
198 tiebreaker_(0), 189 tiebreaker_(0),
199 remote_candidate_generation_(0), 190 remote_candidate_generation_(0),
200 check_receiving_delay_(MIN_CHECK_RECEIVING_DELAY * 5), 191 check_receiving_delay_(MIN_CHECK_RECEIVING_DELAY * 5),
201 receiving_timeout_(MIN_CHECK_RECEIVING_DELAY * 50) { 192 receiving_timeout_(MIN_CHECK_RECEIVING_DELAY * 50) {
202 } 193 }
203 194
204 P2PTransportChannel::~P2PTransportChannel() { 195 P2PTransportChannel::~P2PTransportChannel() {
205 ASSERT(worker_thread_ == rtc::Thread::Current()); 196 ASSERT(worker_thread_ == rtc::Thread::Current());
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 << network->ToString() 277 << network->ToString()
287 << " has more than 1 connection."; 278 << " has more than 1 connection.";
288 return TransportChannelState::STATE_CONNECTING; 279 return TransportChannelState::STATE_CONNECTING;
289 } 280 }
290 } 281 }
291 LOG_J(LS_VERBOSE, this) << "Ice is completed for this channel."; 282 LOG_J(LS_VERBOSE, this) << "Ice is completed for this channel.";
292 283
293 return TransportChannelState::STATE_COMPLETED; 284 return TransportChannelState::STATE_COMPLETED;
294 } 285 }
295 286
296 bool P2PTransportChannel::GetIceProtocolType(IceProtocolType* type) const {
297 *type = protocol_type_;
298 return true;
299 }
300
301 void P2PTransportChannel::SetIceProtocolType(IceProtocolType type) {
302 ASSERT(worker_thread_ == rtc::Thread::Current());
303
304 protocol_type_ = type;
305 for (std::vector<PortInterface *>::iterator it = ports_.begin();
306 it != ports_.end(); ++it) {
307 (*it)->SetIceProtocolType(protocol_type_);
308 }
309 }
310
311 void P2PTransportChannel::SetIceCredentials(const std::string& ice_ufrag, 287 void P2PTransportChannel::SetIceCredentials(const std::string& ice_ufrag,
312 const std::string& ice_pwd) { 288 const std::string& ice_pwd) {
313 ASSERT(worker_thread_ == rtc::Thread::Current()); 289 ASSERT(worker_thread_ == rtc::Thread::Current());
314 bool ice_restart = false; 290 bool ice_restart = false;
315 if (!ice_ufrag_.empty() && !ice_pwd_.empty()) { 291 if (!ice_ufrag_.empty() && !ice_pwd_.empty()) {
316 // Restart candidate allocation if there is any change in either 292 // Restart candidate allocation if there is any change in either
317 // ice ufrag or password. 293 // ice ufrag or password.
318 ice_restart = 294 ice_restart =
319 IceCredentialsChanged(ice_ufrag_, ice_pwd_, ice_ufrag, ice_pwd); 295 IceCredentialsChanged(ice_ufrag_, ice_pwd_, ice_ufrag, ice_pwd);
320 } 296 }
(...skipping 19 matching lines...) Expand all
340 remote_ice_ufrag_ = ice_ufrag; 316 remote_ice_ufrag_ = ice_ufrag;
341 remote_ice_pwd_ = ice_pwd; 317 remote_ice_pwd_ = ice_pwd;
342 318
343 // We need to update the credentials for any peer reflexive candidates. 319 // We need to update the credentials for any peer reflexive candidates.
344 std::vector<Connection*>::iterator it = connections_.begin(); 320 std::vector<Connection*>::iterator it = connections_.begin();
345 for (; it != connections_.end(); ++it) { 321 for (; it != connections_.end(); ++it) {
346 (*it)->MaybeSetRemoteIceCredentials(ice_ufrag, ice_pwd); 322 (*it)->MaybeSetRemoteIceCredentials(ice_ufrag, ice_pwd);
347 } 323 }
348 324
349 if (ice_restart) { 325 if (ice_restart) {
350 // |candidate.generation()| is not signaled in ICEPROTO_RFC5245. 326 // We need to keep track of the remote ice restart so newer
351 // Therefore we need to keep track of the remote ice restart so 327 // connections are prioritized over the older.
352 // newer connections are prioritized over the older.
353 ++remote_candidate_generation_; 328 ++remote_candidate_generation_;
354 } 329 }
355 } 330 }
356 331
357 void P2PTransportChannel::SetRemoteIceMode(IceMode mode) { 332 void P2PTransportChannel::SetRemoteIceMode(IceMode mode) {
358 remote_ice_mode_ = mode; 333 remote_ice_mode_ = mode;
359 } 334 }
360 335
361 void P2PTransportChannel::SetReceivingTimeout(int receiving_timeout_ms) { 336 void P2PTransportChannel::SetReceivingTimeout(int receiving_timeout_ms) {
362 if (receiving_timeout_ms < 0) { 337 if (receiving_timeout_ms < 0) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
403 LOG_J(LS_WARNING, port) << "SetOption(" << it->first 378 LOG_J(LS_WARNING, port) << "SetOption(" << it->first
404 << ", " << it->second 379 << ", " << it->second
405 << ") failed: " << port->GetError(); 380 << ") failed: " << port->GetError();
406 } 381 }
407 } 382 }
408 383
409 // Remember the ports and candidates, and signal that candidates are ready. 384 // Remember the ports and candidates, and signal that candidates are ready.
410 // The session will handle this, and send an initiate/accept/modify message 385 // The session will handle this, and send an initiate/accept/modify message
411 // if one is pending. 386 // if one is pending.
412 387
413 port->SetIceProtocolType(protocol_type_);
414 port->SetIceRole(ice_role_); 388 port->SetIceRole(ice_role_);
415 port->SetIceTiebreaker(tiebreaker_); 389 port->SetIceTiebreaker(tiebreaker_);
416 ports_.push_back(port); 390 ports_.push_back(port);
417 port->SignalUnknownAddress.connect( 391 port->SignalUnknownAddress.connect(
418 this, &P2PTransportChannel::OnUnknownAddress); 392 this, &P2PTransportChannel::OnUnknownAddress);
419 port->SignalDestroyed.connect(this, &P2PTransportChannel::OnPortDestroyed); 393 port->SignalDestroyed.connect(this, &P2PTransportChannel::OnPortDestroyed);
420 port->SignalRoleConflict.connect( 394 port->SignalRoleConflict.connect(
421 this, &P2PTransportChannel::OnRoleConflict); 395 this, &P2PTransportChannel::OnRoleConflict);
422 396
423 // Attempt to create a connection from this new port to all of the remote 397 // Attempt to create a connection from this new port to all of the remote
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
498 472
499 Candidate remote_candidate; 473 Candidate remote_candidate;
500 bool remote_candidate_is_new = (candidate == nullptr); 474 bool remote_candidate_is_new = (candidate == nullptr);
501 if (!remote_candidate_is_new) { 475 if (!remote_candidate_is_new) {
502 remote_candidate = *candidate; 476 remote_candidate = *candidate;
503 if (ufrag_per_port) { 477 if (ufrag_per_port) {
504 remote_candidate.set_address(address); 478 remote_candidate.set_address(address);
505 } 479 }
506 } else { 480 } else {
507 // Create a new candidate with this address. 481 // Create a new candidate with this address.
508 std::string type;
509 int remote_candidate_priority; 482 int remote_candidate_priority;
510 if (port->IceProtocol() == ICEPROTO_RFC5245) {
511 // RFC 5245
512 // If the source transport address of the request does not match any
513 // existing remote candidates, it represents a new peer reflexive remote
514 // candidate.
515 type = PRFLX_PORT_TYPE;
516 483
517 // The priority of the candidate is set to the PRIORITY attribute 484 // The priority of the candidate is set to the PRIORITY attribute
518 // from the request. 485 // from the request.
519 const StunUInt32Attribute* priority_attr = 486 const StunUInt32Attribute* priority_attr =
520 stun_msg->GetUInt32(STUN_ATTR_PRIORITY); 487 stun_msg->GetUInt32(STUN_ATTR_PRIORITY);
521 if (!priority_attr) { 488 if (!priority_attr) {
522 LOG(LS_WARNING) << "P2PTransportChannel::OnUnknownAddress - " 489 LOG(LS_WARNING) << "P2PTransportChannel::OnUnknownAddress - "
523 << "No STUN_ATTR_PRIORITY found in the " 490 << "No STUN_ATTR_PRIORITY found in the "
524 << "stun request message"; 491 << "stun request message";
525 port->SendBindingErrorResponse(stun_msg, address, 492 port->SendBindingErrorResponse(stun_msg, address,
526 STUN_ERROR_BAD_REQUEST, 493 STUN_ERROR_BAD_REQUEST,
527 STUN_ERROR_REASON_BAD_REQUEST); 494 STUN_ERROR_REASON_BAD_REQUEST);
528 return; 495 return;
529 }
530 remote_candidate_priority = priority_attr->value();
531 } else {
532 // G-ICE doesn't support prflx candidate.
533 // We set candidate type to STUN_PORT_TYPE if the binding request comes
534 // from a relay port or the shared socket is used. Otherwise we use the
535 // port's type as the candidate type.
536 if (port->Type() == RELAY_PORT_TYPE || port->SharedSocket()) {
537 type = STUN_PORT_TYPE;
538 } else {
539 type = port->Type();
540 }
541 remote_candidate_priority = remote_candidate.GetPriority(
542 ICE_TYPE_PREFERENCE_PRFLX, port->Network()->preference(), 0);
543 } 496 }
497 remote_candidate_priority = priority_attr->value();
544 498
499 // RFC 5245
500 // If the source transport address of the request does not match any
501 // existing remote candidates, it represents a new peer reflexive remote
502 // candidate.
545 remote_candidate = 503 remote_candidate =
546 Candidate(component(), ProtoToString(proto), address, 0, 504 Candidate(component(), ProtoToString(proto), address, 0,
547 remote_username, remote_password, type, 0U, ""); 505 remote_username, remote_password, PRFLX_PORT_TYPE, 0U, "");
548 506
549 // From RFC 5245, section-7.2.1.3: 507 // From RFC 5245, section-7.2.1.3:
550 // The foundation of the candidate is set to an arbitrary value, different 508 // The foundation of the candidate is set to an arbitrary value, different
551 // from the foundation for all other remote candidates. 509 // from the foundation for all other remote candidates.
552 remote_candidate.set_foundation( 510 remote_candidate.set_foundation(
553 rtc::ToString<uint32>(rtc::ComputeCrc32(remote_candidate.id()))); 511 rtc::ToString<uint32>(rtc::ComputeCrc32(remote_candidate.id())));
554 512
555 remote_candidate.set_priority(remote_candidate_priority); 513 remote_candidate.set_priority(remote_candidate_priority);
556 } 514 }
557 515
558 if (port->IceProtocol() == ICEPROTO_RFC5245) { 516 // RFC5245, the agent constructs a pair whose local candidate is equal to
559 // RFC5245, the agent constructs a pair whose local candidate is equal to 517 // the transport address on which the STUN request was received, and a
560 // the transport address on which the STUN request was received, and a 518 // remote candidate equal to the source transport address where the
561 // remote candidate equal to the source transport address where the 519 // request came from.
562 // request came from.
563 520
564 // There shouldn't be an existing connection with this remote address. 521 // There shouldn't be an existing connection with this remote address.
565 // When ports are muxed, this channel might get multiple unknown address 522 // When ports are muxed, this channel might get multiple unknown address
566 // signals. In that case if the connection is already exists, we should 523 // signals. In that case if the connection is already exists, we should
567 // simply ignore the signal otherwise send server error. 524 // simply ignore the signal otherwise send server error.
568 if (port->GetConnection(remote_candidate.address())) { 525 if (port->GetConnection(remote_candidate.address())) {
569 if (port_muxed) { 526 if (port_muxed) {
570 LOG(LS_INFO) << "Connection already exists for peer reflexive " 527 LOG(LS_INFO) << "Connection already exists for peer reflexive "
571 << "candidate: " << remote_candidate.ToString(); 528 << "candidate: " << remote_candidate.ToString();
572 return; 529 return;
573 } else { 530 } else {
574 ASSERT(false);
575 port->SendBindingErrorResponse(stun_msg, address,
576 STUN_ERROR_SERVER_ERROR,
577 STUN_ERROR_REASON_SERVER_ERROR);
578 return;
579 }
580 }
581
582 Connection* connection = port->CreateConnection(
583 remote_candidate, cricket::PortInterface::ORIGIN_THIS_PORT);
584 if (!connection) {
585 ASSERT(false); 531 ASSERT(false);
586 port->SendBindingErrorResponse(stun_msg, address, 532 port->SendBindingErrorResponse(stun_msg, address,
587 STUN_ERROR_SERVER_ERROR, 533 STUN_ERROR_SERVER_ERROR,
588 STUN_ERROR_REASON_SERVER_ERROR); 534 STUN_ERROR_REASON_SERVER_ERROR);
589 return; 535 return;
590 } 536 }
537 }
591 538
592 LOG(LS_INFO) << "Adding connection from " 539 Connection* connection = port->CreateConnection(
593 << (remote_candidate_is_new ? "peer reflexive" : "resurrected") 540 remote_candidate, cricket::PortInterface::ORIGIN_THIS_PORT);
594 << " candidate: " << remote_candidate.ToString(); 541 if (!connection) {
595 AddConnection(connection); 542 ASSERT(false);
596 connection->ReceivedPing(); 543 port->SendBindingErrorResponse(stun_msg, address,
544 STUN_ERROR_SERVER_ERROR,
545 STUN_ERROR_REASON_SERVER_ERROR);
546 return;
547 }
597 548
598 // Send the pinger a successful stun response. 549 LOG(LS_INFO) << "Adding connection from "
599 port->SendBindingResponse(stun_msg, address); 550 << (remote_candidate_is_new ? "peer reflexive" : "resurrected")
551 << " candidate: " << remote_candidate.ToString();
552 AddConnection(connection);
553 connection->ReceivedPing();
600 554
601 bool received_use_candidate = 555 bool received_use_candidate =
602 stun_msg->GetByteString(STUN_ATTR_USE_CANDIDATE) != nullptr; 556 stun_msg->GetByteString(STUN_ATTR_USE_CANDIDATE) != nullptr;
603 if (received_use_candidate && ice_role_ == ICEROLE_CONTROLLED) { 557 if (received_use_candidate && ice_role_ == ICEROLE_CONTROLLED) {
604 connection->set_nominated(true); 558 connection->set_nominated(true);
605 OnNominated(connection); 559 OnNominated(connection);
606 } 560 }
607 561
608 // Update the list of connections since we just added another. We do this 562 // Update the list of connections since we just added another. We do this
609 // after sending the response since it could (in principle) delete the 563 // after sending the response since it could (in principle) delete the
610 // connection in question. 564 // connection in question.
611 SortConnections(); 565 SortConnections();
612 } else {
613 // Check for connectivity to this address. Create connections
614 // to this address across all local ports. First, add this as a new remote
615 // address
616 if (!CreateConnections(remote_candidate, port, true)) {
617 // Hopefully this won't occur, because changing a destination address
618 // shouldn't cause a new connection to fail
619 ASSERT(false);
620 port->SendBindingErrorResponse(stun_msg, address, STUN_ERROR_SERVER_ERROR,
621 STUN_ERROR_REASON_SERVER_ERROR);
622 return;
623 }
624
625 // Send the pinger a successful stun response.
626 port->SendBindingResponse(stun_msg, address);
627
628 // Update the list of connections since we just added another. We do this
629 // after sending the response since it could (in principle) delete the
630 // connection in question.
631 SortConnections();
632 }
633 } 566 }
634 567
635 void P2PTransportChannel::OnRoleConflict(PortInterface* port) { 568 void P2PTransportChannel::OnRoleConflict(PortInterface* port) {
636 SignalRoleConflict(this); // STUN ping will be sent when SetRole is called 569 SignalRoleConflict(this); // STUN ping will be sent when SetRole is called
637 // from Transport. 570 // from Transport.
638 } 571 }
639 572
640 // When the signalling channel is ready, we can really kick off the allocator 573 // When the signalling channel is ready, we can really kick off the allocator
641 void P2PTransportChannel::OnSignalingReady() { 574 void P2PTransportChannel::OnSignalingReady() {
642 ASSERT(worker_thread_ == rtc::Thread::Current()); 575 ASSERT(worker_thread_ == rtc::Thread::Current());
643 if (waiting_for_signaling_) { 576 if (waiting_for_signaling_) {
644 waiting_for_signaling_ = false; 577 waiting_for_signaling_ = false;
645 AddAllocatorSession(allocator_->CreateSession( 578 AddAllocatorSession(allocator_->CreateSession(
646 SessionId(), content_name(), component(), ice_ufrag_, ice_pwd_)); 579 SessionId(), content_name(), component(), ice_ufrag_, ice_pwd_));
647 } 580 }
648 } 581 }
649 582
650 void P2PTransportChannel::OnNominated(Connection* conn) { 583 void P2PTransportChannel::OnNominated(Connection* conn) {
651 ASSERT(worker_thread_ == rtc::Thread::Current()); 584 ASSERT(worker_thread_ == rtc::Thread::Current());
652 ASSERT(ice_role_ == ICEROLE_CONTROLLED); 585 ASSERT(ice_role_ == ICEROLE_CONTROLLED);
653 ASSERT(protocol_type_ == ICEPROTO_RFC5245);
654 586
655 if (conn->write_state() == Connection::STATE_WRITABLE) { 587 if (conn->write_state() == Connection::STATE_WRITABLE) {
656 if (best_connection_ != conn) { 588 if (best_connection_ != conn) {
657 pending_best_connection_ = NULL; 589 pending_best_connection_ = NULL;
658 LOG(LS_INFO) << "Switching best connection on controlled side: " 590 LOG(LS_INFO) << "Switching best connection on controlled side: "
659 << conn->ToString(); 591 << conn->ToString();
660 SwitchBestConnectionTo(conn); 592 SwitchBestConnectionTo(conn);
661 // Now we have selected the best connection, time to prune other existing 593 // Now we have selected the best connection, time to prune other existing
662 // connections and update the read/write state of the channel. 594 // connections and update the read/write state of the channel.
663 RequestSort(); 595 RequestSort();
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
802 734
803 bool P2PTransportChannel::FindConnection( 735 bool P2PTransportChannel::FindConnection(
804 cricket::Connection* connection) const { 736 cricket::Connection* connection) const {
805 std::vector<Connection*>::const_iterator citer = 737 std::vector<Connection*>::const_iterator citer =
806 std::find(connections_.begin(), connections_.end(), connection); 738 std::find(connections_.begin(), connections_.end(), connection);
807 return citer != connections_.end(); 739 return citer != connections_.end();
808 } 740 }
809 741
810 uint32 P2PTransportChannel::GetRemoteCandidateGeneration( 742 uint32 P2PTransportChannel::GetRemoteCandidateGeneration(
811 const Candidate& candidate) { 743 const Candidate& candidate) {
812 if (protocol_type_ == ICEPROTO_GOOGLE) { 744 // We need to keep track of the remote ice restart so newer
813 // The Candidate.generation() can be trusted. Nothing needs to be done. 745 // connections are prioritized over the older.
814 return candidate.generation();
815 }
816 // |candidate.generation()| is not signaled in ICEPROTO_RFC5245.
817 // Therefore we need to keep track of the remote ice restart so
818 // newer connections are prioritized over the older.
819 ASSERT(candidate.generation() == 0 || 746 ASSERT(candidate.generation() == 0 ||
820 candidate.generation() == remote_candidate_generation_); 747 candidate.generation() == remote_candidate_generation_);
821 return remote_candidate_generation_; 748 return remote_candidate_generation_;
822 } 749 }
823 750
824 // Check if remote candidate is already cached. 751 // Check if remote candidate is already cached.
825 bool P2PTransportChannel::IsDuplicateRemoteCandidate( 752 bool P2PTransportChannel::IsDuplicateRemoteCandidate(
826 const Candidate& candidate) { 753 const Candidate& candidate) {
827 for (uint32 i = 0; i < remote_candidates_.size(); ++i) { 754 for (uint32 i = 0; i < remote_candidates_.size(); ++i) {
828 if (remote_candidates_[i].IsEquivalent(candidate)) { 755 if (remote_candidates_[i].IsEquivalent(candidate)) {
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
986 913
987 // Sort the available connections to find the best one. We also monitor 914 // Sort the available connections to find the best one. We also monitor
988 // the number of available connections and the current state. 915 // the number of available connections and the current state.
989 void P2PTransportChannel::SortConnections() { 916 void P2PTransportChannel::SortConnections() {
990 ASSERT(worker_thread_ == rtc::Thread::Current()); 917 ASSERT(worker_thread_ == rtc::Thread::Current());
991 918
992 // Make sure the connection states are up-to-date since this affects how they 919 // Make sure the connection states are up-to-date since this affects how they
993 // will be sorted. 920 // will be sorted.
994 UpdateConnectionStates(); 921 UpdateConnectionStates();
995 922
996 if (protocol_type_ == ICEPROTO_HYBRID) {
997 // If we are in hybrid mode, we are not sending any ping requests, so there
998 // is no point in sorting the connections. In hybrid state, ports can have
999 // different protocol than hybrid and protocol may differ from one another.
1000 // Instead just update the state of this channel
1001 UpdateChannelState();
1002 return;
1003 }
1004
1005 // Any changes after this point will require a re-sort. 923 // Any changes after this point will require a re-sort.
1006 sort_dirty_ = false; 924 sort_dirty_ = false;
1007 925
1008 // Find the best alternative connection by sorting. It is important to note 926 // Find the best alternative connection by sorting. It is important to note
1009 // that amongst equal preference, writable connections, this will choose the 927 // that amongst equal preference, writable connections, this will choose the
1010 // one whose estimated latency is lowest. So it is the only one that we 928 // one whose estimated latency is lowest. So it is the only one that we
1011 // need to consider switching to. 929 // need to consider switching to.
1012 ConnectionCompare cmp; 930 ConnectionCompare cmp;
1013 std::stable_sort(connections_.begin(), connections_.end(), cmp); 931 std::stable_sort(connections_.begin(), connections_.end(), cmp);
1014 LOG(LS_VERBOSE) << "Sorting available connections:"; 932 LOG(LS_VERBOSE) << "Sorting available connections:";
1015 for (uint32 i = 0; i < connections_.size(); ++i) { 933 for (uint32 i = 0; i < connections_.size(); ++i) {
1016 LOG(LS_VERBOSE) << connections_[i]->ToString(); 934 LOG(LS_VERBOSE) << connections_[i]->ToString();
1017 } 935 }
1018 936
1019 Connection* top_connection = 937 Connection* top_connection =
1020 (connections_.size() > 0) ? connections_[0] : nullptr; 938 (connections_.size() > 0) ? connections_[0] : nullptr;
1021 939
1022 // If necessary, switch to the new choice. 940 // If necessary, switch to the new choice.
1023 // Note that |top_connection| doesn't have to be writable to become the best 941 // Note that |top_connection| doesn't have to be writable to become the best
1024 // connection although it will have higher priority if it is writable. 942 // connection although it will have higher priority if it is writable.
1025 // The controlled side can switch the best connection only if the current 943 // The controlled side can switch the best connection only if the current
1026 // |best connection_| has not been nominated by the controlling side yet. 944 // |best connection_| has not been nominated by the controlling side yet.
1027 945 if ((ice_role_ == ICEROLE_CONTROLLING || !best_nominated_connection()) &&
1028 // We don't want to pick the best connections if channel is using RFC5245.
1029 if ((protocol_type_ != ICEPROTO_RFC5245 || ice_role_ == ICEROLE_CONTROLLING ||
1030 !best_nominated_connection()) &&
1031 ShouldSwitch(best_connection_, top_connection)) { 946 ShouldSwitch(best_connection_, top_connection)) {
1032 LOG(LS_INFO) << "Switching best connection: " << top_connection->ToString(); 947 LOG(LS_INFO) << "Switching best connection: " << top_connection->ToString();
1033 SwitchBestConnectionTo(top_connection); 948 SwitchBestConnectionTo(top_connection);
1034 } 949 }
1035 950
1036 // Controlled side can prune only if the best connection has been nominated. 951 // Controlled side can prune only if the best connection has been nominated.
1037 // because otherwise it may delete the connection that will be selected by 952 // because otherwise it may delete the connection that will be selected by
1038 // the controlling side. 953 // the controlling side.
1039 if (protocol_type_ != ICEPROTO_RFC5245 || ice_role_ == ICEROLE_CONTROLLING || 954 if (ice_role_ == ICEROLE_CONTROLLING || best_nominated_connection()) {
1040 best_nominated_connection()) {
1041 PruneConnections(); 955 PruneConnections();
1042 } 956 }
1043 957
1044 // Check if all connections are timedout. 958 // Check if all connections are timedout.
1045 bool all_connections_timedout = true; 959 bool all_connections_timedout = true;
1046 for (uint32 i = 0; i < connections_.size(); ++i) { 960 for (uint32 i = 0; i < connections_.size(); ++i) {
1047 if (connections_[i]->write_state() != Connection::STATE_WRITE_TIMEOUT) { 961 if (connections_[i]->write_state() != Connection::STATE_WRITE_TIMEOUT) {
1048 all_connections_timedout = false; 962 all_connections_timedout = false;
1049 break; 963 break;
1050 } 964 }
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
1295 // that have received a ping but have not sent a ping since receiving 1209 // that have received a ping but have not sent a ping since receiving
1296 // it (last_received_ping > last_sent_ping). But we shouldn't do 1210 // it (last_received_ping > last_sent_ping). But we shouldn't do
1297 // triggered checks if the connection is already writable. 1211 // triggered checks if the connection is already writable.
1298 Connection* oldest_needing_triggered_check = nullptr; 1212 Connection* oldest_needing_triggered_check = nullptr;
1299 Connection* oldest = nullptr; 1213 Connection* oldest = nullptr;
1300 for (Connection* conn : connections_) { 1214 for (Connection* conn : connections_) {
1301 if (!IsPingable(conn)) { 1215 if (!IsPingable(conn)) {
1302 continue; 1216 continue;
1303 } 1217 }
1304 bool needs_triggered_check = 1218 bool needs_triggered_check =
1305 (protocol_type_ == ICEPROTO_RFC5245 && 1219 (!conn->writable() &&
1306 !conn->writable() &&
1307 conn->last_ping_received() > conn->last_ping_sent()); 1220 conn->last_ping_received() > conn->last_ping_sent());
1308 if (needs_triggered_check && 1221 if (needs_triggered_check &&
1309 (!oldest_needing_triggered_check || 1222 (!oldest_needing_triggered_check ||
1310 (conn->last_ping_received() < 1223 (conn->last_ping_received() <
1311 oldest_needing_triggered_check->last_ping_received()))) { 1224 oldest_needing_triggered_check->last_ping_received()))) {
1312 oldest_needing_triggered_check = conn; 1225 oldest_needing_triggered_check = conn;
1313 } 1226 }
1314 if (!oldest || (conn->last_ping_sent() < oldest->last_ping_sent())) { 1227 if (!oldest || (conn->last_ping_sent() < oldest->last_ping_sent())) {
1315 oldest = conn; 1228 oldest = conn;
1316 } 1229 }
(...skipping 14 matching lines...) Expand all
1331 // a) Channel is in FULL ICE AND 1244 // a) Channel is in FULL ICE AND
1332 // a.1) |conn| is the best connection OR 1245 // a.1) |conn| is the best connection OR
1333 // a.2) there is no best connection OR 1246 // a.2) there is no best connection OR
1334 // a.3) the best connection is unwritable OR 1247 // a.3) the best connection is unwritable OR
1335 // a.4) |conn| has higher priority than best_connection. 1248 // a.4) |conn| has higher priority than best_connection.
1336 // b) we're doing LITE ICE AND 1249 // b) we're doing LITE ICE AND
1337 // b.1) |conn| is the best_connection AND 1250 // b.1) |conn| is the best_connection AND
1338 // b.2) |conn| is writable. 1251 // b.2) |conn| is writable.
1339 void P2PTransportChannel::PingConnection(Connection* conn) { 1252 void P2PTransportChannel::PingConnection(Connection* conn) {
1340 bool use_candidate = false; 1253 bool use_candidate = false;
1341 if (protocol_type_ == ICEPROTO_RFC5245) { 1254 if (remote_ice_mode_ == ICEMODE_FULL && ice_role_ == ICEROLE_CONTROLLING) {
1342 if (remote_ice_mode_ == ICEMODE_FULL && ice_role_ == ICEROLE_CONTROLLING) { 1255 use_candidate = (conn == best_connection_) ||
1343 use_candidate = (conn == best_connection_) || 1256 (best_connection_ == NULL) ||
1344 (best_connection_ == NULL) || 1257 (!best_connection_->writable()) ||
1345 (!best_connection_->writable()) || 1258 (conn->priority() > best_connection_->priority());
1346 (conn->priority() > best_connection_->priority()); 1259 } else if (remote_ice_mode_ == ICEMODE_LITE && conn == best_connection_) {
1347 } else if (remote_ice_mode_ == ICEMODE_LITE && conn == best_connection_) { 1260 use_candidate = best_connection_->writable();
1348 use_candidate = best_connection_->writable();
1349 }
1350 } 1261 }
1351 conn->set_use_candidate_attr(use_candidate); 1262 conn->set_use_candidate_attr(use_candidate);
1352 conn->Ping(rtc::Time()); 1263 conn->Ping(rtc::Time());
1353 } 1264 }
1354 1265
1355 // When a connection's state changes, we need to figure out who to use as 1266 // When a connection's state changes, we need to figure out who to use as
1356 // the best connection again. It could have become usable, or become unusable. 1267 // the best connection again. It could have become usable, or become unusable.
1357 void P2PTransportChannel::OnConnectionStateChange(Connection* connection) { 1268 void P2PTransportChannel::OnConnectionStateChange(Connection* connection) {
1358 ASSERT(worker_thread_ == rtc::Thread::Current()); 1269 ASSERT(worker_thread_ == rtc::Thread::Current());
1359 1270
1360 // Update the best connection if the state change is from pending best 1271 // Update the best connection if the state change is from pending best
1361 // connection and role is controlled. 1272 // connection and role is controlled.
1362 if (protocol_type_ == ICEPROTO_RFC5245 && ice_role_ == ICEROLE_CONTROLLED) { 1273 if (ice_role_ == ICEROLE_CONTROLLED) {
1363 if (connection == pending_best_connection_ && connection->writable()) { 1274 if (connection == pending_best_connection_ && connection->writable()) {
1364 pending_best_connection_ = NULL; 1275 pending_best_connection_ = NULL;
1365 LOG(LS_INFO) << "Switching best connection on controlled side" 1276 LOG(LS_INFO) << "Switching best connection on controlled side"
1366 << " because it's now writable: " << connection->ToString(); 1277 << " because it's now writable: " << connection->ToString();
1367 SwitchBestConnectionTo(connection); 1278 SwitchBestConnectionTo(connection);
1368 } 1279 }
1369 } 1280 }
1370 1281
1371 // We have to unroll the stack before doing this because we may be changing 1282 // We have to unroll the stack before doing this because we may be changing
1372 // the state of connections while sorting. 1283 // the state of connections while sorting.
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1444 } 1355 }
1445 } 1356 }
1446 1357
1447 void P2PTransportChannel::OnReadyToSend(Connection* connection) { 1358 void P2PTransportChannel::OnReadyToSend(Connection* connection) {
1448 if (connection == best_connection_ && writable()) { 1359 if (connection == best_connection_ && writable()) {
1449 SignalReadyToSend(this); 1360 SignalReadyToSend(this);
1450 } 1361 }
1451 } 1362 }
1452 1363
1453 } // namespace cricket 1364 } // namespace cricket
OLDNEW
« no previous file with comments | « webrtc/p2p/base/p2ptransportchannel.h ('k') | webrtc/p2p/base/p2ptransportchannel_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698