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 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
210 // well on a 28.8K modem, which is the slowest connection on which the voice | 210 // well on a 28.8K modem, which is the slowest connection on which the voice |
211 // quality is reasonable at all. | 211 // quality is reasonable at all. |
212 static const int PING_PACKET_SIZE = 60 * 8; | 212 static const int PING_PACKET_SIZE = 60 * 8; |
213 // STRONG_PING_INTERVAL (480ms) is applied when the best connection is both | 213 // STRONG_PING_INTERVAL (480ms) is applied when the best connection is both |
214 // writable and receiving. | 214 // writable and receiving. |
215 static const int STRONG_PING_INTERVAL = 1000 * PING_PACKET_SIZE / 1000; | 215 static const int STRONG_PING_INTERVAL = 1000 * PING_PACKET_SIZE / 1000; |
216 // WEAK_PING_INTERVAL (48ms) is applied when the best connection is either not | 216 // WEAK_PING_INTERVAL (48ms) is applied when the best connection is either not |
217 // writable or not receiving. | 217 // writable or not receiving. |
218 const int WEAK_PING_INTERVAL = 1000 * PING_PACKET_SIZE / 10000; | 218 const int WEAK_PING_INTERVAL = 1000 * PING_PACKET_SIZE / 10000; |
219 | 219 |
220 // If the current best connection is both writable and receiving, then we will | 220 // If the current best connection is both writable and receiving, first several |
pthatcher1
2016/06/01 23:22:02
first several pings => the first several pings
| |
221 // also try hard to make sure it is pinged at this rate (a little less than | 221 // pings will be sent at this rate by default in order for the RTT to converge |
pthatcher1
2016/06/01 23:22:02
This is for all connections, not just the best con
| |
222 // 2 * STRONG_PING_INTERVAL). | 222 // faster. If it pings too fast, other connections may get starved. |
pthatcher1
2016/06/01 23:22:02
Doesn't this apply to all connections, not just th
| |
223 static const int MAX_CURRENT_STRONG_INTERVAL = 900; // ms | 223 static const int MAX_CURRENT_STRONG_INTERVAL = 900; // ms |
pthatcher1
2016/06/01 23:22:02
This needs to be renamed now.
Perhaps:
STABLIZIN
| |
224 | 224 |
225 // Writable connections are pinged at a slower rate. | |
pthatcher1
2016/06/01 23:22:03
once stablized
| |
226 static const int WRITABLE_CONNECTION_PING_INTERVAL = 2500; // ms | |
227 | |
225 static const int MIN_CHECK_RECEIVING_INTERVAL = 50; // ms | 228 static const int MIN_CHECK_RECEIVING_INTERVAL = 50; // ms |
226 | 229 |
227 P2PTransportChannel::P2PTransportChannel(const std::string& transport_name, | 230 P2PTransportChannel::P2PTransportChannel(const std::string& transport_name, |
228 int component, | 231 int component, |
229 P2PTransport* transport, | 232 P2PTransport* transport, |
230 PortAllocator* allocator) | 233 PortAllocator* allocator) |
231 : P2PTransportChannel(transport_name, component, allocator) {} | 234 : P2PTransportChannel(transport_name, component, allocator) {} |
232 | 235 |
233 P2PTransportChannel::P2PTransportChannel(const std::string& transport_name, | 236 P2PTransportChannel::P2PTransportChannel(const std::string& transport_name, |
234 int component, | 237 int component, |
235 PortAllocator* allocator) | 238 PortAllocator* allocator) |
236 : TransportChannelImpl(transport_name, component), | 239 : TransportChannelImpl(transport_name, component), |
237 allocator_(allocator), | 240 allocator_(allocator), |
238 worker_thread_(rtc::Thread::Current()), | 241 worker_thread_(rtc::Thread::Current()), |
239 incoming_only_(false), | 242 incoming_only_(false), |
240 error_(0), | 243 error_(0), |
241 best_connection_(NULL), | 244 best_connection_(NULL), |
242 pending_best_connection_(NULL), | 245 pending_best_connection_(NULL), |
243 sort_dirty_(false), | 246 sort_dirty_(false), |
244 remote_ice_mode_(ICEMODE_FULL), | 247 remote_ice_mode_(ICEMODE_FULL), |
245 ice_role_(ICEROLE_UNKNOWN), | 248 ice_role_(ICEROLE_UNKNOWN), |
246 tiebreaker_(0), | 249 tiebreaker_(0), |
247 gathering_state_(kIceGatheringNew), | 250 gathering_state_(kIceGatheringNew), |
248 check_receiving_interval_(MIN_CHECK_RECEIVING_INTERVAL * 5), | 251 check_receiving_interval_(MIN_CHECK_RECEIVING_INTERVAL * 5), |
249 config_(MIN_CHECK_RECEIVING_INTERVAL * 50 /* receiving_timeout */, | 252 config_(MIN_CHECK_RECEIVING_INTERVAL * 50 /* receiving_timeout */, |
250 0 /* backup_connection_ping_interval */, | 253 0 /* backup_connection_ping_interval */, |
251 false /* gather_continually */, | 254 false /* gather_continually */, |
252 false /* prioritize_most_likely_candidate_pairs */, | 255 false /* prioritize_most_likely_candidate_pairs */, |
253 MAX_CURRENT_STRONG_INTERVAL /* max_strong_interval */) { | 256 WRITABLE_CONNECTION_PING_INTERVAL) { |
254 uint32_t weak_ping_interval = ::strtoul( | 257 uint32_t weak_ping_interval = ::strtoul( |
255 webrtc::field_trial::FindFullName("WebRTC-StunInterPacketDelay").c_str(), | 258 webrtc::field_trial::FindFullName("WebRTC-StunInterPacketDelay").c_str(), |
256 nullptr, 10); | 259 nullptr, 10); |
257 if (weak_ping_interval) { | 260 if (weak_ping_interval) { |
258 weak_ping_interval_ = static_cast<int>(weak_ping_interval); | 261 weak_ping_interval_ = static_cast<int>(weak_ping_interval); |
259 } | 262 } |
260 } | 263 } |
261 | 264 |
262 P2PTransportChannel::~P2PTransportChannel() { | 265 P2PTransportChannel::~P2PTransportChannel() { |
263 ASSERT(worker_thread_ == rtc::Thread::Current()); | 266 ASSERT(worker_thread_ == rtc::Thread::Current()); |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
425 } | 428 } |
426 LOG(LS_INFO) << "Set ICE receiving timeout to " << config_.receiving_timeout | 429 LOG(LS_INFO) << "Set ICE receiving timeout to " << config_.receiving_timeout |
427 << " milliseconds"; | 430 << " milliseconds"; |
428 } | 431 } |
429 | 432 |
430 config_.prioritize_most_likely_candidate_pairs = | 433 config_.prioritize_most_likely_candidate_pairs = |
431 config.prioritize_most_likely_candidate_pairs; | 434 config.prioritize_most_likely_candidate_pairs; |
432 LOG(LS_INFO) << "Set ping most likely connection to " | 435 LOG(LS_INFO) << "Set ping most likely connection to " |
433 << config_.prioritize_most_likely_candidate_pairs; | 436 << config_.prioritize_most_likely_candidate_pairs; |
434 | 437 |
435 if (config.max_strong_interval >= 0 && | 438 if (config.writable_connection_ping_interval >= 0 && |
436 config_.max_strong_interval != config.max_strong_interval) { | 439 config_.writable_connection_ping_interval != |
437 config_.max_strong_interval = config.max_strong_interval; | 440 config.writable_connection_ping_interval) { |
438 LOG(LS_INFO) << "Set max strong interval to " | 441 config_.writable_connection_ping_interval = |
439 << config_.max_strong_interval; | 442 config.writable_connection_ping_interval; |
443 LOG(LS_INFO) << "Set writable_connection_ping_interval to " | |
444 << config_.writable_connection_ping_interval; | |
440 } | 445 } |
441 } | 446 } |
442 | 447 |
443 const IceConfig& P2PTransportChannel::config() const { | 448 const IceConfig& P2PTransportChannel::config() const { |
444 return config_; | 449 return config_; |
445 } | 450 } |
446 | 451 |
447 // Go into the state of processing candidates, and running in general | 452 // Go into the state of processing candidates, and running in general |
448 void P2PTransportChannel::Connect() { | 453 void P2PTransportChannel::Connect() { |
449 ASSERT(worker_thread_ == rtc::Thread::Current()); | 454 ASSERT(worker_thread_ == rtc::Thread::Current()); |
(...skipping 890 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1340 int ping_interval = (weak() || need_more_pings_at_weak_interval) | 1345 int ping_interval = (weak() || need_more_pings_at_weak_interval) |
1341 ? weak_ping_interval_ | 1346 ? weak_ping_interval_ |
1342 : STRONG_PING_INTERVAL; | 1347 : STRONG_PING_INTERVAL; |
1343 if (rtc::TimeMillis() >= last_ping_sent_ms_ + ping_interval) { | 1348 if (rtc::TimeMillis() >= last_ping_sent_ms_ + ping_interval) { |
1344 Connection* conn = FindNextPingableConnection(); | 1349 Connection* conn = FindNextPingableConnection(); |
1345 if (conn) { | 1350 if (conn) { |
1346 PingConnection(conn); | 1351 PingConnection(conn); |
1347 MarkConnectionPinged(conn); | 1352 MarkConnectionPinged(conn); |
1348 } | 1353 } |
1349 } | 1354 } |
1355 | |
1350 int delay = std::min(ping_interval, check_receiving_interval_); | 1356 int delay = std::min(ping_interval, check_receiving_interval_); |
1351 thread()->PostDelayed(delay, this, MSG_CHECK_AND_PING); | 1357 thread()->PostDelayed(delay, this, MSG_CHECK_AND_PING); |
1352 } | 1358 } |
1353 | 1359 |
1354 // A connection is considered a backup connection if the channel state | 1360 // A connection is considered a backup connection if the channel state |
1355 // is completed, the connection is not the best connection and it is active. | 1361 // is completed, the connection is not the best connection and it is active. |
1356 bool P2PTransportChannel::IsBackupConnection(Connection* conn) const { | 1362 bool P2PTransportChannel::IsBackupConnection(Connection* conn) const { |
1357 return state_ == STATE_COMPLETED && conn != best_connection_ && | 1363 return state_ == STATE_COMPLETED && conn != best_connection_ && |
1358 conn->active(); | 1364 conn->active(); |
1359 } | 1365 } |
1360 | 1366 |
1367 bool P2PTransportChannel::IsBestConnectionPingable() { | |
1368 if (!best_connection_ || !best_connection_->connected() || | |
1369 !best_connection_->writable()) { | |
1370 return false; | |
1371 } | |
1372 | |
1373 int interval = NeedToPingFast(best_connection_) | |
1374 ? std::min(MAX_CURRENT_STRONG_INTERVAL, | |
1375 config_.writable_connection_ping_interval) | |
1376 : config_.writable_connection_ping_interval; | |
1377 return best_connection_->last_ping_sent() + interval <= rtc::TimeMillis(); | |
1378 } | |
1379 | |
1380 bool P2PTransportChannel::NeedToPingFast(Connection* conn) { | |
pthatcher1
2016/06/01 23:22:02
This the code I wrote below, I think we don't need
honghaiz3
2016/06/02 00:03:57
Cannot do this.
If the best_connection becomes un
pthatcher1
2016/06/02 18:03:02
Good catch. How about best_connection_ && best_co
honghaiz3
2016/06/02 19:20:25
That would work. It is more readable although at t
| |
1381 return conn->num_pings_sent() <= MIN_PINGS_FOR_RTT_CONVERGENCE; | |
1382 } | |
1383 | |
1361 // Is the connection in a state for us to even consider pinging the other side? | 1384 // Is the connection in a state for us to even consider pinging the other side? |
1362 // We consider a connection pingable even if it's not connected because that's | 1385 // We consider a connection pingable even if it's not connected because that's |
1363 // how a TCP connection is kicked into reconnecting on the active side. | 1386 // how a TCP connection is kicked into reconnecting on the active side. |
1364 bool P2PTransportChannel::IsPingable(Connection* conn, int64_t now) { | 1387 bool P2PTransportChannel::IsPingable(Connection* conn, int64_t now) { |
1365 const Candidate& remote = conn->remote_candidate(); | 1388 const Candidate& remote = conn->remote_candidate(); |
1366 // We should never get this far with an empty remote ufrag. | 1389 // We should never get this far with an empty remote ufrag. |
1367 ASSERT(!remote.username().empty()); | 1390 ASSERT(!remote.username().empty()); |
1368 if (remote.username().empty() || remote.password().empty()) { | 1391 if (remote.username().empty() || remote.password().empty()) { |
1369 // If we don't have an ICE ufrag and pwd, there's no way we can ping. | 1392 // If we don't have an ICE ufrag and pwd, there's no way we can ping. |
1370 return false; | 1393 return false; |
(...skipping 10 matching lines...) Expand all Loading... | |
1381 if (weak()) { | 1404 if (weak()) { |
1382 return true; | 1405 return true; |
1383 } | 1406 } |
1384 | 1407 |
1385 // Always ping active connections regardless whether the channel is completed | 1408 // Always ping active connections regardless whether the channel is completed |
1386 // or not, but backup connections are pinged at a slower rate. | 1409 // or not, but backup connections are pinged at a slower rate. |
1387 if (IsBackupConnection(conn)) { | 1410 if (IsBackupConnection(conn)) { |
1388 return (now >= conn->last_ping_response_received() + | 1411 return (now >= conn->last_ping_response_received() + |
1389 config_.backup_connection_ping_interval); | 1412 config_.backup_connection_ping_interval); |
1390 } | 1413 } |
1414 | |
pthatcher1
2016/06/01 23:22:02
I think instead of having NeedsToPingFast, we can
honghaiz3
2016/06/02 00:03:57
look good to me. This is just
int ping_interval =
honghaiz3
2016/06/02 17:06:25
As I thought more about it, I think it may not be
pthatcher1
2016/06/02 18:03:02
Yes, except you still need the std::min in there i
pthatcher1
2016/06/02 18:03:02
Yes, that's the tradeoff with low-frequency keep-a
honghaiz3
2016/06/02 19:20:25
I did not realize that we may have a case of writa
| |
1415 // The connection will ping at a slower rate with two conditions: | |
1416 // 1. The connection is writable. | |
1417 // 2. The connection has sent enough initial pings for RTT to converge. | |
1418 if (conn->writable() && !NeedToPingFast(conn)) { | |
1419 return (now >= | |
1420 conn->last_ping_sent() + config_.writable_connection_ping_interval); | |
1421 } | |
1422 | |
1391 return conn->active(); | 1423 return conn->active(); |
1392 } | 1424 } |
1393 | 1425 |
1394 // Returns the next pingable connection to ping. This will be the oldest | 1426 // Returns the next pingable connection to ping. This will be the oldest |
1395 // pingable connection unless we have a connected, writable connection that is | 1427 // pingable connection unless we have a connected, writable connection that is |
1396 // past the maximum acceptable ping interval. When reconnecting a TCP | 1428 // past the writable ping interval. When reconnecting a TCP |
1397 // connection, the best connection is disconnected, although still WRITABLE | 1429 // connection, the best connection is disconnected, although still WRITABLE |
1398 // while reconnecting. The newly created connection should be selected as the | 1430 // while reconnecting. The newly created connection should be selected as the |
1399 // ping target to become writable instead. See the big comment in | 1431 // ping target to become writable instead. See the big comment in |
1400 // CompareConnections. | 1432 // CompareConnections. |
1401 Connection* P2PTransportChannel::FindNextPingableConnection() { | 1433 Connection* P2PTransportChannel::FindNextPingableConnection() { |
1402 int64_t now = rtc::TimeMillis(); | 1434 int64_t now = rtc::TimeMillis(); |
1403 Connection* conn_to_ping = nullptr; | 1435 Connection* conn_to_ping = nullptr; |
1404 if (best_connection_ && best_connection_->connected() && | 1436 if (IsBestConnectionPingable()) { |
1405 best_connection_->writable() && | |
1406 (best_connection_->last_ping_sent() + config_.max_strong_interval <= | |
1407 now)) { | |
1408 conn_to_ping = best_connection_; | 1437 conn_to_ping = best_connection_; |
1409 } else { | 1438 } else { |
1410 conn_to_ping = FindConnectionToPing(now); | 1439 conn_to_ping = FindConnectionToPing(now); |
1411 } | 1440 } |
1412 return conn_to_ping; | 1441 return conn_to_ping; |
1413 } | 1442 } |
1414 | 1443 |
1415 void P2PTransportChannel::MarkConnectionPinged(Connection* conn) { | 1444 void P2PTransportChannel::MarkConnectionPinged(Connection* conn) { |
1416 if (conn && pinged_connections_.insert(conn).second) { | 1445 if (conn && pinged_connections_.insert(conn).second) { |
1417 unpinged_connections_.erase(conn); | 1446 unpinged_connections_.erase(conn); |
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1695 | 1724 |
1696 // During the initial state when nothing has been pinged yet, return the first | 1725 // During the initial state when nothing has been pinged yet, return the first |
1697 // one in the ordered |connections_|. | 1726 // one in the ordered |connections_|. |
1698 return *(std::find_if(connections_.begin(), connections_.end(), | 1727 return *(std::find_if(connections_.begin(), connections_.end(), |
1699 [conn1, conn2](Connection* conn) { | 1728 [conn1, conn2](Connection* conn) { |
1700 return conn == conn1 || conn == conn2; | 1729 return conn == conn1 || conn == conn2; |
1701 })); | 1730 })); |
1702 } | 1731 } |
1703 | 1732 |
1704 } // namespace cricket | 1733 } // namespace cricket |
OLD | NEW |