Redirect WindowUpdate frame to pending streams if they are present, and closes connection when a WindowUpdate frame is received on a READ_UNIDIRECTIONAL stream.

We determined that at least in the foreseeable future, pending streams will only be READ_UNIDIRECTIONAL, so they will close connection when receives WindowUpdate frame.

gfe-relnote: protected by gfe2_reloadable_flag_quic_no_window_update_on_read_only_stream.
PiperOrigin-RevId: 256041719
Change-Id: Ie7caf100a890f770bb1863d6479d66a5e0820e2a
diff --git a/quic/core/quic_session.cc b/quic/core/quic_session.cc
index d7aa91e..829b3d3 100644
--- a/quic/core/quic_session.cc
+++ b/quic/core/quic_session.cc
@@ -528,6 +528,18 @@
     flow_controller_.UpdateSendWindowOffset(frame.byte_offset);
     return;
   }
+
+  if (VersionHasIetfQuicFrames(connection_->transport_version()) &&
+      QuicUtils::GetStreamType(stream_id, perspective(),
+                               IsIncomingStream(stream_id)) ==
+          READ_UNIDIRECTIONAL) {
+    connection()->CloseConnection(
+        QUIC_WINDOW_UPDATE_RECEIVED_ON_READ_UNIDIRECTIONAL_STREAM,
+        "WindowUpdateFrame received on READ_UNIDIRECTIONAL stream.",
+        ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    return;
+  }
+
   QuicStream* stream = GetOrCreateStream(stream_id);
   if (stream != nullptr) {
     stream->OnWindowUpdateFrame(frame);
@@ -1279,6 +1291,7 @@
 }
 
 QuicStream* QuicSession::GetOrCreateStream(const QuicStreamId stream_id) {
+  DCHECK(!QuicContainsKey(pending_stream_map_, stream_id));
   if (eliminate_static_stream_map_ &&
       QuicUtils::IsCryptoStreamId(connection_->transport_version(),
                                   stream_id)) {