Don't use a flow controller for QuicCryptoStream when it uses CRYPTO frames
gfe-relnote: QuicCryptoStream change protected behind QUIC_VERSION_99
PiperOrigin-RevId: 248004335
Change-Id: I97d5b6ed0e5523a4264ce2f06e5f6c3249a99fe9
diff --git a/quic/core/quic_stream.cc b/quic/core/quic_stream.cc
index 0d654d6..32b168d 100644
--- a/quic/core/quic_stream.cc
+++ b/quic/core/quic_stream.cc
@@ -181,6 +181,30 @@
sequencer_.set_stream(this);
}
+namespace {
+
+QuicOptional<QuicFlowController> FlowController(QuicStreamId id,
+ QuicSession* session,
+ StreamType type) {
+ if (type == CRYPTO) {
+ // The only QuicStream with a StreamType of CRYPTO is QuicCryptoStream, when
+ // it is using crypto frames instead of stream frames. The QuicCryptoStream
+ // doesn't have any flow control in that case, so we don't create a
+ // QuicFlowController for it.
+ return QuicOptional<QuicFlowController>();
+ }
+ return QuicFlowController(
+ session, id,
+ /*is_connection_flow_controller*/ false,
+ GetReceivedFlowControlWindow(session),
+ GetInitialStreamFlowControlWindowToSend(session),
+ kStreamReceiveWindowLimit,
+ session->flow_controller()->auto_tune_receive_window(),
+ session->flow_controller());
+}
+
+} // namespace
+
QuicStream::QuicStream(QuicStreamId id,
QuicSession* session,
bool is_static,
@@ -192,15 +216,7 @@
type,
0,
false,
- QuicFlowController(
- session,
- id,
- /*is_connection_flow_controller*/ false,
- GetReceivedFlowControlWindow(session),
- GetInitialStreamFlowControlWindowToSend(session),
- kStreamReceiveWindowLimit,
- session->flow_controller()->auto_tune_receive_window(),
- session->flow_controller()),
+ FlowController(id, session, type),
session->flow_controller()) {}
QuicStream::QuicStream(QuicStreamId id,
@@ -210,7 +226,7 @@
StreamType type,
uint64_t stream_bytes_read,
bool fin_received,
- QuicFlowController flow_controller,
+ QuicOptional<QuicFlowController> flow_controller,
QuicFlowController* connection_flow_controller)
: sequencer_(std::move(sequencer)),
id_(id),
@@ -239,7 +255,8 @@
buffered_data_threshold_(GetQuicFlag(FLAGS_quic_buffered_data_threshold)),
is_static_(is_static),
deadline_(QuicTime::Zero()),
- type_(session->connection()->transport_version() == QUIC_VERSION_99
+ type_(session->connection()->transport_version() == QUIC_VERSION_99 &&
+ type != CRYPTO
? QuicUtils::GetStreamType(id_,
perspective_,
session->IsIncomingStream(id_))
@@ -252,7 +269,9 @@
CloseWriteSide();
}
SetFromConfig();
- session_->RegisterStreamPriority(id, is_static_, priority_);
+ if (type_ != CRYPTO) {
+ session_->RegisterStreamPriority(id, is_static_, priority_);
+ }
}
QuicStream::~QuicStream() {
@@ -263,7 +282,7 @@
<< send_buffer_.stream_bytes_outstanding()
<< ", fin_outstanding: " << fin_outstanding_;
}
- if (session_ != nullptr) {
+ if (session_ != nullptr && type_ != CRYPTO) {
session_->UnregisterStreamPriority(id(), is_static_);
}
}
@@ -323,7 +342,7 @@
MaybeIncreaseHighestReceivedOffset(frame.offset + frame_payload_size)) {
// As the highest received offset has changed, check to see if this is a
// violation of flow control.
- if (flow_controller_.FlowControlViolation() ||
+ if (flow_controller_->FlowControlViolation() ||
connection_flow_controller_->FlowControlViolation()) {
CloseConnectionWithDetails(
QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA,
@@ -352,7 +371,7 @@
return;
}
MaybeIncreaseHighestReceivedOffset(frame.byte_offset);
- if (flow_controller_.FlowControlViolation() ||
+ if (flow_controller_->FlowControlViolation() ||
connection_flow_controller_->FlowControlViolation()) {
CloseConnectionWithDetails(
QUIC_FLOW_CONTROL_RECEIVED_TOO_MUCH_DATA,
@@ -493,7 +512,7 @@
}
void QuicStream::MaybeSendBlocked() {
- if (flow_controller_.ShouldSendBlocked()) {
+ if (flow_controller_->ShouldSendBlocked()) {
session_->SendBlocked(id_);
}
if (!stream_contributes_to_connection_flow_control_) {
@@ -507,7 +526,7 @@
// the stream will be given a chance to write when a connection-level
// WINDOW_UPDATE arrives.
if (connection_flow_controller_->IsBlocked() &&
- !flow_controller_.IsBlocked()) {
+ !flow_controller_->IsBlocked()) {
session_->MarkConnectionLevelWriteBlocked(id());
}
}
@@ -707,7 +726,7 @@
rst_sent_ = true;
}
- if (flow_controller_.FlowControlViolation() ||
+ if (flow_controller_->FlowControlViolation() ||
connection_flow_controller_->FlowControlViolation()) {
return;
}
@@ -716,13 +735,13 @@
// the same connection level flow control state, mark all unreceived or
// buffered bytes as consumed.
QuicByteCount bytes_to_consume =
- flow_controller_.highest_received_byte_offset() -
- flow_controller_.bytes_consumed();
+ flow_controller_->highest_received_byte_offset() -
+ flow_controller_->bytes_consumed();
AddBytesConsumed(bytes_to_consume);
}
void QuicStream::OnWindowUpdateFrame(const QuicWindowUpdateFrame& frame) {
- if (flow_controller_.UpdateSendWindowOffset(frame.byte_offset)) {
+ if (flow_controller_->UpdateSendWindowOffset(frame.byte_offset)) {
// Let session unblock this stream.
session_->MarkConnectionLevelWriteBlocked(id_);
}
@@ -731,8 +750,8 @@
bool QuicStream::MaybeIncreaseHighestReceivedOffset(
QuicStreamOffset new_offset) {
uint64_t increment =
- new_offset - flow_controller_.highest_received_byte_offset();
- if (!flow_controller_.UpdateHighestReceivedOffset(new_offset)) {
+ new_offset - flow_controller_->highest_received_byte_offset();
+ if (!flow_controller_->UpdateHighestReceivedOffset(new_offset)) {
return false;
}
@@ -748,16 +767,22 @@
}
void QuicStream::AddBytesSent(QuicByteCount bytes) {
- flow_controller_.AddBytesSent(bytes);
+ flow_controller_->AddBytesSent(bytes);
if (stream_contributes_to_connection_flow_control_) {
connection_flow_controller_->AddBytesSent(bytes);
}
}
void QuicStream::AddBytesConsumed(QuicByteCount bytes) {
+ if (type_ == CRYPTO) {
+ // A stream with type CRYPTO has no flow control, so there's nothing this
+ // function needs to do. This function still gets called by the
+ // QuicStreamSequencers used by QuicCryptoStream.
+ return;
+ }
// Only adjust stream level flow controller if still reading.
if (!read_side_closed_) {
- flow_controller_.AddBytesConsumed(bytes);
+ flow_controller_->AddBytesConsumed(bytes);
}
if (stream_contributes_to_connection_flow_control_) {
@@ -766,7 +791,7 @@
}
void QuicStream::UpdateSendWindowOffset(QuicStreamOffset new_window) {
- if (flow_controller_.UpdateSendWindowOffset(new_window)) {
+ if (flow_controller_->UpdateSendWindowOffset(new_window)) {
// Let session unblock this stream.
session_->MarkConnectionLevelWriteBlocked(id_);
}
@@ -919,7 +944,7 @@
bool fin = fin_buffered_;
// How much data flow control permits to be written.
- QuicByteCount send_window = flow_controller_.SendWindowSize();
+ QuicByteCount send_window = flow_controller_->SendWindowSize();
if (stream_contributes_to_connection_flow_control_) {
send_window =
std::min(send_window, connection_flow_controller_->SendWindowSize());