dcsctp: Add sequence checker to socket
The DcSctpSocket is not thread safe and must be called from a single
thread or from a task queue that serializes access to it. This is now
validated at run-time in debug builds.
Bug: None
Change-Id: I3ed816924c20f6ed7e84a3273bee5a3f8f74112b
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/233420
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Commit-Queue: Victor Boivie <boivie@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#35127}
diff --git a/net/dcsctp/socket/dcsctp_socket.cc b/net/dcsctp/socket/dcsctp_socket.cc
index 1001813..8153910 100644
--- a/net/dcsctp/socket/dcsctp_socket.cc
+++ b/net/dcsctp/socket/dcsctp_socket.cc
@@ -281,6 +281,7 @@
}
void DcSctpSocket::Connect() {
+ RTC_DCHECK_RUN_ON(&thread_checker_);
CallbackDeferrer::ScopedDeferrer deferrer(callbacks_);
if (state_ == State::kClosed) {
@@ -301,6 +302,7 @@
}
void DcSctpSocket::RestoreFromState(const DcSctpSocketHandoverState& state) {
+ RTC_DCHECK_RUN_ON(&thread_checker_);
CallbackDeferrer::ScopedDeferrer deferrer(callbacks_);
if (state_ != State::kClosed) {
@@ -340,6 +342,7 @@
}
void DcSctpSocket::Shutdown() {
+ RTC_DCHECK_RUN_ON(&thread_checker_);
CallbackDeferrer::ScopedDeferrer deferrer(callbacks_);
if (tcb_ != nullptr) {
@@ -368,6 +371,7 @@
}
void DcSctpSocket::Close() {
+ RTC_DCHECK_RUN_ON(&thread_checker_);
CallbackDeferrer::ScopedDeferrer deferrer(callbacks_);
if (state_ != State::kClosed) {
@@ -415,6 +419,7 @@
SendStatus DcSctpSocket::Send(DcSctpMessage message,
const SendOptions& send_options) {
+ RTC_DCHECK_RUN_ON(&thread_checker_);
CallbackDeferrer::ScopedDeferrer deferrer(callbacks_);
if (message.payload().empty()) {
@@ -456,6 +461,7 @@
ResetStreamsStatus DcSctpSocket::ResetStreams(
rtc::ArrayView<const StreamID> outgoing_streams) {
+ RTC_DCHECK_RUN_ON(&thread_checker_);
CallbackDeferrer::ScopedDeferrer deferrer(callbacks_);
if (tcb_ == nullptr) {
@@ -483,6 +489,7 @@
}
SocketState DcSctpSocket::state() const {
+ RTC_DCHECK_RUN_ON(&thread_checker_);
switch (state_) {
case State::kClosed:
return SocketState::kClosed;
@@ -504,23 +511,28 @@
}
void DcSctpSocket::SetMaxMessageSize(size_t max_message_size) {
+ RTC_DCHECK_RUN_ON(&thread_checker_);
options_.max_message_size = max_message_size;
}
size_t DcSctpSocket::buffered_amount(StreamID stream_id) const {
+ RTC_DCHECK_RUN_ON(&thread_checker_);
return send_queue_.buffered_amount(stream_id);
}
size_t DcSctpSocket::buffered_amount_low_threshold(StreamID stream_id) const {
+ RTC_DCHECK_RUN_ON(&thread_checker_);
return send_queue_.buffered_amount_low_threshold(stream_id);
}
void DcSctpSocket::SetBufferedAmountLowThreshold(StreamID stream_id,
size_t bytes) {
+ RTC_DCHECK_RUN_ON(&thread_checker_);
send_queue_.SetBufferedAmountLowThreshold(stream_id, bytes);
}
Metrics DcSctpSocket::GetMetrics() const {
+ RTC_DCHECK_RUN_ON(&thread_checker_);
Metrics metrics = metrics_;
if (tcb_ != nullptr) {
@@ -660,6 +672,7 @@
}
void DcSctpSocket::HandleTimeout(TimeoutID timeout_id) {
+ RTC_DCHECK_RUN_ON(&thread_checker_);
CallbackDeferrer::ScopedDeferrer deferrer(callbacks_);
timer_manager_.HandleTimeout(timeout_id);
@@ -673,6 +686,7 @@
}
void DcSctpSocket::ReceivePacket(rtc::ArrayView<const uint8_t> data) {
+ RTC_DCHECK_RUN_ON(&thread_checker_);
CallbackDeferrer::ScopedDeferrer deferrer(callbacks_);
++metrics_.rx_packets_count;
@@ -1639,6 +1653,7 @@
}
HandoverReadinessStatus DcSctpSocket::GetHandoverReadiness() const {
+ RTC_DCHECK_RUN_ON(&thread_checker_);
HandoverReadinessStatus status;
if (state_ != State::kClosed && state_ != State::kEstablished) {
status.Add(HandoverUnreadinessReason::kWrongConnectionState);
@@ -1652,6 +1667,7 @@
absl::optional<DcSctpSocketHandoverState>
DcSctpSocket::GetHandoverStateAndClose() {
+ RTC_DCHECK_RUN_ON(&thread_checker_);
CallbackDeferrer::ScopedDeferrer deferrer(callbacks_);
if (!GetHandoverReadiness().IsReady()) {
diff --git a/net/dcsctp/socket/dcsctp_socket.h b/net/dcsctp/socket/dcsctp_socket.h
index c249864..b1b3ea9 100644
--- a/net/dcsctp/socket/dcsctp_socket.h
+++ b/net/dcsctp/socket/dcsctp_socket.h
@@ -17,6 +17,7 @@
#include "absl/strings/string_view.h"
#include "api/array_view.h"
+#include "api/sequence_checker.h"
#include "net/dcsctp/packet/chunk/abort_chunk.h"
#include "net/dcsctp/packet/chunk/chunk.h"
#include "net/dcsctp/packet/chunk/cookie_ack_chunk.h"
@@ -253,6 +254,7 @@
const std::string log_prefix_;
const std::unique_ptr<PacketObserver> packet_observer_;
+ RTC_NO_UNIQUE_ADDRESS webrtc::SequenceChecker thread_checker_;
Metrics metrics_;
DcSctpOptions options_;