diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-12 05:35:29 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-12 05:35:29 +0000 |
commit | 59203c63bb777a3bacec32fb8830fba33540e809 (patch) | |
tree | 58298e711c0ff0575818c30485b44a2f21bf28a0 /dom/media/webrtc | |
parent | Adding upstream version 126.0.1. (diff) | |
download | firefox-59203c63bb777a3bacec32fb8830fba33540e809.tar.xz firefox-59203c63bb777a3bacec32fb8830fba33540e809.zip |
Adding upstream version 127.0.upstream/127.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dom/media/webrtc')
36 files changed, 770 insertions, 386 deletions
diff --git a/dom/media/webrtc/MediaEnginePrefs.h b/dom/media/webrtc/MediaEnginePrefs.h index de5daf0ad9..e3eff7eba5 100644 --- a/dom/media/webrtc/MediaEnginePrefs.h +++ b/dom/media/webrtc/MediaEnginePrefs.h @@ -28,6 +28,7 @@ class MediaEnginePrefs { mHeight(0), mFPS(0), mFreq(0), + mUsePlatformProcessing(false), mAecOn(false), mUseAecMobile(false), mAgcOn(false), @@ -44,6 +45,7 @@ class MediaEnginePrefs { int32_t mHeight; int32_t mFPS; int32_t mFreq; // for test tones (fake:true) + bool mUsePlatformProcessing; bool mAecOn; bool mUseAecMobile; bool mAgcOn; diff --git a/dom/media/webrtc/MediaEngineWebRTCAudio.cpp b/dom/media/webrtc/MediaEngineWebRTCAudio.cpp index 220dcf3bd8..c072717e00 100644 --- a/dom/media/webrtc/MediaEngineWebRTCAudio.cpp +++ b/dom/media/webrtc/MediaEngineWebRTCAudio.cpp @@ -148,7 +148,7 @@ nsresult MediaEngineWebRTCMicrophoneSource::Reconfigure( } AudioProcessing::Config AudioInputProcessing::ConfigForPrefs( - const MediaEnginePrefs& aPrefs) { + const MediaEnginePrefs& aPrefs) const { AudioProcessing::Config config; config.pipeline.multi_channel_render = true; @@ -207,6 +207,19 @@ AudioProcessing::Config AudioInputProcessing::ConfigForPrefs( config.high_pass_filter.enabled = aPrefs.mHPFOn; + if (mPlatformProcessingSetParams & + CUBEB_INPUT_PROCESSING_PARAM_ECHO_CANCELLATION) { + config.echo_canceller.enabled = false; + } + if (mPlatformProcessingSetParams & + CUBEB_INPUT_PROCESSING_PARAM_AUTOMATIC_GAIN_CONTROL) { + config.gain_controller1.enabled = config.gain_controller2.enabled = false; + } + if (mPlatformProcessingSetParams & + CUBEB_INPUT_PROCESSING_PARAM_NOISE_SUPPRESSION) { + config.noise_suppression.enabled = false; + } + return config; } @@ -412,11 +425,45 @@ void AudioInputProcessing::Disconnect(MediaTrackGraph* aGraph) { aGraph->AssertOnGraphThread(); } +void AudioInputProcessing::NotifySetRequestedInputProcessingParamsResult( + MediaTrackGraph* aGraph, cubeb_input_processing_params aRequestedParams, + const Result<cubeb_input_processing_params, int>& aResult) { + aGraph->AssertOnGraphThread(); + if (aRequestedParams != RequestedInputProcessingParams(aGraph)) { + // This is a result from an old request, wait for a more recent one. + return; + } + if (aResult.isOk()) { + if (mPlatformProcessingSetParams == aResult.inspect()) { + // No change. + return; + } + mPlatformProcessingSetError = Nothing(); + mPlatformProcessingSetParams = aResult.inspect(); + LOG("AudioInputProcessing %p platform processing params are now %s.", this, + CubebUtils::ProcessingParamsToString(mPlatformProcessingSetParams) + .get()); + } else { + mPlatformProcessingSetError = Some(aResult.inspectErr()); + mPlatformProcessingSetParams = CUBEB_INPUT_PROCESSING_PARAM_NONE; + LOG("AudioInputProcessing %p platform processing params failed to apply. " + "Applying input processing config in libwebrtc.", + this); + } + ApplySettingsInternal(aGraph, mSettings); +} + bool AudioInputProcessing::IsPassThrough(MediaTrackGraph* aGraph) const { aGraph->AssertOnGraphThread(); // The high-pass filter is not taken into account when activating the // pass through, since it's not controllable from content. - return !(mSettings.mAecOn || mSettings.mAgcOn || mSettings.mNoiseOn); + auto config = AppliedConfig(aGraph); + auto aec = [](const auto& config) { return config.echo_canceller.enabled; }; + auto agc = [](const auto& config) { + return config.gain_controller1.enabled || config.gain_controller2.enabled; + }; + auto ns = [](const auto& config) { return config.noise_suppression.enabled; }; + return !(aec(config) || agc(config) || ns(config)); } void AudioInputProcessing::PassThroughChanged(MediaTrackGraph* aGraph) { @@ -438,7 +485,7 @@ void AudioInputProcessing::PassThroughChanged(MediaTrackGraph* aGraph) { } } -uint32_t AudioInputProcessing::GetRequestedInputChannelCount() { +uint32_t AudioInputProcessing::GetRequestedInputChannelCount() const { return mSettings.mChannels; } @@ -668,6 +715,10 @@ void AudioInputProcessing::ProcessOutputData(AudioProcessingTrack* aTrack, return; } + if (aChunk.mDuration == 0) { + return; + } + TrackRate sampleRate = aTrack->mSampleRate; uint32_t framesPerPacket = GetPacketSize(sampleRate); // in frames // Downmix from aChannels to MAX_CHANNELS if needed. @@ -868,6 +919,7 @@ void AudioInputProcessing::PacketizeAndProcess(AudioProcessingTrack* aTrack, !(mPacketCount % 50)) { AudioProcessingStats stats = mAudioProcessing->GetStatistics(); char msg[1024]; + msg[0] = '\0'; size_t offset = 0; #define AddIfValue(format, member) \ if (stats.member.has_value()) { \ @@ -962,14 +1014,61 @@ void AudioInputProcessing::DeviceChanged(MediaTrackGraph* aGraph) { aGraph, aGraph->CurrentDriver(), this); } +cubeb_input_processing_params +AudioInputProcessing::RequestedInputProcessingParams( + MediaTrackGraph* aGraph) const { + aGraph->AssertOnGraphThread(); + if (!mPlatformProcessingEnabled) { + return CUBEB_INPUT_PROCESSING_PARAM_NONE; + } + if (mPlatformProcessingSetError) { + return CUBEB_INPUT_PROCESSING_PARAM_NONE; + } + cubeb_input_processing_params params = CUBEB_INPUT_PROCESSING_PARAM_NONE; + if (mSettings.mAecOn) { + params |= CUBEB_INPUT_PROCESSING_PARAM_ECHO_CANCELLATION; + } + if (mSettings.mAgcOn) { + params |= CUBEB_INPUT_PROCESSING_PARAM_AUTOMATIC_GAIN_CONTROL; + } + if (mSettings.mNoiseOn) { + params |= CUBEB_INPUT_PROCESSING_PARAM_NOISE_SUPPRESSION; + } + return params; +} + void AudioInputProcessing::ApplySettings(MediaTrackGraph* aGraph, CubebUtils::AudioDeviceID aDeviceID, const MediaEnginePrefs& aSettings) { TRACE("AudioInputProcessing::ApplySettings"); aGraph->AssertOnGraphThread(); + // CUBEB_ERROR_NOT_SUPPORTED means the backend does not support platform + // processing. In that case, leave the error in place so we don't request + // processing anew. + if (mPlatformProcessingSetError.valueOr(CUBEB_OK) != + CUBEB_ERROR_NOT_SUPPORTED) { + mPlatformProcessingSetError = Nothing(); + } + // Read previous state from mSettings. uint32_t oldChannelCount = GetRequestedInputChannelCount(); + + ApplySettingsInternal(aGraph, aSettings); + + if (oldChannelCount != GetRequestedInputChannelCount()) { + RequestedInputChannelCountChanged(aGraph, aDeviceID); + } +} + +void AudioInputProcessing::ApplySettingsInternal( + MediaTrackGraph* aGraph, const MediaEnginePrefs& aSettings) { + TRACE("AudioInputProcessing::ApplySettingsInternal"); + aGraph->AssertOnGraphThread(); + + mPlatformProcessingEnabled = aSettings.mUsePlatformProcessing; + + // Read previous state from the applied config. bool wasPassThrough = IsPassThrough(aGraph); mSettings = aSettings; @@ -977,14 +1076,20 @@ void AudioInputProcessing::ApplySettings(MediaTrackGraph* aGraph, mAudioProcessing->ApplyConfig(ConfigForPrefs(aSettings)); } - if (oldChannelCount != GetRequestedInputChannelCount()) { - RequestedInputChannelCountChanged(aGraph, aDeviceID); - } if (wasPassThrough != IsPassThrough(aGraph)) { PassThroughChanged(aGraph); } } +webrtc::AudioProcessing::Config AudioInputProcessing::AppliedConfig( + MediaTrackGraph* aGraph) const { + aGraph->AssertOnGraphThread(); + if (mAudioProcessing) { + return mAudioProcessing->GetConfig(); + } + return ConfigForPrefs(mSettings); +} + void AudioInputProcessing::End() { mEnded = true; mSegment.Clear(); @@ -1078,7 +1183,6 @@ void AudioInputProcessing::EnsureAudioProcessing(AudioProcessingTrack* aTrack) { void AudioInputProcessing::ResetAudioProcessing(MediaTrackGraph* aGraph) { aGraph->AssertOnGraphThread(); MOZ_ASSERT(IsPassThrough(aGraph) || !mEnabled); - MOZ_ASSERT(mPacketizerInput); LOG_FRAME( "(Graph %p, Driver %p) AudioInputProcessing %p Resetting audio " @@ -1091,9 +1195,10 @@ void AudioInputProcessing::ResetAudioProcessing(MediaTrackGraph* aGraph) { mAudioProcessing->Initialize(); } - MOZ_ASSERT(static_cast<uint32_t>(mSegment.GetDuration()) + - mPacketizerInput->FramesAvailable() == - mPacketizerInput->mPacketSize); + MOZ_ASSERT_IF(mPacketizerInput, + static_cast<uint32_t>(mSegment.GetDuration()) + + mPacketizerInput->FramesAvailable() == + mPacketizerInput->mPacketSize); // It's ok to clear all the internal buffer here since we won't use mSegment // in pass-through mode or when audio processing is disabled. diff --git a/dom/media/webrtc/MediaEngineWebRTCAudio.h b/dom/media/webrtc/MediaEngineWebRTCAudio.h index 6b1fbf0089..705d33fc38 100644 --- a/dom/media/webrtc/MediaEngineWebRTCAudio.h +++ b/dom/media/webrtc/MediaEngineWebRTCAudio.h @@ -117,7 +117,8 @@ class AudioInputProcessing : public AudioDataListener { // If we're passing data directly without AEC or any other process, this // means that all voice-processing has been disabled intentionaly. In this // case, consider that the device is not used for voice input. - return !IsPassThrough(aGraph); + return !IsPassThrough(aGraph) || + mPlatformProcessingSetParams != CUBEB_INPUT_PROCESSING_PARAM_NONE; } void Start(MediaTrackGraph* aGraph); @@ -125,18 +126,27 @@ class AudioInputProcessing : public AudioDataListener { void DeviceChanged(MediaTrackGraph* aGraph) override; - uint32_t RequestedInputChannelCount(MediaTrackGraph*) override { + uint32_t RequestedInputChannelCount(MediaTrackGraph*) const override { return GetRequestedInputChannelCount(); } + cubeb_input_processing_params RequestedInputProcessingParams( + MediaTrackGraph* aGraph) const override; + void Disconnect(MediaTrackGraph* aGraph) override; + void NotifySetRequestedInputProcessingParamsResult( + MediaTrackGraph* aGraph, cubeb_input_processing_params aRequestedParams, + const Result<cubeb_input_processing_params, int>& aResult) override; + void PacketizeAndProcess(AudioProcessingTrack* aTrack, const AudioSegment& aSegment); - uint32_t GetRequestedInputChannelCount(); + uint32_t GetRequestedInputChannelCount() const; + // This is true when all processing is disabled, in which case we can skip - // packetization, resampling and other processing passes. + // packetization, resampling and other processing passes. Processing may still + // be applied by the platform on the underlying input track. bool IsPassThrough(MediaTrackGraph* aGraph) const; // This allow changing the APM options, enabling or disabling processing @@ -146,6 +156,9 @@ class AudioInputProcessing : public AudioDataListener { CubebUtils::AudioDeviceID aDeviceID, const MediaEnginePrefs& aSettings); + // The config currently applied to the audio processing module. + webrtc::AudioProcessing::Config AppliedConfig(MediaTrackGraph* aGraph) const; + void End(); TrackTime NumBufferedFrames(MediaTrackGraph* aGraph) const; @@ -163,13 +176,15 @@ class AudioInputProcessing : public AudioDataListener { private: ~AudioInputProcessing() = default; webrtc::AudioProcessing::Config ConfigForPrefs( - const MediaEnginePrefs& aPrefs); + const MediaEnginePrefs& aPrefs) const; void PassThroughChanged(MediaTrackGraph* aGraph); void RequestedInputChannelCountChanged(MediaTrackGraph* aGraph, CubebUtils::AudioDeviceID aDeviceId); void EnsurePacketizer(AudioProcessingTrack* aTrack); void EnsureAudioProcessing(AudioProcessingTrack* aTrack); void ResetAudioProcessing(MediaTrackGraph* aGraph); + void ApplySettingsInternal(MediaTrackGraph* aGraph, + const MediaEnginePrefs& aSettings); PrincipalHandle GetCheckedPrincipal(const AudioSegment& aSegment); // This implements the processing algoritm to apply to the input (e.g. a // microphone). If all algorithms are disabled, this class in not used. This @@ -186,6 +201,17 @@ class AudioInputProcessing : public AudioDataListener { // The current settings from about:config preferences and content-provided // constraints. MediaEnginePrefs mSettings; + // When false, RequestedInputProcessingParams() returns no params, resulting + // in platform processing getting disabled in the platform. + bool mPlatformProcessingEnabled = false; + // The latest error notified to us through + // NotifySetRequestedInputProcessingParamsResult, or Nothing if the latest + // request was successful, or if a request is pending a result. + Maybe<int> mPlatformProcessingSetError; + // The processing params currently applied in the platform. This allows + // adapting the AudioProcessingConfig accordingly. + cubeb_input_processing_params mPlatformProcessingSetParams = + CUBEB_INPUT_PROCESSING_PARAM_NONE; // Buffer for up to one 10ms packet of planar mixed audio output for the // reverse-stream (speaker data) of mAudioProcessing AEC. // Length is packet size * channel count, regardless of how many frames are diff --git a/dom/media/webrtc/jsapi/RTCTransformEventRunnable.cpp b/dom/media/webrtc/jsapi/RTCTransformEventRunnable.cpp index 6f41baf80f..16e3c2fd28 100644 --- a/dom/media/webrtc/jsapi/RTCTransformEventRunnable.cpp +++ b/dom/media/webrtc/jsapi/RTCTransformEventRunnable.cpp @@ -57,8 +57,8 @@ already_AddRefed<Event> RTCTransformEventRunnable::BuildEvent( // Set transformer.[[writable]] to writable. RefPtr<RTCRtpScriptTransformer> transformer = new RTCRtpScriptTransformer(aGlobal); - nsresult nrv = - transformer->Init(aCx, aTransformerOptions, mWorkerPrivate, mProxy); + nsresult nrv = transformer->Init(aCx, aTransformerOptions, + GetCurrentThreadWorkerPrivate(), mProxy); if (NS_WARN_IF(NS_FAILED(nrv))) { // TODO: Error handling. Currently unspecified. return nullptr; diff --git a/dom/media/webrtc/libwebrtcglue/VideoConduit.cpp b/dom/media/webrtc/libwebrtcglue/VideoConduit.cpp index 5862237711..e863934ebc 100644 --- a/dom/media/webrtc/libwebrtcglue/VideoConduit.cpp +++ b/dom/media/webrtc/libwebrtcglue/VideoConduit.cpp @@ -750,8 +750,20 @@ void WebrtcVideoConduit::OnControlConfigChange() { // TODO this is for webrtc-priority, but needs plumbing bits mEncoderConfig.bitrate_priority = 1.0; + // Populate simulcast_layers with their config (not dimensions or + // dimensions-derived properties, as they're only known as a frame to + // be sent is known). + mEncoderConfig.simulcast_layers.clear(); + for (size_t idx = 0; idx < streamCount; ++idx) { + webrtc::VideoStream video_stream; + auto& encoding = codecConfig->mEncodings[idx]; + video_stream.active = encoding.active; + mEncoderConfig.simulcast_layers.push_back(video_stream); + } + // Expected max number of encodings - mEncoderConfig.number_of_streams = streamCount; + mEncoderConfig.number_of_streams = + mEncoderConfig.simulcast_layers.size(); // libwebrtc disables this by default. mSendStreamConfig.suspend_below_min_bitrate = false; diff --git a/dom/media/webrtc/libwebrtcglue/VideoStreamFactory.cpp b/dom/media/webrtc/libwebrtcglue/VideoStreamFactory.cpp index 0ead26a453..d3047f4fca 100644 --- a/dom/media/webrtc/libwebrtcglue/VideoStreamFactory.cpp +++ b/dom/media/webrtc/libwebrtcglue/VideoStreamFactory.cpp @@ -150,6 +150,7 @@ std::vector<webrtc::VideoStream> VideoStreamFactory::CreateEncoderStreams( : aConfig.number_of_streams; MOZ_RELEASE_ASSERT(streamCount >= 1, "Should request at least one stream"); + MOZ_RELEASE_ASSERT(streamCount <= aConfig.simulcast_layers.size()); std::vector<webrtc::VideoStream> streams; streams.reserve(streamCount); @@ -160,10 +161,10 @@ std::vector<webrtc::VideoStream> VideoStreamFactory::CreateEncoderStreams( } for (size_t idx = 0; idx < streamCount; ++idx) { - webrtc::VideoStream video_stream; + webrtc::VideoStream video_stream = aConfig.simulcast_layers[idx]; auto& encoding = mCodecConfig.mEncodings[idx]; - video_stream.active = encoding.active; MOZ_ASSERT(encoding.constraints.scaleDownBy >= 1.0); + MOZ_ASSERT(video_stream.active == encoding.active); gfx::IntSize newSize(0, 0); diff --git a/dom/media/webrtc/metrics.yaml b/dom/media/webrtc/metrics.yaml index aea5cf17fb..dfa8c120f1 100644 --- a/dom/media/webrtc/metrics.yaml +++ b/dom/media/webrtc/metrics.yaml @@ -404,3 +404,84 @@ codec.stats: notification_emails: - webrtc-telemetry-alerts@mozilla.com expires: 132 + +webrtcdtls: + protocol_version: + type: labeled_counter + description: > + The version of DTLS used for each webrtc connection. Can be 1.0, 1.2, or 1.3 (there is no 1.1 version of DTLS) + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1884140 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1884140 + data_sensitivity: + - technical + notification_emails: + - webrtc-telemetry-alerts@mozilla.com + expires: 135 + + cipher: + type: labeled_counter + description: > + The CipherSuite used for each webrtc DTLS connection, as a string + representation of the CipherSuite's ID in 4 hex digits (eg; + TLS_DHE_RSA_WITH_AES_128_CBC_SHA would be "0x0033") + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1884140 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1884140 + data_sensitivity: + - technical + notification_emails: + - webrtc-telemetry-alerts@mozilla.com + expires: 135 + + srtp_cipher: + type: labeled_counter + description: > + The SRTPProtectionProfile (see RFC 5764) used for each webrtc SRTP + connection, as a string representation of the SRTPProtectionProfile's ID + in 4 hex digits (eg; SRTP_AES128_CM_HMAC_SHA1_80 would be "0x0001") + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1884140 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1884140 + data_sensitivity: + - technical + notification_emails: + - webrtc-telemetry-alerts@mozilla.com + expires: 135 + + client_handshake_result: + type: labeled_counter + description: > + The result of each webrtc client DTLS handshake as a string containing + either the name of the error code (eg; SSL_ERROR_BAD_CERTIFICATE), + SUCCESS for successful handshakes, ALPN_FAILURE when ALPN negotiation + fails, or CERT_FAILURE when cert validation fails. + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1884140 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1884140 + data_sensitivity: + - technical + notification_emails: + - webrtc-telemetry-alerts@mozilla.com + expires: 135 + + server_handshake_result: + type: labeled_counter + description: > + The result of each webrtc server DTLS handshake, as the name of the error + code (eg; SSL_ERROR_BAD_CERTIFICATE), the empty string for successful + handshakes, ALPN_FAILURE when ALPN negotiation fails, or CERT_FAILURE when + cert validation fails. + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1884140 + data_reviews: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1884140 + data_sensitivity: + - technical + notification_emails: + - webrtc-telemetry-alerts@mozilla.com + expires: 135 diff --git a/dom/media/webrtc/sdp/rsdparsa_capi/src/lib.rs b/dom/media/webrtc/sdp/rsdparsa_capi/src/lib.rs index 20a13900a2..1286a5d338 100644 --- a/dom/media/webrtc/sdp/rsdparsa_capi/src/lib.rs +++ b/dom/media/webrtc/sdp/rsdparsa_capi/src/lib.rs @@ -99,7 +99,7 @@ pub unsafe extern "C" fn sdp_free_session(sdp_ptr: *mut SdpSession) { pub unsafe extern "C" fn sdp_new_reference(session: *mut SdpSession) -> *const SdpSession { let original = Rc::from_raw(session); let ret = Rc::into_raw(Rc::clone(&original)); - Rc::into_raw(original); // So the original reference doesn't get dropped + std::mem::forget(original); // So the original reference doesn't get dropped ret } diff --git a/dom/media/webrtc/sdp/rsdparsa_capi/src/types.rs b/dom/media/webrtc/sdp/rsdparsa_capi/src/types.rs index 2522c8333d..7b85a173fb 100644 --- a/dom/media/webrtc/sdp/rsdparsa_capi/src/types.rs +++ b/dom/media/webrtc/sdp/rsdparsa_capi/src/types.rs @@ -3,7 +3,6 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use libc::size_t; -use std::boxed::Box; use std::convert::TryInto; use std::error::Error; use std::ffi::CStr; diff --git a/dom/media/webrtc/tests/mochitests/head.js b/dom/media/webrtc/tests/mochitests/head.js index 1fd559217a..cc0992b469 100644 --- a/dom/media/webrtc/tests/mochitests/head.js +++ b/dom/media/webrtc/tests/mochitests/head.js @@ -413,7 +413,7 @@ function setupEnvironment() { // If either fake audio or video is desired we enable fake streams. // If loopback devices are set they will be chosen instead of fakes in gecko. ["media.navigator.streams.fake", WANT_FAKE_AUDIO || WANT_FAKE_VIDEO], - ["media.getusermedia.audiocapture.enabled", true], + ["media.getusermedia.audio.capture.enabled", true], ["media.getusermedia.screensharing.enabled", true], ["media.getusermedia.window.focus_source.enabled", false], ["media.recorder.audio_node.enabled", true], diff --git a/dom/media/webrtc/tests/mochitests/iceTestUtils.js b/dom/media/webrtc/tests/mochitests/iceTestUtils.js index 9e76e3f7df..23237f563b 100644 --- a/dom/media/webrtc/tests/mochitests/iceTestUtils.js +++ b/dom/media/webrtc/tests/mochitests/iceTestUtils.js @@ -75,6 +75,18 @@ async function iceConnected(pc) { }); } +async function dtlsConnected(pc) { + return new Promise((resolve, reject) => { + pc.addEventListener("connectionstatechange", () => { + if (["connected", "completed"].includes(pc.connectionState)) { + resolve(); + } else if (pc.connectionState == "failed") { + reject(new Error(`Connection failed`)); + } + }); + }); +} + // Set up trickle, but does not wait for it to complete. Can be used by itself // in cases where we do not expect any new candidates, but want to still set up // the signal handling in case new candidates _do_ show up. @@ -87,7 +99,8 @@ async function connect( answerer, timeout, context, - noTrickleWait = false + noTrickleWait = false, + waitForDtls = false ) { const trickle1 = trickleIce(offerer, answerer); const trickle2 = trickleIce(answerer, offerer); @@ -110,8 +123,12 @@ async function connect( } }; + const connectionPromises = waitForDtls + ? [dtlsConnected(offerer), dtlsConnected(answerer)] + : [iceConnected(offerer), iceConnected(answerer)]; + await Promise.race([ - Promise.all([iceConnected(offerer), iceConnected(answerer)]), + Promise.all(connectionPromises), throwOnTimeout(timeout, context), ]); } finally { diff --git a/dom/media/webrtc/tests/mochitests/test_peerConnection_glean.html b/dom/media/webrtc/tests/mochitests/test_peerConnection_glean.html index 1faf464566..a382949823 100644 --- a/dom/media/webrtc/tests/mochitests/test_peerConnection_glean.html +++ b/dom/media/webrtc/tests/mochitests/test_peerConnection_glean.html @@ -4,6 +4,7 @@ <head> <script type="application/javascript" src="pc.js"></script> <script type="application/javascript" src="sdpUtils.js"></script> + <script type="application/javascript" src="iceTestUtils.js"></script> </head> <body> @@ -580,6 +581,187 @@ ok(preferredVideoCodec == 6, "checkLoggingMultipleTransceivers glean should show preferred video codec VP8 " + preferredVideoCodec); }, + async function checkDtlsHandshakeSuccess() { + const pc1 = new RTCPeerConnection(); + const pc2 = new RTCPeerConnection(); + await gleanResetTestValues(); + let client_successes = await GleanTest.webrtcdtls.clientHandshakeResult.SUCCESS.testGetValue() || 0; + let server_successes = await GleanTest.webrtcdtls.serverHandshakeResult.SUCCESS.testGetValue() || 0; + let cipher_count = await GleanTest.webrtcdtls.cipher["0x1301"].testGetValue() || 0; + let srtp_cipher_count = await GleanTest.webrtcdtls.srtpCipher["0x0007"].testGetValue() || 0; + is(client_successes, 0); + is(server_successes, 0); + is(cipher_count, 0); + is(srtp_cipher_count, 0); + + const stream = await navigator.mediaDevices.getUserMedia({ video: true }); + pc1.addTrack(stream.getTracks()[0]); + + await connect(pc1, pc2, 32000, "DTLS connected", true, true); + + client_successes = await GleanTest.webrtcdtls.clientHandshakeResult.SUCCESS.testGetValue() || 0; + server_successes = await GleanTest.webrtcdtls.serverHandshakeResult.SUCCESS.testGetValue() || 0; + cipher_count = await GleanTest.webrtcdtls.cipher["0x1301"].testGetValue() || 0; + srtp_cipher_count = await GleanTest.webrtcdtls.srtpCipher["0x0007"].testGetValue() || 0; + is(client_successes, 1); + is(server_successes, 1); + is(cipher_count, 2); + is(srtp_cipher_count, 2); + }, + + async function checkDtlsCipherPrefs() { + await withPrefs([["security.tls13.aes_128_gcm_sha256", false], + ["security.tls13.aes_256_gcm_sha384", false], + ["security.tls13.chacha20_poly1305_sha256", true]], + async () => { + const pc1 = new RTCPeerConnection(); + const pc2 = new RTCPeerConnection(); + await gleanResetTestValues(); + let cipher_count = await GleanTest.webrtcdtls.cipher["0x1303"].testGetValue() || 0; + is(cipher_count, 0); + + const stream = await navigator.mediaDevices.getUserMedia({ video: true }); + pc1.addTrack(stream.getTracks()[0]); + + await connect(pc1, pc2, 32000, "DTLS connected", true, true); + + cipher_count = await GleanTest.webrtcdtls.cipher["0x1303"].testGetValue() || 0; + is(cipher_count, 2); + }); + }, + + async function checkDtlsHandshakeFailure() { + // We don't have many failures we can induce here, but messing up the + // fingerprint is one way. + const offerer = new RTCPeerConnection(); + const answerer = new RTCPeerConnection(); + await gleanResetTestValues(); + let client_failures = await GleanTest.webrtcdtls.clientHandshakeResult.SSL_ERROR_BAD_CERTIFICATE.testGetValue() || 0; + let server_failures = await GleanTest.webrtcdtls.serverHandshakeResult.SSL_ERROR_BAD_CERT_ALERT.testGetValue() || 0; + is(client_failures, 0); + is(server_failures, 0); + + const stream = await navigator.mediaDevices.getUserMedia({ video: true }); + offerer.addTrack(stream.getTracks()[0]); + + trickleIce(offerer, answerer); + trickleIce(answerer, offerer); + await offerer.setLocalDescription(); + let badSdp = offerer.localDescription.sdp; + // Tweak the last digit in the fingerprint sent to the answerer. Answerer + // (which will be the DTLS client) will get an SSL_ERROR_BAD_CERTIFICATE + // error, and the offerer (which will be the DTLS server) will get an + // SSL_ERROR_BAD_CERT_ALERT. + const lastDigit = badSdp.match(/a=fingerprint:.*([0-9A-F])$/m)[1]; + const newLastDigit = lastDigit == '0' ? '1' : '0'; + badSdp = badSdp.replace(/(a=fingerprint:.*)[0-9A-F]$/m, "$1" + newLastDigit); + info(badSdp); + await answerer.setRemoteDescription({sdp: badSdp, type: "offer"}); + await answerer.setLocalDescription(); + await offerer.setRemoteDescription(answerer.localDescription); + + const throwOnTimeout = async () => { + await wait(32000); + throw new Error( + `ICE did not complete within ${timeout} ms`); + }; + + const connectionPromises = [connectionStateReached(offerer, "failed"), + connectionStateReached(answerer, "failed")]; + + await Promise.race([ + Promise.all(connectionPromises), + throwOnTimeout() + ]); + + client_failures = await GleanTest.webrtcdtls.clientHandshakeResult.SSL_ERROR_BAD_CERTIFICATE.testGetValue() || 0; + server_failures = await GleanTest.webrtcdtls.serverHandshakeResult.SSL_ERROR_BAD_CERT_ALERT.testGetValue() || 0; + is(client_failures, 1); + is(server_failures, 1); + }, + + async function checkDtlsVersion1_3() { + // 1.3 should be the default + const pc1 = new RTCPeerConnection(); + const pc2 = new RTCPeerConnection(); + await gleanResetTestValues(); + let count1_0 = await GleanTest.webrtcdtls.protocolVersion["1.0"].testGetValue() || 0; + let count1_2 = await GleanTest.webrtcdtls.protocolVersion["1.2"].testGetValue() || 0; + let count1_3 = await GleanTest.webrtcdtls.protocolVersion["1.3"].testGetValue() || 0; + is(count1_0, 0); + is(count1_2, 0); + is(count1_3, 0); + + const stream = await navigator.mediaDevices.getUserMedia({ video: true }); + pc1.addTrack(stream.getTracks()[0]); + + await connect(pc1, pc2, 32000, "DTLS connected", true, true); + + count1_0 = await GleanTest.webrtcdtls.protocolVersion["1.0"].testGetValue() || 0; + count1_2 = await GleanTest.webrtcdtls.protocolVersion["1.2"].testGetValue() || 0; + count1_3 = await GleanTest.webrtcdtls.protocolVersion["1.3"].testGetValue() || 0; + is(count1_0, 0); + is(count1_2, 0); + is(count1_3, 2); + }, + + async function checkDtlsVersion1_2() { + // Make 1.2 the default + await withPrefs([["media.peerconnection.dtls.version.max", 771]], + async () => { + const pc1 = new RTCPeerConnection(); + const pc2 = new RTCPeerConnection(); + await gleanResetTestValues(); + let count1_0 = await GleanTest.webrtcdtls.protocolVersion["1.0"].testGetValue() || 0; + let count1_2 = await GleanTest.webrtcdtls.protocolVersion["1.2"].testGetValue() || 0; + let count1_3 = await GleanTest.webrtcdtls.protocolVersion["1.3"].testGetValue() || 0; + is(count1_0, 0); + is(count1_2, 0); + is(count1_3, 0); + + const stream = await navigator.mediaDevices.getUserMedia({ video: true }); + pc1.addTrack(stream.getTracks()[0]); + + await connect(pc1, pc2, 32000, "DTLS connected", true, true); + + count1_0 = await GleanTest.webrtcdtls.protocolVersion["1.0"].testGetValue() || 0; + count1_2 = await GleanTest.webrtcdtls.protocolVersion["1.2"].testGetValue() || 0; + count1_3 = await GleanTest.webrtcdtls.protocolVersion["1.3"].testGetValue() || 0; + is(count1_0, 0); + is(count1_2, 2); + is(count1_3, 0); + }); + }, + + async function checkDtlsVersion1_0() { + // Make 1.0 the default + await withPrefs([["media.peerconnection.dtls.version.max", 770], + ["media.peerconnection.dtls.version.min", 770]], + async () => { + const pc1 = new RTCPeerConnection(); + const pc2 = new RTCPeerConnection(); + await gleanResetTestValues(); + let count1_0 = await GleanTest.webrtcdtls.protocolVersion["1.0"].testGetValue() || 0; + let count1_2 = await GleanTest.webrtcdtls.protocolVersion["1.2"].testGetValue() || 0; + let count1_3 = await GleanTest.webrtcdtls.protocolVersion["1.3"].testGetValue() || 0; + is(count1_0, 0); + is(count1_2, 0); + is(count1_3, 0); + + const stream = await navigator.mediaDevices.getUserMedia({ video: true }); + pc1.addTrack(stream.getTracks()[0]); + + await connect(pc1, pc2, 32000, "DTLS connected", true, true); + + count1_0 = await GleanTest.webrtcdtls.protocolVersion["1.0"].testGetValue() || 0; + count1_2 = await GleanTest.webrtcdtls.protocolVersion["1.2"].testGetValue() || 0; + count1_3 = await GleanTest.webrtcdtls.protocolVersion["1.3"].testGetValue() || 0; + is(count1_0, 2); + is(count1_2, 0); + is(count1_3, 0); + }); + }, + ]; runNetworkTest(async () => { diff --git a/dom/media/webrtc/third_party_build/default_config_env b/dom/media/webrtc/third_party_build/default_config_env index be3c5ba7c1..0fef4d3192 100644 --- a/dom/media/webrtc/third_party_build/default_config_env +++ b/dom/media/webrtc/third_party_build/default_config_env @@ -5,41 +5,41 @@ export MOZ_LIBWEBRTC_SRC=$STATE_DIR/moz-libwebrtc # The previous fast-forward bug number is used for some error messaging. -export MOZ_PRIOR_FASTFORWARD_BUG="1876843" +export MOZ_PRIOR_FASTFORWARD_BUG="1883116" # Fast-forwarding each Chromium version of libwebrtc should be done # under a separate bugzilla bug. This bug number is used when crafting # the commit summary as each upstream commit is vendored into the # mercurial repository. The bug used for the v106 fast-forward was # 1800920. -export MOZ_FASTFORWARD_BUG="1883116" +export MOZ_FASTFORWARD_BUG="1888181" # MOZ_NEXT_LIBWEBRTC_MILESTONE and MOZ_NEXT_FIREFOX_REL_TARGET are # not used during fast-forward processing, but facilitate generating this # default config. To generate an default config for the next update, run # bash dom/media/webrtc/third_party_build/update_default_config_env.sh -export MOZ_NEXT_LIBWEBRTC_MILESTONE=122 -export MOZ_NEXT_FIREFOX_REL_TARGET=126 +export MOZ_NEXT_LIBWEBRTC_MILESTONE=123 +export MOZ_NEXT_FIREFOX_REL_TARGET=127 # For Chromium release branches, see: # https://chromiumdash.appspot.com/branches -# Chromium's v121 release branch was 6167. This is used to pre-stack +# Chromium's v122 release branch was 6261. This is used to pre-stack # the previous release branch's commits onto the appropriate base commit # (the first common commit between trunk and the release branch). -export MOZ_PRIOR_UPSTREAM_BRANCH_HEAD_NUM="6167" +export MOZ_PRIOR_UPSTREAM_BRANCH_HEAD_NUM="6261" -# New target release branch for v122 is branch-heads/6261. This is used +# New target release branch for v123 is branch-heads/6312. This is used # to calculate the next upstream commit. -export MOZ_TARGET_UPSTREAM_BRANCH_HEAD="branch-heads/6261" +export MOZ_TARGET_UPSTREAM_BRANCH_HEAD="branch-heads/6312" # For local development 'mozpatches' is fine for a branch name, but when # pushing the patch stack to github, it should be named something like -# 'moz-mods-chr122-for-rel126'. +# 'moz-mods-chr123-for-rel127'. export MOZ_LIBWEBRTC_BRANCH="mozpatches" # After elm has been merged to mozilla-central, the patch stack in # moz-libwebrtc should be pushed to github. The script # push_official_branch.sh uses this branch name when pushing to the # public repo. -export MOZ_LIBWEBRTC_OFFICIAL_BRANCH="moz-mods-chr122-for-rel126" +export MOZ_LIBWEBRTC_OFFICIAL_BRANCH="moz-mods-chr123-for-rel127" diff --git a/dom/media/webrtc/third_party_build/elm_rebase.sh b/dom/media/webrtc/third_party_build/elm_rebase.sh index 0dbf93d3ce..734fcacc40 100644 --- a/dom/media/webrtc/third_party_build/elm_rebase.sh +++ b/dom/media/webrtc/third_party_build/elm_rebase.sh @@ -54,15 +54,32 @@ be as simple as running the following commands: COMMIT_LIST_FILE=$TMP_DIR/rebase-commit-list.txt export HGPLAIN=1 +if [ "x$MOZ_TOP_FF" = "x" ]; then + MOZ_TOP_FF="" +fi +if [ "x$MOZ_BOTTOM_FF" = "x" ]; then + MOZ_BOTTOM_FF="" +fi +if [ "x$STOP_FOR_REORDER" = "x" ]; then + STOP_FOR_REORDER="" +fi + # After this point: # * eE: All commands should succeed. +# * u: All variables should be defined before use. # * o pipefail: All stages of all pipes should succeed. -set -eEo pipefail +set -eEuo pipefail if [ -f $STATE_DIR/rebase_resume_state ]; then source $STATE_DIR/rebase_resume_state else + # on first run, we want to verify sanity of the patch-stack so + # ending guidance is appropriate regarding changes in + # third_party/libwebrtc between the old central we're currently + # based on and the new central we're rebasing onto. + bash dom/media/webrtc/third_party_build/verify_vendoring.sh + if [ "x" == "x$MOZ_TOP_FF" ]; then MOZ_TOP_FF=`hg log -r . -T"{node|short}"` @@ -119,12 +136,6 @@ That command looks like: fi ERROR_HELP="" - # After this point: - # * eE: All commands should succeed. - # * u: All variables should be defined before use. - # * o pipefail: All stages of all pipes should succeed. - set -eEuo pipefail - MOZ_NEW_CENTRAL=`hg log -r central -T"{node|short}"` echo "bottom of fast-foward tree is $MOZ_BOTTOM_FF" diff --git a/dom/media/webrtc/third_party_build/fetch_github_repo.py b/dom/media/webrtc/third_party_build/fetch_github_repo.py index 8caa55d5c5..1031eb528b 100644 --- a/dom/media/webrtc/third_party_build/fetch_github_repo.py +++ b/dom/media/webrtc/third_party_build/fetch_github_repo.py @@ -67,12 +67,16 @@ def fetch_repo(github_path, clone_protocol, force_fetch, tar_path): "git remote add upstream https://webrtc.googlesource.com/src", github_path ) run_git("git fetch upstream", github_path) - run_git("git merge upstream/master", github_path) else: print( "Upstream remote (https://webrtc.googlesource.com/src) already configured" ) + # for sanity, ensure we're on master + run_git("git checkout master", github_path) + # make sure we successfully fetched upstream + run_git("git merge upstream/master", github_path) + # setup upstream branch-heads stdout_lines = run_git( "git config --local --get-all remote.upstream.fetch", github_path @@ -87,9 +91,12 @@ def fetch_repo(github_path, clone_protocol, force_fetch, tar_path): else: print("Upstream remote branch-heads already configured") + # verify that a (quite old) branch-head exists + run_git("git show branch-heads/5059", github_path) + # prevent changing line endings when moving things out of the git repo # (and into hg for instance) - run_git("git config --local core.autocrlf false") + run_git("git config --local core.autocrlf false", github_path) # do a sanity fetch in case this was not a freshly cloned copy of the # repo, meaning it may not have all the mozilla branches present. diff --git a/dom/media/webrtc/third_party_build/loop-ff.sh b/dom/media/webrtc/third_party_build/loop-ff.sh index 73ad22822c..9836a8e687 100644 --- a/dom/media/webrtc/third_party_build/loop-ff.sh +++ b/dom/media/webrtc/third_party_build/loop-ff.sh @@ -99,9 +99,9 @@ To verify vendoring, run: When verify_vendoring.sh is successful, please run the following command in bash: - (source $SCRIPT_DIR/use_config_env.sh ; - ./mach python $SCRIPT_DIR/save_patch_stack.py \ - --repo-path $MOZ_LIBWEBRTC_SRC \ + (source $SCRIPT_DIR/use_config_env.sh ; \\ + ./mach python $SCRIPT_DIR/save_patch_stack.py \\ + --repo-path $MOZ_LIBWEBRTC_SRC \\ --target-branch-head $MOZ_TARGET_UPSTREAM_BRANCH_HEAD ) You may resume running this script with the following command: diff --git a/dom/media/webrtc/third_party_build/prep_repo.sh b/dom/media/webrtc/third_party_build/prep_repo.sh index 8cd9ff6816..b1a04748b7 100644 --- a/dom/media/webrtc/third_party_build/prep_repo.sh +++ b/dom/media/webrtc/third_party_build/prep_repo.sh @@ -13,9 +13,30 @@ trap 'show_error_msg $LINENO' ERR source dom/media/webrtc/third_party_build/use_config_env.sh export HGPLAIN=1 +if [ "x$ALLOW_RERUN" = "x" ]; then + ALLOW_RERUN="0" +fi + echo "MOZ_LIBWEBRTC_SRC: $MOZ_LIBWEBRTC_SRC" echo "MOZ_LIBWEBRTC_BRANCH: $MOZ_LIBWEBRTC_BRANCH" echo "MOZ_FASTFORWARD_BUG: $MOZ_FASTFORWARD_BUG" +echo "ALLOW_RERUN: $ALLOW_RERUN" + +ERROR_HELP=$" +A copy of moz-libwebrtc already exists at $MOZ_LIBWEBRTC_SRC +While this script is not technically idempotent, it will try. +However, the safest way forward is to start fresh by running: + rm -rf $STATE_DIR && \\ + bash $0 + +If you are sure you want to reuse the existing directory, run: + ALLOW_RERUN=1 bash $0 +" +if [ -d $MOZ_LIBWEBRTC_SRC ] && [ "x$ALLOW_RERUN" != "x1" ]; then + echo "$ERROR_HELP" + exit 1 +fi +ERROR_HELP="" # After this point: # * eE: All commands should succeed. @@ -66,8 +87,25 @@ rm -f *.patch # create a new work branch and "export" a new patch stack to rebase # find the common commit between our upstream release branch and trunk -CHERRY_PICK_BASE=`git merge-base branch-heads/$MOZ_PRIOR_UPSTREAM_BRANCH_HEAD_NUM master` -echo "common commit: $CHERRY_PICK_BASE" +PREVIOUS_RELEASE_BRANCH_BASE=`git merge-base branch-heads/$MOZ_PRIOR_UPSTREAM_BRANCH_HEAD_NUM master` +echo "PREVIOUS_RELEASE_BRANCH_BASE: $PREVIOUS_RELEASE_BRANCH_BASE" + +NEXT_RELEASE_BRANCH_BASE=`git merge-base $MOZ_TARGET_UPSTREAM_BRANCH_HEAD master` +echo "NEXT_RELEASE_BRANCH_BASE: $NEXT_RELEASE_BRANCH_BASE" + +ERROR_HELP=$" +The previous release branch base ($PREVIOUS_RELEASE_BRANCH_BASE) +and the next release branch base ($NEXT_RELEASE_BRANCH_BASE) are the +same and should not be. This indicates a problem in the git repo at +$MOZ_LIBWEBRTC_SRC. +At the least it likely means that 'master' is older than the two +release branches. Investigation is necessary. +" +if [ "x$PREVIOUS_RELEASE_BRANCH_BASE" == "x$NEXT_RELEASE_BRANCH_BASE" ]; then + echo "$ERROR_HELP" + exit 1 +fi +ERROR_HELP="" # find the last upstream commit used by the previous update, so we don't # accidentally grab release branch commits that were added after we started @@ -85,9 +123,9 @@ commands will allow the process to continue: git checkout $MOZ_LIBWEBRTC_BRANCH && \\ git checkout -b $MOZ_LIBWEBRTC_BRANCH-old && \\ git branch -D $MOZ_LIBWEBRTC_BRANCH ) && \\ - bash $0 + ALLOW_RERUN=1 bash $0 " -git branch $MOZ_LIBWEBRTC_BRANCH $CHERRY_PICK_BASE +git branch $MOZ_LIBWEBRTC_BRANCH $PREVIOUS_RELEASE_BRANCH_BASE ERROR_HELP="" git checkout $MOZ_LIBWEBRTC_BRANCH @@ -95,7 +133,7 @@ git checkout $MOZ_LIBWEBRTC_BRANCH rm -f $TMP_DIR/*.patch $TMP_DIR/*.patch.bak # grab the patches for all the commits in chrome's release branch for libwebrtc -git format-patch -o $TMP_DIR -k $CHERRY_PICK_BASE..$LAST_UPSTREAM_COMMIT_SHA +git format-patch -o $TMP_DIR -k $PREVIOUS_RELEASE_BRANCH_BASE..$LAST_UPSTREAM_COMMIT_SHA # tweak the release branch commit summaries to show they were cherry picked sed -i.bak -e "/^Subject: / s/^Subject: /Subject: (cherry-pick-branch-heads\/$MOZ_PRIOR_UPSTREAM_BRANCH_HEAD_NUM) /" $TMP_DIR/*.patch git am $TMP_DIR/*.patch # applies to branch mozpatches diff --git a/dom/media/webrtc/third_party_build/verify_vendoring.sh b/dom/media/webrtc/third_party_build/verify_vendoring.sh index 008ab0d5db..6152e6d003 100644 --- a/dom/media/webrtc/third_party_build/verify_vendoring.sh +++ b/dom/media/webrtc/third_party_build/verify_vendoring.sh @@ -13,6 +13,12 @@ trap 'show_error_msg $LINENO' ERR source dom/media/webrtc/third_party_build/use_config_env.sh export HGPLAIN=1 +# After this point: +# * eE: All commands should succeed. +# * u: All variables should be defined before use. +# * o pipefail: All stages of all pipes should succeed. +set -eEuo pipefail + echo "MOZ_LIBWEBRTC_SRC: $MOZ_LIBWEBRTC_SRC" echo "MOZ_LIBWEBRTC_BRANCH: $MOZ_LIBWEBRTC_BRANCH" echo "MOZ_FASTFORWARD_BUG: $MOZ_FASTFORWARD_BUG" @@ -30,27 +36,18 @@ LAST_PATCHSTACK_UPDATE_COMMIT_SHA=`echo $LAST_PATCHSTACK_UPDATE_COMMIT \ echo "LAST_PATCHSTACK_UPDATE_COMMIT_SHA: $LAST_PATCHSTACK_UPDATE_COMMIT_SHA" # grab the oldest, non "Vendor from libwebrtc" line -OLDEST_CANDIDATE_COMMIT=`hg log --template "{node|short} {desc|firstline}\n" \ - -r $LAST_PATCHSTACK_UPDATE_COMMIT_SHA::. \ - | grep -v "Vendor libwebrtc from" | head -1` -echo "OLDEST_CANDIDATE_COMMIT: $OLDEST_CANDIDATE_COMMIT" - -OLDEST_CANDIDATE_SHA=`echo $OLDEST_CANDIDATE_COMMIT \ - | awk '{ print $1; }'` -echo "OLDEST_CANDIDATE_SHA: $OLDEST_CANDIDATE_SHA" +CANDIDATE_COMMITS=`hg log --template "{node|short} {desc|firstline}\n" \ + -r "children($LAST_PATCHSTACK_UPDATE_COMMIT_SHA)::. - desc('re:(Vendor libwebrtc)')" \ + --include "third_party/libwebrtc/" | awk 'BEGIN { ORS=" " }; { print $1; }'` +echo "CANDIDATE_COMMITS:" +echo "$CANDIDATE_COMMITS" EXTRACT_COMMIT_RANGE="{start-commit-sha}::." -if [ "x$CURRENT_SHA" != "x$OLDEST_CANDIDATE_SHA" ]; then - EXTRACT_COMMIT_RANGE="$OLDEST_CANDIDATE_SHA::." +if [ "x$CANDIDATE_COMMITS" != "x" ]; then + EXTRACT_COMMIT_RANGE="$CANDIDATE_COMMITS" echo "EXTRACT_COMMIT_RANGE: $EXTRACT_COMMIT_RANGE" fi -# After this point: -# * eE: All commands should succeed. -# * u: All variables should be defined before use. -# * o pipefail: All stages of all pipes should succeed. -set -eEuo pipefail - ./mach python $SCRIPT_DIR/vendor-libwebrtc.py \ --from-local $MOZ_LIBWEBRTC_SRC \ --commit $MOZ_LIBWEBRTC_BRANCH \ diff --git a/dom/media/webrtc/transport/test/moz.build b/dom/media/webrtc/transport/test/moz.build index a2b0bc2bc2..3213525abd 100644 --- a/dom/media/webrtc/transport/test/moz.build +++ b/dom/media/webrtc/transport/test/moz.build @@ -7,35 +7,39 @@ include("/ipc/chromium/chromium-config.mozbuild") if CONFIG["OS_TARGET"] != "WINNT": - if CONFIG["OS_TARGET"] != "Android": - SOURCES += [ - "ice_unittest.cpp", - ] - SOURCES += [ "buffered_stun_socket_unittest.cpp", "multi_tcp_socket_unittest.cpp", - "nrappkit_unittest.cpp", "proxy_tunnel_socket_unittest.cpp", - "rlogconnector_unittest.cpp", "runnable_utils_unittest.cpp", "simpletokenbucket_unittest.cpp", - "sockettransportservice_unittest.cpp", "stunserver.cpp", "test_nr_socket_ice_unittest.cpp", "test_nr_socket_unittest.cpp", "TestSyncRunnable.cpp", - "transport_unittests.cpp", "turn_unittest.cpp", - "webrtcproxychannel_unittest.cpp", ] - if CONFIG["MOZ_SCTP"]: + # Bug 1894419 - Various failures under TSAN + if not CONFIG["MOZ_TSAN"]: + if CONFIG["OS_TARGET"] != "Android": + SOURCES += [ + "ice_unittest.cpp", + ] + + if CONFIG["MOZ_SCTP"]: + SOURCES += [ + "sctp_unittest.cpp", + ] + SOURCES += [ - "sctp_unittest.cpp", + "nrappkit_unittest.cpp", + "rlogconnector_unittest.cpp", + "sockettransportservice_unittest.cpp", + "transport_unittests.cpp", + "webrtcproxychannel_unittest.cpp", ] - for var in ("HAVE_STRDUP", "NR_SOCKET_IS_VOID_PTR", "SCTP_DEBUG"): DEFINES[var] = True diff --git a/dom/media/webrtc/transport/test_nr_socket.cpp b/dom/media/webrtc/transport/test_nr_socket.cpp index 1a6f226c42..1bf95adc88 100644 --- a/dom/media/webrtc/transport/test_nr_socket.cpp +++ b/dom/media/webrtc/transport/test_nr_socket.cpp @@ -141,8 +141,7 @@ TestNat::NatBehavior TestNat::ToNatBehavior(const std::string& type) { return TestNat::PORT_DEPENDENT; } - MOZ_ASSERT(false, "Invalid NAT behavior"); - return TestNat::ENDPOINT_INDEPENDENT; + MOZ_CRASH("Invalid NAT behavior"); } bool TestNat::has_port_mappings() const { @@ -202,8 +201,8 @@ TestNrSocket::~TestNrSocket() { nat_->erase_socket(this); } RefPtr<NrSocketBase> TestNrSocket::create_external_socket( const nr_transport_addr& dest_addr) const { - MOZ_ASSERT(nat_->enabled_); - MOZ_ASSERT(!nat_->is_an_internal_tuple(dest_addr)); + MOZ_RELEASE_ASSERT(nat_->enabled_); + MOZ_RELEASE_ASSERT(!nat_->is_an_internal_tuple(dest_addr)); int r; nr_transport_addr nat_external_addr; @@ -261,7 +260,7 @@ void TestNrSocket::close() { } int TestNrSocket::listen(int backlog) { - MOZ_ASSERT(internal_socket_->my_addr().protocol == IPPROTO_TCP); + MOZ_RELEASE_ASSERT(internal_socket_->my_addr().protocol == IPPROTO_TCP); r_log(LOG_GENERIC, LOG_DEBUG, "TestNrSocket %p %s listening", this, internal_socket_->my_addr().as_string); @@ -269,7 +268,7 @@ int TestNrSocket::listen(int backlog) { } int TestNrSocket::accept(nr_transport_addr* addrp, nr_socket** sockp) { - MOZ_ASSERT(internal_socket_->my_addr().protocol == IPPROTO_TCP); + MOZ_RELEASE_ASSERT(internal_socket_->my_addr().protocol == IPPROTO_TCP); int r = internal_socket_->accept(addrp, sockp); if (r) { return r; @@ -296,7 +295,7 @@ void TestNrSocket::process_delayed_cb(NR_SOCKET s, int how, void* cb_arg) { int TestNrSocket::sendto(const void* msg, size_t len, int flags, const nr_transport_addr* to) { - MOZ_ASSERT(internal_socket_->my_addr().protocol != IPPROTO_TCP); + MOZ_RELEASE_ASSERT(internal_socket_->my_addr().protocol != IPPROTO_TCP); r_log(LOG_GENERIC, LOG_DEBUG, "TestNrSocket %p %s %s", this, __FUNCTION__, to->as_string); @@ -347,10 +346,7 @@ int TestNrSocket::sendto(const void* msg, size_t len, int flags, external_socket = similar_port_mapping->external_socket_; } else { external_socket = create_external_socket(*to); - if (!external_socket) { - MOZ_ASSERT(false); - return R_INTERNAL; - } + MOZ_RELEASE_ASSERT(external_socket); } port_mapping = create_port_mapping(*to, external_socket); @@ -371,7 +367,7 @@ int TestNrSocket::sendto(const void* msg, size_t len, int flags, int TestNrSocket::recvfrom(void* buf, size_t maxlen, size_t* len, int flags, nr_transport_addr* from) { - MOZ_ASSERT(internal_socket_->my_addr().protocol != IPPROTO_TCP); + MOZ_RELEASE_ASSERT(internal_socket_->my_addr().protocol != IPPROTO_TCP); if (!read_buffer_.empty()) { UdpPacket& packet = read_buffer_.front(); @@ -441,8 +437,8 @@ bool TestNrSocket::allow_ingress(const nr_transport_addr& to, const nr_transport_addr& from, PortMapping** port_mapping_used) const { // This is only called for traffic arriving at a port mapping - MOZ_ASSERT(nat_->enabled_); - MOZ_ASSERT(!nat_->is_an_internal_tuple(from)); + MOZ_RELEASE_ASSERT(nat_->enabled_); + MOZ_RELEASE_ASSERT(!nat_->is_an_internal_tuple(from)); // Find the port mapping (if any) that this packet landed on *port_mapping_used = nullptr; @@ -603,7 +599,7 @@ int TestNrSocket::write(const void* msg, size_t len, size_t* written) { return R_INTERNAL; } // This is TCP only - MOZ_ASSERT(port_mappings_.size() == 1); + MOZ_RELEASE_ASSERT(port_mappings_.size() == 1); r_log(LOG_GENERIC, LOG_DEBUG, "PortMapping %s -> %s writing", port_mappings_.front()->external_socket_->my_addr().as_string, port_mappings_.front()->remote_address_.as_string); @@ -641,7 +637,7 @@ int TestNrSocket::read(void* buf, size_t maxlen, size_t* len) { if (port_mappings_.empty()) { r = internal_socket_->read(buf, maxlen, len); } else { - MOZ_ASSERT(port_mappings_.size() == 1); + MOZ_RELEASE_ASSERT(port_mappings_.size() == 1); r = port_mappings_.front()->external_socket_->read(buf, maxlen, len); if (!r && nat_->refresh_on_ingress_) { port_mappings_.front()->last_used_ = PR_IntervalNow(); @@ -722,7 +718,7 @@ int TestNrSocket::async_wait(int how, NR_async_cb cb, void* cb_arg, if (internal_socket_->my_addr().protocol == IPPROTO_TCP) { // For a TCP connection through a simulated NAT, these signals are // just passed through. - MOZ_ASSERT(port_mappings_.size() == 1); + MOZ_RELEASE_ASSERT(port_mappings_.size() == 1); return port_mappings_.front()->async_wait( how, port_mapping_tcp_passthrough_callback, this, function, line); @@ -834,7 +830,7 @@ void TestNrSocket::on_socket_readable(NrSocketBase* real_socket) { } void TestNrSocket::fire_readable_callback() { - MOZ_ASSERT(poll_flags() & PR_POLL_READ); + MOZ_RELEASE_ASSERT(poll_flags() & PR_POLL_READ); r_log(LOG_GENERIC, LOG_DEBUG, "TestNrSocket %p %s ready for read", this, internal_socket_->my_addr().as_string); fire_callback(NR_ASYNC_WAIT_READ); @@ -849,7 +845,7 @@ void TestNrSocket::port_mapping_writeable_callback(void* ext_sock_v, int how, } void TestNrSocket::write_to_port_mapping(NrSocketBase* external_socket) { - MOZ_ASSERT(internal_socket_->my_addr().protocol != IPPROTO_TCP); + MOZ_RELEASE_ASSERT(internal_socket_->my_addr().protocol != IPPROTO_TCP); int r = 0; for (PortMapping* port_mapping : port_mappings_) { @@ -935,7 +931,7 @@ TestNrSocket::PortMapping::PortMapping( } int TestNrSocket::PortMapping::send_from_queue() { - MOZ_ASSERT(remote_address_.protocol != IPPROTO_TCP); + MOZ_RELEASE_ASSERT(remote_address_.protocol != IPPROTO_TCP); int r = 0; while (!send_queue_.empty()) { @@ -967,7 +963,7 @@ int TestNrSocket::PortMapping::send_from_queue() { int TestNrSocket::PortMapping::sendto(const void* msg, size_t len, const nr_transport_addr& to) { - MOZ_ASSERT(remote_address_.protocol != IPPROTO_TCP); + MOZ_RELEASE_ASSERT(remote_address_.protocol != IPPROTO_TCP); r_log(LOG_GENERIC, LOG_DEBUG, "PortMapping %s -> %s sending to %s", external_socket_->my_addr().as_string, remote_address_.as_string, to.as_string); diff --git a/dom/media/webrtc/transport/third_party/nICEr/src/stun/addrs.c b/dom/media/webrtc/transport/third_party/nICEr/src/stun/addrs.c index 362b7d828e..51f72f4179 100644 --- a/dom/media/webrtc/transport/third_party/nICEr/src/stun/addrs.c +++ b/dom/media/webrtc/transport/third_party/nICEr/src/stun/addrs.c @@ -62,82 +62,125 @@ nr_stun_is_duplicate_addr(nr_local_addr addrs[], int count, nr_local_addr *addr) return 0; } +static int +nr_stun_filter_find_first_addr_with_ifname(nr_local_addr addrs[], int count, const char *ifname) { + for (int i = 0; i < count; ++i) { + if (!strncmp(addrs[i].addr.ifname, ifname, sizeof(addrs[i].addr.ifname))) { + return i; + } + } + return count; +} + +static int +nr_stun_filter_addrs_for_ifname(nr_local_addr src[], const int src_begin, const int src_end, nr_local_addr dest[], int *dest_index, int remove_loopback, int remove_link_local) { + int r, _status; + /* We prefer temp ipv6 for their privacy properties. If we cannot get + * that, we prefer ipv6 that are not based on mac address. */ + int filter_mac_ipv6 = 0; + int filter_teredo_ipv6 = 0; + int filter_non_temp_ipv6 = 0; + + const char* ifname = src[src_begin].addr.ifname; + + /* Figure out what we want to filter */ + for (int i = src_begin; i < src_end; ++i) { + if (strncmp(ifname, src[i].addr.ifname, sizeof(src[i].addr.ifname))) { + /* Ignore addrs from other interfaces */ + continue; + } + + if (src[i].addr.ip_version == NR_IPV6) { + if (nr_transport_addr_is_teredo(&src[i].addr)) { + src[i].interface.type |= NR_INTERFACE_TYPE_TEREDO; + /* Prefer teredo over mac-based address. Probably will never see + * both. */ + filter_mac_ipv6 = 1; + } else { + filter_teredo_ipv6 = 1; + } + + if (!nr_transport_addr_is_mac_based(&src[i].addr)) { + filter_mac_ipv6 = 1; + } + + if (src[i].flags & NR_ADDR_FLAG_TEMPORARY) { + filter_non_temp_ipv6 = 1; + } + } + } + + /* Perform the filtering */ + for (int i = src_begin; i < src_end; ++i) { + if (strncmp(ifname, src[i].addr.ifname, sizeof(src[i].addr.ifname))) { + /* Ignore addrs from other interfaces */ + continue; + } + + if (nr_stun_is_duplicate_addr(dest, *dest_index, &src[i])) { + /* skip src[i], it's a duplicate */ + } + else if (remove_loopback && nr_transport_addr_is_loopback(&src[i].addr)) { + /* skip src[i], it's a loopback */ + } + else if (remove_link_local && + nr_transport_addr_is_link_local(&src[i].addr)) { + /* skip src[i], it's a link-local address */ + } + else if (filter_mac_ipv6 && + nr_transport_addr_is_mac_based(&src[i].addr)) { + /* skip src[i], it's MAC based */ + } + else if (filter_teredo_ipv6 && + nr_transport_addr_is_teredo(&src[i].addr)) { + /* skip src[i], it's a Teredo address */ + } + else if (filter_non_temp_ipv6 && + (src[i].addr.ip_version == NR_IPV6) && + !(src[i].flags & NR_ADDR_FLAG_TEMPORARY)) { + /* skip src[i], it's a non-temporary ipv6, and we have a temporary */ + } + else { + /* otherwise, copy it to the destination array */ + if ((r=nr_local_addr_copy(&dest[*dest_index], &src[i]))) + ABORT(r); + ++(*dest_index); + } + } + + _status = 0; +abort: + return _status; +} + int nr_stun_filter_addrs(nr_local_addr addrs[], int remove_loopback, int remove_link_local, int *count) { int r, _status; nr_local_addr *tmp = 0; - int i; - int n; - /* We prefer temp ipv6 for their privacy properties. If we cannot get - * that, we prefer ipv6 that are not based on mac address. */ - int filter_mac_ipv6 = 0; - int filter_teredo_ipv6 = 0; - int filter_non_temp_ipv6 = 0; + int dest_index = 0; tmp = RMALLOC(*count * sizeof(*tmp)); if (!tmp) ABORT(R_NO_MEMORY); - for (i = 0; i < *count; ++i) { - if (addrs[i].addr.ip_version == NR_IPV6) { - if (nr_transport_addr_is_teredo(&addrs[i].addr)) { - addrs[i].interface.type |= NR_INTERFACE_TYPE_TEREDO; - /* Prefer teredo over mac-based address. Probably will never see - * both. */ - filter_mac_ipv6 = 1; - } else { - filter_teredo_ipv6 = 1; - } - - if (!nr_transport_addr_is_mac_based(&addrs[i].addr)) { - filter_mac_ipv6 = 1; - } - - if (addrs[i].flags & NR_ADDR_FLAG_TEMPORARY) { - filter_non_temp_ipv6 = 1; + for (int i = 0; i < *count; ++i) { + if (i == nr_stun_filter_find_first_addr_with_ifname(addrs, *count, addrs[i].addr.ifname)) { + /* This is the first address associated with this interface. + * Filter for this interface once, now. */ + if (r = nr_stun_filter_addrs_for_ifname(addrs, i, *count, tmp, &dest_index, remove_loopback, remove_link_local)) { + ABORT(r); } } } - n = 0; - for (i = 0; i < *count; ++i) { - if (nr_stun_is_duplicate_addr(tmp, n, &addrs[i])) { - /* skip addrs[i], it's a duplicate */ - } - else if (remove_loopback && nr_transport_addr_is_loopback(&addrs[i].addr)) { - /* skip addrs[i], it's a loopback */ - } - else if (remove_link_local && - nr_transport_addr_is_link_local(&addrs[i].addr)) { - /* skip addrs[i], it's a link-local address */ - } - else if (filter_mac_ipv6 && - nr_transport_addr_is_mac_based(&addrs[i].addr)) { - /* skip addrs[i], it's MAC based */ - } - else if (filter_teredo_ipv6 && - nr_transport_addr_is_teredo(&addrs[i].addr)) { - /* skip addrs[i], it's a Teredo address */ - } - else if (filter_non_temp_ipv6 && - (addrs[i].addr.ip_version == NR_IPV6) && - !(addrs[i].flags & NR_ADDR_FLAG_TEMPORARY)) { - /* skip addrs[i], it's a non-temporary ipv6, and we have a temporary */ - } - else { - /* otherwise, copy it to the temporary array */ - if ((r=nr_local_addr_copy(&tmp[n], &addrs[i]))) - ABORT(r); - ++n; - } - } + /* Clear the entire array out before copying back */ + memset(addrs, 0, *count * sizeof(*addrs)); - *count = n; + *count = dest_index; - memset(addrs, 0, *count * sizeof(*addrs)); /* copy temporary array into passed in/out array */ - for (i = 0; i < *count; ++i) { + for (int i = 0; i < *count; ++i) { if ((r=nr_local_addr_copy(&addrs[i], &tmp[i]))) ABORT(r); } diff --git a/dom/media/webrtc/transport/third_party/nrappkit/src/log/r_log.c b/dom/media/webrtc/transport/third_party/nrappkit/src/log/r_log.c index 09bb24749f..bb47cda879 100644 --- a/dom/media/webrtc/transport/third_party/nrappkit/src/log/r_log.c +++ b/dom/media/webrtc/transport/third_party/nrappkit/src/log/r_log.c @@ -375,22 +375,10 @@ int r_vlog(int facility,int level,const char *format,va_list ap) int stderr_vlog(int facility,int level,const char *format,va_list ap) { -#if 0 /* remove time stamping, for now */ - char cbuf[30]; - time_t tt; - - tt=time(0); - - ctime_r(&tt,cbuf); - cbuf[strlen(cbuf)-1]=0; - - fprintf(stderr,"%s: ",cbuf); -#endif - vfprintf(stderr,format,ap); fprintf(stderr,"\n"); return(0); - } + } int syslog_vlog(int facility,int level,const char *format,va_list ap) { @@ -525,7 +513,7 @@ int r_logging(int facility, int level) static int r_log_get_default_level(void) { - char *log; + char *log = 0; int _status; log=getenv("R_LOG_LEVEL"); @@ -546,7 +534,7 @@ static int r_log_get_default_level(void) static int r_log_get_destinations(int usereg) { - char *log; + char *log = 0; int i; int r,_status; @@ -627,7 +615,7 @@ int r_log_init() int _r_log_init(int use_reg) { #ifndef WIN32 - char *log; + char *log = 0; #endif if(r_log_initted==0) { diff --git a/dom/media/webrtc/transport/third_party/nrappkit/src/registry/registry.c b/dom/media/webrtc/transport/third_party/nrappkit/src/registry/registry.c index 709b1c3fb7..3134ad1536 100644 --- a/dom/media/webrtc/transport/third_party/nrappkit/src/registry/registry.c +++ b/dom/media/webrtc/transport/third_party/nrappkit/src/registry/registry.c @@ -563,7 +563,7 @@ NR_reg_make_registry(NR_registry parent, char *child, NR_registry out) int r, _status; size_t plen; size_t clen; - char *c; + char *c = 0; size_t i; if ((r=nr_reg_is_valid(parent))) diff --git a/dom/media/webrtc/transport/third_party/nrappkit/src/registry/registry_local.c b/dom/media/webrtc/transport/third_party/nrappkit/src/registry/registry_local.c index ed6e19aaa0..e577b7d4e5 100644 --- a/dom/media/webrtc/transport/third_party/nrappkit/src/registry/registry_local.c +++ b/dom/media/webrtc/transport/third_party/nrappkit/src/registry/registry_local.c @@ -134,19 +134,9 @@ static int nr_reg_get_array(char *name, unsigned char type, UCHAR *out, size_t s static int nr_reg_set(char *name, int type, void *data); static int nr_reg_set_array(char *name, unsigned char type, UCHAR *data, size_t length); static int nr_reg_set_parent_registries(char *name); - -/* make these static OLD_REGISTRY */ -#if 0 -static int nr_reg_fetch_node(char *name, unsigned char type, nr_registry_node **node, int *free_node); -static char *nr_reg_alloc_node_data(char *name, nr_registry_node *node, int *freeit); -#else int nr_reg_fetch_node(char *name, unsigned char type, nr_registry_node **node, int *free_node); char *nr_reg_alloc_node_data(char *name, nr_registry_node *node, int *freeit); -#endif static int nr_reg_rfree(void *ptr); -#if 0 /* Unused currently */ -static int nr_reg_noop(void *ptr); -#endif static int nr_reg_compute_length(char *name, nr_registry_node *node, size_t *length); char *nr_reg_action_name(int action); @@ -155,10 +145,6 @@ char *nr_reg_action_name(int action); * nr_array_registry_node */ static r_assoc *nr_registry = 0; -#if 0 /* Unused currently */ -static nr_array_registry_node nr_top_level_node; -#endif - typedef struct nr_reg_find_children_arg_ { size_t size; NR_registry *children; @@ -178,7 +164,7 @@ nr_reg_local_iter(NR_registry prefix, int (*action)(void *ptr, r_assoc_iterator { int r, _status; r_assoc_iterator iter; - char *name; + char *name = 0; int namel; nr_registry_node *node; int prefixl; @@ -246,7 +232,7 @@ nr_reg_local_find_children(void *ptr, r_assoc_iterator *iter, char *prefix, char { int _status; int prefixl = strlen(prefix); - char *dot; + char *dot = 0; nr_reg_find_children_arg *arg = (void*)ptr; assert(sizeof(*(arg->children)) == sizeof(NR_registry)); @@ -275,7 +261,7 @@ int nr_reg_local_count_children(void *ptr, r_assoc_iterator *iter, char *prefix, char *name, nr_registry_node *node) { int prefixl = strlen(prefix); - char *dot; + char *dot = 0; /* only count children */ if (name[prefixl] == '.') { @@ -296,7 +282,7 @@ nr_reg_local_dump_print(void *ptr, r_assoc_iterator *iter, char *prefix, char *n { int _status; int freeit = 0; - char *data; + char *data = 0; /* only print leaf nodes */ if (node->type != NR_REG_TYPE_REGISTRY) { @@ -315,14 +301,6 @@ nr_reg_local_dump_print(void *ptr, r_assoc_iterator *iter, char *prefix, char *n } -#if 0 /* Unused currently */ -int -nr_reg_noop(void *ptr) -{ - return 0; -} -#endif - int nr_reg_rfree(void *ptr) { @@ -750,7 +728,7 @@ nr_reg_set_parent_registries(char *name) { int r, _status; char *parent = 0; - char *dot; + char *dot = 0; if ((parent = r_strdup(name)) == 0) ABORT(R_NO_MEMORY); @@ -955,7 +933,7 @@ nr_reg_local_get_type(NR_registry name, NR_registry_type type) { int r, _status; nr_registry_node *node = 0; - char *str; + char *str = 0; if ((r=nr_reg_is_valid(name))) ABORT(r); @@ -1044,7 +1022,7 @@ int nr_reg_local_get_child_count(NR_registry parent, size_t *count) { int r, _status; - nr_registry_node *ignore1; + nr_registry_node *ignore1 = 0; int ignore2; diff --git a/dom/media/webrtc/transport/third_party/nrappkit/src/registry/registrycb.c b/dom/media/webrtc/transport/third_party/nrappkit/src/registry/registrycb.c index 4b326a1ee2..bd3570cefc 100644 --- a/dom/media/webrtc/transport/third_party/nrappkit/src/registry/registrycb.c +++ b/dom/media/webrtc/transport/third_party/nrappkit/src/registry/registrycb.c @@ -118,9 +118,9 @@ int nr_reg_register_callback(NR_registry name, char action, void (*cb)(void *cb_arg, char action, NR_registry name), void *cb_arg) { int r, _status; - r_assoc *assoc; + r_assoc *assoc = 0; int create_assoc = 0; - nr_reg_cb_info *info; + nr_reg_cb_info *info = 0; int create_info = 0; unsigned char cb_id[SIZEOF_CB_ID]; @@ -191,7 +191,7 @@ int nr_reg_unregister_callback(char *name, char action, void (*cb)(void *cb_arg, char action, NR_registry name)) { int r, _status; - r_assoc *assoc; + r_assoc *assoc = 0; int size; unsigned char cb_id[SIZEOF_CB_ID]; @@ -283,12 +283,12 @@ int nr_reg_raise_event_recurse(char *name, char *tmp, int action) { int r, _status; - r_assoc *assoc; + r_assoc *assoc = 0; nr_reg_cb_info *info; r_assoc_iterator iter; - char *key; + char *key = 0; int keyl; - char *c; + char *c = 0; int free_tmp = 0; int count; diff --git a/dom/media/webrtc/transport/third_party/nrappkit/src/util/libekr/r_assoc.c b/dom/media/webrtc/transport/third_party/nrappkit/src/util/libekr/r_assoc.c index 25b3827d50..eb8cb0b061 100644 --- a/dom/media/webrtc/transport/third_party/nrappkit/src/util/libekr/r_assoc.c +++ b/dom/media/webrtc/transport/third_party/nrappkit/src/util/libekr/r_assoc.c @@ -150,7 +150,7 @@ int r_assoc_create(assocp,hash_func,bits) int r_assoc_destroy(assocp) r_assoc **assocp; { - r_assoc *assoc; + r_assoc *assoc = 0; int i; if(!assocp || !*assocp) @@ -169,7 +169,7 @@ int r_assoc_destroy(assocp) static int destroy_assoc_chain(chain) r_assoc_el *chain; { - r_assoc_el *nxt; + r_assoc_el *nxt = 0; while(chain){ nxt=chain->next; @@ -190,7 +190,7 @@ static int copy_assoc_chain(knewp,old) r_assoc_el **knewp; r_assoc_el *old; { - r_assoc_el *knew=0,*ptr,*tmp; + r_assoc_el *knew = 0, *ptr = 0, *tmp = 0; int r,_status; ptr=0; /* Pacify GCC's uninitialized warning. @@ -245,7 +245,7 @@ static int r_assoc_fetch_bucket(assoc,key,len,bucketp) r_assoc_el **bucketp; { UINT4 hash_value; - r_assoc_el *bucket; + r_assoc_el *bucket = 0; hash_value=assoc->hash_func(key,len,assoc->bits); @@ -265,7 +265,7 @@ int r_assoc_fetch(assoc,key,len,datap) int len; void **datap; { - r_assoc_el *bucket; + r_assoc_el *bucket = 0; int r; if(r=r_assoc_fetch_bucket(assoc,key,len,&bucket)){ @@ -287,7 +287,7 @@ int r_assoc_insert(assoc,key,len,data,copy,destroy,how) int (*destroy)(void *ptr); int how; { - r_assoc_el *bucket,*new_bucket=0; + r_assoc_el *bucket = 0, *new_bucket = 0; int r,_status; if(r=r_assoc_fetch_bucket(assoc,key,len,&bucket)){ @@ -340,7 +340,7 @@ int r_assoc_delete(assoc,key,len) int len; { int r; - r_assoc_el *bucket; + r_assoc_el *bucket = 0; UINT4 hash_value; if(r=r_assoc_fetch_bucket(assoc,key,len,&bucket)){ @@ -377,7 +377,7 @@ int r_assoc_copy(knewp,old) r_assoc *old; { int r,_status,i; - r_assoc *knew; + r_assoc *knew = 0; if(!(knew=(r_assoc *)RCALLOC(sizeof(r_assoc)))) ABORT(R_NO_MEMORY); @@ -441,7 +441,7 @@ int r_assoc_iter(iter,key,keyl,val) void **val; { int i; - r_assoc_el *ret; + r_assoc_el *ret = 0; if(!iter->next) return(R_EOD); diff --git a/dom/media/webrtc/transport/third_party/nrappkit/src/util/libekr/r_crc32.c b/dom/media/webrtc/transport/third_party/nrappkit/src/util/libekr/r_crc32.c index 38d3e4da38..6def127dfd 100644 --- a/dom/media/webrtc/transport/third_party/nrappkit/src/util/libekr/r_crc32.c +++ b/dom/media/webrtc/transport/third_party/nrappkit/src/util/libekr/r_crc32.c @@ -157,7 +157,7 @@ r_crc32(buf, dlen, cval) u_int32_t *cval; { u_int32_t crc = ~0; - char *p ; + char *p = 0; int i; u_int32_t crc32_total = 0 ; diff --git a/dom/media/webrtc/transport/third_party/nrappkit/src/util/libekr/r_data.c b/dom/media/webrtc/transport/third_party/nrappkit/src/util/libekr/r_data.c index dfb7af2d5c..23df74fb8b 100644 --- a/dom/media/webrtc/transport/third_party/nrappkit/src/util/libekr/r_data.c +++ b/dom/media/webrtc/transport/third_party/nrappkit/src/util/libekr/r_data.c @@ -183,7 +183,7 @@ int r_data_destroy(dp) int r_data_destroy_v(v) void *v; { - Data *d; + Data *d = 0; if(!v) return(0); @@ -199,7 +199,7 @@ int r_data_destroy_v(v) int r_data_destroy_vp(v) void **v; { - Data *d; + Data *d = 0; if(!v || !*v) return(0); diff --git a/dom/media/webrtc/transport/third_party/nrappkit/src/util/libekr/r_list.c b/dom/media/webrtc/transport/third_party/nrappkit/src/util/libekr/r_list.c index 4e71d67030..527d39b43a 100644 --- a/dom/media/webrtc/transport/third_party/nrappkit/src/util/libekr/r_list.c +++ b/dom/media/webrtc/transport/third_party/nrappkit/src/util/libekr/r_list.c @@ -117,8 +117,8 @@ int r_list_create(listp) int r_list_destroy(listp) r_list **listp; { - r_list *list; - r_list_el *el; + r_list *list = 0; + r_list_el *el = 0; if(!listp || !*listp) return(0); @@ -147,7 +147,7 @@ int r_list_copy(outp,in) r_list *in; { r_list *out=0; - r_list_el *el,*el2,*last=0; + r_list_el *el = 0, *el2 = 0, *last = 0; int r, _status; if(!in){ diff --git a/dom/media/webrtc/transport/third_party/nrappkit/src/util/libekr/r_memory.c b/dom/media/webrtc/transport/third_party/nrappkit/src/util/libekr/r_memory.c index 53846fc019..3cfcc916d4 100644 --- a/dom/media/webrtc/transport/third_party/nrappkit/src/util/libekr/r_memory.c +++ b/dom/media/webrtc/transport/third_party/nrappkit/src/util/libekr/r_memory.c @@ -66,7 +66,7 @@ void *r_malloc(type,size) size_t size; { size_t total; - r_malloc_chunk *chunk; + r_malloc_chunk *chunk = 0; total=size+sizeof(r_malloc_chunk); @@ -90,7 +90,7 @@ void *r_calloc(type,number,size) size_t number; size_t size; { - void *ret; + void *ret = 0; size_t total; total=number*size; @@ -106,7 +106,7 @@ void *r_calloc(type,number,size) void r_free(ptr) void *ptr; { - r_malloc_chunk *chunk; + r_malloc_chunk *chunk = 0; if(!ptr) return; @@ -125,7 +125,7 @@ void *r_realloc(ptr,size) void *ptr; size_t size; { - r_malloc_chunk *chunk,*nchunk; + r_malloc_chunk *chunk = 0, *nchunk = 0; size_t total; if(!ptr) return(r_malloc(255,size)); @@ -154,7 +154,7 @@ char *r_strdup(str) const char *str; { int len; - char *nstr; + char *nstr = 0; if(!str) return(0); diff --git a/dom/media/webrtc/transport/third_party/nrappkit/src/util/libekr/r_replace.c b/dom/media/webrtc/transport/third_party/nrappkit/src/util/libekr/r_replace.c index 8916b884cc..4dc8feb878 100644 --- a/dom/media/webrtc/transport/third_party/nrappkit/src/util/libekr/r_replace.c +++ b/dom/media/webrtc/transport/third_party/nrappkit/src/util/libekr/r_replace.c @@ -88,7 +88,7 @@ char *strdup(str) char *str; { int len=strlen(str); - char *n; + char *n = 0; if(!(n=(char *)malloc(len+1))) return(0); diff --git a/dom/media/webrtc/transport/third_party/nrappkit/src/util/p_buf.c b/dom/media/webrtc/transport/third_party/nrappkit/src/util/p_buf.c index 459baecdda..6ada8420ed 100644 --- a/dom/media/webrtc/transport/third_party/nrappkit/src/util/p_buf.c +++ b/dom/media/webrtc/transport/third_party/nrappkit/src/util/p_buf.c @@ -72,7 +72,7 @@ int nr_p_buf_ctx_create(size,ctxp) int nr_p_buf_ctx_destroy(ctxp) nr_p_buf_ctx **ctxp; { - nr_p_buf_ctx *ctx; + nr_p_buf_ctx *ctx = 0; if(!ctxp || !*ctxp) return(0); @@ -133,7 +133,7 @@ int nr_p_buf_free_chain(ctx,head) nr_p_buf_ctx *ctx; nr_p_buf_head *head; { - nr_p_buf *n1,*n2; + nr_p_buf *n1 = 0, *n2 = 0; n1=STAILQ_FIRST(head); while(n1){ @@ -155,7 +155,7 @@ int nr_p_buf_write_to_chain(ctx,chain,data,len) UINT4 len; { int r,_status; - nr_p_buf *buf; + nr_p_buf *buf = 0; buf=STAILQ_LAST(chain,nr_p_buf_,entry); while(len){ @@ -186,7 +186,7 @@ int nr_p_buf_write_to_chain(ctx,chain,data,len) static int nr_p_buf_destroy_chain(head) nr_p_buf_head *head; { - nr_p_buf *n1,*n2; + nr_p_buf *n1 = 0, *n2 = 0; n1=STAILQ_FIRST(head); while(n1){ diff --git a/dom/media/webrtc/transport/third_party/nrappkit/src/util/util.c b/dom/media/webrtc/transport/third_party/nrappkit/src/util/util.c index 79b14a8967..51f75832b1 100644 --- a/dom/media/webrtc/transport/third_party/nrappkit/src/util/util.c +++ b/dom/media/webrtc/transport/third_party/nrappkit/src/util/util.c @@ -79,38 +79,6 @@ int nr_get_filename(base,name,namep) return(_status); } -#if 0 -int read_RSA_private_key(base,name,keyp) - char *base; - char *name; - RSA **keyp; - { - char *keyfile=0; - BIO *bio=0; - FILE *fp=0; - RSA *rsa=0; - int r,_status; - - /* Load the keyfile */ - if(r=get_filename(base,name,&keyfile)) - ABORT(r); - if(!(fp=fopen(keyfile,"r"))) - ABORT(R_NOT_FOUND); - if(!(bio=BIO_new(BIO_s_file()))) - ABORT(R_NO_MEMORY); - BIO_set_fp(bio,fp,BIO_NOCLOSE); - - if(!(rsa=PEM_read_bio_RSAPrivateKey(bio,0,0,0))) - ABORT(R_NOT_FOUND); - - *keyp=rsa; - _status=0; - abort: - return(_status); - } -#endif - - void nr_errprintf_log(const char *format,...) { va_list ap; @@ -296,55 +264,6 @@ int nr_sha1_file(char *filename,UCHAR *out) // TODO #else -#if 0 - -#include <fts.h> - -int nr_rm_tree(char *path) - { - FTS *fts=0; - FTSENT *p; - int failed=0; - int _status; - char *argv[2]; - - argv[0]=path; - argv[1]=0; - - if(!(fts=fts_open(argv,0,NULL))){ - r_log_e(LOG_COMMON,LOG_ERR,"Couldn't open directory %s",path); - ABORT(R_FAILED); - } - - while(p=fts_read(fts)){ - switch(p->fts_info){ - case FTS_D: - break; - case FTS_DOT: - break; - case FTS_ERR: - r_log_e(LOG_COMMON,LOG_ERR,"Problem reading %s",p->fts_path); - break; - default: - r_log(LOG_COMMON,LOG_DEBUG,"Removing %s",p->fts_path); - errno=0; - if(remove(p->fts_path)){ - r_log_e(LOG_COMMON,LOG_ERR,"Problem removing %s",p->fts_path); - failed=1; - } - } - } - - if(failed) - ABORT(R_FAILED); - - _status=0; - abort: - if(fts) fts_close(fts); - return(_status); - } -#endif - int nr_write_pid_file(char *pid_filename) { FILE *fp; @@ -625,7 +544,7 @@ inet_ntop6(const unsigned char *src, char *dst, size_t size) * to use pointer overlays. All the world's not a VAX. */ char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"]; - char *tp, *ep; + char *tp = 0, *ep = 0; struct { int base, len; } best, cur; unsigned int words[NS_IN6ADDRSZ / NS_INT16SZ]; int i; diff --git a/dom/media/webrtc/transport/third_party/nrappkit/src/util/util.h b/dom/media/webrtc/transport/third_party/nrappkit/src/util/util.h index d7861659cd..26c692fbbe 100644 --- a/dom/media/webrtc/transport/third_party/nrappkit/src/util/util.h +++ b/dom/media/webrtc/transport/third_party/nrappkit/src/util/util.h @@ -43,11 +43,6 @@ #include "registry.h" int nr_get_filename(char *base,char *name, char **namep); -#if 0 -#include <openssl/ssl.h> - -int read_RSA_private_key(char *base, char *name,RSA **keyp); -#endif void nr_errprintf_log(const char *fmt,...); void nr_errprintf_log2(void *ignore, const char *fmt,...); extern int nr_util_default_log_facility; diff --git a/dom/media/webrtc/transport/transportlayerdtls.cpp b/dom/media/webrtc/transport/transportlayerdtls.cpp index 4ab8aaa029..1279726bce 100644 --- a/dom/media/webrtc/transport/transportlayerdtls.cpp +++ b/dom/media/webrtc/transport/transportlayerdtls.cpp @@ -9,12 +9,14 @@ #include "transportlayerdtls.h" #include <algorithm> +#include <iomanip> #include <queue> #include <sstream> #include "dtlsidentity.h" #include "keyhi.h" #include "logging.h" +#include "mozilla/glean/GleanMetrics.h" #include "mozilla/Telemetry.h" #include "mozilla/UniquePtr.h" #include "mozilla/Unused.h" @@ -889,6 +891,7 @@ void TransportLayerDtls::Handshake() { if (!cert_ok_) { MOZ_MTLOG(ML_ERROR, LAYER_INFO << "Certificate check never occurred"); TL_SET_STATE(TS_ERROR); + RecordHandshakeCompletionTelemetry("CERT_FAILURE"); return; } if (!CheckAlpn()) { @@ -897,11 +900,13 @@ void TransportLayerDtls::Handshake() { // (assuming the close_notify isn't dropped). ssl_fd_ = nullptr; TL_SET_STATE(TS_ERROR); + RecordHandshakeCompletionTelemetry("ALPN_FAILURE"); return; } TL_SET_STATE(TS_OPEN); + RecordHandshakeCompletionTelemetry("SUCCESS"); RecordTlsTelemetry(); timer_ = nullptr; } else { @@ -932,6 +937,7 @@ void TransportLayerDtls::Handshake() { MOZ_MTLOG(ML_ERROR, LAYER_INFO << "DTLS handshake error " << err << " (" << err_msg << ")"); TL_SET_STATE(TS_ERROR); + RecordHandshakeCompletionTelemetry(err_msg); break; } } @@ -1468,6 +1474,17 @@ void TransportLayerDtls::TimerCallback(nsITimer* timer, void* arg) { dtls->Handshake(); } +void TransportLayerDtls::RecordHandshakeCompletionTelemetry( + const char* aResult) { + if (role_ == CLIENT) { + mozilla::glean::webrtcdtls::client_handshake_result.Get(nsCString(aResult)) + .Add(1); + } else { + mozilla::glean::webrtcdtls::server_handshake_result.Get(nsCString(aResult)) + .Add(1); + } +} + void TransportLayerDtls::RecordTlsTelemetry() { MOZ_ASSERT(state_ == TS_OPEN); SSLChannelInfo info; @@ -1478,54 +1495,29 @@ void TransportLayerDtls::RecordTlsTelemetry() { return; } - uint16_t telemetry_cipher = 0; - - switch (info.cipherSuite) { - /* Old DHE ciphers: candidates for removal, see bug 1227519 */ - case TLS_DHE_RSA_WITH_AES_128_CBC_SHA: - telemetry_cipher = 1; - break; - case TLS_DHE_RSA_WITH_AES_256_CBC_SHA: - telemetry_cipher = 2; - break; - /* Current ciphers */ - case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: - telemetry_cipher = 3; - break; - case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: - telemetry_cipher = 4; - break; - case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: - telemetry_cipher = 5; - break; - case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: - telemetry_cipher = 6; - break; - case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: - telemetry_cipher = 7; + switch (info.protocolVersion) { + case SSL_LIBRARY_VERSION_TLS_1_1: + mozilla::glean::webrtcdtls::protocol_version.Get("1.0"_ns).Add(1); break; - case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: - telemetry_cipher = 8; + case SSL_LIBRARY_VERSION_TLS_1_2: + mozilla::glean::webrtcdtls::protocol_version.Get("1.2"_ns).Add(1); break; - case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: - telemetry_cipher = 9; - break; - case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: - telemetry_cipher = 10; - break; - /* TLS 1.3 ciphers */ - case TLS_AES_128_GCM_SHA256: - telemetry_cipher = 11; - break; - case TLS_CHACHA20_POLY1305_SHA256: - telemetry_cipher = 12; - break; - case TLS_AES_256_GCM_SHA384: - telemetry_cipher = 13; + case SSL_LIBRARY_VERSION_TLS_1_3: + mozilla::glean::webrtcdtls::protocol_version.Get("1.3"_ns).Add(1); break; + default: + MOZ_CRASH("Unknown SSL version"); } - Telemetry::Accumulate(Telemetry::WEBRTC_DTLS_CIPHER, telemetry_cipher); + { + std::ostringstream oss; + // Record TLS cipher-suite ID as a string (eg; + // TLS_DHE_RSA_WITH_AES_128_CBC_SHA is 0x0033) + oss << "0x" << std::setfill('0') << std::setw(4) << std::hex + << info.cipherSuite; + mozilla::glean::webrtcdtls::cipher.Get(nsCString(oss.str().c_str())).Add(1); + MOZ_MTLOG(ML_DEBUG, "cipher: " << oss.str()); + } uint16_t cipher; nsresult rv = GetSrtpCipher(&cipher); @@ -1535,24 +1527,15 @@ void TransportLayerDtls::RecordTlsTelemetry() { return; } - auto cipher_label = mozilla::Telemetry::LABELS_WEBRTC_SRTP_CIPHER::Unknown; - - switch (cipher) { - case kDtlsSrtpAes128CmHmacSha1_80: - cipher_label = Telemetry::LABELS_WEBRTC_SRTP_CIPHER::Aes128CmHmacSha1_80; - break; - case kDtlsSrtpAes128CmHmacSha1_32: - cipher_label = Telemetry::LABELS_WEBRTC_SRTP_CIPHER::Aes128CmHmacSha1_32; - break; - case kDtlsSrtpAeadAes128Gcm: - cipher_label = Telemetry::LABELS_WEBRTC_SRTP_CIPHER::AeadAes128Gcm; - break; - case kDtlsSrtpAeadAes256Gcm: - cipher_label = Telemetry::LABELS_WEBRTC_SRTP_CIPHER::AeadAes256Gcm; - break; + { + std::ostringstream oss; + // Record SRTP cipher-suite ID as a string (eg; + // SRTP_AES128_CM_HMAC_SHA1_80 is 0x0001) + oss << "0x" << std::setfill('0') << std::setw(4) << std::hex << cipher; + mozilla::glean::webrtcdtls::srtp_cipher.Get(nsCString(oss.str().c_str())) + .Add(1); + MOZ_MTLOG(ML_DEBUG, "srtp cipher: " << oss.str()); } - - Telemetry::AccumulateCategorical(cipher_label); } } // namespace mozilla diff --git a/dom/media/webrtc/transport/transportlayerdtls.h b/dom/media/webrtc/transport/transportlayerdtls.h index d68a6e77d5..e0370a04b2 100644 --- a/dom/media/webrtc/transport/transportlayerdtls.h +++ b/dom/media/webrtc/transport/transportlayerdtls.h @@ -144,7 +144,7 @@ class TransportLayerDtls final : public TransportLayer { SECStatus CheckDigest(const DtlsDigest& digest, UniqueCERTCertificate& cert) const; - void RecordHandshakeCompletionTelemetry(TransportLayer::State endState); + void RecordHandshakeCompletionTelemetry(const char* aResult); void RecordTlsTelemetry(); static PRBool WriteSrtpXtn(PRFileDesc* fd, SSLHandshakeType message, |