Reland "Add thread guards to JsepTransport"
This reverts commit caedb5db82b2bc8273910f4a0d1afb1d0e2994f3. Reason for revert: Fixed issue (allow SetNeedsIceRestart from off-thread). Original change's description: > Revert "Add thread guards to JsepTransport" > > This reverts commit 7e1db52c93c57a180073906eda6a58919a9fd537. > > Reason for revert: Breaks downstream. > > Original change's description: > > Add thread guards to JsepTransport > > > > This ensures that JsepTransport's methods are either only accessed on the thread > > that creates it, or using methods that are marked for off-thread use > > (using a lock to prevent simultaneous access). > > > > The intent is to document the existing contract, and to make it easy to find the > > actions needed to convert the class to a pure single-threaded class. > > > > Bug: webrtc:10300 > > Change-Id: Ib5cdc027632c36baec55179937d6eb664bbaf6f5 > > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/121946 > > Commit-Queue: Harald Alvestrand <hta@webrtc.org> > > Reviewed-by: Karl Wiberg <kwiberg@webrtc.org> > > Reviewed-by: Henrik Boström <hbos@webrtc.org> > > Cr-Commit-Position: refs/heads/master@{#27427} > > TBR=steveanton@webrtc.org,solenberg@webrtc.org,kwiberg@webrtc.org,hbos@webrtc.org,hta@webrtc.org > > Change-Id: I30c65d2161de9376ccd1172e2b261f2280fb1d75 > No-Presubmit: true > No-Tree-Checks: true > No-Try: true > Bug: webrtc:10300 > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/130519 > Reviewed-by: Gustaf Ullberg <gustaf@webrtc.org> > Commit-Queue: Gustaf Ullberg <gustaf@webrtc.org> > Cr-Commit-Position: refs/heads/master@{#27429} Change-Id: Ic32bfc04d96e657fc67c3d3999f77969e55ed994 Bug: webrtc:10300 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/130962 Reviewed-by: Karl Wiberg <kwiberg@webrtc.org> Reviewed-by: Harald Alvestrand <hta@webrtc.org> Commit-Queue: Harald Alvestrand <hta@webrtc.org> Cr-Commit-Position: refs/heads/master@{#27434}
This commit is contained in:

committed by
Commit Bot

parent
33d2a91737
commit
78a5e96001
@ -99,8 +99,12 @@ JsepTransport::JsepTransport(
|
|||||||
std::unique_ptr<DtlsTransportInternal> rtp_dtls_transport,
|
std::unique_ptr<DtlsTransportInternal> rtp_dtls_transport,
|
||||||
std::unique_ptr<DtlsTransportInternal> rtcp_dtls_transport,
|
std::unique_ptr<DtlsTransportInternal> rtcp_dtls_transport,
|
||||||
std::unique_ptr<webrtc::MediaTransportInterface> media_transport)
|
std::unique_ptr<webrtc::MediaTransportInterface> media_transport)
|
||||||
: mid_(mid),
|
: network_thread_(rtc::Thread::Current()),
|
||||||
|
mid_(mid),
|
||||||
local_certificate_(local_certificate),
|
local_certificate_(local_certificate),
|
||||||
|
unencrypted_rtp_transport_(std::move(unencrypted_rtp_transport)),
|
||||||
|
sdes_transport_(std::move(sdes_transport)),
|
||||||
|
dtls_srtp_transport_(std::move(dtls_srtp_transport)),
|
||||||
rtp_dtls_transport_(
|
rtp_dtls_transport_(
|
||||||
rtp_dtls_transport ? new rtc::RefCountedObject<webrtc::DtlsTransport>(
|
rtp_dtls_transport ? new rtc::RefCountedObject<webrtc::DtlsTransport>(
|
||||||
std::move(rtp_dtls_transport))
|
std::move(rtp_dtls_transport))
|
||||||
@ -112,19 +116,17 @@ JsepTransport::JsepTransport(
|
|||||||
: nullptr),
|
: nullptr),
|
||||||
media_transport_(std::move(media_transport)) {
|
media_transport_(std::move(media_transport)) {
|
||||||
RTC_DCHECK(rtp_dtls_transport_);
|
RTC_DCHECK(rtp_dtls_transport_);
|
||||||
if (unencrypted_rtp_transport) {
|
// Verify the "only one out of these three can be set" invariant.
|
||||||
|
if (unencrypted_rtp_transport_) {
|
||||||
RTC_DCHECK(!sdes_transport);
|
RTC_DCHECK(!sdes_transport);
|
||||||
RTC_DCHECK(!dtls_srtp_transport);
|
RTC_DCHECK(!dtls_srtp_transport);
|
||||||
unencrypted_rtp_transport_ = std::move(unencrypted_rtp_transport);
|
} else if (sdes_transport_) {
|
||||||
} else if (sdes_transport) {
|
|
||||||
RTC_DCHECK(!unencrypted_rtp_transport);
|
RTC_DCHECK(!unencrypted_rtp_transport);
|
||||||
RTC_DCHECK(!dtls_srtp_transport);
|
RTC_DCHECK(!dtls_srtp_transport);
|
||||||
sdes_transport_ = std::move(sdes_transport);
|
|
||||||
} else {
|
} else {
|
||||||
RTC_DCHECK(dtls_srtp_transport);
|
RTC_DCHECK(dtls_srtp_transport_);
|
||||||
RTC_DCHECK(!unencrypted_rtp_transport);
|
RTC_DCHECK(!unencrypted_rtp_transport);
|
||||||
RTC_DCHECK(!sdes_transport);
|
RTC_DCHECK(!sdes_transport);
|
||||||
dtls_srtp_transport_ = std::move(dtls_srtp_transport);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (media_transport_) {
|
if (media_transport_) {
|
||||||
@ -152,6 +154,7 @@ webrtc::RTCError JsepTransport::SetLocalJsepTransportDescription(
|
|||||||
SdpType type) {
|
SdpType type) {
|
||||||
webrtc::RTCError error;
|
webrtc::RTCError error;
|
||||||
|
|
||||||
|
RTC_DCHECK_RUN_ON(network_thread_);
|
||||||
if (!VerifyIceParams(jsep_description)) {
|
if (!VerifyIceParams(jsep_description)) {
|
||||||
return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
|
return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
|
||||||
"Invalid ice-ufrag or ice-pwd length.");
|
"Invalid ice-ufrag or ice-pwd length.");
|
||||||
@ -179,7 +182,6 @@ webrtc::RTCError JsepTransport::SetLocalJsepTransportDescription(
|
|||||||
dtls_srtp_transport_->UpdateRecvEncryptedHeaderExtensionIds(
|
dtls_srtp_transport_->UpdateRecvEncryptedHeaderExtensionIds(
|
||||||
jsep_description.encrypted_header_extension_ids);
|
jsep_description.encrypted_header_extension_ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ice_restarting =
|
bool ice_restarting =
|
||||||
local_description_ != nullptr &&
|
local_description_ != nullptr &&
|
||||||
IceCredentialsChanged(local_description_->transport_desc.ice_ufrag,
|
IceCredentialsChanged(local_description_->transport_desc.ice_ufrag,
|
||||||
@ -194,13 +196,14 @@ webrtc::RTCError JsepTransport::SetLocalJsepTransportDescription(
|
|||||||
if (!local_fp) {
|
if (!local_fp) {
|
||||||
local_certificate_ = nullptr;
|
local_certificate_ = nullptr;
|
||||||
} else {
|
} else {
|
||||||
error = VerifyCertificateFingerprint(local_certificate_.get(), local_fp);
|
error = VerifyCertificateFingerprint(local_certificate_, local_fp);
|
||||||
if (!error.ok()) {
|
if (!error.ok()) {
|
||||||
local_description_.reset();
|
local_description_.reset();
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
rtc::CritScope scope(&accessor_lock_);
|
||||||
RTC_DCHECK(rtp_dtls_transport_->internal());
|
RTC_DCHECK(rtp_dtls_transport_->internal());
|
||||||
SetLocalIceParameters(rtp_dtls_transport_->internal()->ice_transport());
|
SetLocalIceParameters(rtp_dtls_transport_->internal()->ice_transport());
|
||||||
|
|
||||||
@ -208,7 +211,7 @@ webrtc::RTCError JsepTransport::SetLocalJsepTransportDescription(
|
|||||||
RTC_DCHECK(rtcp_dtls_transport_->internal());
|
RTC_DCHECK(rtcp_dtls_transport_->internal());
|
||||||
SetLocalIceParameters(rtcp_dtls_transport_->internal()->ice_transport());
|
SetLocalIceParameters(rtcp_dtls_transport_->internal()->ice_transport());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// If PRANSWER/ANSWER is set, we should decide transport protocol type.
|
// If PRANSWER/ANSWER is set, we should decide transport protocol type.
|
||||||
if (type == SdpType::kPrAnswer || type == SdpType::kAnswer) {
|
if (type == SdpType::kPrAnswer || type == SdpType::kAnswer) {
|
||||||
error = NegotiateAndSetDtlsParameters(type);
|
error = NegotiateAndSetDtlsParameters(type);
|
||||||
@ -217,12 +220,14 @@ webrtc::RTCError JsepTransport::SetLocalJsepTransportDescription(
|
|||||||
local_description_.reset();
|
local_description_.reset();
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
rtc::CritScope scope(&accessor_lock_);
|
||||||
if (needs_ice_restart_ && ice_restarting) {
|
if (needs_ice_restart_ && ice_restarting) {
|
||||||
needs_ice_restart_ = false;
|
needs_ice_restart_ = false;
|
||||||
RTC_LOG(LS_VERBOSE) << "needs-ice-restart flag cleared for transport "
|
RTC_LOG(LS_VERBOSE) << "needs-ice-restart flag cleared for transport "
|
||||||
<< mid();
|
<< mid();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return webrtc::RTCError::OK();
|
return webrtc::RTCError::OK();
|
||||||
}
|
}
|
||||||
@ -232,6 +237,7 @@ webrtc::RTCError JsepTransport::SetRemoteJsepTransportDescription(
|
|||||||
webrtc::SdpType type) {
|
webrtc::SdpType type) {
|
||||||
webrtc::RTCError error;
|
webrtc::RTCError error;
|
||||||
|
|
||||||
|
RTC_DCHECK_RUN_ON(network_thread_);
|
||||||
if (!VerifyIceParams(jsep_description)) {
|
if (!VerifyIceParams(jsep_description)) {
|
||||||
remote_description_.reset();
|
remote_description_.reset();
|
||||||
return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
|
return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
|
||||||
@ -266,12 +272,11 @@ webrtc::RTCError JsepTransport::SetRemoteJsepTransportDescription(
|
|||||||
}
|
}
|
||||||
|
|
||||||
remote_description_.reset(new JsepTransportDescription(jsep_description));
|
remote_description_.reset(new JsepTransportDescription(jsep_description));
|
||||||
RTC_DCHECK(rtp_dtls_transport_->internal());
|
RTC_DCHECK(rtp_dtls_transport());
|
||||||
SetRemoteIceParameters(rtp_dtls_transport_->internal()->ice_transport());
|
SetRemoteIceParameters(rtp_dtls_transport()->ice_transport());
|
||||||
|
|
||||||
if (rtcp_dtls_transport_) {
|
if (rtcp_dtls_transport()) {
|
||||||
RTC_DCHECK(rtcp_dtls_transport_->internal());
|
SetRemoteIceParameters(rtcp_dtls_transport()->ice_transport());
|
||||||
SetRemoteIceParameters(rtcp_dtls_transport_->internal()->ice_transport());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If PRANSWER/ANSWER is set, we should decide transport protocol type.
|
// If PRANSWER/ANSWER is set, we should decide transport protocol type.
|
||||||
@ -287,6 +292,7 @@ webrtc::RTCError JsepTransport::SetRemoteJsepTransportDescription(
|
|||||||
|
|
||||||
webrtc::RTCError JsepTransport::AddRemoteCandidates(
|
webrtc::RTCError JsepTransport::AddRemoteCandidates(
|
||||||
const Candidates& candidates) {
|
const Candidates& candidates) {
|
||||||
|
RTC_DCHECK_RUN_ON(network_thread_);
|
||||||
if (!local_description_ || !remote_description_) {
|
if (!local_description_ || !remote_description_) {
|
||||||
return webrtc::RTCError(webrtc::RTCErrorType::INVALID_STATE,
|
return webrtc::RTCError(webrtc::RTCErrorType::INVALID_STATE,
|
||||||
mid() +
|
mid() +
|
||||||
@ -312,6 +318,7 @@ webrtc::RTCError JsepTransport::AddRemoteCandidates(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void JsepTransport::SetNeedsIceRestartFlag() {
|
void JsepTransport::SetNeedsIceRestartFlag() {
|
||||||
|
rtc::CritScope scope(&accessor_lock_);
|
||||||
if (!needs_ice_restart_) {
|
if (!needs_ice_restart_) {
|
||||||
needs_ice_restart_ = true;
|
needs_ice_restart_ = true;
|
||||||
RTC_LOG(LS_VERBOSE) << "needs-ice-restart flag set for transport " << mid();
|
RTC_LOG(LS_VERBOSE) << "needs-ice-restart flag set for transport " << mid();
|
||||||
@ -319,6 +326,8 @@ void JsepTransport::SetNeedsIceRestartFlag() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
absl::optional<rtc::SSLRole> JsepTransport::GetDtlsRole() const {
|
absl::optional<rtc::SSLRole> JsepTransport::GetDtlsRole() const {
|
||||||
|
RTC_DCHECK_RUN_ON(network_thread_);
|
||||||
|
rtc::CritScope scope(&accessor_lock_);
|
||||||
RTC_DCHECK(rtp_dtls_transport_);
|
RTC_DCHECK(rtp_dtls_transport_);
|
||||||
RTC_DCHECK(rtp_dtls_transport_->internal());
|
RTC_DCHECK(rtp_dtls_transport_->internal());
|
||||||
rtc::SSLRole dtls_role;
|
rtc::SSLRole dtls_role;
|
||||||
@ -330,6 +339,8 @@ absl::optional<rtc::SSLRole> JsepTransport::GetDtlsRole() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool JsepTransport::GetStats(TransportStats* stats) {
|
bool JsepTransport::GetStats(TransportStats* stats) {
|
||||||
|
RTC_DCHECK_RUN_ON(network_thread_);
|
||||||
|
rtc::CritScope scope(&accessor_lock_);
|
||||||
stats->transport_name = mid();
|
stats->transport_name = mid();
|
||||||
stats->channel_stats.clear();
|
stats->channel_stats.clear();
|
||||||
RTC_DCHECK(rtp_dtls_transport_->internal());
|
RTC_DCHECK(rtp_dtls_transport_->internal());
|
||||||
@ -344,6 +355,7 @@ bool JsepTransport::GetStats(TransportStats* stats) {
|
|||||||
webrtc::RTCError JsepTransport::VerifyCertificateFingerprint(
|
webrtc::RTCError JsepTransport::VerifyCertificateFingerprint(
|
||||||
const rtc::RTCCertificate* certificate,
|
const rtc::RTCCertificate* certificate,
|
||||||
const rtc::SSLFingerprint* fingerprint) const {
|
const rtc::SSLFingerprint* fingerprint) const {
|
||||||
|
RTC_DCHECK_RUN_ON(network_thread_);
|
||||||
if (!fingerprint) {
|
if (!fingerprint) {
|
||||||
return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
|
return webrtc::RTCError(webrtc::RTCErrorType::INVALID_PARAMETER,
|
||||||
"No fingerprint");
|
"No fingerprint");
|
||||||
@ -369,6 +381,8 @@ webrtc::RTCError JsepTransport::VerifyCertificateFingerprint(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void JsepTransport::SetActiveResetSrtpParams(bool active_reset_srtp_params) {
|
void JsepTransport::SetActiveResetSrtpParams(bool active_reset_srtp_params) {
|
||||||
|
RTC_DCHECK_RUN_ON(network_thread_);
|
||||||
|
rtc::CritScope scope(&accessor_lock_);
|
||||||
if (dtls_srtp_transport_) {
|
if (dtls_srtp_transport_) {
|
||||||
RTC_LOG(INFO)
|
RTC_LOG(INFO)
|
||||||
<< "Setting active_reset_srtp_params of DtlsSrtpTransport to: "
|
<< "Setting active_reset_srtp_params of DtlsSrtpTransport to: "
|
||||||
@ -378,6 +392,7 @@ void JsepTransport::SetActiveResetSrtpParams(bool active_reset_srtp_params) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void JsepTransport::SetLocalIceParameters(IceTransportInternal* ice_transport) {
|
void JsepTransport::SetLocalIceParameters(IceTransportInternal* ice_transport) {
|
||||||
|
RTC_DCHECK_RUN_ON(network_thread_);
|
||||||
RTC_DCHECK(ice_transport);
|
RTC_DCHECK(ice_transport);
|
||||||
RTC_DCHECK(local_description_);
|
RTC_DCHECK(local_description_);
|
||||||
ice_transport->SetIceParameters(
|
ice_transport->SetIceParameters(
|
||||||
@ -386,6 +401,7 @@ void JsepTransport::SetLocalIceParameters(IceTransportInternal* ice_transport) {
|
|||||||
|
|
||||||
void JsepTransport::SetRemoteIceParameters(
|
void JsepTransport::SetRemoteIceParameters(
|
||||||
IceTransportInternal* ice_transport) {
|
IceTransportInternal* ice_transport) {
|
||||||
|
RTC_DCHECK_RUN_ON(network_thread_);
|
||||||
RTC_DCHECK(ice_transport);
|
RTC_DCHECK(ice_transport);
|
||||||
RTC_DCHECK(remote_description_);
|
RTC_DCHECK(remote_description_);
|
||||||
ice_transport->SetRemoteIceParameters(
|
ice_transport->SetRemoteIceParameters(
|
||||||
@ -397,6 +413,7 @@ webrtc::RTCError JsepTransport::SetNegotiatedDtlsParameters(
|
|||||||
DtlsTransportInternal* dtls_transport,
|
DtlsTransportInternal* dtls_transport,
|
||||||
absl::optional<rtc::SSLRole> dtls_role,
|
absl::optional<rtc::SSLRole> dtls_role,
|
||||||
rtc::SSLFingerprint* remote_fingerprint) {
|
rtc::SSLFingerprint* remote_fingerprint) {
|
||||||
|
RTC_DCHECK_RUN_ON(network_thread_);
|
||||||
RTC_DCHECK(dtls_transport);
|
RTC_DCHECK(dtls_transport);
|
||||||
// Set SSL role. Role must be set before fingerprint is applied, which
|
// Set SSL role. Role must be set before fingerprint is applied, which
|
||||||
// initiates DTLS setup.
|
// initiates DTLS setup.
|
||||||
@ -418,6 +435,7 @@ webrtc::RTCError JsepTransport::SetNegotiatedDtlsParameters(
|
|||||||
bool JsepTransport::SetRtcpMux(bool enable,
|
bool JsepTransport::SetRtcpMux(bool enable,
|
||||||
webrtc::SdpType type,
|
webrtc::SdpType type,
|
||||||
ContentSource source) {
|
ContentSource source) {
|
||||||
|
RTC_DCHECK_RUN_ON(network_thread_);
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case SdpType::kOffer:
|
case SdpType::kOffer:
|
||||||
@ -448,6 +466,12 @@ bool JsepTransport::SetRtcpMux(bool enable,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void JsepTransport::ActivateRtcpMux() {
|
void JsepTransport::ActivateRtcpMux() {
|
||||||
|
{
|
||||||
|
// Don't hold the network_thread_ lock while calling other functions,
|
||||||
|
// since they might call other functions that call RTC_DCHECK_RUN_ON.
|
||||||
|
// TODO(https://crbug.com/webrtc/10318): Simplify when possible.
|
||||||
|
RTC_DCHECK_RUN_ON(network_thread_);
|
||||||
|
}
|
||||||
if (unencrypted_rtp_transport_) {
|
if (unencrypted_rtp_transport_) {
|
||||||
RTC_DCHECK(!sdes_transport_);
|
RTC_DCHECK(!sdes_transport_);
|
||||||
RTC_DCHECK(!dtls_srtp_transport_);
|
RTC_DCHECK(!dtls_srtp_transport_);
|
||||||
@ -463,7 +487,10 @@ void JsepTransport::ActivateRtcpMux() {
|
|||||||
dtls_srtp_transport_->SetDtlsTransports(rtp_dtls_transport(),
|
dtls_srtp_transport_->SetDtlsTransports(rtp_dtls_transport(),
|
||||||
/*rtcp_dtls_transport=*/nullptr);
|
/*rtcp_dtls_transport=*/nullptr);
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
rtc::CritScope scope(&accessor_lock_);
|
||||||
rtcp_dtls_transport_ = nullptr; // Destroy this reference.
|
rtcp_dtls_transport_ = nullptr; // Destroy this reference.
|
||||||
|
}
|
||||||
// Notify the JsepTransportController to update the aggregate states.
|
// Notify the JsepTransportController to update the aggregate states.
|
||||||
SignalRtcpMuxActive();
|
SignalRtcpMuxActive();
|
||||||
}
|
}
|
||||||
@ -472,6 +499,8 @@ bool JsepTransport::SetSdes(const std::vector<CryptoParams>& cryptos,
|
|||||||
const std::vector<int>& encrypted_extension_ids,
|
const std::vector<int>& encrypted_extension_ids,
|
||||||
webrtc::SdpType type,
|
webrtc::SdpType type,
|
||||||
ContentSource source) {
|
ContentSource source) {
|
||||||
|
RTC_DCHECK_RUN_ON(network_thread_);
|
||||||
|
rtc::CritScope scope(&accessor_lock_);
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
ret = sdes_negotiator_.Process(cryptos, type, source);
|
ret = sdes_negotiator_.Process(cryptos, type, source);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
@ -514,6 +543,7 @@ bool JsepTransport::SetSdes(const std::vector<CryptoParams>& cryptos,
|
|||||||
|
|
||||||
webrtc::RTCError JsepTransport::NegotiateAndSetDtlsParameters(
|
webrtc::RTCError JsepTransport::NegotiateAndSetDtlsParameters(
|
||||||
SdpType local_description_type) {
|
SdpType local_description_type) {
|
||||||
|
RTC_DCHECK_RUN_ON(network_thread_);
|
||||||
if (!local_description_ || !remote_description_) {
|
if (!local_description_ || !remote_description_) {
|
||||||
return webrtc::RTCError(webrtc::RTCErrorType::INVALID_STATE,
|
return webrtc::RTCError(webrtc::RTCErrorType::INVALID_STATE,
|
||||||
"Applying an answer transport description "
|
"Applying an answer transport description "
|
||||||
@ -550,19 +580,16 @@ webrtc::RTCError JsepTransport::NegotiateAndSetDtlsParameters(
|
|||||||
// between future SetRemote/SetLocal invocations and new transport
|
// between future SetRemote/SetLocal invocations and new transport
|
||||||
// creation, we have the negotiation state saved until a new
|
// creation, we have the negotiation state saved until a new
|
||||||
// negotiation happens.
|
// negotiation happens.
|
||||||
RTC_DCHECK(rtp_dtls_transport_->internal());
|
RTC_DCHECK(rtp_dtls_transport());
|
||||||
webrtc::RTCError error = SetNegotiatedDtlsParameters(
|
webrtc::RTCError error = SetNegotiatedDtlsParameters(
|
||||||
rtp_dtls_transport_->internal(), negotiated_dtls_role,
|
rtp_dtls_transport(), negotiated_dtls_role, remote_fingerprint.get());
|
||||||
remote_fingerprint.get());
|
|
||||||
if (!error.ok()) {
|
if (!error.ok()) {
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rtcp_dtls_transport_) {
|
if (rtcp_dtls_transport()) {
|
||||||
RTC_DCHECK(rtcp_dtls_transport_->internal());
|
error = SetNegotiatedDtlsParameters(
|
||||||
error = SetNegotiatedDtlsParameters(rtcp_dtls_transport_->internal(),
|
rtcp_dtls_transport(), negotiated_dtls_role, remote_fingerprint.get());
|
||||||
negotiated_dtls_role,
|
|
||||||
remote_fingerprint.get());
|
|
||||||
}
|
}
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
@ -657,6 +684,8 @@ webrtc::RTCError JsepTransport::NegotiateDtlsRole(
|
|||||||
|
|
||||||
bool JsepTransport::GetTransportStats(DtlsTransportInternal* dtls_transport,
|
bool JsepTransport::GetTransportStats(DtlsTransportInternal* dtls_transport,
|
||||||
TransportStats* stats) {
|
TransportStats* stats) {
|
||||||
|
RTC_DCHECK_RUN_ON(network_thread_);
|
||||||
|
rtc::CritScope scope(&accessor_lock_);
|
||||||
RTC_DCHECK(dtls_transport);
|
RTC_DCHECK(dtls_transport);
|
||||||
TransportChannelStats substats;
|
TransportChannelStats substats;
|
||||||
if (rtcp_dtls_transport_) {
|
if (rtcp_dtls_transport_) {
|
||||||
@ -681,7 +710,11 @@ void JsepTransport::OnStateChanged(webrtc::MediaTransportState state) {
|
|||||||
// TODO(bugs.webrtc.org/9719) This method currently fires on the network
|
// TODO(bugs.webrtc.org/9719) This method currently fires on the network
|
||||||
// thread, but media transport does not make such guarantees. We need to make
|
// thread, but media transport does not make such guarantees. We need to make
|
||||||
// sure this callback is guaranteed to be executed on the network thread.
|
// sure this callback is guaranteed to be executed on the network thread.
|
||||||
|
RTC_DCHECK_RUN_ON(network_thread_);
|
||||||
|
{
|
||||||
|
rtc::CritScope scope(&accessor_lock_);
|
||||||
media_transport_state_ = state;
|
media_transport_state_ = state;
|
||||||
|
}
|
||||||
SignalMediaTransportStateChanged();
|
SignalMediaTransportStateChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include "rtc_base/rtc_certificate.h"
|
#include "rtc_base/rtc_certificate.h"
|
||||||
#include "rtc_base/ssl_stream_adapter.h"
|
#include "rtc_base/ssl_stream_adapter.h"
|
||||||
#include "rtc_base/third_party/sigslot/sigslot.h"
|
#include "rtc_base/third_party/sigslot/sigslot.h"
|
||||||
|
#include "rtc_base/thread_checker.h"
|
||||||
|
|
||||||
namespace cricket {
|
namespace cricket {
|
||||||
|
|
||||||
@ -101,11 +102,13 @@ class JsepTransport : public sigslot::has_slots<>,
|
|||||||
// Needed in order to verify the local fingerprint.
|
// Needed in order to verify the local fingerprint.
|
||||||
void SetLocalCertificate(
|
void SetLocalCertificate(
|
||||||
const rtc::scoped_refptr<rtc::RTCCertificate>& local_certificate) {
|
const rtc::scoped_refptr<rtc::RTCCertificate>& local_certificate) {
|
||||||
|
RTC_DCHECK_RUN_ON(network_thread_);
|
||||||
local_certificate_ = local_certificate;
|
local_certificate_ = local_certificate;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the local certificate provided by SetLocalCertificate.
|
// Return the local certificate provided by SetLocalCertificate.
|
||||||
rtc::scoped_refptr<rtc::RTCCertificate> GetLocalCertificate() const {
|
rtc::scoped_refptr<rtc::RTCCertificate> GetLocalCertificate() const {
|
||||||
|
RTC_DCHECK_RUN_ON(network_thread_);
|
||||||
return local_certificate_;
|
return local_certificate_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,7 +133,10 @@ class JsepTransport : public sigslot::has_slots<>,
|
|||||||
// Returns true if the ICE restart flag above was set, and no ICE restart has
|
// Returns true if the ICE restart flag above was set, and no ICE restart has
|
||||||
// occurred yet for this transport (by applying a local description with
|
// occurred yet for this transport (by applying a local description with
|
||||||
// changed ufrag/password).
|
// changed ufrag/password).
|
||||||
bool needs_ice_restart() const { return needs_ice_restart_; }
|
bool needs_ice_restart() const {
|
||||||
|
rtc::CritScope scope(&accessor_lock_);
|
||||||
|
return needs_ice_restart_;
|
||||||
|
}
|
||||||
|
|
||||||
// Returns role if negotiated, or empty absl::optional if it hasn't been
|
// Returns role if negotiated, or empty absl::optional if it hasn't been
|
||||||
// negotiated yet.
|
// negotiated yet.
|
||||||
@ -140,14 +146,19 @@ class JsepTransport : public sigslot::has_slots<>,
|
|||||||
bool GetStats(TransportStats* stats);
|
bool GetStats(TransportStats* stats);
|
||||||
|
|
||||||
const JsepTransportDescription* local_description() const {
|
const JsepTransportDescription* local_description() const {
|
||||||
|
RTC_DCHECK_RUN_ON(network_thread_);
|
||||||
return local_description_.get();
|
return local_description_.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
const JsepTransportDescription* remote_description() const {
|
const JsepTransportDescription* remote_description() const {
|
||||||
|
RTC_DCHECK_RUN_ON(network_thread_);
|
||||||
return remote_description_.get();
|
return remote_description_.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
webrtc::RtpTransportInternal* rtp_transport() const {
|
webrtc::RtpTransportInternal* rtp_transport() const {
|
||||||
|
// This method is called from the signaling thread, which means
|
||||||
|
// that a race is possible, making safety analysis complex.
|
||||||
|
// After fixing, this method should be marked "network thread only".
|
||||||
if (dtls_srtp_transport_) {
|
if (dtls_srtp_transport_) {
|
||||||
return dtls_srtp_transport_.get();
|
return dtls_srtp_transport_.get();
|
||||||
} else if (sdes_transport_) {
|
} else if (sdes_transport_) {
|
||||||
@ -158,6 +169,7 @@ class JsepTransport : public sigslot::has_slots<>,
|
|||||||
}
|
}
|
||||||
|
|
||||||
const DtlsTransportInternal* rtp_dtls_transport() const {
|
const DtlsTransportInternal* rtp_dtls_transport() const {
|
||||||
|
rtc::CritScope scope(&accessor_lock_);
|
||||||
if (rtp_dtls_transport_) {
|
if (rtp_dtls_transport_) {
|
||||||
return rtp_dtls_transport_->internal();
|
return rtp_dtls_transport_->internal();
|
||||||
} else {
|
} else {
|
||||||
@ -166,6 +178,7 @@ class JsepTransport : public sigslot::has_slots<>,
|
|||||||
}
|
}
|
||||||
|
|
||||||
DtlsTransportInternal* rtp_dtls_transport() {
|
DtlsTransportInternal* rtp_dtls_transport() {
|
||||||
|
rtc::CritScope scope(&accessor_lock_);
|
||||||
if (rtp_dtls_transport_) {
|
if (rtp_dtls_transport_) {
|
||||||
return rtp_dtls_transport_->internal();
|
return rtp_dtls_transport_->internal();
|
||||||
} else {
|
} else {
|
||||||
@ -174,6 +187,7 @@ class JsepTransport : public sigslot::has_slots<>,
|
|||||||
}
|
}
|
||||||
|
|
||||||
const DtlsTransportInternal* rtcp_dtls_transport() const {
|
const DtlsTransportInternal* rtcp_dtls_transport() const {
|
||||||
|
rtc::CritScope scope(&accessor_lock_);
|
||||||
if (rtcp_dtls_transport_) {
|
if (rtcp_dtls_transport_) {
|
||||||
return rtcp_dtls_transport_->internal();
|
return rtcp_dtls_transport_->internal();
|
||||||
} else {
|
} else {
|
||||||
@ -182,6 +196,7 @@ class JsepTransport : public sigslot::has_slots<>,
|
|||||||
}
|
}
|
||||||
|
|
||||||
DtlsTransportInternal* rtcp_dtls_transport() {
|
DtlsTransportInternal* rtcp_dtls_transport() {
|
||||||
|
rtc::CritScope scope(&accessor_lock_);
|
||||||
if (rtcp_dtls_transport_) {
|
if (rtcp_dtls_transport_) {
|
||||||
return rtcp_dtls_transport_->internal();
|
return rtcp_dtls_transport_->internal();
|
||||||
} else {
|
} else {
|
||||||
@ -190,6 +205,7 @@ class JsepTransport : public sigslot::has_slots<>,
|
|||||||
}
|
}
|
||||||
|
|
||||||
rtc::scoped_refptr<webrtc::DtlsTransport> RtpDtlsTransport() {
|
rtc::scoped_refptr<webrtc::DtlsTransport> RtpDtlsTransport() {
|
||||||
|
rtc::CritScope scope(&accessor_lock_);
|
||||||
return rtp_dtls_transport_;
|
return rtp_dtls_transport_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,11 +213,13 @@ class JsepTransport : public sigslot::has_slots<>,
|
|||||||
// Note that media transport is owned by jseptransport and the pointer
|
// Note that media transport is owned by jseptransport and the pointer
|
||||||
// to media transport will becomes invalid after destruction of jseptransport.
|
// to media transport will becomes invalid after destruction of jseptransport.
|
||||||
webrtc::MediaTransportInterface* media_transport() const {
|
webrtc::MediaTransportInterface* media_transport() const {
|
||||||
|
rtc::CritScope scope(&accessor_lock_);
|
||||||
return media_transport_.get();
|
return media_transport_.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the latest media transport state.
|
// Returns the latest media transport state.
|
||||||
webrtc::MediaTransportState media_transport_state() const {
|
webrtc::MediaTransportState media_transport_state() const {
|
||||||
|
rtc::CritScope scope(&accessor_lock_);
|
||||||
return media_transport_state_;
|
return media_transport_state_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -271,36 +289,51 @@ class JsepTransport : public sigslot::has_slots<>,
|
|||||||
// Invoked whenever the state of the media transport changes.
|
// Invoked whenever the state of the media transport changes.
|
||||||
void OnStateChanged(webrtc::MediaTransportState state) override;
|
void OnStateChanged(webrtc::MediaTransportState state) override;
|
||||||
|
|
||||||
|
// Owning thread, for safety checks
|
||||||
|
const rtc::Thread* const network_thread_;
|
||||||
|
// Critical scope for fields accessed off-thread
|
||||||
|
// TODO(https://bugs.webrtc.org/10300): Stop doing this.
|
||||||
|
rtc::CriticalSection accessor_lock_;
|
||||||
const std::string mid_;
|
const std::string mid_;
|
||||||
// needs-ice-restart bit as described in JSEP.
|
// needs-ice-restart bit as described in JSEP.
|
||||||
bool needs_ice_restart_ = false;
|
bool needs_ice_restart_ RTC_GUARDED_BY(accessor_lock_) = false;
|
||||||
rtc::scoped_refptr<rtc::RTCCertificate> local_certificate_;
|
rtc::scoped_refptr<rtc::RTCCertificate> local_certificate_
|
||||||
std::unique_ptr<JsepTransportDescription> local_description_;
|
RTC_GUARDED_BY(network_thread_);
|
||||||
std::unique_ptr<JsepTransportDescription> remote_description_;
|
std::unique_ptr<JsepTransportDescription> local_description_
|
||||||
|
RTC_GUARDED_BY(network_thread_);
|
||||||
|
std::unique_ptr<JsepTransportDescription> remote_description_
|
||||||
|
RTC_GUARDED_BY(network_thread_);
|
||||||
|
|
||||||
// To avoid downcasting and make it type safe, keep three unique pointers for
|
// To avoid downcasting and make it type safe, keep three unique pointers for
|
||||||
// different SRTP mode and only one of these is non-nullptr.
|
// different SRTP mode and only one of these is non-nullptr.
|
||||||
std::unique_ptr<webrtc::RtpTransport> unencrypted_rtp_transport_;
|
// Since these are const, the variables don't need locks;
|
||||||
std::unique_ptr<webrtc::SrtpTransport> sdes_transport_;
|
// accessing the objects depends on the objects' thread safety contract.
|
||||||
std::unique_ptr<webrtc::DtlsSrtpTransport> dtls_srtp_transport_;
|
const std::unique_ptr<webrtc::RtpTransport> unencrypted_rtp_transport_;
|
||||||
|
const std::unique_ptr<webrtc::SrtpTransport> sdes_transport_;
|
||||||
|
const std::unique_ptr<webrtc::DtlsSrtpTransport> dtls_srtp_transport_;
|
||||||
|
|
||||||
rtc::scoped_refptr<webrtc::DtlsTransport> rtp_dtls_transport_;
|
rtc::scoped_refptr<webrtc::DtlsTransport> rtp_dtls_transport_
|
||||||
rtc::scoped_refptr<webrtc::DtlsTransport> rtcp_dtls_transport_;
|
RTC_GUARDED_BY(accessor_lock_);
|
||||||
|
rtc::scoped_refptr<webrtc::DtlsTransport> rtcp_dtls_transport_
|
||||||
|
RTC_GUARDED_BY(accessor_lock_);
|
||||||
|
|
||||||
SrtpFilter sdes_negotiator_;
|
SrtpFilter sdes_negotiator_ RTC_GUARDED_BY(network_thread_);
|
||||||
RtcpMuxFilter rtcp_mux_negotiator_;
|
RtcpMuxFilter rtcp_mux_negotiator_ RTC_GUARDED_BY(network_thread_);
|
||||||
|
|
||||||
// Cache the encrypted header extension IDs for SDES negoitation.
|
// Cache the encrypted header extension IDs for SDES negoitation.
|
||||||
absl::optional<std::vector<int>> send_extension_ids_;
|
absl::optional<std::vector<int>> send_extension_ids_
|
||||||
absl::optional<std::vector<int>> recv_extension_ids_;
|
RTC_GUARDED_BY(network_thread_);
|
||||||
|
absl::optional<std::vector<int>> recv_extension_ids_
|
||||||
|
RTC_GUARDED_BY(network_thread_);
|
||||||
|
|
||||||
// Optional media transport (experimental).
|
// Optional media transport (experimental).
|
||||||
std::unique_ptr<webrtc::MediaTransportInterface> media_transport_;
|
std::unique_ptr<webrtc::MediaTransportInterface> media_transport_
|
||||||
|
RTC_GUARDED_BY(accessor_lock_);
|
||||||
|
|
||||||
// If |media_transport_| is provided, this variable represents the state of
|
// If |media_transport_| is provided, this variable represents the state of
|
||||||
// media transport.
|
// media transport.
|
||||||
webrtc::MediaTransportState media_transport_state_ =
|
webrtc::MediaTransportState media_transport_state_
|
||||||
webrtc::MediaTransportState::kPending;
|
RTC_GUARDED_BY(accessor_lock_) = webrtc::MediaTransportState::kPending;
|
||||||
|
|
||||||
RTC_DISALLOW_COPY_AND_ASSIGN(JsepTransport);
|
RTC_DISALLOW_COPY_AND_ASSIGN(JsepTransport);
|
||||||
};
|
};
|
||||||
|
@ -747,6 +747,24 @@ TEST_P(PeerConnectionEndToEndTest, TooManyDataChannelsOpenedBeforeConnecting) {
|
|||||||
|
|
||||||
#endif // HAVE_SCTP
|
#endif // HAVE_SCTP
|
||||||
|
|
||||||
|
TEST_P(PeerConnectionEndToEndTest, CanRestartIce) {
|
||||||
|
rtc::scoped_refptr<webrtc::AudioDecoderFactory> real_decoder_factory =
|
||||||
|
webrtc::CreateBuiltinAudioDecoderFactory();
|
||||||
|
CreatePcs(webrtc::CreateBuiltinAudioEncoderFactory(),
|
||||||
|
CreateForwardingMockDecoderFactory(real_decoder_factory.get()));
|
||||||
|
GetAndAddUserMedia();
|
||||||
|
Negotiate();
|
||||||
|
WaitForCallEstablished();
|
||||||
|
// Cause ICE restart to be requested.
|
||||||
|
auto config = caller_->pc()->GetConfiguration();
|
||||||
|
ASSERT_NE(PeerConnectionInterface::kRelay, config.type);
|
||||||
|
config.type = PeerConnectionInterface::kRelay;
|
||||||
|
webrtc::RTCError error;
|
||||||
|
ASSERT_TRUE(caller_->pc()->SetConfiguration(config, &error));
|
||||||
|
// When solving https://crbug.com/webrtc/10504, all we need to check
|
||||||
|
// is that we do not crash. We should also be testing that restart happens.
|
||||||
|
}
|
||||||
|
|
||||||
INSTANTIATE_TEST_SUITE_P(PeerConnectionEndToEndTest,
|
INSTANTIATE_TEST_SUITE_P(PeerConnectionEndToEndTest,
|
||||||
PeerConnectionEndToEndTest,
|
PeerConnectionEndToEndTest,
|
||||||
Values(SdpSemantics::kPlanB,
|
Values(SdpSemantics::kPlanB,
|
||||||
|
Reference in New Issue
Block a user