Deflake FrontlineInfoRtt in gfe/gfe2/quic:end_to_end_test for IETF QUIC.

See http://b/170083879#comment9 for contexts.

Protected by FLAGS_quic_reloadable_flag_quic_process_undecryptable_packets_after_async_decrypt_callback.

PiperOrigin-RevId: 337596125
Change-Id: Ia3478770125b5046ebc63674f0e0eb663ba9fb74
diff --git a/quic/core/handshaker_delegate_interface.h b/quic/core/handshaker_delegate_interface.h
index 5103509..a8e5e96 100644
--- a/quic/core/handshaker_delegate_interface.h
+++ b/quic/core/handshaker_delegate_interface.h
@@ -71,6 +71,9 @@
       const TransportParameters& params,
       bool is_resumption,
       std::string* error_details) = 0;
+
+  // Called at the end of an handshake operation callback.
+  virtual void OnHandshakeCallbackDone() = 0;
 };
 
 }  // namespace quic
diff --git a/quic/core/quic_connection.h b/quic/core/quic_connection.h
index 26629ba..a009954 100644
--- a/quic/core/quic_connection.h
+++ b/quic/core/quic_connection.h
@@ -1109,6 +1109,8 @@
 
   bool check_keys_before_writing() const { return check_keys_before_writing_; }
 
+  bool is_processing_packet() const { return framer_.is_processing_packet(); }
+
  protected:
   // Calls cancel() on all the alarms owned by this connection.
   void CancelAllAlarms();
diff --git a/quic/core/quic_framer.cc b/quic/core/quic_framer.cc
index ede689c..f775afb 100644
--- a/quic/core/quic_framer.cc
+++ b/quic/core/quic_framer.cc
@@ -1415,6 +1415,13 @@
 }
 
 bool QuicFramer::ProcessPacket(const QuicEncryptedPacket& packet) {
+  is_processing_packet_ = true;
+  bool result = ProcessPacketInternal(packet);
+  is_processing_packet_ = false;
+  return result;
+}
+
+bool QuicFramer::ProcessPacketInternal(const QuicEncryptedPacket& packet) {
   QuicDataReader reader(packet.data(), packet.length());
 
   bool packet_has_ietf_packet_header = false;
diff --git a/quic/core/quic_framer.h b/quic/core/quic_framer.h
index 763d0b8..f029dd1 100644
--- a/quic/core/quic_framer.h
+++ b/quic/core/quic_framer.h
@@ -319,6 +319,9 @@
   // ignored.
   bool ProcessPacket(const QuicEncryptedPacket& packet);
 
+  // Whether we are in the middle of a call to this->ProcessPacket.
+  bool is_processing_packet() const { return is_processing_packet_; }
+
   // Largest size in bytes of all stream frame fields without the payload.
   static size_t GetMinStreamFrameSize(QuicTransportVersion version,
                                       QuicStreamId stream_id,
@@ -1042,6 +1045,8 @@
                               QuicIetfFrameType type,
                               QuicStreamId* id);
 
+  bool ProcessPacketInternal(const QuicEncryptedPacket& packet);
+
   std::string detailed_error_;
   QuicFramerVisitorInterface* visitor_;
   QuicErrorCode error_;
@@ -1115,6 +1120,9 @@
   // owned. TODO(fayang): Consider add data producer to framer's constructor.
   QuicStreamFrameDataProducer* data_producer_;
 
+  // Whether we are in the middle of a call to this->ProcessPacket.
+  bool is_processing_packet_ = false;
+
   // If true, framer infers packet header type (IETF/GQUIC) from version_.
   // Otherwise, framer infers packet header type from first byte of a received
   // packet.
diff --git a/quic/core/quic_session.cc b/quic/core/quic_session.cc
index 9705710..a8d9e6f 100644
--- a/quic/core/quic_session.cc
+++ b/quic/core/quic_session.cc
@@ -1675,6 +1675,16 @@
                                             error_details);
 }
 
+void QuicSession::OnHandshakeCallbackDone() {
+  if (!connection_->connected()) {
+    return;
+  }
+
+  if (!connection()->is_processing_packet()) {
+    connection()->MaybeProcessUndecryptablePackets();
+  }
+}
+
 void QuicSession::OnCryptoHandshakeMessageSent(
     const CryptoHandshakeMessage& /*message*/) {}
 
diff --git a/quic/core/quic_session.h b/quic/core/quic_session.h
index e22bd23..8fca9bd 100644
--- a/quic/core/quic_session.h
+++ b/quic/core/quic_session.h
@@ -276,6 +276,7 @@
   QuicErrorCode ProcessTransportParameters(const TransportParameters& params,
                                            bool is_resumption,
                                            std::string* error_details) override;
+  void OnHandshakeCallbackDone() override;
 
   // Implement StreamDelegateInterface.
   void OnStreamError(QuicErrorCode error_code,
diff --git a/quic/core/tls_server_handshaker.cc b/quic/core/tls_server_handshaker.cc
index 405e109..7b5ec3b 100644
--- a/quic/core/tls_server_handshaker.cc
+++ b/quic/core/tls_server_handshaker.cc
@@ -12,6 +12,8 @@
 #include "third_party/boringssl/src/include/openssl/ssl.h"
 #include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_server_config.h"
 #include "net/third_party/quiche/src/quic/core/crypto/transport_parameters.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_flag_utils.h"
+#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_hostname_utils.h"
 #include "net/third_party/quiche/src/quic/platform/api/quic_logging.h"
 #include "net/third_party/quiche/src/common/platform/api/quiche_arraysize.h"
@@ -38,7 +40,7 @@
   handshaker_->state_ = STATE_SIGNATURE_COMPLETE;
   handshaker_->signature_callback_ = nullptr;
   if (last_state == STATE_SIGNATURE_PENDING) {
-    handshaker_->AdvanceHandshake();
+    handshaker_->AdvanceHandshakeFromCallback();
   }
 }
 
@@ -68,7 +70,7 @@
   // messages. We need to have it resume processing handshake messages by
   // calling AdvanceHandshake.
   if (handshaker_->state_ == STATE_TICKET_DECRYPTION_PENDING) {
-    handshaker_->AdvanceHandshake();
+    handshaker_->AdvanceHandshakeFromCallback();
   }
   // The TicketDecrypter took ownership of this callback when Decrypt was
   // called. Once the callback returns, it will be deleted. Remove the
@@ -274,6 +276,17 @@
   }
 }
 
+void TlsServerHandshaker::AdvanceHandshakeFromCallback() {
+  AdvanceHandshake();
+  if (GetQuicReloadableFlag(
+          quic_process_undecryptable_packets_after_async_decrypt_callback) &&
+      state_ != STATE_CONNECTION_CLOSED) {
+    QUIC_RELOADABLE_FLAG_COUNT(
+        quic_process_undecryptable_packets_after_async_decrypt_callback);
+    handshaker_delegate()->OnHandshakeCallbackDone();
+  }
+}
+
 void TlsServerHandshaker::CloseConnection(QuicErrorCode error,
                                           const std::string& reason_phrase) {
   state_ = STATE_CONNECTION_CLOSED;
diff --git a/quic/core/tls_server_handshaker.h b/quic/core/tls_server_handshaker.h
index 7b28825..b6ea353 100644
--- a/quic/core/tls_server_handshaker.h
+++ b/quic/core/tls_server_handshaker.h
@@ -89,6 +89,10 @@
   // Called when a new message is received on the crypto stream and is available
   // for the TLS stack to read.
   void AdvanceHandshake() override;
+
+  // Called when a potentially async operation is done and the done callback
+  // needs to advance the handshake.
+  void AdvanceHandshakeFromCallback();
   void CloseConnection(QuicErrorCode error,
                        const std::string& reason_phrase) override;