Let TlsClientHandshaker handle connection close during config negotiation. Client side change only. not protected. PiperOrigin-RevId: 310978120 Change-Id: I0f373ffe0874a09c3bbf15901dd8de6ad938a264
diff --git a/quic/core/tls_client_handshaker.cc b/quic/core/tls_client_handshaker.cc index a6aee11..d7fa95b 100644 --- a/quic/core/tls_client_handshaker.cc +++ b/quic/core/tls_client_handshaker.cc
@@ -248,6 +248,11 @@ } session()->OnConfigNegotiated(); + if (state_ == STATE_CONNECTION_CLOSED) { + *error_details = + "Session closed the connection when parsing negotiated config."; + return false; + } return true; }
diff --git a/quic/core/tls_client_handshaker_test.cc b/quic/core/tls_client_handshaker_test.cc index 2629bd4..85492b8 100644 --- a/quic/core/tls_client_handshaker_test.cc +++ b/quic/core/tls_client_handshaker_test.cc
@@ -12,8 +12,10 @@ #include "net/third_party/quiche/src/quic/core/quic_server_id.h" #include "net/third_party/quiche/src/quic/core/quic_utils.h" #include "net/third_party/quiche/src/quic/platform/api/quic_expect_bug.h" +#include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/quic/platform/api/quic_test.h" #include "net/third_party/quiche/src/quic/test_tools/crypto_test_utils.h" +#include "net/third_party/quiche/src/quic/test_tools/quic_session_peer.h" #include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h" #include "net/third_party/quiche/src/quic/test_tools/simple_session_cache.h" #include "net/third_party/quiche/src/quic/tools/fake_proof_verifier.h" @@ -167,6 +169,7 @@ server_compressed_certs_cache_( QuicCompressedCertsCache::kQuicCompressedCertsCacheSize) { SetQuicReloadableFlag(quic_enable_tls_resumption, true); + SetQuicReloadableFlag(quic_enable_zero_rtt_for_tls, true); server_crypto_config_ = crypto_test_utils::CryptoServerConfigForTesting(); CreateConnection(); } @@ -412,6 +415,37 @@ EXPECT_EQ(server_stream()->crypto_negotiated_params().sni, ""); } +TEST_P(TlsClientHandshakerTest, BadTransportParams) { + if (!connection_->version().UsesHttp3()) { + return; + } + SetQuicReloadableFlag(quic_notify_handshaker_on_connection_close, true); + // Finish establishing the first connection: + CompleteCryptoHandshake(); + + // Create a second connection + CreateConnection(); + + stream()->CryptoConnect(); + auto* id_manager = QuicSessionPeer::v99_streamid_manager(session_.get()); + EXPECT_EQ(kDefaultMaxStreamsPerConnection, + id_manager->max_outgoing_bidirectional_streams()); + QuicConfig config; + config.SetMaxBidirectionalStreamsToSend( + config.GetMaxBidirectionalStreamsToSend() - 1); + + EXPECT_CALL(*connection_, CloseConnection(QUIC_MAX_STREAMS_ERROR, _, _)) + .WillOnce(testing::Invoke(connection_, + &MockQuicConnection::ReallyCloseConnection)); + // Close connection will be called again in the handshaker, but this will be + // no-op as the connection is already closed. + EXPECT_CALL(*connection_, CloseConnection(QUIC_HANDSHAKE_FAILED, _, _)); + + crypto_test_utils::HandshakeWithFakeServer( + &config, server_crypto_config_.get(), &server_helper_, &alarm_factory_, + connection_, stream(), AlpnForVersion(connection_->version())); +} + } // namespace } // namespace test } // namespace quic
diff --git a/quic/test_tools/crypto_test_utils.cc b/quic/test_tools/crypto_test_utils.cc index 0694e7d..4864441 100644 --- a/quic/test_tools/crypto_test_utils.cc +++ b/quic/test_tools/crypto_test_utils.cc
@@ -262,7 +262,9 @@ CommunicateHandshakeMessages(client_conn, client, server_conn, server_session.GetMutableCryptoStream()); - CompareClientAndServerKeys(client, server_session.GetMutableCryptoStream()); + if (client_conn->connected() && server_conn->connected()) { + CompareClientAndServerKeys(client, server_session.GetMutableCryptoStream()); + } return client->num_sent_client_hellos(); } @@ -364,8 +366,9 @@ PacketSavingConnection* server_conn, QuicCryptoStream* server) { size_t client_i = 0, server_i = 0; - while (!client->one_rtt_keys_available() || - !server->one_rtt_keys_available()) { + while (client_conn->connected() && server_conn->connected() && + (!client->one_rtt_keys_available() || + !server->one_rtt_keys_available())) { ASSERT_GT(client_conn->encrypted_packets_.size(), client_i); QUIC_LOG(INFO) << "Processing " << client_conn->encrypted_packets_.size() - client_i