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

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

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