| 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 |