#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "third_party/blink/renderer/modules/peerconnection/rtc_peer_connection.h"
#include <algorithm>
#include <memory>
#include <optional>
#include <string>
#include <utility>
#include "base/feature_list.h"
#include "base/lazy_instance.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
#include "base/notreached.h"
#include "base/numerics/safe_conversions.h"
#include "base/task/single_thread_task_runner.h"
#include "base/task/thread_pool.h"
#include "build/build_config.h"
#include "build/buildflag.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom-blink.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/public/platform/web_crypto_algorithm_params.h"
#include "third_party/blink/public/web/web_local_frame.h"
#include "third_party/blink/renderer/bindings/core/v8/dictionary.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/bindings/core/v8/script_value.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_union_object_string.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_union_string_stringsequence.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_void_function.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_media_stream_track.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_answer_options.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_certificate.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_configuration.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_data_channel_init.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_ice_candidate_init.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_ice_server.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_offer_options.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_peer_connection_error_callback.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_rtp_transceiver_init.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_session_description_callback.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_rtc_session_description_init.h"
#include "third_party/blink/renderer/bindings/modules/v8/v8_union_mediastreamtrack_string.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/dom/dom_time_stamp.h"
#include "third_party/blink/renderer/core/execution_context/agent.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
#include "third_party/blink/renderer/core/frame/deprecation/deprecation.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
#include "third_party/blink/renderer/core/frame/local_frame_client.h"
#include "third_party/blink/renderer/modules/crypto/crypto_result_impl.h"
#include "third_party/blink/renderer/modules/mediastream/media_constraints_impl.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream_event.h"
#include "third_party/blink/renderer/modules/mediastream/media_stream_track_impl.h"
#include "third_party/blink/renderer/modules/peerconnection/peer_connection_dependency_factory.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_certificate.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_certificate_generator.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_data_channel.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_data_channel_event.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_dtls_transport.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_dtmf_sender.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_error_util.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_ice_transport.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_handler.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_error_event.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_peer_connection_ice_event.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_receiver.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_sender.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_rtp_transceiver.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_sctp_transport.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_session_description.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_impl.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_session_description_request_promise_impl.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_stats_report.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_track_event.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_void_request_impl.h"
#include "third_party/blink/renderer/modules/peerconnection/rtc_void_request_promise_impl.h"
#include "third_party/blink/renderer/modules/peerconnection/web_rtc_stats_report_callback_resolver.h"
#include "third_party/blink/renderer/platform/bindings/exception_code.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/bindings/v8_throw_exception.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/instrumentation/instance_counters.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_answer_options_platform.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_ice_candidate_platform.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_offer_options_platform.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_session_description_platform.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_stats.h"
#include "third_party/blink/renderer/platform/peerconnection/rtc_void_request.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/scheduler/public/event_loop.h"
#include "third_party/blink/renderer/platform/scheduler/public/scheduling_policy.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
#include "third_party/webrtc/api/data_channel_interface.h"
#include "third_party/webrtc/api/dtls_transport_interface.h"
#include "third_party/webrtc/api/jsep.h"
#include "third_party/webrtc/api/peer_connection_interface.h"
#include "third_party/webrtc/api/priority.h"
#include "third_party/webrtc/rtc_base/ssl_identity.h"
namespace blink {
namespace {
const char kSignalingStateClosedMessage[] = …;
const char kModifiedSdpMessage[] = …;
base::LazyInstance<RTCPeerConnection::RtcPeerConnectionHandlerFactoryCallback>::
Leaky g_create_rpc_peer_connection_handler_callback_ = …;
const int64_t kMaxPeerConnections = …;
bool ThrowExceptionIfSignalingStateClosed(
webrtc::PeerConnectionInterface::SignalingState state,
ExceptionState* exception_state) { … }
void AsyncCallErrorCallback(ExecutionContext* context,
V8RTCPeerConnectionErrorCallback* error_callback,
DOMException* exception) { … }
bool CallErrorCallbackIfSignalingStateClosed(
ExecutionContext* context,
webrtc::PeerConnectionInterface::SignalingState state,
V8RTCPeerConnectionErrorCallback* error_callback) { … }
bool IsIceCandidateMissingSdpMidAndMLineIndex(
const RTCIceCandidateInit* candidate) { … }
RTCOfferOptionsPlatform* ConvertToRTCOfferOptionsPlatform(
const RTCOfferOptions* options) { … }
RTCAnswerOptionsPlatform* ConvertToRTCAnswerOptionsPlatform(
const RTCAnswerOptions* options) { … }
RTCIceCandidatePlatform* ConvertToRTCIceCandidatePlatform(
ExecutionContext* context,
const RTCIceCandidateInit* candidate) { … }
webrtc::PeerConnectionInterface::IceTransportsType IceTransportPolicyFromString(
const String& policy) { … }
bool IsValidStunURL(const KURL& url) { … }
bool IsValidTurnURL(const KURL& url) { … }
webrtc::PeerConnectionInterface::RTCConfiguration ParseConfiguration(
ExecutionContext* context,
const RTCConfiguration* configuration,
ExceptionState* exception_state) { … }
bool SdpMismatch(String old_sdp, String new_sdp, String attribute) { … }
bool IceUfragPwdMismatch(String old_sdp, String new_sdp) { … }
bool FingerprintMismatch(String old_sdp, String new_sdp) { … }
bool ContainsLegacySimulcast(String sdp) { … }
bool ContainsLegacyRtpDataChannel(String sdp) { … }
bool ContainsCandidate(String sdp) { … }
bool ContainsOpusStereo(String sdp) { … }
}
RTCPeerConnection::EventWrapper::EventWrapper(Event* event,
BoolFunction function)
: … { … }
bool RTCPeerConnection::EventWrapper::Setup() { … }
void RTCPeerConnection::EventWrapper::Trace(Visitor* visitor) const { … }
RTCPeerConnection* RTCPeerConnection::Create(
ExecutionContext* context,
const RTCConfiguration* rtc_configuration,
ExceptionState& exception_state) { … }
RTCPeerConnection::RTCPeerConnection(
ExecutionContext* context,
webrtc::PeerConnectionInterface::RTCConfiguration configuration,
bool encoded_insertable_streams,
ExceptionState& exception_state)
: … { … }
RTCPeerConnection::~RTCPeerConnection() { … }
void RTCPeerConnection::Dispose() { … }
ScriptPromise<RTCSessionDescriptionInit> RTCPeerConnection::createOffer(
ScriptState* script_state,
const RTCOfferOptions* options,
ExceptionState& exception_state) { … }
ScriptPromise<IDLUndefined> RTCPeerConnection::createOffer(
ScriptState* script_state,
V8RTCSessionDescriptionCallback* success_callback,
V8RTCPeerConnectionErrorCallback* error_callback,
const RTCOfferOptions* options,
ExceptionState& exception_state) { … }
ScriptPromise<RTCSessionDescriptionInit> RTCPeerConnection::createAnswer(
ScriptState* script_state,
const RTCAnswerOptions* options,
ExceptionState& exception_state) { … }
ScriptPromise<IDLUndefined> RTCPeerConnection::createAnswer(
ScriptState* script_state,
V8RTCSessionDescriptionCallback* success_callback,
V8RTCPeerConnectionErrorCallback* error_callback,
ExceptionState&) { … }
DOMException* RTCPeerConnection::checkSdpForStateErrors(
ExecutionContext* context,
const ParsedSessionDescription& parsed_sdp) { … }
HeapHashSet<Member<RTCIceTransport>> RTCPeerConnection::ActiveIceTransports()
const { … }
void RTCPeerConnection::GenerateCertificateCompleted(
ScriptPromiseResolver<RTCCertificate>* resolver,
rtc::scoped_refptr<rtc::RTCCertificate> certificate) { … }
void RTCPeerConnection::UpdateIceConnectionState() { … }
ScriptPromise<IDLUndefined> RTCPeerConnection::setLocalDescription(
ScriptState* script_state,
ExceptionState& exception_state) { … }
ScriptPromise<IDLUndefined> RTCPeerConnection::setLocalDescription(
ScriptState* script_state,
const RTCSessionDescriptionInit* session_description_init,
ExceptionState& exception_state) { … }
ScriptPromise<IDLUndefined> RTCPeerConnection::setLocalDescription(
ScriptState* script_state,
const RTCSessionDescriptionInit* session_description_init,
V8VoidFunction* success_callback,
V8RTCPeerConnectionErrorCallback* error_callback) { … }
RTCSessionDescription* RTCPeerConnection::localDescription() const { … }
RTCSessionDescription* RTCPeerConnection::currentLocalDescription() const { … }
RTCSessionDescription* RTCPeerConnection::pendingLocalDescription() const { … }
ScriptPromise<IDLUndefined> RTCPeerConnection::setRemoteDescription(
ScriptState* script_state,
const RTCSessionDescriptionInit* session_description_init,
ExceptionState& exception_state) { … }
ScriptPromise<IDLUndefined> RTCPeerConnection::setRemoteDescription(
ScriptState* script_state,
const RTCSessionDescriptionInit* session_description_init,
V8VoidFunction* success_callback,
V8RTCPeerConnectionErrorCallback* error_callback) { … }
RTCSessionDescription* RTCPeerConnection::remoteDescription() const { … }
RTCSessionDescription* RTCPeerConnection::currentRemoteDescription() const { … }
RTCSessionDescription* RTCPeerConnection::pendingRemoteDescription() const { … }
RTCConfiguration* RTCPeerConnection::getConfiguration(
ScriptState* script_state) const { … }
void RTCPeerConnection::setConfiguration(
ScriptState* script_state,
const RTCConfiguration* rtc_configuration,
ExceptionState& exception_state) { … }
ScriptPromise<RTCCertificate> RTCPeerConnection::generateCertificate(
ScriptState* script_state,
const V8AlgorithmIdentifier* keygen_algorithm,
ExceptionState& exception_state) { … }
ScriptPromise<IDLUndefined> RTCPeerConnection::addIceCandidate(
ScriptState* script_state,
const RTCIceCandidateInit* candidate,
ExceptionState& exception_state) { … }
ScriptPromise<IDLUndefined> RTCPeerConnection::addIceCandidate(
ScriptState* script_state,
const RTCIceCandidateInit* candidate,
V8VoidFunction* success_callback,
V8RTCPeerConnectionErrorCallback* error_callback,
ExceptionState& exception_state) { … }
String RTCPeerConnection::signalingState() const { … }
String RTCPeerConnection::iceGatheringState() const { … }
String RTCPeerConnection::iceConnectionState() const { … }
String RTCPeerConnection::connectionState() const { … }
std::optional<bool> RTCPeerConnection::canTrickleIceCandidates() const { … }
void RTCPeerConnection::restartIce() { … }
void RTCPeerConnection::addStream(ScriptState* script_state,
MediaStream* stream,
ExceptionState& exception_state) { … }
void RTCPeerConnection::removeStream(MediaStream* stream,
ExceptionState& exception_state) { … }
MediaStreamVector RTCPeerConnection::getLocalStreams() const { … }
MediaStreamVector RTCPeerConnection::getRemoteStreams() const { … }
ScriptPromise<RTCStatsReport> RTCPeerConnection::getStats(
ScriptState* script_state,
MediaStreamTrack* selector,
ExceptionState& exception_state) { … }
const HeapVector<Member<RTCRtpTransceiver>>&
RTCPeerConnection::getTransceivers() const { … }
const HeapVector<Member<RTCRtpSender>>& RTCPeerConnection::getSenders() const { … }
const HeapVector<Member<RTCRtpReceiver>>& RTCPeerConnection::getReceivers()
const { … }
RtpContributingSourceCache& RTCPeerConnection::GetRtpContributingSourceCache() { … }
std::optional<webrtc::RtpTransceiverInit> ValidateRtpTransceiverInit(
ExecutionContext* execution_context,
ExceptionState& exception_state,
const RTCRtpTransceiverInit* init,
const String kind) { … }
RTCRtpTransceiver* RTCPeerConnection::addTransceiver(
const V8UnionMediaStreamTrackOrString* track_or_kind,
const RTCRtpTransceiverInit* init,
ExceptionState& exception_state) { … }
RTCRtpSender* RTCPeerConnection::addTrack(MediaStreamTrack* track,
MediaStreamVector streams,
ExceptionState& exception_state) { … }
void RTCPeerConnection::removeTrack(RTCRtpSender* sender,
ExceptionState& exception_state) { … }
RTCSctpTransport* RTCPeerConnection::sctp() const { … }
RTCDataChannel* RTCPeerConnection::createDataChannel(
ScriptState* script_state,
String label,
const RTCDataChannelInit* data_channel_dict,
ExceptionState& exception_state) { … }
MediaStreamTrack* RTCPeerConnection::GetTrackForTesting(
MediaStreamComponent* component) const { … }
RTCRtpSender* RTCPeerConnection::FindSenderForTrackAndStream(
MediaStreamTrack* track,
MediaStream* stream) { … }
HeapVector<Member<RTCRtpSender>>::iterator RTCPeerConnection::FindSender(
const RTCRtpSenderPlatform& web_sender) { … }
HeapVector<Member<RTCRtpReceiver>>::iterator RTCPeerConnection::FindReceiver(
const RTCRtpReceiverPlatform& platform_receiver) { … }
HeapVector<Member<RTCRtpTransceiver>>::iterator
RTCPeerConnection::FindTransceiver(
const RTCRtpTransceiverPlatform& platform_transceiver) { … }
RTCRtpSender* RTCPeerConnection::CreateOrUpdateSender(
std::unique_ptr<RTCRtpSenderPlatform> rtp_sender_platform,
String kind) { … }
RTCRtpReceiver* RTCPeerConnection::CreateOrUpdateReceiver(
std::unique_ptr<RTCRtpReceiverPlatform> platform_receiver) { … }
RTCRtpTransceiver* RTCPeerConnection::CreateOrUpdateTransceiver(
std::unique_ptr<RTCRtpTransceiverPlatform> platform_transceiver) { … }
RTCDtlsTransport* RTCPeerConnection::CreateOrUpdateDtlsTransport(
rtc::scoped_refptr<webrtc::DtlsTransportInterface> native_transport,
const webrtc::DtlsTransportInformation& information) { … }
RTCIceTransport* RTCPeerConnection::CreateOrUpdateIceTransport(
rtc::scoped_refptr<webrtc::IceTransportInterface> ice_transport) { … }
RTCDTMFSender* RTCPeerConnection::createDTMFSender(
MediaStreamTrack* track,
ExceptionState& exception_state) { … }
void RTCPeerConnection::close() { … }
void RTCPeerConnection::RegisterTrack(MediaStreamTrack* track) { … }
void RTCPeerConnection::NoteSdpCreated(const RTCSessionDescriptionInit& desc) { … }
void RTCPeerConnection::OnStreamAddTrack(MediaStream* stream,
MediaStreamTrack* track,
ExceptionState& exception_state) { … }
void RTCPeerConnection::OnStreamRemoveTrack(MediaStream* stream,
MediaStreamTrack* track,
ExceptionState& exception_state) { … }
void RTCPeerConnection::NegotiationNeeded() { … }
void RTCPeerConnection::DidGenerateICECandidate(
RTCIceCandidatePlatform* platform_candidate) { … }
void RTCPeerConnection::DidFailICECandidate(const String& address,
std::optional<uint16_t> port,
const String& host_candidate,
const String& url,
int error_code,
const String& error_text) { … }
void RTCPeerConnection::DidChangeSessionDescriptions(
RTCSessionDescriptionPlatform* pending_local_description,
RTCSessionDescriptionPlatform* current_local_description,
RTCSessionDescriptionPlatform* pending_remote_description,
RTCSessionDescriptionPlatform* current_remote_description) { … }
void RTCPeerConnection::DidChangeIceGatheringState(
webrtc::PeerConnectionInterface::IceGatheringState new_state) { … }
void RTCPeerConnection::DidChangePeerConnectionState(
webrtc::PeerConnectionInterface::PeerConnectionState new_state) { … }
void RTCPeerConnection::DidModifySctpTransport(
WebRTCSctpTransportSnapshot snapshot) { … }
void RTCPeerConnection::DidModifyTransceivers(
webrtc::PeerConnectionInterface::SignalingState signaling_state,
Vector<std::unique_ptr<RTCRtpTransceiverPlatform>> platform_transceivers,
Vector<uintptr_t> removed_transceiver_ids,
bool is_remote_description_or_rollback) { … }
void RTCPeerConnection::SetAssociatedMediaStreams(
RTCRtpReceiver* receiver,
const Vector<String>& stream_ids,
HeapVector<std::pair<Member<MediaStream>, Member<MediaStreamTrack>>>*
remove_list,
HeapVector<std::pair<Member<MediaStream>, Member<MediaStreamTrack>>>*
add_list) { … }
void RTCPeerConnection::DidAddRemoteDataChannel(
rtc::scoped_refptr<webrtc::DataChannelInterface> channel) { … }
void RTCPeerConnection::DidNoteInterestingUsage(int usage_pattern) { … }
void RTCPeerConnection::UnregisterPeerConnectionHandler() { … }
void RTCPeerConnection::ClosePeerConnection() { … }
const AtomicString& RTCPeerConnection::InterfaceName() const { … }
ExecutionContext* RTCPeerConnection::GetExecutionContext() const { … }
void RTCPeerConnection::ContextDestroyed() { … }
void RTCPeerConnection::ChangeSignalingState(
webrtc::PeerConnectionInterface::SignalingState signaling_state,
bool dispatch_event_immediately) { … }
void RTCPeerConnection::ChangeIceGatheringState(
webrtc::PeerConnectionInterface::IceGatheringState ice_gathering_state) { … }
bool RTCPeerConnection::SetIceGatheringState(
webrtc::PeerConnectionInterface::IceGatheringState ice_gathering_state) { … }
void RTCPeerConnection::ChangeIceConnectionState(
webrtc::PeerConnectionInterface::IceConnectionState ice_connection_state) { … }
webrtc::PeerConnectionInterface::IceConnectionState
RTCPeerConnection::ComputeIceConnectionState() { … }
bool RTCPeerConnection::HasAnyFailedIceTransport() const { … }
bool RTCPeerConnection::HasAnyDisconnectedIceTransport() const { … }
bool RTCPeerConnection::HasAllNewOrClosedIceTransports() const { … }
bool RTCPeerConnection::HasAnyNewOrCheckingIceTransport() const { … }
bool RTCPeerConnection::HasAllCompletedOrClosedIceTransports() const { … }
bool RTCPeerConnection::HasAllConnectedCompletedOrClosedIceTransports() const { … }
void RTCPeerConnection::ChangePeerConnectionState(
webrtc::PeerConnectionInterface::PeerConnectionState
peer_connection_state) { … }
bool RTCPeerConnection::SetPeerConnectionState(
webrtc::PeerConnectionInterface::PeerConnectionState
peer_connection_state) { … }
void RTCPeerConnection::CloseInternal() { … }
void RTCPeerConnection::MaybeDispatchEvent(Event* event) { … }
void RTCPeerConnection::ScheduleDispatchEvent(Event* event) { … }
void RTCPeerConnection::ScheduleDispatchEvent(Event* event,
BoolFunction setup_function) { … }
void RTCPeerConnection::DispatchScheduledEvents() { … }
void RTCPeerConnection::Trace(Visitor* visitor) const { … }
void RTCPeerConnection::SetRtcPeerConnectionHandlerFactoryForTesting(
RtcPeerConnectionHandlerFactoryCallback callback) { … }
int RTCPeerConnection::PeerConnectionCount() { … }
int RTCPeerConnection::PeerConnectionCountLimit() { … }
void RTCPeerConnection::DisableBackForwardCache(ExecutionContext* context) { … }
}