Add a new QUIC Connection option to specify Cubic for the client side only.
Supports the experiment plan in go/prague-cubic.
PiperOrigin-RevId: 707928694
diff --git a/quiche/quic/core/crypto/crypto_protocol.h b/quiche/quic/core/crypto/crypto_protocol.h
index b5acba6..a925471 100644
--- a/quiche/quic/core/crypto/crypto_protocol.h
+++ b/quiche/quic/core/crypto/crypto_protocol.h
@@ -304,6 +304,8 @@
DEFINE_STATIC_QUIC_TAG(PRGC); // Prague Cubic congestion
// control (client-only)
+DEFINE_STATIC_QUIC_TAG(CQBC); // Client-only Cubic congestion control. Used
+ // for a control in the PRGC experiment.
// Optional support of truncated Connection IDs. If sent by a peer, the value
// is the minimum number of bytes allowed for the connection ID sent to the
diff --git a/quiche/quic/core/quic_sent_packet_manager.cc b/quiche/quic/core/quic_sent_packet_manager.cc
index 7b270f2..5917ac8 100644
--- a/quiche/quic/core/quic_sent_packet_manager.cc
+++ b/quiche/quic/core/quic_sent_packet_manager.cc
@@ -137,10 +137,6 @@
}
// Configure congestion control.
- if (perspective == Perspective::IS_CLIENT &&
- config.HasClientRequestedIndependentOption(kPRGC, perspective)) {
- SetSendAlgorithm(kPragueCubic);
- }
if (config.HasClientRequestedIndependentOption(kTBBR, perspective)) {
SetSendAlgorithm(kBBR);
}
@@ -157,6 +153,13 @@
config.HasClientRequestedIndependentOption(kQBIC, perspective))) {
SetSendAlgorithm(kCubicBytes);
}
+ if (perspective == Perspective::IS_CLIENT) {
+ if (config.HasClientRequestedIndependentOption(kPRGC, perspective)) {
+ SetSendAlgorithm(kPragueCubic);
+ } else if (config.HasClientRequestedIndependentOption(kCQBC, perspective)) {
+ SetSendAlgorithm(kCubicBytes);
+ }
+ }
// Initial window.
if (config.HasClientRequestedIndependentOption(kIW03, perspective)) {
diff --git a/quiche/quic/core/quic_sent_packet_manager_test.cc b/quiche/quic/core/quic_sent_packet_manager_test.cc
index cbe8861..4576014 100644
--- a/quiche/quic/core/quic_sent_packet_manager_test.cc
+++ b/quiche/quic/core/quic_sent_packet_manager_test.cc
@@ -1266,6 +1266,15 @@
// The server does nothing on kPRGC.
EXPECT_EQ(kRenoBytes, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_)
->GetCongestionControlType());
+
+ options.clear();
+ options.push_back(kCQBC);
+ QuicConfigPeer::SetReceivedConnectionOptions(&config, options);
+ EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+ manager_.SetFromConfig(config);
+ // The server does nothing on kCQBC.
+ EXPECT_EQ(kRenoBytes, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_)
+ ->GetCongestionControlType());
}
TEST_F(QuicSentPacketManagerTest, NegotiateClientCongestionControlFromOptions) {
@@ -1334,15 +1343,33 @@
EXPECT_EQ(kPragueCubic, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_)
->GetCongestionControlType());
- // Test that kPRGC is overriden by other options.
+ options.clear();
+ options.push_back(kCQBC);
+ config.SetClientConnectionOptions(options);
+ EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+ manager_.SetFromConfig(config);
+ EXPECT_EQ(kCubicBytes, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_)
+ ->GetCongestionControlType());
+
+ // Test that kPRGC is not overriden by other options.
options.clear();
options.push_back(kPRGC);
options.push_back(kTBBR);
config.SetClientConnectionOptions(options);
EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
manager_.SetFromConfig(config);
- EXPECT_EQ(kBBR, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_)
- ->GetCongestionControlType());
+ EXPECT_EQ(kPragueCubic, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_)
+ ->GetCongestionControlType());
+
+ // Test that kCQBC is not overriden by other options.
+ options.clear();
+ options.push_back(kCQBC);
+ options.push_back(kTBBR);
+ config.SetClientConnectionOptions(options);
+ EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+ manager_.SetFromConfig(config);
+ EXPECT_EQ(kCubicBytes, QuicSentPacketManagerPeer::GetSendAlgorithm(manager_)
+ ->GetCongestionControlType());
}
TEST_F(QuicSentPacketManagerTest, UseInitialRoundTripTimeToSend) {