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}
This commit is contained in:
Victor Boivie 2021-09-29 22:23:15 +02:00 committed by WebRTC LUCI CQ
parent fe903d5eab
commit 5755f3edaf
2 changed files with 18 additions and 0 deletions

View file

@ -281,6 +281,7 @@ void DcSctpSocket::MakeConnectionParameters() {
}
void DcSctpSocket::Connect() {
RTC_DCHECK_RUN_ON(&thread_checker_);
CallbackDeferrer::ScopedDeferrer deferrer(callbacks_);
if (state_ == State::kClosed) {
@ -301,6 +302,7 @@ void DcSctpSocket::Connect() {
}
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::RestoreFromState(const DcSctpSocketHandoverState& state) {
}
void DcSctpSocket::Shutdown() {
RTC_DCHECK_RUN_ON(&thread_checker_);
CallbackDeferrer::ScopedDeferrer deferrer(callbacks_);
if (tcb_ != nullptr) {
@ -368,6 +371,7 @@ void DcSctpSocket::Shutdown() {
}
void DcSctpSocket::Close() {
RTC_DCHECK_RUN_ON(&thread_checker_);
CallbackDeferrer::ScopedDeferrer deferrer(callbacks_);
if (state_ != State::kClosed) {
@ -415,6 +419,7 @@ void DcSctpSocket::InternalClose(ErrorKind error, absl::string_view message) {
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 @@ SendStatus DcSctpSocket::Send(DcSctpMessage message,
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 @@ ResetStreamsStatus DcSctpSocket::ResetStreams(
}
SocketState DcSctpSocket::state() const {
RTC_DCHECK_RUN_ON(&thread_checker_);
switch (state_) {
case State::kClosed:
return SocketState::kClosed;
@ -504,23 +511,28 @@ SocketState DcSctpSocket::state() const {
}
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 @@ bool DcSctpSocket::ValidatePacket(const SctpPacket& packet) {
}
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::HandleTimeout(TimeoutID timeout_id) {
}
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 @@ void DcSctpSocket::SendShutdownAck() {
}
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 @@ HandoverReadinessStatus DcSctpSocket::GetHandoverReadiness() const {
absl::optional<DcSctpSocketHandoverState>
DcSctpSocket::GetHandoverStateAndClose() {
RTC_DCHECK_RUN_ON(&thread_checker_);
CallbackDeferrer::ScopedDeferrer deferrer(callbacks_);
if (!GetHandoverReadiness().IsReady()) {

View file

@ -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 @@ class DcSctpSocket : public DcSctpSocketInterface {
const std::string log_prefix_;
const std::unique_ptr<PacketObserver> packet_observer_;
RTC_NO_UNIQUE_ADDRESS webrtc::SequenceChecker thread_checker_;
Metrics metrics_;
DcSctpOptions options_;