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 |