Move stream static checks from QuicSession to QuicStream.
This change is to encourage the rule of "If session needs to hand over things to the stream, let the stream do as much as it can".
gfe-relnote: no behavior change. not protected.
PiperOrigin-RevId: 298695625
Change-Id: I808702aec0f688cb1d2d83e8e84f85a4f73fa1c7
diff --git a/quic/core/quic_session.cc b/quic/core/quic_session.cc
index 26a4356..4df126f 100644
--- a/quic/core/quic_session.cc
+++ b/quic/core/quic_session.cc
@@ -175,7 +175,6 @@
}
void QuicSession::OnStreamFrame(const QuicStreamFrame& frame) {
- // TODO(rch) deal with the error case of stream id 0.
QuicStreamId stream_id = frame.stream_id;
if (stream_id == QuicUtils::GetInvalidStreamId(transport_version())) {
connection()->CloseConnection(
@@ -205,12 +204,6 @@
}
return;
}
- if (frame.fin && stream->is_static()) {
- connection()->CloseConnection(
- QUIC_INVALID_STREAM_ID, "Attempt to close a static stream",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return;
- }
stream->OnStreamFrame(frame);
}
@@ -290,28 +283,11 @@
return;
}
- // Do not reset the sream if all data has been sent and acknowledged.
- if (stream->write_side_closed() && !stream->IsWaitingForAcks()) {
- QUIC_DVLOG(1) << ENDPOINT
- << "Ignoring STOP_SENDING for a write closed stream, id: "
- << stream_id;
+ if (!stream->OnStopSending(frame.application_error_code)) {
return;
}
- if (stream->is_static()) {
- QUIC_DVLOG(1) << ENDPOINT
- << "Received STOP_SENDING for a static stream, id: "
- << stream_id << " Closing connection";
- connection()->CloseConnection(
- QUIC_INVALID_STREAM_ID, "Received STOP_SENDING for a static stream",
- ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
- return;
- }
-
- stream->OnStopSending(frame.application_error_code);
-
- stream->set_stream_error(
- static_cast<QuicRstStreamErrorCode>(frame.application_error_code));
+ // TODO(renjietang): Consider moving those code into the
if (connection()->connected()) {
MaybeSendRstStreamFrame(
stream->id(),
diff --git a/quic/core/quic_stream.cc b/quic/core/quic_stream.cc
index dbf9e66..575011e 100644
--- a/quic/core/quic_stream.cc
+++ b/quic/core/quic_stream.cc
@@ -390,6 +390,12 @@
DCHECK(!(read_side_closed_ && write_side_closed_));
+ if (frame.fin && is_static_) {
+ OnUnrecoverableError(QUIC_INVALID_STREAM_ID,
+ "Attempt to close a static stream");
+ return;
+ }
+
if (type_ == WRITE_UNIDIRECTIONAL) {
OnUnrecoverableError(QUIC_DATA_RECEIVED_ON_WRITE_UNIDIRECTIONAL_STREAM,
"Data received on write unidirectional stream");
@@ -460,6 +466,28 @@
sequencer_.OnStreamFrame(frame);
}
+bool QuicStream::OnStopSending(uint16_t code) {
+ // Do not reset the stream if all data has been sent and acknowledged.
+ if (write_side_closed() && !IsWaitingForAcks()) {
+ QUIC_DVLOG(1) << ENDPOINT
+ << "Ignoring STOP_SENDING for a write closed stream, id: "
+ << id_;
+ return false;
+ }
+
+ if (is_static_) {
+ QUIC_DVLOG(1) << ENDPOINT
+ << "Received STOP_SENDING for a static stream, id: " << id_
+ << " Closing connection";
+ OnUnrecoverableError(QUIC_INVALID_STREAM_ID,
+ "Received STOP_SENDING for a static stream");
+ return false;
+ }
+
+ stream_error_ = static_cast<QuicRstStreamErrorCode>(code);
+ return true;
+}
+
int QuicStream::num_frames_received() const {
return sequencer_.num_frames_received();
}
diff --git a/quic/core/quic_stream.h b/quic/core/quic_stream.h
index 36aec05..aa2e11d 100644
--- a/quic/core/quic_stream.h
+++ b/quic/core/quic_stream.h
@@ -348,8 +348,9 @@
// this method or not.
void SendStopSending(uint16_t code);
- // Handle received StopSending frame.
- virtual void OnStopSending(uint16_t /*code*/) {}
+ // Handle received StopSending frame. Returns true if the processing finishes
+ // gracefully.
+ virtual bool OnStopSending(uint16_t code);
// Close the write side of the socket. Further writes will fail.
// Can be called by the subclass or internally.