| 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 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 73 const int WEAK_PING_INTERVAL = 1000 * PING_PACKET_SIZE / 10000; | 73 const int WEAK_PING_INTERVAL = 1000 * PING_PACKET_SIZE / 10000; |
| 74 | 74 |
| 75 // Writable connections are pinged at a faster rate while stabilizing. | 75 // Writable connections are pinged at a faster rate while stabilizing. |
| 76 const int STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL = 900; // ms | 76 const int STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL = 900; // ms |
| 77 | 77 |
| 78 // Writable connections are pinged at a slower rate once stabilized. | 78 // Writable connections are pinged at a slower rate once stabilized. |
| 79 const int STABLE_WRITABLE_CONNECTION_PING_INTERVAL = 2500; // ms | 79 const int STABLE_WRITABLE_CONNECTION_PING_INTERVAL = 2500; // ms |
| 80 | 80 |
| 81 static const int MIN_CHECK_RECEIVING_INTERVAL = 50; // ms | 81 static const int MIN_CHECK_RECEIVING_INTERVAL = 50; // ms |
| 82 | 82 |
| 83 static const int RECEIVING_SWITCHING_DELAY = 1000; // ms |
| 84 |
| 83 // We periodically check if any existing networks do not have any connection | 85 // We periodically check if any existing networks do not have any connection |
| 84 // and regather on those networks. | 86 // and regather on those networks. |
| 85 static const int DEFAULT_REGATHER_ON_FAILED_NETWORKS_INTERVAL = 5 * 60 * 1000; | 87 static const int DEFAULT_REGATHER_ON_FAILED_NETWORKS_INTERVAL = 5 * 60 * 1000; |
| 86 static constexpr int a_is_better = 1; | 88 static constexpr int a_is_better = 1; |
| 87 static constexpr int b_is_better = -1; | 89 static constexpr int b_is_better = -1; |
| 88 | 90 |
| 89 P2PTransportChannel::P2PTransportChannel(const std::string& transport_name, | 91 P2PTransportChannel::P2PTransportChannel(const std::string& transport_name, |
| 90 int component, | 92 int component, |
| 91 P2PTransport* transport, | 93 P2PTransport* transport, |
| 92 PortAllocator* allocator) | 94 PortAllocator* allocator) |
| (...skipping 12 matching lines...) Expand all Loading... |
| 105 ice_role_(ICEROLE_UNKNOWN), | 107 ice_role_(ICEROLE_UNKNOWN), |
| 106 tiebreaker_(0), | 108 tiebreaker_(0), |
| 107 gathering_state_(kIceGatheringNew), | 109 gathering_state_(kIceGatheringNew), |
| 108 check_receiving_interval_(MIN_CHECK_RECEIVING_INTERVAL * 5), | 110 check_receiving_interval_(MIN_CHECK_RECEIVING_INTERVAL * 5), |
| 109 config_(MIN_CHECK_RECEIVING_INTERVAL * 50 /* receiving_timeout */, | 111 config_(MIN_CHECK_RECEIVING_INTERVAL * 50 /* receiving_timeout */, |
| 110 0 /* backup_connection_ping_interval */, | 112 0 /* backup_connection_ping_interval */, |
| 111 GATHER_ONCE /* continual_gathering_policy */, | 113 GATHER_ONCE /* continual_gathering_policy */, |
| 112 false /* prioritize_most_likely_candidate_pairs */, | 114 false /* prioritize_most_likely_candidate_pairs */, |
| 113 STABLE_WRITABLE_CONNECTION_PING_INTERVAL, | 115 STABLE_WRITABLE_CONNECTION_PING_INTERVAL, |
| 114 true /* presume_writable_when_fully_relayed */, | 116 true /* presume_writable_when_fully_relayed */, |
| 115 DEFAULT_REGATHER_ON_FAILED_NETWORKS_INTERVAL) { | 117 DEFAULT_REGATHER_ON_FAILED_NETWORKS_INTERVAL, |
| 118 RECEIVING_SWITCHING_DELAY) { |
| 116 uint32_t weak_ping_interval = ::strtoul( | 119 uint32_t weak_ping_interval = ::strtoul( |
| 117 webrtc::field_trial::FindFullName("WebRTC-StunInterPacketDelay").c_str(), | 120 webrtc::field_trial::FindFullName("WebRTC-StunInterPacketDelay").c_str(), |
| 118 nullptr, 10); | 121 nullptr, 10); |
| 119 if (weak_ping_interval) { | 122 if (weak_ping_interval) { |
| 120 weak_ping_interval_ = static_cast<int>(weak_ping_interval); | 123 weak_ping_interval_ = static_cast<int>(weak_ping_interval); |
| 121 } | 124 } |
| 122 } | 125 } |
| 123 | 126 |
| 124 P2PTransportChannel::~P2PTransportChannel() { | 127 P2PTransportChannel::~P2PTransportChannel() { |
| 125 ASSERT(worker_thread_ == rtc::Thread::Current()); | 128 ASSERT(worker_thread_ == rtc::Thread::Current()); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 177 // criteria is as follows: | 180 // criteria is as follows: |
| 178 // i) write/receiving/connected states | 181 // i) write/receiving/connected states |
| 179 // ii) For controlled side, | 182 // ii) For controlled side, |
| 180 // a) nomination state, | 183 // a) nomination state, |
| 181 // b) last data received time. | 184 // b) last data received time. |
| 182 // iii) Lower cost / higher priority. | 185 // iii) Lower cost / higher priority. |
| 183 // iv) rtt. | 186 // iv) rtt. |
| 184 // TODO(honghaiz): Stop the aggressive nomination on the controlling side and | 187 // TODO(honghaiz): Stop the aggressive nomination on the controlling side and |
| 185 // implement the ice-renomination option. | 188 // implement the ice-renomination option. |
| 186 bool P2PTransportChannel::ShouldSwitchSelectedConnection( | 189 bool P2PTransportChannel::ShouldSwitchSelectedConnection( |
| 187 Connection* new_connection) const { | 190 Connection* new_connection, |
| 191 bool* missed_receiving_unchanged_threshold) const { |
| 188 if (!new_connection || selected_connection_ == new_connection) { | 192 if (!new_connection || selected_connection_ == new_connection) { |
| 189 return false; | 193 return false; |
| 190 } | 194 } |
| 191 | 195 |
| 192 if (selected_connection_ == nullptr) { | 196 if (selected_connection_ == nullptr) { |
| 193 return true; | 197 return true; |
| 194 } | 198 } |
| 195 | 199 |
| 196 int cmp = CompareConnections(selected_connection_, new_connection); | 200 rtc::Optional<int64_t> receiving_unchanged_threshold( |
| 201 rtc::TimeMillis() - config_.receiving_switching_delay.value_or(0)); |
| 202 int cmp = CompareConnections(selected_connection_, new_connection, |
| 203 receiving_unchanged_threshold, |
| 204 missed_receiving_unchanged_threshold); |
| 197 if (cmp != 0) { | 205 if (cmp != 0) { |
| 198 return cmp < 0; | 206 return cmp < 0; |
| 199 } | 207 } |
| 200 | 208 |
| 201 // If everything else is the same, switch only if rtt has improved by | 209 // If everything else is the same, switch only if rtt has improved by |
| 202 // a margin. | 210 // a margin. |
| 203 return new_connection->rtt() <= selected_connection_->rtt() - kMinImprovement; | 211 return new_connection->rtt() <= selected_connection_->rtt() - kMinImprovement; |
| 204 } | 212 } |
| 205 | 213 |
| 214 bool P2PTransportChannel::MaybeSwitchSelectedConnection( |
| 215 Connection* new_connection, |
| 216 const std::string& reason) { |
| 217 bool missed_receiving_unchanged_threshold = false; |
| 218 if (ShouldSwitchSelectedConnection(new_connection, |
| 219 &missed_receiving_unchanged_threshold)) { |
| 220 LOG(LS_INFO) << "Switching selected connection due to " << reason; |
| 221 SwitchSelectedConnection(new_connection); |
| 222 return true; |
| 223 } |
| 224 if (missed_receiving_unchanged_threshold && |
| 225 config_.receiving_switching_delay) { |
| 226 // If we do not switch to the connection because it missed the receiving |
| 227 // threshold, the new connection is in a better receiving state than the |
| 228 // currently selected connection. So we need to re-check whether it needs |
| 229 // to be switched at a later time. |
| 230 thread()->PostDelayed(RTC_FROM_HERE, *config_.receiving_switching_delay, |
| 231 this, MSG_SORT_AND_UPDATE_STATE); |
| 232 } |
| 233 return false; |
| 234 } |
| 235 |
| 206 void P2PTransportChannel::SetIceRole(IceRole ice_role) { | 236 void P2PTransportChannel::SetIceRole(IceRole ice_role) { |
| 207 ASSERT(worker_thread_ == rtc::Thread::Current()); | 237 ASSERT(worker_thread_ == rtc::Thread::Current()); |
| 208 if (ice_role_ != ice_role) { | 238 if (ice_role_ != ice_role) { |
| 209 ice_role_ = ice_role; | 239 ice_role_ = ice_role; |
| 210 for (PortInterface* port : ports_) { | 240 for (PortInterface* port : ports_) { |
| 211 port->SetIceRole(ice_role); | 241 port->SetIceRole(ice_role); |
| 212 } | 242 } |
| 213 // Update role on removed ports as well, because they may still have | 243 // Update role on removed ports as well, because they may still have |
| 214 // connections alive that should be using the correct role. | 244 // connections alive that should be using the correct role. |
| 215 for (PortInterface* port : removed_ports_) { | 245 for (PortInterface* port : removed_ports_) { |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 362 << config_.presume_writable_when_fully_relayed; | 392 << config_.presume_writable_when_fully_relayed; |
| 363 } | 393 } |
| 364 } | 394 } |
| 365 | 395 |
| 366 if (config.regather_on_failed_networks_interval) { | 396 if (config.regather_on_failed_networks_interval) { |
| 367 config_.regather_on_failed_networks_interval = | 397 config_.regather_on_failed_networks_interval = |
| 368 config.regather_on_failed_networks_interval; | 398 config.regather_on_failed_networks_interval; |
| 369 LOG(LS_INFO) << "Set regather_on_failed_networks_interval to " | 399 LOG(LS_INFO) << "Set regather_on_failed_networks_interval to " |
| 370 << *config_.regather_on_failed_networks_interval; | 400 << *config_.regather_on_failed_networks_interval; |
| 371 } | 401 } |
| 402 if (config.receiving_switching_delay) { |
| 403 config_.receiving_switching_delay = config.receiving_switching_delay; |
| 404 LOG(LS_INFO) << "Set receiving_switching_delay to" |
| 405 << *config_.receiving_switching_delay; |
| 406 } |
| 372 } | 407 } |
| 373 | 408 |
| 374 const IceConfig& P2PTransportChannel::config() const { | 409 const IceConfig& P2PTransportChannel::config() const { |
| 375 return config_; | 410 return config_; |
| 376 } | 411 } |
| 377 | 412 |
| 378 void P2PTransportChannel::MaybeStartGathering() { | 413 void P2PTransportChannel::MaybeStartGathering() { |
| 379 if (ice_ufrag_.empty() || ice_pwd_.empty()) { | 414 if (ice_ufrag_.empty() || ice_pwd_.empty()) { |
| 380 return; | 415 return; |
| 381 } | 416 } |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 620 } | 655 } |
| 621 | 656 |
| 622 void P2PTransportChannel::OnNominated(Connection* conn) { | 657 void P2PTransportChannel::OnNominated(Connection* conn) { |
| 623 ASSERT(worker_thread_ == rtc::Thread::Current()); | 658 ASSERT(worker_thread_ == rtc::Thread::Current()); |
| 624 ASSERT(ice_role_ == ICEROLE_CONTROLLED); | 659 ASSERT(ice_role_ == ICEROLE_CONTROLLED); |
| 625 | 660 |
| 626 if (selected_connection_ == conn) { | 661 if (selected_connection_ == conn) { |
| 627 return; | 662 return; |
| 628 } | 663 } |
| 629 | 664 |
| 630 if (!ShouldSwitchSelectedConnection(conn)) { | 665 if (MaybeSwitchSelectedConnection(conn, |
| 666 "nomination on the controlled side")) { |
| 667 // Now that we have selected a connection, it is time to prune other |
| 668 // connections and update the read/write state of the channel. |
| 669 RequestSortAndStateUpdate(); |
| 670 } else { |
| 631 LOG(LS_INFO) | 671 LOG(LS_INFO) |
| 632 << "Not switching the selected connection on controlled side yet: " | 672 << "Not switching the selected connection on controlled side yet: " |
| 633 << conn->ToString(); | 673 << conn->ToString(); |
| 634 return; | |
| 635 } | 674 } |
| 636 | |
| 637 LOG(LS_INFO) | |
| 638 << "Switching selected connection on controlled side due to nomination: " | |
| 639 << conn->ToString(); | |
| 640 SwitchSelectedConnection(conn); | |
| 641 // Now that we have selected a connection, it is time to prune other | |
| 642 // connections and update the read/write state of the channel. | |
| 643 RequestSortAndStateUpdate(); | |
| 644 } | 675 } |
| 645 | 676 |
| 646 void P2PTransportChannel::AddRemoteCandidate(const Candidate& candidate) { | 677 void P2PTransportChannel::AddRemoteCandidate(const Candidate& candidate) { |
| 647 ASSERT(worker_thread_ == rtc::Thread::Current()); | 678 ASSERT(worker_thread_ == rtc::Thread::Current()); |
| 648 | 679 |
| 649 uint32_t generation = GetRemoteCandidateGeneration(candidate); | 680 uint32_t generation = GetRemoteCandidateGeneration(candidate); |
| 650 // If a remote candidate with a previous generation arrives, drop it. | 681 // If a remote candidate with a previous generation arrives, drop it. |
| 651 if (generation < remote_ice_generation()) { | 682 if (generation < remote_ice_generation()) { |
| 652 LOG(LS_WARNING) << "Dropping a remote candidate because its ufrag " | 683 LOG(LS_WARNING) << "Dropping a remote candidate because its ufrag " |
| 653 << candidate.username() | 684 << candidate.username() |
| (...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 980 thread()->Post(RTC_FROM_HERE, this, MSG_CHECK_AND_PING); | 1011 thread()->Post(RTC_FROM_HERE, this, MSG_CHECK_AND_PING); |
| 981 thread()->PostDelayed(RTC_FROM_HERE, | 1012 thread()->PostDelayed(RTC_FROM_HERE, |
| 982 *config_.regather_on_failed_networks_interval, this, | 1013 *config_.regather_on_failed_networks_interval, this, |
| 983 MSG_REGATHER_ON_FAILED_NETWORKS); | 1014 MSG_REGATHER_ON_FAILED_NETWORKS); |
| 984 started_pinging_ = true; | 1015 started_pinging_ = true; |
| 985 } | 1016 } |
| 986 } | 1017 } |
| 987 | 1018 |
| 988 // Compare two connections based on their writing, receiving, and connected | 1019 // Compare two connections based on their writing, receiving, and connected |
| 989 // states. | 1020 // states. |
| 990 int P2PTransportChannel::CompareConnectionStates(const Connection* a, | 1021 int P2PTransportChannel::CompareConnectionStates( |
| 991 const Connection* b) const { | 1022 const Connection* a, |
| 1023 const Connection* b, |
| 1024 rtc::Optional<int64_t> receiving_unchanged_threshold, |
| 1025 bool* missed_receiving_unchanged_threshold) const { |
| 992 // First, prefer a connection that's writable or presumed writable over | 1026 // First, prefer a connection that's writable or presumed writable over |
| 993 // one that's not writable. | 1027 // one that's not writable. |
| 994 bool a_writable = a->writable() || PresumedWritable(a); | 1028 bool a_writable = a->writable() || PresumedWritable(a); |
| 995 bool b_writable = b->writable() || PresumedWritable(b); | 1029 bool b_writable = b->writable() || PresumedWritable(b); |
| 996 if (a_writable && !b_writable) { | 1030 if (a_writable && !b_writable) { |
| 997 return a_is_better; | 1031 return a_is_better; |
| 998 } | 1032 } |
| 999 if (!a_writable && b_writable) { | 1033 if (!a_writable && b_writable) { |
| 1000 return b_is_better; | 1034 return b_is_better; |
| 1001 } | 1035 } |
| 1002 | 1036 |
| 1003 // Sort based on write-state. Better states have lower values. | 1037 // Sort based on write-state. Better states have lower values. |
| 1004 if (a->write_state() < b->write_state()) { | 1038 if (a->write_state() < b->write_state()) { |
| 1005 return a_is_better; | 1039 return a_is_better; |
| 1006 } | 1040 } |
| 1007 if (b->write_state() < a->write_state()) { | 1041 if (b->write_state() < a->write_state()) { |
| 1008 return b_is_better; | 1042 return b_is_better; |
| 1009 } | 1043 } |
| 1010 | 1044 |
| 1011 // We prefer a receiving connection to a non-receiving, higher-priority | 1045 // We prefer a receiving connection to a non-receiving, higher-priority |
| 1012 // connection when sorting connections and choosing which connection to | 1046 // connection when sorting connections and choosing which connection to |
| 1013 // switch to. | 1047 // switch to. |
| 1014 if (a->receiving() && !b->receiving()) { | 1048 if (a->receiving() && !b->receiving()) { |
| 1015 return a_is_better; | 1049 return a_is_better; |
| 1016 } | 1050 } |
| 1017 if (!a->receiving() && b->receiving()) { | 1051 if (!a->receiving() && b->receiving()) { |
| 1018 return b_is_better; | 1052 if (!receiving_unchanged_threshold || |
| 1053 (a->receiving_unchanged_since() <= *receiving_unchanged_threshold && |
| 1054 b->receiving_unchanged_since() <= *receiving_unchanged_threshold)) { |
| 1055 return b_is_better; |
| 1056 } |
| 1057 *missed_receiving_unchanged_threshold = true; |
| 1019 } | 1058 } |
| 1020 | 1059 |
| 1021 // WARNING: Some complexity here about TCP reconnecting. | 1060 // WARNING: Some complexity here about TCP reconnecting. |
| 1022 // When a TCP connection fails because of a TCP socket disconnecting, the | 1061 // When a TCP connection fails because of a TCP socket disconnecting, the |
| 1023 // active side of the connection will attempt to reconnect for 5 seconds while | 1062 // active side of the connection will attempt to reconnect for 5 seconds while |
| 1024 // pretending to be writable (the connection is not set to the unwritable | 1063 // pretending to be writable (the connection is not set to the unwritable |
| 1025 // state). On the passive side, the connection also remains writable even | 1064 // state). On the passive side, the connection also remains writable even |
| 1026 // though it is disconnected, and a new connection is created when the active | 1065 // though it is disconnected, and a new connection is created when the active |
| 1027 // side connects. At that point, there are two TCP connections on the passive | 1066 // side connects. At that point, there are two TCP connections on the passive |
| 1028 // side: 1. the old, disconnected one that is pretending to be writable, and | 1067 // side: 1. the old, disconnected one that is pretending to be writable, and |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1075 if (a->priority() < b->priority()) { | 1114 if (a->priority() < b->priority()) { |
| 1076 return b_is_better; | 1115 return b_is_better; |
| 1077 } | 1116 } |
| 1078 | 1117 |
| 1079 // If we're still tied at this point, prefer a younger generation. | 1118 // If we're still tied at this point, prefer a younger generation. |
| 1080 // (Younger generation means a larger generation number). | 1119 // (Younger generation means a larger generation number). |
| 1081 return (a->remote_candidate().generation() + a->port()->generation()) - | 1120 return (a->remote_candidate().generation() + a->port()->generation()) - |
| 1082 (b->remote_candidate().generation() + b->port()->generation()); | 1121 (b->remote_candidate().generation() + b->port()->generation()); |
| 1083 } | 1122 } |
| 1084 | 1123 |
| 1085 int P2PTransportChannel::CompareConnections(const Connection* a, | 1124 int P2PTransportChannel::CompareConnections( |
| 1086 const Connection* b) const { | 1125 const Connection* a, |
| 1126 const Connection* b, |
| 1127 rtc::Optional<int64_t> receiving_unchanged_threshold, |
| 1128 bool* missed_receiving_unchanged_threshold) const { |
| 1087 RTC_CHECK(a != nullptr); | 1129 RTC_CHECK(a != nullptr); |
| 1088 RTC_CHECK(b != nullptr); | 1130 RTC_CHECK(b != nullptr); |
| 1089 | 1131 |
| 1090 // We prefer to switch to a writable and receiving connection over a | 1132 // We prefer to switch to a writable and receiving connection over a |
| 1091 // non-writable or non-receiving connection, even if the latter has | 1133 // non-writable or non-receiving connection, even if the latter has |
| 1092 // been nominated by the controlling side. | 1134 // been nominated by the controlling side. |
| 1093 int state_cmp = CompareConnectionStates(a, b); | 1135 int state_cmp = CompareConnectionStates(a, b, receiving_unchanged_threshold, |
| 1136 missed_receiving_unchanged_threshold); |
| 1094 if (state_cmp != 0) { | 1137 if (state_cmp != 0) { |
| 1095 return state_cmp; | 1138 return state_cmp; |
| 1096 } | 1139 } |
| 1097 | 1140 |
| 1098 if (ice_role_ == ICEROLE_CONTROLLED) { | 1141 if (ice_role_ == ICEROLE_CONTROLLED) { |
| 1099 // Compare the connections based on the nomination states and the last data | 1142 // Compare the connections based on the nomination states and the last data |
| 1100 // received time if this is on the controlled side. | 1143 // received time if this is on the controlled side. |
| 1101 if (a->nominated() && !b->nominated()) { | 1144 if (a->nominated() && !b->nominated()) { |
| 1102 return a_is_better; | 1145 return a_is_better; |
| 1103 } | 1146 } |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1136 | 1179 |
| 1137 // Any changes after this point will require a re-sort. | 1180 // Any changes after this point will require a re-sort. |
| 1138 sort_dirty_ = false; | 1181 sort_dirty_ = false; |
| 1139 | 1182 |
| 1140 // Find the best alternative connection by sorting. It is important to note | 1183 // Find the best alternative connection by sorting. It is important to note |
| 1141 // that amongst equal preference, writable connections, this will choose the | 1184 // that amongst equal preference, writable connections, this will choose the |
| 1142 // one whose estimated latency is lowest. So it is the only one that we | 1185 // one whose estimated latency is lowest. So it is the only one that we |
| 1143 // need to consider switching to. | 1186 // need to consider switching to. |
| 1144 std::stable_sort(connections_.begin(), connections_.end(), | 1187 std::stable_sort(connections_.begin(), connections_.end(), |
| 1145 [this](const Connection* a, const Connection* b) { | 1188 [this](const Connection* a, const Connection* b) { |
| 1146 int cmp = CompareConnections(a, b); | 1189 int cmp = CompareConnections( |
| 1190 a, b, rtc::Optional<int64_t>(), nullptr); |
| 1147 if (cmp != 0) { | 1191 if (cmp != 0) { |
| 1148 return cmp > 0; | 1192 return cmp > 0; |
| 1149 } | 1193 } |
| 1150 | |
| 1151 // Otherwise, sort based on latency estimate. | 1194 // Otherwise, sort based on latency estimate. |
| 1152 return a->rtt() < b->rtt(); | 1195 return a->rtt() < b->rtt(); |
| 1153 }); | 1196 }); |
| 1154 | 1197 |
| 1155 LOG(LS_VERBOSE) << "Sorting " << connections_.size() | 1198 LOG(LS_VERBOSE) << "Sorting " << connections_.size() |
| 1156 << " available connections:"; | 1199 << " available connections:"; |
| 1157 for (size_t i = 0; i < connections_.size(); ++i) { | 1200 for (size_t i = 0; i < connections_.size(); ++i) { |
| 1158 LOG(LS_VERBOSE) << connections_[i]->ToString(); | 1201 LOG(LS_VERBOSE) << connections_[i]->ToString(); |
| 1159 } | 1202 } |
| 1160 | 1203 |
| 1161 Connection* top_connection = | 1204 Connection* top_connection = |
| 1162 (connections_.size() > 0) ? connections_[0] : nullptr; | 1205 (connections_.size() > 0) ? connections_[0] : nullptr; |
| 1163 | 1206 |
| 1164 // If necessary, switch to the new choice. Note that |top_connection| doesn't | 1207 // If necessary, switch to the new choice. Note that |top_connection| doesn't |
| 1165 // have to be writable to become the selected connection although it will | 1208 // have to be writable to become the selected connection although it will |
| 1166 // have higher priority if it is writable. | 1209 // have higher priority if it is writable. |
| 1167 if (ShouldSwitchSelectedConnection(top_connection)) { | 1210 MaybeSwitchSelectedConnection(top_connection, "sorting"); |
| 1168 LOG(LS_INFO) << "Switching selected connection after sorting: " | |
| 1169 << top_connection->ToString(); | |
| 1170 SwitchSelectedConnection(top_connection); | |
| 1171 } | |
| 1172 | 1211 |
| 1173 // The controlled side can prune only if the selected connection has been | 1212 // The controlled side can prune only if the selected connection has been |
| 1174 // nominated because otherwise it may prune the connection that will be | 1213 // nominated because otherwise it may prune the connection that will be |
| 1175 // selected by the controlling side. | 1214 // selected by the controlling side. |
| 1176 // TODO(honghaiz): This is not enough to prevent a connection from being | 1215 // TODO(honghaiz): This is not enough to prevent a connection from being |
| 1177 // pruned too early because with aggressive nomination, the controlling side | 1216 // pruned too early because with aggressive nomination, the controlling side |
| 1178 // will nominate every connection until it becomes writable. | 1217 // will nominate every connection until it becomes writable. |
| 1179 if (ice_role_ == ICEROLE_CONTROLLING || | 1218 if (ice_role_ == ICEROLE_CONTROLLING || |
| 1180 (selected_connection_ && selected_connection_->nominated())) { | 1219 (selected_connection_ && selected_connection_->nominated())) { |
| 1181 PruneConnections(); | 1220 PruneConnections(); |
| (...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1615 LOG_J(LS_INFO, this) << "Removed connection (" | 1654 LOG_J(LS_INFO, this) << "Removed connection (" |
| 1616 << static_cast<int>(connections_.size()) << " remaining)"; | 1655 << static_cast<int>(connections_.size()) << " remaining)"; |
| 1617 | 1656 |
| 1618 // If this is currently the selected connection, then we need to pick a new | 1657 // If this is currently the selected connection, then we need to pick a new |
| 1619 // one. The call to SortConnectionsAndUpdateState will pick a new one. It | 1658 // one. The call to SortConnectionsAndUpdateState will pick a new one. It |
| 1620 // looks at the current selected connection in order to avoid switching | 1659 // looks at the current selected connection in order to avoid switching |
| 1621 // between fairly similar ones. Since this connection is no longer an option, | 1660 // between fairly similar ones. Since this connection is no longer an option, |
| 1622 // we can just set selected to nullptr and re-choose a best assuming that | 1661 // we can just set selected to nullptr and re-choose a best assuming that |
| 1623 // there was no selected connection. | 1662 // there was no selected connection. |
| 1624 if (selected_connection_ == connection) { | 1663 if (selected_connection_ == connection) { |
| 1625 LOG(LS_INFO) << "selected connection destroyed. Will choose a new one."; | 1664 LOG(LS_INFO) << "Selected connection destroyed. Will choose a new one."; |
| 1626 SwitchSelectedConnection(nullptr); | 1665 SwitchSelectedConnection(nullptr); |
| 1627 RequestSortAndStateUpdate(); | 1666 RequestSortAndStateUpdate(); |
| 1628 } else { | 1667 } else { |
| 1629 // If a non-selected connection was destroyed, we don't need to re-sort but | 1668 // If a non-selected connection was destroyed, we don't need to re-sort but |
| 1630 // we do need to update state, because we could be switching to "failed" or | 1669 // we do need to update state, because we could be switching to "failed" or |
| 1631 // "completed". | 1670 // "completed". |
| 1632 UpdateState(); | 1671 UpdateState(); |
| 1633 } | 1672 } |
| 1634 } | 1673 } |
| 1635 | 1674 |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1719 | 1758 |
| 1720 // Do not deliver, if packet doesn't belong to the correct transport channel. | 1759 // Do not deliver, if packet doesn't belong to the correct transport channel. |
| 1721 if (!FindConnection(connection)) | 1760 if (!FindConnection(connection)) |
| 1722 return; | 1761 return; |
| 1723 | 1762 |
| 1724 // Let the client know of an incoming packet | 1763 // Let the client know of an incoming packet |
| 1725 SignalReadPacket(this, data, len, packet_time, 0); | 1764 SignalReadPacket(this, data, len, packet_time, 0); |
| 1726 | 1765 |
| 1727 // May need to switch the sending connection based on the receiving media path | 1766 // May need to switch the sending connection based on the receiving media path |
| 1728 // if this is the controlled side. | 1767 // if this is the controlled side. |
| 1729 if (ice_role_ == ICEROLE_CONTROLLED && | 1768 if (ice_role_ == ICEROLE_CONTROLLED) { |
| 1730 ShouldSwitchSelectedConnection(connection)) { | 1769 MaybeSwitchSelectedConnection(connection, "data received"); |
| 1731 LOG(LS_INFO) << "Switching selected connection on controlled side due to " | |
| 1732 << "data received: " << connection->ToString(); | |
| 1733 SwitchSelectedConnection(connection); | |
| 1734 } | 1770 } |
| 1735 } | 1771 } |
| 1736 | 1772 |
| 1737 void P2PTransportChannel::OnSentPacket(const rtc::SentPacket& sent_packet) { | 1773 void P2PTransportChannel::OnSentPacket(const rtc::SentPacket& sent_packet) { |
| 1738 ASSERT(worker_thread_ == rtc::Thread::Current()); | 1774 ASSERT(worker_thread_ == rtc::Thread::Current()); |
| 1739 | 1775 |
| 1740 SignalSentPacket(this, sent_packet); | 1776 SignalSentPacket(this, sent_packet); |
| 1741 } | 1777 } |
| 1742 | 1778 |
| 1743 void P2PTransportChannel::OnReadyToSend(Connection* connection) { | 1779 void P2PTransportChannel::OnReadyToSend(Connection* connection) { |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1857 | 1893 |
| 1858 // During the initial state when nothing has been pinged yet, return the first | 1894 // During the initial state when nothing has been pinged yet, return the first |
| 1859 // one in the ordered |connections_|. | 1895 // one in the ordered |connections_|. |
| 1860 return *(std::find_if(connections_.begin(), connections_.end(), | 1896 return *(std::find_if(connections_.begin(), connections_.end(), |
| 1861 [conn1, conn2](Connection* conn) { | 1897 [conn1, conn2](Connection* conn) { |
| 1862 return conn == conn1 || conn == conn2; | 1898 return conn == conn1 || conn == conn2; |
| 1863 })); | 1899 })); |
| 1864 } | 1900 } |
| 1865 | 1901 |
| 1866 } // namespace cricket | 1902 } // namespace cricket |
| OLD | NEW |