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

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: Fix test cases 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 /* 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
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::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
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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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