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 1009 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1020 rtc::DiffServCodePoint P2PTransportChannel::DefaultDscpValue() const { | 1020 rtc::DiffServCodePoint P2PTransportChannel::DefaultDscpValue() const { |
1021 OptionMap::const_iterator it = options_.find(rtc::Socket::OPT_DSCP); | 1021 OptionMap::const_iterator it = options_.find(rtc::Socket::OPT_DSCP); |
1022 if (it == options_.end()) { | 1022 if (it == options_.end()) { |
1023 return rtc::DSCP_NO_CHANGE; | 1023 return rtc::DSCP_NO_CHANGE; |
1024 } | 1024 } |
1025 return static_cast<rtc::DiffServCodePoint> (it->second); | 1025 return static_cast<rtc::DiffServCodePoint> (it->second); |
1026 } | 1026 } |
1027 | 1027 |
1028 // Monitor connection states. | 1028 // Monitor connection states. |
1029 void P2PTransportChannel::UpdateConnectionStates() { | 1029 void P2PTransportChannel::UpdateConnectionStates() { |
1030 uint32_t now = rtc::Time(); | 1030 int64_t now = rtc::Time64(); |
1031 | 1031 |
1032 // We need to copy the list of connections since some may delete themselves | 1032 // We need to copy the list of connections since some may delete themselves |
1033 // when we call UpdateState. | 1033 // when we call UpdateState. |
1034 for (size_t i = 0; i < connections_.size(); ++i) | 1034 for (size_t i = 0; i < connections_.size(); ++i) |
1035 connections_[i]->UpdateState(now); | 1035 connections_[i]->UpdateState(now); |
1036 } | 1036 } |
1037 | 1037 |
1038 // Prepare for best candidate sorting. | 1038 // Prepare for best candidate sorting. |
1039 void P2PTransportChannel::RequestSort() { | 1039 void P2PTransportChannel::RequestSort() { |
1040 if (!sort_dirty_) { | 1040 if (!sort_dirty_) { |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1253 } | 1253 } |
1254 | 1254 |
1255 // Handle queued up check-and-ping request | 1255 // Handle queued up check-and-ping request |
1256 void P2PTransportChannel::OnCheckAndPing() { | 1256 void P2PTransportChannel::OnCheckAndPing() { |
1257 // Make sure the states of the connections are up-to-date (since this affects | 1257 // Make sure the states of the connections are up-to-date (since this affects |
1258 // which ones are pingable). | 1258 // which ones are pingable). |
1259 UpdateConnectionStates(); | 1259 UpdateConnectionStates(); |
1260 // When the best connection is either not receiving or not writable, | 1260 // When the best connection is either not receiving or not writable, |
1261 // switch to weak ping interval. | 1261 // switch to weak ping interval. |
1262 int ping_interval = weak() ? weak_ping_interval_ : STRONG_PING_INTERVAL; | 1262 int ping_interval = weak() ? weak_ping_interval_ : STRONG_PING_INTERVAL; |
1263 if (rtc::Time() >= last_ping_sent_ms_ + ping_interval) { | 1263 if (rtc::Time64() >= last_ping_sent_ms_ + ping_interval) { |
1264 Connection* conn = FindNextPingableConnection(); | 1264 Connection* conn = FindNextPingableConnection(); |
1265 if (conn) { | 1265 if (conn) { |
1266 PingConnection(conn); | 1266 PingConnection(conn); |
1267 MarkConnectionPinged(conn); | 1267 MarkConnectionPinged(conn); |
1268 } | 1268 } |
1269 } | 1269 } |
1270 int delay = std::min(ping_interval, check_receiving_interval_); | 1270 int delay = std::min(ping_interval, check_receiving_interval_); |
1271 thread()->PostDelayed(delay, this, MSG_CHECK_AND_PING); | 1271 thread()->PostDelayed(delay, this, MSG_CHECK_AND_PING); |
1272 } | 1272 } |
1273 | 1273 |
1274 // A connection is considered a backup connection if the channel state | 1274 // A connection is considered a backup connection if the channel state |
1275 // is completed, the connection is not the best connection and it is active. | 1275 // is completed, the connection is not the best connection and it is active. |
1276 bool P2PTransportChannel::IsBackupConnection(Connection* conn) const { | 1276 bool P2PTransportChannel::IsBackupConnection(Connection* conn) const { |
1277 return state_ == STATE_COMPLETED && conn != best_connection_ && | 1277 return state_ == STATE_COMPLETED && conn != best_connection_ && |
1278 conn->active(); | 1278 conn->active(); |
1279 } | 1279 } |
1280 | 1280 |
1281 // Is the connection in a state for us to even consider pinging the other side? | 1281 // Is the connection in a state for us to even consider pinging the other side? |
1282 // We consider a connection pingable even if it's not connected because that's | 1282 // We consider a connection pingable even if it's not connected because that's |
1283 // how a TCP connection is kicked into reconnecting on the active side. | 1283 // how a TCP connection is kicked into reconnecting on the active side. |
1284 bool P2PTransportChannel::IsPingable(Connection* conn, uint32_t now) { | 1284 bool P2PTransportChannel::IsPingable(Connection* conn, int64_t now) { |
1285 const Candidate& remote = conn->remote_candidate(); | 1285 const Candidate& remote = conn->remote_candidate(); |
1286 // We should never get this far with an empty remote ufrag. | 1286 // We should never get this far with an empty remote ufrag. |
1287 ASSERT(!remote.username().empty()); | 1287 ASSERT(!remote.username().empty()); |
1288 if (remote.username().empty() || remote.password().empty()) { | 1288 if (remote.username().empty() || remote.password().empty()) { |
1289 // If we don't have an ICE ufrag and pwd, there's no way we can ping. | 1289 // If we don't have an ICE ufrag and pwd, there's no way we can ping. |
1290 return false; | 1290 return false; |
1291 } | 1291 } |
1292 | 1292 |
1293 // An never connected connection cannot be written to at all, so pinging is | 1293 // An never connected connection cannot be written to at all, so pinging is |
1294 // out of the question. However, if it has become WRITABLE, it is in the | 1294 // out of the question. However, if it has become WRITABLE, it is in the |
(...skipping 17 matching lines...) Expand all Loading... |
1312 } | 1312 } |
1313 | 1313 |
1314 // Returns the next pingable connection to ping. This will be the oldest | 1314 // Returns the next pingable connection to ping. This will be the oldest |
1315 // pingable connection unless we have a connected, writable connection that is | 1315 // pingable connection unless we have a connected, writable connection that is |
1316 // past the maximum acceptable ping interval. When reconnecting a TCP | 1316 // past the maximum acceptable ping interval. When reconnecting a TCP |
1317 // connection, the best connection is disconnected, although still WRITABLE | 1317 // connection, the best connection is disconnected, although still WRITABLE |
1318 // while reconnecting. The newly created connection should be selected as the | 1318 // while reconnecting. The newly created connection should be selected as the |
1319 // ping target to become writable instead. See the big comment in | 1319 // ping target to become writable instead. See the big comment in |
1320 // CompareConnections. | 1320 // CompareConnections. |
1321 Connection* P2PTransportChannel::FindNextPingableConnection() { | 1321 Connection* P2PTransportChannel::FindNextPingableConnection() { |
1322 uint32_t now = rtc::Time(); | 1322 int64_t now = rtc::Time64(); |
1323 Connection* conn_to_ping = nullptr; | 1323 Connection* conn_to_ping = nullptr; |
1324 if (best_connection_ && best_connection_->connected() && | 1324 if (best_connection_ && best_connection_->connected() && |
1325 best_connection_->writable() && | 1325 best_connection_->writable() && |
1326 (best_connection_->last_ping_sent() + config_.max_strong_interval <= | 1326 (best_connection_->last_ping_sent() + config_.max_strong_interval <= |
1327 now)) { | 1327 now)) { |
1328 conn_to_ping = best_connection_; | 1328 conn_to_ping = best_connection_; |
1329 } else { | 1329 } else { |
1330 conn_to_ping = FindConnectionToPing(now); | 1330 conn_to_ping = FindConnectionToPing(now); |
1331 } | 1331 } |
1332 return conn_to_ping; | 1332 return conn_to_ping; |
(...skipping 20 matching lines...) Expand all Loading... |
1353 void P2PTransportChannel::PingConnection(Connection* conn) { | 1353 void P2PTransportChannel::PingConnection(Connection* conn) { |
1354 bool use_candidate = false; | 1354 bool use_candidate = false; |
1355 if (remote_ice_mode_ == ICEMODE_FULL && ice_role_ == ICEROLE_CONTROLLING) { | 1355 if (remote_ice_mode_ == ICEMODE_FULL && ice_role_ == ICEROLE_CONTROLLING) { |
1356 use_candidate = (conn == best_connection_) || (best_connection_ == NULL) || | 1356 use_candidate = (conn == best_connection_) || (best_connection_ == NULL) || |
1357 (!best_connection_->writable()) || | 1357 (!best_connection_->writable()) || |
1358 (CompareConnectionCandidates(best_connection_, conn) < 0); | 1358 (CompareConnectionCandidates(best_connection_, conn) < 0); |
1359 } else if (remote_ice_mode_ == ICEMODE_LITE && conn == best_connection_) { | 1359 } else if (remote_ice_mode_ == ICEMODE_LITE && conn == best_connection_) { |
1360 use_candidate = best_connection_->writable(); | 1360 use_candidate = best_connection_->writable(); |
1361 } | 1361 } |
1362 conn->set_use_candidate_attr(use_candidate); | 1362 conn->set_use_candidate_attr(use_candidate); |
1363 last_ping_sent_ms_ = rtc::Time(); | 1363 last_ping_sent_ms_ = rtc::Time64(); |
1364 conn->Ping(last_ping_sent_ms_); | 1364 conn->Ping(last_ping_sent_ms_); |
1365 } | 1365 } |
1366 | 1366 |
1367 // When a connection's state changes, we need to figure out who to use as | 1367 // When a connection's state changes, we need to figure out who to use as |
1368 // the best connection again. It could have become usable, or become unusable. | 1368 // the best connection again. It could have become usable, or become unusable. |
1369 void P2PTransportChannel::OnConnectionStateChange(Connection* connection) { | 1369 void P2PTransportChannel::OnConnectionStateChange(Connection* connection) { |
1370 ASSERT(worker_thread_ == rtc::Thread::Current()); | 1370 ASSERT(worker_thread_ == rtc::Thread::Current()); |
1371 | 1371 |
1372 // Update the best connection if the state change is from pending best | 1372 // Update the best connection if the state change is from pending best |
1373 // connection and role is controlled. | 1373 // connection and role is controlled. |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1501 if (connection == best_connection_ && writable()) { | 1501 if (connection == best_connection_ && writable()) { |
1502 SignalReadyToSend(this); | 1502 SignalReadyToSend(this); |
1503 } | 1503 } |
1504 } | 1504 } |
1505 | 1505 |
1506 // Find "triggered checks". We ping first those connections that have | 1506 // Find "triggered checks". We ping first those connections that have |
1507 // received a ping but have not sent a ping since receiving it | 1507 // received a ping but have not sent a ping since receiving it |
1508 // (last_received_ping > last_sent_ping). But we shouldn't do | 1508 // (last_received_ping > last_sent_ping). But we shouldn't do |
1509 // triggered checks if the connection is already writable. | 1509 // triggered checks if the connection is already writable. |
1510 Connection* P2PTransportChannel::FindOldestConnectionNeedingTriggeredCheck( | 1510 Connection* P2PTransportChannel::FindOldestConnectionNeedingTriggeredCheck( |
1511 uint32_t now) { | 1511 int64_t now) { |
1512 Connection* oldest_needing_triggered_check = nullptr; | 1512 Connection* oldest_needing_triggered_check = nullptr; |
1513 for (auto conn : connections_) { | 1513 for (auto conn : connections_) { |
1514 if (!IsPingable(conn, now)) { | 1514 if (!IsPingable(conn, now)) { |
1515 continue; | 1515 continue; |
1516 } | 1516 } |
1517 bool needs_triggered_check = | 1517 bool needs_triggered_check = |
1518 (!conn->writable() && | 1518 (!conn->writable() && |
1519 conn->last_ping_received() > conn->last_ping_sent()); | 1519 conn->last_ping_received() > conn->last_ping_sent()); |
1520 if (needs_triggered_check && | 1520 if (needs_triggered_check && |
1521 (!oldest_needing_triggered_check || | 1521 (!oldest_needing_triggered_check || |
1522 (conn->last_ping_received() < | 1522 (conn->last_ping_received() < |
1523 oldest_needing_triggered_check->last_ping_received()))) { | 1523 oldest_needing_triggered_check->last_ping_received()))) { |
1524 oldest_needing_triggered_check = conn; | 1524 oldest_needing_triggered_check = conn; |
1525 } | 1525 } |
1526 } | 1526 } |
1527 | 1527 |
1528 if (oldest_needing_triggered_check) { | 1528 if (oldest_needing_triggered_check) { |
1529 LOG(LS_INFO) << "Selecting connection for triggered check: " | 1529 LOG(LS_INFO) << "Selecting connection for triggered check: " |
1530 << oldest_needing_triggered_check->ToString(); | 1530 << oldest_needing_triggered_check->ToString(); |
1531 } | 1531 } |
1532 return oldest_needing_triggered_check; | 1532 return oldest_needing_triggered_check; |
1533 } | 1533 } |
1534 | 1534 |
1535 Connection* P2PTransportChannel::FindConnectionToPing(uint32_t now) { | 1535 Connection* P2PTransportChannel::FindConnectionToPing(int64_t now) { |
1536 RTC_CHECK(connections_.size() == | 1536 RTC_CHECK(connections_.size() == |
1537 pinged_connections_.size() + unpinged_connections_.size()); | 1537 pinged_connections_.size() + unpinged_connections_.size()); |
1538 | 1538 |
1539 // If there is nothing pingable in the |unpinged_connections_|, copy | 1539 // If there is nothing pingable in the |unpinged_connections_|, copy |
1540 // over from |pinged_connections_|. We do this here such that the | 1540 // over from |pinged_connections_|. We do this here such that the |
1541 // new connection will take precedence. | 1541 // new connection will take precedence. |
1542 if (std::find_if(unpinged_connections_.begin(), unpinged_connections_.end(), | 1542 if (std::find_if(unpinged_connections_.begin(), unpinged_connections_.end(), |
1543 [this, now](Connection* conn) { | 1543 [this, now](Connection* conn) { |
1544 return this->IsPingable(conn, now); | 1544 return this->IsPingable(conn, now); |
1545 }) == unpinged_connections_.end()) { | 1545 }) == unpinged_connections_.end()) { |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1614 | 1614 |
1615 // During the initial state when nothing has been pinged yet, return the first | 1615 // During the initial state when nothing has been pinged yet, return the first |
1616 // one in the ordered |connections_|. | 1616 // one in the ordered |connections_|. |
1617 return *(std::find_if(connections_.begin(), connections_.end(), | 1617 return *(std::find_if(connections_.begin(), connections_.end(), |
1618 [conn1, conn2](Connection* conn) { | 1618 [conn1, conn2](Connection* conn) { |
1619 return conn == conn1 || conn == conn2; | 1619 return conn == conn1 || conn == conn2; |
1620 })); | 1620 })); |
1621 } | 1621 } |
1622 | 1622 |
1623 } // namespace cricket | 1623 } // namespace cricket |
OLD | NEW |