Merge QuicStream::ValidateFlowControlLimit() into QuicStream::ConfigSendWindowOffset(). No behavior change. not protected. PiperOrigin-RevId: 325854323 Change-Id: I99220463651fc308c49d88ab754d2c8311bc1a34
diff --git a/quic/core/quic_session.cc b/quic/core/quic_session.cc index f26ff27..39d969c 100644 --- a/quic/core/quic_session.cc +++ b/quic/core/quic_session.cc
@@ -1347,7 +1347,7 @@ } void QuicSession::OnNewStreamFlowControlWindow(QuicStreamOffset new_window) { - DCHECK_EQ(connection_->version().handshake_protocol, PROTOCOL_QUIC_CRYPTO); + DCHECK(version().UsesQuicCrypto()); QUIC_DVLOG(1) << ENDPOINT << "OnNewStreamFlowControlWindow " << new_window; if (new_window < kMinimumFlowControlSendWindow && !connection_->version().AllowsLowFlowControlLimits()) { @@ -1364,7 +1364,8 @@ for (auto const& kv : stream_map_) { QUIC_DVLOG(1) << ENDPOINT << "Informing stream " << kv.first << " of new stream flow control window " << new_window; - if (!kv.second->ConfigSendWindowOffset(new_window)) { + if (!kv.second->MaybeConfigSendWindowOffset( + new_window, /* was_zero_rtt_rejected = */ false)) { return; } } @@ -1373,7 +1374,8 @@ << ENDPOINT << "Informing crypto stream of new stream flow control window " << new_window; - GetMutableCryptoStream()->ConfigSendWindowOffset(new_window); + GetMutableCryptoStream()->MaybeConfigSendWindowOffset( + new_window, /* was_zero_rtt_rejected = */ false); } } @@ -1400,11 +1402,8 @@ } QUIC_DVLOG(1) << ENDPOINT << "Informing unidirectional stream " << id << " of new stream flow control window " << new_window; - if (!kv.second->ValidateFlowControlLimit(new_window, - was_zero_rtt_rejected_)) { - return; - } - if (!kv.second->ConfigSendWindowOffset(new_window)) { + if (!kv.second->MaybeConfigSendWindowOffset(new_window, + was_zero_rtt_rejected_)) { return; } } @@ -1434,11 +1433,8 @@ } QUIC_DVLOG(1) << ENDPOINT << "Informing outgoing bidirectional stream " << id << " of new stream flow control window " << new_window; - if (!kv.second->ValidateFlowControlLimit(new_window, - was_zero_rtt_rejected_)) { - return; - } - if (!kv.second->ConfigSendWindowOffset(new_window)) { + if (!kv.second->MaybeConfigSendWindowOffset(new_window, + was_zero_rtt_rejected_)) { return; } } @@ -1468,11 +1464,8 @@ } QUIC_DVLOG(1) << ENDPOINT << "Informing incoming bidirectional stream " << id << " of new stream flow control window " << new_window; - if (!kv.second->ValidateFlowControlLimit(new_window, - was_zero_rtt_rejected_)) { - return; - } - if (!kv.second->ConfigSendWindowOffset(new_window)) { + if (!kv.second->MaybeConfigSendWindowOffset(new_window, + was_zero_rtt_rejected_)) { return; } }
diff --git a/quic/core/quic_stream.cc b/quic/core/quic_stream.cc index b25a159..cafad49 100644 --- a/quic/core/quic_stream.cc +++ b/quic/core/quic_stream.cc
@@ -931,17 +931,41 @@ } } -bool QuicStream::ConfigSendWindowOffset(QuicStreamOffset new_offset) { +bool QuicStream::MaybeConfigSendWindowOffset(QuicStreamOffset new_offset, + bool was_zero_rtt_rejected) { if (!flow_controller_.has_value()) { QUIC_BUG << ENDPOINT << "ConfigSendWindowOffset called on stream without flow control"; return false; } - QUIC_BUG_IF(session()->version().AllowsLowFlowControlLimits() && - new_offset < flow_controller_->send_window_offset()) - << ENDPOINT << "The new offset " << new_offset - << " decreases current offset " << flow_controller_->send_window_offset(); + if (was_zero_rtt_rejected && new_offset < flow_controller_->bytes_sent()) { + QUIC_BUG_IF(perspective_ == Perspective::IS_SERVER) + << "Server streams' flow control should never be configured twice."; + OnUnrecoverableError( + QUIC_ZERO_RTT_UNRETRANSMITTABLE, + quiche::QuicheStrCat( + "Server rejected 0-RTT, aborting because new stream max data ", + new_offset, " for stream ", id_, + " is less than currently used: ", flow_controller_->bytes_sent())); + return false; + } + + if (session()->version().AllowsLowFlowControlLimits() && + new_offset < flow_controller_->send_window_offset()) { + QUIC_BUG_IF(perspective_ == Perspective::IS_SERVER) + << "Server streams' flow control should never be configured twice."; + OnUnrecoverableError( + was_zero_rtt_rejected ? QUIC_ZERO_RTT_REJECTION_LIMIT_REDUCED + : QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED, + quiche::QuicheStrCat( + was_zero_rtt_rejected ? "Server rejected 0-RTT, aborting because " + : "", + "new stream max data ", new_offset, " decreases current limit: ", + flow_controller_->send_window_offset())); + return false; + } + if (flow_controller_->UpdateSendWindowOffset(new_offset)) { // Let session unblock this stream. session_->MarkConnectionLevelWriteBlocked(id_); @@ -1247,37 +1271,6 @@ } } -bool QuicStream::ValidateFlowControlLimit(QuicStreamOffset new_window, - bool was_zero_rtt_rejected) { - if (was_zero_rtt_rejected && new_window < flow_controller_->bytes_sent()) { - QUIC_BUG_IF(perspective_ == Perspective::IS_SERVER) - << "Server streams' flow control should never be configured twice."; - OnUnrecoverableError( - QUIC_ZERO_RTT_UNRETRANSMITTABLE, - quiche::QuicheStrCat( - "Server rejected 0-RTT, aborting because new stream max data ", - new_window, " for stream ", id_, - " is less than currently used: ", flow_controller_->bytes_sent())); - return false; - } - - if (VersionUsesHttp3(transport_version()) && - new_window < flow_controller_->send_window_offset()) { - QUIC_BUG_IF(perspective_ == Perspective::IS_SERVER) - << "Server streams' flow control should never be configured twice."; - OnUnrecoverableError( - was_zero_rtt_rejected ? QUIC_ZERO_RTT_REJECTION_LIMIT_REDUCED - : QUIC_ZERO_RTT_RESUMPTION_LIMIT_REDUCED, - quiche::QuicheStrCat( - was_zero_rtt_rejected ? "Server rejected 0-RTT, aborting because " - : "", - "new stream max data ", new_window, " decreases current limit: ", - flow_controller_->send_window_offset())); - return false; - } - return true; -} - bool QuicStream::MaybeSetTtl(QuicTime::Delta ttl) { if (is_static_) { QUIC_BUG << "Cannot set TTL of a static stream.";
diff --git a/quic/core/quic_stream.h b/quic/core/quic_stream.h index 8d7ce19..a01d163 100644 --- a/quic/core/quic_stream.h +++ b/quic/core/quic_stream.h
@@ -179,12 +179,6 @@ // Send PRIORITY_UPDATE frame if application protocol supports it. virtual void MaybeSendPriorityUpdateFrame() {} - // Closes the connection and returns false if |new_window| is lower than - // stream's current flow control window. - // Returns true otherwise. - bool ValidateFlowControlLimit(QuicStreamOffset new_window, - bool was_zero_rtt_rejected); - // Sets |priority_| to priority. This should only be called before bytes are // written to the server. For a server stream, this is called when a // PRIORITY_UPDATE frame is received. This calls @@ -244,7 +238,11 @@ bool MaybeIncreaseHighestReceivedOffset(QuicStreamOffset new_offset); // Set the flow controller's send window offset from session config. - bool ConfigSendWindowOffset(QuicStreamOffset new_offset); + // |was_zero_rtt_rejected| is true if this config is from a rejected IETF QUIC + // 0-RTT attempt. Closes the connection and returns false if |new_offset| is + // not valid. + bool MaybeConfigSendWindowOffset(QuicStreamOffset new_offset, + bool was_zero_rtt_rejected); // Returns true if the stream has received either a RST_STREAM or a FIN - // either of which gives a definitive number of bytes which the peer has