Add 8AFF QUIC connection option to support 8 anti-amplification factor.

This adds the 8AFF QuicTag and handles setting anti_amplification_factor_ to 8
when requested by the client in SetFromConfig.

PiperOrigin-RevId: 979845844
diff --git a/quiche/quic/core/crypto/crypto_protocol.h b/quiche/quic/core/crypto/crypto_protocol.h
index d80cc8a..5e07736 100644
--- a/quiche/quic/core/crypto/crypto_protocol.h
+++ b/quiche/quic/core/crypto/crypto_protocol.h
@@ -381,6 +381,7 @@
 
 DEFINE_STATIC_QUIC_TAG(3AFF);  // 3 anti amplification factor.
 DEFINE_STATIC_QUIC_TAG(5AFF);  // 5 anti amplification factor.
+DEFINE_STATIC_QUIC_TAG(8AFF);  // 8 anti amplification factor.
 DEFINE_STATIC_QUIC_TAG(10AF);  // 10 anti amplification factor.
 
 // Enable path MTU discovery experiment.
diff --git a/quiche/quic/core/quic_connection.cc b/quiche/quic/core/quic_connection.cc
index 0ee35f4..1a2de23 100644
--- a/quiche/quic/core/quic_connection.cc
+++ b/quiche/quic/core/quic_connection.cc
@@ -541,6 +541,9 @@
   if (config.HasClientRequestedIndependentOption(k5AFF, perspective_)) {
     anti_amplification_factor_ = 5;
   }
+  if (config.HasClientRequestedIndependentOption(k8AFF, perspective_)) {
+    anti_amplification_factor_ = 8;
+  }
   if (config.HasClientRequestedIndependentOption(k10AF, perspective_)) {
     anti_amplification_factor_ = 10;
   }
diff --git a/quiche/quic/core/quic_connection_test.cc b/quiche/quic/core/quic_connection_test.cc
index 9afc888..d37545c 100644
--- a/quiche/quic/core/quic_connection_test.cc
+++ b/quiche/quic/core/quic_connection_test.cc
@@ -9956,6 +9956,80 @@
   }
 }
 
+TEST_P(QuicConnectionTest, 8AntiAmplificationLimit) {
+  if (!connection_.version().IsIetfQuic() ||
+      GetQuicFlag(quic_enforce_strict_amplification_factor)) {
+    return;
+  }
+  EXPECT_CALL(visitor_, OnCryptoFrame(_)).Times(AnyNumber());
+
+  set_perspective(Perspective::IS_SERVER);
+  QuicConfig config;
+  QuicTagVector connection_options;
+  connection_options.push_back(k8AFF);
+  config.SetInitialReceivedConnectionOptions(connection_options);
+  if (connection_.version().IsIetfQuic()) {
+    QuicConfigPeer::SetReceivedOriginalConnectionId(
+        &config, connection_.connection_id());
+    QuicConfigPeer::SetReceivedInitialSourceConnectionId(&config,
+                                                         QuicConnectionId());
+  }
+  EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _));
+  EXPECT_CALL(*send_algorithm_, EnableECT1()).WillOnce(Return(false));
+  EXPECT_CALL(*send_algorithm_, EnableECT0()).WillOnce(Return(false));
+  connection_.SetFromConfig(config);
+
+  // Verify no data can be sent at the beginning because bytes received is 0.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  connection_.SendCryptoDataWithString("foo", 0);
+  EXPECT_FALSE(connection_.CanWrite(HAS_RETRANSMITTABLE_DATA));
+  EXPECT_FALSE(connection_.CanWrite(NO_RETRANSMITTABLE_DATA));
+  EXPECT_FALSE(connection_.GetRetransmissionAlarm()->IsSet());
+
+  // Receives packet 1.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  ForceWillingAndAbleToWriteOnceForDeferSending();
+  ProcessCryptoPacketAtLevel(1, ENCRYPTION_INITIAL);
+
+  const size_t anti_amplification_factor = 8;
+  // Verify now packets can be sent.
+  for (size_t i = 1; i < anti_amplification_factor; ++i) {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+    connection_.SendCryptoDataWithString("foo", i * 3);
+    // Verify retransmission alarm is not set if throttled by anti-amplification
+    // limit.
+    EXPECT_EQ(i != anti_amplification_factor - 1,
+              connection_.GetRetransmissionAlarm()->IsSet());
+  }
+  // Verify server is throttled by anti-amplification limit.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  connection_.SendCryptoDataWithString("foo", anti_amplification_factor * 3);
+
+  // Receives packet 2.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  ForceWillingAndAbleToWriteOnceForDeferSending();
+  ProcessCryptoPacketAtLevel(2, ENCRYPTION_INITIAL);
+  // Verify more packets can be sent.
+  for (size_t i = anti_amplification_factor + 1;
+       i < anti_amplification_factor * 2; ++i) {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+    connection_.SendCryptoDataWithString("foo", i * 3);
+  }
+  // Verify server is throttled by anti-amplification limit.
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  connection_.SendCryptoDataWithString("foo",
+                                       2 * anti_amplification_factor * 3);
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+  ForceWillingAndAbleToWriteOnceForDeferSending();
+  ProcessPacket(3);
+  // Verify anti-amplification limit is gone after address validation.
+  for (size_t i = 0; i < 100; ++i) {
+    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
+    connection_.SendStreamDataWithString(3, "first", i * 0, NO_FIN);
+  }
+}
+
 TEST_P(QuicConnectionTest, 10AntiAmplificationLimit) {
   if (!connection_.version().IsIetfQuic() ||
       GetQuicFlag(quic_enforce_strict_amplification_factor)) {