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."};