Enable QUIC Path Degraded Experiment.

The experiment controls how many PTOs are allowed before a path becomes degraded.

Protected by QUIC connection options.

PiperOrigin-RevId: 766276642
diff --git a/quiche/quic/core/crypto/crypto_protocol.h b/quiche/quic/core/crypto/crypto_protocol.h
index c1bf0db..5435e4d 100644
--- a/quiche/quic/core/crypto/crypto_protocol.h
+++ b/quiche/quic/core/crypto/crypto_protocol.h
@@ -520,6 +520,11 @@
 // Fix timeouts experiment.
 DEFINE_STATIC_QUIC_TAG(FTOE);
 
+// Path degradation experiments.
+DEFINE_STATIC_QUIC_TAG(PDE2);  // 2 PTOs for path degradation.
+DEFINE_STATIC_QUIC_TAG(PDE3);  // 3 PTOs for path degradation.
+DEFINE_STATIC_QUIC_TAG(PDE5);  // 5 PTOs for path degradation.
+
 #undef DEFINE_STATIC_QUIC_TAG
 
 // These tags have a special form so that they appear either at the beginning
diff --git a/quiche/quic/core/quic_sent_packet_manager.cc b/quiche/quic/core/quic_sent_packet_manager.cc
index ac1cc36..cdb6dde 100644
--- a/quiche/quic/core/quic_sent_packet_manager.cc
+++ b/quiche/quic/core/quic_sent_packet_manager.cc
@@ -218,6 +218,17 @@
   if (config.HasClientSentConnectionOption(kRNIB, perspective)) {
     pacing_sender_.set_remove_non_initial_burst();
   }
+  // Path degradation experiments
+  if (config.HasClientRequestedIndependentOption(kPDE2, perspective)) {
+    num_ptos_for_path_degrading_ = 2;
+  }
+  if (config.HasClientRequestedIndependentOption(kPDE3, perspective)) {
+    num_ptos_for_path_degrading_ = 3;
+  }
+  // kPDE4 is the default. We have the experiments with kPDE4.
+  if (config.HasClientRequestedIndependentOption(kPDE5, perspective)) {
+    num_ptos_for_path_degrading_ = 5;
+  }
   send_algorithm_->SetFromConfig(config, perspective);
   loss_algorithm_->SetFromConfig(config, perspective);
 
diff --git a/quiche/quic/core/quic_sent_packet_manager_test.cc b/quiche/quic/core/quic_sent_packet_manager_test.cc
index f325d58..ca83497 100644
--- a/quiche/quic/core/quic_sent_packet_manager_test.cc
+++ b/quiche/quic/core/quic_sent_packet_manager_test.cc
@@ -3556,6 +3556,30 @@
                                    ENCRYPTION_FORWARD_SECURE, ecn_counts));
 }
 
+// Test that the path degrading delay is set correctly when the path degrading
+// connection option is set.
+TEST_F(QuicSentPacketManagerTest, GetPathDegradingDelayUsingPTO) {
+  QuicConfig client_config;
+  QuicTagVector all_path_dergradation_options = {kPDE2, kPDE3, kPDE5};
+  uint8_t pto_count = 2;
+  for (QuicTag current_dergradation_option : all_path_dergradation_options) {
+    QuicTagVector client_options;
+    client_options.push_back(current_dergradation_option);
+    QuicSentPacketManagerPeer::SetPerspective(&manager_,
+                                              Perspective::IS_CLIENT);
+    client_config.SetClientConnectionOptions(client_options);
+    EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+    EXPECT_CALL(*network_change_visitor_, OnCongestionChange());
+    manager_.SetFromConfig(client_config);
+    QuicTime::Delta expected_delay = pto_count * manager_.GetPtoDelay();
+    EXPECT_EQ(expected_delay, manager_.GetPathDegradingDelay());
+    pto_count++;
+    if (pto_count == 4) {
+      pto_count++;
+    }
+  }
+}
+
 }  // namespace
 }  // namespace test
 }  // namespace quic