gfe-relnote: In QUIC v48, support partial write of CRYPTO frames. Protected by existing gfe2_reloadable_flag_quic_enable_version_48.

PiperOrigin-RevId: 264373472
Change-Id: I285900280e459bbd70e519ec1e78dc2fa518e4c4
diff --git a/quic/core/quic_session.cc b/quic/core/quic_session.cc
index fd3d489..a335804 100644
--- a/quic/core/quic_session.cc
+++ b/quic/core/quic_session.cc
@@ -572,11 +572,24 @@
   size_t num_writes = flow_controller_.IsBlocked()
                           ? write_blocked_streams_.NumBlockedSpecialStreams()
                           : write_blocked_streams_.NumBlockedStreams();
-  if (num_writes == 0 && !control_frame_manager_.WillingToWrite()) {
+  if (num_writes == 0 && !control_frame_manager_.WillingToWrite() &&
+      (!QuicVersionUsesCryptoFrames(connection_->transport_version()) ||
+       !GetCryptoStream()->HasBufferedCryptoFrames())) {
     return;
   }
 
   QuicConnection::ScopedPacketFlusher flusher(connection_);
+  if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
+    QuicCryptoStream* crypto_stream = GetMutableCryptoStream();
+    if (crypto_stream->HasBufferedCryptoFrames()) {
+      crypto_stream->WriteBufferedCryptoFrames();
+    }
+    if (crypto_stream->HasBufferedCryptoFrames()) {
+      // Cannot finish writing buffered crypto frames, connection is write
+      // blocked.
+      return;
+    }
+  }
   if (control_frame_manager_.WillingToWrite()) {
     control_frame_manager_.OnCanWrite();
   }
@@ -626,6 +639,10 @@
   // 3) If the crypto or headers streams are blocked, or
   // 4) connection is not flow control blocked and there are write blocked
   // streams.
+  if (QuicVersionUsesCryptoFrames(connection_->transport_version()) &&
+      HasPendingHandshake()) {
+    return true;
+  }
   return control_frame_manager_.WillingToWrite() ||
          !streams_with_pending_retransmission_.empty() ||
          write_blocked_streams_.HasWriteBlockedSpecialStream() ||
@@ -635,9 +652,8 @@
 
 bool QuicSession::HasPendingHandshake() const {
   if (QuicVersionUsesCryptoFrames(connection_->transport_version())) {
-    // Writing CRYPTO frames is not subject to flow control, so there can't be
-    // pending data to write, only pending retransmissions.
-    return GetCryptoStream()->HasPendingCryptoRetransmission();
+    return GetCryptoStream()->HasPendingCryptoRetransmission() ||
+           GetCryptoStream()->HasBufferedCryptoFrames();
   }
   return QuicContainsKey(
              streams_with_pending_retransmission_,