Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(430)

Unified Diff: net/quic/chromium/quic_stream_factory_test.cc

Issue 2780523002: m58 merge QUIC: mark QUIC handshake failed if connection is closed after CryptoConnect (Closed)
Patch Set: Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: net/quic/chromium/quic_stream_factory_test.cc
diff --git a/net/quic/chromium/quic_stream_factory_test.cc b/net/quic/chromium/quic_stream_factory_test.cc
index d6fd5aeb42ec0c74be6e856b963bf382beebf52f..92f93ee28d23e98e90cdfeeea424fe8f5510e607 100644
--- a/net/quic/chromium/quic_stream_factory_test.cc
+++ b/net/quic/chromium/quic_stream_factory_test.cc
@@ -316,6 +316,12 @@ class QuicStreamFactoryTestBase {
return QuicStreamFactoryPeer::HasActiveSession(factory_.get(), server_id);
}
+ bool HasActiveJob(const HostPortPair& host_port_pair,
+ const PrivacyMode privacy_mode) {
+ QuicServerId server_id(host_port_pair, privacy_mode);
+ return QuicStreamFactoryPeer::HasActiveJob(factory_.get(), server_id);
+ }
+
bool HasActiveCertVerifierJob(const QuicServerId& server_id) {
return QuicStreamFactoryPeer::HasActiveCertVerifierJob(factory_.get(),
server_id);
@@ -1803,6 +1809,134 @@ TEST_P(QuicStreamFactoryTest, CloseAllSessions) {
EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
}
+// Regression test for crbug.com/700617. Test a write error during the
+// crypto handshake will not hang QuicStreamFactory::Job and should
+// report QUIC_HANDSHAKE_FAILED to upper layers. Subsequent
+// QuicStreamRequest should succeed without hanging.
+TEST_P(QuicStreamFactoryTest,
+ WriteErrorInCryptoConnectWithAsyncHostResolution) {
+ Initialize();
+ // Use unmocked crypto stream to do crypto connect.
+ crypto_client_stream_factory_.set_handshake_mode(
+ MockCryptoClientStream::USE_DEFAULT_CRYPTO_STREAM);
+
+ MockQuicData socket_data;
+ socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
+ // Trigger PACKET_WRITE_ERROR when sending packets in crypto connect.
+ socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
+ socket_data.AddSocketDataToFactory(&socket_factory_);
+
+ // Create request, should fail after the write of the CHLO fails.
+ QuicStreamRequest request(factory_.get());
+ EXPECT_EQ(ERR_IO_PENDING,
+ request.Request(host_port_pair_, privacy_mode_,
+ /*cert_verify_flags=*/0, url_, "GET", net_log_,
+ callback_.callback()));
+ EXPECT_EQ(ERR_QUIC_HANDSHAKE_FAILED, callback_.WaitForResult());
+ EXPECT_FALSE(HasActiveSession(host_port_pair_));
+ EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
+
+ // Verify new requests can be sent normally without hanging.
+ crypto_client_stream_factory_.set_handshake_mode(
+ MockCryptoClientStream::COLD_START);
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ MockQuicData socket_data2;
+ socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
+ socket_data2.AddWrite(
+ ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE,
+ kDefaultMaxUncompressedHeaderSize, nullptr));
+ socket_data2.AddSocketDataToFactory(&socket_factory_);
+
+ QuicStreamRequest request2(factory_.get());
+ EXPECT_EQ(ERR_IO_PENDING,
+ request2.Request(host_port_pair_, privacy_mode_,
+ /*cert_verify_flags=*/0, url_, "GET", net_log_,
+ callback_.callback()));
+ EXPECT_FALSE(HasActiveSession(host_port_pair_));
+ EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
+ // Run the message loop to complete host resolution.
+ base::RunLoop().RunUntilIdle();
+
+ // Complete handshake. QuicStreamFactory::Job should complete and succeed.
+ crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
+ QuicSession::HANDSHAKE_CONFIRMED);
+ EXPECT_THAT(callback_.WaitForResult(), IsOk());
+ EXPECT_TRUE(HasActiveSession(host_port_pair_));
+ EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
+
+ // Create QuicHttpStream.
+ std::unique_ptr<QuicHttpStream> stream = request2.CreateStream();
+ EXPECT_TRUE(stream.get());
+ stream.reset();
+ EXPECT_TRUE(socket_data.AllReadDataConsumed());
+ EXPECT_TRUE(socket_data.AllWriteDataConsumed());
+ EXPECT_TRUE(socket_data2.AllReadDataConsumed());
+ EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
+}
+
+TEST_P(QuicStreamFactoryTest, WriteErrorInCryptoConnectWithSyncHostResolution) {
+ Initialize();
+ // Use unmocked crypto stream to do crypto connect.
+ crypto_client_stream_factory_.set_handshake_mode(
+ MockCryptoClientStream::USE_DEFAULT_CRYPTO_STREAM);
+ host_resolver_.set_synchronous_mode(true);
+ host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
+ "192.168.0.1", "");
+
+ MockQuicData socket_data;
+ socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
+ // Trigger PACKET_WRITE_ERROR when sending packets in crypto connect.
+ socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
+ socket_data.AddSocketDataToFactory(&socket_factory_);
+
+ // Create request, should fail immediately.
+ QuicStreamRequest request(factory_.get());
+ EXPECT_EQ(ERR_QUIC_HANDSHAKE_FAILED,
+ request.Request(host_port_pair_, privacy_mode_,
+ /*cert_verify_flags=*/0, url_, "GET", net_log_,
+ callback_.callback()));
+ // Check no active session, or active jobs left for this server.
+ EXPECT_FALSE(HasActiveSession(host_port_pair_));
+ EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
+
+ // Verify new requests can be sent normally without hanging.
+ crypto_client_stream_factory_.set_handshake_mode(
+ MockCryptoClientStream::COLD_START);
+ ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
+ crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
+ MockQuicData socket_data2;
+ socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
+ socket_data2.AddWrite(
+ ConstructSettingsPacket(1, SETTINGS_MAX_HEADER_LIST_SIZE,
+ kDefaultMaxUncompressedHeaderSize, nullptr));
+ socket_data2.AddSocketDataToFactory(&socket_factory_);
+
+ QuicStreamRequest request2(factory_.get());
+ EXPECT_EQ(ERR_IO_PENDING,
+ request2.Request(host_port_pair_, privacy_mode_,
+ /*cert_verify_flags=*/0, url_, "GET", net_log_,
+ callback_.callback()));
+ EXPECT_FALSE(HasActiveSession(host_port_pair_));
+ EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
+
+ // Complete handshake.
+ crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
+ QuicSession::HANDSHAKE_CONFIRMED);
+ EXPECT_THAT(callback_.WaitForResult(), IsOk());
+ EXPECT_TRUE(HasActiveSession(host_port_pair_));
+ EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
+
+ // Create QuicHttpStream.
+ std::unique_ptr<QuicHttpStream> stream = request2.CreateStream();
+ EXPECT_TRUE(stream.get());
+ stream.reset();
+ EXPECT_TRUE(socket_data.AllReadDataConsumed());
+ EXPECT_TRUE(socket_data.AllWriteDataConsumed());
+ EXPECT_TRUE(socket_data2.AllReadDataConsumed());
+ EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
+}
+
TEST_P(QuicStreamFactoryTest, OnIPAddressChanged) {
close_sessions_on_ip_change_ = true;
Initialize();
« no previous file with comments | « net/quic/chromium/quic_network_transaction_unittest.cc ('k') | net/quic/test_tools/mock_crypto_client_stream.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698