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

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

Issue 1577233006: Implement Turn/Turn first logic for connection selection. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc@master
Patch Set: missed to rename a var Created 4 years, 9 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
« no previous file with comments | « webrtc/p2p/base/p2ptransportchannel.h ('k') | webrtc/p2p/base/p2ptransportchannel_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 13 matching lines...) Expand all
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
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,
241 backup_connection_ping_interval_(0) { 250 0,
251 false,
252 false,
pthatcher1 2016/03/02 20:54:36 Can you put a comment of what these are so it's ea
guoweis_webrtc 2016/03/02 22:10:47 Done.
253 MAX_CURRENT_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
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
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::GetIceConfig() const {
pthatcher1 2016/03/02 20:54:36 Can you make this just config()?
guoweis_webrtc 2016/03/02 22:10:47 Done.
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
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
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
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 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
1257 1285
1258 // If the channel is weakly connected, ping all connections. 1286 // If the channel is weakly connected, ping all connections.
1259 if (weak()) { 1287 if (weak()) {
1260 return true; 1288 return true;
1261 } 1289 }
1262 1290
1263 // Always ping active connections regardless whether the channel is completed 1291 // Always ping active connections regardless whether the channel is completed
1264 // or not, but backup connections are pinged at a slower rate. 1292 // or not, but backup connections are pinged at a slower rate.
1265 if (IsBackupConnection(conn)) { 1293 if (IsBackupConnection(conn)) {
1266 return (now >= conn->last_ping_response_received() + 1294 return (now >= conn->last_ping_response_received() +
1267 backup_connection_ping_interval_); 1295 config_.backup_connection_ping_interval);
1268 } 1296 }
1269 return conn->active(); 1297 return conn->active();
1270 } 1298 }
1271 1299
1272 // Returns the next pingable connection to ping. This will be the oldest 1300 // Returns the next pingable connection to ping. This will be the oldest
1273 // pingable connection unless we have a connected, writable connection that is 1301 // pingable connection unless we have a connected, writable connection that is
1274 // past the maximum acceptable ping delay. When reconnecting a TCP connection, 1302 // past the maximum acceptable ping delay. When reconnecting a TCP connection,
1275 // the best connection is disconnected, although still WRITABLE while 1303 // the best connection is disconnected, although still WRITABLE while
1276 // reconnecting. The newly created connection should be selected as the ping 1304 // reconnecting. The newly created connection should be selected as the ping
1277 // target to become writable instead. See the big comment in CompareConnections. 1305 // target to become writable instead. See the big comment in CompareConnections.
1278 Connection* P2PTransportChannel::FindNextPingableConnection() { 1306 Connection* P2PTransportChannel::FindNextPingableConnection() {
1279 uint32_t now = rtc::Time(); 1307 uint32_t now = rtc::Time();
1308 Connection* conn_to_ping = nullptr;
1280 if (best_connection_ && best_connection_->connected() && 1309 if (best_connection_ && best_connection_->connected() &&
1281 best_connection_->writable() && 1310 best_connection_->writable() &&
1282 (best_connection_->last_ping_sent() + MAX_CURRENT_STRONG_DELAY <= now)) { 1311 (best_connection_->last_ping_sent() + config_.max_strong_delay <= now)) {
1283 return best_connection_; 1312 conn_to_ping = best_connection_;
1313 } else {
1314 conn_to_ping = FindConnectionToPing(now);
1284 } 1315 }
1285 1316 if (conn_to_ping && pinged_connections_.insert(conn_to_ping).second) {
1286 // First, find "triggered checks". We ping first those connections 1317 unpinged_connections_.erase(conn_to_ping);
pthatcher1 2016/03/02 20:54:36 I think it would be more correct to move this to O
guoweis_webrtc 2016/03/02 22:10:47 Done.
1287 // that have received a ping but have not sent a ping since receiving
1288 // it (last_received_ping > last_sent_ping). But we shouldn't do
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 } 1318 }
1309 1319 return conn_to_ping;
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 } 1320 }
1317 1321
1318 // Apart from sending ping from |conn| this method also updates 1322 // Apart from sending ping from |conn| this method also updates
1319 // |use_candidate_attr| flag. The criteria to update this flag is 1323 // |use_candidate_attr| flag. The criteria to update this flag is
1320 // explained below. 1324 // explained below.
1321 // Set USE-CANDIDATE if doing ICE AND this channel is in CONTROLLING AND 1325 // Set USE-CANDIDATE if doing ICE AND this channel is in CONTROLLING AND
1322 // a) Channel is in FULL ICE AND 1326 // a) Channel is in FULL ICE AND
1323 // a.1) |conn| is the best connection OR 1327 // a.1) |conn| is the best connection OR
1324 // a.2) there is no best connection OR 1328 // a.2) there is no best connection OR
1325 // a.3) the best connection is unwritable OR 1329 // a.3) the best connection is unwritable OR
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1375 void P2PTransportChannel::OnConnectionDestroyed(Connection* connection) { 1379 void P2PTransportChannel::OnConnectionDestroyed(Connection* connection) {
1376 ASSERT(worker_thread_ == rtc::Thread::Current()); 1380 ASSERT(worker_thread_ == rtc::Thread::Current());
1377 1381
1378 // Note: the previous best_connection_ may be destroyed by now, so don't 1382 // Note: the previous best_connection_ may be destroyed by now, so don't
1379 // use it. 1383 // use it.
1380 1384
1381 // Remove this connection from the list. 1385 // Remove this connection from the list.
1382 std::vector<Connection*>::iterator iter = 1386 std::vector<Connection*>::iterator iter =
1383 std::find(connections_.begin(), connections_.end(), connection); 1387 std::find(connections_.begin(), connections_.end(), connection);
1384 ASSERT(iter != connections_.end()); 1388 ASSERT(iter != connections_.end());
1389 pinged_connections_.erase(*iter);
1390 unpinged_connections_.erase(*iter);
1385 connections_.erase(iter); 1391 connections_.erase(iter);
1386 1392
1387 LOG_J(LS_INFO, this) << "Removed connection (" 1393 LOG_J(LS_INFO, this) << "Removed connection ("
1388 << static_cast<int>(connections_.size()) << " remaining)"; 1394 << static_cast<int>(connections_.size()) << " remaining)";
1389 1395
1390 if (pending_best_connection_ == connection) { 1396 if (pending_best_connection_ == connection) {
1391 pending_best_connection_ = NULL; 1397 pending_best_connection_ = NULL;
1392 } 1398 }
1393 1399
1394 // If this is currently the best connection, then we need to pick a new one. 1400 // If this is currently the best connection, then we need to pick a new one.
(...skipping 24 matching lines...) Expand all
1419 if (iter != ports_.end()) 1425 if (iter != ports_.end())
1420 ports_.erase(iter); 1426 ports_.erase(iter);
1421 1427
1422 LOG(INFO) << "Removed port from p2p socket: " 1428 LOG(INFO) << "Removed port from p2p socket: "
1423 << static_cast<int>(ports_.size()) << " remaining"; 1429 << static_cast<int>(ports_.size()) << " remaining";
1424 } 1430 }
1425 1431
1426 void P2PTransportChannel::OnPortNetworkInactive(PortInterface* port) { 1432 void P2PTransportChannel::OnPortNetworkInactive(PortInterface* port) {
1427 // If it does not gather continually, the port will be removed from the list 1433 // If it does not gather continually, the port will be removed from the list
1428 // when ICE restarts. 1434 // when ICE restarts.
1429 if (!gather_continually_) { 1435 if (!config_.gather_continually) {
1430 return; 1436 return;
1431 } 1437 }
1432 auto it = std::find(ports_.begin(), ports_.end(), port); 1438 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. 1439 // Don't need to do anything if the port has been deleted from the port list.
1434 if (it == ports_.end()) { 1440 if (it == ports_.end()) {
1435 return; 1441 return;
1436 } 1442 }
1437 ports_.erase(it); 1443 ports_.erase(it);
1438 LOG(INFO) << "Removed port due to inactive networks: " << ports_.size() 1444 LOG(INFO) << "Removed port due to inactive networks: " << ports_.size()
1439 << " remaining"; 1445 << " remaining";
(...skipping 27 matching lines...) Expand all
1467 1473
1468 SignalSentPacket(this, sent_packet); 1474 SignalSentPacket(this, sent_packet);
1469 } 1475 }
1470 1476
1471 void P2PTransportChannel::OnReadyToSend(Connection* connection) { 1477 void P2PTransportChannel::OnReadyToSend(Connection* connection) {
1472 if (connection == best_connection_ && writable()) { 1478 if (connection == best_connection_ && writable()) {
1473 SignalReadyToSend(this); 1479 SignalReadyToSend(this);
1474 } 1480 }
1475 } 1481 }
1476 1482
1483 // Find "triggered checks". We ping first those connections that have
1484 // received a ping but have not sent a ping since receiving it
1485 // (last_received_ping > last_sent_ping). But we shouldn't do
1486 // triggered checks if the connection is already writable.
1487 Connection* P2PTransportChannel::FindOldestConnectionNeedingTriggeredCheck(
1488 uint32_t now) {
1489 Connection* oldest_needing_triggered_check = nullptr;
1490 for (auto conn : connections_) {
1491 if (!IsPingable(conn, now)) {
1492 continue;
1493 }
1494 bool needs_triggered_check =
1495 (!conn->writable() &&
1496 conn->last_ping_received() > conn->last_ping_sent());
1497 if (needs_triggered_check &&
1498 (!oldest_needing_triggered_check ||
1499 (conn->last_ping_received() <
1500 oldest_needing_triggered_check->last_ping_received()))) {
1501 oldest_needing_triggered_check = conn;
1502 }
1503 }
1504
1505 if (oldest_needing_triggered_check) {
1506 LOG(LS_INFO) << "Selecting connection for triggered check: "
1507 << oldest_needing_triggered_check->ToString();
1508 }
1509 return oldest_needing_triggered_check;
1510 }
1511
1512 Connection* P2PTransportChannel::FindConnectionToPing(uint32_t now) {
1513 RTC_CHECK(connections_.size() ==
1514 pinged_connections_.size() + unpinged_connections_.size());
1515
1516 // If there is nothing pingable in the |unpinged_connections_|, copy over from
1517 // |pinged_connections_|.
1518 if (std::find_if(unpinged_connections_.begin(), unpinged_connections_.end(),
1519 [this, now](Connection* conn) {
1520 return this->IsPingable(conn, now);
1521 }) == unpinged_connections_.end()) {
1522 unpinged_connections_.insert(pinged_connections_.begin(),
1523 pinged_connections_.end());
1524 pinged_connections_.clear();
1525 }
pthatcher1 2016/03/02 20:54:36 I think this should also happen in OnCheckAndPing.
guoweis_webrtc 2016/03/02 22:10:47 I put it here on purpose such that if we get a new
1526
1527 Connection* conn_to_ping = FindOldestConnectionNeedingTriggeredCheck(now);
1528 if (conn_to_ping) {
1529 return conn_to_ping;
1530 }
1531
1532 for (Connection* conn : unpinged_connections_) {
1533 if (!IsPingable(conn, now)) {
1534 continue;
1535 }
1536 if (!conn_to_ping ||
1537 SelectMorePingableConnection(conn_to_ping, conn) == conn) {
1538 conn_to_ping = conn;
1539 }
1540 }
1541 return conn_to_ping;
1542 }
1543
1544 Connection* P2PTransportChannel::MostLikelyToWork(Connection* conn1,
1545 Connection* conn2) {
1546 bool rr1 = IsRelayRelay(conn1);
1547 bool rr2 = IsRelayRelay(conn2);
1548 if (rr1 && !rr2) {
1549 return conn1;
1550 } else if (rr2 && !rr1) {
1551 return conn2;
1552 } else if (rr1 && rr2) {
1553 bool udp1 = IsUdp(conn1);
1554 bool udp2 = IsUdp(conn2);
1555 if (udp1 && !udp2) {
1556 return conn1;
1557 } else if (udp2 && udp1) {
1558 return conn2;
1559 }
1560 }
1561 return nullptr;
1562 }
1563
1564 Connection* P2PTransportChannel::LeastRecentlyPinged(Connection* conn1,
1565 Connection* conn2) {
1566 if (conn1->last_ping_sent() < conn2->last_ping_sent()) {
1567 return conn1;
1568 }
1569 if (conn1->last_ping_sent() > conn2->last_ping_sent()) {
1570 return conn2;
1571 }
1572 return nullptr;
1573 }
1574
1575 Connection* P2PTransportChannel::SelectMorePingableConnection(
pthatcher1 2016/03/02 20:54:36 To keep up with your naming conventions, this shou
guoweis_webrtc 2016/03/02 22:10:47 Done.
1576 Connection* conn1,
1577 Connection* conn2) {
1578 RTC_DCHECK(conn1 != conn2);
1579 if (config_.prioritize_most_likely_candidate_pairs) {
1580 Connection* most_likely_to_work_conn = MostLikelyToWork(conn1, conn2);
1581 if (most_likely_to_work_conn) {
1582 return most_likely_to_work_conn;
1583 }
1584 }
1585
1586 Connection* least_recently_pinged_conn = LeastRecentlyPinged(conn1, conn2);
1587 if (least_recently_pinged_conn) {
1588 return least_recently_pinged_conn;
1589 }
1590
1591 // During the initial state when nothing has been pinged yet, return the first
1592 // one in the ordered |connections_|.
1593 return *(std::find_if(connections_.begin(), connections_.end(),
1594 [conn1, conn2](Connection* conn) {
1595 return conn == conn1 || conn == conn2;
1596 }));
1597 }
1598
1477 } // namespace cricket 1599 } // namespace cricket
OLDNEW
« no previous file with comments | « webrtc/p2p/base/p2ptransportchannel.h ('k') | webrtc/p2p/base/p2ptransportchannel_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698