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

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

Issue 2099563004: Start ICE connectivity checks as soon as the first pair is pingable. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Start pinging when we first have a connection AND ICE credentials. Created 4 years, 5 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 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 connection->SignalReadPacket.connect( 147 connection->SignalReadPacket.connect(
148 this, &P2PTransportChannel::OnReadPacket); 148 this, &P2PTransportChannel::OnReadPacket);
149 connection->SignalReadyToSend.connect( 149 connection->SignalReadyToSend.connect(
150 this, &P2PTransportChannel::OnReadyToSend); 150 this, &P2PTransportChannel::OnReadyToSend);
151 connection->SignalStateChange.connect( 151 connection->SignalStateChange.connect(
152 this, &P2PTransportChannel::OnConnectionStateChange); 152 this, &P2PTransportChannel::OnConnectionStateChange);
153 connection->SignalDestroyed.connect( 153 connection->SignalDestroyed.connect(
154 this, &P2PTransportChannel::OnConnectionDestroyed); 154 this, &P2PTransportChannel::OnConnectionDestroyed);
155 connection->SignalNominated.connect(this, &P2PTransportChannel::OnNominated); 155 connection->SignalNominated.connect(this, &P2PTransportChannel::OnNominated);
156 had_connection_ = true; 156 had_connection_ = true;
157 // If this is the first connection and we have remote ICE credentials, we can
158 // start pinging.
159 MaybeStartPinging();
157 } 160 }
158 161
159 // Determines whether we should switch the selected connection to 162 // Determines whether we should switch the selected connection to
160 // |new_connection| based the writable/receiving state, the nomination state, 163 // |new_connection| based the writable/receiving state, the nomination state,
161 // and the last data received time. This prevents the controlled side from 164 // and the last data received time. This prevents the controlled side from
162 // switching the selected connection too frequently when the controlling side 165 // switching the selected connection too frequently when the controlling side
163 // is doing aggressive nominations. The precedence of the connection switching 166 // is doing aggressive nominations. The precedence of the connection switching
164 // criteria is as follows: 167 // criteria is as follows:
165 // i) write/receiving/connected states 168 // i) write/receiving/connected states
166 // ii) For controlled side, 169 // ii) For controlled side,
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 } 284 }
282 // We need to update the credentials and generation for any peer reflexive 285 // We need to update the credentials and generation for any peer reflexive
283 // candidates. 286 // candidates.
284 for (Connection* conn : connections_) { 287 for (Connection* conn : connections_) {
285 conn->MaybeSetRemoteIceCredentialsAndGeneration( 288 conn->MaybeSetRemoteIceCredentialsAndGeneration(
286 ice_ufrag, ice_pwd, 289 ice_ufrag, ice_pwd,
287 static_cast<int>(remote_ice_parameters_.size() - 1)); 290 static_cast<int>(remote_ice_parameters_.size() - 1));
288 } 291 }
289 // Updating the remote ICE candidate generation could change the sort order. 292 // Updating the remote ICE candidate generation could change the sort order.
290 RequestSort(); 293 RequestSort();
294 // If this is the first time receiving ICE credentials and we already have a
295 // connection (for example, to a prflx candidate), we can start pinging.
296 MaybeStartPinging();
291 } 297 }
292 298
293 void P2PTransportChannel::SetRemoteIceMode(IceMode mode) { 299 void P2PTransportChannel::SetRemoteIceMode(IceMode mode) {
294 remote_ice_mode_ = mode; 300 remote_ice_mode_ = mode;
295 } 301 }
296 302
297 void P2PTransportChannel::SetIceConfig(const IceConfig& config) { 303 void P2PTransportChannel::SetIceConfig(const IceConfig& config) {
298 config_.gather_continually = config.gather_continually; 304 config_.gather_continually = config.gather_continually;
299 LOG(LS_INFO) << "Set gather_continually to " << config_.gather_continually; 305 LOG(LS_INFO) << "Set gather_continually to " << config_.gather_continually;
300 306
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 LOG(LS_INFO) << "Set presume writable when fully relayed to " 351 LOG(LS_INFO) << "Set presume writable when fully relayed to "
346 << config_.presume_writable_when_fully_relayed; 352 << config_.presume_writable_when_fully_relayed;
347 } 353 }
348 } 354 }
349 } 355 }
350 356
351 const IceConfig& P2PTransportChannel::config() const { 357 const IceConfig& P2PTransportChannel::config() const {
352 return config_; 358 return config_;
353 } 359 }
354 360
355 // Go into the state of processing candidates, and running in general 361 void P2PTransportChannel::MaybeStartGathering() {
356 void P2PTransportChannel::Connect() {
357 ASSERT(worker_thread_ == rtc::Thread::Current());
358 if (ice_ufrag_.empty() || ice_pwd_.empty()) { 362 if (ice_ufrag_.empty() || ice_pwd_.empty()) {
359 ASSERT(false);
360 LOG(LS_ERROR) << "P2PTransportChannel::Connect: The ice_ufrag_ and the "
361 << "ice_pwd_ are not set.";
362 return; 363 return;
363 } 364 }
364
365 // Start checking and pinging as the ports come in.
366 thread()->Post(RTC_FROM_HERE, this, MSG_CHECK_AND_PING);
367 }
368
369 void P2PTransportChannel::MaybeStartGathering() {
370 // Start gathering if we never started before, or if an ICE restart occurred. 365 // Start gathering if we never started before, or if an ICE restart occurred.
371 if (allocator_sessions_.empty() || 366 if (allocator_sessions_.empty() ||
372 IceCredentialsChanged(allocator_sessions_.back()->ice_ufrag(), 367 IceCredentialsChanged(allocator_sessions_.back()->ice_ufrag(),
373 allocator_sessions_.back()->ice_pwd(), ice_ufrag_, 368 allocator_sessions_.back()->ice_pwd(), ice_ufrag_,
374 ice_pwd_)) { 369 ice_pwd_)) {
375 if (gathering_state_ != kIceGatheringGathering) { 370 if (gathering_state_ != kIceGatheringGathering) {
376 gathering_state_ = kIceGatheringGathering; 371 gathering_state_ = kIceGatheringGathering;
377 SignalGatheringState(this); 372 SignalGatheringState(this);
378 } 373 }
379 // Time for a new allocator. 374 // Time for a new allocator.
(...skipping 565 matching lines...) Expand 10 before | Expand all | Expand 10 after
945 } 940 }
946 941
947 // Prepare for best candidate sorting. 942 // Prepare for best candidate sorting.
948 void P2PTransportChannel::RequestSort() { 943 void P2PTransportChannel::RequestSort() {
949 if (!sort_dirty_) { 944 if (!sort_dirty_) {
950 worker_thread_->Post(RTC_FROM_HERE, this, MSG_SORT); 945 worker_thread_->Post(RTC_FROM_HERE, this, MSG_SORT);
951 sort_dirty_ = true; 946 sort_dirty_ = true;
952 } 947 }
953 } 948 }
954 949
950 void P2PTransportChannel::MaybeStartPinging() {
951 if (started_pinging_) {
952 return;
953 }
954
955 int64_t now = rtc::TimeMillis();
956 for (const Connection* c : connections_) {
957 if (IsPingable(c, now)) {
pthatcher1 2016/06/28 01:16:32 Could be slightly more readable with: if (std::no
Taylor Brandstetter 2016/06/28 02:01:42 Done. Though I think: if (any_of) { do_thing();
958 LOG_J(LS_INFO, this) << "Have a pingable connection for the first time; "
959 << "starting to ping.";
960 thread()->Post(RTC_FROM_HERE, this, MSG_CHECK_AND_PING);
961 started_pinging_ = true;
962 return;
963 }
964 }
965 }
966
955 // Compare two connections based on their writing, receiving, and connected 967 // Compare two connections based on their writing, receiving, and connected
956 // states. 968 // states.
957 int P2PTransportChannel::CompareConnectionStates(const Connection* a, 969 int P2PTransportChannel::CompareConnectionStates(const Connection* a,
958 const Connection* b) const { 970 const Connection* b) const {
959 // First, prefer a connection that's writable or presumed writable over 971 // First, prefer a connection that's writable or presumed writable over
960 // one that's not writable. 972 // one that's not writable.
961 bool a_writable = a->writable() || PresumedWritable(a); 973 bool a_writable = a->writable() || PresumedWritable(a);
962 bool b_writable = b->writable() || PresumedWritable(b); 974 bool b_writable = b->writable() || PresumedWritable(b);
963 if (a_writable && !b_writable) { 975 if (a_writable && !b_writable) {
964 return a_is_better; 976 return a_is_better;
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after
1419 PingConnection(conn); 1431 PingConnection(conn);
1420 MarkConnectionPinged(conn); 1432 MarkConnectionPinged(conn);
1421 } 1433 }
1422 } 1434 }
1423 int delay = std::min(ping_interval, check_receiving_interval_); 1435 int delay = std::min(ping_interval, check_receiving_interval_);
1424 thread()->PostDelayed(RTC_FROM_HERE, delay, this, MSG_CHECK_AND_PING); 1436 thread()->PostDelayed(RTC_FROM_HERE, delay, this, MSG_CHECK_AND_PING);
1425 } 1437 }
1426 1438
1427 // A connection is considered a backup connection if the channel state 1439 // A connection is considered a backup connection if the channel state
1428 // is completed, the connection is not the selected connection and it is active. 1440 // is completed, the connection is not the selected connection and it is active.
1429 bool P2PTransportChannel::IsBackupConnection(Connection* conn) const { 1441 bool P2PTransportChannel::IsBackupConnection(const Connection* conn) const {
1430 return state_ == STATE_COMPLETED && conn != selected_connection_ && 1442 return state_ == STATE_COMPLETED && conn != selected_connection_ &&
1431 conn->active(); 1443 conn->active();
1432 } 1444 }
1433 1445
1434 // Is the connection in a state for us to even consider pinging the other side? 1446 // Is the connection in a state for us to even consider pinging the other side?
1435 // We consider a connection pingable even if it's not connected because that's 1447 // We consider a connection pingable even if it's not connected because that's
1436 // how a TCP connection is kicked into reconnecting on the active side. 1448 // how a TCP connection is kicked into reconnecting on the active side.
1437 bool P2PTransportChannel::IsPingable(Connection* conn, int64_t now) { 1449 bool P2PTransportChannel::IsPingable(const Connection* conn,
1450 int64_t now) const {
1438 const Candidate& remote = conn->remote_candidate(); 1451 const Candidate& remote = conn->remote_candidate();
1439 // We should never get this far with an empty remote ufrag. 1452 // We should never get this far with an empty remote ufrag.
1440 ASSERT(!remote.username().empty()); 1453 ASSERT(!remote.username().empty());
1441 if (remote.username().empty() || remote.password().empty()) { 1454 if (remote.username().empty() || remote.password().empty()) {
1442 // If we don't have an ICE ufrag and pwd, there's no way we can ping. 1455 // If we don't have an ICE ufrag and pwd, there's no way we can ping.
1443 return false; 1456 return false;
1444 } 1457 }
1445 1458
1446 // A failed connection will not be pinged. 1459 // A failed connection will not be pinged.
1447 if (conn->state() == Connection::STATE_FAILED) { 1460 if (conn->state() == Connection::STATE_FAILED) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
1485 bool P2PTransportChannel::IsSelectedConnectionPingable(int64_t now) { 1498 bool P2PTransportChannel::IsSelectedConnectionPingable(int64_t now) {
1486 if (!selected_connection_ || !selected_connection_->connected() || 1499 if (!selected_connection_ || !selected_connection_->connected() ||
1487 !selected_connection_->writable()) { 1500 !selected_connection_->writable()) {
1488 return false; 1501 return false;
1489 } 1502 }
1490 1503
1491 int interval = CalculateActiveWritablePingInterval(selected_connection_, now); 1504 int interval = CalculateActiveWritablePingInterval(selected_connection_, now);
1492 return selected_connection_->last_ping_sent() + interval <= now; 1505 return selected_connection_->last_ping_sent() + interval <= now;
1493 } 1506 }
1494 1507
1495 int P2PTransportChannel::CalculateActiveWritablePingInterval(Connection* conn, 1508 int P2PTransportChannel::CalculateActiveWritablePingInterval(
1496 int64_t now) { 1509 const Connection* conn,
1510 int64_t now) const {
1497 // Ping each connection at a higher rate at least 1511 // Ping each connection at a higher rate at least
1498 // MIN_PINGS_AT_WEAK_PING_INTERVAL times. 1512 // MIN_PINGS_AT_WEAK_PING_INTERVAL times.
1499 if (conn->num_pings_sent() < MIN_PINGS_AT_WEAK_PING_INTERVAL) { 1513 if (conn->num_pings_sent() < MIN_PINGS_AT_WEAK_PING_INTERVAL) {
1500 return weak_ping_interval_; 1514 return weak_ping_interval_;
1501 } 1515 }
1502 1516
1503 int stable_interval = config_.stable_writable_connection_ping_interval; 1517 int stable_interval = config_.stable_writable_connection_ping_interval;
1504 int stablizing_interval = 1518 int stablizing_interval =
1505 std::min(stable_interval, STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL); 1519 std::min(stable_interval, STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL);
1506 1520
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
1799 1813
1800 // During the initial state when nothing has been pinged yet, return the first 1814 // During the initial state when nothing has been pinged yet, return the first
1801 // one in the ordered |connections_|. 1815 // one in the ordered |connections_|.
1802 return *(std::find_if(connections_.begin(), connections_.end(), 1816 return *(std::find_if(connections_.begin(), connections_.end(),
1803 [conn1, conn2](Connection* conn) { 1817 [conn1, conn2](Connection* conn) {
1804 return conn == conn1 || conn == conn2; 1818 return conn == conn1 || conn == conn2;
1805 })); 1819 }));
1806 } 1820 }
1807 1821
1808 } // namespace cricket 1822 } // 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