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

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

Issue 1263663002: Remove GICE. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: fix more tests 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 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 << network->ToString() 278 << network->ToString()
288 << " has more than 1 connection."; 279 << " has more than 1 connection.";
289 return TransportChannelState::STATE_CONNECTING; 280 return TransportChannelState::STATE_CONNECTING;
290 } 281 }
291 } 282 }
292 LOG_J(LS_VERBOSE, this) << "Ice is completed for this channel."; 283 LOG_J(LS_VERBOSE, this) << "Ice is completed for this channel.";
293 284
294 return TransportChannelState::STATE_COMPLETED; 285 return TransportChannelState::STATE_COMPLETED;
295 } 286 }
296 287
297 bool P2PTransportChannel::GetIceProtocolType(IceProtocolType* type) const {
298 *type = protocol_type_;
299 return true;
300 }
301
302 void P2PTransportChannel::SetIceProtocolType(IceProtocolType type) {
303 ASSERT(worker_thread_ == rtc::Thread::Current());
304
305 protocol_type_ = type;
306 for (std::vector<PortInterface *>::iterator it = ports_.begin();
307 it != ports_.end(); ++it) {
308 (*it)->SetIceProtocolType(protocol_type_);
309 }
310 }
311
312 void P2PTransportChannel::SetIceCredentials(const std::string& ice_ufrag, 288 void P2PTransportChannel::SetIceCredentials(const std::string& ice_ufrag,
313 const std::string& ice_pwd) { 289 const std::string& ice_pwd) {
314 ASSERT(worker_thread_ == rtc::Thread::Current()); 290 ASSERT(worker_thread_ == rtc::Thread::Current());
315 bool ice_restart = false; 291 bool ice_restart = false;
316 if (!ice_ufrag_.empty() && !ice_pwd_.empty()) { 292 if (!ice_ufrag_.empty() && !ice_pwd_.empty()) {
317 // Restart candidate allocation if there is any change in either 293 // Restart candidate allocation if there is any change in either
318 // ice ufrag or password. 294 // ice ufrag or password.
319 ice_restart = 295 ice_restart =
320 IceCredentialsChanged(ice_ufrag_, ice_pwd_, ice_ufrag, ice_pwd); 296 IceCredentialsChanged(ice_ufrag_, ice_pwd_, ice_ufrag, ice_pwd);
321 } 297 }
(...skipping 19 matching lines...) Expand all
341 remote_ice_ufrag_ = ice_ufrag; 317 remote_ice_ufrag_ = ice_ufrag;
342 remote_ice_pwd_ = ice_pwd; 318 remote_ice_pwd_ = ice_pwd;
343 319
344 // We need to update the credentials for any peer reflexive candidates. 320 // We need to update the credentials for any peer reflexive candidates.
345 std::vector<Connection*>::iterator it = connections_.begin(); 321 std::vector<Connection*>::iterator it = connections_.begin();
346 for (; it != connections_.end(); ++it) { 322 for (; it != connections_.end(); ++it) {
347 (*it)->MaybeSetRemoteIceCredentials(ice_ufrag, ice_pwd); 323 (*it)->MaybeSetRemoteIceCredentials(ice_ufrag, ice_pwd);
348 } 324 }
349 325
350 if (ice_restart) { 326 if (ice_restart) {
351 // |candidate.generation()| is not signaled in ICEPROTO_RFC5245. 327 // We need to keep track of the remote ice restart so newer
352 // Therefore we need to keep track of the remote ice restart so 328 // connections are prioritized over the older.
353 // newer connections are prioritized over the older.
354 ++remote_candidate_generation_; 329 ++remote_candidate_generation_;
355 } 330 }
356 } 331 }
357 332
358 void P2PTransportChannel::SetRemoteIceMode(IceMode mode) { 333 void P2PTransportChannel::SetRemoteIceMode(IceMode mode) {
359 remote_ice_mode_ = mode; 334 remote_ice_mode_ = mode;
360 } 335 }
361 336
362 void P2PTransportChannel::SetReceivingTimeout(int receiving_timeout_ms) { 337 void P2PTransportChannel::SetReceivingTimeout(int receiving_timeout_ms) {
363 if (receiving_timeout_ms < 0) { 338 if (receiving_timeout_ms < 0) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
404 LOG_J(LS_WARNING, port) << "SetOption(" << it->first 379 LOG_J(LS_WARNING, port) << "SetOption(" << it->first
405 << ", " << it->second 380 << ", " << it->second
406 << ") failed: " << port->GetError(); 381 << ") failed: " << port->GetError();
407 } 382 }
408 } 383 }
409 384
410 // Remember the ports and candidates, and signal that candidates are ready. 385 // Remember the ports and candidates, and signal that candidates are ready.
411 // The session will handle this, and send an initiate/accept/modify message 386 // The session will handle this, and send an initiate/accept/modify message
412 // if one is pending. 387 // if one is pending.
413 388
414 port->SetIceProtocolType(protocol_type_);
415 port->SetIceRole(ice_role_); 389 port->SetIceRole(ice_role_);
416 port->SetIceTiebreaker(tiebreaker_); 390 port->SetIceTiebreaker(tiebreaker_);
417 ports_.push_back(port); 391 ports_.push_back(port);
418 port->SignalUnknownAddress.connect( 392 port->SignalUnknownAddress.connect(
419 this, &P2PTransportChannel::OnUnknownAddress); 393 this, &P2PTransportChannel::OnUnknownAddress);
420 port->SignalDestroyed.connect(this, &P2PTransportChannel::OnPortDestroyed); 394 port->SignalDestroyed.connect(this, &P2PTransportChannel::OnPortDestroyed);
421 port->SignalRoleConflict.connect( 395 port->SignalRoleConflict.connect(
422 this, &P2PTransportChannel::OnRoleConflict); 396 this, &P2PTransportChannel::OnRoleConflict);
423 397
424 // Attempt to create a connection from this new port to all of the remote 398 // 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
499 473
500 Candidate remote_candidate; 474 Candidate remote_candidate;
501 bool remote_candidate_is_new = (candidate == nullptr); 475 bool remote_candidate_is_new = (candidate == nullptr);
502 if (!remote_candidate_is_new) { 476 if (!remote_candidate_is_new) {
503 remote_candidate = *candidate; 477 remote_candidate = *candidate;
504 if (ufrag_per_port) { 478 if (ufrag_per_port) {
505 remote_candidate.set_address(address); 479 remote_candidate.set_address(address);
506 } 480 }
507 } else { 481 } else {
508 // Create a new candidate with this address. 482 // Create a new candidate with this address.
509 std::string type; 483 std::string type;
Taylor Brandstetter 2015/07/29 17:35:17 Sorry if I'm being overly picky, but there's still
pthatcher1 2015/07/31 00:28:53 Picky is good. Thank you.
510 int remote_candidate_priority; 484 int remote_candidate_priority;
511 if (port->IceProtocol() == ICEPROTO_RFC5245) {
512 // RFC 5245
513 // If the source transport address of the request does not match any
514 // existing remote candidates, it represents a new peer reflexive remote
515 // candidate.
516 type = PRFLX_PORT_TYPE;
517 485
518 // The priority of the candidate is set to the PRIORITY attribute 486 // The priority of the candidate is set to the PRIORITY attribute
519 // from the request. 487 // from the request.
520 const StunUInt32Attribute* priority_attr = 488 const StunUInt32Attribute* priority_attr =
521 stun_msg->GetUInt32(STUN_ATTR_PRIORITY); 489 stun_msg->GetUInt32(STUN_ATTR_PRIORITY);
522 if (!priority_attr) { 490 if (!priority_attr) {
523 LOG(LS_WARNING) << "P2PTransportChannel::OnUnknownAddress - " 491 LOG(LS_WARNING) << "P2PTransportChannel::OnUnknownAddress - "
524 << "No STUN_ATTR_PRIORITY found in the " 492 << "No STUN_ATTR_PRIORITY found in the "
525 << "stun request message"; 493 << "stun request message";
526 port->SendBindingErrorResponse(stun_msg, address, 494 port->SendBindingErrorResponse(stun_msg, address,
527 STUN_ERROR_BAD_REQUEST, 495 STUN_ERROR_BAD_REQUEST,
528 STUN_ERROR_REASON_BAD_REQUEST); 496 STUN_ERROR_REASON_BAD_REQUEST);
529 return; 497 return;
530 }
531 remote_candidate_priority = priority_attr->value();
532 } else {
533 // G-ICE doesn't support prflx candidate.
534 // We set candidate type to STUN_PORT_TYPE if the binding request comes
535 // from a relay port or the shared socket is used. Otherwise we use the
536 // port's type as the candidate type.
537 if (port->Type() == RELAY_PORT_TYPE || port->SharedSocket()) {
538 type = STUN_PORT_TYPE;
539 } else {
540 type = port->Type();
541 }
542 remote_candidate_priority = remote_candidate.GetPriority(
543 ICE_TYPE_PREFERENCE_PRFLX, port->Network()->preference(), 0);
544 } 498 }
499 remote_candidate_priority = priority_attr->value();
545 500
501 // RFC 5245
502 // If the source transport address of the request does not match any
503 // existing remote candidates, it represents a new peer reflexive remote
504 // candidate.
546 remote_candidate = 505 remote_candidate =
547 Candidate(component(), ProtoToString(proto), address, 0, 506 Candidate(component(), ProtoToString(proto), address, 0,
548 remote_username, remote_password, type, 0U, ""); 507 remote_username, remote_password, PRFLX_PORT_TYPE, 0U, "");
549 508
550 // From RFC 5245, section-7.2.1.3: 509 // From RFC 5245, section-7.2.1.3:
551 // The foundation of the candidate is set to an arbitrary value, different 510 // The foundation of the candidate is set to an arbitrary value, different
552 // from the foundation for all other remote candidates. 511 // from the foundation for all other remote candidates.
553 remote_candidate.set_foundation( 512 remote_candidate.set_foundation(
554 rtc::ToString<uint32>(rtc::ComputeCrc32(remote_candidate.id()))); 513 rtc::ToString<uint32>(rtc::ComputeCrc32(remote_candidate.id())));
555 514
556 remote_candidate.set_priority(remote_candidate_priority); 515 remote_candidate.set_priority(remote_candidate_priority);
557 } 516 }
558 517
559 if (port->IceProtocol() == ICEPROTO_RFC5245) { 518 // RFC5245, the agent constructs a pair whose local candidate is equal to
560 // RFC5245, the agent constructs a pair whose local candidate is equal to 519 // the transport address on which the STUN request was received, and a
561 // the transport address on which the STUN request was received, and a 520 // remote candidate equal to the source transport address where the
562 // remote candidate equal to the source transport address where the 521 // request came from.
563 // request came from.
564 522
565 // There shouldn't be an existing connection with this remote address. 523 // There shouldn't be an existing connection with this remote address.
566 // When ports are muxed, this channel might get multiple unknown address 524 // When ports are muxed, this channel might get multiple unknown address
567 // signals. In that case if the connection is already exists, we should 525 // signals. In that case if the connection is already exists, we should
568 // simply ignore the signal othewise send server error. 526 // simply ignore the signal othewise send server error.
569 if (port->GetConnection(remote_candidate.address())) { 527 if (port->GetConnection(remote_candidate.address())) {
570 if (port_muxed) { 528 if (port_muxed) {
571 LOG(LS_INFO) << "Connection already exists for peer reflexive " 529 LOG(LS_INFO) << "Connection already exists for peer reflexive "
572 << "candidate: " << remote_candidate.ToString(); 530 << "candidate: " << remote_candidate.ToString();
573 return; 531 return;
574 } else { 532 } else {
575 ASSERT(false);
576 port->SendBindingErrorResponse(stun_msg, address,
577 STUN_ERROR_SERVER_ERROR,
578 STUN_ERROR_REASON_SERVER_ERROR);
579 return;
580 }
581 }
582
583 Connection* connection = port->CreateConnection(
584 remote_candidate, cricket::PortInterface::ORIGIN_THIS_PORT);
585 if (!connection) {
586 ASSERT(false); 533 ASSERT(false);
587 port->SendBindingErrorResponse(stun_msg, address, 534 port->SendBindingErrorResponse(stun_msg, address,
588 STUN_ERROR_SERVER_ERROR, 535 STUN_ERROR_SERVER_ERROR,
589 STUN_ERROR_REASON_SERVER_ERROR); 536 STUN_ERROR_REASON_SERVER_ERROR);
590 return; 537 return;
591 } 538 }
539 }
592 540
593 LOG(LS_INFO) << "Adding connection from " 541 Connection* connection = port->CreateConnection(
594 << (remote_candidate_is_new ? "peer reflexive" : "resurrected") 542 remote_candidate, cricket::PortInterface::ORIGIN_THIS_PORT);
595 << " candidate: " << remote_candidate.ToString(); 543 if (!connection) {
596 AddConnection(connection); 544 ASSERT(false);
597 connection->ReceivedPing(); 545 port->SendBindingErrorResponse(stun_msg, address,
546 STUN_ERROR_SERVER_ERROR,
547 STUN_ERROR_REASON_SERVER_ERROR);
548 return;
549 }
598 550
599 // Send the pinger a successful stun response. 551 LOG(LS_INFO) << "Adding connection from "
600 port->SendBindingResponse(stun_msg, address); 552 << (remote_candidate_is_new ? "peer reflexive" : "resurrected")
553 << " candidate: " << remote_candidate.ToString();
554 AddConnection(connection);
555 connection->ReceivedPing();
601 556
602 // Update the list of connections since we just added another. We do this 557 // Update the list of connections since we just added another. We do this
603 // after sending the response since it could (in principle) delete the 558 // after sending the response since it could (in principle) delete the
604 // connection in question. 559 // connection in question.
605 SortConnections(); 560 SortConnections();
606 } else {
607 // Check for connectivity to this address. Create connections
608 // to this address across all local ports. First, add this as a new remote
609 // address
610 if (!CreateConnections(remote_candidate, port, true)) {
611 // Hopefully this won't occur, because changing a destination address
612 // shouldn't cause a new connection to fail
613 ASSERT(false);
614 port->SendBindingErrorResponse(stun_msg, address, STUN_ERROR_SERVER_ERROR,
615 STUN_ERROR_REASON_SERVER_ERROR);
616 return;
617 }
618
619 // Send the pinger a successful stun response.
620 port->SendBindingResponse(stun_msg, address);
621
622 // Update the list of connections since we just added another. We do this
623 // after sending the response since it could (in principle) delete the
624 // connection in question.
625 SortConnections();
626 }
627 } 561 }
628 562
629 void P2PTransportChannel::OnRoleConflict(PortInterface* port) { 563 void P2PTransportChannel::OnRoleConflict(PortInterface* port) {
630 SignalRoleConflict(this); // STUN ping will be sent when SetRole is called 564 SignalRoleConflict(this); // STUN ping will be sent when SetRole is called
631 // from Transport. 565 // from Transport.
632 } 566 }
633 567
634 // When the signalling channel is ready, we can really kick off the allocator 568 // When the signalling channel is ready, we can really kick off the allocator
635 void P2PTransportChannel::OnSignalingReady() { 569 void P2PTransportChannel::OnSignalingReady() {
636 ASSERT(worker_thread_ == rtc::Thread::Current()); 570 ASSERT(worker_thread_ == rtc::Thread::Current());
637 if (waiting_for_signaling_) { 571 if (waiting_for_signaling_) {
638 waiting_for_signaling_ = false; 572 waiting_for_signaling_ = false;
639 AddAllocatorSession(allocator_->CreateSession( 573 AddAllocatorSession(allocator_->CreateSession(
640 SessionId(), content_name(), component(), ice_ufrag_, ice_pwd_)); 574 SessionId(), content_name(), component(), ice_ufrag_, ice_pwd_));
641 } 575 }
642 } 576 }
643 577
644 void P2PTransportChannel::OnUseCandidate(Connection* conn) { 578 void P2PTransportChannel::OnUseCandidate(Connection* conn) {
645 ASSERT(worker_thread_ == rtc::Thread::Current()); 579 ASSERT(worker_thread_ == rtc::Thread::Current());
646 ASSERT(ice_role_ == ICEROLE_CONTROLLED); 580 ASSERT(ice_role_ == ICEROLE_CONTROLLED);
647 ASSERT(protocol_type_ == ICEPROTO_RFC5245);
648 581
649 if (conn->write_state() == Connection::STATE_WRITABLE) { 582 if (conn->write_state() == Connection::STATE_WRITABLE) {
650 if (best_connection_ != conn) { 583 if (best_connection_ != conn) {
651 pending_best_connection_ = NULL; 584 pending_best_connection_ = NULL;
652 LOG(LS_INFO) << "Switching best connection on controlled side: " 585 LOG(LS_INFO) << "Switching best connection on controlled side: "
653 << conn->ToString(); 586 << conn->ToString();
654 SwitchBestConnectionTo(conn); 587 SwitchBestConnectionTo(conn);
655 // Now we have selected the best connection, time to prune other existing 588 // Now we have selected the best connection, time to prune other existing
656 // connections and update the read/write state of the channel. 589 // connections and update the read/write state of the channel.
657 RequestSort(); 590 RequestSort();
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
785 718
786 bool P2PTransportChannel::FindConnection( 719 bool P2PTransportChannel::FindConnection(
787 cricket::Connection* connection) const { 720 cricket::Connection* connection) const {
788 std::vector<Connection*>::const_iterator citer = 721 std::vector<Connection*>::const_iterator citer =
789 std::find(connections_.begin(), connections_.end(), connection); 722 std::find(connections_.begin(), connections_.end(), connection);
790 return citer != connections_.end(); 723 return citer != connections_.end();
791 } 724 }
792 725
793 uint32 P2PTransportChannel::GetRemoteCandidateGeneration( 726 uint32 P2PTransportChannel::GetRemoteCandidateGeneration(
794 const Candidate& candidate) { 727 const Candidate& candidate) {
795 if (protocol_type_ == ICEPROTO_GOOGLE) { 728 // We need to keep track of the remote ice restart so newer
796 // The Candidate.generation() can be trusted. Nothing needs to be done. 729 // connections are prioritized over the older.
797 return candidate.generation();
798 }
799 // |candidate.generation()| is not signaled in ICEPROTO_RFC5245.
800 // Therefore we need to keep track of the remote ice restart so
801 // newer connections are prioritized over the older.
802 ASSERT(candidate.generation() == 0 || 730 ASSERT(candidate.generation() == 0 ||
803 candidate.generation() == remote_candidate_generation_); 731 candidate.generation() == remote_candidate_generation_);
804 return remote_candidate_generation_; 732 return remote_candidate_generation_;
805 } 733 }
806 734
807 // Check if remote candidate is already cached. 735 // Check if remote candidate is already cached.
808 bool P2PTransportChannel::IsDuplicateRemoteCandidate( 736 bool P2PTransportChannel::IsDuplicateRemoteCandidate(
809 const Candidate& candidate) { 737 const Candidate& candidate) {
810 for (uint32 i = 0; i < remote_candidates_.size(); ++i) { 738 for (uint32 i = 0; i < remote_candidates_.size(); ++i) {
811 if (remote_candidates_[i].IsEquivalent(candidate)) { 739 if (remote_candidates_[i].IsEquivalent(candidate)) {
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
969 897
970 // Sort the available connections to find the best one. We also monitor 898 // Sort the available connections to find the best one. We also monitor
971 // the number of available connections and the current state. 899 // the number of available connections and the current state.
972 void P2PTransportChannel::SortConnections() { 900 void P2PTransportChannel::SortConnections() {
973 ASSERT(worker_thread_ == rtc::Thread::Current()); 901 ASSERT(worker_thread_ == rtc::Thread::Current());
974 902
975 // Make sure the connection states are up-to-date since this affects how they 903 // Make sure the connection states are up-to-date since this affects how they
976 // will be sorted. 904 // will be sorted.
977 UpdateConnectionStates(); 905 UpdateConnectionStates();
978 906
979 if (protocol_type_ == ICEPROTO_HYBRID) {
980 // If we are in hybrid mode, we are not sending any ping requests, so there
981 // is no point in sorting the connections. In hybrid state, ports can have
982 // different protocol than hybrid and protocol may differ from one another.
983 // Instead just update the state of this channel
984 UpdateChannelState();
985 return;
986 }
987
988 // Any changes after this point will require a re-sort. 907 // Any changes after this point will require a re-sort.
989 sort_dirty_ = false; 908 sort_dirty_ = false;
990 909
991 // Get a list of the networks that we are using. 910 // Get a list of the networks that we are using.
992 std::set<rtc::Network*> networks; 911 std::set<rtc::Network*> networks;
993 for (uint32 i = 0; i < connections_.size(); ++i) 912 for (uint32 i = 0; i < connections_.size(); ++i)
994 networks.insert(connections_[i]->port()->Network()); 913 networks.insert(connections_[i]->port()->Network());
995 914
996 // Find the best alternative connection by sorting. It is important to note 915 // Find the best alternative connection by sorting. It is important to note
997 // that amongst equal preference, writable connections, this will choose the 916 // 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 917 // one whose estimated latency is lowest. So it is the only one that we
999 // need to consider switching to. 918 // need to consider switching to.
1000 919
1001 ConnectionCompare cmp; 920 ConnectionCompare cmp;
1002 std::stable_sort(connections_.begin(), connections_.end(), cmp); 921 std::stable_sort(connections_.begin(), connections_.end(), cmp);
1003 LOG(LS_VERBOSE) << "Sorting available connections:"; 922 LOG(LS_VERBOSE) << "Sorting available connections:";
1004 for (uint32 i = 0; i < connections_.size(); ++i) { 923 for (uint32 i = 0; i < connections_.size(); ++i) {
1005 LOG(LS_VERBOSE) << connections_[i]->ToString(); 924 LOG(LS_VERBOSE) << connections_[i]->ToString();
1006 } 925 }
1007 926
1008 Connection* top_connection = NULL; 927 Connection* top_connection = NULL;
1009 if (connections_.size() > 0) 928 if (connections_.size() > 0)
1010 top_connection = connections_[0]; 929 top_connection = connections_[0];
1011 930
1012 // We don't want to pick the best connections if channel is using RFC5245 931 // We don't want to pick the best connections if channel is
1013 // and it's mode is CONTROLLED, as connections will be selected by the 932 // CONTROLLED, as connections will be selected by the CONTROLLING
1014 // CONTROLLING agent. 933 // agent.
1015 934
1016 // If necessary, switch to the new choice. 935 // If necessary, switch to the new choice.
1017 if (protocol_type_ != ICEPROTO_RFC5245 || ice_role_ == ICEROLE_CONTROLLING) { 936 if (ice_role_ == ICEROLE_CONTROLLING) {
1018 if (ShouldSwitch(best_connection_, top_connection)) { 937 if (ShouldSwitch(best_connection_, top_connection)) {
1019 LOG(LS_INFO) << "Switching best connection on controlling side: " 938 LOG(LS_INFO) << "Switching best connection on controlling side: "
1020 << top_connection->ToString(); 939 << top_connection->ToString();
1021 SwitchBestConnectionTo(top_connection); 940 SwitchBestConnectionTo(top_connection);
1022 } 941 }
1023 } 942 }
1024 943
1025 // We can prune any connection for which there is a connected, writable 944 // We can prune any connection for which there is a connected, writable
1026 // connection on the same network with better or equal priority. We leave 945 // connection on the same network with better or equal priority. We leave
1027 // those with better priority just in case they become writable later (at 946 // those with better priority just in case they become writable later (at
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
1266 // that have received a ping but have not sent a ping since receiving 1185 // 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 1186 // it (last_received_ping > last_sent_ping). But we shouldn't do
1268 // triggered checks if the connection is already writable. 1187 // triggered checks if the connection is already writable.
1269 Connection* oldest_needing_triggered_check = nullptr; 1188 Connection* oldest_needing_triggered_check = nullptr;
1270 Connection* oldest = nullptr; 1189 Connection* oldest = nullptr;
1271 for (Connection* conn : connections_) { 1190 for (Connection* conn : connections_) {
1272 if (!IsPingable(conn)) { 1191 if (!IsPingable(conn)) {
1273 continue; 1192 continue;
1274 } 1193 }
1275 bool needs_triggered_check = 1194 bool needs_triggered_check =
1276 (protocol_type_ == ICEPROTO_RFC5245 && 1195 (!conn->writable() &&
1277 !conn->writable() &&
1278 conn->last_ping_received() > conn->last_ping_sent()); 1196 conn->last_ping_received() > conn->last_ping_sent());
1279 if (needs_triggered_check && 1197 if (needs_triggered_check &&
1280 (!oldest_needing_triggered_check || 1198 (!oldest_needing_triggered_check ||
1281 (conn->last_ping_received() < 1199 (conn->last_ping_received() <
1282 oldest_needing_triggered_check->last_ping_received()))) { 1200 oldest_needing_triggered_check->last_ping_received()))) {
1283 oldest_needing_triggered_check = conn; 1201 oldest_needing_triggered_check = conn;
1284 } 1202 }
1285 if (!oldest || (conn->last_ping_sent() < oldest->last_ping_sent())) { 1203 if (!oldest || (conn->last_ping_sent() < oldest->last_ping_sent())) {
1286 oldest = conn; 1204 oldest = conn;
1287 } 1205 }
(...skipping 14 matching lines...) Expand all
1302 // a) Channel is in FULL ICE AND 1220 // a) Channel is in FULL ICE AND
1303 // a.1) |conn| is the best connection OR 1221 // a.1) |conn| is the best connection OR
1304 // a.2) there is no best connection OR 1222 // a.2) there is no best connection OR
1305 // a.3) the best connection is unwritable OR 1223 // a.3) the best connection is unwritable OR
1306 // a.4) |conn| has higher priority than best_connection. 1224 // a.4) |conn| has higher priority than best_connection.
1307 // b) we're doing LITE ICE AND 1225 // b) we're doing LITE ICE AND
1308 // b.1) |conn| is the best_connection AND 1226 // b.1) |conn| is the best_connection AND
1309 // b.2) |conn| is writable. 1227 // b.2) |conn| is writable.
1310 void P2PTransportChannel::PingConnection(Connection* conn) { 1228 void P2PTransportChannel::PingConnection(Connection* conn) {
1311 bool use_candidate = false; 1229 bool use_candidate = false;
1312 if (protocol_type_ == ICEPROTO_RFC5245) { 1230 if (remote_ice_mode_ == ICEMODE_FULL && ice_role_ == ICEROLE_CONTROLLING) {
1313 if (remote_ice_mode_ == ICEMODE_FULL && ice_role_ == ICEROLE_CONTROLLING) { 1231 use_candidate = (conn == best_connection_) ||
1314 use_candidate = (conn == best_connection_) || 1232 (best_connection_ == NULL) ||
1315 (best_connection_ == NULL) || 1233 (!best_connection_->writable()) ||
1316 (!best_connection_->writable()) || 1234 (conn->priority() > best_connection_->priority());
1317 (conn->priority() > best_connection_->priority()); 1235 } else if (remote_ice_mode_ == ICEMODE_LITE && conn == best_connection_) {
1318 } else if (remote_ice_mode_ == ICEMODE_LITE && conn == best_connection_) { 1236 use_candidate = best_connection_->writable();
1319 use_candidate = best_connection_->writable();
1320 }
1321 } 1237 }
1322 conn->set_use_candidate_attr(use_candidate); 1238 conn->set_use_candidate_attr(use_candidate);
1323 conn->Ping(rtc::Time()); 1239 conn->Ping(rtc::Time());
1324 } 1240 }
1325 1241
1326 // When a connection's state changes, we need to figure out who to use as 1242 // When a connection's state changes, we need to figure out who to use as
1327 // the best connection again. It could have become usable, or become unusable. 1243 // the best connection again. It could have become usable, or become unusable.
1328 void P2PTransportChannel::OnConnectionStateChange(Connection* connection) { 1244 void P2PTransportChannel::OnConnectionStateChange(Connection* connection) {
1329 ASSERT(worker_thread_ == rtc::Thread::Current()); 1245 ASSERT(worker_thread_ == rtc::Thread::Current());
1330 1246
1331 // Update the best connection if the state change is from pending best 1247 // Update the best connection if the state change is from pending best
1332 // connection and role is controlled. 1248 // connection and role is controlled.
1333 if (protocol_type_ == ICEPROTO_RFC5245 && ice_role_ == ICEROLE_CONTROLLED) { 1249 if (ice_role_ == ICEROLE_CONTROLLED) {
1334 if (connection == pending_best_connection_ && connection->writable()) { 1250 if (connection == pending_best_connection_ && connection->writable()) {
1335 pending_best_connection_ = NULL; 1251 pending_best_connection_ = NULL;
1336 LOG(LS_INFO) << "Switching best connection on controlled side" 1252 LOG(LS_INFO) << "Switching best connection on controlled side"
1337 << " because it's now writable: " << connection->ToString(); 1253 << " because it's now writable: " << connection->ToString();
1338 SwitchBestConnectionTo(connection); 1254 SwitchBestConnectionTo(connection);
1339 } 1255 }
1340 } 1256 }
1341 1257
1342 // We have to unroll the stack before doing this because we may be changing 1258 // We have to unroll the stack before doing this because we may be changing
1343 // the state of connections while sorting. 1259 // the state of connections while sorting.
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1408 SignalReadPacket(this, data, len, packet_time, 0); 1324 SignalReadPacket(this, data, len, packet_time, 0);
1409 } 1325 }
1410 1326
1411 void P2PTransportChannel::OnReadyToSend(Connection* connection) { 1327 void P2PTransportChannel::OnReadyToSend(Connection* connection) {
1412 if (connection == best_connection_ && writable()) { 1328 if (connection == best_connection_ && writable()) {
1413 SignalReadyToSend(this); 1329 SignalReadyToSend(this);
1414 } 1330 }
1415 } 1331 }
1416 1332
1417 } // namespace cricket 1333 } // 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