In IETF QUIC client: Delay retransmission of 0-RTT data to be after QuicSession config is set to the fresh server config.

This allows us to verify server config in QuicSession::OnConfigNegotiated() before attempting retransmission. Implementation will come as follow-up.

Also enable T050 in quic_spdy_client_session_test

Client side change only. not protected.

PiperOrigin-RevId: 315352910
Change-Id: I7357e217729c6e59187cce17a30b364517c2c632
diff --git a/quic/core/http/quic_server_session_base_test.cc b/quic/core/http/quic_server_session_base_test.cc
index 291884d..6af67a6 100644
--- a/quic/core/http/quic_server_session_base_test.cc
+++ b/quic/core/http/quic_server_session_base_test.cc
@@ -352,6 +352,7 @@
   // more than the negotiated stream limit to deal with rare cases where a
   // client FIN/RST is lost.
 
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
   session_->OnConfigNegotiated();
   if (!VersionHasIetfQuicFrames(transport_version())) {
     // The slightly increased stream limit is set during config negotiation.  It
@@ -404,6 +405,7 @@
   // streams available.  The server accepts slightly more than the negotiated
   // stream limit to deal with rare cases where a client FIN/RST is lost.
 
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
   session_->OnConfigNegotiated();
   const size_t kAvailableStreamLimit =
       session_->MaxAvailableBidirectionalStreams();
@@ -509,6 +511,7 @@
   QuicTagVector copt;
   copt.push_back(kBWRE);
   QuicConfigPeer::SetReceivedConnectionOptions(session_->config(), copt);
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
   session_->OnConfigNegotiated();
   EXPECT_TRUE(
       QuicServerSessionBasePeer::IsBandwidthResumptionEnabled(session_.get()));
@@ -699,6 +702,7 @@
   QuicTagVector copt;
   copt.push_back(kBWMX);
   QuicConfigPeer::SetReceivedConnectionOptions(session_->config(), copt);
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
   session_->OnConfigNegotiated();
   EXPECT_TRUE(
       QuicServerSessionBasePeer::IsBandwidthResumptionEnabled(session_.get()));
@@ -707,6 +711,7 @@
 TEST_P(QuicServerSessionBaseTest, NoBandwidthResumptionByDefault) {
   EXPECT_FALSE(
       QuicServerSessionBasePeer::IsBandwidthResumptionEnabled(session_.get()));
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
   session_->OnConfigNegotiated();
   EXPECT_FALSE(
       QuicServerSessionBasePeer::IsBandwidthResumptionEnabled(session_.get()));
diff --git a/quic/core/http/quic_spdy_client_session.cc b/quic/core/http/quic_spdy_client_session.cc
index 6127e1b..7440edc 100644
--- a/quic/core/http/quic_spdy_client_session.cc
+++ b/quic/core/http/quic_spdy_client_session.cc
@@ -186,7 +186,7 @@
   return std::make_unique<QuicCryptoClientStream>(
       server_id_, this,
       crypto_config_->proof_verifier()->CreateDefaultContext(), crypto_config_,
-      this, /*has_application_state = */ true);
+      this, /*has_application_state = */ version().UsesHttp3());
 }
 
 bool QuicSpdyClientSession::IsAuthorized(const std::string& /*authority*/) {
diff --git a/quic/core/http/quic_spdy_client_session_test.cc b/quic/core/http/quic_spdy_client_session_test.cc
index 34d95c9..1a6ed6c 100644
--- a/quic/core/http/quic_spdy_client_session_test.cc
+++ b/quic/core/http/quic_spdy_client_session_test.cc
@@ -974,23 +974,31 @@
 }
 
 TEST_P(QuicSpdyClientSessionTest, IetfZeroRttSetup) {
-  // This feature is HTTP/3 only
-  if (!VersionUsesHttp3(session_->transport_version())) {
+  // This feature is TLS-only.
+  if (session_->version().UsesQuicCrypto()) {
     return;
   }
+
   CompleteCryptoHandshake();
   EXPECT_FALSE(session_->GetCryptoStream()->IsResumption());
-  SettingsFrame settings;
-  settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 2;
-  settings.values[SETTINGS_MAX_HEADER_LIST_SIZE] = 5;
-  settings.values[256] = 4;  // unknown setting
-  session_->OnSettingsFrame(settings);
+  if (session_->version().UsesHttp3()) {
+    SettingsFrame settings;
+    settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 2;
+    settings.values[SETTINGS_MAX_HEADER_LIST_SIZE] = 5;
+    settings.values[256] = 4;  // unknown setting
+    session_->OnSettingsFrame(settings);
+  }
 
   CreateConnection();
   // Session configs should be in initial state.
-  EXPECT_EQ(0u, session_->flow_controller()->send_window_offset());
-  EXPECT_EQ(std::numeric_limits<size_t>::max(),
-            session_->max_outbound_header_list_size());
+  if (session_->version().UsesHttp3()) {
+    EXPECT_EQ(0u, session_->flow_controller()->send_window_offset());
+    EXPECT_EQ(std::numeric_limits<size_t>::max(),
+              session_->max_outbound_header_list_size());
+  } else {
+    EXPECT_EQ(kMinimumFlowControlSendWindow,
+              session_->flow_controller()->send_window_offset());
+  }
   session_->CryptoConnect();
   EXPECT_TRUE(session_->IsEncryptionEstablished());
   EXPECT_EQ(ENCRYPTION_ZERO_RTT, session_->connection()->encryption_level());
@@ -999,17 +1007,23 @@
   // succeeds.
   EXPECT_EQ(kInitialSessionFlowControlWindowForTest,
             session_->flow_controller()->send_window_offset());
-  auto* id_manager = QuicSessionPeer::v99_streamid_manager(session_.get());
-  EXPECT_EQ(kDefaultMaxStreamsPerConnection,
-            id_manager->max_outgoing_bidirectional_streams());
-  EXPECT_EQ(
-      kDefaultMaxStreamsPerConnection + kHttp3StaticUnidirectionalStreamCount,
-      id_manager->max_outgoing_unidirectional_streams());
-  auto* control_stream =
-      QuicSpdySessionPeer::GetSendControlStream(session_.get());
-  EXPECT_EQ(kInitialStreamFlowControlWindowForTest,
-            control_stream->flow_controller()->send_window_offset());
-  EXPECT_EQ(5u, session_->max_outbound_header_list_size());
+  if (session_->version().UsesHttp3()) {
+    auto* id_manager = QuicSessionPeer::v99_streamid_manager(session_.get());
+    EXPECT_EQ(kDefaultMaxStreamsPerConnection,
+              id_manager->max_outgoing_bidirectional_streams());
+    EXPECT_EQ(
+        kDefaultMaxStreamsPerConnection + kHttp3StaticUnidirectionalStreamCount,
+        id_manager->max_outgoing_unidirectional_streams());
+    auto* control_stream =
+        QuicSpdySessionPeer::GetSendControlStream(session_.get());
+    EXPECT_EQ(kInitialStreamFlowControlWindowForTest,
+              control_stream->flow_controller()->send_window_offset());
+    EXPECT_EQ(5u, session_->max_outbound_header_list_size());
+  } else {
+    auto* id_manager = QuicSessionPeer::GetStreamIdManager(session_.get());
+    EXPECT_EQ(kDefaultMaxStreamsPerConnection,
+              id_manager->max_open_outgoing_streams());
+  }
 
   // Complete the handshake with a different config.
   QuicConfig config = DefaultQuicConfig();
@@ -1026,28 +1040,39 @@
   EXPECT_TRUE(session_->GetCryptoStream()->IsResumption());
   EXPECT_EQ(kInitialSessionFlowControlWindowForTest + 1,
             session_->flow_controller()->send_window_offset());
-  EXPECT_EQ(kDefaultMaxStreamsPerConnection + 1,
-            id_manager->max_outgoing_bidirectional_streams());
-  EXPECT_EQ(kDefaultMaxStreamsPerConnection +
-                kHttp3StaticUnidirectionalStreamCount + 1,
-            id_manager->max_outgoing_unidirectional_streams());
-  EXPECT_EQ(kInitialStreamFlowControlWindowForTest + 1,
-            control_stream->flow_controller()->send_window_offset());
+  if (session_->version().UsesHttp3()) {
+    auto* id_manager = QuicSessionPeer::v99_streamid_manager(session_.get());
+    auto* control_stream =
+        QuicSpdySessionPeer::GetSendControlStream(session_.get());
+    EXPECT_EQ(kDefaultMaxStreamsPerConnection + 1,
+              id_manager->max_outgoing_bidirectional_streams());
+    EXPECT_EQ(kDefaultMaxStreamsPerConnection +
+                  kHttp3StaticUnidirectionalStreamCount + 1,
+              id_manager->max_outgoing_unidirectional_streams());
+    EXPECT_EQ(kInitialStreamFlowControlWindowForTest + 1,
+              control_stream->flow_controller()->send_window_offset());
+  } else {
+    auto* id_manager = QuicSessionPeer::GetStreamIdManager(session_.get());
+    EXPECT_EQ(kDefaultMaxStreamsPerConnection + 1,
+              id_manager->max_open_outgoing_streams());
+  }
 }
 
 TEST_P(QuicSpdyClientSessionTest, RetransmitDataOnZeroRttReject) {
-  // This feature is HTTP/3 only
-  if (!VersionUsesHttp3(session_->transport_version())) {
+  // This feature is TLS-only.
+  if (session_->version().UsesQuicCrypto()) {
     return;
   }
 
   CompleteCryptoHandshake();
   EXPECT_FALSE(session_->GetCryptoStream()->IsResumption());
-  SettingsFrame settings;
-  settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 2;
-  settings.values[SETTINGS_MAX_HEADER_LIST_SIZE] = 5;
-  settings.values[256] = 4;  // unknown setting
-  session_->OnSettingsFrame(settings);
+  if (session_->version().UsesHttp3()) {
+    SettingsFrame settings;
+    settings.values[SETTINGS_QPACK_MAX_TABLE_CAPACITY] = 2;
+    settings.values[SETTINGS_MAX_HEADER_LIST_SIZE] = 5;
+    settings.values[256] = 4;  // unknown setting
+    session_->OnSettingsFrame(settings);
+  }
 
   // Create a second connection, but disable 0-RTT on the server.
   CreateConnection();
@@ -1056,12 +1081,13 @@
   config.SetMaxBidirectionalStreamsToSend(kDefaultMaxStreamsPerConnection);
   SSL_CTX_set_early_data_enabled(server_crypto_config_->ssl_ctx(), false);
 
-  // 3 packets will be written: CHLO, HTTP/3 SETTINGS, and request data.
+  // Packets will be written: CHLO, HTTP/3 SETTINGS (H/3 only), and request
+  // data.
   EXPECT_CALL(*connection_,
               OnPacketSent(ENCRYPTION_INITIAL, NOT_RETRANSMISSION));
   EXPECT_CALL(*connection_,
               OnPacketSent(ENCRYPTION_ZERO_RTT, NOT_RETRANSMISSION))
-      .Times(2);
+      .Times(session_->version().UsesHttp3() ? 2 : 1);
   session_->CryptoConnect();
   EXPECT_TRUE(session_->IsEncryptionEstablished());
   EXPECT_EQ(ENCRYPTION_ZERO_RTT, session_->connection()->encryption_level());
diff --git a/quic/core/http/quic_spdy_session_test.cc b/quic/core/http/quic_spdy_session_test.cc
index 7b4e0d7..b391c06 100644
--- a/quic/core/http/quic_spdy_session_test.cc
+++ b/quic/core/http/quic_spdy_session_test.cc
@@ -1615,6 +1615,7 @@
     return;
   }
   QuicConfigPeer::SetReceivedMaxUnidirectionalStreams(session_.config(), 2u);
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
 
   EXPECT_CALL(
       *connection_,
@@ -1629,6 +1630,7 @@
   copt.push_back(kIFW7);
   QuicConfigPeer::SetReceivedConnectionOptions(session_.config(), copt);
 
+  connection_->SetDefaultEncryptionLevel(ENCRYPTION_FORWARD_SECURE);
   session_.OnConfigNegotiated();
   EXPECT_EQ(192 * 1024u, QuicFlowControllerPeer::ReceiveWindowSize(
                              session_.flow_controller()));