gfe-relnote: Check for partial write when crypto frame gets retransmitted. This only affects T099 which supports amplification factor.
PiperOrigin-RevId: 272518334
Change-Id: Ia79b1ae533824e0c4a06de53a24451ea5f697e2b
diff --git a/quic/core/quic_crypto_stream.cc b/quic/core/quic_crypto_stream.cc
index 3081516..d62417f 100644
--- a/quic/core/quic_crypto_stream.cc
+++ b/quic/core/quic_crypto_stream.cc
@@ -256,6 +256,9 @@
size_t bytes_consumed = session()->connection()->SendCryptoData(
level, pending.length, pending.offset);
send_buffer->OnStreamDataRetransmitted(pending.offset, bytes_consumed);
+ if (bytes_consumed < pending.length) {
+ break;
+ }
}
}
session()->connection()->SetDefaultEncryptionLevel(current_encryption_level);
@@ -401,6 +404,9 @@
crypto_frame->level, retransmission_length, retransmission_offset);
send_buffer->OnStreamDataRetransmitted(retransmission_offset,
bytes_consumed);
+ if (bytes_consumed < retransmission_length) {
+ break;
+ }
}
session()->connection()->SetDefaultEncryptionLevel(current_encryption_level);
}
diff --git a/quic/core/quic_crypto_stream_test.cc b/quic/core/quic_crypto_stream_test.cc
index 095e2b7..4b2e2f7 100644
--- a/quic/core/quic_crypto_stream_test.cc
+++ b/quic/core/quic_crypto_stream_test.cc
@@ -586,6 +586,38 @@
QuicCryptoFrame(ENCRYPTION_INITIAL, offset, large_frame));
}
+TEST_F(QuicCryptoStreamTest, RetransmitCryptoFramesAndPartialWrite) {
+ if (!QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+ return;
+ }
+
+ EXPECT_CALL(*connection_, SendCryptoData(_, _, _)).Times(0);
+ InSequence s;
+ // Send [0, 1350) in ENCRYPTION_INITIAL.
+ EXPECT_EQ(ENCRYPTION_INITIAL, connection_->encryption_level());
+ std::string data(1350, 'a');
+ EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1350, 0))
+ .WillOnce(Invoke(connection_,
+ &MockQuicConnection::QuicConnection_SendCryptoData));
+ stream_->WriteCryptoData(ENCRYPTION_INITIAL, data);
+
+ // Lost [0, 1000).
+ QuicCryptoFrame lost_frame(ENCRYPTION_INITIAL, 0, 1000);
+ stream_->OnCryptoFrameLost(&lost_frame);
+ EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
+ // Simulate connection is constrained by amplification restriction.
+ EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1000, 0))
+ .WillOnce(Return(0));
+ stream_->WritePendingCryptoRetransmission();
+ EXPECT_TRUE(stream_->HasPendingCryptoRetransmission());
+ // Connection gets unblocked.
+ EXPECT_CALL(*connection_, SendCryptoData(ENCRYPTION_INITIAL, 1000, 0))
+ .WillOnce(Invoke(connection_,
+ &MockQuicConnection::QuicConnection_SendCryptoData));
+ stream_->WritePendingCryptoRetransmission();
+ EXPECT_FALSE(stream_->HasPendingCryptoRetransmission());
+}
+
} // namespace
} // namespace test
} // namespace quic
diff --git a/quic/core/quic_versions.cc b/quic/core/quic_versions.cc
index 01d2f79..223780b 100644
--- a/quic/core/quic_versions.cc
+++ b/quic/core/quic_versions.cc
@@ -85,8 +85,8 @@
}
bool ParsedQuicVersion::SupportsAntiAmplificationLimit() const {
- // TODO(b/141944763) Enable this for version T099 once issue is resolved.
- return false;
+ return transport_version == QUIC_VERSION_99 &&
+ handshake_protocol == PROTOCOL_TLS1_3;
}
bool VersionHasLengthPrefixedConnectionIds(