Wire in the ack exponent trransport config for IETF QUIC

gfe-relnote: N/A, for IETF QUIC Only, protected by V99 flag.
PiperOrigin-RevId: 260736433
Change-Id: I5468bc4f052d78d2bf6890cdf0734cece5b107c0
diff --git a/quic/core/quic_config.cc b/quic/core/quic_config.cc
index 661b5f3..22aef80 100644
--- a/quic/core/quic_config.cc
+++ b/quic/core/quic_config.cc
@@ -414,7 +414,8 @@
       support_max_header_list_size_(kSMHL, PRESENCE_OPTIONAL),
       stateless_reset_token_(kSRST, PRESENCE_OPTIONAL),
       max_incoming_unidirectional_streams_(kMIUS, PRESENCE_OPTIONAL),
-      max_ack_delay_ms_(kMAD, PRESENCE_OPTIONAL) {
+      max_ack_delay_ms_(kMAD, PRESENCE_OPTIONAL),
+      ack_delay_exponent_(kADE, PRESENCE_OPTIONAL) {
   SetDefaults();
 }
 
@@ -557,6 +558,22 @@
   return max_ack_delay_ms_.GetReceivedValue();
 }
 
+void QuicConfig::SetAckDelayExponentToSend(uint32_t exponent) {
+  ack_delay_exponent_.SetSendValue(exponent);
+}
+
+uint32_t QuicConfig::GetAckDelayExponentToSend() {
+  return ack_delay_exponent_.GetSendValue();
+}
+
+bool QuicConfig::HasReceivedAckDelayExponent() const {
+  return ack_delay_exponent_.HasReceivedValue();
+}
+
+uint32_t QuicConfig::ReceivedAckDelayExponent() const {
+  return ack_delay_exponent_.GetReceivedValue();
+}
+
 bool QuicConfig::HasSetBytesForConnectionIdToSend() const {
   return bytes_for_connection_id_.HasSendValue();
 }
@@ -711,6 +728,7 @@
   SetInitialSessionFlowControlWindowToSend(kMinimumFlowControlSendWindow);
   SetMaxAckDelayToSendMs(kDefaultDelayedAckTimeMs);
   SetSupportMaxHeaderListSize();
+  SetAckDelayExponentToSend(kDefaultAckDelayExponent);
 }
 
 void QuicConfig::ToHandshakeMessage(
@@ -724,6 +742,7 @@
   max_incoming_bidirectional_streams_.ToHandshakeMessage(out);
   if (VersionHasIetfQuicFrames(transport_version)) {
     max_incoming_unidirectional_streams_.ToHandshakeMessage(out);
+    ack_delay_exponent_.ToHandshakeMessage(out);
   }
   if (GetQuicReloadableFlag(quic_negotiate_ack_delay_time)) {
     QUIC_RELOADABLE_FLAG_COUNT_N(quic_negotiate_ack_delay_time, 1, 4);
@@ -806,6 +825,10 @@
     error = max_ack_delay_ms_.ProcessPeerHello(peer_hello, hello_type,
                                                error_details);
   }
+  if (error == QUIC_NO_ERROR) {
+    error = ack_delay_exponent_.ProcessPeerHello(peer_hello, hello_type,
+                                                 error_details);
+  }
   return error;
 }
 
@@ -838,6 +861,7 @@
     QUIC_RELOADABLE_FLAG_COUNT_N(quic_negotiate_ack_delay_time, 3, 4);
     params->max_ack_delay.set_value(kDefaultDelayedAckTimeMs);
   }
+  params->ack_delay_exponent.set_value(ack_delay_exponent_.GetSendValue());
   params->disable_migration =
       connection_migration_disabled_.HasSendValue() &&
       connection_migration_disabled_.GetSendValue() != 0;
@@ -924,6 +948,9 @@
     max_ack_delay_ms_.SetReceivedValue(std::min<uint32_t>(
         params.max_ack_delay.value(), std::numeric_limits<uint32_t>::max()));
   }
+  if (params.ack_delay_exponent.IsValid()) {
+    ack_delay_exponent_.SetReceivedValue(params.ack_delay_exponent.value());
+  }
   connection_migration_disabled_.SetReceivedValue(
       params.disable_migration ? 1u : 0u);