tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit c7e5b8a6409ede1ce621710de2ec1af41de2fe76
parent e4acecf36c2155faf50a6cafaa09d05e66c91765
Author: Dan Baker <dbaker@mozilla.com>
Date:   Mon,  1 Dec 2025 21:34:23 -0700

Bug 2000941 - Vendor libwebrtc from c12a00ea3b

Upstream commit: https://webrtc.googlesource.com/src/+/c12a00ea3ba2caa62dc0aa40c79ba93e50a700b0
    Require field trial parameter offer:true to create offer with RFC8888

    To both offer and answer with RFC 8888 support, use field trial string "WebRTC-RFC8888CongestionControlFeedback/Enabled,offer:true/"

    The purpose is to simplify rollout.
    ie. first, an experiment with answering an offer with RFC 8888 can be rolled out. This should be a
    noop. Later enabling sending an offer should enable using RFC8888.

    Bug: webrtc:42225697
    Change-Id: I2b4e52a9335303f2ef6a744027d83eb7f18e1edf
    Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/404041
    Reviewed-by: Harald Alvestrand <hta@webrtc.org>
    Commit-Queue: Per Kjellander <perkj@webrtc.org>
    Cr-Commit-Position: refs/heads/main@{#45671}

Diffstat:
Mthird_party/libwebrtc/README.mozilla.last-vendor | 4++--
Mthird_party/libwebrtc/moz-patch-stack/s0102.patch | 2+-
Mthird_party/libwebrtc/pc/BUILD.gn | 1+
Mthird_party/libwebrtc/pc/congestion_control_integrationtest.cc | 60+++++++++++++++++++++++++++++++++++++++++++++++++++---------
Mthird_party/libwebrtc/pc/media_session.cc | 33+++++++++++++++++++++++----------
Mthird_party/libwebrtc/pc/media_session.h | 5+++++
Mthird_party/libwebrtc/pc/rtc_stats_integrationtest.cc | 2+-
Mthird_party/libwebrtc/test/peer_scenario/tests/l4s_test.cc | 16++++++++++------
8 files changed, 94 insertions(+), 29 deletions(-)

diff --git a/third_party/libwebrtc/README.mozilla.last-vendor b/third_party/libwebrtc/README.mozilla.last-vendor @@ -1,4 +1,4 @@ # ./mach python dom/media/webrtc/third_party_build/vendor-libwebrtc.py --from-local /Users/danielbaker/elm/.moz-fast-forward/moz-libwebrtc --commit mozpatches libwebrtc -libwebrtc updated from /Users/danielbaker/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2025-12-02T04:30:56.067111+00:00. +libwebrtc updated from /Users/danielbaker/elm/.moz-fast-forward/moz-libwebrtc commit mozpatches on 2025-12-02T04:34:09.212126+00:00. # base of lastest vendoring -b83fd4628c +c12a00ea3b diff --git a/third_party/libwebrtc/moz-patch-stack/s0102.patch b/third_party/libwebrtc/moz-patch-stack/s0102.patch @@ -601,7 +601,7 @@ index b7561e53b6..fe7eb57423 100644 import("../../webrtc.gni") diff --git a/pc/BUILD.gn b/pc/BUILD.gn -index deb0435c15..44d226504f 100644 +index 23d10bbd83..0c5ec81d48 100644 --- a/pc/BUILD.gn +++ b/pc/BUILD.gn @@ -30,8 +30,8 @@ diff --git a/third_party/libwebrtc/pc/BUILD.gn b/third_party/libwebrtc/pc/BUILD.gn @@ -377,6 +377,7 @@ rtc_library("media_session") { "../rtc_base:checks", "../rtc_base:logging", "../rtc_base:unique_id_generator", + "../rtc_base/experiments:field_trial_parser", "../rtc_base/memory:always_valid_pointer", "//third_party/abseil-cpp/absl/algorithm:container", "//third_party/abseil-cpp/absl/strings", diff --git a/third_party/libwebrtc/pc/congestion_control_integrationtest.cc b/third_party/libwebrtc/pc/congestion_control_integrationtest.cc @@ -44,18 +44,32 @@ class PeerConnectionCongestionControlTest : PeerConnectionIntegrationBaseTest(SdpSemantics::kUnifiedPlan) {} }; -TEST_F(PeerConnectionCongestionControlTest, OfferContainsCcfbIfEnabled) { +TEST_F(PeerConnectionCongestionControlTest, + OfferDoesNotContainCcfbEvenIfEnabled) { SetFieldTrials("WebRTC-RFC8888CongestionControlFeedback/Enabled/"); ASSERT_TRUE(CreatePeerConnectionWrappers()); caller()->AddAudioVideoTracks(); std::unique_ptr<SessionDescriptionInterface> offer = caller()->CreateOfferAndWait(); std::string offer_str = absl::StrCat(*offer); + EXPECT_THAT(offer_str, Not(HasSubstr("a=rtcp-fb:* ack ccfb\r\n"))); +} + +TEST_F(PeerConnectionCongestionControlTest, OfferContainsCcfbIfFieldTrial) { + SetFieldTrials("WebRTC-RFC8888CongestionControlFeedback/Enabled,offer:true/"); + ASSERT_TRUE(CreatePeerConnectionWrappers()); + caller()->AddAudioVideoTracks(); + std::unique_ptr<SessionDescriptionInterface> offer = + caller()->CreateOfferAndWait(); + std::string offer_str = absl::StrCat(*offer); EXPECT_THAT(offer_str, HasSubstr("a=rtcp-fb:* ack ccfb\r\n")); } TEST_F(PeerConnectionCongestionControlTest, ReceiveOfferSetsCcfbFlag) { - SetFieldTrials("WebRTC-RFC8888CongestionControlFeedback/Enabled/"); + SetFieldTrials(kCallerName, + "WebRTC-RFC8888CongestionControlFeedback/Enabled,offer:true/"); + SetFieldTrials(kCalleeName, + "WebRTC-RFC8888CongestionControlFeedback/Enabled/"); ASSERT_TRUE(CreatePeerConnectionWrappers()); ConnectFakeSignalingForSdpOnly(); caller()->AddAudioVideoTracks(); @@ -89,7 +103,7 @@ TEST_F(PeerConnectionCongestionControlTest, ReceiveOfferSetsCcfbFlag) { TEST_F(PeerConnectionCongestionControlTest, SendOnlySupportDoesNotEnableCcFb) { // Enable CCFB for sender, do not enable it for receiver SetFieldTrials(kCallerName, - "WebRTC-RFC8888CongestionControlFeedback/Enabled/"); + "WebRTC-RFC8888CongestionControlFeedback/Enabled,offer:true/"); SetFieldTrials(kCalleeName, "WebRTC-RFC8888CongestionControlFeedback/Disabled/"); ASSERT_TRUE(CreatePeerConnectionWrappers()); @@ -126,7 +140,7 @@ TEST_F(PeerConnectionCongestionControlTest, ReNegotiationCalleeDoesNotSupportCcfb) { // Enable CCFB for sender, do not enable it for receiver SetFieldTrials(kCallerName, - "WebRTC-RFC8888CongestionControlFeedback/Enabled/"); + "WebRTC-RFC8888CongestionControlFeedback/Enabled,offer:true/"); SetFieldTrials(kCalleeName, "WebRTC-RFC8888CongestionControlFeedback/Disabled/"); ASSERT_TRUE(CreatePeerConnectionWrappers()); @@ -152,10 +166,10 @@ TEST_F(PeerConnectionCongestionControlTest, TEST_F(PeerConnectionCongestionControlTest, ReNegotiationBothSupportCcfb) { SetFieldTrials(kCallerName, - "WebRTC-RFC8888CongestionControlFeedback/Enabled/" + "WebRTC-RFC8888CongestionControlFeedback/Enabled,offer:true/" "WebRTC-HeaderExtensionNegotiateMemory/Enabled/"); SetFieldTrials(kCalleeName, - "WebRTC-RFC8888CongestionControlFeedback/Enabled/" + "WebRTC-RFC8888CongestionControlFeedback/Enabled,offer:true/" "WebRTC-HeaderExtensionNegotiateMemory/Enabled/"); ASSERT_TRUE(CreatePeerConnectionWrappers()); ConnectFakeSignalingForSdpOnly(); @@ -191,7 +205,7 @@ TEST_F(PeerConnectionCongestionControlTest, ReNegotiationBothSupportCcfb) { #ifdef WEBRTC_HAVE_SCTP TEST_F(PeerConnectionCongestionControlTest, ReceiveOfferWithDataChannelsSetsCcfbFlag) { - SetFieldTrials("WebRTC-RFC8888CongestionControlFeedback/Enabled/"); + SetFieldTrials("WebRTC-RFC8888CongestionControlFeedback/Enabled,offer:true/"); ASSERT_TRUE(CreatePeerConnectionWrappers()); ConnectFakeSignalingForSdpOnly(); caller()->AddAudioVideoTracks(); @@ -240,7 +254,7 @@ TEST_F(PeerConnectionCongestionControlTest, #endif TEST_F(PeerConnectionCongestionControlTest, NegotiatingCcfbRemovesTsn) { - SetFieldTrials("WebRTC-RFC8888CongestionControlFeedback/Enabled/"); + SetFieldTrials("WebRTC-RFC8888CongestionControlFeedback/Enabled,offer:true/"); ASSERT_TRUE(CreatePeerConnectionWrappers()); ConnectFakeSignalingForSdpOnly(); callee()->AddVideoTrack(); @@ -320,7 +334,7 @@ TEST_F(PeerConnectionCongestionControlTest, NegotiatingCcfbRemovesTsn) { } TEST_F(PeerConnectionCongestionControlTest, CcfbGetsUsed) { - SetFieldTrials("WebRTC-RFC8888CongestionControlFeedback/Enabled/"); + SetFieldTrials("WebRTC-RFC8888CongestionControlFeedback/Enabled,offer:true/"); ASSERT_TRUE(CreatePeerConnectionWrappers()); ConnectFakeSignaling(); caller()->AddAudioVideoTracks(); @@ -368,4 +382,32 @@ TEST_F(PeerConnectionCongestionControlTest, TransportCcGetsUsed) { EXPECT_THAT(pc_internal->FeedbackAccordingToRfc8888CountForTesting(), Eq(0)); } +TEST_F(PeerConnectionCongestionControlTest, + TransportCcGetsUsedIfCalleeNotEnabledRfc8888) { + SetFieldTrials(kCallerName, + "WebRTC-RFC8888CongestionControlFeedback/Enabled,offer:true/"); + SetFieldTrials(kCalleeName, + "WebRTC-RFC8888CongestionControlFeedback/Disabled/"); + ASSERT_TRUE(CreatePeerConnectionWrappers()); + ConnectFakeSignaling(); + caller()->AddAudioVideoTracks(); + caller()->CreateAndSetAndSignalOffer(); + ASSERT_THAT(WaitUntil([&] { return SignalingStateStable(); }, IsTrue()), + IsRtcOk()); + MediaExpectations media_expectations; + media_expectations.CalleeExpectsSomeAudio(); + media_expectations.CalleeExpectsSomeVideo(); + ASSERT_TRUE(ExpectNewFrames(media_expectations)); + auto pc_internal = caller()->pc_internal(); + EXPECT_THAT( + WaitUntil( + [&] { + return pc_internal->FeedbackAccordingToTransportCcCountForTesting(); + }, + Gt(0)), + IsRtcOk()); + // Test that RFC 8888 feedback is NOT generated when field trial disabled. + EXPECT_THAT(pc_internal->FeedbackAccordingToRfc8888CountForTesting(), Eq(0)); +} + } // namespace webrtc diff --git a/third_party/libwebrtc/pc/media_session.cc b/third_party/libwebrtc/pc/media_session.cc @@ -662,6 +662,21 @@ const TransportDescription* GetTransportDescription( return desc; } +bool OfferRfc8888(const FieldTrialsView& field_trials) { + if (field_trials.IsEnabled("WebRTC-RFC8888CongestionControlFeedback")) { + FieldTrialParameter<bool> offer_rfc_8888("offer", false); + ParseFieldTrial( + {&offer_rfc_8888}, + field_trials.Lookup("WebRTC-RFC8888CongestionControlFeedback")); + return offer_rfc_8888; + } + return false; +} + +bool AcceptOfferWithRfc8888(const FieldTrialsView& field_trials) { + return field_trials.IsEnabled("WebRTC-RFC8888CongestionControlFeedback"); +} + } // namespace MediaSessionDescriptionFactory::MediaSessionDescriptionFactory( @@ -670,7 +685,10 @@ MediaSessionDescriptionFactory::MediaSessionDescriptionFactory( UniqueRandomIdGenerator* ssrc_generator, const TransportDescriptionFactory* transport_desc_factory, CodecLookupHelper* codec_lookup_helper) - : ssrc_generator_(ssrc_generator), + : offer_rfc_8888_(OfferRfc8888(transport_desc_factory->trials())), + accept_offer_with_rfc_8888_( + AcceptOfferWithRfc8888(transport_desc_factory->trials())), + ssrc_generator_(ssrc_generator), transport_desc_factory_(transport_desc_factory), codec_lookup_helper_(codec_lookup_helper), payload_types_in_transport_trial_enabled_( @@ -838,8 +856,7 @@ MediaSessionDescriptionFactory::CreateAnswerOrError( // Decide what congestion control feedback format we're using. bool has_ack_ccfb = false; - if (transport_desc_factory_->trials().IsEnabled( - "WebRTC-RFC8888CongestionControlFeedback")) { + if (accept_offer_with_rfc_8888_) { for (const auto& content : offer->contents()) { if (content.type != MediaProtocolType::kRtp) { continue; @@ -1169,9 +1186,7 @@ RTCError MediaSessionDescriptionFactory::AddRtpContentForOffer( content_description = std::make_unique<VideoContentDescription>(); } // RFC 8888 support. - content_description->set_rtcp_fb_ack_ccfb( - transport_desc_factory_->trials().IsEnabled( - "WebRTC-RFC8888CongestionControlFeedback")); + content_description->set_rtcp_fb_ack_ccfb(offer_rfc_8888_); auto error = CreateMediaContentOffer( media_description_options, session_options, codecs_to_include, header_extensions, ssrc_generator(), current_streams, @@ -1338,10 +1353,8 @@ RTCError MediaSessionDescriptionFactory::AddRtpContentForAnswer( // RFC 8888 support. Only answer with "ack ccfb" if offer has it and // experiment is enabled. if (offer_content_description->rtcp_fb_ack_ccfb()) { - bool use_ccfb = transport_desc_factory_->trials().IsEnabled( - "WebRTC-RFC8888CongestionControlFeedback"); - if (use_ccfb) { - answer_content->set_rtcp_fb_ack_ccfb(use_ccfb); + if (accept_offer_with_rfc_8888_) { + answer_content->set_rtcp_fb_ack_ccfb(true); for (auto& codec : codecs_to_include) { codec.feedback_params.Remove(FeedbackParam(kRtcpFbParamTransportCc)); } diff --git a/third_party/libwebrtc/pc/media_session.h b/third_party/libwebrtc/pc/media_session.h @@ -28,6 +28,7 @@ #include "pc/codec_vendor.h" #include "pc/media_options.h" #include "pc/session_description.h" +#include "rtc_base/experiments/field_trial_parser.h" #include "rtc_base/memory/always_valid_pointer.h" #include "rtc_base/unique_id_generator.h" @@ -173,6 +174,10 @@ class MediaSessionDescriptionFactory { return ssrc_generator_.get(); } + // Feedback format according to RFC-8888 will be offered if true. + const bool offer_rfc_8888_; + // Feedback format according to RFC-8888 will be accepted if offered. + const bool accept_offer_with_rfc_8888_; bool is_unified_plan_ = false; // This object may or may not be owned by this class. AlwaysValidPointer<UniqueRandomIdGenerator> const ssrc_generator_; diff --git a/third_party/libwebrtc/pc/rtc_stats_integrationtest.cc b/third_party/libwebrtc/pc/rtc_stats_integrationtest.cc @@ -1245,7 +1245,7 @@ TEST_F(RTCStatsIntegrationTest, ExperimentalPsnrStats) { } TEST_F(RTCStatsIntegrationTest, ExperimentalTransportCcfbStats) { - StartCall("WebRTC-RFC8888CongestionControlFeedback/Enabled/"); + StartCall("WebRTC-RFC8888CongestionControlFeedback/Enabled,offer:true/"); // This assumes all other stats are ok and tests the stats which should be // different under the field trial. diff --git a/third_party/libwebrtc/test/peer_scenario/tests/l4s_test.cc b/third_party/libwebrtc/test/peer_scenario/tests/l4s_test.cc @@ -168,7 +168,8 @@ TEST(L4STest, NegotiateAndUseCcfbIfEnabled) { PeerScenario s(*test_info_); PeerScenarioClient::Config config; - config.field_trials.Set("WebRTC-RFC8888CongestionControlFeedback", "Enabled"); + config.field_trials.Set("WebRTC-RFC8888CongestionControlFeedback", + "Enabled,offer:true"); config.disable_encryption = true; PeerScenarioClient* caller = s.CreateClient(config); PeerScenarioClient* callee = s.CreateClient(config); @@ -253,7 +254,7 @@ TEST_P(FeedbackFormatTest, AdaptToLinkCapacityWithoutEcn) { caller_config.disable_encryption = true; caller_config.field_trials.Set( "WebRTC-RFC8888CongestionControlFeedback", - params.caller_supports_rfc8888 ? "Enabled" : "Disabled"); + params.caller_supports_rfc8888 ? "Enabled,offer:true" : "Disabled"); PeerScenarioClient* caller = s.CreateClient(caller_config); PeerScenarioClient::Config callee_config; @@ -356,7 +357,7 @@ TEST(L4STest, NoCcfbSentAfterRenegotiationAndCallerCachLocalDescription) { PeerScenarioClient::Config caller_config; caller_config.disable_encryption = true; caller_config.field_trials.Set("WebRTC-RFC8888CongestionControlFeedback", - "Enabled"); + "Enabled,offer:true"); PeerScenarioClient* caller = s.CreateClient(caller_config); PeerScenarioClient::Config callee_config; @@ -463,7 +464,8 @@ TEST(L4STest, NoCcfbSentAfterRenegotiationAndCallerCachLocalDescription) { TEST(L4STest, CallerAdaptToLinkCapacityOnNetworkWithEcn) { PeerScenario s(*test_info_); PeerScenarioClient::Config config; - config.field_trials.Set("WebRTC-RFC8888CongestionControlFeedback", "Enabled"); + config.field_trials.Set("WebRTC-RFC8888CongestionControlFeedback", + "Enabled,offer:true"); PeerScenarioClient* caller = s.CreateClient(config); PeerScenarioClient* callee = s.CreateClient(config); @@ -506,7 +508,8 @@ TEST(L4STest, SendsEct1UntilFirstFeedback) { PeerScenario s(*test_info_); PeerScenarioClient::Config config; - config.field_trials.Set("WebRTC-RFC8888CongestionControlFeedback", "Enabled"); + config.field_trials.Set("WebRTC-RFC8888CongestionControlFeedback", + "Enabled,offer:true"); config.disable_encryption = true; PeerScenarioClient* caller = s.CreateClient(config); PeerScenarioClient* callee = s.CreateClient(config); @@ -563,7 +566,8 @@ TEST(L4STest, SendsEct1AfterRouteChange) { PeerScenario s(*test_info_); PeerScenarioClient::Config config; - config.field_trials.Set("WebRTC-RFC8888CongestionControlFeedback", "Enabled"); + config.field_trials.Set("WebRTC-RFC8888CongestionControlFeedback", + "Enabled,offer:true"); config.disable_encryption = true; config.endpoints = {{0, {.type = AdapterType::ADAPTER_TYPE_WIFI}}}; PeerScenarioClient* caller = s.CreateClient(config);