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 13 matching lines...) Expand all Loading... |
24 #include "webrtc/system_wrappers/include/field_trial.h" | 24 #include "webrtc/system_wrappers/include/field_trial.h" |
25 | 25 |
26 namespace { | 26 namespace { |
27 | 27 |
28 // messages for queuing up work for ourselves | 28 // messages for queuing up work for ourselves |
29 enum { MSG_SORT = 1, MSG_CHECK_AND_PING }; | 29 enum { MSG_SORT = 1, MSG_CHECK_AND_PING }; |
30 | 30 |
31 // The minimum improvement in RTT that justifies a switch. | 31 // The minimum improvement in RTT that justifies a switch. |
32 static const double kMinImprovement = 10; | 32 static const double kMinImprovement = 10; |
33 | 33 |
| 34 bool IsRelayRelay(cricket::Connection* conn) { |
| 35 return conn->local_candidate().type() == cricket::RELAY_PORT_TYPE && |
| 36 conn->remote_candidate().type() == cricket::RELAY_PORT_TYPE; |
| 37 } |
| 38 |
| 39 bool IsUdp(cricket::Connection* conn) { |
| 40 return conn->local_candidate().relay_protocol() == cricket::UDP_PROTOCOL_NAME; |
| 41 } |
| 42 |
34 cricket::PortInterface::CandidateOrigin GetOrigin(cricket::PortInterface* port, | 43 cricket::PortInterface::CandidateOrigin GetOrigin(cricket::PortInterface* port, |
35 cricket::PortInterface* origin_port) { | 44 cricket::PortInterface* origin_port) { |
36 if (!origin_port) | 45 if (!origin_port) |
37 return cricket::PortInterface::ORIGIN_MESSAGE; | 46 return cricket::PortInterface::ORIGIN_MESSAGE; |
38 else if (port == origin_port) | 47 else if (port == origin_port) |
39 return cricket::PortInterface::ORIGIN_THIS_PORT; | 48 return cricket::PortInterface::ORIGIN_THIS_PORT; |
40 else | 49 else |
41 return cricket::PortInterface::ORIGIN_OTHER_PORT; | 50 return cricket::PortInterface::ORIGIN_OTHER_PORT; |
42 } | 51 } |
43 | 52 |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
230 incoming_only_(false), | 239 incoming_only_(false), |
231 error_(0), | 240 error_(0), |
232 best_connection_(NULL), | 241 best_connection_(NULL), |
233 pending_best_connection_(NULL), | 242 pending_best_connection_(NULL), |
234 sort_dirty_(false), | 243 sort_dirty_(false), |
235 remote_ice_mode_(ICEMODE_FULL), | 244 remote_ice_mode_(ICEMODE_FULL), |
236 ice_role_(ICEROLE_UNKNOWN), | 245 ice_role_(ICEROLE_UNKNOWN), |
237 tiebreaker_(0), | 246 tiebreaker_(0), |
238 gathering_state_(kIceGatheringNew), | 247 gathering_state_(kIceGatheringNew), |
239 check_receiving_delay_(MIN_CHECK_RECEIVING_DELAY * 5), | 248 check_receiving_delay_(MIN_CHECK_RECEIVING_DELAY * 5), |
240 receiving_timeout_(MIN_CHECK_RECEIVING_DELAY * 50), | 249 config_(MIN_CHECK_RECEIVING_DELAY * 50 /* receiving_timeout */, |
241 backup_connection_ping_interval_(0) { | 250 0 /* backup_connection_ping_interval */, |
| 251 false /* gather_continually */, |
| 252 false /* prioritize_most_likely_candidate_pairs */, |
| 253 MAX_CURRENT_STRONG_DELAY /* most_strong_delay */) { |
242 uint32_t weak_ping_delay = ::strtoul( | 254 uint32_t weak_ping_delay = ::strtoul( |
243 webrtc::field_trial::FindFullName("WebRTC-StunInterPacketDelay").c_str(), | 255 webrtc::field_trial::FindFullName("WebRTC-StunInterPacketDelay").c_str(), |
244 nullptr, 10); | 256 nullptr, 10); |
245 if (weak_ping_delay) { | 257 if (weak_ping_delay) { |
246 weak_ping_delay_ = weak_ping_delay; | 258 weak_ping_delay_ = weak_ping_delay; |
247 } | 259 } |
248 } | 260 } |
249 | 261 |
250 P2PTransportChannel::~P2PTransportChannel() { | 262 P2PTransportChannel::~P2PTransportChannel() { |
251 ASSERT(worker_thread_ == rtc::Thread::Current()); | 263 ASSERT(worker_thread_ == rtc::Thread::Current()); |
(...skipping 18 matching lines...) Expand all Loading... |
270 session->SignalPortReady.connect(this, &P2PTransportChannel::OnPortReady); | 282 session->SignalPortReady.connect(this, &P2PTransportChannel::OnPortReady); |
271 session->SignalCandidatesReady.connect( | 283 session->SignalCandidatesReady.connect( |
272 this, &P2PTransportChannel::OnCandidatesReady); | 284 this, &P2PTransportChannel::OnCandidatesReady); |
273 session->SignalCandidatesAllocationDone.connect( | 285 session->SignalCandidatesAllocationDone.connect( |
274 this, &P2PTransportChannel::OnCandidatesAllocationDone); | 286 this, &P2PTransportChannel::OnCandidatesAllocationDone); |
275 session->StartGettingPorts(); | 287 session->StartGettingPorts(); |
276 } | 288 } |
277 | 289 |
278 void P2PTransportChannel::AddConnection(Connection* connection) { | 290 void P2PTransportChannel::AddConnection(Connection* connection) { |
279 connections_.push_back(connection); | 291 connections_.push_back(connection); |
| 292 unpinged_connections_.insert(connection); |
280 connection->set_remote_ice_mode(remote_ice_mode_); | 293 connection->set_remote_ice_mode(remote_ice_mode_); |
281 connection->set_receiving_timeout(receiving_timeout_); | 294 connection->set_receiving_timeout(config_.receiving_timeout_ms); |
282 connection->SignalReadPacket.connect( | 295 connection->SignalReadPacket.connect( |
283 this, &P2PTransportChannel::OnReadPacket); | 296 this, &P2PTransportChannel::OnReadPacket); |
284 connection->SignalReadyToSend.connect( | 297 connection->SignalReadyToSend.connect( |
285 this, &P2PTransportChannel::OnReadyToSend); | 298 this, &P2PTransportChannel::OnReadyToSend); |
286 connection->SignalStateChange.connect( | 299 connection->SignalStateChange.connect( |
287 this, &P2PTransportChannel::OnConnectionStateChange); | 300 this, &P2PTransportChannel::OnConnectionStateChange); |
288 connection->SignalDestroyed.connect( | 301 connection->SignalDestroyed.connect( |
289 this, &P2PTransportChannel::OnConnectionDestroyed); | 302 this, &P2PTransportChannel::OnConnectionDestroyed); |
290 connection->SignalNominated.connect(this, &P2PTransportChannel::OnNominated); | 303 connection->SignalNominated.connect(this, &P2PTransportChannel::OnNominated); |
291 had_connection_ = true; | 304 had_connection_ = true; |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
381 for (Connection* conn : connections_) { | 394 for (Connection* conn : connections_) { |
382 conn->MaybeSetRemoteIceCredentials(ice_ufrag, ice_pwd); | 395 conn->MaybeSetRemoteIceCredentials(ice_ufrag, ice_pwd); |
383 } | 396 } |
384 } | 397 } |
385 | 398 |
386 void P2PTransportChannel::SetRemoteIceMode(IceMode mode) { | 399 void P2PTransportChannel::SetRemoteIceMode(IceMode mode) { |
387 remote_ice_mode_ = mode; | 400 remote_ice_mode_ = mode; |
388 } | 401 } |
389 | 402 |
390 void P2PTransportChannel::SetIceConfig(const IceConfig& config) { | 403 void P2PTransportChannel::SetIceConfig(const IceConfig& config) { |
391 gather_continually_ = config.gather_continually; | 404 config_.gather_continually = config.gather_continually; |
392 LOG(LS_INFO) << "Set gather_continually to " << gather_continually_; | 405 LOG(LS_INFO) << "Set gather_continually to " << config_.gather_continually; |
393 | 406 |
394 if (config.backup_connection_ping_interval >= 0 && | 407 if (config.backup_connection_ping_interval >= 0 && |
395 backup_connection_ping_interval_ != | 408 config_.backup_connection_ping_interval != |
396 config.backup_connection_ping_interval) { | 409 config.backup_connection_ping_interval) { |
397 backup_connection_ping_interval_ = config.backup_connection_ping_interval; | 410 config_.backup_connection_ping_interval = |
| 411 config.backup_connection_ping_interval; |
398 LOG(LS_INFO) << "Set backup connection ping interval to " | 412 LOG(LS_INFO) << "Set backup connection ping interval to " |
399 << backup_connection_ping_interval_ << " milliseconds."; | 413 << config_.backup_connection_ping_interval << " milliseconds."; |
400 } | 414 } |
401 | 415 |
402 if (config.receiving_timeout_ms >= 0 && | 416 if (config.receiving_timeout_ms >= 0 && |
403 receiving_timeout_ != config.receiving_timeout_ms) { | 417 config_.receiving_timeout_ms != config.receiving_timeout_ms) { |
404 receiving_timeout_ = config.receiving_timeout_ms; | 418 config_.receiving_timeout_ms = config.receiving_timeout_ms; |
405 check_receiving_delay_ = | 419 check_receiving_delay_ = |
406 std::max(MIN_CHECK_RECEIVING_DELAY, receiving_timeout_ / 10); | 420 std::max(MIN_CHECK_RECEIVING_DELAY, config_.receiving_timeout_ms / 10); |
407 | 421 |
408 for (Connection* connection : connections_) { | 422 for (Connection* connection : connections_) { |
409 connection->set_receiving_timeout(receiving_timeout_); | 423 connection->set_receiving_timeout(config_.receiving_timeout_ms); |
410 } | 424 } |
411 LOG(LS_INFO) << "Set ICE receiving timeout to " << receiving_timeout_ | 425 LOG(LS_INFO) << "Set ICE receiving timeout to " |
412 << " milliseconds"; | 426 << config_.receiving_timeout_ms << " milliseconds"; |
413 } | 427 } |
| 428 |
| 429 config_.prioritize_most_likely_candidate_pairs = |
| 430 config.prioritize_most_likely_candidate_pairs; |
| 431 LOG(LS_INFO) << "Set ping most likely connection to " |
| 432 << config_.prioritize_most_likely_candidate_pairs; |
| 433 |
| 434 if (config.max_strong_delay >= 0 && |
| 435 config_.max_strong_delay != config.max_strong_delay) { |
| 436 config_.max_strong_delay = config.max_strong_delay; |
| 437 LOG(LS_INFO) << "Set max strong delay to " << config_.max_strong_delay; |
| 438 } |
| 439 } |
| 440 |
| 441 const IceConfig& P2PTransportChannel::config() const { |
| 442 return config_; |
414 } | 443 } |
415 | 444 |
416 // Go into the state of processing candidates, and running in general | 445 // Go into the state of processing candidates, and running in general |
417 void P2PTransportChannel::Connect() { | 446 void P2PTransportChannel::Connect() { |
418 ASSERT(worker_thread_ == rtc::Thread::Current()); | 447 ASSERT(worker_thread_ == rtc::Thread::Current()); |
419 if (ice_ufrag_.empty() || ice_pwd_.empty()) { | 448 if (ice_ufrag_.empty() || ice_pwd_.empty()) { |
420 ASSERT(false); | 449 ASSERT(false); |
421 LOG(LS_ERROR) << "P2PTransportChannel::Connect: The ice_ufrag_ and the " | 450 LOG(LS_ERROR) << "P2PTransportChannel::Connect: The ice_ufrag_ and the " |
422 << "ice_pwd_ are not set."; | 451 << "ice_pwd_ are not set."; |
423 return; | 452 return; |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
622 return; | 651 return; |
623 } else { | 652 } else { |
624 ASSERT(false); | 653 ASSERT(false); |
625 port->SendBindingErrorResponse(stun_msg, address, | 654 port->SendBindingErrorResponse(stun_msg, address, |
626 STUN_ERROR_SERVER_ERROR, | 655 STUN_ERROR_SERVER_ERROR, |
627 STUN_ERROR_REASON_SERVER_ERROR); | 656 STUN_ERROR_REASON_SERVER_ERROR); |
628 return; | 657 return; |
629 } | 658 } |
630 } | 659 } |
631 | 660 |
632 Connection* connection = port->CreateConnection( | 661 Connection* connection = |
633 remote_candidate, cricket::PortInterface::ORIGIN_THIS_PORT); | 662 port->CreateConnection(remote_candidate, PortInterface::ORIGIN_THIS_PORT); |
634 if (!connection) { | 663 if (!connection) { |
635 ASSERT(false); | 664 ASSERT(false); |
636 port->SendBindingErrorResponse(stun_msg, address, STUN_ERROR_SERVER_ERROR, | 665 port->SendBindingErrorResponse(stun_msg, address, STUN_ERROR_SERVER_ERROR, |
637 STUN_ERROR_REASON_SERVER_ERROR); | 666 STUN_ERROR_REASON_SERVER_ERROR); |
638 return; | 667 return; |
639 } | 668 } |
640 | 669 |
641 LOG(LS_INFO) << "Adding connection from " | 670 LOG(LS_INFO) << "Adding connection from " |
642 << (remote_candidate_is_new ? "peer reflexive" : "resurrected") | 671 << (remote_candidate_is_new ? "peer reflexive" : "resurrected") |
643 << " candidate: " << remote_candidate.ToString(); | 672 << " candidate: " << remote_candidate.ToString(); |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
800 << connection->remote_candidate().ToString() | 829 << connection->remote_candidate().ToString() |
801 << "New remote candidate: " | 830 << "New remote candidate: " |
802 << remote_candidate.ToString(); | 831 << remote_candidate.ToString(); |
803 return false; | 832 return false; |
804 } | 833 } |
805 } else { | 834 } else { |
806 PortInterface::CandidateOrigin origin = GetOrigin(port, origin_port); | 835 PortInterface::CandidateOrigin origin = GetOrigin(port, origin_port); |
807 | 836 |
808 // Don't create connection if this is a candidate we received in a | 837 // Don't create connection if this is a candidate we received in a |
809 // message and we are not allowed to make outgoing connections. | 838 // message and we are not allowed to make outgoing connections. |
810 if (origin == cricket::PortInterface::ORIGIN_MESSAGE && incoming_only_) | 839 if (origin == PortInterface::ORIGIN_MESSAGE && incoming_only_) |
811 return false; | 840 return false; |
812 | 841 |
813 connection = port->CreateConnection(remote_candidate, origin); | 842 connection = port->CreateConnection(remote_candidate, origin); |
814 if (!connection) | 843 if (!connection) |
815 return false; | 844 return false; |
816 | 845 |
817 AddConnection(connection); | 846 AddConnection(connection); |
818 | 847 |
819 LOG_J(LS_INFO, this) << "Created connection with origin=" << origin << ", (" | 848 LOG_J(LS_INFO, this) << "Created connection with origin=" << origin << ", (" |
820 << connections_.size() << " total)"; | 849 << connections_.size() << " total)"; |
821 } | 850 } |
822 | 851 |
823 return true; | 852 return true; |
824 } | 853 } |
825 | 854 |
826 bool P2PTransportChannel::FindConnection( | 855 bool P2PTransportChannel::FindConnection(Connection* connection) const { |
827 cricket::Connection* connection) const { | |
828 std::vector<Connection*>::const_iterator citer = | 856 std::vector<Connection*>::const_iterator citer = |
829 std::find(connections_.begin(), connections_.end(), connection); | 857 std::find(connections_.begin(), connections_.end(), connection); |
830 return citer != connections_.end(); | 858 return citer != connections_.end(); |
831 } | 859 } |
832 | 860 |
833 uint32_t P2PTransportChannel::GetRemoteCandidateGeneration( | 861 uint32_t P2PTransportChannel::GetRemoteCandidateGeneration( |
834 const Candidate& candidate) { | 862 const Candidate& candidate) { |
835 // If the candidate has a ufrag, use it to find the generation. | 863 // If the candidate has a ufrag, use it to find the generation. |
836 if (!candidate.username().empty()) { | 864 if (!candidate.username().empty()) { |
837 uint32_t generation = 0; | 865 uint32_t generation = 0; |
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1147 if (!IsGettingPorts()) { | 1175 if (!IsGettingPorts()) { |
1148 return; | 1176 return; |
1149 } | 1177 } |
1150 | 1178 |
1151 for (PortAllocatorSession* session : allocator_sessions_) { | 1179 for (PortAllocatorSession* session : allocator_sessions_) { |
1152 if (!session->IsGettingPorts()) { | 1180 if (!session->IsGettingPorts()) { |
1153 continue; | 1181 continue; |
1154 } | 1182 } |
1155 // If gathering continually, keep the last session running so that it | 1183 // If gathering continually, keep the last session running so that it |
1156 // will gather candidates if the networks change. | 1184 // will gather candidates if the networks change. |
1157 if (gather_continually_ && session == allocator_sessions_.back()) { | 1185 if (config_.gather_continually && session == allocator_sessions_.back()) { |
1158 session->ClearGettingPorts(); | 1186 session->ClearGettingPorts(); |
1159 break; | 1187 break; |
1160 } | 1188 } |
1161 session->StopGettingPorts(); | 1189 session->StopGettingPorts(); |
1162 } | 1190 } |
1163 } | 1191 } |
1164 | 1192 |
1165 // If all connections timed out, delete them all. | 1193 // If all connections timed out, delete them all. |
1166 void P2PTransportChannel::HandleAllTimedOut() { | 1194 void P2PTransportChannel::HandleAllTimedOut() { |
1167 for (Connection* connection : connections_) { | 1195 for (Connection* connection : connections_) { |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1216 // Make sure the states of the connections are up-to-date (since this affects | 1244 // Make sure the states of the connections are up-to-date (since this affects |
1217 // which ones are pingable). | 1245 // which ones are pingable). |
1218 UpdateConnectionStates(); | 1246 UpdateConnectionStates(); |
1219 // When the best connection is either not receiving or not writable, | 1247 // When the best connection is either not receiving or not writable, |
1220 // switch to weak ping delay. | 1248 // switch to weak ping delay. |
1221 int ping_delay = weak() ? weak_ping_delay_ : STRONG_PING_DELAY; | 1249 int ping_delay = weak() ? weak_ping_delay_ : STRONG_PING_DELAY; |
1222 if (rtc::Time() >= last_ping_sent_ms_ + ping_delay) { | 1250 if (rtc::Time() >= last_ping_sent_ms_ + ping_delay) { |
1223 Connection* conn = FindNextPingableConnection(); | 1251 Connection* conn = FindNextPingableConnection(); |
1224 if (conn) { | 1252 if (conn) { |
1225 PingConnection(conn); | 1253 PingConnection(conn); |
| 1254 MarkConnectionPinged(conn); |
1226 } | 1255 } |
1227 } | 1256 } |
1228 int check_delay = std::min(ping_delay, check_receiving_delay_); | 1257 int check_delay = std::min(ping_delay, check_receiving_delay_); |
1229 thread()->PostDelayed(check_delay, this, MSG_CHECK_AND_PING); | 1258 thread()->PostDelayed(check_delay, this, MSG_CHECK_AND_PING); |
1230 } | 1259 } |
1231 | 1260 |
1232 // A connection is considered a backup connection if the channel state | 1261 // A connection is considered a backup connection if the channel state |
1233 // is completed, the connection is not the best connection and it is active. | 1262 // is completed, the connection is not the best connection and it is active. |
1234 bool P2PTransportChannel::IsBackupConnection(Connection* conn) const { | 1263 bool P2PTransportChannel::IsBackupConnection(Connection* conn) const { |
1235 return state_ == STATE_COMPLETED && conn != best_connection_ && | 1264 return state_ == STATE_COMPLETED && conn != best_connection_ && |
(...skipping 21 matching lines...) Expand all Loading... |
1257 | 1286 |
1258 // If the channel is weakly connected, ping all connections. | 1287 // If the channel is weakly connected, ping all connections. |
1259 if (weak()) { | 1288 if (weak()) { |
1260 return true; | 1289 return true; |
1261 } | 1290 } |
1262 | 1291 |
1263 // Always ping active connections regardless whether the channel is completed | 1292 // Always ping active connections regardless whether the channel is completed |
1264 // or not, but backup connections are pinged at a slower rate. | 1293 // or not, but backup connections are pinged at a slower rate. |
1265 if (IsBackupConnection(conn)) { | 1294 if (IsBackupConnection(conn)) { |
1266 return (now >= conn->last_ping_response_received() + | 1295 return (now >= conn->last_ping_response_received() + |
1267 backup_connection_ping_interval_); | 1296 config_.backup_connection_ping_interval); |
1268 } | 1297 } |
1269 return conn->active(); | 1298 return conn->active(); |
1270 } | 1299 } |
1271 | 1300 |
1272 // Returns the next pingable connection to ping. This will be the oldest | 1301 // Returns the next pingable connection to ping. This will be the oldest |
1273 // pingable connection unless we have a connected, writable connection that is | 1302 // pingable connection unless we have a connected, writable connection that is |
1274 // past the maximum acceptable ping delay. When reconnecting a TCP connection, | 1303 // past the maximum acceptable ping delay. When reconnecting a TCP connection, |
1275 // the best connection is disconnected, although still WRITABLE while | 1304 // the best connection is disconnected, although still WRITABLE while |
1276 // reconnecting. The newly created connection should be selected as the ping | 1305 // reconnecting. The newly created connection should be selected as the ping |
1277 // target to become writable instead. See the big comment in CompareConnections. | 1306 // target to become writable instead. See the big comment in CompareConnections. |
1278 Connection* P2PTransportChannel::FindNextPingableConnection() { | 1307 Connection* P2PTransportChannel::FindNextPingableConnection() { |
1279 uint32_t now = rtc::Time(); | 1308 uint32_t now = rtc::Time(); |
| 1309 Connection* conn_to_ping = nullptr; |
1280 if (best_connection_ && best_connection_->connected() && | 1310 if (best_connection_ && best_connection_->connected() && |
1281 best_connection_->writable() && | 1311 best_connection_->writable() && |
1282 (best_connection_->last_ping_sent() + MAX_CURRENT_STRONG_DELAY <= now)) { | 1312 (best_connection_->last_ping_sent() + config_.max_strong_delay <= now)) { |
1283 return best_connection_; | 1313 conn_to_ping = best_connection_; |
| 1314 } else { |
| 1315 conn_to_ping = FindConnectionToPing(now); |
1284 } | 1316 } |
| 1317 return conn_to_ping; |
| 1318 } |
1285 | 1319 |
1286 // First, find "triggered checks". We ping first those connections | 1320 void P2PTransportChannel::MarkConnectionPinged(Connection* conn) { |
1287 // that have received a ping but have not sent a ping since receiving | 1321 if (conn && pinged_connections_.insert(conn).second) { |
1288 // it (last_received_ping > last_sent_ping). But we shouldn't do | 1322 unpinged_connections_.erase(conn); |
1289 // triggered checks if the connection is already writable. | |
1290 Connection* oldest_needing_triggered_check = nullptr; | |
1291 Connection* oldest = nullptr; | |
1292 for (Connection* conn : connections_) { | |
1293 if (!IsPingable(conn, now)) { | |
1294 continue; | |
1295 } | |
1296 bool needs_triggered_check = | |
1297 (!conn->writable() && | |
1298 conn->last_ping_received() > conn->last_ping_sent()); | |
1299 if (needs_triggered_check && | |
1300 (!oldest_needing_triggered_check || | |
1301 (conn->last_ping_received() < | |
1302 oldest_needing_triggered_check->last_ping_received()))) { | |
1303 oldest_needing_triggered_check = conn; | |
1304 } | |
1305 if (!oldest || (conn->last_ping_sent() < oldest->last_ping_sent())) { | |
1306 oldest = conn; | |
1307 } | |
1308 } | 1323 } |
1309 | |
1310 if (oldest_needing_triggered_check) { | |
1311 LOG(LS_INFO) << "Selecting connection for triggered check: " << | |
1312 oldest_needing_triggered_check->ToString(); | |
1313 return oldest_needing_triggered_check; | |
1314 } | |
1315 return oldest; | |
1316 } | 1324 } |
1317 | 1325 |
1318 // Apart from sending ping from |conn| this method also updates | 1326 // Apart from sending ping from |conn| this method also updates |
1319 // |use_candidate_attr| flag. The criteria to update this flag is | 1327 // |use_candidate_attr| flag. The criteria to update this flag is |
1320 // explained below. | 1328 // explained below. |
1321 // Set USE-CANDIDATE if doing ICE AND this channel is in CONTROLLING AND | 1329 // Set USE-CANDIDATE if doing ICE AND this channel is in CONTROLLING AND |
1322 // a) Channel is in FULL ICE AND | 1330 // a) Channel is in FULL ICE AND |
1323 // a.1) |conn| is the best connection OR | 1331 // a.1) |conn| is the best connection OR |
1324 // a.2) there is no best connection OR | 1332 // a.2) there is no best connection OR |
1325 // a.3) the best connection is unwritable OR | 1333 // a.3) the best connection is unwritable OR |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1375 void P2PTransportChannel::OnConnectionDestroyed(Connection* connection) { | 1383 void P2PTransportChannel::OnConnectionDestroyed(Connection* connection) { |
1376 ASSERT(worker_thread_ == rtc::Thread::Current()); | 1384 ASSERT(worker_thread_ == rtc::Thread::Current()); |
1377 | 1385 |
1378 // Note: the previous best_connection_ may be destroyed by now, so don't | 1386 // Note: the previous best_connection_ may be destroyed by now, so don't |
1379 // use it. | 1387 // use it. |
1380 | 1388 |
1381 // Remove this connection from the list. | 1389 // Remove this connection from the list. |
1382 std::vector<Connection*>::iterator iter = | 1390 std::vector<Connection*>::iterator iter = |
1383 std::find(connections_.begin(), connections_.end(), connection); | 1391 std::find(connections_.begin(), connections_.end(), connection); |
1384 ASSERT(iter != connections_.end()); | 1392 ASSERT(iter != connections_.end()); |
| 1393 pinged_connections_.erase(*iter); |
| 1394 unpinged_connections_.erase(*iter); |
1385 connections_.erase(iter); | 1395 connections_.erase(iter); |
1386 | 1396 |
1387 LOG_J(LS_INFO, this) << "Removed connection (" | 1397 LOG_J(LS_INFO, this) << "Removed connection (" |
1388 << static_cast<int>(connections_.size()) << " remaining)"; | 1398 << static_cast<int>(connections_.size()) << " remaining)"; |
1389 | 1399 |
1390 if (pending_best_connection_ == connection) { | 1400 if (pending_best_connection_ == connection) { |
1391 pending_best_connection_ = NULL; | 1401 pending_best_connection_ = NULL; |
1392 } | 1402 } |
1393 | 1403 |
1394 // If this is currently the best connection, then we need to pick a new one. | 1404 // If this is currently the best connection, then we need to pick a new one. |
(...skipping 24 matching lines...) Expand all Loading... |
1419 if (iter != ports_.end()) | 1429 if (iter != ports_.end()) |
1420 ports_.erase(iter); | 1430 ports_.erase(iter); |
1421 | 1431 |
1422 LOG(INFO) << "Removed port from p2p socket: " | 1432 LOG(INFO) << "Removed port from p2p socket: " |
1423 << static_cast<int>(ports_.size()) << " remaining"; | 1433 << static_cast<int>(ports_.size()) << " remaining"; |
1424 } | 1434 } |
1425 | 1435 |
1426 void P2PTransportChannel::OnPortNetworkInactive(PortInterface* port) { | 1436 void P2PTransportChannel::OnPortNetworkInactive(PortInterface* port) { |
1427 // If it does not gather continually, the port will be removed from the list | 1437 // If it does not gather continually, the port will be removed from the list |
1428 // when ICE restarts. | 1438 // when ICE restarts. |
1429 if (!gather_continually_) { | 1439 if (!config_.gather_continually) { |
1430 return; | 1440 return; |
1431 } | 1441 } |
1432 auto it = std::find(ports_.begin(), ports_.end(), port); | 1442 auto it = std::find(ports_.begin(), ports_.end(), port); |
1433 // Don't need to do anything if the port has been deleted from the port list. | 1443 // Don't need to do anything if the port has been deleted from the port list. |
1434 if (it == ports_.end()) { | 1444 if (it == ports_.end()) { |
1435 return; | 1445 return; |
1436 } | 1446 } |
1437 ports_.erase(it); | 1447 ports_.erase(it); |
1438 LOG(INFO) << "Removed port due to inactive networks: " << ports_.size() | 1448 LOG(INFO) << "Removed port due to inactive networks: " << ports_.size() |
1439 << " remaining"; | 1449 << " remaining"; |
(...skipping 27 matching lines...) Expand all Loading... |
1467 | 1477 |
1468 SignalSentPacket(this, sent_packet); | 1478 SignalSentPacket(this, sent_packet); |
1469 } | 1479 } |
1470 | 1480 |
1471 void P2PTransportChannel::OnReadyToSend(Connection* connection) { | 1481 void P2PTransportChannel::OnReadyToSend(Connection* connection) { |
1472 if (connection == best_connection_ && writable()) { | 1482 if (connection == best_connection_ && writable()) { |
1473 SignalReadyToSend(this); | 1483 SignalReadyToSend(this); |
1474 } | 1484 } |
1475 } | 1485 } |
1476 | 1486 |
| 1487 // Find "triggered checks". We ping first those connections that have |
| 1488 // received a ping but have not sent a ping since receiving it |
| 1489 // (last_received_ping > last_sent_ping). But we shouldn't do |
| 1490 // triggered checks if the connection is already writable. |
| 1491 Connection* P2PTransportChannel::FindOldestConnectionNeedingTriggeredCheck( |
| 1492 uint32_t now) { |
| 1493 Connection* oldest_needing_triggered_check = nullptr; |
| 1494 for (auto conn : connections_) { |
| 1495 if (!IsPingable(conn, now)) { |
| 1496 continue; |
| 1497 } |
| 1498 bool needs_triggered_check = |
| 1499 (!conn->writable() && |
| 1500 conn->last_ping_received() > conn->last_ping_sent()); |
| 1501 if (needs_triggered_check && |
| 1502 (!oldest_needing_triggered_check || |
| 1503 (conn->last_ping_received() < |
| 1504 oldest_needing_triggered_check->last_ping_received()))) { |
| 1505 oldest_needing_triggered_check = conn; |
| 1506 } |
| 1507 } |
| 1508 |
| 1509 if (oldest_needing_triggered_check) { |
| 1510 LOG(LS_INFO) << "Selecting connection for triggered check: " |
| 1511 << oldest_needing_triggered_check->ToString(); |
| 1512 } |
| 1513 return oldest_needing_triggered_check; |
| 1514 } |
| 1515 |
| 1516 Connection* P2PTransportChannel::FindConnectionToPing(uint32_t now) { |
| 1517 RTC_CHECK(connections_.size() == |
| 1518 pinged_connections_.size() + unpinged_connections_.size()); |
| 1519 |
| 1520 // If there is nothing pingable in the |unpinged_connections_|, copy |
| 1521 // over from |pinged_connections_|. We do this here such that the |
| 1522 // new connection will take precedence. |
| 1523 if (std::find_if(unpinged_connections_.begin(), unpinged_connections_.end(), |
| 1524 [this, now](Connection* conn) { |
| 1525 return this->IsPingable(conn, now); |
| 1526 }) == unpinged_connections_.end()) { |
| 1527 unpinged_connections_.insert(pinged_connections_.begin(), |
| 1528 pinged_connections_.end()); |
| 1529 pinged_connections_.clear(); |
| 1530 } |
| 1531 |
| 1532 Connection* conn_to_ping = FindOldestConnectionNeedingTriggeredCheck(now); |
| 1533 if (conn_to_ping) { |
| 1534 return conn_to_ping; |
| 1535 } |
| 1536 |
| 1537 for (Connection* conn : unpinged_connections_) { |
| 1538 if (!IsPingable(conn, now)) { |
| 1539 continue; |
| 1540 } |
| 1541 if (!conn_to_ping || |
| 1542 SelectMostPingableConnection(conn_to_ping, conn) == conn) { |
| 1543 conn_to_ping = conn; |
| 1544 } |
| 1545 } |
| 1546 return conn_to_ping; |
| 1547 } |
| 1548 |
| 1549 Connection* P2PTransportChannel::MostLikelyToWork(Connection* conn1, |
| 1550 Connection* conn2) { |
| 1551 bool rr1 = IsRelayRelay(conn1); |
| 1552 bool rr2 = IsRelayRelay(conn2); |
| 1553 if (rr1 && !rr2) { |
| 1554 return conn1; |
| 1555 } else if (rr2 && !rr1) { |
| 1556 return conn2; |
| 1557 } else if (rr1 && rr2) { |
| 1558 bool udp1 = IsUdp(conn1); |
| 1559 bool udp2 = IsUdp(conn2); |
| 1560 if (udp1 && !udp2) { |
| 1561 return conn1; |
| 1562 } else if (udp2 && udp1) { |
| 1563 return conn2; |
| 1564 } |
| 1565 } |
| 1566 return nullptr; |
| 1567 } |
| 1568 |
| 1569 Connection* P2PTransportChannel::LeastRecentlyPinged(Connection* conn1, |
| 1570 Connection* conn2) { |
| 1571 if (conn1->last_ping_sent() < conn2->last_ping_sent()) { |
| 1572 return conn1; |
| 1573 } |
| 1574 if (conn1->last_ping_sent() > conn2->last_ping_sent()) { |
| 1575 return conn2; |
| 1576 } |
| 1577 return nullptr; |
| 1578 } |
| 1579 |
| 1580 Connection* P2PTransportChannel::SelectMostPingableConnection( |
| 1581 Connection* conn1, |
| 1582 Connection* conn2) { |
| 1583 RTC_DCHECK(conn1 != conn2); |
| 1584 if (config_.prioritize_most_likely_candidate_pairs) { |
| 1585 Connection* most_likely_to_work_conn = MostLikelyToWork(conn1, conn2); |
| 1586 if (most_likely_to_work_conn) { |
| 1587 return most_likely_to_work_conn; |
| 1588 } |
| 1589 } |
| 1590 |
| 1591 Connection* least_recently_pinged_conn = LeastRecentlyPinged(conn1, conn2); |
| 1592 if (least_recently_pinged_conn) { |
| 1593 return least_recently_pinged_conn; |
| 1594 } |
| 1595 |
| 1596 // During the initial state when nothing has been pinged yet, return the first |
| 1597 // one in the ordered |connections_|. |
| 1598 return *(std::find_if(connections_.begin(), connections_.end(), |
| 1599 [conn1, conn2](Connection* conn) { |
| 1600 return conn == conn1 || conn == conn2; |
| 1601 })); |
| 1602 } |
| 1603 |
1477 } // namespace cricket | 1604 } // namespace cricket |
OLD | NEW |