This reverts commit 6b143c1c0686519bc9d73223c1350cee286c8d78. Reason for revert: Relanding with updated expectations for SctpTransport::Information based on TransceiverStateSurfacer in Chromium. Original change's description: > Revert "Fix unsynchronized access to mid_to_transport_ in JsepTransportController" > > This reverts commit 6cd405850467683cf10d05028ea0f644a68a91a4. > > Reason for revert: Breaks WebRTC Chromium FYI Bots > > First failure: > https://ci.chromium.org/p/chromium/builders/webrtc.fyi/WebRTC%20Chromium%20FYI%20Android%20Tests%20%28dbg%29%20%28L%20Nexus5%29/1925 > > Failed tests: > WebRtcDataBrowserTest.CallWithSctpDataAndMedia > WebRtcDataBrowserTest.CallWithSctpDataOnly > > Original change's description: > > Fix unsynchronized access to mid_to_transport_ in JsepTransportController > > > > * Added several thread checks to JTC to help with programmer errors. > > * Avoid a few Invokes() to the network thread here and there such > > as for fetching sctp transport name for getStats(). The transport > > name is now cached when it changes on the network thread. > > * JsepTransportController instances now get deleted on the network > > thread rather than on the signaling thread + issuing an Invoke() > > in the dtor. > > * Moved some thread hops from JTC over to PC which is where the problem > > exists and also (imho) makes it easier to see where hops happen in > > the PC code. > > * The sctp transport is now started asynchronously when we push down the > > media description. > > * PeerConnection proxy calls GetSctpTransport directly on the network > > thread instead of to the signaling thread + blocking on the network > > thread. > > * The above changes simplified things for webrtc::SctpTransport which > > allowed for removing locking from that class and delete some code. > > > > Bug: webrtc:9987, webrtc:12445 > > Change-Id: Ic89a9426e314e1b93c81751d4f732f05fa448fbc > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/205620 > > Commit-Queue: Tommi <tommi@webrtc.org> > > Reviewed-by: Harald Alvestrand <hta@webrtc.org> > > Cr-Commit-Position: refs/heads/master@{#33191} > > TBR=tommi@webrtc.org,hta@webrtc.org > > Change-Id: I7b2913d5133807589461105cf07eff3e9bb7157e > No-Presubmit: true > No-Tree-Checks: true > No-Try: true > Bug: webrtc:9987 > Bug: webrtc:12445 > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/206466 > Reviewed-by: Guido Urdaneta <guidou@webrtc.org> > Commit-Queue: Guido Urdaneta <guidou@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#33204} TBR=tommi@webrtc.org,hta@webrtc.org,guidou@webrtc.org # Not skipping CQ checks because this is a reland. Bug: webrtc:9987 Bug: webrtc:12445 Change-Id: Icb205cbac493ed3b881d71ea3af4fb9018701bf4 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/206560 Reviewed-by: Tommi <tommi@webrtc.org> Reviewed-by: Guido Urdaneta <guidou@webrtc.org> Commit-Queue: Tommi <tommi@webrtc.org> Cr-Commit-Position: refs/heads/master@{#33219}
169 lines
5.7 KiB
C++
169 lines
5.7 KiB
C++
/*
|
|
* Copyright 2018 The WebRTC project authors. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree. An additional intellectual property rights grant can be found
|
|
* in the file PATENTS. All contributing project authors may
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
*/
|
|
|
|
#include "pc/sctp_transport.h"
|
|
|
|
#include <algorithm>
|
|
#include <utility>
|
|
|
|
#include "absl/types/optional.h"
|
|
#include "rtc_base/checks.h"
|
|
#include "rtc_base/location.h"
|
|
#include "rtc_base/logging.h"
|
|
#include "rtc_base/synchronization/sequence_checker.h"
|
|
|
|
namespace webrtc {
|
|
|
|
SctpTransport::SctpTransport(
|
|
std::unique_ptr<cricket::SctpTransportInternal> internal)
|
|
: owner_thread_(rtc::Thread::Current()),
|
|
info_(SctpTransportState::kNew),
|
|
internal_sctp_transport_(std::move(internal)) {
|
|
RTC_DCHECK(internal_sctp_transport_.get());
|
|
internal_sctp_transport_->SignalAssociationChangeCommunicationUp.connect(
|
|
this, &SctpTransport::OnAssociationChangeCommunicationUp);
|
|
// TODO(https://bugs.webrtc.org/10360): Add handlers for transport closing.
|
|
|
|
if (dtls_transport_) {
|
|
UpdateInformation(SctpTransportState::kConnecting);
|
|
} else {
|
|
UpdateInformation(SctpTransportState::kNew);
|
|
}
|
|
}
|
|
|
|
SctpTransport::~SctpTransport() {
|
|
// We depend on the network thread to call Clear() before dropping
|
|
// its last reference to this object.
|
|
RTC_DCHECK(owner_thread_->IsCurrent() || !internal_sctp_transport_);
|
|
}
|
|
|
|
SctpTransportInformation SctpTransport::Information() const {
|
|
// TODO(tommi): Update PeerConnection::GetSctpTransport to hand out a proxy
|
|
// to the transport so that we can be sure that methods get called on the
|
|
// expected thread. Chromium currently calls this method from
|
|
// TransceiverStateSurfacer.
|
|
if (!owner_thread_->IsCurrent()) {
|
|
return owner_thread_->Invoke<SctpTransportInformation>(
|
|
RTC_FROM_HERE, [this] { return Information(); });
|
|
}
|
|
RTC_DCHECK_RUN_ON(owner_thread_);
|
|
return info_;
|
|
}
|
|
|
|
void SctpTransport::RegisterObserver(SctpTransportObserverInterface* observer) {
|
|
RTC_DCHECK_RUN_ON(owner_thread_);
|
|
RTC_DCHECK(observer);
|
|
RTC_DCHECK(!observer_);
|
|
observer_ = observer;
|
|
}
|
|
|
|
void SctpTransport::UnregisterObserver() {
|
|
RTC_DCHECK_RUN_ON(owner_thread_);
|
|
observer_ = nullptr;
|
|
}
|
|
|
|
rtc::scoped_refptr<DtlsTransportInterface> SctpTransport::dtls_transport()
|
|
const {
|
|
RTC_DCHECK_RUN_ON(owner_thread_);
|
|
return dtls_transport_;
|
|
}
|
|
|
|
// Internal functions
|
|
void SctpTransport::Clear() {
|
|
RTC_DCHECK_RUN_ON(owner_thread_);
|
|
RTC_DCHECK(internal());
|
|
// Note that we delete internal_sctp_transport_, but
|
|
// only drop the reference to dtls_transport_.
|
|
dtls_transport_ = nullptr;
|
|
internal_sctp_transport_ = nullptr;
|
|
UpdateInformation(SctpTransportState::kClosed);
|
|
}
|
|
|
|
void SctpTransport::SetDtlsTransport(
|
|
rtc::scoped_refptr<DtlsTransport> transport) {
|
|
RTC_DCHECK_RUN_ON(owner_thread_);
|
|
SctpTransportState next_state = info_.state();
|
|
dtls_transport_ = transport;
|
|
if (internal_sctp_transport_) {
|
|
if (transport) {
|
|
internal_sctp_transport_->SetDtlsTransport(transport->internal());
|
|
transport->internal()->SignalDtlsState.connect(
|
|
this, &SctpTransport::OnDtlsStateChange);
|
|
if (info_.state() == SctpTransportState::kNew) {
|
|
next_state = SctpTransportState::kConnecting;
|
|
}
|
|
} else {
|
|
internal_sctp_transport_->SetDtlsTransport(nullptr);
|
|
}
|
|
}
|
|
|
|
UpdateInformation(next_state);
|
|
}
|
|
|
|
void SctpTransport::Start(int local_port,
|
|
int remote_port,
|
|
int max_message_size) {
|
|
RTC_DCHECK_RUN_ON(owner_thread_);
|
|
info_ = SctpTransportInformation(info_.state(), info_.dtls_transport(),
|
|
max_message_size, info_.MaxChannels());
|
|
|
|
if (!internal()->Start(local_port, remote_port, max_message_size)) {
|
|
RTC_LOG(LS_ERROR) << "Failed to push down SCTP parameters, closing.";
|
|
UpdateInformation(SctpTransportState::kClosed);
|
|
}
|
|
}
|
|
|
|
void SctpTransport::UpdateInformation(SctpTransportState state) {
|
|
RTC_DCHECK_RUN_ON(owner_thread_);
|
|
bool must_send_update = (state != info_.state());
|
|
// TODO(https://bugs.webrtc.org/10358): Update max channels from internal
|
|
// SCTP transport when available.
|
|
if (internal_sctp_transport_) {
|
|
info_ = SctpTransportInformation(
|
|
state, dtls_transport_, info_.MaxMessageSize(), info_.MaxChannels());
|
|
} else {
|
|
info_ = SctpTransportInformation(
|
|
state, dtls_transport_, info_.MaxMessageSize(), info_.MaxChannels());
|
|
}
|
|
|
|
if (observer_ && must_send_update) {
|
|
observer_->OnStateChange(info_);
|
|
}
|
|
}
|
|
|
|
void SctpTransport::OnAssociationChangeCommunicationUp() {
|
|
RTC_DCHECK_RUN_ON(owner_thread_);
|
|
RTC_DCHECK(internal_sctp_transport_);
|
|
if (internal_sctp_transport_->max_outbound_streams() &&
|
|
internal_sctp_transport_->max_inbound_streams()) {
|
|
int max_channels =
|
|
std::min(*(internal_sctp_transport_->max_outbound_streams()),
|
|
*(internal_sctp_transport_->max_inbound_streams()));
|
|
// Record max channels.
|
|
info_ = SctpTransportInformation(info_.state(), info_.dtls_transport(),
|
|
info_.MaxMessageSize(), max_channels);
|
|
}
|
|
|
|
UpdateInformation(SctpTransportState::kConnected);
|
|
}
|
|
|
|
void SctpTransport::OnDtlsStateChange(cricket::DtlsTransportInternal* transport,
|
|
cricket::DtlsTransportState state) {
|
|
RTC_DCHECK_RUN_ON(owner_thread_);
|
|
RTC_CHECK(transport == dtls_transport_->internal());
|
|
if (state == cricket::DTLS_TRANSPORT_CLOSED ||
|
|
state == cricket::DTLS_TRANSPORT_FAILED) {
|
|
UpdateInformation(SctpTransportState::kClosed);
|
|
// TODO(http://bugs.webrtc.org/11090): Close all the data channels
|
|
}
|
|
}
|
|
|
|
} // namespace webrtc
|