Enforce limit on number of blocked streams in QPACK decoder.

gfe-relnote: n/a, change to QUIC v99-only code.  Protected by existing disabled gfe2_reloadable_flag_quic_enable_version_99.
PiperOrigin-RevId: 264688336
Change-Id: Iab1e97a9f31ef95d8dfa05ca8439bf066913b5ba
diff --git a/quic/core/qpack/qpack_decoder.cc b/quic/core/qpack/qpack_decoder.cc
index 7fac1f2..b20cbdf 100644
--- a/quic/core/qpack/qpack_decoder.cc
+++ b/quic/core/qpack/qpack_decoder.cc
@@ -12,10 +12,11 @@
 
 QpackDecoder::QpackDecoder(
     uint64_t maximum_dynamic_table_capacity,
-    uint64_t /* maximum_blocked_streams */,
+    uint64_t maximum_blocked_streams,
     EncoderStreamErrorDelegate* encoder_stream_error_delegate)
     : encoder_stream_error_delegate_(encoder_stream_error_delegate),
-      encoder_stream_receiver_(this) {
+      encoder_stream_receiver_(this),
+      maximum_blocked_streams_(maximum_blocked_streams) {
   DCHECK(encoder_stream_error_delegate_);
 
   header_table_.SetMaximumDynamicTableCapacity(maximum_dynamic_table_capacity);
@@ -29,6 +30,17 @@
   decoder_stream_sender_.SendStreamCancellation(stream_id);
 }
 
+bool QpackDecoder::OnStreamBlocked(QuicStreamId stream_id) {
+  auto result = blocked_streams_.insert(stream_id);
+  DCHECK(result.second);
+  return blocked_streams_.size() <= maximum_blocked_streams_;
+}
+
+void QpackDecoder::OnStreamUnblocked(QuicStreamId stream_id) {
+  size_t result = blocked_streams_.erase(stream_id);
+  DCHECK_EQ(1u, result);
+}
+
 void QpackDecoder::OnInsertWithNameReference(bool is_static,
                                              uint64_t name_index,
                                              QuicStringPiece value) {
@@ -117,7 +129,7 @@
     QuicStreamId stream_id,
     QpackProgressiveDecoder::HeadersHandlerInterface* handler) {
   return QuicMakeUnique<QpackProgressiveDecoder>(
-      stream_id, &header_table_, &decoder_stream_sender_, handler);
+      stream_id, this, &header_table_, &decoder_stream_sender_, handler);
 }
 
 }  // namespace quic