| Index: net/quic/core/quic_crypto_server_stream.cc
 | 
| diff --git a/net/quic/core/quic_crypto_server_stream.cc b/net/quic/core/quic_crypto_server_stream.cc
 | 
| index 900bd683e510a36bcb04fff4e2963c3b1e38ee57..eccb67e2105592f3f5fe9f3a725e71ea22d34eb1 100644
 | 
| --- a/net/quic/core/quic_crypto_server_stream.cc
 | 
| +++ b/net/quic/core/quic_crypto_server_stream.cc
 | 
| @@ -43,13 +43,6 @@ class QuicCryptoServerStream::ProcessClientHelloCallback
 | 
|        return;
 | 
|      }
 | 
|  
 | 
| -    // Note: set the parent's callback to nullptr here because
 | 
| -    // FinishProcessingHandshakeMessageAfterProcessClientHello can be invoked
 | 
| -    // from either synchronous or asynchronous codepaths.  When the synchronous
 | 
| -    // codepaths are removed, this assignment should move to
 | 
| -    // FinishProcessingHandshakeMessageAfterProcessClientHello.
 | 
| -    stream_->process_client_hello_cb_ = nullptr;
 | 
| -
 | 
|      stream_->FinishProcessingHandshakeMessageAfterProcessClientHello(
 | 
|          *result_, error, error_details, std::move(message),
 | 
|          std::move(diversification_nonce), std::move(proof_source_details));
 | 
| @@ -96,7 +89,6 @@ QuicCryptoServerStream::QuicCryptoServerStream(
 | 
|        crypto_config_(crypto_config),
 | 
|        compressed_certs_cache_(compressed_certs_cache),
 | 
|        signed_config_(new QuicSignedServerConfig),
 | 
| -      validate_client_hello_cb_(nullptr),
 | 
|        helper_(helper),
 | 
|        num_handshake_messages_(0),
 | 
|        num_handshake_messages_with_server_nonces_(0),
 | 
| @@ -106,6 +98,7 @@ QuicCryptoServerStream::QuicCryptoServerStream(
 | 
|            use_stateless_rejects_if_peer_supported),
 | 
|        peer_supports_stateless_rejects_(false),
 | 
|        chlo_packet_size_(0),
 | 
| +      validate_client_hello_cb_(nullptr),
 | 
|        process_client_hello_cb_(nullptr) {
 | 
|    DCHECK_EQ(Perspective::IS_SERVER, session->connection()->perspective());
 | 
|  }
 | 
| @@ -149,7 +142,9 @@ void QuicCryptoServerStream::OnHandshakeMessage(
 | 
|      return;
 | 
|    }
 | 
|  
 | 
| -  if (validate_client_hello_cb_ != nullptr) {
 | 
| +  if (validate_client_hello_cb_ != nullptr ||
 | 
| +      (base::GetFlag(FLAGS_quic_reloadable_flag_fix_quic_callback_crash) &&
 | 
| +       process_client_hello_cb_ != nullptr)) {
 | 
|      // Already processing some other handshake message.  The protocol
 | 
|      // does not allow for clients to send multiple handshake messages
 | 
|      // before the server has a chance to respond.
 | 
| @@ -162,6 +157,8 @@ void QuicCryptoServerStream::OnHandshakeMessage(
 | 
|    CryptoUtils::HashHandshakeMessage(message, &chlo_hash_);
 | 
|  
 | 
|    std::unique_ptr<ValidateCallback> cb(new ValidateCallback(this));
 | 
| +  DCHECK(validate_client_hello_cb_ == nullptr);
 | 
| +  DCHECK(process_client_hello_cb_ == nullptr);
 | 
|    validate_client_hello_cb_ = cb.get();
 | 
|    crypto_config_->ValidateClientHello(
 | 
|        message, session()->connection()->peer_address().host(),
 | 
| @@ -177,6 +174,7 @@ void QuicCryptoServerStream::FinishProcessingHandshakeMessage(
 | 
|  
 | 
|    // Clear the callback that got us here.
 | 
|    DCHECK(validate_client_hello_cb_ != nullptr);
 | 
| +  DCHECK(process_client_hello_cb_ == nullptr);
 | 
|    validate_client_hello_cb_ = nullptr;
 | 
|  
 | 
|    if (use_stateless_rejects_if_peer_supported_) {
 | 
| @@ -197,6 +195,11 @@ void QuicCryptoServerStream::
 | 
|          std::unique_ptr<CryptoHandshakeMessage> reply,
 | 
|          std::unique_ptr<DiversificationNonce> diversification_nonce,
 | 
|          std::unique_ptr<ProofSource::Details> proof_source_details) {
 | 
| +  // Clear the callback that got us here.
 | 
| +  DCHECK(process_client_hello_cb_ != nullptr);
 | 
| +  DCHECK(validate_client_hello_cb_ == nullptr);
 | 
| +  process_client_hello_cb_ = nullptr;
 | 
| +
 | 
|    const CryptoHandshakeMessage& message = result.client_hello;
 | 
|    if (error != QUIC_NO_ERROR) {
 | 
|      CloseConnectionWithDetails(error, error_details);
 | 
| 
 |