Propagate clock into BasicIceController
Bug: webrtc:42223992
Change-Id: I15e4d1a8c692e8a04f50d0f0b51cabecc584b0ab
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/407100
Reviewed-by: Per Kjellander <perkj@webrtc.org>
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#45508}
diff --git a/p2p/BUILD.gn b/p2p/BUILD.gn
index ba483b7..2baa0e2 100644
--- a/p2p/BUILD.gn
+++ b/p2p/BUILD.gn
@@ -81,7 +81,10 @@
":transport_description",
"../api:array_view",
"../api:candidate",
+ "../api/environment",
"../api/transport:enums",
+ "../api/units:time_delta",
+ "../api/units:timestamp",
"../rtc_base:checks",
"../rtc_base:ip_address",
"../rtc_base:logging",
@@ -386,6 +389,7 @@
":ice_transport_internal",
":p2p_transport_channel_ice_field_trials",
":transport_description",
+ "../api/environment",
]
}
diff --git a/p2p/base/basic_ice_controller.cc b/p2p/base/basic_ice_controller.cc
index ca8f826..8da13f5 100644
--- a/p2p/base/basic_ice_controller.cc
+++ b/p2p/base/basic_ice_controller.cc
@@ -22,6 +22,8 @@
#include "absl/algorithm/container.h"
#include "api/candidate.h"
#include "api/transport/enums.h"
+#include "api/units/time_delta.h"
+#include "api/units/timestamp.h"
#include "p2p/base/connection.h"
#include "p2p/base/connection_info.h"
#include "p2p/base/ice_controller_factory_interface.h"
@@ -36,7 +38,6 @@
#include "rtc_base/net_helper.h"
#include "rtc_base/network.h"
#include "rtc_base/network_constants.h"
-#include "rtc_base/time_utils.h"
namespace {
@@ -86,7 +87,8 @@
namespace webrtc {
BasicIceController::BasicIceController(const IceControllerFactoryArgs& args)
- : ice_transport_state_func_(args.ice_transport_state_func),
+ : env_(args.env),
+ ice_transport_state_func_(args.ice_transport_state_func),
ice_role_func_(args.ice_role_func),
is_connection_pruned_func_(args.is_connection_pruned_func),
field_trials_(args.ice_field_trials) {}
@@ -116,7 +118,7 @@
}
bool BasicIceController::HasPingableConnection() const {
- int64_t now = TimeMillis();
+ Timestamp now = Connection::AlignTime(env_.clock().CurrentTime());
return absl::c_any_of(connections_, [this, now](const Connection* c) {
return IsPingable(c, now);
});
@@ -137,7 +139,8 @@
: strong_ping_interval();
const Connection* conn = nullptr;
- if (TimeMillis() >= last_ping_sent_ms + ping_interval) {
+ if (Connection::AlignTime(env_.clock().CurrentTime()).ms() >=
+ last_ping_sent_ms + ping_interval) {
conn = FindNextPingableConnection();
}
PingResult res(conn, std::min(ping_interval, check_receiving_interval()));
@@ -152,7 +155,7 @@
// Returns the next pingable connection to ping.
const Connection* BasicIceController::FindNextPingableConnection() {
- int64_t now = TimeMillis();
+ Timestamp now = Connection::AlignTime(env_.clock().CurrentTime());
// Rule 1: Selected connection takes priority over non-selected ones.
if (selected_connection_ && selected_connection_->connected() &&
@@ -238,7 +241,7 @@
// (last_ping_received > last_ping_sent). But we shouldn't do
// triggered checks if the connection is already writable.
const Connection* BasicIceController::FindOldestConnectionNeedingTriggeredCheck(
- int64_t now) {
+ Timestamp now) {
const Connection* oldest_needing_triggered_check = nullptr;
for (auto* conn : connections_) {
if (!IsPingable(conn, now)) {
@@ -264,24 +267,24 @@
bool BasicIceController::WritableConnectionPastPingInterval(
const Connection* conn,
- int64_t now) const {
- int interval = CalculateActiveWritablePingInterval(conn, now);
- return conn->last_ping_sent() + interval <= now;
+ Timestamp now) const {
+ TimeDelta interval = CalculateActiveWritablePingInterval(conn, now);
+ return conn->LastPingSent() + interval <= now;
}
-int BasicIceController::CalculateActiveWritablePingInterval(
+TimeDelta BasicIceController::CalculateActiveWritablePingInterval(
const Connection* conn,
- int64_t now) const {
+ Timestamp now) const {
// Ping each connection at a higher rate at least
// MIN_PINGS_AT_WEAK_PING_INTERVAL times.
if (conn->num_pings_sent() < MIN_PINGS_AT_WEAK_PING_INTERVAL) {
- return weak_ping_interval();
+ return TimeDelta::Millis(weak_ping_interval());
}
- int stable_interval =
- config_.stable_writable_connection_ping_interval_or_default();
- int weak_or_stablizing_interval = std::min(
- stable_interval, WEAK_OR_STABILIZING_WRITABLE_CONNECTION_PING_INTERVAL);
+ TimeDelta stable_interval = TimeDelta::Millis(
+ config_.stable_writable_connection_ping_interval_or_default());
+ TimeDelta weak_or_stablizing_interval = std::min(
+ stable_interval, kWeakOrStabilizingWritableConnectionPingInterval);
// If the channel is weak or the connection is not stable yet, use the
// weak_or_stablizing_interval.
return (!weak() && conn->stable(now)) ? stable_interval
@@ -291,7 +294,8 @@
// Is the connection in a state for us to even consider pinging the other side?
// We consider a connection pingable even if it's not connected because that's
// how a TCP connection is kicked into reconnecting on the active side.
-bool BasicIceController::IsPingable(const Connection* conn, int64_t now) const {
+bool BasicIceController::IsPingable(const Connection* conn,
+ Timestamp now) const {
const Candidate& remote = conn->remote_candidate();
// We should never get this far with an empty remote ufrag.
RTC_DCHECK(!remote.username().empty());
@@ -327,8 +331,10 @@
// or not, but backup connections are pinged at a slower rate.
if (IsBackupConnection(conn)) {
return conn->rtt_samples() == 0 ||
- (now >= conn->last_ping_response_received() +
- config_.backup_connection_ping_interval_or_default());
+ (now >=
+ conn->LastPingResponseReceived() +
+ TimeDelta::Millis(
+ config_.backup_connection_ping_interval_or_default()));
}
// Don't ping inactive non-backup connections.
if (!conn->active()) {
@@ -452,7 +458,7 @@
return {.connection = new_connection};
}
- int64_t now = TimeMillis();
+ Timestamp now = Connection::AlignTime(env_.clock().CurrentTime());
int64_t max_delay = 0;
if (new_connection->last_ping_received() > 0 &&
field_trials_->initial_select_dampening_ping_received.has_value()) {
@@ -461,26 +467,24 @@
max_delay = *field_trials_->initial_select_dampening;
}
- int64_t start_wait =
- initial_select_timestamp_ms_ == 0 ? now : initial_select_timestamp_ms_;
- int64_t max_wait_until = start_wait + max_delay;
+ Timestamp start_wait = initial_select_timestamp_.value_or(now);
+ Timestamp max_wait_until = start_wait + TimeDelta::Millis(max_delay);
if (now >= max_wait_until) {
RTC_LOG(LS_INFO) << "reset initial_select_timestamp_ = "
- << initial_select_timestamp_ms_
- << " selection delayed by: " << (now - start_wait) << "ms";
- initial_select_timestamp_ms_ = 0;
+ << initial_select_timestamp_.value_or(Timestamp::Zero())
+ << " selection delayed by: " << (now - start_wait);
+ initial_select_timestamp_ = std::nullopt;
return {.connection = new_connection};
}
// We are not yet ready to select first connection...
- if (initial_select_timestamp_ms_ == 0) {
+ if (!initial_select_timestamp_.has_value()) {
// Set timestamp on first time...
// but run the delayed invokation everytime to
// avoid possibility that we miss it.
- initial_select_timestamp_ms_ = now;
- RTC_LOG(LS_INFO) << "set initial_select_timestamp_ms_ = "
- << initial_select_timestamp_ms_;
+ initial_select_timestamp_ = now;
+ RTC_LOG(LS_INFO) << "set initial_select_timestamp_ = " << now;
}
int min_delay = max_delay;
@@ -519,7 +523,8 @@
bool missed_receiving_unchanged_threshold = false;
std::optional<int64_t> receiving_unchanged_threshold(
- TimeMillis() - config_.receiving_switching_delay_or_default());
+ Connection::AlignTime(env_.clock().CurrentTime()).ms() -
+ config_.receiving_switching_delay_or_default());
int cmp = CompareConnections(selected_connection_, new_connection,
receiving_unchanged_threshold,
&missed_receiving_unchanged_threshold);
diff --git a/p2p/base/basic_ice_controller.h b/p2p/base/basic_ice_controller.h
index b2aa3c3..66a0402 100644
--- a/p2p/base/basic_ice_controller.h
+++ b/p2p/base/basic_ice_controller.h
@@ -20,6 +20,9 @@
#include <vector>
#include "api/array_view.h"
+#include "api/environment/environment.h"
+#include "api/units/time_delta.h"
+#include "api/units/timestamp.h"
#include "p2p/base/connection.h"
#include "p2p/base/ice_controller_factory_interface.h"
#include "p2p/base/ice_controller_interface.h"
@@ -91,7 +94,7 @@
config_.receiving_timeout_or_default() / 10);
}
- const Connection* FindOldestConnectionNeedingTriggeredCheck(int64_t now);
+ const Connection* FindOldestConnectionNeedingTriggeredCheck(Timestamp now);
// Between `conn1` and `conn2`, this function returns the one which should
// be pinged first.
const Connection* MorePingable(const Connection* conn1,
@@ -104,14 +107,14 @@
const Connection* LeastRecentlyPinged(const Connection* conn1,
const Connection* conn2);
- bool IsPingable(const Connection* conn, int64_t now) const;
+ bool IsPingable(const Connection* conn, Timestamp now) const;
bool IsBackupConnection(const Connection* conn) const;
// Whether a writable connection is past its ping interval and needs to be
// pinged again.
bool WritableConnectionPastPingInterval(const Connection* conn,
- int64_t now) const;
- int CalculateActiveWritablePingInterval(const Connection* conn,
- int64_t now) const;
+ Timestamp now) const;
+ TimeDelta CalculateActiveWritablePingInterval(const Connection* conn,
+ Timestamp now) const;
std::map<const Network*, const Connection*> GetBestConnectionByNetwork()
const;
@@ -152,6 +155,7 @@
SwitchResult HandleInitialSelectDampening(IceSwitchReason reason,
const Connection* new_connection);
+ const Environment env_;
std::function<IceTransportStateInternal()> ice_transport_state_func_;
std::function<IceRole()> ice_role_func_;
std::function<bool(const Connection*)> is_connection_pruned_func_;
@@ -170,7 +174,7 @@
std::set<const Connection*> unpinged_connections_;
// Timestamp for when we got the first selectable connection.
- int64_t initial_select_timestamp_ms_ = 0;
+ std::optional<Timestamp> initial_select_timestamp_;
};
} // namespace webrtc
diff --git a/p2p/base/ice_controller_factory_interface.h b/p2p/base/ice_controller_factory_interface.h
index 2f8754e..966d3e3 100644
--- a/p2p/base/ice_controller_factory_interface.h
+++ b/p2p/base/ice_controller_factory_interface.h
@@ -15,6 +15,7 @@
#include <memory>
#include <string>
+#include "api/environment/environment.h"
#include "p2p/base/connection.h"
#include "p2p/base/ice_controller_interface.h"
#include "p2p/base/ice_transport_internal.h"
@@ -25,6 +26,7 @@
// struct with arguments to IceControllerFactoryInterface::Create
struct IceControllerFactoryArgs {
+ Environment env;
std::function<IceTransportStateInternal()> ice_transport_state_func;
std::function<IceRole()> ice_role_func;
std::function<bool(const Connection*)> is_connection_pruned_func;
diff --git a/p2p/base/p2p_transport_channel.cc b/p2p/base/p2p_transport_channel.cc
index eee1092..82d854f 100644
--- a/p2p/base/p2p_transport_channel.cc
+++ b/p2p/base/p2p_transport_channel.cc
@@ -215,6 +215,7 @@
ParseFieldTrials(env_.field_trials());
IceControllerFactoryArgs args{
+ .env = env_,
.ice_transport_state_func = [this] { return GetState(); },
.ice_role_func = [this] { return GetIceRole(); },
.is_connection_pruned_func =
diff --git a/p2p/base/wrapping_active_ice_controller_unittest.cc b/p2p/base/wrapping_active_ice_controller_unittest.cc
index 074f3b6..8b56013 100644
--- a/p2p/base/wrapping_active_ice_controller_unittest.cc
+++ b/p2p/base/wrapping_active_ice_controller_unittest.cc
@@ -26,24 +26,13 @@
#include "rtc_base/event.h"
#include "rtc_base/fake_clock.h"
#include "rtc_base/thread.h"
+#include "test/create_test_environment.h"
#include "test/gmock.h"
#include "test/gtest.h"
+namespace webrtc {
namespace {
-using ::webrtc::Connection;
-using ::webrtc::IceConfig;
-using ::webrtc::IceControllerFactoryArgs;
-using ::webrtc::IceControllerInterface;
-using ::webrtc::IceMode;
-using ::webrtc::IceRecheckEvent;
-using ::webrtc::IceSwitchReason;
-using ::webrtc::MockIceAgent;
-using ::webrtc::MockIceController;
-using ::webrtc::MockIceControllerFactory;
-using ::webrtc::NominationMode;
-using ::webrtc::WrappingActiveIceController;
-
using ::testing::_;
using ::testing::ElementsAreArray;
using ::testing::IsEmpty;
@@ -52,11 +41,6 @@
using ::testing::Return;
using ::testing::Sequence;
-using ::webrtc::AutoThread;
-using ::webrtc::Event;
-using ::webrtc::ScopedFakeClock;
-using ::webrtc::TimeDelta;
-
using NiceMockIceController = NiceMock<MockIceController>;
const Connection* kConnection = reinterpret_cast<const Connection*>(0xabcd);
@@ -72,7 +56,7 @@
TEST(WrappingActiveIceControllerTest, CreateLegacyIceControllerFromFactory) {
AutoThread main;
MockIceAgent agent;
- IceControllerFactoryArgs args;
+ IceControllerFactoryArgs args = {.env = CreateTestEnvironment()};
MockIceControllerFactory legacy_controller_factory;
EXPECT_CALL(legacy_controller_factory, RecordIceControllerCreated()).Times(1);
WrappingActiveIceController controller(&agent, &legacy_controller_factory,
@@ -83,7 +67,8 @@
AutoThread main;
MockIceAgent agent;
std::unique_ptr<MockIceController> will_move =
- std::make_unique<MockIceController>(IceControllerFactoryArgs{});
+ std::make_unique<MockIceController>(
+ IceControllerFactoryArgs{.env = CreateTestEnvironment()});
MockIceController* wrapped = will_move.get();
WrappingActiveIceController controller(&agent, std::move(will_move));
@@ -120,7 +105,8 @@
ScopedFakeClock clock;
NiceMock<MockIceAgent> agent;
std::unique_ptr<NiceMockIceController> will_move =
- std::make_unique<NiceMockIceController>(IceControllerFactoryArgs{});
+ std::make_unique<NiceMockIceController>(
+ IceControllerFactoryArgs{.env = CreateTestEnvironment()});
NiceMockIceController* wrapped = will_move.get();
WrappingActiveIceController controller(&agent, std::move(will_move));
@@ -165,7 +151,8 @@
ScopedFakeClock clock;
NiceMock<MockIceAgent> agent;
std::unique_ptr<NiceMockIceController> will_move =
- std::make_unique<NiceMockIceController>(IceControllerFactoryArgs{});
+ std::make_unique<NiceMockIceController>(
+ IceControllerFactoryArgs{.env = CreateTestEnvironment()});
NiceMockIceController* wrapped = will_move.get();
WrappingActiveIceController controller(&agent, std::move(will_move));
@@ -223,7 +210,8 @@
NiceMock<MockIceAgent> agent;
std::unique_ptr<NiceMockIceController> will_move =
- std::make_unique<NiceMockIceController>(IceControllerFactoryArgs{});
+ std::make_unique<NiceMockIceController>(
+ IceControllerFactoryArgs{.env = CreateTestEnvironment()});
NiceMockIceController* wrapped = will_move.get();
WrappingActiveIceController controller(&agent, std::move(will_move));
@@ -268,7 +256,8 @@
NiceMock<MockIceAgent> agent;
std::unique_ptr<NiceMockIceController> will_move =
- std::make_unique<NiceMockIceController>(IceControllerFactoryArgs{});
+ std::make_unique<NiceMockIceController>(
+ IceControllerFactoryArgs{.env = CreateTestEnvironment()});
NiceMockIceController* wrapped = will_move.get();
WrappingActiveIceController controller(&agent, std::move(will_move));
@@ -319,3 +308,4 @@
}
} // namespace
+} // namespace webrtc