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;