gfe-relnote: Create handshaker for QuicCryptoServerStream in constructor instead of later. Protected by reloadable flag quic_set_server_handshaker_in_constructor.

PiperOrigin-RevId: 286659143
Change-Id: I2b95c42420ebb27bfc14fe003b69dad423a60451
diff --git a/quic/core/quic_crypto_server_stream.cc b/quic/core/quic_crypto_server_stream.cc
index f0f0f64..784b20a 100644
--- a/quic/core/quic_crypto_server_stream.cc
+++ b/quic/core/quic_crypto_server_stream.cc
@@ -32,11 +32,42 @@
     QuicCompressedCertsCache* compressed_certs_cache,
     QuicSession* session,
     Helper* helper)
+    : QuicCryptoServerStream(crypto_config,
+                             compressed_certs_cache,
+                             session,
+                             helper,
+                             /*handshaker*/ nullptr) {}
+
+QuicCryptoServerStream::QuicCryptoServerStream(
+    const QuicCryptoServerConfig* crypto_config,
+    QuicCompressedCertsCache* compressed_certs_cache,
+    QuicSession* session,
+    Helper* helper,
+    std::unique_ptr<HandshakerDelegate> handshaker)
     : QuicCryptoServerStreamBase(session),
+      handshaker_(std::move(handshaker)),
+      create_handshaker_in_constructor_(
+          GetQuicReloadableFlag(quic_create_server_handshaker_in_constructor)),
       crypto_config_(crypto_config),
       compressed_certs_cache_(compressed_certs_cache),
       helper_(helper) {
   DCHECK_EQ(Perspective::IS_SERVER, session->connection()->perspective());
+  if (create_handshaker_in_constructor_ && !handshaker_) {
+    switch (session->connection()->version().handshake_protocol) {
+      case PROTOCOL_QUIC_CRYPTO:
+        handshaker_ = std::make_unique<QuicCryptoServerHandshaker>(
+            crypto_config_, this, compressed_certs_cache_, session, helper_);
+        break;
+      case PROTOCOL_TLS1_3:
+        handshaker_ = std::make_unique<TlsServerHandshaker>(
+            this, session, crypto_config_->ssl_ctx(),
+            crypto_config_->proof_source());
+        break;
+      case PROTOCOL_UNSUPPORTED:
+        QUIC_BUG << "Attempting to create QuicCryptoServerStream for unknown "
+                    "handshake protocol";
+    }
+  }
 }
 
 QuicCryptoServerStream::~QuicCryptoServerStream() {}
@@ -122,6 +153,9 @@
 void QuicCryptoServerStream::OnSuccessfulVersionNegotiation(
     const ParsedQuicVersion& version) {
   DCHECK_EQ(version, session()->connection()->version());
+  if (create_handshaker_in_constructor_) {
+    return;
+  }
   CHECK(!handshaker_);
   switch (session()->connection()->version().handshake_protocol) {
     case PROTOCOL_QUIC_CRYPTO:
diff --git a/quic/core/quic_crypto_server_stream.h b/quic/core/quic_crypto_server_stream.h
index 2e0e723..427cced 100644
--- a/quic/core/quic_crypto_server_stream.h
+++ b/quic/core/quic_crypto_server_stream.h
@@ -188,6 +188,11 @@
   // handshaker hasn't been set yet. If set_handshaker is called outside of
   // OnSuccessfulVersionNegotiation, then that method must be overridden to not
   // set a handshaker.
+  QuicCryptoServerStream(const QuicCryptoServerConfig* crypto_config,
+                         QuicCompressedCertsCache* compressed_certs_cache,
+                         QuicSession* session,
+                         Helper* helper,
+                         std::unique_ptr<HandshakerDelegate> handshaker);
   void set_handshaker(std::unique_ptr<HandshakerDelegate> handshaker);
   HandshakerDelegate* handshaker() const;
 
@@ -197,6 +202,8 @@
 
  private:
   std::unique_ptr<HandshakerDelegate> handshaker_;
+  // Latched value of quic_create_server_handshaker_in_constructor flag.
+  bool create_handshaker_in_constructor_;
 
   // Arguments from QuicCryptoServerStream constructor that might need to be
   // passed to the HandshakerDelegate constructor in its late construction.