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