Remove QuicSession::SendRstStreamInner() because the |close_write_side_only| code paths share so little with each other.
gfe-relnote: protected by gfe2_reloadable_flag_quic_delete_send_rst_stream_inner
PiperOrigin-RevId: 282598706
Change-Id: I2a9df3f32f9ce8670d0f829238e0d8aa6f93dbd0
diff --git a/quic/core/quic_session.cc b/quic/core/quic_session.cc
index 2870b37..9b53845 100644
--- a/quic/core/quic_session.cc
+++ b/quic/core/quic_session.cc
@@ -248,11 +248,6 @@
return;
}
- // Get the QuicStream for this stream. Ignore the STOP_SENDING
- // if the QuicStream pointer is NULL
- // QUESTION(fkastenholz): IS THIS THE RIGHT THING TO DO? (that is, this would
- // happen IFF there was an entry in the map, but the pointer is null. sounds
- // more like a deep programming error rather than a simple protocol problem).
QuicStream* stream = it->second.get();
if (stream == nullptr) {
QUIC_BUG << ENDPOINT
@@ -275,11 +270,15 @@
stream->set_stream_error(
static_cast<QuicRstStreamErrorCode>(frame.application_error_code));
- SendRstStreamInner(
- stream->id(),
- static_cast<quic::QuicRstStreamErrorCode>(frame.application_error_code),
- stream->stream_bytes_written(),
- /*close_write_side_only=*/true);
+ if (connection()->connected()) {
+ MaybeSendRstStreamFrame(
+ stream->id(),
+ static_cast<quic::QuicRstStreamErrorCode>(frame.application_error_code),
+ stream->stream_bytes_written());
+ connection_->OnStreamReset(stream->id(),
+ static_cast<quic::QuicRstStreamErrorCode>(
+ frame.application_error_code));
+ }
stream->set_rst_sent(true);
stream->CloseWriteSide();
}
@@ -701,7 +700,24 @@
void QuicSession::SendRstStream(QuicStreamId id,
QuicRstStreamErrorCode error,
QuicStreamOffset bytes_written) {
- SendRstStreamInner(id, error, bytes_written, /*close_write_side_only=*/false);
+ if (!GetQuicReloadableFlag(quic_delete_send_rst_stream_inner)) {
+ SendRstStreamInner(id, error, bytes_written, false);
+ return;
+ }
+ QUIC_RELOADABLE_FLAG_COUNT(quic_delete_send_rst_stream_inner);
+ if (connection()->connected()) {
+ QuicConnection::ScopedPacketFlusher flusher(connection());
+ MaybeSendRstStreamFrame(id, error, bytes_written);
+ MaybeSendStopSendingFrame(id, error);
+
+ connection_->OnStreamReset(id, error);
+ }
+
+ if (error != QUIC_STREAM_NO_ERROR && QuicContainsKey(zombie_streams_, id)) {
+ OnStreamDoneWaitingForAcks(id);
+ return;
+ }
+ CloseStreamInner(id, true);
}
void QuicSession::SendRstStreamInner(QuicStreamId id,
@@ -740,6 +756,27 @@
}
}
+void QuicSession::MaybeSendRstStreamFrame(QuicStreamId id,
+ QuicRstStreamErrorCode error,
+ QuicStreamOffset bytes_written) {
+ DCHECK(connection()->connected());
+ if (!VersionHasIetfQuicFrames(transport_version()) ||
+ QuicUtils::GetStreamType(id, perspective(), IsIncomingStream(id)) !=
+ READ_UNIDIRECTIONAL) {
+ control_frame_manager_.WriteOrBufferRstStream(id, error, bytes_written);
+ }
+}
+
+void QuicSession::MaybeSendStopSendingFrame(QuicStreamId id,
+ QuicRstStreamErrorCode error) {
+ DCHECK(connection()->connected());
+ if (VersionHasIetfQuicFrames(transport_version()) &&
+ QuicUtils::GetStreamType(id, perspective(), IsIncomingStream(id)) !=
+ WRITE_UNIDIRECTIONAL) {
+ control_frame_manager_.WriteOrBufferStopSending(error, id);
+ }
+}
+
void QuicSession::SendGoAway(QuicErrorCode error_code,
const std::string& reason) {
// GOAWAY frame is not supported in v99.
diff --git a/quic/core/quic_session.h b/quic/core/quic_session.h
index 2d0f252..8ceba0f 100644
--- a/quic/core/quic_session.h
+++ b/quic/core/quic_session.h
@@ -671,6 +671,14 @@
// stream.
void PendingStreamOnRstStream(const QuicRstStreamFrame& frame);
+ // Does actual work of sending RESET_STREAM, if the stream type allows.
+ void MaybeSendRstStreamFrame(QuicStreamId id,
+ QuicRstStreamErrorCode error,
+ QuicStreamOffset bytes_written);
+
+ // Sends a STOP_SENDING frame if the stream type allows.
+ void MaybeSendStopSendingFrame(QuicStreamId id, QuicRstStreamErrorCode error);
+
// Keep track of highest received byte offset of locally closed streams, while
// waiting for a definitive final highest offset from the peer.
std::map<QuicStreamId, QuicStreamOffset>
diff --git a/quic/core/quic_session_test.cc b/quic/core/quic_session_test.cc
index d3df0a7..6334f66 100644
--- a/quic/core/quic_session_test.cc
+++ b/quic/core/quic_session_test.cc
@@ -2768,33 +2768,26 @@
}
QuicStreamId read_only = GetNthClientInitiatedUnidirectionalId(0);
- EXPECT_CALL(*connection_, SendControlFrame(_)).Times(0);
- EXPECT_CALL(*connection_, OnStreamReset(read_only, _));
- session_.SendRstStreamInner(read_only, QUIC_STREAM_CANCELLED, 0,
- /*close_write_side_only = */ true);
EXPECT_CALL(*connection_, SendControlFrame(_))
.Times(1)
.WillOnce(Invoke(&ClearControlFrame));
EXPECT_CALL(*connection_, OnStreamReset(read_only, _));
- session_.SendRstStreamInner(read_only, QUIC_STREAM_CANCELLED, 0,
- /*close_write_side_only = */ false);
+ session_.SendRstStream(read_only, QUIC_STREAM_CANCELLED, 0);
QuicStreamId write_only = GetNthServerInitiatedUnidirectionalId(0);
EXPECT_CALL(*connection_, SendControlFrame(_))
.Times(1)
.WillOnce(Invoke(&ClearControlFrame));
EXPECT_CALL(*connection_, OnStreamReset(write_only, _));
- session_.SendRstStreamInner(write_only, QUIC_STREAM_CANCELLED, 0,
- /*close_write_side_only = */ false);
+ session_.SendRstStream(write_only, QUIC_STREAM_CANCELLED, 0);
QuicStreamId bidirectional = GetNthClientInitiatedBidirectionalId(0);
EXPECT_CALL(*connection_, SendControlFrame(_))
.Times(2)
.WillRepeatedly(Invoke(&ClearControlFrame));
EXPECT_CALL(*connection_, OnStreamReset(bidirectional, _));
- session_.SendRstStreamInner(bidirectional, QUIC_STREAM_CANCELLED, 0,
- /*close_write_side_only = */ false);
+ session_.SendRstStream(bidirectional, QUIC_STREAM_CANCELLED, 0);
}
// A client test class that can be used when the automatic configuration is not
diff --git a/quic/core/quic_stream_test.cc b/quic/core/quic_stream_test.cc
index ba21608..673c7a7 100644
--- a/quic/core/quic_stream_test.cc
+++ b/quic/core/quic_stream_test.cc
@@ -912,10 +912,8 @@
.WillRepeatedly(Invoke(&ClearControlFrame));
EXPECT_CALL(*session_, SendRstStream(stream_->id(), QUIC_STREAM_CANCELLED, 9))
.WillOnce(InvokeWithoutArgs([this]() {
- return QuicSessionPeer::SendRstStreamInner(
- session_.get(), stream_->id(), QUIC_STREAM_CANCELLED,
- stream_->stream_bytes_written(),
- /*close_write_side_only=*/false);
+ session_->ReallySendRstStream(stream_->id(), QUIC_STREAM_CANCELLED,
+ stream_->stream_bytes_written());
}));
stream_->Reset(QUIC_STREAM_CANCELLED);
@@ -1574,25 +1572,6 @@
}
}
-// SendOnlyRstStream must only send a RESET_STREAM (no bundled STOP_SENDING).
-TEST_P(QuicStreamTest, SendOnlyRstStream) {
- Initialize();
- if (!VersionHasIetfQuicFrames(connection_->transport_version())) {
- return;
- }
-
- EXPECT_CALL(*connection_,
- OnStreamReset(stream_->id(), QUIC_BAD_APPLICATION_PAYLOAD));
- EXPECT_CALL(*connection_, SendControlFrame(_))
- .Times(1)
- .WillOnce(Invoke(this, &QuicStreamTest::ClearResetStreamFrame));
-
- QuicSessionPeer::SendRstStreamInner(session_.get(), stream_->id(),
- QUIC_BAD_APPLICATION_PAYLOAD,
- stream_->stream_bytes_written(),
- /*close_write_side_only=*/true);
-}
-
TEST_P(QuicStreamTest, WindowUpdateForReadOnlyStream) {
Initialize();
diff --git a/quic/test_tools/quic_session_peer.cc b/quic/test_tools/quic_session_peer.cc
index 001f1ca..f9e785d 100644
--- a/quic/test_tools/quic_session_peer.cc
+++ b/quic/test_tools/quic_session_peer.cc
@@ -226,15 +226,6 @@
}
// static
-void QuicSessionPeer::SendRstStreamInner(QuicSession* session,
- QuicStreamId id,
- QuicRstStreamErrorCode error,
- QuicStreamOffset bytes_written,
- bool close_write_side_only) {
- session->SendRstStreamInner(id, error, bytes_written, close_write_side_only);
-}
-
-// static
PendingStream* QuicSessionPeer::GetPendingStream(QuicSession* session,
QuicStreamId stream_id) {
auto it = session->pending_stream_map_.find(stream_id);
diff --git a/quic/test_tools/quic_session_peer.h b/quic/test_tools/quic_session_peer.h
index eed3bdd..446cd67 100644
--- a/quic/test_tools/quic_session_peer.h
+++ b/quic/test_tools/quic_session_peer.h
@@ -79,11 +79,6 @@
QuicSession* session);
static QuicStreamIdManager* v99_unidirectional_stream_id_manager(
QuicSession* session);
- static void SendRstStreamInner(QuicSession* session,
- QuicStreamId id,
- QuicRstStreamErrorCode error,
- QuicStreamOffset bytes_written,
- bool close_write_side_only);
static PendingStream* GetPendingStream(QuicSession* session,
QuicStreamId stream_id);
static void set_is_configured(QuicSession* session, bool value);
diff --git a/quic/test_tools/quic_test_utils.h b/quic/test_tools/quic_test_utils.h
index c3c29fa..89dc2dc 100644
--- a/quic/test_tools/quic_test_utils.h
+++ b/quic/test_tools/quic_test_utils.h
@@ -668,6 +668,12 @@
QuicStreamOffset offset,
StreamSendingState state);
+ void ReallySendRstStream(QuicStreamId id,
+ QuicRstStreamErrorCode error,
+ QuicStreamOffset bytes_written) {
+ QuicSession::SendRstStream(id, error, bytes_written);
+ }
+
private:
std::unique_ptr<QuicCryptoStream> crypto_stream_;
};