Delay setting stateless reset token in config until session initialization. This avoids virtual function GetStatelessResetToken be called in QuicSession constructor.

This change is an internal landing of https://github.com/google/quiche/pull/26 authored by slusnys.

Protected by FLAGS_quic_reloadable_flag_quic_delay_setting_stateless_reset_token.

PiperOrigin-RevId: 485586079
diff --git a/quiche/quic/core/quic_config.cc b/quiche/quic/core/quic_config.cc
index c059787..e60df28 100644
--- a/quiche/quic/core/quic_config.cc
+++ b/quiche/quic/core/quic_config.cc
@@ -987,6 +987,10 @@
   stateless_reset_token_.SetSendValue(stateless_reset_token);
 }
 
+bool QuicConfig::HasStatelessResetTokenToSend() const {
+  return stateless_reset_token_.HasSendValue();
+}
+
 bool QuicConfig::HasReceivedStatelessResetToken() const {
   return stateless_reset_token_.HasReceivedValue();
 }
diff --git a/quiche/quic/core/quic_config.h b/quiche/quic/core/quic_config.h
index 7abfb7d..61fa9eb 100644
--- a/quiche/quic/core/quic_config.h
+++ b/quiche/quic/core/quic_config.h
@@ -421,6 +421,7 @@
   // Stateless reset token.
   void SetStatelessResetTokenToSend(
       const StatelessResetToken& stateless_reset_token);
+  bool HasStatelessResetTokenToSend() const;
   bool HasReceivedStatelessResetToken() const;
   const StatelessResetToken& ReceivedStatelessResetToken() const;
 
diff --git a/quiche/quic/core/quic_flags_list.h b/quiche/quic/core/quic_flags_list.h
index 0f9f269..88cd4a0 100644
--- a/quiche/quic/core/quic_flags_list.h
+++ b/quiche/quic/core/quic_flags_list.h
@@ -35,6 +35,8 @@
 QUIC_FLAG(quic_reloadable_flag_quic_one_write_for_headers, true)
 // If true, default-enable 5RTO blachole detection.
 QUIC_FLAG(quic_reloadable_flag_quic_default_enable_5rto_blackhole_detection2, true)
+// If true, delay setting of stateless reset token until session initialization.
+QUIC_FLAG(quic_reloadable_flag_quic_delay_setting_stateless_reset_token, false)
 // If true, disable QUIC version Q043.
 QUIC_FLAG(quic_reloadable_flag_quic_disable_version_q043, false)
 // If true, disable QUIC version Q046.
diff --git a/quiche/quic/core/quic_session.cc b/quiche/quic/core/quic_session.cc
index b4abf52..6665e26 100644
--- a/quiche/quic/core/quic_session.cc
+++ b/quiche/quic/core/quic_session.cc
@@ -111,7 +111,8 @@
   closed_streams_clean_up_alarm_ =
       absl::WrapUnique<QuicAlarm>(connection_->alarm_factory()->CreateAlarm(
           new ClosedStreamsCleanUpDelegate(this)));
-  if (perspective() == Perspective::IS_SERVER &&
+  if (!delay_setting_stateless_reset_token_ &&
+      perspective() == Perspective::IS_SERVER &&
       connection_->version().handshake_protocol == PROTOCOL_TLS1_3) {
     config_.SetStatelessResetTokenToSend(GetStatelessResetToken());
   }
@@ -135,6 +136,12 @@
       config_.SetMinAckDelayMs(kDefaultMinAckDelayTimeMs);
     }
   }
+  if (delay_setting_stateless_reset_token_ &&
+      perspective() == Perspective::IS_SERVER &&
+      connection_->version().handshake_protocol == PROTOCOL_TLS1_3) {
+    QUIC_RELOADABLE_FLAG_COUNT(quic_delay_setting_stateless_reset_token);
+    config_.SetStatelessResetTokenToSend(GetStatelessResetToken());
+  }
 
   connection_->CreateConnectionIdManager();
 
diff --git a/quiche/quic/core/quic_session.h b/quiche/quic/core/quic_session.h
index e51d77a..85d49e8 100644
--- a/quiche/quic/core/quic_session.h
+++ b/quiche/quic/core/quic_session.h
@@ -1006,6 +1006,9 @@
   // This indicates a liveness testing is in progress, and push back the
   // creation of new outgoing bidirectional streams.
   bool liveness_testing_in_progress_;
+
+  const bool delay_setting_stateless_reset_token_ =
+      GetQuicReloadableFlag(quic_delay_setting_stateless_reset_token);
 };
 
 }  // namespace quic
diff --git a/quiche/quic/core/quic_session_test.cc b/quiche/quic/core/quic_session_test.cc
index 3e66183..041d5c8 100644
--- a/quiche/quic/core/quic_session_test.cc
+++ b/quiche/quic/core/quic_session_test.cc
@@ -3162,6 +3162,13 @@
   EXPECT_FALSE(crypto_stream->HasBufferedCryptoFrames());
 }
 
+TEST_P(QuicSessionTestServer, SetStatelessResetTokenToSend) {
+  if (!session_.version().HasIetfQuicFrames()) {
+    return;
+  }
+  EXPECT_TRUE(session_.config()->HasStatelessResetTokenToSend());
+}
+
 // A client test class that can be used when the automatic configuration is not
 // desired.
 class QuicSessionTestClientUnconfigured : public QuicSessionTestBase {