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 |
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. If it pings too fast, other |
222 // 2 * STRONG_PING_INTERVAL). | 222 // connection may get starved. |
Taylor Brandstetter
2016/05/27 20:11:00
"connection" -> "connections"
Also, may want to me
| |
223 static const int MAX_CURRENT_STRONG_INTERVAL = 900; // ms | 223 static const int MAX_CURRENT_STRONG_INTERVAL = 900; // ms |
224 | 224 |
225 // Writable connections are pinged at a slower rate. | |
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 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
426 } | 429 } |
427 LOG(LS_INFO) << "Set ICE receiving timeout to " << config_.receiving_timeout | 430 LOG(LS_INFO) << "Set ICE receiving timeout to " << config_.receiving_timeout |
428 << " milliseconds"; | 431 << " milliseconds"; |
429 } | 432 } |
430 | 433 |
431 config_.prioritize_most_likely_candidate_pairs = | 434 config_.prioritize_most_likely_candidate_pairs = |
432 config.prioritize_most_likely_candidate_pairs; | 435 config.prioritize_most_likely_candidate_pairs; |
433 LOG(LS_INFO) << "Set ping most likely connection to " | 436 LOG(LS_INFO) << "Set ping most likely connection to " |
434 << config_.prioritize_most_likely_candidate_pairs; | 437 << config_.prioritize_most_likely_candidate_pairs; |
435 | 438 |
436 if (config.max_strong_interval >= 0 && | 439 if (config.writable_connection_ping_interval >= 0 && |
437 config_.max_strong_interval != config.max_strong_interval) { | 440 config_.writable_connection_ping_interval != |
438 config_.max_strong_interval = config.max_strong_interval; | 441 config.writable_connection_ping_interval) { |
439 LOG(LS_INFO) << "Set max strong interval to " | 442 config_.writable_connection_ping_interval = |
440 << config_.max_strong_interval; | 443 config.writable_connection_ping_interval; |
444 LOG(LS_INFO) << "Set writable_connection_ping_interval to " | |
445 << config_.writable_connection_ping_interval; | |
441 } | 446 } |
442 } | 447 } |
443 | 448 |
444 const IceConfig& P2PTransportChannel::config() const { | 449 const IceConfig& P2PTransportChannel::config() const { |
445 return config_; | 450 return config_; |
446 } | 451 } |
447 | 452 |
448 // Go into the state of processing candidates, and running in general | 453 // Go into the state of processing candidates, and running in general |
449 void P2PTransportChannel::Connect() { | 454 void P2PTransportChannel::Connect() { |
450 ASSERT(worker_thread_ == rtc::Thread::Current()); | 455 ASSERT(worker_thread_ == rtc::Thread::Current()); |
(...skipping 849 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1300 // When the best connection is either not receiving or not writable, | 1305 // When the best connection is either not receiving or not writable, |
1301 // switch to weak ping interval. | 1306 // switch to weak ping interval. |
1302 int ping_interval = weak() ? weak_ping_interval_ : STRONG_PING_INTERVAL; | 1307 int ping_interval = weak() ? weak_ping_interval_ : STRONG_PING_INTERVAL; |
1303 if (rtc::TimeMillis() >= last_ping_sent_ms_ + ping_interval) { | 1308 if (rtc::TimeMillis() >= last_ping_sent_ms_ + ping_interval) { |
1304 Connection* conn = FindNextPingableConnection(); | 1309 Connection* conn = FindNextPingableConnection(); |
1305 if (conn) { | 1310 if (conn) { |
1306 PingConnection(conn); | 1311 PingConnection(conn); |
1307 MarkConnectionPinged(conn); | 1312 MarkConnectionPinged(conn); |
1308 } | 1313 } |
1309 } | 1314 } |
1315 | |
1310 int delay = std::min(ping_interval, check_receiving_interval_); | 1316 int delay = std::min(ping_interval, check_receiving_interval_); |
1311 thread()->PostDelayed(delay, this, MSG_CHECK_AND_PING); | 1317 thread()->PostDelayed(delay, this, MSG_CHECK_AND_PING); |
1312 } | 1318 } |
1313 | 1319 |
1314 // A connection is considered a backup connection if the channel state | 1320 // A connection is considered a backup connection if the channel state |
1315 // is completed, the connection is not the best connection and it is active. | 1321 // is completed, the connection is not the best connection and it is active. |
1316 bool P2PTransportChannel::IsBackupConnection(Connection* conn) const { | 1322 bool P2PTransportChannel::IsBackupConnection(Connection* conn) const { |
1317 return state_ == STATE_COMPLETED && conn != best_connection_ && | 1323 return state_ == STATE_COMPLETED && conn != best_connection_ && |
1318 conn->active(); | 1324 conn->active(); |
1319 } | 1325 } |
1320 | 1326 |
1327 bool P2PTransportChannel::IsBestConnectionPingable() { | |
1328 int64_t now = rtc::TimeMillis(); | |
1329 bool is_pingable = false; | |
1330 if (best_connection_ && best_connection_->connected() && | |
1331 best_connection_->writable()) { | |
1332 // The best_connection need to ping at a fast rate. | |
pthatcher1
2016/05/27 17:36:31
need => needs
| |
1333 is_pingable = | |
1334 (best_connection_->NeedToPingFast() && | |
1335 best_connection_->last_ping_sent() + MAX_CURRENT_STRONG_INTERVAL <= | |
1336 now); | |
1337 | |
1338 // After passing writable_connection_ping_interval, the best connection | |
1339 // becomes pingable no matter if it needs to ping fast or not. | |
1340 is_pingable = | |
1341 is_pingable || (best_connection_->last_ping_sent() + | |
1342 config_.writable_connection_ping_interval <= | |
1343 now); | |
pthatcher1
2016/05/27 17:36:31
This would be more clear with early returns and an
zhihuang1
2016/06/01 21:15:01
writable_connection_ping_interval may be smaller t
| |
1344 } | |
1345 return is_pingable; | |
1346 } | |
1347 | |
1321 // Is the connection in a state for us to even consider pinging the other side? | 1348 // Is the connection in a state for us to even consider pinging the other side? |
1322 // We consider a connection pingable even if it's not connected because that's | 1349 // We consider a connection pingable even if it's not connected because that's |
1323 // how a TCP connection is kicked into reconnecting on the active side. | 1350 // how a TCP connection is kicked into reconnecting on the active side. |
1324 bool P2PTransportChannel::IsPingable(Connection* conn, int64_t now) { | 1351 bool P2PTransportChannel::IsPingable(Connection* conn, int64_t now) { |
1325 const Candidate& remote = conn->remote_candidate(); | 1352 const Candidate& remote = conn->remote_candidate(); |
1326 // We should never get this far with an empty remote ufrag. | 1353 // We should never get this far with an empty remote ufrag. |
1327 ASSERT(!remote.username().empty()); | 1354 ASSERT(!remote.username().empty()); |
1328 if (remote.username().empty() || remote.password().empty()) { | 1355 if (remote.username().empty() || remote.password().empty()) { |
1329 // If we don't have an ICE ufrag and pwd, there's no way we can ping. | 1356 // If we don't have an ICE ufrag and pwd, there's no way we can ping. |
1330 return false; | 1357 return false; |
(...skipping 10 matching lines...) Expand all Loading... | |
1341 if (weak()) { | 1368 if (weak()) { |
1342 return true; | 1369 return true; |
1343 } | 1370 } |
1344 | 1371 |
1345 // Always ping active connections regardless whether the channel is completed | 1372 // Always ping active connections regardless whether the channel is completed |
1346 // or not, but backup connections are pinged at a slower rate. | 1373 // or not, but backup connections are pinged at a slower rate. |
1347 if (IsBackupConnection(conn)) { | 1374 if (IsBackupConnection(conn)) { |
1348 return (now >= conn->last_ping_response_received() + | 1375 return (now >= conn->last_ping_response_received() + |
1349 config_.backup_connection_ping_interval); | 1376 config_.backup_connection_ping_interval); |
1350 } | 1377 } |
1378 | |
1379 // The connect will ping at a slower rate with two conditions: | |
1380 // 1. The connection is writable. | |
1381 // 2. The connection is not sending first several pings | |
Taylor Brandstetter
2016/05/27 20:11:00
"The connect" -> "The connection"
"is not sending
| |
1382 // (kFirstNPingsWithFastRate) | |
1383 if (conn->writable() && !conn->NeedToPingFast()) { | |
1384 return (now >= | |
1385 conn->last_ping_sent() + config_.writable_connection_ping_interval); | |
1386 } | |
1387 | |
1351 return conn->active(); | 1388 return conn->active(); |
1352 } | 1389 } |
1353 | 1390 |
1354 // Returns the next pingable connection to ping. This will be the oldest | 1391 // Returns the next pingable connection to ping. This will be the oldest |
1355 // pingable connection unless we have a connected, writable connection that is | 1392 // pingable connection unless we have a connected, writable connection that is |
1356 // past the maximum acceptable ping interval. When reconnecting a TCP | 1393 // past the writable ping interval. When reconnecting a TCP |
1357 // connection, the best connection is disconnected, although still WRITABLE | 1394 // connection, the best connection is disconnected, although still WRITABLE |
1358 // while reconnecting. The newly created connection should be selected as the | 1395 // while reconnecting. The newly created connection should be selected as the |
1359 // ping target to become writable instead. See the big comment in | 1396 // ping target to become writable instead. See the big comment in |
1360 // CompareConnections. | 1397 // CompareConnections. |
1361 Connection* P2PTransportChannel::FindNextPingableConnection() { | 1398 Connection* P2PTransportChannel::FindNextPingableConnection() { |
1362 int64_t now = rtc::TimeMillis(); | 1399 int64_t now = rtc::TimeMillis(); |
1363 Connection* conn_to_ping = nullptr; | 1400 Connection* conn_to_ping = nullptr; |
1364 if (best_connection_ && best_connection_->connected() && | 1401 if (IsBestConnectionPingable()) { |
1365 best_connection_->writable() && | |
1366 (best_connection_->last_ping_sent() + config_.max_strong_interval <= | |
1367 now)) { | |
1368 conn_to_ping = best_connection_; | 1402 conn_to_ping = best_connection_; |
1369 } else { | 1403 } else { |
1370 conn_to_ping = FindConnectionToPing(now); | 1404 conn_to_ping = FindConnectionToPing(now); |
1371 } | 1405 } |
1372 return conn_to_ping; | 1406 return conn_to_ping; |
1373 } | 1407 } |
1374 | 1408 |
1375 void P2PTransportChannel::MarkConnectionPinged(Connection* conn) { | 1409 void P2PTransportChannel::MarkConnectionPinged(Connection* conn) { |
1376 if (conn && pinged_connections_.insert(conn).second) { | 1410 if (conn && pinged_connections_.insert(conn).second) { |
1377 unpinged_connections_.erase(conn); | 1411 unpinged_connections_.erase(conn); |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1658 | 1692 |
1659 // During the initial state when nothing has been pinged yet, return the first | 1693 // During the initial state when nothing has been pinged yet, return the first |
1660 // one in the ordered |connections_|. | 1694 // one in the ordered |connections_|. |
1661 return *(std::find_if(connections_.begin(), connections_.end(), | 1695 return *(std::find_if(connections_.begin(), connections_.end(), |
1662 [conn1, conn2](Connection* conn) { | 1696 [conn1, conn2](Connection* conn) { |
1663 return conn == conn1 || conn == conn2; | 1697 return conn == conn1 || conn == conn2; |
1664 })); | 1698 })); |
1665 } | 1699 } |
1666 | 1700 |
1667 } // namespace cricket | 1701 } // namespace cricket |
OLD | NEW |