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

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

Issue 2069493002: Do not switch best connection on the controlled side too frequently (Closed) Base URL: https://chromium.googlesource.com/external/webrtc@master
Patch Set: Address comments Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
95 95
96 // WARNING: Some complexity here about TCP reconnecting. 96 // WARNING: Some complexity here about TCP reconnecting.
97 // When a TCP connection fails because of a TCP socket disconnecting, the 97 // When a TCP connection fails because of a TCP socket disconnecting, the
98 // active side of the connection will attempt to reconnect for 5 seconds while 98 // active side of the connection will attempt to reconnect for 5 seconds while
99 // pretending to be writable (the connection is not set to the unwritable 99 // pretending to be writable (the connection is not set to the unwritable
100 // state). On the passive side, the connection also remains writable even 100 // state). On the passive side, the connection also remains writable even
101 // though it is disconnected, and a new connection is created when the active 101 // though it is disconnected, and a new connection is created when the active
102 // side connects. At that point, there are two TCP connections on the passive 102 // side connects. At that point, there are two TCP connections on the passive
103 // side: 1. the old, disconnected one that is pretending to be writable, and 103 // side: 1. the old, disconnected one that is pretending to be writable, and
104 // 2. the new, connected one that is maybe not yet writable. For purposes of 104 // 2. the new, connected one that is maybe not yet writable. For purposes of
105 // pruning, pinging, and selecting the best connection, we want to treat the 105 // pruning, pinging, and selecting the connection to use, we want to treat the
106 // new connection as "better" than the old one. We could add a method called 106 // new connection as "better" than the old one. We could add a method called
107 // something like Connection::ImReallyBadEvenThoughImWritable, but that is 107 // something like Connection::ImReallyBadEvenThoughImWritable, but that is
108 // equivalent to the existing Connection::connected(), which we already have. 108 // equivalent to the existing Connection::connected(), which we already have.
109 // So, in code throughout this file, we'll check whether the connection is 109 // So, in code throughout this file, we'll check whether the connection is
110 // connected() or not, and if it is not, treat it as "worse" than a connected 110 // connected() or not, and if it is not, treat it as "worse" than a connected
111 // one, even though it's writable. In the code below, we're doing so to make 111 // one, even though it's writable. In the code below, we're doing so to make
112 // sure we treat a new writable connection as better than an old disconnected 112 // sure we treat a new writable connection as better than an old disconnected
113 // connection. 113 // connection.
114 114
115 // In the case where we reconnect TCP connections, the original best 115 // In the case where we reconnect TCP connections, the original best
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
203 } // unnamed namespace 203 } // unnamed namespace
204 204
205 namespace cricket { 205 namespace cricket {
206 206
207 // When the socket is unwritable, we will use 10 Kbps (ignoring IP+UDP headers) 207 // When the socket is unwritable, we will use 10 Kbps (ignoring IP+UDP headers)
208 // for pinging. When the socket is writable, we will use only 1 Kbps because 208 // for pinging. When the socket is writable, we will use only 1 Kbps because
209 // we don't want to degrade the quality on a modem. These numbers should work 209 // we don't want to degrade the quality on a modem. These numbers should work
210 // well on a 28.8K modem, which is the slowest connection on which the voice 210 // well on a 28.8K modem, which is the slowest connection on which the voice
211 // quality is reasonable at all. 211 // quality is reasonable at all.
212 static const int PING_PACKET_SIZE = 60 * 8; 212 static const int PING_PACKET_SIZE = 60 * 8;
213 // STRONG_PING_INTERVAL (480ms) is applied when the best connection is both 213 // STRONG_PING_INTERVAL (480ms) is applied when the selected connection is both
214 // writable and receiving. 214 // writable and receiving.
215 static const int STRONG_PING_INTERVAL = 1000 * PING_PACKET_SIZE / 1000; 215 static const int STRONG_PING_INTERVAL = 1000 * PING_PACKET_SIZE / 1000;
216 // WEAK_PING_INTERVAL (48ms) is applied when the best connection is either not 216 // WEAK_PING_INTERVAL (48ms) is applied when the selected connection is either
217 // writable or not receiving. 217 // not writable or not receiving.
218 const int WEAK_PING_INTERVAL = 1000 * PING_PACKET_SIZE / 10000; 218 const int WEAK_PING_INTERVAL = 1000 * PING_PACKET_SIZE / 10000;
219 219
220 // If the current best connection is both writable and receiving, then we will 220 // If the current selected connection is both writable and receiving, then we
221 // also try hard to make sure it is pinged at this rate (a little less than 221 // will also try hard to make sure it is pinged at this rate (a little less
222 // 2 * STRONG_PING_INTERVAL). 222 // than 2 * STRONG_PING_INTERVAL).
223 static const int MAX_CURRENT_STRONG_INTERVAL = 900; // ms 223 static const int MAX_CURRENT_STRONG_INTERVAL = 900; // ms
224 224
225 static const int MIN_CHECK_RECEIVING_INTERVAL = 50; // ms 225 static const int MIN_CHECK_RECEIVING_INTERVAL = 50; // ms
226 226
227 P2PTransportChannel::P2PTransportChannel(const std::string& transport_name, 227 P2PTransportChannel::P2PTransportChannel(const std::string& transport_name,
228 int component, 228 int component,
229 P2PTransport* transport, 229 P2PTransport* transport,
230 PortAllocator* allocator) 230 PortAllocator* allocator)
231 : P2PTransportChannel(transport_name, component, allocator) {} 231 : P2PTransportChannel(transport_name, component, allocator) {}
232 232
233 P2PTransportChannel::P2PTransportChannel(const std::string& transport_name, 233 P2PTransportChannel::P2PTransportChannel(const std::string& transport_name,
234 int component, 234 int component,
235 PortAllocator* allocator) 235 PortAllocator* allocator)
236 : TransportChannelImpl(transport_name, component), 236 : TransportChannelImpl(transport_name, component),
237 allocator_(allocator), 237 allocator_(allocator),
238 worker_thread_(rtc::Thread::Current()), 238 worker_thread_(rtc::Thread::Current()),
239 incoming_only_(false), 239 incoming_only_(false),
240 error_(0), 240 error_(0),
241 best_connection_(NULL),
242 pending_best_connection_(NULL),
243 sort_dirty_(false), 241 sort_dirty_(false),
244 remote_ice_mode_(ICEMODE_FULL), 242 remote_ice_mode_(ICEMODE_FULL),
245 ice_role_(ICEROLE_UNKNOWN), 243 ice_role_(ICEROLE_UNKNOWN),
246 tiebreaker_(0), 244 tiebreaker_(0),
247 gathering_state_(kIceGatheringNew), 245 gathering_state_(kIceGatheringNew),
248 check_receiving_interval_(MIN_CHECK_RECEIVING_INTERVAL * 5), 246 check_receiving_interval_(MIN_CHECK_RECEIVING_INTERVAL * 5),
249 config_(MIN_CHECK_RECEIVING_INTERVAL * 50 /* receiving_timeout */, 247 config_(MIN_CHECK_RECEIVING_INTERVAL * 50 /* receiving_timeout */,
250 0 /* backup_connection_ping_interval */, 248 0 /* backup_connection_ping_interval */,
251 false /* gather_continually */, 249 false /* gather_continually */,
252 false /* prioritize_most_likely_candidate_pairs */, 250 false /* prioritize_most_likely_candidate_pairs */,
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
294 connection->SignalReadyToSend.connect( 292 connection->SignalReadyToSend.connect(
295 this, &P2PTransportChannel::OnReadyToSend); 293 this, &P2PTransportChannel::OnReadyToSend);
296 connection->SignalStateChange.connect( 294 connection->SignalStateChange.connect(
297 this, &P2PTransportChannel::OnConnectionStateChange); 295 this, &P2PTransportChannel::OnConnectionStateChange);
298 connection->SignalDestroyed.connect( 296 connection->SignalDestroyed.connect(
299 this, &P2PTransportChannel::OnConnectionDestroyed); 297 this, &P2PTransportChannel::OnConnectionDestroyed);
300 connection->SignalNominated.connect(this, &P2PTransportChannel::OnNominated); 298 connection->SignalNominated.connect(this, &P2PTransportChannel::OnNominated);
301 had_connection_ = true; 299 had_connection_ = true;
302 } 300 }
303 301
302 // Determines whether we should switch the selected connection to
303 // |new_connection| based the writable state, the last nominated connection,
304 // and the last connection receiving data. This is to prevent that the
305 // controlled side may switch the selected connection too frequently when
306 // the controlling side is doing aggressive nominations. With this
307 // implementation, the controlled side will switch the selected connection
308 // if the new nominated connection is writable, and
309 // i) the selected connection is nullptr, or
310 // ii) the selected connection was not nominated, or
311 // iii) the new connection is nominated and is receiving data, or
312 // iv) the new connection has lower cost or high priority.
313 // TODO(honghaiz): Stop the aggressive nomination on the controlling side and
314 // implement the ice-renomination option.
315 bool P2PTransportChannel::ShouldSwitchOnNominatedOrDataReceived(
316 cricket::Connection* new_connection) const {
317 RTC_CHECK(new_connection != nullptr);
318 if (!new_connection->writable()) {
319 return false;
320 }
321 if (selected_connection_ == nullptr || !selected_connection_->nominated()) {
322 return true;
323 }
pthatcher1 2016/06/17 00:27:11 As mentioned, I think this is more clear and corre
honghaiz3 2016/06/17 19:18:18 Done.
324 if (new_connection == last_nominated_connection_ &&
pthatcher1 2016/06/17 00:27:11 I think we shouldn't change the behavior based on
honghaiz3 2016/06/17 19:18:18 Done.
325 new_connection == last_receiving_connection_) {
326 return true;
327 }
pthatcher1 2016/06/17 00:27:11 As mentioned, I think this is more robust: if (co
honghaiz3 2016/06/17 19:18:18 Done.
328 // Lastly, compare the network cost and priority.
329 return CompareConnectionCandidates(selected_connection_, new_connection) < 0;
330 }
331
304 void P2PTransportChannel::SetIceRole(IceRole ice_role) { 332 void P2PTransportChannel::SetIceRole(IceRole ice_role) {
305 ASSERT(worker_thread_ == rtc::Thread::Current()); 333 ASSERT(worker_thread_ == rtc::Thread::Current());
306 if (ice_role_ != ice_role) { 334 if (ice_role_ != ice_role) {
307 ice_role_ = ice_role; 335 ice_role_ = ice_role;
308 for (std::vector<PortInterface *>::iterator it = ports_.begin(); 336 for (std::vector<PortInterface *>::iterator it = ports_.begin();
309 it != ports_.end(); ++it) { 337 it != ports_.end(); ++it) {
310 (*it)->SetIceRole(ice_role); 338 (*it)->SetIceRole(ice_role);
311 } 339 }
312 } 340 }
313 } 341 }
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after
722 return nullptr; 750 return nullptr;
723 } 751 }
724 *generation = params.rend() - it - 1; 752 *generation = params.rend() - it - 1;
725 return &(*it); 753 return &(*it);
726 } 754 }
727 755
728 void P2PTransportChannel::OnNominated(Connection* conn) { 756 void P2PTransportChannel::OnNominated(Connection* conn) {
729 ASSERT(worker_thread_ == rtc::Thread::Current()); 757 ASSERT(worker_thread_ == rtc::Thread::Current());
730 ASSERT(ice_role_ == ICEROLE_CONTROLLED); 758 ASSERT(ice_role_ == ICEROLE_CONTROLLED);
731 759
732 if (conn->write_state() == Connection::STATE_WRITABLE) { 760 if (selected_connection_ == conn) {
733 if (best_connection_ != conn) { 761 return;
734 pending_best_connection_ = NULL;
735 LOG(LS_INFO) << "Switching best connection on controlled side: "
736 << conn->ToString();
737 SwitchBestConnectionTo(conn);
738 // Now we have selected the best connection, time to prune other existing
739 // connections and update the read/write state of the channel.
740 RequestSort();
741 }
742 } else {
743 LOG(LS_INFO) << "Not switching the best connection on controlled side yet,"
744 << " because it's not writable: " << conn->ToString();
745 pending_best_connection_ = conn;
746 } 762 }
763
764 last_nominated_connection_ = conn;
765 if (!ShouldSwitchOnNominatedOrDataReceived(conn)) {
766 LOG(LS_INFO)
767 << "Not switching the selected connection on controlled side yet: "
768 << conn->ToString();
769 return;
770 }
771
772 LOG(LS_INFO)
773 << "Switching selected connection on controlled side due to nomination: "
774 << conn->ToString();
775 SwitchSelectedConnection(conn);
776 // Now we have selected the selected connection, time to prune other existing
777 // connections and update the read/write state of the channel.
778 RequestSort();
747 } 779 }
748 780
749 void P2PTransportChannel::AddRemoteCandidate(const Candidate& candidate) { 781 void P2PTransportChannel::AddRemoteCandidate(const Candidate& candidate) {
750 ASSERT(worker_thread_ == rtc::Thread::Current()); 782 ASSERT(worker_thread_ == rtc::Thread::Current());
751 783
752 uint32_t generation = GetRemoteCandidateGeneration(candidate); 784 uint32_t generation = GetRemoteCandidateGeneration(candidate);
753 // If a remote candidate with a previous generation arrives, drop it. 785 // If a remote candidate with a previous generation arrives, drop it.
754 if (generation < remote_ice_generation()) { 786 if (generation < remote_ice_generation()) {
755 LOG(LS_WARNING) << "Dropping a remote candidate because its ufrag " 787 LOG(LS_WARNING) << "Dropping a remote candidate because its ufrag "
756 << candidate.username() 788 << candidate.username()
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
983 ASSERT(worker_thread_ == rtc::Thread::Current()); 1015 ASSERT(worker_thread_ == rtc::Thread::Current());
984 1016
985 const auto& found = options_.find(opt); 1017 const auto& found = options_.find(opt);
986 if (found == options_.end()) { 1018 if (found == options_.end()) {
987 return false; 1019 return false;
988 } 1020 }
989 *value = found->second; 1021 *value = found->second;
990 return true; 1022 return true;
991 } 1023 }
992 1024
993 // Send data to the other side, using our best connection. 1025 // Send data to the other side, using our selected connection.
994 int P2PTransportChannel::SendPacket(const char *data, size_t len, 1026 int P2PTransportChannel::SendPacket(const char *data, size_t len,
995 const rtc::PacketOptions& options, 1027 const rtc::PacketOptions& options,
996 int flags) { 1028 int flags) {
997 ASSERT(worker_thread_ == rtc::Thread::Current()); 1029 ASSERT(worker_thread_ == rtc::Thread::Current());
998 if (flags != 0) { 1030 if (flags != 0) {
999 error_ = EINVAL; 1031 error_ = EINVAL;
1000 return -1; 1032 return -1;
1001 } 1033 }
1002 if (best_connection_ == NULL) { 1034 if (selected_connection_ == NULL) {
1003 error_ = EWOULDBLOCK; 1035 error_ = EWOULDBLOCK;
1004 return -1; 1036 return -1;
1005 } 1037 }
1006 1038
1007 last_sent_packet_id_ = options.packet_id; 1039 last_sent_packet_id_ = options.packet_id;
1008 int sent = best_connection_->Send(data, len, options); 1040 int sent = selected_connection_->Send(data, len, options);
1009 if (sent <= 0) { 1041 if (sent <= 0) {
1010 ASSERT(sent < 0); 1042 ASSERT(sent < 0);
1011 error_ = best_connection_->GetError(); 1043 error_ = selected_connection_->GetError();
1012 } 1044 }
1013 return sent; 1045 return sent;
1014 } 1046 }
1015 1047
1016 bool P2PTransportChannel::GetStats(ConnectionInfos *infos) { 1048 bool P2PTransportChannel::GetStats(ConnectionInfos *infos) {
1017 ASSERT(worker_thread_ == rtc::Thread::Current()); 1049 ASSERT(worker_thread_ == rtc::Thread::Current());
1018 // Gather connection infos. 1050 // Gather connection infos.
1019 infos->clear(); 1051 infos->clear();
1020 1052
1021 for (Connection* connection : connections_) { 1053 for (Connection* connection : connections_) {
1022 ConnectionInfo info = connection->stats(); 1054 ConnectionInfo info = connection->stats();
1023 info.best_connection = (best_connection_ == connection); 1055 info.best_connection = (selected_connection_ == connection);
1024 info.receiving = connection->receiving(); 1056 info.receiving = connection->receiving();
1025 info.writable = (connection->write_state() == Connection::STATE_WRITABLE); 1057 info.writable = (connection->write_state() == Connection::STATE_WRITABLE);
1026 info.timeout = 1058 info.timeout =
1027 (connection->write_state() == Connection::STATE_WRITE_TIMEOUT); 1059 (connection->write_state() == Connection::STATE_WRITE_TIMEOUT);
1028 info.new_connection = !connection->reported(); 1060 info.new_connection = !connection->reported();
1029 connection->set_reported(true); 1061 connection->set_reported(true);
1030 info.rtt = connection->rtt(); 1062 info.rtt = connection->rtt();
1031 info.local_candidate = connection->local_candidate(); 1063 info.local_candidate = connection->local_candidate();
1032 info.remote_candidate = connection->remote_candidate(); 1064 info.remote_candidate = connection->remote_candidate();
1033 info.key = connection; 1065 info.key = connection;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1083 std::stable_sort(connections_.begin(), connections_.end(), cmp); 1115 std::stable_sort(connections_.begin(), connections_.end(), cmp);
1084 LOG(LS_VERBOSE) << "Sorting " << connections_.size() 1116 LOG(LS_VERBOSE) << "Sorting " << connections_.size()
1085 << " available connections:"; 1117 << " available connections:";
1086 for (size_t i = 0; i < connections_.size(); ++i) { 1118 for (size_t i = 0; i < connections_.size(); ++i) {
1087 LOG(LS_VERBOSE) << connections_[i]->ToString(); 1119 LOG(LS_VERBOSE) << connections_[i]->ToString();
1088 } 1120 }
1089 1121
1090 Connection* top_connection = 1122 Connection* top_connection =
1091 (connections_.size() > 0) ? connections_[0] : nullptr; 1123 (connections_.size() > 0) ? connections_[0] : nullptr;
1092 1124
1093 // If necessary, switch to the new choice. 1125 // If necessary, switch to the new choice. Note that |top_connection| doesn't
1094 // Note that |top_connection| doesn't have to be writable to become the best 1126 // have to be writable to become the selected connection although it will
1095 // connection although it will have higher priority if it is writable. 1127 // have higher priority if it is writable.
1096 if (ShouldSwitch(best_connection_, top_connection, ice_role_)) { 1128 if (ShouldSwitch(selected_connection_, top_connection, ice_role_)) {
1097 LOG(LS_INFO) << "Switching best connection: " << top_connection->ToString(); 1129 LOG(LS_INFO) << "Switching selected connection after sorting: "
pthatcher1 2016/06/17 00:27:11 Can we please unify the two ShouldSwitch methods i
honghaiz3 2016/06/22 08:03:15 Done.
1098 SwitchBestConnectionTo(top_connection); 1130 << top_connection->ToString();
1131 SwitchSelectedConnection(top_connection);
1099 } 1132 }
1100 1133
1101 // Controlled side can prune only if the best connection has been nominated. 1134 // Controlled side can prune only if the selected connection has been
1102 // because otherwise it may delete the connection that will be selected by 1135 // nominated because otherwise it may prune the connection that will be
1103 // the controlling side. 1136 // selected by the controlling side.
1104 if (ice_role_ == ICEROLE_CONTROLLING || best_nominated_connection()) { 1137 // TODO(honghaiz): This is still problematic because with aggressive
1138 // nomination, the controlling side will nominate every connection until it
1139 // becomes writable.
1140 if (ice_role_ == ICEROLE_CONTROLLING || selected_nominated_connection()) {
1105 PruneConnections(); 1141 PruneConnections();
1106 } 1142 }
1107 1143
1108 // Check if all connections are timedout. 1144 // Check if all connections are timedout.
1109 bool all_connections_timedout = true; 1145 bool all_connections_timedout = true;
1110 for (size_t i = 0; i < connections_.size(); ++i) { 1146 for (size_t i = 0; i < connections_.size(); ++i) {
1111 if (connections_[i]->write_state() != Connection::STATE_WRITE_TIMEOUT) { 1147 if (connections_[i]->write_state() != Connection::STATE_WRITE_TIMEOUT) {
1112 all_connections_timedout = false; 1148 all_connections_timedout = false;
1113 break; 1149 break;
1114 } 1150 }
1115 } 1151 }
1116 1152
1117 // Now update the writable state of the channel with the information we have 1153 // Now update the writable state of the channel with the information we have
1118 // so far. 1154 // so far.
1119 if (all_connections_timedout) { 1155 if (all_connections_timedout) {
1120 HandleAllTimedOut(); 1156 HandleAllTimedOut();
1121 } 1157 }
1122 1158
1123 // Update the state of this channel. This method is called whenever the 1159 // Update the state of this channel. This method is called whenever the
1124 // state of any connection changes, so this is a good place to do this. 1160 // state of any connection changes, so this is a good place to do this.
1125 UpdateState(); 1161 UpdateState();
1126 } 1162 }
1127 1163
1128 Connection* P2PTransportChannel::best_nominated_connection() const { 1164 Connection* P2PTransportChannel::selected_nominated_connection() const {
1129 return (best_connection_ && best_connection_->nominated()) ? best_connection_ 1165 return (selected_connection_ && selected_connection_->nominated())
1130 : nullptr; 1166 ? selected_connection_
1167 : nullptr;
1131 } 1168 }
1132 1169
1133 void P2PTransportChannel::PruneConnections() { 1170 void P2PTransportChannel::PruneConnections() {
1134 // We can prune any connection for which there is a connected, writable 1171 // We can prune any connection for which there is a connected, writable
1135 // connection on the same network with better or equal priority. We leave 1172 // connection on the same network with better or equal priority. We leave
1136 // those with better priority just in case they become writable later (at 1173 // those with better priority just in case they become writable later (at
1137 // which point, we would prune out the current best connection). We leave 1174 // which point, we would prune out the current selected connection). We leave
1138 // connections on other networks because they may not be using the same 1175 // connections on other networks because they may not be using the same
1139 // resources and they may represent very distinct paths over which we can 1176 // resources and they may represent very distinct paths over which we can
1140 // switch. If the |premier| connection is not connected, we may be 1177 // switch. If the |premier| connection is not connected, we may be
1141 // reconnecting a TCP connection and temporarily do not prune connections in 1178 // reconnecting a TCP connection and temporarily do not prune connections in
1142 // this network. See the big comment in CompareConnections. 1179 // this network. See the big comment in CompareConnections.
1143 1180
1144 // Get a list of the networks that we are using. 1181 // Get a list of the networks that we are using.
1145 std::set<rtc::Network*> networks; 1182 std::set<rtc::Network*> networks;
1146 for (const Connection* conn : connections_) { 1183 for (const Connection* conn : connections_) {
1147 networks.insert(conn->port()->Network()); 1184 networks.insert(conn->port()->Network());
1148 } 1185 }
1149 for (rtc::Network* network : networks) { 1186 for (rtc::Network* network : networks) {
1150 Connection* premier = GetBestConnectionOnNetwork(network); 1187 Connection* premier = GetBestConnectionOnNetwork(network);
1151 // Do not prune connections if the current best connection is weak on this 1188 // Do not prune connections if the current selected connection is weak on
1152 // network. Otherwise, it may delete connections prematurely. 1189 // this network. Otherwise, it may delete connections prematurely.
1153 if (!premier || premier->weak()) { 1190 if (!premier || premier->weak()) {
1154 continue; 1191 continue;
1155 } 1192 }
1156 1193
1157 for (Connection* conn : connections_) { 1194 for (Connection* conn : connections_) {
1158 if ((conn != premier) && (conn->port()->Network() == network) && 1195 if ((conn != premier) && (conn->port()->Network() == network) &&
1159 (CompareConnectionCandidates(premier, conn) >= 0)) { 1196 (CompareConnectionCandidates(premier, conn) >= 0)) {
1160 conn->Prune(); 1197 conn->Prune();
1161 } 1198 }
1162 } 1199 }
1163 } 1200 }
1164 } 1201 }
1165 1202
1166 // Track the best connection, and let listeners know 1203 // Track the selected connection, and let listeners know.
1167 void P2PTransportChannel::SwitchBestConnectionTo(Connection* conn) { 1204 void P2PTransportChannel::SwitchSelectedConnection(Connection* conn) {
1168 // Note: if conn is NULL, the previous best_connection_ has been destroyed, 1205 // Note: if conn is NULL, the previous |selected_connection_| has been
1169 // so don't use it. 1206 // destroyed, so don't use it.
1170 Connection* old_best_connection = best_connection_; 1207 Connection* old_selected_connection = selected_connection_;
1171 best_connection_ = conn; 1208 selected_connection_ = conn;
1172 if (best_connection_) { 1209 if (selected_connection_) {
1173 if (old_best_connection) { 1210 if (old_selected_connection) {
1174 LOG_J(LS_INFO, this) << "Previous best connection: " 1211 LOG_J(LS_INFO, this) << "Previous selected connection: "
1175 << old_best_connection->ToString(); 1212 << old_selected_connection->ToString();
1176 } 1213 }
1177 LOG_J(LS_INFO, this) << "New best connection: " 1214 LOG_J(LS_INFO, this) << "New selected connection: "
1178 << best_connection_->ToString(); 1215 << selected_connection_->ToString();
1179 SignalRouteChange(this, best_connection_->remote_candidate()); 1216 SignalRouteChange(this, selected_connection_->remote_candidate());
1180 // This is a temporary, but safe fix to webrtc issue 5705. 1217 // This is a temporary, but safe fix to webrtc issue 5705.
1181 // TODO(honghaiz): Make all EWOULDBLOCK error routed through the transport 1218 // TODO(honghaiz): Make all EWOULDBLOCK error routed through the transport
1182 // channel so that it knows whether the media channel is allowed to 1219 // channel so that it knows whether the media channel is allowed to
1183 // send; then it will only signal ready-to-send if the media channel 1220 // send; then it will only signal ready-to-send if the media channel
1184 // has been disallowed to send. 1221 // has been disallowed to send.
1185 if (best_connection_->writable()) { 1222 if (selected_connection_->writable()) {
1186 SignalReadyToSend(this); 1223 SignalReadyToSend(this);
1187 } 1224 }
1188 } else { 1225 } else {
1189 LOG_J(LS_INFO, this) << "No best connection"; 1226 LOG_J(LS_INFO, this) << "No selected connection";
1190 } 1227 }
1191 // TODO(honghaiz): rename best_connection_ with selected_connection_ or 1228 // TODO(honghaiz): rename selected_connection_ with selected_connection_ or
1192 // selected_candidate pair_. 1229 // selected_candidate pair_.
1193 SignalSelectedCandidatePairChanged(this, best_connection_, 1230 SignalSelectedCandidatePairChanged(this, selected_connection_,
1194 last_sent_packet_id_); 1231 last_sent_packet_id_);
1195 } 1232 }
1196 1233
1197 // Warning: UpdateState should eventually be called whenever a connection 1234 // Warning: UpdateState should eventually be called whenever a connection
1198 // is added, deleted, or the write state of any connection changes so that the 1235 // is added, deleted, or the write state of any connection changes so that the
1199 // transport controller will get the up-to-date channel state. However it 1236 // transport controller will get the up-to-date channel state. However it
1200 // should not be called too often; in the case that multiple connection states 1237 // should not be called too often; in the case that multiple connection states
1201 // change, it should be called after all the connection states have changed. For 1238 // change, it should be called after all the connection states have changed. For
1202 // example, we call this at the end of SortConnections. 1239 // example, we call this at the end of SortConnections.
1203 void P2PTransportChannel::UpdateState() { 1240 void P2PTransportChannel::UpdateState() {
(...skipping 26 matching lines...) Expand all
1230 RTC_DCHECK(state == STATE_CONNECTING || state == STATE_COMPLETED); 1267 RTC_DCHECK(state == STATE_CONNECTING || state == STATE_COMPLETED);
1231 break; 1268 break;
1232 default: 1269 default:
1233 RTC_DCHECK(false); 1270 RTC_DCHECK(false);
1234 break; 1271 break;
1235 } 1272 }
1236 state_ = state; 1273 state_ = state;
1237 SignalStateChanged(this); 1274 SignalStateChanged(this);
1238 } 1275 }
1239 1276
1240 bool writable = best_connection_ && best_connection_->writable(); 1277 bool writable = selected_connection_ && selected_connection_->writable();
1241 set_writable(writable); 1278 set_writable(writable);
1242 1279
1243 bool receiving = false; 1280 bool receiving = false;
1244 for (const Connection* connection : connections_) { 1281 for (const Connection* connection : connections_) {
1245 if (connection->receiving()) { 1282 if (connection->receiving()) {
1246 receiving = true; 1283 receiving = true;
1247 break; 1284 break;
1248 } 1285 }
1249 } 1286 }
1250 set_receiving(receiving); 1287 set_receiving(receiving);
(...skipping 19 matching lines...) Expand all
1270 } 1307 }
1271 1308
1272 // If all connections timed out, delete them all. 1309 // If all connections timed out, delete them all.
1273 void P2PTransportChannel::HandleAllTimedOut() { 1310 void P2PTransportChannel::HandleAllTimedOut() {
1274 for (Connection* connection : connections_) { 1311 for (Connection* connection : connections_) {
1275 connection->Destroy(); 1312 connection->Destroy();
1276 } 1313 }
1277 } 1314 }
1278 1315
1279 bool P2PTransportChannel::weak() const { 1316 bool P2PTransportChannel::weak() const {
1280 return !best_connection_ || best_connection_->weak(); 1317 return !selected_connection_ || selected_connection_->weak();
1281 } 1318 }
1282 1319
1283 // If we have a best connection, return it, otherwise return top one in the 1320 // If we have a selected connection, return it, otherwise return top one in the
1284 // list (later we will mark it best). 1321 // list (later we will mark it best).
1285 Connection* P2PTransportChannel::GetBestConnectionOnNetwork( 1322 Connection* P2PTransportChannel::GetBestConnectionOnNetwork(
1286 rtc::Network* network) const { 1323 rtc::Network* network) const {
1287 // If the best connection is on this network, then it wins. 1324 // If the selected connection is on this network, then it wins.
1288 if (best_connection_ && (best_connection_->port()->Network() == network)) 1325 if (selected_connection_ &&
1289 return best_connection_; 1326 (selected_connection_->port()->Network() == network))
1327 return selected_connection_;
1290 1328
1291 // Otherwise, we return the top-most in sorted order. 1329 // Otherwise, we return the top-most in sorted order.
1292 for (size_t i = 0; i < connections_.size(); ++i) { 1330 for (size_t i = 0; i < connections_.size(); ++i) {
1293 if (connections_[i]->port()->Network() == network) 1331 if (connections_[i]->port()->Network() == network)
1294 return connections_[i]; 1332 return connections_[i];
1295 } 1333 }
1296 1334
1297 return NULL; 1335 return NULL;
1298 } 1336 }
1299 1337
(...skipping 16 matching lines...) Expand all
1316 void P2PTransportChannel::OnSort() { 1354 void P2PTransportChannel::OnSort() {
1317 // Resort the connections based on the new statistics. 1355 // Resort the connections based on the new statistics.
1318 SortConnections(); 1356 SortConnections();
1319 } 1357 }
1320 1358
1321 // Handle queued up check-and-ping request 1359 // Handle queued up check-and-ping request
1322 void P2PTransportChannel::OnCheckAndPing() { 1360 void P2PTransportChannel::OnCheckAndPing() {
1323 // Make sure the states of the connections are up-to-date (since this affects 1361 // Make sure the states of the connections are up-to-date (since this affects
1324 // which ones are pingable). 1362 // which ones are pingable).
1325 UpdateConnectionStates(); 1363 UpdateConnectionStates();
1326 // When the best connection is not receiving or not writable, or any active 1364 // When the selected connection is not receiving or not writable, or any
1327 // connection has not been pinged enough times, use the weak ping interval. 1365 // active connection has not been pinged enough times, use the weak ping
1366 // interval.
1328 bool need_more_pings_at_weak_interval = std::any_of( 1367 bool need_more_pings_at_weak_interval = std::any_of(
1329 connections_.begin(), connections_.end(), [](Connection* conn) { 1368 connections_.begin(), connections_.end(), [](Connection* conn) {
1330 return conn->active() && 1369 return conn->active() &&
1331 conn->num_pings_sent() < MIN_PINGS_AT_WEAK_PING_INTERVAL; 1370 conn->num_pings_sent() < MIN_PINGS_AT_WEAK_PING_INTERVAL;
1332 }); 1371 });
1333 int ping_interval = (weak() || need_more_pings_at_weak_interval) 1372 int ping_interval = (weak() || need_more_pings_at_weak_interval)
1334 ? weak_ping_interval_ 1373 ? weak_ping_interval_
1335 : STRONG_PING_INTERVAL; 1374 : STRONG_PING_INTERVAL;
1336 if (rtc::TimeMillis() >= last_ping_sent_ms_ + ping_interval) { 1375 if (rtc::TimeMillis() >= last_ping_sent_ms_ + ping_interval) {
1337 Connection* conn = FindNextPingableConnection(); 1376 Connection* conn = FindNextPingableConnection();
1338 if (conn) { 1377 if (conn) {
1339 PingConnection(conn); 1378 PingConnection(conn);
1340 MarkConnectionPinged(conn); 1379 MarkConnectionPinged(conn);
1341 } 1380 }
1342 } 1381 }
1343 int delay = std::min(ping_interval, check_receiving_interval_); 1382 int delay = std::min(ping_interval, check_receiving_interval_);
1344 thread()->PostDelayed(RTC_FROM_HERE, delay, this, MSG_CHECK_AND_PING); 1383 thread()->PostDelayed(RTC_FROM_HERE, delay, this, MSG_CHECK_AND_PING);
1345 } 1384 }
1346 1385
1347 // A connection is considered a backup connection if the channel state 1386 // A connection is considered a backup connection if the channel state
1348 // is completed, the connection is not the best connection and it is active. 1387 // is completed, the connection is not the selected connection and it is active.
1349 bool P2PTransportChannel::IsBackupConnection(Connection* conn) const { 1388 bool P2PTransportChannel::IsBackupConnection(Connection* conn) const {
1350 return state_ == STATE_COMPLETED && conn != best_connection_ && 1389 return state_ == STATE_COMPLETED && conn != selected_connection_ &&
1351 conn->active(); 1390 conn->active();
1352 } 1391 }
1353 1392
1354 // Is the connection in a state for us to even consider pinging the other side? 1393 // Is the connection in a state for us to even consider pinging the other side?
1355 // We consider a connection pingable even if it's not connected because that's 1394 // We consider a connection pingable even if it's not connected because that's
1356 // how a TCP connection is kicked into reconnecting on the active side. 1395 // how a TCP connection is kicked into reconnecting on the active side.
1357 bool P2PTransportChannel::IsPingable(Connection* conn, int64_t now) { 1396 bool P2PTransportChannel::IsPingable(Connection* conn, int64_t now) {
1358 const Candidate& remote = conn->remote_candidate(); 1397 const Candidate& remote = conn->remote_candidate();
1359 // We should never get this far with an empty remote ufrag. 1398 // We should never get this far with an empty remote ufrag.
1360 ASSERT(!remote.username().empty()); 1399 ASSERT(!remote.username().empty());
(...skipping 19 matching lines...) Expand all
1380 if (IsBackupConnection(conn)) { 1419 if (IsBackupConnection(conn)) {
1381 return (now >= conn->last_ping_response_received() + 1420 return (now >= conn->last_ping_response_received() +
1382 config_.backup_connection_ping_interval); 1421 config_.backup_connection_ping_interval);
1383 } 1422 }
1384 return conn->active(); 1423 return conn->active();
1385 } 1424 }
1386 1425
1387 // Returns the next pingable connection to ping. This will be the oldest 1426 // Returns the next pingable connection to ping. This will be the oldest
1388 // pingable connection unless we have a connected, writable connection that is 1427 // pingable connection unless we have a connected, writable connection that is
1389 // past the maximum acceptable ping interval. When reconnecting a TCP 1428 // past the maximum acceptable ping interval. When reconnecting a TCP
1390 // connection, the best connection is disconnected, although still WRITABLE 1429 // connection, the selected connection is disconnected, although still WRITABLE
1391 // while reconnecting. The newly created connection should be selected as the 1430 // while reconnecting. The newly created connection should be selected as the
1392 // ping target to become writable instead. See the big comment in 1431 // ping target to become writable instead. See the big comment in
1393 // CompareConnections. 1432 // CompareConnections.
1394 Connection* P2PTransportChannel::FindNextPingableConnection() { 1433 Connection* P2PTransportChannel::FindNextPingableConnection() {
1395 int64_t now = rtc::TimeMillis(); 1434 int64_t now = rtc::TimeMillis();
1396 Connection* conn_to_ping = nullptr; 1435 Connection* conn_to_ping = nullptr;
1397 if (best_connection_ && best_connection_->connected() && 1436 if (selected_connection_ && selected_connection_->connected() &&
1398 best_connection_->writable() && 1437 selected_connection_->writable() &&
1399 (best_connection_->last_ping_sent() + config_.max_strong_interval <= 1438 (selected_connection_->last_ping_sent() + config_.max_strong_interval <=
1400 now)) { 1439 now)) {
1401 conn_to_ping = best_connection_; 1440 conn_to_ping = selected_connection_;
1402 } else { 1441 } else {
1403 conn_to_ping = FindConnectionToPing(now); 1442 conn_to_ping = FindConnectionToPing(now);
1404 } 1443 }
1405 return conn_to_ping; 1444 return conn_to_ping;
1406 } 1445 }
1407 1446
1408 void P2PTransportChannel::MarkConnectionPinged(Connection* conn) { 1447 void P2PTransportChannel::MarkConnectionPinged(Connection* conn) {
1409 if (conn && pinged_connections_.insert(conn).second) { 1448 if (conn && pinged_connections_.insert(conn).second) {
1410 unpinged_connections_.erase(conn); 1449 unpinged_connections_.erase(conn);
1411 } 1450 }
1412 } 1451 }
1413 1452
1414 // Apart from sending ping from |conn| this method also updates 1453 // Apart from sending ping from |conn| this method also updates
1415 // |use_candidate_attr| flag. The criteria to update this flag is 1454 // |use_candidate_attr| flag. The criteria to update this flag is
1416 // explained below. 1455 // explained below.
1417 // Set USE-CANDIDATE if doing ICE AND this channel is in CONTROLLING AND 1456 // Set USE-CANDIDATE if doing ICE AND this channel is in CONTROLLING AND
1418 // a) Channel is in FULL ICE AND 1457 // a) Channel is in FULL ICE AND
1419 // a.1) |conn| is the best connection OR 1458 // a.1) |conn| is the selected connection OR
1420 // a.2) there is no best connection OR 1459 // a.2) there is no selected connection OR
1421 // a.3) the best connection is unwritable OR 1460 // a.3) the selected connection is unwritable OR
1422 // a.4) |conn| has higher priority than best_connection. 1461 // a.4) |conn| has higher priority than selected_connection.
1423 // b) we're doing LITE ICE AND 1462 // b) we're doing LITE ICE AND
1424 // b.1) |conn| is the best_connection AND 1463 // b.1) |conn| is the selected_connection AND
1425 // b.2) |conn| is writable. 1464 // b.2) |conn| is writable.
1426 void P2PTransportChannel::PingConnection(Connection* conn) { 1465 void P2PTransportChannel::PingConnection(Connection* conn) {
1427 bool use_candidate = false; 1466 bool use_candidate = false;
1428 if (remote_ice_mode_ == ICEMODE_FULL && ice_role_ == ICEROLE_CONTROLLING) { 1467 if (remote_ice_mode_ == ICEMODE_FULL && ice_role_ == ICEROLE_CONTROLLING) {
1429 use_candidate = (conn == best_connection_) || (best_connection_ == NULL) || 1468 use_candidate =
1430 (!best_connection_->writable()) || 1469 (conn == selected_connection_) || (selected_connection_ == NULL) ||
1431 (CompareConnectionCandidates(best_connection_, conn) < 0); 1470 (!selected_connection_->writable()) ||
1432 } else if (remote_ice_mode_ == ICEMODE_LITE && conn == best_connection_) { 1471 (CompareConnectionCandidates(selected_connection_, conn) < 0);
1433 use_candidate = best_connection_->writable(); 1472 } else if (remote_ice_mode_ == ICEMODE_LITE && conn == selected_connection_) {
1473 use_candidate = selected_connection_->writable();
1434 } 1474 }
1435 conn->set_use_candidate_attr(use_candidate); 1475 conn->set_use_candidate_attr(use_candidate);
1436 last_ping_sent_ms_ = rtc::TimeMillis(); 1476 last_ping_sent_ms_ = rtc::TimeMillis();
1437 conn->Ping(last_ping_sent_ms_); 1477 conn->Ping(last_ping_sent_ms_);
1438 } 1478 }
1439 1479
1440 // When a connection's state changes, we need to figure out who to use as 1480 // When a connection's state changes, we need to figure out who to use as
1441 // the best connection again. It could have become usable, or become unusable. 1481 // the selected connection again. It could have become usable, or become
1482 // unusable.
1442 void P2PTransportChannel::OnConnectionStateChange(Connection* connection) { 1483 void P2PTransportChannel::OnConnectionStateChange(Connection* connection) {
1443 ASSERT(worker_thread_ == rtc::Thread::Current()); 1484 ASSERT(worker_thread_ == rtc::Thread::Current());
1444 1485
1445 // Update the best connection if the state change is from pending best 1486 // Update the selected connection if the state change is from last nominated
1446 // connection and role is controlled. 1487 // connection and role is controlled.
1447 if (ice_role_ == ICEROLE_CONTROLLED) { 1488 if (ice_role_ == ICEROLE_CONTROLLED &&
1448 if (connection == pending_best_connection_ && connection->writable()) { 1489 connection == last_nominated_connection_ &&
1449 pending_best_connection_ = NULL; 1490 connection != selected_connection_ &&
1450 LOG(LS_INFO) << "Switching best connection on controlled side" 1491 ShouldSwitchOnNominatedOrDataReceived(connection)) {
1451 << " because it's now writable: " << connection->ToString(); 1492 LOG(LS_INFO) << "Switching selected connection on controlled side"
1452 SwitchBestConnectionTo(connection); 1493 << " because it's now writable: " << connection->ToString();
1453 } 1494 SwitchSelectedConnection(connection);
1454 } 1495 }
1455 1496
1456 // May stop the allocator session when at least one connection becomes 1497 // May stop the allocator session when at least one connection becomes
1457 // strongly connected after starting to get ports and the local candidate of 1498 // strongly connected after starting to get ports and the local candidate of
1458 // the connection is at the latest generation. It is not enough to check 1499 // the connection is at the latest generation. It is not enough to check
1459 // that the connection becomes weakly connected because the connection may be 1500 // that the connection becomes weakly connected because the connection may be
1460 // changing from (writable, receiving) to (writable, not receiving). 1501 // changing from (writable, receiving) to (writable, not receiving).
1461 bool strongly_connected = !connection->weak(); 1502 bool strongly_connected = !connection->weak();
1462 bool latest_generation = connection->local_candidate().generation() >= 1503 bool latest_generation = connection->local_candidate().generation() >=
1463 allocator_session()->generation(); 1504 allocator_session()->generation();
1464 if (strongly_connected && latest_generation) { 1505 if (strongly_connected && latest_generation) {
1465 MaybeStopPortAllocatorSessions(); 1506 MaybeStopPortAllocatorSessions();
1466 } 1507 }
1467 1508
1468 // We have to unroll the stack before doing this because we may be changing 1509 // We have to unroll the stack before doing this because we may be changing
1469 // the state of connections while sorting. 1510 // the state of connections while sorting.
1470 RequestSort(); 1511 RequestSort();
1471 } 1512 }
1472 1513
1473 // When a connection is removed, edit it out, and then update our best 1514 // When a connection is removed, edit it out, and then update our best
1474 // connection. 1515 // connection.
1475 void P2PTransportChannel::OnConnectionDestroyed(Connection* connection) { 1516 void P2PTransportChannel::OnConnectionDestroyed(Connection* connection) {
1476 ASSERT(worker_thread_ == rtc::Thread::Current()); 1517 ASSERT(worker_thread_ == rtc::Thread::Current());
1477 1518
1478 // Note: the previous best_connection_ may be destroyed by now, so don't 1519 // Note: the previous selected_connection_ may be destroyed by now, so don't
1479 // use it. 1520 // use it.
1480 1521
1481 // Remove this connection from the list. 1522 // Remove this connection from the list.
1482 std::vector<Connection*>::iterator iter = 1523 std::vector<Connection*>::iterator iter =
1483 std::find(connections_.begin(), connections_.end(), connection); 1524 std::find(connections_.begin(), connections_.end(), connection);
1484 ASSERT(iter != connections_.end()); 1525 ASSERT(iter != connections_.end());
1485 pinged_connections_.erase(*iter); 1526 pinged_connections_.erase(*iter);
1486 unpinged_connections_.erase(*iter); 1527 unpinged_connections_.erase(*iter);
1487 connections_.erase(iter); 1528 connections_.erase(iter);
1488 1529
1489 LOG_J(LS_INFO, this) << "Removed connection (" 1530 LOG_J(LS_INFO, this) << "Removed connection ("
1490 << static_cast<int>(connections_.size()) << " remaining)"; 1531 << static_cast<int>(connections_.size()) << " remaining)";
1491 1532
1492 if (pending_best_connection_ == connection) { 1533 // If this is currently the selected connection, then we need to pick a new
1493 pending_best_connection_ = NULL; 1534 // one. The call to SortConnections will pick a new one. It looks at the
1494 } 1535 // current selected connection in order to avoid switching between fairly
1495 1536 // similar ones. Since this connection is no longer an option, we can just
1496 // If this is currently the best connection, then we need to pick a new one. 1537 // set selected to nullptr and re-choose a best assuming that there was no
1497 // The call to SortConnections will pick a new one. It looks at the current 1538 // selected connection.
1498 // best connection in order to avoid switching between fairly similar ones. 1539 if (selected_connection_ == connection) {
1499 // Since this connection is no longer an option, we can just set best to NULL 1540 LOG(LS_INFO) << "selected connection destroyed. Will choose a new one.";
1500 // and re-choose a best assuming that there was no best connection. 1541 SwitchSelectedConnection(nullptr);
1501 if (best_connection_ == connection) {
1502 LOG(LS_INFO) << "Best connection destroyed. Will choose a new one.";
1503 SwitchBestConnectionTo(NULL);
1504 RequestSort(); 1542 RequestSort();
1505 } 1543 }
1506 1544
1507 UpdateState(); 1545 UpdateState();
1508 } 1546 }
1509 1547
1510 // When a port is destroyed remove it from our list of ports to use for 1548 // When a port is destroyed remove it from our list of ports to use for
1511 // connection attempts. 1549 // connection attempts.
1512 void P2PTransportChannel::OnPortDestroyed(PortInterface* port) { 1550 void P2PTransportChannel::OnPortDestroyed(PortInterface* port) {
1513 ASSERT(worker_thread_ == rtc::Thread::Current()); 1551 ASSERT(worker_thread_ == rtc::Thread::Current());
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1552 1590
1553 // Do not deliver, if packet doesn't belong to the correct transport channel. 1591 // Do not deliver, if packet doesn't belong to the correct transport channel.
1554 if (!FindConnection(connection)) 1592 if (!FindConnection(connection))
1555 return; 1593 return;
1556 1594
1557 // Let the client know of an incoming packet 1595 // Let the client know of an incoming packet
1558 SignalReadPacket(this, data, len, packet_time, 0); 1596 SignalReadPacket(this, data, len, packet_time, 0);
1559 1597
1560 // May need to switch the sending connection based on the receiving media path 1598 // May need to switch the sending connection based on the receiving media path
1561 // if this is the controlled side. 1599 // if this is the controlled side.
1562 if (ice_role_ == ICEROLE_CONTROLLED && !best_nominated_connection() && 1600 if (ice_role_ != ICEROLE_CONTROLLED || selected_connection_ == connection) {
1563 connection->writable() && best_connection_ != connection) { 1601 return;
1564 SwitchBestConnectionTo(connection); 1602 }
1603
1604 last_receiving_connection_ = connection;
1605 if (ShouldSwitchOnNominatedOrDataReceived(connection)) {
1606 LOG(LS_INFO)
1607 << "Switching selected connection on controlled side due to receiving: "
1608 << connection->ToString();
1609 SwitchSelectedConnection(connection);
1565 } 1610 }
1566 } 1611 }
1567 1612
1568 void P2PTransportChannel::OnSentPacket(const rtc::SentPacket& sent_packet) { 1613 void P2PTransportChannel::OnSentPacket(const rtc::SentPacket& sent_packet) {
1569 ASSERT(worker_thread_ == rtc::Thread::Current()); 1614 ASSERT(worker_thread_ == rtc::Thread::Current());
1570 1615
1571 SignalSentPacket(this, sent_packet); 1616 SignalSentPacket(this, sent_packet);
1572 } 1617 }
1573 1618
1574 void P2PTransportChannel::OnReadyToSend(Connection* connection) { 1619 void P2PTransportChannel::OnReadyToSend(Connection* connection) {
1575 if (connection == best_connection_ && writable()) { 1620 if (connection == selected_connection_ && writable()) {
1576 SignalReadyToSend(this); 1621 SignalReadyToSend(this);
1577 } 1622 }
1578 } 1623 }
1579 1624
1580 // Find "triggered checks". We ping first those connections that have 1625 // Find "triggered checks". We ping first those connections that have
1581 // received a ping but have not sent a ping since receiving it 1626 // received a ping but have not sent a ping since receiving it
1582 // (last_received_ping > last_sent_ping). But we shouldn't do 1627 // (last_received_ping > last_sent_ping). But we shouldn't do
1583 // triggered checks if the connection is already writable. 1628 // triggered checks if the connection is already writable.
1584 Connection* P2PTransportChannel::FindOldestConnectionNeedingTriggeredCheck( 1629 Connection* P2PTransportChannel::FindOldestConnectionNeedingTriggeredCheck(
1585 int64_t now) { 1630 int64_t now) {
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1688 1733
1689 // During the initial state when nothing has been pinged yet, return the first 1734 // During the initial state when nothing has been pinged yet, return the first
1690 // one in the ordered |connections_|. 1735 // one in the ordered |connections_|.
1691 return *(std::find_if(connections_.begin(), connections_.end(), 1736 return *(std::find_if(connections_.begin(), connections_.end(),
1692 [conn1, conn2](Connection* conn) { 1737 [conn1, conn2](Connection* conn) {
1693 return conn == conn1 || conn == conn2; 1738 return conn == conn1 || conn == conn2;
1694 })); 1739 }));
1695 } 1740 }
1696 1741
1697 } // namespace cricket 1742 } // namespace cricket
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698