| OLD | NEW |
| 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 15 matching lines...) Expand all Loading... |
| 26 MSG_SORT = 1, | 26 MSG_SORT = 1, |
| 27 MSG_PING, | 27 MSG_PING, |
| 28 MSG_CHECK_RECEIVING | 28 MSG_CHECK_RECEIVING |
| 29 }; | 29 }; |
| 30 | 30 |
| 31 // When the socket is unwritable, we will use 10 Kbps (ignoring IP+UDP headers) | 31 // When the socket is unwritable, we will use 10 Kbps (ignoring IP+UDP headers) |
| 32 // for pinging. When the socket is writable, we will use only 1 Kbps because | 32 // for pinging. When the socket is writable, we will use only 1 Kbps because |
| 33 // we don't want to degrade the quality on a modem. These numbers should work | 33 // we don't want to degrade the quality on a modem. These numbers should work |
| 34 // well on a 28.8K modem, which is the slowest connection on which the voice | 34 // well on a 28.8K modem, which is the slowest connection on which the voice |
| 35 // quality is reasonable at all. | 35 // quality is reasonable at all. |
| 36 static const uint32 PING_PACKET_SIZE = 60 * 8; | 36 static const uint32_t PING_PACKET_SIZE = 60 * 8; |
| 37 static const uint32 WRITABLE_DELAY = 1000 * PING_PACKET_SIZE / 1000; // 480ms | 37 static const uint32_t WRITABLE_DELAY = 1000 * PING_PACKET_SIZE / 1000; // 480ms |
| 38 static const uint32 UNWRITABLE_DELAY = 1000 * PING_PACKET_SIZE / 10000; // 50ms | 38 static const uint32_t UNWRITABLE_DELAY = |
| 39 1000 * PING_PACKET_SIZE / 10000; // 50ms |
| 39 | 40 |
| 40 // If there is a current writable connection, then we will also try hard to | 41 // If there is a current writable connection, then we will also try hard to |
| 41 // make sure it is pinged at this rate. | 42 // make sure it is pinged at this rate. |
| 42 static const uint32 MAX_CURRENT_WRITABLE_DELAY = 900; // 2*WRITABLE_DELAY - bit | 43 static const uint32_t MAX_CURRENT_WRITABLE_DELAY = |
| 44 900; // 2*WRITABLE_DELAY - bit |
| 43 | 45 |
| 44 static const int MIN_CHECK_RECEIVING_DELAY = 50; // ms | 46 static const int MIN_CHECK_RECEIVING_DELAY = 50; // ms |
| 45 | 47 |
| 46 // The minimum improvement in RTT that justifies a switch. | 48 // The minimum improvement in RTT that justifies a switch. |
| 47 static const double kMinImprovement = 10; | 49 static const double kMinImprovement = 10; |
| 48 | 50 |
| 49 cricket::PortInterface::CandidateOrigin GetOrigin(cricket::PortInterface* port, | 51 cricket::PortInterface::CandidateOrigin GetOrigin(cricket::PortInterface* port, |
| 50 cricket::PortInterface* origin_port) { | 52 cricket::PortInterface* origin_port) { |
| 51 if (!origin_port) | 53 if (!origin_port) |
| 52 return cricket::PortInterface::ORIGIN_MESSAGE; | 54 return cricket::PortInterface::ORIGIN_MESSAGE; |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 188 ice_role_(ICEROLE_UNKNOWN), | 190 ice_role_(ICEROLE_UNKNOWN), |
| 189 tiebreaker_(0), | 191 tiebreaker_(0), |
| 190 remote_candidate_generation_(0), | 192 remote_candidate_generation_(0), |
| 191 check_receiving_delay_(MIN_CHECK_RECEIVING_DELAY * 5), | 193 check_receiving_delay_(MIN_CHECK_RECEIVING_DELAY * 5), |
| 192 receiving_timeout_(MIN_CHECK_RECEIVING_DELAY * 50) { | 194 receiving_timeout_(MIN_CHECK_RECEIVING_DELAY * 50) { |
| 193 } | 195 } |
| 194 | 196 |
| 195 P2PTransportChannel::~P2PTransportChannel() { | 197 P2PTransportChannel::~P2PTransportChannel() { |
| 196 ASSERT(worker_thread_ == rtc::Thread::Current()); | 198 ASSERT(worker_thread_ == rtc::Thread::Current()); |
| 197 | 199 |
| 198 for (uint32 i = 0; i < allocator_sessions_.size(); ++i) | 200 for (uint32_t i = 0; i < allocator_sessions_.size(); ++i) |
| 199 delete allocator_sessions_[i]; | 201 delete allocator_sessions_[i]; |
| 200 } | 202 } |
| 201 | 203 |
| 202 // Add the allocator session to our list so that we know which sessions | 204 // Add the allocator session to our list so that we know which sessions |
| 203 // are still active. | 205 // are still active. |
| 204 void P2PTransportChannel::AddAllocatorSession(PortAllocatorSession* session) { | 206 void P2PTransportChannel::AddAllocatorSession(PortAllocatorSession* session) { |
| 205 session->set_generation(static_cast<uint32>(allocator_sessions_.size())); | 207 session->set_generation(static_cast<uint32_t>(allocator_sessions_.size())); |
| 206 allocator_sessions_.push_back(session); | 208 allocator_sessions_.push_back(session); |
| 207 | 209 |
| 208 // We now only want to apply new candidates that we receive to the ports | 210 // We now only want to apply new candidates that we receive to the ports |
| 209 // created by this new session because these are replacing those of the | 211 // created by this new session because these are replacing those of the |
| 210 // previous sessions. | 212 // previous sessions. |
| 211 ports_.clear(); | 213 ports_.clear(); |
| 212 | 214 |
| 213 session->SignalPortReady.connect(this, &P2PTransportChannel::OnPortReady); | 215 session->SignalPortReady.connect(this, &P2PTransportChannel::OnPortReady); |
| 214 session->SignalCandidatesReady.connect( | 216 session->SignalCandidatesReady.connect( |
| 215 this, &P2PTransportChannel::OnCandidatesReady); | 217 this, &P2PTransportChannel::OnCandidatesReady); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 237 ASSERT(worker_thread_ == rtc::Thread::Current()); | 239 ASSERT(worker_thread_ == rtc::Thread::Current()); |
| 238 if (ice_role_ != ice_role) { | 240 if (ice_role_ != ice_role) { |
| 239 ice_role_ = ice_role; | 241 ice_role_ = ice_role; |
| 240 for (std::vector<PortInterface *>::iterator it = ports_.begin(); | 242 for (std::vector<PortInterface *>::iterator it = ports_.begin(); |
| 241 it != ports_.end(); ++it) { | 243 it != ports_.end(); ++it) { |
| 242 (*it)->SetIceRole(ice_role); | 244 (*it)->SetIceRole(ice_role); |
| 243 } | 245 } |
| 244 } | 246 } |
| 245 } | 247 } |
| 246 | 248 |
| 247 void P2PTransportChannel::SetIceTiebreaker(uint64 tiebreaker) { | 249 void P2PTransportChannel::SetIceTiebreaker(uint64_t tiebreaker) { |
| 248 ASSERT(worker_thread_ == rtc::Thread::Current()); | 250 ASSERT(worker_thread_ == rtc::Thread::Current()); |
| 249 if (!ports_.empty()) { | 251 if (!ports_.empty()) { |
| 250 LOG(LS_ERROR) | 252 LOG(LS_ERROR) |
| 251 << "Attempt to change tiebreaker after Port has been allocated."; | 253 << "Attempt to change tiebreaker after Port has been allocated."; |
| 252 return; | 254 return; |
| 253 } | 255 } |
| 254 | 256 |
| 255 tiebreaker_ = tiebreaker; | 257 tiebreaker_ = tiebreaker; |
| 256 } | 258 } |
| 257 | 259 |
| 258 // Currently a channel is considered ICE completed once there is no | 260 // Currently a channel is considered ICE completed once there is no |
| 259 // more than one connection per Network. This works for a single NIC | 261 // more than one connection per Network. This works for a single NIC |
| 260 // with both IPv4 and IPv6 enabled. However, this condition won't | 262 // with both IPv4 and IPv6 enabled. However, this condition won't |
| 261 // happen when there are multiple NICs and all of them have | 263 // happen when there are multiple NICs and all of them have |
| 262 // connectivity. | 264 // connectivity. |
| 263 // TODO(guoweis): Change Completion to be driven by a channel level | 265 // TODO(guoweis): Change Completion to be driven by a channel level |
| 264 // timer. | 266 // timer. |
| 265 TransportChannelState P2PTransportChannel::GetState() const { | 267 TransportChannelState P2PTransportChannel::GetState() const { |
| 266 std::set<rtc::Network*> networks; | 268 std::set<rtc::Network*> networks; |
| 267 | 269 |
| 268 if (connections_.size() == 0) { | 270 if (connections_.size() == 0) { |
| 269 return TransportChannelState::STATE_FAILED; | 271 return TransportChannelState::STATE_FAILED; |
| 270 } | 272 } |
| 271 | 273 |
| 272 for (uint32 i = 0; i < connections_.size(); ++i) { | 274 for (uint32_t i = 0; i < connections_.size(); ++i) { |
| 273 rtc::Network* network = connections_[i]->port()->Network(); | 275 rtc::Network* network = connections_[i]->port()->Network(); |
| 274 if (networks.find(network) == networks.end()) { | 276 if (networks.find(network) == networks.end()) { |
| 275 networks.insert(network); | 277 networks.insert(network); |
| 276 } else { | 278 } else { |
| 277 LOG_J(LS_VERBOSE, this) << "Ice not completed yet for this channel as " | 279 LOG_J(LS_VERBOSE, this) << "Ice not completed yet for this channel as " |
| 278 << network->ToString() | 280 << network->ToString() |
| 279 << " has more than 1 connection."; | 281 << " has more than 1 connection."; |
| 280 return TransportChannelState::STATE_CONNECTING; | 282 return TransportChannelState::STATE_CONNECTING; |
| 281 } | 283 } |
| 282 } | 284 } |
| (...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 506 // existing remote candidates, it represents a new peer reflexive remote | 508 // existing remote candidates, it represents a new peer reflexive remote |
| 507 // candidate. | 509 // candidate. |
| 508 remote_candidate = | 510 remote_candidate = |
| 509 Candidate(component(), ProtoToString(proto), address, 0, | 511 Candidate(component(), ProtoToString(proto), address, 0, |
| 510 remote_username, remote_password, PRFLX_PORT_TYPE, 0U, ""); | 512 remote_username, remote_password, PRFLX_PORT_TYPE, 0U, ""); |
| 511 | 513 |
| 512 // From RFC 5245, section-7.2.1.3: | 514 // From RFC 5245, section-7.2.1.3: |
| 513 // The foundation of the candidate is set to an arbitrary value, different | 515 // The foundation of the candidate is set to an arbitrary value, different |
| 514 // from the foundation for all other remote candidates. | 516 // from the foundation for all other remote candidates. |
| 515 remote_candidate.set_foundation( | 517 remote_candidate.set_foundation( |
| 516 rtc::ToString<uint32>(rtc::ComputeCrc32(remote_candidate.id()))); | 518 rtc::ToString<uint32_t>(rtc::ComputeCrc32(remote_candidate.id()))); |
| 517 | 519 |
| 518 remote_candidate.set_priority(remote_candidate_priority); | 520 remote_candidate.set_priority(remote_candidate_priority); |
| 519 } | 521 } |
| 520 | 522 |
| 521 // RFC5245, the agent constructs a pair whose local candidate is equal to | 523 // RFC5245, the agent constructs a pair whose local candidate is equal to |
| 522 // the transport address on which the STUN request was received, and a | 524 // the transport address on which the STUN request was received, and a |
| 523 // remote candidate equal to the source transport address where the | 525 // remote candidate equal to the source transport address where the |
| 524 // request came from. | 526 // request came from. |
| 525 | 527 |
| 526 // There shouldn't be an existing connection with this remote address. | 528 // There shouldn't be an existing connection with this remote address. |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 602 } else { | 604 } else { |
| 603 LOG(LS_INFO) << "Not switching the best connection on controlled side yet," | 605 LOG(LS_INFO) << "Not switching the best connection on controlled side yet," |
| 604 << " because it's not writable: " << conn->ToString(); | 606 << " because it's not writable: " << conn->ToString(); |
| 605 pending_best_connection_ = conn; | 607 pending_best_connection_ = conn; |
| 606 } | 608 } |
| 607 } | 609 } |
| 608 | 610 |
| 609 void P2PTransportChannel::OnCandidate(const Candidate& candidate) { | 611 void P2PTransportChannel::OnCandidate(const Candidate& candidate) { |
| 610 ASSERT(worker_thread_ == rtc::Thread::Current()); | 612 ASSERT(worker_thread_ == rtc::Thread::Current()); |
| 611 | 613 |
| 612 uint32 generation = candidate.generation(); | 614 uint32_t generation = candidate.generation(); |
| 613 // Network may not guarantee the order of the candidate delivery. If a | 615 // Network may not guarantee the order of the candidate delivery. If a |
| 614 // remote candidate with an older generation arrives, drop it. | 616 // remote candidate with an older generation arrives, drop it. |
| 615 if (generation != 0 && generation < remote_candidate_generation_) { | 617 if (generation != 0 && generation < remote_candidate_generation_) { |
| 616 LOG(LS_WARNING) << "Dropping a remote candidate because its generation " | 618 LOG(LS_WARNING) << "Dropping a remote candidate because its generation " |
| 617 << generation | 619 << generation |
| 618 << " is lower than the current remote generation " | 620 << " is lower than the current remote generation " |
| 619 << remote_candidate_generation_; | 621 << remote_candidate_generation_; |
| 620 return; | 622 return; |
| 621 } | 623 } |
| 622 | 624 |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 729 return true; | 731 return true; |
| 730 } | 732 } |
| 731 | 733 |
| 732 bool P2PTransportChannel::FindConnection( | 734 bool P2PTransportChannel::FindConnection( |
| 733 cricket::Connection* connection) const { | 735 cricket::Connection* connection) const { |
| 734 std::vector<Connection*>::const_iterator citer = | 736 std::vector<Connection*>::const_iterator citer = |
| 735 std::find(connections_.begin(), connections_.end(), connection); | 737 std::find(connections_.begin(), connections_.end(), connection); |
| 736 return citer != connections_.end(); | 738 return citer != connections_.end(); |
| 737 } | 739 } |
| 738 | 740 |
| 739 uint32 P2PTransportChannel::GetRemoteCandidateGeneration( | 741 uint32_t P2PTransportChannel::GetRemoteCandidateGeneration( |
| 740 const Candidate& candidate) { | 742 const Candidate& candidate) { |
| 741 // We need to keep track of the remote ice restart so newer | 743 // We need to keep track of the remote ice restart so newer |
| 742 // connections are prioritized over the older. | 744 // connections are prioritized over the older. |
| 743 ASSERT(candidate.generation() == 0 || | 745 ASSERT(candidate.generation() == 0 || |
| 744 candidate.generation() == remote_candidate_generation_); | 746 candidate.generation() == remote_candidate_generation_); |
| 745 return remote_candidate_generation_; | 747 return remote_candidate_generation_; |
| 746 } | 748 } |
| 747 | 749 |
| 748 // Check if remote candidate is already cached. | 750 // Check if remote candidate is already cached. |
| 749 bool P2PTransportChannel::IsDuplicateRemoteCandidate( | 751 bool P2PTransportChannel::IsDuplicateRemoteCandidate( |
| 750 const Candidate& candidate) { | 752 const Candidate& candidate) { |
| 751 for (uint32 i = 0; i < remote_candidates_.size(); ++i) { | 753 for (uint32_t i = 0; i < remote_candidates_.size(); ++i) { |
| 752 if (remote_candidates_[i].IsEquivalent(candidate)) { | 754 if (remote_candidates_[i].IsEquivalent(candidate)) { |
| 753 return true; | 755 return true; |
| 754 } | 756 } |
| 755 } | 757 } |
| 756 return false; | 758 return false; |
| 757 } | 759 } |
| 758 | 760 |
| 759 // Maintain our remote candidate list, adding this new remote one. | 761 // Maintain our remote candidate list, adding this new remote one. |
| 760 void P2PTransportChannel::RememberRemoteCandidate( | 762 void P2PTransportChannel::RememberRemoteCandidate( |
| 761 const Candidate& remote_candidate, PortInterface* origin_port) { | 763 const Candidate& remote_candidate, PortInterface* origin_port) { |
| 762 // Remove any candidates whose generation is older than this one. The | 764 // Remove any candidates whose generation is older than this one. The |
| 763 // presence of a new generation indicates that the old ones are not useful. | 765 // presence of a new generation indicates that the old ones are not useful. |
| 764 uint32 i = 0; | 766 uint32_t i = 0; |
| 765 while (i < remote_candidates_.size()) { | 767 while (i < remote_candidates_.size()) { |
| 766 if (remote_candidates_[i].generation() < remote_candidate.generation()) { | 768 if (remote_candidates_[i].generation() < remote_candidate.generation()) { |
| 767 LOG(INFO) << "Pruning candidate from old generation: " | 769 LOG(INFO) << "Pruning candidate from old generation: " |
| 768 << remote_candidates_[i].address().ToSensitiveString(); | 770 << remote_candidates_[i].address().ToSensitiveString(); |
| 769 remote_candidates_.erase(remote_candidates_.begin() + i); | 771 remote_candidates_.erase(remote_candidates_.begin() + i); |
| 770 } else { | 772 } else { |
| 771 i += 1; | 773 i += 1; |
| 772 } | 774 } |
| 773 } | 775 } |
| 774 | 776 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 788 ASSERT(worker_thread_ == rtc::Thread::Current()); | 790 ASSERT(worker_thread_ == rtc::Thread::Current()); |
| 789 OptionMap::iterator it = options_.find(opt); | 791 OptionMap::iterator it = options_.find(opt); |
| 790 if (it == options_.end()) { | 792 if (it == options_.end()) { |
| 791 options_.insert(std::make_pair(opt, value)); | 793 options_.insert(std::make_pair(opt, value)); |
| 792 } else if (it->second == value) { | 794 } else if (it->second == value) { |
| 793 return 0; | 795 return 0; |
| 794 } else { | 796 } else { |
| 795 it->second = value; | 797 it->second = value; |
| 796 } | 798 } |
| 797 | 799 |
| 798 for (uint32 i = 0; i < ports_.size(); ++i) { | 800 for (uint32_t i = 0; i < ports_.size(); ++i) { |
| 799 int val = ports_[i]->SetOption(opt, value); | 801 int val = ports_[i]->SetOption(opt, value); |
| 800 if (val < 0) { | 802 if (val < 0) { |
| 801 // Because this also occurs deferred, probably no point in reporting an | 803 // Because this also occurs deferred, probably no point in reporting an |
| 802 // error | 804 // error |
| 803 LOG(WARNING) << "SetOption(" << opt << ", " << value << ") failed: " | 805 LOG(WARNING) << "SetOption(" << opt << ", " << value << ") failed: " |
| 804 << ports_[i]->GetError(); | 806 << ports_[i]->GetError(); |
| 805 } | 807 } |
| 806 } | 808 } |
| 807 return 0; | 809 return 0; |
| 808 } | 810 } |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 884 // Begin allocate (or immediately re-allocate, if MSG_ALLOCATE pending) | 886 // Begin allocate (or immediately re-allocate, if MSG_ALLOCATE pending) |
| 885 void P2PTransportChannel::Allocate() { | 887 void P2PTransportChannel::Allocate() { |
| 886 // Time for a new allocator, lets make sure we have a signalling channel | 888 // Time for a new allocator, lets make sure we have a signalling channel |
| 887 // to communicate candidates through first. | 889 // to communicate candidates through first. |
| 888 waiting_for_signaling_ = true; | 890 waiting_for_signaling_ = true; |
| 889 SignalRequestSignaling(this); | 891 SignalRequestSignaling(this); |
| 890 } | 892 } |
| 891 | 893 |
| 892 // Monitor connection states. | 894 // Monitor connection states. |
| 893 void P2PTransportChannel::UpdateConnectionStates() { | 895 void P2PTransportChannel::UpdateConnectionStates() { |
| 894 uint32 now = rtc::Time(); | 896 uint32_t now = rtc::Time(); |
| 895 | 897 |
| 896 // We need to copy the list of connections since some may delete themselves | 898 // We need to copy the list of connections since some may delete themselves |
| 897 // when we call UpdateState. | 899 // when we call UpdateState. |
| 898 for (uint32 i = 0; i < connections_.size(); ++i) | 900 for (uint32_t i = 0; i < connections_.size(); ++i) |
| 899 connections_[i]->UpdateState(now); | 901 connections_[i]->UpdateState(now); |
| 900 } | 902 } |
| 901 | 903 |
| 902 // Prepare for best candidate sorting. | 904 // Prepare for best candidate sorting. |
| 903 void P2PTransportChannel::RequestSort() { | 905 void P2PTransportChannel::RequestSort() { |
| 904 if (!sort_dirty_) { | 906 if (!sort_dirty_) { |
| 905 worker_thread_->Post(this, MSG_SORT); | 907 worker_thread_->Post(this, MSG_SORT); |
| 906 sort_dirty_ = true; | 908 sort_dirty_ = true; |
| 907 } | 909 } |
| 908 } | 910 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 919 // Any changes after this point will require a re-sort. | 921 // Any changes after this point will require a re-sort. |
| 920 sort_dirty_ = false; | 922 sort_dirty_ = false; |
| 921 | 923 |
| 922 // Find the best alternative connection by sorting. It is important to note | 924 // Find the best alternative connection by sorting. It is important to note |
| 923 // that amongst equal preference, writable connections, this will choose the | 925 // that amongst equal preference, writable connections, this will choose the |
| 924 // one whose estimated latency is lowest. So it is the only one that we | 926 // one whose estimated latency is lowest. So it is the only one that we |
| 925 // need to consider switching to. | 927 // need to consider switching to. |
| 926 ConnectionCompare cmp; | 928 ConnectionCompare cmp; |
| 927 std::stable_sort(connections_.begin(), connections_.end(), cmp); | 929 std::stable_sort(connections_.begin(), connections_.end(), cmp); |
| 928 LOG(LS_VERBOSE) << "Sorting available connections:"; | 930 LOG(LS_VERBOSE) << "Sorting available connections:"; |
| 929 for (uint32 i = 0; i < connections_.size(); ++i) { | 931 for (uint32_t i = 0; i < connections_.size(); ++i) { |
| 930 LOG(LS_VERBOSE) << connections_[i]->ToString(); | 932 LOG(LS_VERBOSE) << connections_[i]->ToString(); |
| 931 } | 933 } |
| 932 | 934 |
| 933 Connection* top_connection = | 935 Connection* top_connection = |
| 934 (connections_.size() > 0) ? connections_[0] : nullptr; | 936 (connections_.size() > 0) ? connections_[0] : nullptr; |
| 935 | 937 |
| 936 // If necessary, switch to the new choice. | 938 // If necessary, switch to the new choice. |
| 937 // Note that |top_connection| doesn't have to be writable to become the best | 939 // Note that |top_connection| doesn't have to be writable to become the best |
| 938 // connection although it will have higher priority if it is writable. | 940 // connection although it will have higher priority if it is writable. |
| 939 // The controlled side can switch the best connection only if the current | 941 // The controlled side can switch the best connection only if the current |
| 940 // |best connection_| has not been nominated by the controlling side yet. | 942 // |best connection_| has not been nominated by the controlling side yet. |
| 941 if ((ice_role_ == ICEROLE_CONTROLLING || !best_nominated_connection()) && | 943 if ((ice_role_ == ICEROLE_CONTROLLING || !best_nominated_connection()) && |
| 942 ShouldSwitch(best_connection_, top_connection)) { | 944 ShouldSwitch(best_connection_, top_connection)) { |
| 943 LOG(LS_INFO) << "Switching best connection: " << top_connection->ToString(); | 945 LOG(LS_INFO) << "Switching best connection: " << top_connection->ToString(); |
| 944 SwitchBestConnectionTo(top_connection); | 946 SwitchBestConnectionTo(top_connection); |
| 945 } | 947 } |
| 946 | 948 |
| 947 // Controlled side can prune only if the best connection has been nominated. | 949 // Controlled side can prune only if the best connection has been nominated. |
| 948 // because otherwise it may delete the connection that will be selected by | 950 // because otherwise it may delete the connection that will be selected by |
| 949 // the controlling side. | 951 // the controlling side. |
| 950 if (ice_role_ == ICEROLE_CONTROLLING || best_nominated_connection()) { | 952 if (ice_role_ == ICEROLE_CONTROLLING || best_nominated_connection()) { |
| 951 PruneConnections(); | 953 PruneConnections(); |
| 952 } | 954 } |
| 953 | 955 |
| 954 // Check if all connections are timedout. | 956 // Check if all connections are timedout. |
| 955 bool all_connections_timedout = true; | 957 bool all_connections_timedout = true; |
| 956 for (uint32 i = 0; i < connections_.size(); ++i) { | 958 for (uint32_t i = 0; i < connections_.size(); ++i) { |
| 957 if (connections_[i]->write_state() != Connection::STATE_WRITE_TIMEOUT) { | 959 if (connections_[i]->write_state() != Connection::STATE_WRITE_TIMEOUT) { |
| 958 all_connections_timedout = false; | 960 all_connections_timedout = false; |
| 959 break; | 961 break; |
| 960 } | 962 } |
| 961 } | 963 } |
| 962 | 964 |
| 963 // Now update the writable state of the channel with the information we have | 965 // Now update the writable state of the channel with the information we have |
| 964 // so far. | 966 // so far. |
| 965 if (best_connection_ && best_connection_->writable()) { | 967 if (best_connection_ && best_connection_->writable()) { |
| 966 HandleWritable(); | 968 HandleWritable(); |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1043 | 1045 |
| 1044 // TODO(honghaiz): The channel receiving state is set in OnCheckReceiving. | 1046 // TODO(honghaiz): The channel receiving state is set in OnCheckReceiving. |
| 1045 // Will revisit in a subsequent code change. | 1047 // Will revisit in a subsequent code change. |
| 1046 } | 1048 } |
| 1047 | 1049 |
| 1048 // We checked the status of our connections and we had at least one that | 1050 // We checked the status of our connections and we had at least one that |
| 1049 // was writable, go into the writable state. | 1051 // was writable, go into the writable state. |
| 1050 void P2PTransportChannel::HandleWritable() { | 1052 void P2PTransportChannel::HandleWritable() { |
| 1051 ASSERT(worker_thread_ == rtc::Thread::Current()); | 1053 ASSERT(worker_thread_ == rtc::Thread::Current()); |
| 1052 if (!writable()) { | 1054 if (!writable()) { |
| 1053 for (uint32 i = 0; i < allocator_sessions_.size(); ++i) { | 1055 for (uint32_t i = 0; i < allocator_sessions_.size(); ++i) { |
| 1054 if (allocator_sessions_[i]->IsGettingPorts()) { | 1056 if (allocator_sessions_[i]->IsGettingPorts()) { |
| 1055 allocator_sessions_[i]->StopGettingPorts(); | 1057 allocator_sessions_[i]->StopGettingPorts(); |
| 1056 } | 1058 } |
| 1057 } | 1059 } |
| 1058 } | 1060 } |
| 1059 | 1061 |
| 1060 was_writable_ = true; | 1062 was_writable_ = true; |
| 1061 set_writable(true); | 1063 set_writable(true); |
| 1062 } | 1064 } |
| 1063 | 1065 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1077 | 1079 |
| 1078 // If we have a best connection, return it, otherwise return top one in the | 1080 // If we have a best connection, return it, otherwise return top one in the |
| 1079 // list (later we will mark it best). | 1081 // list (later we will mark it best). |
| 1080 Connection* P2PTransportChannel::GetBestConnectionOnNetwork( | 1082 Connection* P2PTransportChannel::GetBestConnectionOnNetwork( |
| 1081 rtc::Network* network) const { | 1083 rtc::Network* network) const { |
| 1082 // If the best connection is on this network, then it wins. | 1084 // If the best connection is on this network, then it wins. |
| 1083 if (best_connection_ && (best_connection_->port()->Network() == network)) | 1085 if (best_connection_ && (best_connection_->port()->Network() == network)) |
| 1084 return best_connection_; | 1086 return best_connection_; |
| 1085 | 1087 |
| 1086 // Otherwise, we return the top-most in sorted order. | 1088 // Otherwise, we return the top-most in sorted order. |
| 1087 for (uint32 i = 0; i < connections_.size(); ++i) { | 1089 for (uint32_t i = 0; i < connections_.size(); ++i) { |
| 1088 if (connections_[i]->port()->Network() == network) | 1090 if (connections_[i]->port()->Network() == network) |
| 1089 return connections_[i]; | 1091 return connections_[i]; |
| 1090 } | 1092 } |
| 1091 | 1093 |
| 1092 return NULL; | 1094 return NULL; |
| 1093 } | 1095 } |
| 1094 | 1096 |
| 1095 // Handle any queued up requests | 1097 // Handle any queued up requests |
| 1096 void P2PTransportChannel::OnMessage(rtc::Message *pmsg) { | 1098 void P2PTransportChannel::OnMessage(rtc::Message *pmsg) { |
| 1097 switch (pmsg->message_id) { | 1099 switch (pmsg->message_id) { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1121 // Make sure the states of the connections are up-to-date (since this affects | 1123 // Make sure the states of the connections are up-to-date (since this affects |
| 1122 // which ones are pingable). | 1124 // which ones are pingable). |
| 1123 UpdateConnectionStates(); | 1125 UpdateConnectionStates(); |
| 1124 | 1126 |
| 1125 // Find the oldest pingable connection and have it do a ping. | 1127 // Find the oldest pingable connection and have it do a ping. |
| 1126 Connection* conn = FindNextPingableConnection(); | 1128 Connection* conn = FindNextPingableConnection(); |
| 1127 if (conn) | 1129 if (conn) |
| 1128 PingConnection(conn); | 1130 PingConnection(conn); |
| 1129 | 1131 |
| 1130 // Post ourselves a message to perform the next ping. | 1132 // Post ourselves a message to perform the next ping. |
| 1131 uint32 delay = writable() ? WRITABLE_DELAY : UNWRITABLE_DELAY; | 1133 uint32_t delay = writable() ? WRITABLE_DELAY : UNWRITABLE_DELAY; |
| 1132 thread()->PostDelayed(delay, this, MSG_PING); | 1134 thread()->PostDelayed(delay, this, MSG_PING); |
| 1133 } | 1135 } |
| 1134 | 1136 |
| 1135 void P2PTransportChannel::OnCheckReceiving() { | 1137 void P2PTransportChannel::OnCheckReceiving() { |
| 1136 if (best_connection_) { | 1138 if (best_connection_) { |
| 1137 bool receiving = rtc::Time() <= | 1139 bool receiving = rtc::Time() <= |
| 1138 best_connection_->last_received() + receiving_timeout_; | 1140 best_connection_->last_received() + receiving_timeout_; |
| 1139 set_receiving(receiving); | 1141 set_receiving(receiving); |
| 1140 } | 1142 } |
| 1141 | 1143 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1166 return !writable() || conn->write_state() != Connection::STATE_WRITE_TIMEOUT; | 1168 return !writable() || conn->write_state() != Connection::STATE_WRITE_TIMEOUT; |
| 1167 } | 1169 } |
| 1168 | 1170 |
| 1169 // Returns the next pingable connection to ping. This will be the oldest | 1171 // Returns the next pingable connection to ping. This will be the oldest |
| 1170 // pingable connection unless we have a connected, writable connection that is | 1172 // pingable connection unless we have a connected, writable connection that is |
| 1171 // past the maximum acceptable ping delay. When reconnecting a TCP connection, | 1173 // past the maximum acceptable ping delay. When reconnecting a TCP connection, |
| 1172 // the best connection is disconnected, although still WRITABLE while | 1174 // the best connection is disconnected, although still WRITABLE while |
| 1173 // reconnecting. The newly created connection should be selected as the ping | 1175 // reconnecting. The newly created connection should be selected as the ping |
| 1174 // target to become writable instead. See the big comment in CompareConnections. | 1176 // target to become writable instead. See the big comment in CompareConnections. |
| 1175 Connection* P2PTransportChannel::FindNextPingableConnection() { | 1177 Connection* P2PTransportChannel::FindNextPingableConnection() { |
| 1176 uint32 now = rtc::Time(); | 1178 uint32_t now = rtc::Time(); |
| 1177 if (best_connection_ && best_connection_->connected() && | 1179 if (best_connection_ && best_connection_->connected() && |
| 1178 (best_connection_->write_state() == Connection::STATE_WRITABLE) && | 1180 (best_connection_->write_state() == Connection::STATE_WRITABLE) && |
| 1179 (best_connection_->last_ping_sent() + MAX_CURRENT_WRITABLE_DELAY <= | 1181 (best_connection_->last_ping_sent() + MAX_CURRENT_WRITABLE_DELAY <= |
| 1180 now)) { | 1182 now)) { |
| 1181 return best_connection_; | 1183 return best_connection_; |
| 1182 } | 1184 } |
| 1183 | 1185 |
| 1184 // First, find "triggered checks". We ping first those connections | 1186 // First, find "triggered checks". We ping first those connections |
| 1185 // that have received a ping but have not sent a ping since receiving | 1187 // that have received a ping but have not sent a ping since receiving |
| 1186 // it (last_received_ping > last_sent_ping). But we shouldn't do | 1188 // it (last_received_ping > last_sent_ping). But we shouldn't do |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1331 } | 1333 } |
| 1332 } | 1334 } |
| 1333 | 1335 |
| 1334 void P2PTransportChannel::OnReadyToSend(Connection* connection) { | 1336 void P2PTransportChannel::OnReadyToSend(Connection* connection) { |
| 1335 if (connection == best_connection_ && writable()) { | 1337 if (connection == best_connection_ && writable()) { |
| 1336 SignalReadyToSend(this); | 1338 SignalReadyToSend(this); |
| 1337 } | 1339 } |
| 1338 } | 1340 } |
| 1339 | 1341 |
| 1340 } // namespace cricket | 1342 } // namespace cricket |
| OLD | NEW |