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());