From 40a355a42d4a9444dc753c04c6608dade2f06a23 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 03:13:27 +0200 Subject: Adding upstream version 125.0.1. Signed-off-by: Daniel Baumann --- third_party/libwebrtc/net/dcsctp/socket/BUILD.gn | 6 +- .../net/dcsctp/socket/callback_deferrer.cc | 4 +- .../net/dcsctp/socket/callback_deferrer.h | 1 + third_party/libwebrtc/net/dcsctp/socket/context.h | 7 +- .../libwebrtc/net/dcsctp/socket/dcsctp_socket.cc | 44 ++++---- .../libwebrtc/net/dcsctp/socket/dcsctp_socket.h | 6 +- .../dcsctp/socket/dcsctp_socket_network_test.cc | 16 +-- .../net/dcsctp/socket/dcsctp_socket_test.cc | 121 +++++++++++---------- .../net/dcsctp/socket/heartbeat_handler.cc | 43 ++++---- .../net/dcsctp/socket/heartbeat_handler.h | 6 +- .../net/dcsctp/socket/heartbeat_handler_test.cc | 19 ++-- .../libwebrtc/net/dcsctp/socket/mock_context.h | 7 +- .../dcsctp/socket/mock_dcsctp_socket_callbacks.h | 12 +- .../net/dcsctp/socket/stream_reset_handler.cc | 8 +- .../net/dcsctp/socket/stream_reset_handler.h | 5 +- .../net/dcsctp/socket/stream_reset_handler_test.cc | 21 ++-- .../dcsctp/socket/transmission_control_block.cc | 45 ++++---- .../net/dcsctp/socket/transmission_control_block.h | 18 +-- 18 files changed, 212 insertions(+), 177 deletions(-) (limited to 'third_party/libwebrtc/net/dcsctp/socket') diff --git a/third_party/libwebrtc/net/dcsctp/socket/BUILD.gn b/third_party/libwebrtc/net/dcsctp/socket/BUILD.gn index 681ddd47e9..04f61e5b72 100644 --- a/third_party/libwebrtc/net/dcsctp/socket/BUILD.gn +++ b/third_party/libwebrtc/net/dcsctp/socket/BUILD.gn @@ -11,6 +11,7 @@ import("../../../webrtc.gni") rtc_source_set("context") { sources = [ "context.h" ] deps = [ + "../../../api/units:time_delta", "../common:internal_types", "../packet:sctp_packet", "../public:socket", @@ -23,6 +24,7 @@ rtc_library("heartbeat_handler") { deps = [ ":context", "../../../api:array_view", + "../../../api/units:time_delta", "../../../rtc_base:checks", "../../../rtc_base:logging", "../packet:bounded_io", @@ -48,11 +50,12 @@ rtc_library("stream_reset_handler") { deps = [ ":context", "../../../api:array_view", + "../../../api/units:time_delta", "../../../rtc_base:checks", "../../../rtc_base:logging", + "../../../rtc_base:stringutils", "../../../rtc_base/containers:flat_set", "../common:internal_types", - "../common:str_join", "../packet:chunk", "../packet:parameter", "../packet:sctp_packet", @@ -97,6 +100,7 @@ rtc_library("transmission_control_block") { ":stream_reset_handler", "../../../api:array_view", "../../../api/task_queue:task_queue", + "../../../api/units:time_delta", "../../../rtc_base:checks", "../../../rtc_base:logging", "../../../rtc_base:stringutils", diff --git a/third_party/libwebrtc/net/dcsctp/socket/callback_deferrer.cc b/third_party/libwebrtc/net/dcsctp/socket/callback_deferrer.cc index 123526e782..0a24020167 100644 --- a/third_party/libwebrtc/net/dcsctp/socket/callback_deferrer.cc +++ b/third_party/libwebrtc/net/dcsctp/socket/callback_deferrer.cc @@ -28,7 +28,7 @@ class MessageDeliverer { } private: - struct State : public rtc::RefCountInterface { + struct State : public webrtc::RefCountInterface { explicit State(DcSctpMessage&& m) : has_delivered(false), message(std::move(m)) {} bool has_delivered; @@ -70,6 +70,8 @@ std::unique_ptr CallbackDeferrer::CreateTimeout( } TimeMs CallbackDeferrer::TimeMillis() { + // This should not be called by the library - it's migrated to `Now()`. + RTC_DCHECK(false); // Will not be deferred - call directly. return underlying_.TimeMillis(); } diff --git a/third_party/libwebrtc/net/dcsctp/socket/callback_deferrer.h b/third_party/libwebrtc/net/dcsctp/socket/callback_deferrer.h index 1c35dda6cf..6659e87155 100644 --- a/third_party/libwebrtc/net/dcsctp/socket/callback_deferrer.h +++ b/third_party/libwebrtc/net/dcsctp/socket/callback_deferrer.h @@ -65,6 +65,7 @@ class CallbackDeferrer : public DcSctpSocketCallbacks { std::unique_ptr CreateTimeout( webrtc::TaskQueueBase::DelayPrecision precision) override; TimeMs TimeMillis() override; + webrtc::Timestamp Now() override { return underlying_.Now(); } uint32_t GetRandomInt(uint32_t low, uint32_t high) override; void OnMessageReceived(DcSctpMessage message) override; void OnError(ErrorKind error, absl::string_view message) override; diff --git a/third_party/libwebrtc/net/dcsctp/socket/context.h b/third_party/libwebrtc/net/dcsctp/socket/context.h index eca5b9e4fb..8e970e8c8e 100644 --- a/third_party/libwebrtc/net/dcsctp/socket/context.h +++ b/third_party/libwebrtc/net/dcsctp/socket/context.h @@ -13,6 +13,7 @@ #include #include "absl/strings/string_view.h" +#include "api/units/time_delta.h" #include "net/dcsctp/common/internal_types.h" #include "net/dcsctp/packet/sctp_packet.h" #include "net/dcsctp/public/dcsctp_socket.h" @@ -39,11 +40,11 @@ class Context { // Returns the socket callbacks. virtual DcSctpSocketCallbacks& callbacks() const = 0; - // Observes a measured RTT value, in milliseconds. - virtual void ObserveRTT(DurationMs rtt_ms) = 0; + // Observes a measured RTT value. + virtual void ObserveRTT(webrtc::TimeDelta rtt_ms) = 0; // Returns the current Retransmission Timeout (rto) value, in milliseconds. - virtual DurationMs current_rto() const = 0; + virtual webrtc::TimeDelta current_rto() const = 0; // Increments the transmission error counter, given a human readable reason. virtual bool IncrementTxErrorCounter(absl::string_view reason) = 0; diff --git a/third_party/libwebrtc/net/dcsctp/socket/dcsctp_socket.cc b/third_party/libwebrtc/net/dcsctp/socket/dcsctp_socket.cc index 32bcdaaacf..f0f9590943 100644 --- a/third_party/libwebrtc/net/dcsctp/socket/dcsctp_socket.cc +++ b/third_party/libwebrtc/net/dcsctp/socket/dcsctp_socket.cc @@ -82,6 +82,8 @@ namespace dcsctp { namespace { +using ::webrtc::TimeDelta; +using ::webrtc::Timestamp; // https://tools.ietf.org/html/rfc4960#section-5.1 constexpr uint32_t kMinVerificationTag = 1; @@ -187,19 +189,19 @@ DcSctpSocket::DcSctpSocket(absl::string_view log_prefix, t1_init_(timer_manager_.CreateTimer( "t1-init", absl::bind_front(&DcSctpSocket::OnInitTimerExpiry, this), - TimerOptions(options.t1_init_timeout, + TimerOptions(options.t1_init_timeout.ToTimeDelta(), TimerBackoffAlgorithm::kExponential, options.max_init_retransmits))), t1_cookie_(timer_manager_.CreateTimer( "t1-cookie", absl::bind_front(&DcSctpSocket::OnCookieTimerExpiry, this), - TimerOptions(options.t1_cookie_timeout, + TimerOptions(options.t1_cookie_timeout.ToTimeDelta(), TimerBackoffAlgorithm::kExponential, options.max_init_retransmits))), t2_shutdown_(timer_manager_.CreateTimer( "t2-shutdown", absl::bind_front(&DcSctpSocket::OnShutdownTimerExpiry, this), - TimerOptions(options.t2_shutdown_timeout, + TimerOptions(options.t2_shutdown_timeout.ToTimeDelta(), TimerBackoffAlgorithm::kExponential, options.max_retransmissions))), packet_sender_(callbacks_, @@ -518,7 +520,7 @@ SendStatus DcSctpSocket::Send(DcSctpMessage message, return SendStatus::kErrorResourceExhaustion; } - TimeMs now = callbacks_.TimeMillis(); + Timestamp now = callbacks_.Now(); ++metrics_.tx_messages_count; send_queue_.Add(now, std::move(message), send_options); if (tcb_ != nullptr) { @@ -600,11 +602,11 @@ absl::optional DcSctpSocket::GetMetrics() const { Metrics metrics = metrics_; metrics.cwnd_bytes = tcb_->cwnd(); - metrics.srtt_ms = tcb_->current_srtt().value(); + metrics.srtt_ms = tcb_->current_srtt().ms(); size_t packet_payload_size = options_.mtu - SctpPacket::kHeaderSize - DataChunk::kHeaderSize; metrics.unack_data_count = - tcb_->retransmission_queue().outstanding_items() + + tcb_->retransmission_queue().unacked_items() + (send_queue_.total_buffered_amount() + packet_payload_size - 1) / packet_payload_size; metrics.peer_rwnd_bytes = tcb_->retransmission_queue().rwnd(); @@ -768,7 +770,7 @@ void DcSctpSocket::ReceivePacket(rtc::ArrayView data) { ++metrics_.rx_packets_count; if (packet_observer_ != nullptr) { - packet_observer_->OnReceivedPacket(callbacks_.TimeMillis(), data); + packet_observer_->OnReceivedPacket(TimeMs(callbacks_.Now().ms()), data); } absl::optional packet = SctpPacket::Parse(data, options_); @@ -921,7 +923,7 @@ bool DcSctpSocket::HandleUnrecognizedChunk( return continue_processing; } -absl::optional DcSctpSocket::OnInitTimerExpiry() { +TimeDelta DcSctpSocket::OnInitTimerExpiry() { RTC_DLOG(LS_VERBOSE) << log_prefix() << "Timer " << t1_init_->name() << " has expired: " << t1_init_->expiration_count() << "/" << t1_init_->options().max_restarts.value_or(-1); @@ -933,10 +935,10 @@ absl::optional DcSctpSocket::OnInitTimerExpiry() { InternalClose(ErrorKind::kTooManyRetries, "No INIT_ACK received"); } RTC_DCHECK(IsConsistent()); - return absl::nullopt; + return TimeDelta::Zero(); } -absl::optional DcSctpSocket::OnCookieTimerExpiry() { +TimeDelta DcSctpSocket::OnCookieTimerExpiry() { // https://tools.ietf.org/html/rfc4960#section-4 // "If the T1-cookie timer expires, the endpoint MUST retransmit COOKIE // ECHO and restart the T1-cookie timer without changing state. This MUST @@ -951,16 +953,16 @@ absl::optional DcSctpSocket::OnCookieTimerExpiry() { RTC_DCHECK(state_ == State::kCookieEchoed); if (t1_cookie_->is_running()) { - tcb_->SendBufferedPackets(callbacks_.TimeMillis()); + tcb_->SendBufferedPackets(callbacks_.Now()); } else { InternalClose(ErrorKind::kTooManyRetries, "No COOKIE_ACK received"); } RTC_DCHECK(IsConsistent()); - return absl::nullopt; + return TimeDelta::Zero(); } -absl::optional DcSctpSocket::OnShutdownTimerExpiry() { +TimeDelta DcSctpSocket::OnShutdownTimerExpiry() { RTC_DLOG(LS_VERBOSE) << log_prefix() << "Timer " << t2_shutdown_->name() << " has expired: " << t2_shutdown_->expiration_count() << "/" @@ -980,7 +982,7 @@ absl::optional DcSctpSocket::OnShutdownTimerExpiry() { InternalClose(ErrorKind::kTooManyRetries, "No SHUTDOWN_ACK received"); RTC_DCHECK(IsConsistent()); - return absl::nullopt; + return TimeDelta::Zero(); } // https://tools.ietf.org/html/rfc4960#section-9.2 @@ -996,7 +998,7 @@ void DcSctpSocket::OnSentPacket(rtc::ArrayView packet, // The packet observer is invoked even if the packet was failed to be sent, to // indicate an attempt was made. if (packet_observer_ != nullptr) { - packet_observer_->OnSentPacket(callbacks_.TimeMillis(), packet); + packet_observer_->OnSentPacket(TimeMs(callbacks_.Now().ms()), packet); } if (status == SendPacketStatus::kSuccess) { @@ -1282,7 +1284,7 @@ void DcSctpSocket::HandleInitAck( // The connection isn't fully established just yet. tcb_->SetCookieEchoChunk(CookieEchoChunk(cookie->data())); - tcb_->SendBufferedPackets(callbacks_.TimeMillis()); + tcb_->SendBufferedPackets(callbacks_.Now()); t1_cookie_->Start(); } @@ -1351,7 +1353,7 @@ void DcSctpSocket::HandleCookieEcho( // "A COOKIE ACK chunk may be bundled with any pending DATA chunks (and/or // SACK chunks), but the COOKIE ACK chunk MUST be the first chunk in the // packet." - tcb_->SendBufferedPackets(b, callbacks_.TimeMillis()); + tcb_->SendBufferedPackets(b, callbacks_.Now()); } bool DcSctpSocket::HandleCookieEchoWithTCB(const CommonHeader& header, @@ -1449,7 +1451,7 @@ void DcSctpSocket::HandleCookieAck( t1_cookie_->Stop(); tcb_->ClearCookieEchoChunk(); SetState(State::kEstablished, "COOKIE_ACK received"); - tcb_->SendBufferedPackets(callbacks_.TimeMillis()); + tcb_->SendBufferedPackets(callbacks_.Now()); callbacks_.OnConnected(); } @@ -1465,7 +1467,7 @@ void DcSctpSocket::HandleSack(const CommonHeader& header, absl::optional chunk = SackChunk::Parse(descriptor.data); if (ValidateParseSuccess(chunk) && ValidateHasTCB()) { - TimeMs now = callbacks_.TimeMillis(); + Timestamp now = callbacks_.Now(); SackChunk sack = ChunkValidators::Clean(*std::move(chunk)); if (tcb_->retransmission_queue().HandleSack(now, sack)) { @@ -1554,7 +1556,7 @@ void DcSctpSocket::HandleError(const CommonHeader& header, void DcSctpSocket::HandleReconfig( const CommonHeader& header, const SctpPacket::ChunkDescriptor& descriptor) { - TimeMs now = callbacks_.TimeMillis(); + Timestamp now = callbacks_.Now(); absl::optional chunk = ReConfigChunk::Parse(descriptor.data); if (ValidateParseSuccess(chunk) && ValidateHasTCB()) { tcb_->stream_reset_handler().HandleReConfig(*std::move(chunk)); @@ -1718,7 +1720,7 @@ void DcSctpSocket::HandleForwardTsnCommon(const AnyForwardTsnChunk& chunk) { } void DcSctpSocket::MaybeSendShutdownOrAck() { - if (tcb_->retransmission_queue().outstanding_bytes() != 0) { + if (tcb_->retransmission_queue().unacked_bytes() != 0) { return; } diff --git a/third_party/libwebrtc/net/dcsctp/socket/dcsctp_socket.h b/third_party/libwebrtc/net/dcsctp/socket/dcsctp_socket.h index f91eb3ead4..deb6ee23e7 100644 --- a/third_party/libwebrtc/net/dcsctp/socket/dcsctp_socket.h +++ b/third_party/libwebrtc/net/dcsctp/socket/dcsctp_socket.h @@ -155,9 +155,9 @@ class DcSctpSocket : public DcSctpSocketInterface { // Closes the association, because of too many retransmission errors. void CloseConnectionBecauseOfTooManyTransmissionErrors(); // Timer expiration handlers - absl::optional OnInitTimerExpiry(); - absl::optional OnCookieTimerExpiry(); - absl::optional OnShutdownTimerExpiry(); + webrtc::TimeDelta OnInitTimerExpiry(); + webrtc::TimeDelta OnCookieTimerExpiry(); + webrtc::TimeDelta OnShutdownTimerExpiry(); void OnSentPacket(rtc::ArrayView packet, SendPacketStatus status); // Sends SHUTDOWN or SHUTDOWN-ACK if the socket is shutting down and if all diff --git a/third_party/libwebrtc/net/dcsctp/socket/dcsctp_socket_network_test.cc b/third_party/libwebrtc/net/dcsctp/socket/dcsctp_socket_network_test.cc index f097bfa095..f73ecce445 100644 --- a/third_party/libwebrtc/net/dcsctp/socket/dcsctp_socket_network_test.cc +++ b/third_party/libwebrtc/net/dcsctp/socket/dcsctp_socket_network_test.cc @@ -55,6 +55,8 @@ using ::testing::AllOf; using ::testing::Ge; using ::testing::Le; using ::testing::SizeIs; +using ::webrtc::TimeDelta; +using ::webrtc::Timestamp; constexpr StreamID kStreamId(1); constexpr PPID kPpid(53); @@ -142,13 +144,13 @@ class SctpActor : public DcSctpSocketCallbacks { emulated_socket_(emulated_socket), timeout_factory_( *thread_, - [this]() { return TimeMillis(); }, + [this]() { return TimeMs(Now().ms()); }, [this](dcsctp::TimeoutID timeout_id) { sctp_socket_.HandleTimeout(timeout_id); }), random_(GetUniqueSeed()), sctp_socket_(name, *this, nullptr, sctp_options), - last_bandwidth_printout_(TimeMs(TimeMillis())) { + last_bandwidth_printout_(Now()) { emulated_socket.SetReceiver([this](rtc::CopyOnWriteBuffer buf) { // The receiver will be executed on the NetworkEmulation task queue, but // the dcSCTP socket is owned by `thread_` and is not thread-safe. @@ -157,11 +159,11 @@ class SctpActor : public DcSctpSocketCallbacks { } void PrintBandwidth() { - TimeMs now = TimeMillis(); - DurationMs duration = now - last_bandwidth_printout_; + Timestamp now = Now(); + TimeDelta duration = now - last_bandwidth_printout_; double bitrate_mbps = - static_cast(received_bytes_ * 8) / *duration / 1000; + static_cast(received_bytes_ * 8) / duration.ms() / 1000; RTC_LOG(LS_INFO) << log_prefix() << rtc::StringFormat("Received %0.2f Mbps", bitrate_mbps); @@ -185,7 +187,7 @@ class SctpActor : public DcSctpSocketCallbacks { return timeout_factory_.CreateTimeout(precision); } - TimeMs TimeMillis() override { return TimeMs(rtc::TimeMillis()); } + Timestamp Now() override { return Timestamp::Millis(rtc::TimeMillis()); } uint32_t GetRandomInt(uint32_t low, uint32_t high) override { return random_.Rand(low, high); @@ -314,7 +316,7 @@ class SctpActor : public DcSctpSocketCallbacks { DcSctpSocket sctp_socket_; size_t received_bytes_ = 0; absl::optional last_received_message_; - TimeMs last_bandwidth_printout_; + Timestamp last_bandwidth_printout_; // Per-second received bitrates, in Mbps std::vector received_bitrate_mbps_; webrtc::ScopedTaskSafety safety_; diff --git a/third_party/libwebrtc/net/dcsctp/socket/dcsctp_socket_test.cc b/third_party/libwebrtc/net/dcsctp/socket/dcsctp_socket_test.cc index 13202846ac..dc76b80a37 100644 --- a/third_party/libwebrtc/net/dcsctp/socket/dcsctp_socket_test.cc +++ b/third_party/libwebrtc/net/dcsctp/socket/dcsctp_socket_test.cc @@ -73,6 +73,8 @@ using ::testing::Not; using ::testing::Property; using ::testing::SizeIs; using ::testing::UnorderedElementsAre; +using ::webrtc::TimeDelta; +using ::webrtc::Timestamp; constexpr SendOptions kSendOptions; constexpr size_t kLargeMessageSize = DcSctpOptions::kMaxSafeMTUSize * 20; @@ -269,7 +271,7 @@ void RunTimers(SocketUnderTest& s) { } } -void AdvanceTime(SocketUnderTest& a, SocketUnderTest& z, DurationMs duration) { +void AdvanceTime(SocketUnderTest& a, SocketUnderTest& z, TimeDelta duration) { a.cb.AdvanceTime(duration); z.cb.AdvanceTime(duration); @@ -282,14 +284,14 @@ void AdvanceTime(SocketUnderTest& a, SocketUnderTest& z, DurationMs duration) { void ExchangeMessagesAndAdvanceTime( SocketUnderTest& a, SocketUnderTest& z, - DurationMs max_timeout = DurationMs(10000)) { - TimeMs time_started = a.cb.TimeMillis(); - while (a.cb.TimeMillis() - time_started < max_timeout) { + TimeDelta max_timeout = TimeDelta::Seconds(10)) { + Timestamp time_started = a.cb.Now(); + while (a.cb.Now() - time_started < max_timeout) { ExchangeMessages(a, z); - DurationMs time_to_next_timeout = + TimeDelta time_to_next_timeout = std::min(a.cb.GetTimeToNextTimeout(), z.cb.GetTimeToNextTimeout()); - if (time_to_next_timeout == DurationMs::InfiniteDuration()) { + if (time_to_next_timeout.IsPlusInfinity()) { // No more pending timer. return; } @@ -535,7 +537,7 @@ TEST(DcSctpSocketTest, EstablishConnectionLostCookieAck) { EXPECT_EQ(z.socket.state(), SocketState::kConnected); // This will make A re-send the COOKIE_ECHO - AdvanceTime(a, z, DurationMs(a.options.t1_cookie_timeout)); + AdvanceTime(a, z, a.options.t1_cookie_timeout.ToTimeDelta()); // Z reads COOKIE_ECHO, produces COOKIE_ACK z.socket.ReceivePacket(a.cb.ConsumeSentPacket()); @@ -555,7 +557,7 @@ TEST(DcSctpSocketTest, ResendInitAndEstablishConnection) { EXPECT_THAT(a.cb.ConsumeSentPacket(), HasChunks(ElementsAre(IsChunkType(InitChunk::kType)))); - AdvanceTime(a, z, a.options.t1_init_timeout); + AdvanceTime(a, z, a.options.t1_init_timeout.ToTimeDelta()); // Z reads INIT, produces INIT_ACK z.socket.ReceivePacket(a.cb.ConsumeSentPacket()); @@ -581,7 +583,7 @@ TEST(DcSctpSocketTest, ResendingInitTooManyTimesAborts) { HasChunks(ElementsAre(IsChunkType(InitChunk::kType)))); for (int i = 0; i < *a.options.max_init_retransmits; ++i) { - AdvanceTime(a, z, a.options.t1_init_timeout * (1 << i)); + AdvanceTime(a, z, a.options.t1_init_timeout.ToTimeDelta() * (1 << i)); // INIT is resent EXPECT_THAT(a.cb.ConsumeSentPacket(), @@ -590,8 +592,9 @@ TEST(DcSctpSocketTest, ResendingInitTooManyTimesAborts) { // Another timeout, after the max init retransmits. EXPECT_CALL(a.cb, OnAborted).Times(1); - AdvanceTime( - a, z, a.options.t1_init_timeout * (1 << *a.options.max_init_retransmits)); + AdvanceTime(a, z, + a.options.t1_init_timeout.ToTimeDelta() * + (1 << *a.options.max_init_retransmits)); EXPECT_EQ(a.socket.state(), SocketState::kClosed); } @@ -611,7 +614,7 @@ TEST(DcSctpSocketTest, ResendCookieEchoAndEstablishConnection) { EXPECT_THAT(a.cb.ConsumeSentPacket(), HasChunks(ElementsAre(IsChunkType(CookieEchoChunk::kType)))); - AdvanceTime(a, z, a.options.t1_init_timeout); + AdvanceTime(a, z, a.options.t1_init_timeout.ToTimeDelta()); // Z reads COOKIE_ECHO, produces COOKIE_ACK z.socket.ReceivePacket(a.cb.ConsumeSentPacket()); @@ -638,7 +641,7 @@ TEST(DcSctpSocketTest, ResendingCookieEchoTooManyTimesAborts) { HasChunks(ElementsAre(IsChunkType(CookieEchoChunk::kType)))); for (int i = 0; i < *a.options.max_init_retransmits; ++i) { - AdvanceTime(a, z, a.options.t1_cookie_timeout * (1 << i)); + AdvanceTime(a, z, a.options.t1_cookie_timeout.ToTimeDelta() * (1 << i)); // COOKIE_ECHO is resent EXPECT_THAT(a.cb.ConsumeSentPacket(), @@ -647,9 +650,9 @@ TEST(DcSctpSocketTest, ResendingCookieEchoTooManyTimesAborts) { // Another timeout, after the max init retransmits. EXPECT_CALL(a.cb, OnAborted).Times(1); - AdvanceTime( - a, z, - a.options.t1_cookie_timeout * (1 << *a.options.max_init_retransmits)); + AdvanceTime(a, z, + a.options.t1_cookie_timeout.ToTimeDelta() * + (1 << *a.options.max_init_retransmits)); EXPECT_EQ(a.socket.state(), SocketState::kClosed); } @@ -680,11 +683,13 @@ TEST(DcSctpSocketTest, DoesntSendMorePacketsUntilCookieAckHasBeenReceived) { // will be T1-COOKIE that drives retransmissions, so when the T3-RTX expires, // nothing should be retransmitted. ASSERT_TRUE(a.options.rto_initial < a.options.t1_cookie_timeout); - AdvanceTime(a, z, a.options.rto_initial); + AdvanceTime(a, z, a.options.rto_initial.ToTimeDelta()); EXPECT_THAT(a.cb.ConsumeSentPacket(), IsEmpty()); // When T1-COOKIE expires, both the COOKIE-ECHO and DATA should be present. - AdvanceTime(a, z, a.options.t1_cookie_timeout - a.options.rto_initial); + AdvanceTime(a, z, + a.options.t1_cookie_timeout.ToTimeDelta() - + a.options.rto_initial.ToTimeDelta()); // And this COOKIE-ECHO and DATA is also lost - never received by Z. EXPECT_THAT(a.cb.ConsumeSentPacket(), @@ -694,7 +699,7 @@ TEST(DcSctpSocketTest, DoesntSendMorePacketsUntilCookieAckHasBeenReceived) { EXPECT_THAT(a.cb.ConsumeSentPacket(), IsEmpty()); // COOKIE_ECHO has exponential backoff. - AdvanceTime(a, z, a.options.t1_cookie_timeout * 2); + AdvanceTime(a, z, a.options.t1_cookie_timeout.ToTimeDelta() * 2); // Z reads COOKIE_ECHO, produces COOKIE_ACK z.socket.ReceivePacket(a.cb.ConsumeSentPacket()); @@ -747,7 +752,7 @@ TEST(DcSctpSocketTest, ShutdownTimerExpiresTooManyTimeClosesConnection) { EXPECT_EQ(a.socket.state(), SocketState::kShuttingDown); for (int i = 0; i < *a.options.max_retransmissions; ++i) { - AdvanceTime(a, z, DurationMs(a.options.rto_initial * (1 << i))); + AdvanceTime(a, z, a.options.rto_initial.ToTimeDelta() * (1 << i)); // Dropping every shutdown chunk. EXPECT_THAT(a.cb.ConsumeSentPacket(), @@ -757,7 +762,8 @@ TEST(DcSctpSocketTest, ShutdownTimerExpiresTooManyTimeClosesConnection) { // The last expiry, makes it abort the connection. EXPECT_CALL(a.cb, OnAborted).Times(1); AdvanceTime(a, z, - a.options.rto_initial * (1 << *a.options.max_retransmissions)); + a.options.rto_initial.ToTimeDelta() * + (1 << *a.options.max_retransmissions)); EXPECT_EQ(a.socket.state(), SocketState::kClosed); EXPECT_THAT(a.cb.ConsumeSentPacket(), @@ -815,7 +821,7 @@ TEST_P(DcSctpSocketParametrizedTest, TimeoutResendsPacket) { a.cb.ConsumeSentPacket(); RTC_LOG(LS_INFO) << "Advancing time"; - AdvanceTime(a, *z, a.options.rto_initial); + AdvanceTime(a, *z, a.options.rto_initial.ToTimeDelta()); z->socket.ReceivePacket(a.cb.ConsumeSentPacket()); @@ -886,7 +892,7 @@ TEST_P(DcSctpSocketParametrizedTest, ExpectHeartbeatToBeSent) { EXPECT_THAT(a.cb.ConsumeSentPacket(), IsEmpty()); - AdvanceTime(a, *z, a.options.heartbeat_interval); + AdvanceTime(a, *z, a.options.heartbeat_interval.ToTimeDelta()); std::vector packet = a.cb.ConsumeSentPacket(); // The info is a single 64-bit number. @@ -920,7 +926,7 @@ TEST_P(DcSctpSocketParametrizedTest, for (int i = 0; i < *a.options.max_retransmissions; ++i) { RTC_LOG(LS_INFO) << "Letting HEARTBEAT interval timer expire - sending..."; - AdvanceTime(a, *z, time_to_next_hearbeat); + AdvanceTime(a, *z, time_to_next_hearbeat.ToTimeDelta()); // Dropping every heartbeat. ASSERT_HAS_VALUE_AND_ASSIGN( @@ -929,20 +935,20 @@ TEST_P(DcSctpSocketParametrizedTest, EXPECT_EQ(hb_packet.descriptors()[0].type, HeartbeatRequestChunk::kType); RTC_LOG(LS_INFO) << "Letting the heartbeat expire."; - AdvanceTime(a, *z, DurationMs(1000)); + AdvanceTime(a, *z, TimeDelta::Millis(1000)); time_to_next_hearbeat = a.options.heartbeat_interval - DurationMs(1000); } RTC_LOG(LS_INFO) << "Letting HEARTBEAT interval timer expire - sending..."; - AdvanceTime(a, *z, time_to_next_hearbeat); + AdvanceTime(a, *z, time_to_next_hearbeat.ToTimeDelta()); // Last heartbeat EXPECT_THAT(a.cb.ConsumeSentPacket(), Not(IsEmpty())); EXPECT_CALL(a.cb, OnAborted).Times(1); // Should suffice as exceeding RTO - AdvanceTime(a, *z, DurationMs(1000)); + AdvanceTime(a, *z, TimeDelta::Millis(1000)); z = MaybeHandoverSocket(std::move(z)); } @@ -959,7 +965,7 @@ TEST_P(DcSctpSocketParametrizedTest, RecoversAfterASuccessfulAck) { // Force-close socket Z so that it doesn't interfere from now on. z->socket.Close(); - DurationMs time_to_next_hearbeat = a.options.heartbeat_interval; + TimeDelta time_to_next_hearbeat = a.options.heartbeat_interval.ToTimeDelta(); for (int i = 0; i < *a.options.max_retransmissions; ++i) { AdvanceTime(a, *z, time_to_next_hearbeat); @@ -968,9 +974,10 @@ TEST_P(DcSctpSocketParametrizedTest, RecoversAfterASuccessfulAck) { a.cb.ConsumeSentPacket(); RTC_LOG(LS_INFO) << "Letting the heartbeat expire."; - AdvanceTime(a, *z, DurationMs(1000)); + AdvanceTime(a, *z, TimeDelta::Seconds(1)); - time_to_next_hearbeat = a.options.heartbeat_interval - DurationMs(1000); + time_to_next_hearbeat = + a.options.heartbeat_interval.ToTimeDelta() - TimeDelta::Seconds(1); } RTC_LOG(LS_INFO) << "Getting the last heartbeat - and acking it"; @@ -990,7 +997,7 @@ TEST_P(DcSctpSocketParametrizedTest, RecoversAfterASuccessfulAck) { // Should suffice as exceeding RTO - which will not fire. EXPECT_CALL(a.cb, OnAborted).Times(0); - AdvanceTime(a, *z, DurationMs(1000)); + AdvanceTime(a, *z, TimeDelta::Seconds(1)); EXPECT_THAT(a.cb.ConsumeSentPacket(), IsEmpty()); @@ -1245,7 +1252,7 @@ TEST_P(DcSctpSocketParametrizedTest, SendMessageWithLimitedRtx) { a.socket.ReceivePacket(z->cb.ConsumeSentPacket()); // Handle delayed SACK for third DATA - AdvanceTime(a, *z, a.options.delayed_ack_max_timeout); + AdvanceTime(a, *z, a.options.delayed_ack_max_timeout.ToTimeDelta()); // Handle SACK for second DATA a.socket.ReceivePacket(z->cb.ConsumeSentPacket()); @@ -1254,7 +1261,7 @@ TEST_P(DcSctpSocketParametrizedTest, SendMessageWithLimitedRtx) { // in-flight and the reported gap could be due to out-of-order delivery. So // the RetransmissionQueue will not mark it as "to be retransmitted" until // after the t3-rtx timer has expired. - AdvanceTime(a, *z, a.options.rto_initial); + AdvanceTime(a, *z, a.options.rto_initial.ToTimeDelta()); // The chunk will be marked as retransmitted, and then as abandoned, which // will trigger a FORWARD-TSN to be sent. @@ -1352,7 +1359,7 @@ TEST_P(DcSctpSocketParametrizedTest, SendManyFragmentedMessagesWithLimitedRtx) { ExchangeMessages(a, *z); // Let the RTX timer expire, and exchange FORWARD-TSN/SACKs - AdvanceTime(a, *z, a.options.rto_initial); + AdvanceTime(a, *z, a.options.rto_initial.ToTimeDelta()); ExchangeMessages(a, *z); @@ -1484,7 +1491,7 @@ TEST(DcSctpSocketTest, PassingHighWatermarkWillOnlyAcceptCumAckTsn) { .Build()); // The receiver might have moved into delayed ack mode. - AdvanceTime(a, z, z.options.rto_initial); + AdvanceTime(a, z, z.options.rto_initial.ToTimeDelta()); EXPECT_THAT(z.cb.ConsumeSentPacket(), HasChunks(ElementsAre(IsSack( @@ -1528,7 +1535,7 @@ TEST(DcSctpSocketTest, PassingHighWatermarkWillOnlyAcceptCumAckTsn) { .Build()); // The receiver might have moved into delayed ack mode. - AdvanceTime(a, z, z.options.rto_initial); + AdvanceTime(a, z, z.options.rto_initial.ToTimeDelta()); EXPECT_THAT(z.cb.ConsumeSentPacket(), HasChunks(ElementsAre(IsSack( @@ -1562,13 +1569,13 @@ TEST_P(DcSctpSocketParametrizedTest, SendsMessagesWithLowLifetime) { z = MaybeHandoverSocket(std::move(z)); // Mock that the time always goes forward. - TimeMs now(0); - EXPECT_CALL(a.cb, TimeMillis).WillRepeatedly([&]() { - now += DurationMs(3); + Timestamp now = Timestamp::Zero(); + EXPECT_CALL(a.cb, Now).WillRepeatedly([&]() { + now += TimeDelta::Millis(3); return now; }); - EXPECT_CALL(z->cb, TimeMillis).WillRepeatedly([&]() { - now += DurationMs(3); + EXPECT_CALL(z->cb, Now).WillRepeatedly([&]() { + now += TimeDelta::Millis(3); return now; }); @@ -1592,7 +1599,7 @@ TEST_P(DcSctpSocketParametrizedTest, SendsMessagesWithLowLifetime) { EXPECT_FALSE(z->cb.ConsumeReceivedMessage().has_value()); // Validate that the sockets really make the time move forward. - EXPECT_GE(*now, kIterations * 2); + EXPECT_GE(now.ms(), kIterations * 2); MaybeHandoverSocketAndSendMessage(a, std::move(z)); } @@ -1614,13 +1621,13 @@ TEST_P(DcSctpSocketParametrizedTest, lifetime_1.lifetime = DurationMs(1); // Mock that the time always goes forward. - TimeMs now(0); - EXPECT_CALL(a.cb, TimeMillis).WillRepeatedly([&]() { - now += DurationMs(3); + Timestamp now = Timestamp::Zero(); + EXPECT_CALL(a.cb, Now).WillRepeatedly([&]() { + now += TimeDelta::Millis(3); return now; }); - EXPECT_CALL(z->cb, TimeMillis).WillRepeatedly([&]() { - now += DurationMs(3); + EXPECT_CALL(z->cb, Now).WillRepeatedly([&]() { + now += TimeDelta::Millis(3); return now; }); @@ -1944,7 +1951,7 @@ TEST(DcSctpSocketTest, RxAndTxPacketMetricsIncrease) { EXPECT_EQ(z.socket.GetMetrics()->rx_messages_count, 2u); // Delayed sack - AdvanceTime(a, z, a.options.delayed_ack_max_timeout); + AdvanceTime(a, z, a.options.delayed_ack_max_timeout.ToTimeDelta()); a.socket.ReceivePacket(z.cb.ConsumeSentPacket()); // SACK EXPECT_EQ(a.socket.GetMetrics()->unack_data_count, 0u); @@ -1981,7 +1988,7 @@ TEST(DcSctpSocketTest, RetransmissionMetricsAreSetForNormalRetransmit) { a.socket.Send(DcSctpMessage(StreamID(1), PPID(53), payload), kSendOptions); a.cb.ConsumeSentPacket(); - AdvanceTime(a, z, a.options.rto_initial); + AdvanceTime(a, z, a.options.rto_initial.ToTimeDelta()); ExchangeMessages(a, z); EXPECT_EQ(a.socket.GetMetrics()->rtx_packets_count, 1u); @@ -2185,7 +2192,7 @@ TEST_P(DcSctpSocketParametrizedTest, CanLoseFirstOrderedMessage) { // First DATA is lost, and retransmission timer will delete it. a.cb.ConsumeSentPacket(); - AdvanceTime(a, *z, a.options.rto_initial); + AdvanceTime(a, *z, a.options.rto_initial.ToTimeDelta()); ExchangeMessages(a, *z); // Send a second message (SID=0, SSN=1). @@ -2574,7 +2581,7 @@ TEST(DcSctpSocketTest, LifecycleEventsAreGeneratedForAckedMessages) { EXPECT_CALL(a.cb, OnLifecycleEnd(LifecycleId(42))); ExchangeMessages(a, z); // In case of delayed ack. - AdvanceTime(a, z, a.options.delayed_ack_max_timeout); + AdvanceTime(a, z, a.options.delayed_ack_max_timeout.ToTimeDelta()); ExchangeMessages(a, z); EXPECT_THAT(GetReceivedMessagePpids(z), ElementsAre(101, 102, 103)); @@ -2617,15 +2624,15 @@ TEST(DcSctpSocketTest, LifecycleEventsForFailMaxRetransmissions) { ExchangeMessages(a, z); // Handle delayed SACK. - AdvanceTime(a, z, a.options.delayed_ack_max_timeout); + AdvanceTime(a, z, a.options.delayed_ack_max_timeout.ToTimeDelta()); ExchangeMessages(a, z); // The chunk is now NACKed. Let the RTO expire, to discard the message. - AdvanceTime(a, z, a.options.rto_initial); + AdvanceTime(a, z, a.options.rto_initial.ToTimeDelta()); ExchangeMessages(a, z); // Handle delayed SACK. - AdvanceTime(a, z, a.options.delayed_ack_max_timeout); + AdvanceTime(a, z, a.options.delayed_ack_max_timeout.ToTimeDelta()); ExchangeMessages(a, z); EXPECT_THAT(GetReceivedMessagePpids(z), ElementsAre(51, 53)); @@ -2672,7 +2679,7 @@ TEST(DcSctpSocketTest, LifecycleEventsForExpiredMessageWithLifetimeLimit) { .lifecycle_id = LifecycleId(1), }); - AdvanceTime(a, z, DurationMs(200)); + AdvanceTime(a, z, TimeDelta::Millis(200)); EXPECT_CALL(a.cb, OnLifecycleMessageExpired(LifecycleId(1), /*maybe_delivered=*/false)); @@ -2769,7 +2776,7 @@ TEST(DcSctpSocketTest, ResetStreamsDeferred) { // Z sent "in progress", which will make A buffer packets until it's sure // that the reconfiguration has been applied. A will retry - wait for that. - AdvanceTime(a, z, a.options.rto_initial); + AdvanceTime(a, z, a.options.rto_initial.ToTimeDelta()); auto reconfig2 = a.cb.ConsumeSentPacket(); EXPECT_THAT(reconfig2, HasChunks(ElementsAre(IsReConfig(HasParameters( @@ -3018,7 +3025,7 @@ TEST(DcSctpSocketTest, HandlesForwardTsnOutOfOrderWithStreamResetting) { HasChunks(ElementsAre( IsDataChunk(AllOf(Property(&DataChunk::ssn, SSN(0)), Property(&DataChunk::ppid, PPID(51))))))); - AdvanceTime(a, z, a.options.rto_initial); + AdvanceTime(a, z, a.options.rto_initial.ToTimeDelta()); auto fwd_tsn_packet = a.cb.ConsumeSentPacket(); EXPECT_THAT(fwd_tsn_packet, diff --git a/third_party/libwebrtc/net/dcsctp/socket/heartbeat_handler.cc b/third_party/libwebrtc/net/dcsctp/socket/heartbeat_handler.cc index 902dff962f..31211e0d13 100644 --- a/third_party/libwebrtc/net/dcsctp/socket/heartbeat_handler.cc +++ b/third_party/libwebrtc/net/dcsctp/socket/heartbeat_handler.cc @@ -21,6 +21,7 @@ #include "absl/strings/string_view.h" #include "absl/types/optional.h" #include "api/array_view.h" +#include "api/units/time_delta.h" #include "net/dcsctp/packet/bounded_byte_reader.h" #include "net/dcsctp/packet/bounded_byte_writer.h" #include "net/dcsctp/packet/chunk/heartbeat_ack_chunk.h" @@ -35,6 +36,8 @@ #include "rtc_base/logging.h" namespace dcsctp { +using ::webrtc::TimeDelta; +using ::webrtc::Timestamp; // This is stored (in serialized form) as HeartbeatInfoParameter sent in // HeartbeatRequestChunk and received back in HeartbeatAckChunk. It should be @@ -49,11 +52,11 @@ class HeartbeatInfo { static constexpr size_t kBufferSize = sizeof(uint64_t); static_assert(kBufferSize == 8, "Unexpected buffer size"); - explicit HeartbeatInfo(TimeMs created_at) : created_at_(created_at) {} + explicit HeartbeatInfo(Timestamp created_at) : created_at_(created_at) {} std::vector Serialize() { - uint32_t high_bits = static_cast(*created_at_ >> 32); - uint32_t low_bits = static_cast(*created_at_); + uint32_t high_bits = static_cast(created_at_.ms() >> 32); + uint32_t low_bits = static_cast(created_at_.ms()); std::vector data(kBufferSize); BoundedByteWriter writer(data); @@ -75,13 +78,13 @@ class HeartbeatInfo { uint32_t low_bits = reader.Load32<4>(); uint64_t created_at = static_cast(high_bits) << 32 | low_bits; - return HeartbeatInfo(TimeMs(created_at)); + return HeartbeatInfo(Timestamp::Millis(created_at)); } - TimeMs created_at() const { return created_at_; } + Timestamp created_at() const { return created_at_; } private: - const TimeMs created_at_; + const Timestamp created_at_; }; HeartbeatHandler::HeartbeatHandler(absl::string_view log_prefix, @@ -91,17 +94,18 @@ HeartbeatHandler::HeartbeatHandler(absl::string_view log_prefix, : log_prefix_(log_prefix), ctx_(context), timer_manager_(timer_manager), - interval_duration_(options.heartbeat_interval), + interval_duration_(options.heartbeat_interval.ToTimeDelta()), interval_duration_should_include_rtt_( options.heartbeat_interval_include_rtt), interval_timer_(timer_manager_->CreateTimer( "heartbeat-interval", absl::bind_front(&HeartbeatHandler::OnIntervalTimerExpiry, this), - TimerOptions(interval_duration_, TimerBackoffAlgorithm::kFixed))), + TimerOptions(interval_duration_, + TimerBackoffAlgorithm::kFixed))), timeout_timer_(timer_manager_->CreateTimer( "heartbeat-timeout", absl::bind_front(&HeartbeatHandler::OnTimeoutTimerExpiry, this), - TimerOptions(options.rto_initial, + TimerOptions(options.rto_initial.ToTimeDelta(), TimerBackoffAlgorithm::kExponential, /*max_restarts=*/0))) { // The interval timer must always be running as long as the association is up. @@ -109,7 +113,7 @@ HeartbeatHandler::HeartbeatHandler(absl::string_view log_prefix, } void HeartbeatHandler::RestartTimer() { - if (interval_duration_ == DurationMs(0)) { + if (interval_duration_.IsZero()) { // Heartbeating has been disabled. return; } @@ -117,7 +121,8 @@ void HeartbeatHandler::RestartTimer() { if (interval_duration_should_include_rtt_) { // The RTT should be used, but it's not easy accessible. The RTO will // suffice. - interval_timer_->set_duration(interval_duration_ + ctx_->current_rto()); + interval_timer_->set_duration( + interval_duration_ + ctx_->current_rto()); } else { interval_timer_->set_duration(interval_duration_); } @@ -153,8 +158,8 @@ void HeartbeatHandler::HandleHeartbeatAck(HeartbeatAckChunk chunk) { return; } - TimeMs now = ctx_->callbacks().TimeMillis(); - if (info->created_at() > TimeMs(0) && info->created_at() <= now) { + Timestamp now = ctx_->callbacks().Now(); + if (info->created_at() > Timestamp::Zero() && info->created_at() <= now) { ctx_->ObserveRTT(now - info->created_at()); } @@ -164,13 +169,13 @@ void HeartbeatHandler::HandleHeartbeatAck(HeartbeatAckChunk chunk) { ctx_->ClearTxErrorCounter(); } -absl::optional HeartbeatHandler::OnIntervalTimerExpiry() { +TimeDelta HeartbeatHandler::OnIntervalTimerExpiry() { if (ctx_->is_connection_established()) { - HeartbeatInfo info(ctx_->callbacks().TimeMillis()); + HeartbeatInfo info(ctx_->callbacks().Now()); timeout_timer_->set_duration(ctx_->current_rto()); timeout_timer_->Start(); RTC_DLOG(LS_INFO) << log_prefix_ << "Sending HEARTBEAT with timeout " - << *timeout_timer_->duration(); + << webrtc::ToString(timeout_timer_->duration()); Parameters parameters = Parameters::Builder() .Add(HeartbeatInfoParameter(info.Serialize())) @@ -183,14 +188,14 @@ absl::optional HeartbeatHandler::OnIntervalTimerExpiry() { << log_prefix_ << "Will not send HEARTBEAT when connection not established"; } - return absl::nullopt; + return TimeDelta::Zero(); } -absl::optional HeartbeatHandler::OnTimeoutTimerExpiry() { +TimeDelta HeartbeatHandler::OnTimeoutTimerExpiry() { // Note that the timeout timer is not restarted. It will be started again when // the interval timer expires. RTC_DCHECK(!timeout_timer_->is_running()); ctx_->IncrementTxErrorCounter("HEARTBEAT timeout"); - return absl::nullopt; + return TimeDelta::Zero(); } } // namespace dcsctp diff --git a/third_party/libwebrtc/net/dcsctp/socket/heartbeat_handler.h b/third_party/libwebrtc/net/dcsctp/socket/heartbeat_handler.h index 318b02955b..ac58b97a64 100644 --- a/third_party/libwebrtc/net/dcsctp/socket/heartbeat_handler.h +++ b/third_party/libwebrtc/net/dcsctp/socket/heartbeat_handler.h @@ -50,14 +50,14 @@ class HeartbeatHandler { void HandleHeartbeatAck(HeartbeatAckChunk chunk); private: - absl::optional OnIntervalTimerExpiry(); - absl::optional OnTimeoutTimerExpiry(); + webrtc::TimeDelta OnIntervalTimerExpiry(); + webrtc::TimeDelta OnTimeoutTimerExpiry(); const absl::string_view log_prefix_; Context* ctx_; TimerManager* timer_manager_; // The time for a connection to be idle before a heartbeat is sent. - const DurationMs interval_duration_; + const webrtc::TimeDelta interval_duration_; // Adding RTT to the duration will add some jitter, which is good in // production, but less good in unit tests, which is why it can be disabled. const bool interval_duration_should_include_rtt_; diff --git a/third_party/libwebrtc/net/dcsctp/socket/heartbeat_handler_test.cc b/third_party/libwebrtc/net/dcsctp/socket/heartbeat_handler_test.cc index d573192440..4475527322 100644 --- a/third_party/libwebrtc/net/dcsctp/socket/heartbeat_handler_test.cc +++ b/third_party/libwebrtc/net/dcsctp/socket/heartbeat_handler_test.cc @@ -30,6 +30,7 @@ using ::testing::IsEmpty; using ::testing::NiceMock; using ::testing::Return; using ::testing::SizeIs; +using ::webrtc::TimeDelta; constexpr DurationMs kHeartbeatInterval = DurationMs(30'000); @@ -51,7 +52,7 @@ class HeartbeatHandlerTestBase : public testing::Test { }), handler_("log: ", options_, &context_, &timer_manager_) {} - void AdvanceTime(DurationMs duration) { + void AdvanceTime(webrtc::TimeDelta duration) { callbacks_.AdvanceTime(duration); for (;;) { absl::optional timeout_id = callbacks_.GetNextExpiredTimeout(); @@ -80,7 +81,7 @@ class DisabledHeartbeatHandlerTest : public HeartbeatHandlerTestBase { }; TEST_F(HeartbeatHandlerTest, HasRunningHeartbeatIntervalTimer) { - AdvanceTime(options_.heartbeat_interval); + AdvanceTime(options_.heartbeat_interval.ToTimeDelta()); // Validate that a heartbeat request was sent. std::vector payload = callbacks_.ConsumeSentPacket(); @@ -119,7 +120,7 @@ TEST_F(HeartbeatHandlerTest, RepliesToHeartbeatRequests) { } TEST_F(HeartbeatHandlerTest, SendsHeartbeatRequestsOnIdleChannel) { - AdvanceTime(options_.heartbeat_interval); + AdvanceTime(options_.heartbeat_interval.ToTimeDelta()); // Grab the request, and make a response. std::vector payload = callbacks_.ConsumeSentPacket(); @@ -134,7 +135,7 @@ TEST_F(HeartbeatHandlerTest, SendsHeartbeatRequestsOnIdleChannel) { HeartbeatAckChunk ack(std::move(req).extract_parameters()); // Respond a while later. This RTT will be measured by the handler - constexpr DurationMs rtt(313); + constexpr TimeDelta rtt = TimeDelta::Millis(313); EXPECT_CALL(context_, ObserveRTT(rtt)).Times(1); @@ -143,7 +144,7 @@ TEST_F(HeartbeatHandlerTest, SendsHeartbeatRequestsOnIdleChannel) { } TEST_F(HeartbeatHandlerTest, DoesntObserveInvalidHeartbeats) { - AdvanceTime(options_.heartbeat_interval); + AdvanceTime(options_.heartbeat_interval.ToTimeDelta()); // Grab the request, and make a response. std::vector payload = callbacks_.ConsumeSentPacket(); @@ -161,15 +162,15 @@ TEST_F(HeartbeatHandlerTest, DoesntObserveInvalidHeartbeats) { // Go backwards in time - which make the HEARTBEAT-ACK have an invalid // timestamp in it, as it will be in the future. - callbacks_.AdvanceTime(DurationMs(-100)); + callbacks_.AdvanceTime(TimeDelta::Millis(-100)); handler_.HandleHeartbeatAck(std::move(ack)); } TEST_F(HeartbeatHandlerTest, IncreasesErrorIfNotAckedInTime) { - DurationMs rto(105); + TimeDelta rto = TimeDelta::Millis(105); EXPECT_CALL(context_, current_rto).WillOnce(Return(rto)); - AdvanceTime(options_.heartbeat_interval); + AdvanceTime(options_.heartbeat_interval.ToTimeDelta()); // Validate that a request was sent. EXPECT_THAT(callbacks_.ConsumeSentPacket(), Not(IsEmpty())); @@ -179,7 +180,7 @@ TEST_F(HeartbeatHandlerTest, IncreasesErrorIfNotAckedInTime) { } TEST_F(DisabledHeartbeatHandlerTest, IsReallyDisabled) { - AdvanceTime(options_.heartbeat_interval); + AdvanceTime(options_.heartbeat_interval.ToTimeDelta()); // Validate that a request was NOT sent. EXPECT_THAT(callbacks_.ConsumeSentPacket(), IsEmpty()); diff --git a/third_party/libwebrtc/net/dcsctp/socket/mock_context.h b/third_party/libwebrtc/net/dcsctp/socket/mock_context.h index 88e71d1b35..bbd9cd17d9 100644 --- a/third_party/libwebrtc/net/dcsctp/socket/mock_context.h +++ b/third_party/libwebrtc/net/dcsctp/socket/mock_context.h @@ -40,7 +40,8 @@ class MockContext : public Context { ON_CALL(*this, peer_initial_tsn) .WillByDefault(testing::Return(PeerInitialTsn())); ON_CALL(*this, callbacks).WillByDefault(testing::ReturnRef(callbacks_)); - ON_CALL(*this, current_rto).WillByDefault(testing::Return(DurationMs(123))); + ON_CALL(*this, current_rto) + .WillByDefault(testing::Return(webrtc::TimeDelta::Millis(123))); ON_CALL(*this, Send).WillByDefault([this](SctpPacket::Builder& builder) { callbacks_.SendPacketWithStatus(builder.Build()); }); @@ -51,8 +52,8 @@ class MockContext : public Context { MOCK_METHOD(TSN, peer_initial_tsn, (), (const, override)); MOCK_METHOD(DcSctpSocketCallbacks&, callbacks, (), (const, override)); - MOCK_METHOD(void, ObserveRTT, (DurationMs rtt_ms), (override)); - MOCK_METHOD(DurationMs, current_rto, (), (const, override)); + MOCK_METHOD(void, ObserveRTT, (webrtc::TimeDelta rtt), (override)); + MOCK_METHOD(webrtc::TimeDelta, current_rto, (), (const, override)); MOCK_METHOD(bool, IncrementTxErrorCounter, (absl::string_view reason), diff --git a/third_party/libwebrtc/net/dcsctp/socket/mock_dcsctp_socket_callbacks.h b/third_party/libwebrtc/net/dcsctp/socket/mock_dcsctp_socket_callbacks.h index 150c1b9fa5..972e547b12 100644 --- a/third_party/libwebrtc/net/dcsctp/socket/mock_dcsctp_socket_callbacks.h +++ b/third_party/libwebrtc/net/dcsctp/socket/mock_dcsctp_socket_callbacks.h @@ -80,7 +80,7 @@ class MockDcSctpSocketCallbacks : public DcSctpSocketCallbacks { << log_prefix_ << "Socket abort: " << ToString(error) << "; " << message; }); - ON_CALL(*this, TimeMillis).WillByDefault([this]() { return now_; }); + ON_CALL(*this, Now).WillByDefault([this]() { return now_; }); } MOCK_METHOD(SendPacketStatus, @@ -94,7 +94,7 @@ class MockDcSctpSocketCallbacks : public DcSctpSocketCallbacks { return timeout_manager_.CreateTimeout(); } - MOCK_METHOD(TimeMs, TimeMillis, (), (override)); + MOCK_METHOD(webrtc::Timestamp, Now, (), (override)); uint32_t GetRandomInt(uint32_t low, uint32_t high) override { return random_.Rand(low, high); } @@ -159,20 +159,20 @@ class MockDcSctpSocketCallbacks : public DcSctpSocketCallbacks { return ret; } - void AdvanceTime(DurationMs duration_ms) { now_ = now_ + duration_ms; } - void SetTime(TimeMs now) { now_ = now; } + void AdvanceTime(webrtc::TimeDelta duration) { now_ = now_ + duration; } + void SetTime(webrtc::Timestamp now) { now_ = now; } absl::optional GetNextExpiredTimeout() { return timeout_manager_.GetNextExpiredTimeout(); } - DurationMs GetTimeToNextTimeout() const { + webrtc::TimeDelta GetTimeToNextTimeout() const { return timeout_manager_.GetTimeToNextTimeout(); } private: const std::string log_prefix_; - TimeMs now_ = TimeMs(0); + webrtc::Timestamp now_ = webrtc::Timestamp::Zero(); webrtc::Random random_; FakeTimeoutManager timeout_manager_; std::deque> sent_packets_; diff --git a/third_party/libwebrtc/net/dcsctp/socket/stream_reset_handler.cc b/third_party/libwebrtc/net/dcsctp/socket/stream_reset_handler.cc index 2094309afe..fafb9933e5 100644 --- a/third_party/libwebrtc/net/dcsctp/socket/stream_reset_handler.cc +++ b/third_party/libwebrtc/net/dcsctp/socket/stream_reset_handler.cc @@ -16,8 +16,8 @@ #include "absl/types/optional.h" #include "api/array_view.h" +#include "api/units/time_delta.h" #include "net/dcsctp/common/internal_types.h" -#include "net/dcsctp/common/str_join.h" #include "net/dcsctp/packet/chunk/reconfig_chunk.h" #include "net/dcsctp/packet/parameter/add_incoming_streams_request_parameter.h" #include "net/dcsctp/packet/parameter/add_outgoing_streams_request_parameter.h" @@ -35,9 +35,11 @@ #include "net/dcsctp/timer/timer.h" #include "net/dcsctp/tx/retransmission_queue.h" #include "rtc_base/logging.h" +#include "rtc_base/strings/str_join.h" namespace dcsctp { namespace { +using ::webrtc::TimeDelta; using ResponseResult = ReconfigurationResponseParameter::Result; bool DescriptorsAre(const std::vector& c, @@ -347,13 +349,13 @@ void StreamResetHandler::ResetStreams( } } -absl::optional StreamResetHandler::OnReconfigTimerExpiry() { +TimeDelta StreamResetHandler::OnReconfigTimerExpiry() { if (current_request_->has_been_sent()) { // There is an outstanding request, which timed out while waiting for a // response. if (!ctx_->IncrementTxErrorCounter("RECONFIG timeout")) { // Timed out. The connection will close after processing the timers. - return absl::nullopt; + return TimeDelta::Zero(); } } else { // There is no outstanding request, but there is a prepared one. This means diff --git a/third_party/libwebrtc/net/dcsctp/socket/stream_reset_handler.h b/third_party/libwebrtc/net/dcsctp/socket/stream_reset_handler.h index c335130175..77e8f3bd97 100644 --- a/third_party/libwebrtc/net/dcsctp/socket/stream_reset_handler.h +++ b/third_party/libwebrtc/net/dcsctp/socket/stream_reset_handler.h @@ -20,6 +20,7 @@ #include "absl/strings/string_view.h" #include "absl/types/optional.h" #include "api/array_view.h" +#include "api/units/time_delta.h" #include "net/dcsctp/common/internal_types.h" #include "net/dcsctp/packet/chunk/reconfig_chunk.h" #include "net/dcsctp/packet/parameter/incoming_ssn_reset_request_parameter.h" @@ -80,7 +81,7 @@ class StreamResetHandler { reconfig_timer_(timer_manager->CreateTimer( "re-config", absl::bind_front(&StreamResetHandler::OnReconfigTimerExpiry, this), - TimerOptions(DurationMs(0)))), + TimerOptions(webrtc::TimeDelta::Zero()))), next_outgoing_req_seq_nbr_( handover_state ? ReconfigRequestSN(handover_state->tx.next_reset_req_sn) @@ -211,7 +212,7 @@ class StreamResetHandler { void HandleResponse(const ParameterDescriptor& descriptor); // Expiration handler for the Reconfig timer. - absl::optional OnReconfigTimerExpiry(); + webrtc::TimeDelta OnReconfigTimerExpiry(); const absl::string_view log_prefix_; Context* ctx_; diff --git a/third_party/libwebrtc/net/dcsctp/socket/stream_reset_handler_test.cc b/third_party/libwebrtc/net/dcsctp/socket/stream_reset_handler_test.cc index 091d717f8a..e675c9bcef 100644 --- a/third_party/libwebrtc/net/dcsctp/socket/stream_reset_handler_test.cc +++ b/third_party/libwebrtc/net/dcsctp/socket/stream_reset_handler_test.cc @@ -48,6 +48,7 @@ using ::testing::Property; using ::testing::Return; using ::testing::SizeIs; using ::testing::UnorderedElementsAre; +using ::webrtc::TimeDelta; using ResponseResult = ReconfigurationResponseParameter::Result; using SkippedStream = AnyForwardTsnChunk::SkippedStream; @@ -57,7 +58,7 @@ constexpr TSN kPeerInitialTsn = MockContext::PeerInitialTsn(); constexpr ReconfigRequestSN kPeerInitialReqSn = ReconfigRequestSN(*kPeerInitialTsn); constexpr uint32_t kArwnd = 131072; -constexpr DurationMs kRto = DurationMs(250); +constexpr TimeDelta kRto = TimeDelta::Millis(250); constexpr std::array kShortPayload = {1, 2, 3, 4}; @@ -97,12 +98,12 @@ class StreamResetHandlerTest : public testing::Test { }), delayed_ack_timer_(timer_manager_.CreateTimer( "test/delayed_ack", - []() { return absl::nullopt; }, - TimerOptions(DurationMs(0)))), + []() { return TimeDelta::Zero(); }, + TimerOptions(TimeDelta::Zero()))), t3_rtx_timer_(timer_manager_.CreateTimer( "test/t3_rtx", - []() { return absl::nullopt; }, - TimerOptions(DurationMs(0)))), + []() { return TimeDelta::Zero(); }, + TimerOptions(TimeDelta::Zero()))), data_tracker_(std::make_unique("log: ", delayed_ack_timer_.get(), kPeerInitialTsn)), @@ -115,7 +116,7 @@ class StreamResetHandlerTest : public testing::Test { kMyInitialTsn, kArwnd, producer_, - [](DurationMs rtt_ms) {}, + [](TimeDelta rtt) {}, []() {}, *t3_rtx_timer_, DcSctpOptions())), @@ -129,8 +130,8 @@ class StreamResetHandlerTest : public testing::Test { EXPECT_CALL(ctx_, current_rto).WillRepeatedly(Return(kRto)); } - void AdvanceTime(DurationMs duration) { - callbacks_.AdvanceTime(kRto); + void AdvanceTime(TimeDelta duration) { + callbacks_.AdvanceTime(duration); for (;;) { absl::optional timeout_id = callbacks_.GetNextExpiredTimeout(); if (!timeout_id.has_value()) { @@ -204,8 +205,8 @@ class StreamResetHandlerTest : public testing::Test { std::make_unique("log: ", kPeerInitialTsn, kArwnd); reasm_->RestoreFromState(state); retransmission_queue_ = std::make_unique( - "", &callbacks_, kMyInitialTsn, kArwnd, producer_, - [](DurationMs rtt_ms) {}, []() {}, *t3_rtx_timer_, DcSctpOptions(), + "", &callbacks_, kMyInitialTsn, kArwnd, producer_, [](TimeDelta rtt) {}, + []() {}, *t3_rtx_timer_, DcSctpOptions(), /*supports_partial_reliability=*/true, /*use_message_interleaving=*/false); retransmission_queue_->RestoreFromState(state); diff --git a/third_party/libwebrtc/net/dcsctp/socket/transmission_control_block.cc b/third_party/libwebrtc/net/dcsctp/socket/transmission_control_block.cc index 0621b48e80..c6c8861e1f 100644 --- a/third_party/libwebrtc/net/dcsctp/socket/transmission_control_block.cc +++ b/third_party/libwebrtc/net/dcsctp/socket/transmission_control_block.cc @@ -17,6 +17,7 @@ #include #include "absl/types/optional.h" +#include "api/units/time_delta.h" #include "net/dcsctp/packet/chunk/data_chunk.h" #include "net/dcsctp/packet/chunk/forward_tsn_chunk.h" #include "net/dcsctp/packet/chunk/idata_chunk.h" @@ -37,6 +38,8 @@ #include "rtc_base/strings/string_builder.h" namespace dcsctp { +using ::webrtc::TimeDelta; +using ::webrtc::Timestamp; TransmissionControlBlock::TransmissionControlBlock( TimerManager& timer_manager, @@ -61,20 +64,20 @@ TransmissionControlBlock::TransmissionControlBlock( t3_rtx_(timer_manager_.CreateTimer( "t3-rtx", absl::bind_front(&TransmissionControlBlock::OnRtxTimerExpiry, this), - TimerOptions(options.rto_initial, + TimerOptions(options.rto_initial.ToTimeDelta(), TimerBackoffAlgorithm::kExponential, /*max_restarts=*/absl::nullopt, options.max_timer_backoff_duration.has_value() - ? *options.max_timer_backoff_duration - : DurationMs::InfiniteDuration()))), + ? options.max_timer_backoff_duration->ToTimeDelta() + : TimeDelta::PlusInfinity()))), delayed_ack_timer_(timer_manager_.CreateTimer( "delayed-ack", absl::bind_front(&TransmissionControlBlock::OnDelayedAckTimerExpiry, this), - TimerOptions(options.delayed_ack_max_timeout, + TimerOptions(options.delayed_ack_max_timeout.ToTimeDelta(), TimerBackoffAlgorithm::kExponential, /*max_restarts=*/0, - /*max_backoff_duration=*/DurationMs::InfiniteDuration(), + /*max_backoff_duration=*/TimeDelta::PlusInfinity(), webrtc::TaskQueueBase::DelayPrecision::kHigh))), my_verification_tag_(my_verification_tag), my_initial_tsn_(my_initial_tsn), @@ -112,21 +115,22 @@ TransmissionControlBlock::TransmissionControlBlock( send_queue.EnableMessageInterleaving(capabilities.message_interleaving); } -void TransmissionControlBlock::ObserveRTT(DurationMs rtt) { - DurationMs prev_rto = rto_.rto(); +void TransmissionControlBlock::ObserveRTT(TimeDelta rtt) { + TimeDelta prev_rto = rto_.rto(); rto_.ObserveRTT(rtt); - RTC_DLOG(LS_VERBOSE) << log_prefix_ << "new rtt=" << *rtt - << ", srtt=" << *rto_.srtt() << ", rto=" << *rto_.rto() - << " (" << *prev_rto << ")"; + RTC_DLOG(LS_VERBOSE) << log_prefix_ << "new rtt=" << webrtc::ToString(rtt) + << ", srtt=" << webrtc::ToString(rto_.srtt()) + << ", rto=" << webrtc::ToString(rto_.rto()) << " (" + << webrtc::ToString(prev_rto) << ")"; t3_rtx_->set_duration(rto_.rto()); - DurationMs delayed_ack_tmo = - std::min(rto_.rto() * 0.5, options_.delayed_ack_max_timeout); + TimeDelta delayed_ack_tmo = std::min( + rto_.rto() * 0.5, options_.delayed_ack_max_timeout.ToTimeDelta()); delayed_ack_timer_->set_duration(delayed_ack_tmo); } -absl::optional TransmissionControlBlock::OnRtxTimerExpiry() { - TimeMs now = callbacks_.TimeMillis(); +TimeDelta TransmissionControlBlock::OnRtxTimerExpiry() { + Timestamp now = callbacks_.Now(); RTC_DLOG(LS_INFO) << log_prefix_ << "Timer " << t3_rtx_->name() << " has expired"; if (cookie_echo_chunk_.has_value()) { @@ -139,13 +143,13 @@ absl::optional TransmissionControlBlock::OnRtxTimerExpiry() { SendBufferedPackets(now); } } - return absl::nullopt; + return TimeDelta::Zero(); } -absl::optional TransmissionControlBlock::OnDelayedAckTimerExpiry() { +TimeDelta TransmissionControlBlock::OnDelayedAckTimerExpiry() { data_tracker_.HandleDelayedAckTimerExpiry(); MaybeSendSack(); - return absl::nullopt; + return TimeDelta::Zero(); } void TransmissionControlBlock::MaybeSendSack() { @@ -158,7 +162,7 @@ void TransmissionControlBlock::MaybeSendSack() { } void TransmissionControlBlock::MaybeSendForwardTsn(SctpPacket::Builder& builder, - TimeMs now) { + Timestamp now) { if (now >= limit_forward_tsn_until_ && retransmission_queue_.ShouldSendForwardTsn(now)) { if (capabilities_.message_interleaving) { @@ -173,7 +177,8 @@ void TransmissionControlBlock::MaybeSendForwardTsn(SctpPacket::Builder& builder, // sending a duplicate FORWARD TSN." // "Any delay applied to the sending of FORWARD TSN chunk SHOULD NOT exceed // 200ms and MUST NOT exceed 500ms". - limit_forward_tsn_until_ = now + std::min(DurationMs(200), rto_.srtt()); + limit_forward_tsn_until_ = + now + std::min(TimeDelta::Millis(200), rto_.srtt()); } } @@ -205,7 +210,7 @@ void TransmissionControlBlock::MaybeSendFastRetransmit() { } void TransmissionControlBlock::SendBufferedPackets(SctpPacket::Builder& builder, - TimeMs now) { + Timestamp now) { for (int packet_idx = 0; packet_idx < options_.max_burst && retransmission_queue_.can_send_data(); ++packet_idx) { diff --git a/third_party/libwebrtc/net/dcsctp/socket/transmission_control_block.h b/third_party/libwebrtc/net/dcsctp/socket/transmission_control_block.h index 46a39d5a7b..f8b2445525 100644 --- a/third_party/libwebrtc/net/dcsctp/socket/transmission_control_block.h +++ b/third_party/libwebrtc/net/dcsctp/socket/transmission_control_block.h @@ -67,8 +67,8 @@ class TransmissionControlBlock : public Context { TSN my_initial_tsn() const override { return my_initial_tsn_; } TSN peer_initial_tsn() const override { return peer_initial_tsn_; } DcSctpSocketCallbacks& callbacks() const override { return callbacks_; } - void ObserveRTT(DurationMs rtt) override; - DurationMs current_rto() const override { return rto_.rto(); } + void ObserveRTT(webrtc::TimeDelta rtt) override; + webrtc::TimeDelta current_rto() const override { return rto_.rto(); } bool IncrementTxErrorCounter(absl::string_view reason) override { return tx_error_counter_.Increment(reason); } @@ -91,7 +91,7 @@ class TransmissionControlBlock : public Context { StreamResetHandler& stream_reset_handler() { return stream_reset_handler_; } HeartbeatHandler& heartbeat_handler() { return heartbeat_handler_; } size_t cwnd() const { return retransmission_queue_.cwnd(); } - DurationMs current_srtt() const { return rto_.srtt(); } + webrtc::TimeDelta current_srtt() const { return rto_.srtt(); } // Returns this socket's verification tag, set in all packet headers. VerificationTag my_verification_tag() const { return my_verification_tag_; } @@ -108,7 +108,7 @@ class TransmissionControlBlock : public Context { void MaybeSendSack(); // Sends a FORWARD-TSN, if it is needed and allowed (rate-limited). - void MaybeSendForwardTsn(SctpPacket::Builder& builder, TimeMs now); + void MaybeSendForwardTsn(SctpPacket::Builder& builder, webrtc::Timestamp now); // Will be set while the socket is in kCookieEcho state. In this state, there // can only be a single packet outstanding, and it must contain the COOKIE @@ -129,12 +129,12 @@ class TransmissionControlBlock : public Context { // Fills `builder` (which may already be filled with control chunks) with // other control and data chunks, and sends packets as much as can be // allowed by the congestion control algorithm. - void SendBufferedPackets(SctpPacket::Builder& builder, TimeMs now); + void SendBufferedPackets(SctpPacket::Builder& builder, webrtc::Timestamp now); // As above, but without passing in a builder. If `cookie_echo_chunk_` is // present, then only one packet will be sent, with this chunk as the first // chunk. - void SendBufferedPackets(TimeMs now) { + void SendBufferedPackets(webrtc::Timestamp now) { SctpPacket::Builder builder(peer_verification_tag_, options_); SendBufferedPackets(builder, now); } @@ -149,9 +149,9 @@ class TransmissionControlBlock : public Context { private: // Will be called when the retransmission timer (t3-rtx) expires. - absl::optional OnRtxTimerExpiry(); + webrtc::TimeDelta OnRtxTimerExpiry(); // Will be called when the delayed ack timer expires. - absl::optional OnDelayedAckTimerExpiry(); + webrtc::TimeDelta OnDelayedAckTimerExpiry(); const absl::string_view log_prefix_; const DcSctpOptions options_; @@ -172,7 +172,7 @@ class TransmissionControlBlock : public Context { const std::function is_connection_established_; PacketSender& packet_sender_; // Rate limiting of FORWARD-TSN. Next can be sent at or after this timestamp. - TimeMs limit_forward_tsn_until_ = TimeMs(0); + webrtc::Timestamp limit_forward_tsn_until_ = webrtc::Timestamp::Zero(); RetransmissionTimeout rto_; RetransmissionErrorCounter tx_error_counter_; -- cgit v1.2.3