gfe-relnote: In QUIC, do not send control frames if connection does not have application keys for v99. Protected by quic_enable_version_99.

PiperOrigin-RevId: 264897304
Change-Id: I6b7448b79da6a5119c579003f7d44e8ee7bc13e8
diff --git a/quic/core/http/quic_spdy_session_test.cc b/quic/core/http/quic_spdy_session_test.cc
index c75ffa5..9f3bcbe 100644
--- a/quic/core/http/quic_spdy_session_test.cc
+++ b/quic/core/http/quic_spdy_session_test.cc
@@ -962,6 +962,7 @@
     // GoAway frames are not in version 99
     return;
   }
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
   MockPacketWriter* writer = static_cast<MockPacketWriter*>(
       QuicConnectionPeer::GetWriter(session_.connection()));
   EXPECT_CALL(*writer, WritePacket(_, _, _, _, _))
diff --git a/quic/core/quic_connection.cc b/quic/core/quic_connection.cc
index 20db396..6b6a3a6 100644
--- a/quic/core/quic_connection.cc
+++ b/quic/core/quic_connection.cc
@@ -1541,6 +1541,14 @@
 }
 
 bool QuicConnection::SendControlFrame(const QuicFrame& frame) {
+  if (SupportsMultiplePacketNumberSpaces() &&
+      (encryption_level_ == ENCRYPTION_INITIAL ||
+       encryption_level_ == ENCRYPTION_HANDSHAKE)) {
+    QUIC_DVLOG(1) << ENDPOINT << "Failed to send control frame: " << frame
+                  << " at encryption level: "
+                  << QuicUtils::EncryptionLevelToString(encryption_level_);
+    return false;
+  }
   ScopedPacketFlusher flusher(this);
   const bool consumed =
       packet_generator_.ConsumeRetransmittableControlFrame(frame);
diff --git a/quic/core/quic_connection_test.cc b/quic/core/quic_connection_test.cc
index 0bd2c57..41b02f8 100644
--- a/quic/core/quic_connection_test.cc
+++ b/quic/core/quic_connection_test.cc
@@ -7195,6 +7195,7 @@
   connection_.set_debug_visitor(&debug_visitor);
 
   CongestionBlockWrites();
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
   EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _)).Times(1);
   EXPECT_CALL(debug_visitor, OnPingSent()).Times(1);
@@ -7206,6 +7207,7 @@
   MockQuicConnectionDebugVisitor debug_visitor;
   connection_.set_debug_visitor(&debug_visitor);
 
+  connection_.SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
   EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _)).Times(1);
   EXPECT_EQ(0u, connection_.GetStats().blocked_frames_sent);
@@ -7214,6 +7216,22 @@
   EXPECT_FALSE(connection_.HasQueuedData());
 }
 
+TEST_P(QuicConnectionTest, FailedToSendBlockedFrames) {
+  if (!connection_.SupportsMultiplePacketNumberSpaces()) {
+    return;
+  }
+  MockQuicConnectionDebugVisitor debug_visitor;
+  connection_.set_debug_visitor(&debug_visitor);
+  QuicBlockedFrame blocked(1, 3);
+
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(0);
+  EXPECT_CALL(debug_visitor, OnPacketSent(_, _, _, _)).Times(0);
+  EXPECT_EQ(0u, connection_.GetStats().blocked_frames_sent);
+  connection_.SendControlFrame(QuicFrame(&blocked));
+  EXPECT_EQ(0u, connection_.GetStats().blocked_frames_sent);
+  EXPECT_FALSE(connection_.HasQueuedData());
+}
+
 TEST_P(QuicConnectionTest, SendingUnencryptedStreamDataFails) {
   // EXPECT_QUIC_BUG tests are expensive so only run one instance of them.
   if (!IsDefaultTestConfiguration()) {
diff --git a/quic/core/quic_session_test.cc b/quic/core/quic_session_test.cc
index 09d2bbb..267b2df 100644
--- a/quic/core/quic_session_test.cc
+++ b/quic/core/quic_session_test.cc
@@ -1259,6 +1259,7 @@
     // GoAway frames are not in version 99
     return;
   }
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
   MockPacketWriter* writer = static_cast<MockPacketWriter*>(
       QuicConnectionPeer::GetWriter(session_.connection()));
   EXPECT_CALL(*writer, WritePacket(_, _, _, _, _))