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