Internal change

PiperOrigin-RevId: 381082207
diff --git a/quic/core/quic_flags_list.h b/quic/core/quic_flags_list.h
index 40dd86b..135b0ab 100644
--- a/quic/core/quic_flags_list.h
+++ b/quic/core/quic_flags_list.h
@@ -33,6 +33,8 @@
 QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_can_send_ack_frequency, true)
 // If true, allow client to enable BBRv2 on server via connection option \'B2ON\'.
 QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_allow_client_enabled_bbr_v2, false)
+// If true, allow ticket open to be ignored in TlsServerHandshaker. Also fixes TlsServerHandshaker::ResumptionAttempted when handshake hints is used.
+QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_tls_allow_ignore_ticket_open, false)
 // If true, close read side but not write side in QuicSpdyStream::OnStreamReset().
 QUIC_FLAG(FLAGS_quic_reloadable_flag_quic_fix_on_stream_reset, true)
 // If true, default on PTO which unifies TLP + RTO loss recovery.
diff --git a/quic/core/tls_server_handshaker.cc b/quic/core/tls_server_handshaker.cc
index c129de3..3575fa0 100644
--- a/quic/core/tls_server_handshaker.cc
+++ b/quic/core/tls_server_handshaker.cc
@@ -679,8 +679,18 @@
     absl::string_view in) {
   QUICHE_DCHECK(proof_source_->GetTicketCrypter());
 
+  if (allow_ignore_ticket_open_ && ignore_ticket_open_) {
+    // SetIgnoreTicketOpen has been called. Typically this means the caller is
+    // using handshake hints and expect the hints to contain ticket decryption
+    // results.
+    QUIC_CODE_COUNT(quic_tls_server_handshaker_tickets_ignored_1);
+    return ssl_ticket_aead_ignore_ticket;
+  }
+
   if (!ticket_decryption_callback_) {
-    ticket_received_ = true;
+    if (!allow_ignore_ticket_open_) {
+      ticket_received_ = true;
+    }
     ticket_decryption_callback_ = new DecryptCallback(this);
     proof_source_->GetTicketCrypter()->Decrypt(
         in, std::unique_ptr<DecryptCallback>(ticket_decryption_callback_));
@@ -732,7 +742,7 @@
   if (decrypted_session_ticket_.empty()) {
     QUIC_DLOG(ERROR) << "Session ticket decryption failed; ignoring ticket";
     // Ticket decryption failed. Ignore the ticket.
-    QUIC_CODE_COUNT(quic_tls_server_handshaker_tickets_ignored);
+    QUIC_CODE_COUNT(quic_tls_server_handshaker_tickets_ignored_2);
     return ssl_ticket_aead_ignore_ticket;
   }
   if (max_out_len < decrypted_session_ticket_.size()) {
@@ -773,6 +783,14 @@
     return ssl_select_cert_error;
   }
 
+  if (allow_ignore_ticket_open_) {
+    const uint8_t* unused_extension_bytes;
+    size_t unused_extension_len;
+    ticket_received_ = SSL_early_callback_ctx_extension_get(
+        client_hello, TLSEXT_TYPE_pre_shared_key, &unused_extension_bytes,
+        &unused_extension_len);
+  }
+
   // This callback is called very early by Boring SSL, most of the SSL_get_foo
   // function do not work at this point, but SSL_get_servername does.
   const char* hostname = SSL_get_servername(ssl(), TLSEXT_NAMETYPE_host_name);
diff --git a/quic/core/tls_server_handshaker.h b/quic/core/tls_server_handshaker.h
index 6d216df..f1decb7 100644
--- a/quic/core/tls_server_handshaker.h
+++ b/quic/core/tls_server_handshaker.h
@@ -182,9 +182,14 @@
 
   bool WillNotCallComputeSignature() const override;
 
+  void SetIgnoreTicketOpen(bool value) { ignore_ticket_open_ = value; }
+
   const bool close_proof_source_handle_promptly_ =
       GetQuicReloadableFlag(quic_tls_close_proof_source_handle_promptly);
 
+  const bool allow_ignore_ticket_open_ =
+      GetQuicReloadableFlag(quic_tls_allow_ignore_ticket_open);
+
  private:
   class QUIC_EXPORT_PRIVATE DecryptCallback
       : public ProofSource::DecryptCallback {
@@ -318,6 +323,9 @@
   // indicates that the client attempted a resumption.
   bool ticket_received_ = false;
 
+  // Force SessionTicketOpen to return ssl_ticket_aead_ignore_ticket if called.
+  bool ignore_ticket_open_ = false;
+
   // nullopt means select cert hasn't started.
   absl::optional<QuicAsyncStatus> select_cert_status_;