Close connection on incoming PRIORITY_UPDATE frame with invalid stream ID. gfe-relnote: n/a, change to QUIC v99-only code. Protected by existing disabled gfe2_reloadable_flag_quic_enable_version_99. PiperOrigin-RevId: 290870791 Change-Id: Ie618cfe2479ae1f7f0151b0bc03a939aec9e87b6
diff --git a/quic/core/http/quic_spdy_session.cc b/quic/core/http/quic_spdy_session.cc index 301e1d1..db93a86 100644 --- a/quic/core/http/quic_spdy_session.cc +++ b/quic/core/http/quic_spdy_session.cc
@@ -504,7 +504,19 @@ return true; } - // TODO(b/147306124): Signal error on invalid stream_id. + QuicStreamCount advertised_max_incoming_bidirectional_streams = + GetAdvertisedMaxIncomingBidirectionalStreams(); + if (advertised_max_incoming_bidirectional_streams == 0 || + stream_id > QuicUtils::GetFirstBidirectionalStreamId( + transport_version(), Perspective::IS_CLIENT) + + QuicUtils::StreamIdDelta(transport_version()) * + (advertised_max_incoming_bidirectional_streams - 1)) { + connection()->CloseConnection( + QUIC_INVALID_STREAM_ID, + "PRIORITY_UPDATE frame received for invalid stream.", + ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET); + return false; + } MaybeSetStreamPriority(stream_id, spdy::SpdyStreamPrecedence(urgency));
diff --git a/quic/core/quic_session.cc b/quic/core/quic_session.cc index 5f3ea29..16ec7b6 100644 --- a/quic/core/quic_session.cc +++ b/quic/core/quic_session.cc
@@ -1509,6 +1509,12 @@ GetNumOpenOutgoingStreams()); } +QuicStreamCount QuicSession::GetAdvertisedMaxIncomingBidirectionalStreams() + const { + DCHECK(VersionHasIetfQuicFrames(transport_version())); + return v99_streamid_manager_.advertised_max_incoming_bidirectional_streams(); +} + QuicStream* QuicSession::GetOrCreateStream(const QuicStreamId stream_id) { DCHECK(!QuicContainsKey(pending_stream_map_, stream_id)); if (QuicUtils::IsCryptoStreamId(transport_version(), stream_id)) {
diff --git a/quic/core/quic_session.h b/quic/core/quic_session.h index f473156..84ba8e1 100644 --- a/quic/core/quic_session.h +++ b/quic/core/quic_session.h
@@ -544,6 +544,10 @@ // Returns the number of open dynamic streams. uint64_t GetNumOpenDynamicStreams() const; + // Returns the maximum bidirectional streams parameter sent with the handshake + // as a transport parameter, or in the most recent MAX_STREAMS frame. + QuicStreamCount GetAdvertisedMaxIncomingBidirectionalStreams() const; + // Performs the work required to close |stream_id|. If |locally_reset| // then the stream has been reset by this endpoint, not by the peer. virtual void CloseStreamInner(QuicStreamId stream_id, bool locally_reset);