Update QuicControlFrameManager to support RESET_STREAM_AT frames. New code is not called anywhere in the code base. PiperOrigin-RevId: 686983422
diff --git a/quiche/quic/core/quic_control_frame_manager.cc b/quiche/quic/core/quic_control_frame_manager.cc index 28c5b0c..9dd73a1 100644 --- a/quiche/quic/core/quic_control_frame_manager.cc +++ b/quiche/quic/core/quic_control_frame_manager.cc
@@ -10,8 +10,10 @@ #include "quiche/quic/core/frames/quic_ack_frequency_frame.h" #include "quiche/quic/core/frames/quic_frame.h" #include "quiche/quic/core/frames/quic_new_connection_id_frame.h" +#include "quiche/quic/core/frames/quic_reset_stream_at_frame.h" #include "quiche/quic/core/frames/quic_retire_connection_id_frame.h" #include "quiche/quic/core/quic_constants.h" +#include "quiche/quic/core/quic_error_codes.h" #include "quiche/quic/core/quic_session.h" #include "quiche/quic/core/quic_types.h" #include "quiche/quic/core/quic_utils.h" @@ -68,6 +70,15 @@ ++last_control_frame_id_, id, error, bytes_written)))); } +void QuicControlFrameManager::WriteOrBufferResetStreamAt( + QuicStreamId id, QuicResetStreamError error, QuicStreamOffset bytes_written, + QuicStreamOffset reliable_size) { + QUIC_DVLOG(1) << "Writing RST_STREAM_AT_FRAME"; + WriteOrBufferQuicFrame((QuicFrame(new QuicResetStreamAtFrame( + ++last_control_frame_id_, id, error.ietf_application_code(), + bytes_written, reliable_size)))); +} + void QuicControlFrameManager::WriteOrBufferGoAway( QuicErrorCode error, QuicStreamId last_good_stream_id, const std::string& reason) {
diff --git a/quiche/quic/core/quic_control_frame_manager.h b/quiche/quic/core/quic_control_frame_manager.h index 3508f9d..3fc93b0 100644 --- a/quiche/quic/core/quic_control_frame_manager.h +++ b/quiche/quic/core/quic_control_frame_manager.h
@@ -57,6 +57,12 @@ void WriteOrBufferRstStream(QuicControlFrameId id, QuicResetStreamError error, QuicStreamOffset bytes_written); + // Tries to send a RESET_STREAM_AT frame. Buffers the frame if it cannot be + // sent immediately. + void WriteOrBufferResetStreamAt(QuicStreamId id, QuicResetStreamError error, + QuicStreamOffset bytes_written, + QuicStreamOffset reliable_size); + // Tries to send a GOAWAY_FRAME. Buffers the frame if it cannot be sent // immediately. void WriteOrBufferGoAway(QuicErrorCode error,
diff --git a/quiche/quic/core/quic_control_frame_manager_test.cc b/quiche/quic/core/quic_control_frame_manager_test.cc index 2201c4a..a007d92 100644 --- a/quiche/quic/core/quic_control_frame_manager_test.cc +++ b/quiche/quic/core/quic_control_frame_manager_test.cc
@@ -10,7 +10,9 @@ #include "quiche/quic/core/crypto/null_encrypter.h" #include "quiche/quic/core/frames/quic_ack_frequency_frame.h" +#include "quiche/quic/core/frames/quic_reset_stream_at_frame.h" #include "quiche/quic/core/frames/quic_retire_connection_id_frame.h" +#include "quiche/quic/core/quic_error_codes.h" #include "quiche/quic/core/quic_types.h" #include "quiche/quic/platform/api/quic_expect_bug.h" #include "quiche/quic/platform/api/quic_flags.h" @@ -84,6 +86,26 @@ EXPECT_FALSE(manager_->WillingToWrite()); } +TEST_F(QuicControlFrameManagerTest, WriteOrBufferResetStreamAt) { + QuicResetStreamAtFrame reset_stream_at = {1, kTestStreamId, + QUIC_STREAM_CANCELLED, 20, 10}; + EXPECT_CALL(*session_, WriteControlFrame(_, _)) + .WillOnce(Invoke([&reset_stream_at](const QuicFrame& frame, + TransmissionType /*type*/) { + EXPECT_EQ(RESET_STREAM_AT_FRAME, frame.type); + EXPECT_EQ(reset_stream_at, *frame.reset_stream_at_frame); + ClearControlFrame(frame); + return true; + })); + manager_->WriteOrBufferResetStreamAt( + reset_stream_at.stream_id, + QuicResetStreamError::FromIetf(reset_stream_at.error), + reset_stream_at.final_offset, reset_stream_at.reliable_offset); + EXPECT_EQ(1, QuicControlFrameManagerPeer::QueueSize(manager_.get())); + EXPECT_TRUE(manager_->IsControlFrameOutstanding(QuicFrame(&reset_stream_at))); + EXPECT_FALSE(manager_->WillingToWrite()); +} + TEST_F(QuicControlFrameManagerTest, WriteOrBufferGoAway) { QuicGoAwayFrame goaway = {1, QUIC_PEER_GOING_AWAY, kTestStreamId, "Going away."};