gfe-relnote: Let QUIC client drops initial key when a handshake packet has been sent. protected by existing gfe2_reloadable_flag_quic_enable_version_draft_25_v3 and gfe2_reloadable_flag_quic_enable_version_draft_27.
PiperOrigin-RevId: 308882771
Change-Id: Icbae03467ebc7845dacb8d6398cd2657dcf11632
diff --git a/quic/core/http/quic_spdy_session_test.cc b/quic/core/http/quic_spdy_session_test.cc
index 4049caf..7bc452f 100644
--- a/quic/core/http/quic_spdy_session_test.cc
+++ b/quic/core/http/quic_spdy_session_test.cc
@@ -137,6 +137,7 @@
}
void OnPacketDecrypted(EncryptionLevel /*level*/) override {}
void OnOneRttPacketAcknowledged() override {}
+ void OnHandshakePacketSent() override {}
void OnHandshakeDoneReceived() override {}
MOCK_METHOD(void, OnCanWrite, (), (override));
diff --git a/quic/core/http/quic_spdy_stream_test.cc b/quic/core/http/quic_spdy_stream_test.cc
index cdee5ef..6535328 100644
--- a/quic/core/http/quic_spdy_stream_test.cc
+++ b/quic/core/http/quic_spdy_stream_test.cc
@@ -124,6 +124,7 @@
}
void OnPacketDecrypted(EncryptionLevel /*level*/) override {}
void OnOneRttPacketAcknowledged() override {}
+ void OnHandshakePacketSent() override {}
void OnHandshakeDoneReceived() override {}
MOCK_METHOD(void, OnCanWrite, (), (override));
diff --git a/quic/core/quic_coalesced_packet.h b/quic/core/quic_coalesced_packet.h
index 1974f77..447ab95 100644
--- a/quic/core/quic_coalesced_packet.h
+++ b/quic/core/quic_coalesced_packet.h
@@ -36,6 +36,9 @@
std::string ToString(size_t serialized_length) const;
+ // Returns true if this coalesced packet contains packet of |level|.
+ bool ContainsPacketOfEncryptionLevel(EncryptionLevel level) const;
+
const SerializedPacket* initial_packet() const {
return initial_packet_.get();
}
@@ -49,9 +52,6 @@
QuicPacketLength max_packet_length() const { return max_packet_length_; }
private:
- // Returns true if this coalesced packet contains packet of |level|.
- bool ContainsPacketOfEncryptionLevel(EncryptionLevel level) const;
-
// self/peer addresses are set when trying to coalesce the first packet.
// Packets with different self/peer addresses cannot be coalesced.
QuicSocketAddress self_address_;
diff --git a/quic/core/quic_connection.cc b/quic/core/quic_connection.cc
index 7a23582..e8dd94b 100644
--- a/quic/core/quic_connection.cc
+++ b/quic/core/quic_connection.cc
@@ -4032,6 +4032,12 @@
if (debug_visitor_ != nullptr) {
debug_visitor_->OnCoalescedPacketSent(coalesced_packet_, length);
}
+ if (coalesced_packet_.ContainsPacketOfEncryptionLevel(
+ ENCRYPTION_HANDSHAKE)) {
+ // This is only called in coalescer because all ENCRYPTION_HANDSHAKE
+ // packets go through the coalescer.
+ visitor_->OnHandshakePacketSent();
+ }
return true;
}
@@ -4055,6 +4061,11 @@
if (debug_visitor_ != nullptr) {
debug_visitor_->OnCoalescedPacketSent(coalesced_packet_, length);
}
+ if (coalesced_packet_.ContainsPacketOfEncryptionLevel(ENCRYPTION_HANDSHAKE)) {
+ // This is only called in coalescer because all ENCRYPTION_HANDSHAKE
+ // packets go through the coalescer.
+ visitor_->OnHandshakePacketSent();
+ }
// Account for added padding.
if (length > coalesced_packet_.length()) {
size_t padding_size = length - coalesced_packet_.length();
diff --git a/quic/core/quic_connection.h b/quic/core/quic_connection.h
index e653352..aa68288 100644
--- a/quic/core/quic_connection.h
+++ b/quic/core/quic_connection.h
@@ -181,6 +181,9 @@
// Called when a 1RTT packet has been acknowledged.
virtual void OnOneRttPacketAcknowledged() = 0;
+
+ // Called when a packet of ENCRYPTION_HANDSHAKE gets sent.
+ virtual void OnHandshakePacketSent() = 0;
};
// Interface which gets callbacks from the QuicConnection at interesting
diff --git a/quic/core/quic_connection_test.cc b/quic/core/quic_connection_test.cc
index 4ad005d..11977e6 100644
--- a/quic/core/quic_connection_test.cc
+++ b/quic/core/quic_connection_test.cc
@@ -10209,6 +10209,7 @@
connection_.set_debug_visitor(&debug_visitor);
EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _)).Times(3);
EXPECT_CALL(debug_visitor, OnCoalescedPacketSent(_, _)).Times(1);
+ EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
{
QuicConnection::ScopedPacketFlusher flusher(&connection_);
use_tagging_decrypter();
@@ -10280,6 +10281,7 @@
connection_.SetEncrypter(ENCRYPTION_HANDSHAKE,
std::make_unique<TaggingEncrypter>(0x02));
connection_.SetDefaultEncryptionLevel(ENCRYPTION_HANDSHAKE);
+ EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
connection_.SendCryptoDataWithString("foo", 0, ENCRYPTION_HANDSHAKE);
EXPECT_EQ(0x02020202u, writer_->final_bytes_of_last_packet());
@@ -10294,6 +10296,7 @@
// Retransmit handshake data.
clock_.AdvanceTime(retransmission_time - clock_.Now());
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(4), _, _));
+ EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
connection_.GetRetransmissionAlarm()->Fire();
EXPECT_EQ(0x02020202u, writer_->final_bytes_of_last_packet());
@@ -10307,6 +10310,7 @@
// Retransmit handshake data again.
clock_.AdvanceTime(retransmission_time - clock_.Now());
EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(7), _, _));
+ EXPECT_CALL(visitor_, OnHandshakePacketSent()).Times(1);
connection_.GetRetransmissionAlarm()->Fire();
EXPECT_EQ(0x02020202u, writer_->final_bytes_of_last_packet());
diff --git a/quic/core/quic_crypto_client_handshaker.h b/quic/core/quic_crypto_client_handshaker.h
index ed8ddc7..40b490e 100644
--- a/quic/core/quic_crypto_client_handshaker.h
+++ b/quic/core/quic_crypto_client_handshaker.h
@@ -51,6 +51,7 @@
HandshakeState GetHandshakeState() const override;
size_t BufferSizeLimitForLevel(EncryptionLevel level) const override;
void OnOneRttPacketAcknowledged() override {}
+ void OnHandshakePacketSent() override {}
void OnHandshakeDoneReceived() override;
void OnApplicationState(
std::unique_ptr<ApplicationState> /*application_state*/) override {
diff --git a/quic/core/quic_crypto_client_stream.cc b/quic/core/quic_crypto_client_stream.cc
index 6f2ffcf..532a982 100644
--- a/quic/core/quic_crypto_client_stream.cc
+++ b/quic/core/quic_crypto_client_stream.cc
@@ -113,6 +113,10 @@
handshaker_->OnOneRttPacketAcknowledged();
}
+void QuicCryptoClientStream::OnHandshakePacketSent() {
+ handshaker_->OnHandshakePacketSent();
+}
+
void QuicCryptoClientStream::OnHandshakeDoneReceived() {
handshaker_->OnHandshakeDoneReceived();
}
diff --git a/quic/core/quic_crypto_client_stream.h b/quic/core/quic_crypto_client_stream.h
index d095deb..82b0ef9 100644
--- a/quic/core/quic_crypto_client_stream.h
+++ b/quic/core/quic_crypto_client_stream.h
@@ -156,6 +156,9 @@
// Called when a 1RTT packet has been acknowledged.
virtual void OnOneRttPacketAcknowledged() = 0;
+ // Called when a packet of ENCRYPTION_HANDSHAKE gets sent.
+ virtual void OnHandshakePacketSent() = 0;
+
// Called when handshake done has been received.
virtual void OnHandshakeDoneReceived() = 0;
@@ -211,6 +214,7 @@
CryptoMessageParser* crypto_message_parser() override;
void OnPacketDecrypted(EncryptionLevel /*level*/) override {}
void OnOneRttPacketAcknowledged() override;
+ void OnHandshakePacketSent() override;
void OnHandshakeDoneReceived() override;
HandshakeState GetHandshakeState() const override;
size_t BufferSizeLimitForLevel(EncryptionLevel level) const override;
diff --git a/quic/core/quic_crypto_server_stream.h b/quic/core/quic_crypto_server_stream.h
index fd14d27..8eef07c 100644
--- a/quic/core/quic_crypto_server_stream.h
+++ b/quic/core/quic_crypto_server_stream.h
@@ -42,6 +42,7 @@
CachedNetworkParameters cached_network_params) override;
void OnPacketDecrypted(EncryptionLevel level) override;
void OnOneRttPacketAcknowledged() override {}
+ void OnHandshakePacketSent() override {}
void OnHandshakeDoneReceived() override;
bool ShouldSendExpectCTHeader() const override;
diff --git a/quic/core/quic_crypto_stream.h b/quic/core/quic_crypto_stream.h
index 94e4730..d3d1082 100644
--- a/quic/core/quic_crypto_stream.h
+++ b/quic/core/quic_crypto_stream.h
@@ -91,6 +91,9 @@
// Called when a 1RTT packet has been acknowledged.
virtual void OnOneRttPacketAcknowledged() = 0;
+ // Called when a packet of ENCRYPTION_HANDSHAKE gets sent.
+ virtual void OnHandshakePacketSent() = 0;
+
// Called when a handshake done frame has been received.
virtual void OnHandshakeDoneReceived() = 0;
diff --git a/quic/core/quic_crypto_stream_test.cc b/quic/core/quic_crypto_stream_test.cc
index 6365bc7..5f414e6 100644
--- a/quic/core/quic_crypto_stream_test.cc
+++ b/quic/core/quic_crypto_stream_test.cc
@@ -58,6 +58,7 @@
}
void OnPacketDecrypted(EncryptionLevel /*level*/) override {}
void OnOneRttPacketAcknowledged() override {}
+ void OnHandshakePacketSent() override {}
void OnHandshakeDoneReceived() override {}
HandshakeState GetHandshakeState() const override { return HANDSHAKE_START; }
diff --git a/quic/core/quic_session.cc b/quic/core/quic_session.cc
index 3524242..930fc2f 100644
--- a/quic/core/quic_session.cc
+++ b/quic/core/quic_session.cc
@@ -289,6 +289,10 @@
GetMutableCryptoStream()->OnOneRttPacketAcknowledged();
}
+void QuicSession::OnHandshakePacketSent() {
+ GetMutableCryptoStream()->OnHandshakePacketSent();
+}
+
void QuicSession::PendingStreamOnRstStream(const QuicRstStreamFrame& frame) {
DCHECK(VersionUsesHttp3(transport_version()));
QuicStreamId stream_id = frame.stream_id;
diff --git a/quic/core/quic_session.h b/quic/core/quic_session.h
index 85c1a5f..1825322 100644
--- a/quic/core/quic_session.h
+++ b/quic/core/quic_session.h
@@ -126,6 +126,7 @@
void OnStopSendingFrame(const QuicStopSendingFrame& frame) override;
void OnPacketDecrypted(EncryptionLevel level) override;
void OnOneRttPacketAcknowledged() override;
+ void OnHandshakePacketSent() override;
// QuicStreamFrameDataProducer
WriteStreamDataResult WriteStreamData(QuicStreamId id,
diff --git a/quic/core/quic_session_test.cc b/quic/core/quic_session_test.cc
index db24eca..8c6e9dd 100644
--- a/quic/core/quic_session_test.cc
+++ b/quic/core/quic_session_test.cc
@@ -117,6 +117,7 @@
}
void OnPacketDecrypted(EncryptionLevel /*level*/) override {}
void OnOneRttPacketAcknowledged() override {}
+ void OnHandshakePacketSent() override {}
void OnHandshakeDoneReceived() override {}
HandshakeState GetHandshakeState() const override {
return one_rtt_keys_available() ? HANDSHAKE_COMPLETE : HANDSHAKE_START;
diff --git a/quic/core/tls_client_handshaker.cc b/quic/core/tls_client_handshaker.cc
index 3770ebd..9379087 100644
--- a/quic/core/tls_client_handshaker.cc
+++ b/quic/core/tls_client_handshaker.cc
@@ -296,6 +296,15 @@
OnHandshakeConfirmed();
}
+void TlsClientHandshaker::OnHandshakePacketSent() {
+ if (initial_keys_dropped_) {
+ return;
+ }
+ handshaker_delegate()->DiscardOldEncryptionKey(ENCRYPTION_INITIAL);
+ handshaker_delegate()->DiscardOldDecryptionKey(ENCRYPTION_INITIAL);
+ initial_keys_dropped_ = true;
+}
+
void TlsClientHandshaker::OnHandshakeDoneReceived() {
if (!one_rtt_keys_available_) {
CloseConnection(QUIC_HANDSHAKE_FAILED,
@@ -529,8 +538,6 @@
if (level == ENCRYPTION_HANDSHAKE &&
state_ < STATE_ENCRYPTION_HANDSHAKE_DATA_SENT) {
state_ = STATE_ENCRYPTION_HANDSHAKE_DATA_SENT;
- handshaker_delegate()->DiscardOldEncryptionKey(ENCRYPTION_INITIAL);
- handshaker_delegate()->DiscardOldDecryptionKey(ENCRYPTION_INITIAL);
}
TlsHandshaker::WriteMessage(level, data);
}
diff --git a/quic/core/tls_client_handshaker.h b/quic/core/tls_client_handshaker.h
index 7acec4f..91b8be8 100644
--- a/quic/core/tls_client_handshaker.h
+++ b/quic/core/tls_client_handshaker.h
@@ -59,6 +59,7 @@
HandshakeState GetHandshakeState() const override;
size_t BufferSizeLimitForLevel(EncryptionLevel level) const override;
void OnOneRttPacketAcknowledged() override;
+ void OnHandshakePacketSent() override;
void OnHandshakeDoneReceived() override;
void SetWriteSecret(EncryptionLevel level,
const SSL_CIPHER* cipher,
@@ -159,6 +160,7 @@
std::string cert_verify_error_details_;
bool encryption_established_ = false;
+ bool initial_keys_dropped_ = false;
bool one_rtt_keys_available_ = false;
bool handshake_confirmed_ = false;
QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters>
diff --git a/quic/core/tls_handshaker_test.cc b/quic/core/tls_handshaker_test.cc
index 147d62f..1bd9fae 100644
--- a/quic/core/tls_handshaker_test.cc
+++ b/quic/core/tls_handshaker_test.cc
@@ -183,6 +183,7 @@
void OnPacketDecrypted(EncryptionLevel /*level*/) override {}
void OnOneRttPacketAcknowledged() override {}
+ void OnHandshakePacketSent() override {}
HandshakeState GetHandshakeState() const override {
return handshaker()->GetHandshakeState();
diff --git a/quic/core/tls_server_handshaker.h b/quic/core/tls_server_handshaker.h
index 9d72d30..28fa121 100644
--- a/quic/core/tls_server_handshaker.h
+++ b/quic/core/tls_server_handshaker.h
@@ -47,6 +47,7 @@
CachedNetworkParameters cached_network_params) override;
void OnPacketDecrypted(EncryptionLevel level) override;
void OnOneRttPacketAcknowledged() override {}
+ void OnHandshakePacketSent() override {}
void OnHandshakeDoneReceived() override;
bool ShouldSendExpectCTHeader() const override;
diff --git a/quic/test_tools/quic_test_utils.h b/quic/test_tools/quic_test_utils.h
index 5a24909..c4976b0 100644
--- a/quic/test_tools/quic_test_utils.h
+++ b/quic/test_tools/quic_test_utils.h
@@ -536,6 +536,7 @@
(override));
MOCK_METHOD(void, OnPacketDecrypted, (EncryptionLevel), (override));
MOCK_METHOD(void, OnOneRttPacketAcknowledged, (), (override));
+ MOCK_METHOD(void, OnHandshakePacketSent, (), (override));
};
class MockQuicConnectionHelper : public QuicConnectionHelperInterface {
@@ -830,6 +831,7 @@
CryptoMessageParser* crypto_message_parser() override;
void OnPacketDecrypted(EncryptionLevel /*level*/) override {}
void OnOneRttPacketAcknowledged() override {}
+ void OnHandshakePacketSent() override {}
void OnHandshakeDoneReceived() override {}
HandshakeState GetHandshakeState() const override { return HANDSHAKE_START; }
diff --git a/quic/test_tools/simulator/quic_endpoint.h b/quic/test_tools/simulator/quic_endpoint.h
index f3a9f02..8b9fd1f 100644
--- a/quic/test_tools/simulator/quic_endpoint.h
+++ b/quic/test_tools/simulator/quic_endpoint.h
@@ -87,6 +87,7 @@
void OnStopSendingFrame(const QuicStopSendingFrame& /*frame*/) override {}
void OnPacketDecrypted(EncryptionLevel /*level*/) override {}
void OnOneRttPacketAcknowledged() override {}
+ void OnHandshakePacketSent() override {}
// End QuicConnectionVisitorInterface implementation.