gfe-relnote: In QUIC, add SetSoftMaxPacketLength to set a soft max packet length in creator. If a single frame is failed to be serialized, restore the actual max packet length. Not used yet. Not protected.
PiperOrigin-RevId: 278424350
Change-Id: Ie89ba741b6798dee0683b4678edc9242f37f7672
diff --git a/quic/core/quic_packet_creator_test.cc b/quic/core/quic_packet_creator_test.cc
index 5a0c9db..0ba7bd1 100644
--- a/quic/core/quic_packet_creator_test.cc
+++ b/quic/core/quic_packet_creator_test.cc
@@ -2167,6 +2167,75 @@
}
}
+TEST_P(QuicPacketCreatorTest, SoftMaxPacketLength) {
+ creator_.set_encryption_level(ENCRYPTION_FORWARD_SECURE);
+ QuicByteCount previous_max_packet_length = creator_.max_packet_length();
+ const size_t overhead =
+ GetPacketHeaderOverhead(client_framer_.transport_version()) +
+ QuicPacketCreator::MinPlaintextPacketSize(client_framer_.version()) +
+ GetEncryptionOverhead();
+ // Make sure a length which cannot accommodate header (includes header
+ // protection minimal length) gets rejected.
+ creator_.SetSoftMaxPacketLength(overhead - 1);
+ EXPECT_EQ(previous_max_packet_length, creator_.max_packet_length());
+
+ creator_.SetSoftMaxPacketLength(overhead);
+ EXPECT_EQ(overhead, creator_.max_packet_length());
+
+ // Verify creator has room for stream frame because max_packet_length_ gets
+ // restored.
+ ASSERT_TRUE(creator_.HasRoomForStreamFrame(GetNthClientInitiatedStreamId(1),
+ kMaxIetfVarInt, kMaxIetfVarInt));
+ EXPECT_EQ(previous_max_packet_length, creator_.max_packet_length());
+
+ // Same for message frame.
+ if (VersionSupportsMessageFrames(client_framer_.transport_version())) {
+ creator_.SetSoftMaxPacketLength(overhead);
+ // Verify GetCurrentLargestMessagePayload is based on the actual
+ // max_packet_length.
+ EXPECT_LT(1u, creator_.GetCurrentLargestMessagePayload());
+ EXPECT_EQ(overhead, creator_.max_packet_length());
+ ASSERT_TRUE(creator_.HasRoomForMessageFrame(
+ creator_.GetCurrentLargestMessagePayload()));
+ EXPECT_EQ(previous_max_packet_length, creator_.max_packet_length());
+ }
+
+ // Verify creator can consume crypto data because max_packet_length_ gets
+ // restored.
+ creator_.SetSoftMaxPacketLength(overhead);
+ EXPECT_EQ(overhead, creator_.max_packet_length());
+ std::string data = "crypto data";
+ MakeIOVector(data, &iov_);
+ QuicFrame frame;
+ if (!QuicVersionUsesCryptoFrames(client_framer_.transport_version())) {
+ ASSERT_TRUE(creator_.ConsumeDataToFillCurrentPacket(
+ QuicUtils::GetCryptoStreamId(client_framer_.transport_version()), &iov_,
+ 1u, iov_.iov_len, 0u, kOffset, false, true, NOT_RETRANSMISSION,
+ &frame));
+ size_t bytes_consumed = frame.stream_frame.data_length;
+ EXPECT_LT(0u, bytes_consumed);
+ } else {
+ producer_.SaveCryptoData(ENCRYPTION_INITIAL, kOffset, data);
+ ASSERT_TRUE(creator_.ConsumeCryptoDataToFillCurrentPacket(
+ ENCRYPTION_INITIAL, data.length(), kOffset,
+ /*needs_full_padding=*/true, NOT_RETRANSMISSION, &frame));
+ size_t bytes_consumed = frame.crypto_frame->data_length;
+ EXPECT_LT(0u, bytes_consumed);
+ }
+ EXPECT_TRUE(creator_.HasPendingFrames());
+ EXPECT_CALL(delegate_, OnSerializedPacket(_))
+ .WillOnce(Invoke(this, &QuicPacketCreatorTest::SaveSerializedPacket));
+ creator_.FlushCurrentPacket();
+
+ // Verify ACK frame can be consumed.
+ creator_.SetSoftMaxPacketLength(overhead);
+ EXPECT_EQ(overhead, creator_.max_packet_length());
+ QuicAckFrame ack_frame(InitAckFrame(10u));
+ EXPECT_TRUE(
+ creator_.AddSavedFrame(QuicFrame(&ack_frame), NOT_RETRANSMISSION));
+ EXPECT_TRUE(creator_.HasPendingFrames());
+}
+
} // namespace
} // namespace test
} // namespace quic