| 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 89487b0f6a22c593aca71a82c7460985c2f7a6a0..2ca8dbe9f779857174a7f32dec655cf4b8cc3dba 100644
|
| --- a/net/quic/chromium/quic_stream_factory_test.cc
|
| +++ b/net/quic/chromium/quic_stream_factory_test.cc
|
| @@ -90,6 +90,8 @@
|
|
|
| const char kDefaultServerHostName[] = "www.example.org";
|
| const char kServer2HostName[] = "mail.example.org";
|
| +const char kServer3HostName[] = "docs.example.org";
|
| +const char kServer4HostName[] = "images.example.org";
|
| const char kDifferentHostname[] = "different.example.com";
|
| const int kDefaultServerPort = 443;
|
| const char kDefaultUrl[] = "https://www.example.org/";
|
| @@ -247,6 +249,11 @@
|
| enable_non_blocking_io_(true),
|
| disable_disk_cache_(false),
|
| prefer_aes_(false),
|
| + max_number_of_lossy_connections_(0),
|
| + packet_loss_threshold_(1.0f),
|
| + max_disabled_reasons_(3),
|
| + threshold_timeouts_with_open_streams_(2),
|
| + threshold_public_resets_post_handshake_(2),
|
| receive_buffer_size_(0),
|
| delay_tcp_race_(true),
|
| close_sessions_on_ip_change_(false),
|
| @@ -283,8 +290,10 @@
|
| enable_port_selection_, always_require_handshake_confirmation_,
|
| disable_connection_pooling_, load_server_info_timeout_srtt_multiplier_,
|
| enable_connection_racing_, enable_non_blocking_io_, disable_disk_cache_,
|
| - prefer_aes_, receive_buffer_size_, delay_tcp_race_,
|
| - /*max_server_configs_stored_in_properties*/ 0,
|
| + prefer_aes_, max_number_of_lossy_connections_, packet_loss_threshold_,
|
| + max_disabled_reasons_, threshold_timeouts_with_open_streams_,
|
| + threshold_public_resets_post_handshake_, receive_buffer_size_,
|
| + delay_tcp_race_, /*max_server_configs_stored_in_properties*/ 0,
|
| close_sessions_on_ip_change_,
|
| disable_quic_on_timeout_with_open_streams_,
|
| idle_connection_timeout_seconds_, reduced_ping_timeout_seconds_,
|
| @@ -536,6 +545,11 @@
|
| bool enable_non_blocking_io_;
|
| bool disable_disk_cache_;
|
| bool prefer_aes_;
|
| + int max_number_of_lossy_connections_;
|
| + double packet_loss_threshold_;
|
| + int max_disabled_reasons_;
|
| + int threshold_timeouts_with_open_streams_;
|
| + int threshold_public_resets_post_handshake_;
|
| int receive_buffer_size_;
|
| bool delay_tcp_race_;
|
| bool close_sessions_on_ip_change_;
|
| @@ -3186,16 +3200,182 @@
|
| EXPECT_TRUE(socket_data.AllWriteDataConsumed());
|
| }
|
|
|
| -TEST_P(QuicStreamFactoryTest, ReducePingTimeoutOnConnectionTimeOutOpenStreams) {
|
| - reduced_ping_timeout_seconds_ = 10;
|
| - disable_disk_cache_ = true;
|
| - Initialize();
|
| - ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
|
| +TEST_P(QuicStreamFactoryTest, BadPacketLoss) {
|
| + disable_disk_cache_ = false;
|
| + max_number_of_lossy_connections_ = 2;
|
| + Initialize();
|
| + ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
|
| + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
|
| + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
|
| crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
|
| crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
|
|
|
| QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
|
| - EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get()));
|
| +
|
| + EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
|
| + host_port_pair_.port()));
|
| + EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumberOfLossyConnections(
|
| + factory_.get(), host_port_pair_.port()));
|
| +
|
| + MockQuicData socket_data;
|
| + socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
|
| + socket_data.AddSocketDataToFactory(&socket_factory_);
|
| +
|
| + MockQuicData socket_data2;
|
| + socket_data2.AddSocketDataToFactory(&socket_factory_);
|
| +
|
| + MockQuicData socket_data3;
|
| + socket_data3.AddSocketDataToFactory(&socket_factory_);
|
| +
|
| + MockQuicData socket_data4;
|
| + socket_data4.AddSocketDataToFactory(&socket_factory_);
|
| +
|
| + HostPortPair server2(kServer2HostName, kDefaultServerPort);
|
| + HostPortPair server3(kServer3HostName, kDefaultServerPort);
|
| + HostPortPair server4(kServer4HostName, kDefaultServerPort);
|
| +
|
| + crypto_client_stream_factory_.set_handshake_mode(
|
| + MockCryptoClientStream::ZERO_RTT);
|
| + host_resolver_.set_synchronous_mode(true);
|
| + host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
|
| + "192.168.0.1", "");
|
| + host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
|
| + host_resolver_.rules()->AddIPLiteralRule(server3.host(), "192.168.0.1", "");
|
| + host_resolver_.rules()->AddIPLiteralRule(server4.host(), "192.168.0.1", "");
|
| +
|
| + QuicStreamRequest request(factory_.get());
|
| + EXPECT_EQ(OK, request.Request(host_port_pair_, privacy_mode_,
|
| + /*cert_verify_flags=*/0, url_, "GET", net_log_,
|
| + callback_.callback()));
|
| +
|
| + QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
|
| +
|
| + DVLOG(1) << "Create 1st session and test packet loss";
|
| +
|
| + // Set packet_loss_rate to a lower value than packet_loss_threshold.
|
| + EXPECT_FALSE(
|
| + factory_->OnHandshakeConfirmed(session, /*packet_loss_rate=*/0.9f));
|
| + EXPECT_TRUE(session->connection()->connected());
|
| + EXPECT_TRUE(HasActiveSession(host_port_pair_));
|
| + EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
|
| + host_port_pair_.port()));
|
| + EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumberOfLossyConnections(
|
| + factory_.get(), host_port_pair_.port()));
|
| +
|
| + // Set packet_loss_rate to a higher value than packet_loss_threshold only once
|
| + // and that shouldn't close the session and it shouldn't disable QUIC.
|
| + EXPECT_FALSE(
|
| + factory_->OnHandshakeConfirmed(session, /*packet_loss_rate=*/1.0f));
|
| + EXPECT_EQ(1, QuicStreamFactoryPeer::GetNumberOfLossyConnections(
|
| + factory_.get(), host_port_pair_.port()));
|
| + EXPECT_TRUE(session->connection()->connected());
|
| + EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
|
| + host_port_pair_.port()));
|
| + EXPECT_TRUE(HasActiveSession(host_port_pair_));
|
| +
|
| + // Test N-in-a-row high packet loss connections.
|
| +
|
| + DVLOG(1) << "Create 2nd session and test packet loss";
|
| +
|
| + TestCompletionCallback callback2;
|
| + QuicStreamRequest request2(factory_.get());
|
| + EXPECT_EQ(OK, request2.Request(server2, privacy_mode_,
|
| + /*cert_verify_flags=*/0, url2_, "GET",
|
| + net_log_, callback2.callback()));
|
| + QuicChromiumClientSession* session2 = GetActiveSession(server2);
|
| +
|
| + // If there is no packet loss during handshake confirmation, number of lossy
|
| + // connections for the port should be 0.
|
| + EXPECT_EQ(1, QuicStreamFactoryPeer::GetNumberOfLossyConnections(
|
| + factory_.get(), server2.port()));
|
| + EXPECT_FALSE(
|
| + factory_->OnHandshakeConfirmed(session2, /*packet_loss_rate=*/0.9f));
|
| + EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumberOfLossyConnections(
|
| + factory_.get(), server2.port()));
|
| + EXPECT_FALSE(
|
| + QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(), server2.port()));
|
| +
|
| + // Set packet_loss_rate to a higher value than packet_loss_threshold only once
|
| + // and that shouldn't close the session and it shouldn't disable QUIC.
|
| + EXPECT_FALSE(
|
| + factory_->OnHandshakeConfirmed(session2, /*packet_loss_rate=*/1.0f));
|
| + EXPECT_EQ(1, QuicStreamFactoryPeer::GetNumberOfLossyConnections(
|
| + factory_.get(), server2.port()));
|
| + EXPECT_TRUE(session2->connection()->connected());
|
| + EXPECT_FALSE(
|
| + QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(), server2.port()));
|
| + EXPECT_TRUE(HasActiveSession(server2));
|
| +
|
| + DVLOG(1) << "Create 3rd session which also has packet loss";
|
| +
|
| + TestCompletionCallback callback3;
|
| + QuicStreamRequest request3(factory_.get());
|
| + EXPECT_EQ(OK, request3.Request(server3, privacy_mode_,
|
| + /*cert_verify_flags=*/0, url3_, "GET",
|
| + net_log_, callback3.callback()));
|
| + QuicChromiumClientSession* session3 = GetActiveSession(server3);
|
| +
|
| + DVLOG(1) << "Create 4th session with packet loss and test IsQuicDisabled()";
|
| + TestCompletionCallback callback4;
|
| + QuicStreamRequest request4(factory_.get());
|
| + EXPECT_EQ(OK, request4.Request(server4, privacy_mode_,
|
| + /*cert_verify_flags=*/0, url4_, "GET",
|
| + net_log_, callback4.callback()));
|
| + QuicChromiumClientSession* session4 = GetActiveSession(server4);
|
| +
|
| + // Set packet_loss_rate to higher value than packet_loss_threshold 2nd time in
|
| + // a row and that should close the session and disable QUIC.
|
| + EXPECT_TRUE(
|
| + factory_->OnHandshakeConfirmed(session3, /*packet_loss_rate=*/1.0f));
|
| + EXPECT_EQ(2, QuicStreamFactoryPeer::GetNumberOfLossyConnections(
|
| + factory_.get(), server3.port()));
|
| + EXPECT_FALSE(session3->connection()->connected());
|
| + EXPECT_TRUE(
|
| + QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(), server3.port()));
|
| + EXPECT_FALSE(HasActiveSession(server3));
|
| +
|
| + // Set packet_loss_rate to higher value than packet_loss_threshold 3rd time in
|
| + // a row and IsQuicDisabled() should close the session.
|
| + EXPECT_TRUE(
|
| + factory_->OnHandshakeConfirmed(session4, /*packet_loss_rate=*/1.0f));
|
| + EXPECT_EQ(3, QuicStreamFactoryPeer::GetNumberOfLossyConnections(
|
| + factory_.get(), server4.port()));
|
| + EXPECT_FALSE(session4->connection()->connected());
|
| + EXPECT_TRUE(
|
| + QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(), server4.port()));
|
| + EXPECT_FALSE(HasActiveSession(server4));
|
| +
|
| + std::unique_ptr<QuicHttpStream> stream = request.CreateStream();
|
| + EXPECT_TRUE(stream.get());
|
| + std::unique_ptr<QuicHttpStream> stream2 = request2.CreateStream();
|
| + EXPECT_TRUE(stream2.get());
|
| + std::unique_ptr<QuicHttpStream> stream3 = request3.CreateStream();
|
| + EXPECT_TRUE(stream3.get());
|
| + std::unique_ptr<QuicHttpStream> stream4 = request4.CreateStream();
|
| + EXPECT_TRUE(stream4.get());
|
| + EXPECT_TRUE(socket_data.AllReadDataConsumed());
|
| + EXPECT_TRUE(socket_data.AllWriteDataConsumed());
|
| + EXPECT_TRUE(socket_data2.AllReadDataConsumed());
|
| + EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
|
| + EXPECT_TRUE(socket_data3.AllReadDataConsumed());
|
| + EXPECT_TRUE(socket_data3.AllWriteDataConsumed());
|
| + EXPECT_TRUE(socket_data4.AllReadDataConsumed());
|
| + EXPECT_TRUE(socket_data4.AllWriteDataConsumed());
|
| +}
|
| +
|
| +TEST_P(QuicStreamFactoryTest, PublicResetPostHandshakeTwoOfTwo) {
|
| + disable_disk_cache_ = false;
|
| + threshold_public_resets_post_handshake_ = 2;
|
| + Initialize();
|
| + ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
|
| + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
|
| + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
|
| + QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
|
| +
|
| + EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
|
| + host_port_pair_.port()));
|
| + EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumberOfLossyConnections(
|
| + factory_.get(), host_port_pair_.port()));
|
|
|
| MockQuicData socket_data;
|
| socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
|
| @@ -3214,18 +3394,96 @@
|
| "192.168.0.1", "");
|
| host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
|
|
|
| - // Quic should use default PING timeout when no previous connection times out
|
| - // with open stream.
|
| - EXPECT_EQ(QuicTime::Delta::FromSeconds(kPingTimeoutSecs),
|
| - QuicStreamFactoryPeer::GetPingTimeout(factory_.get()));
|
| QuicStreamRequest request(factory_.get());
|
| EXPECT_EQ(OK, request.Request(host_port_pair_, privacy_mode_,
|
| /*cert_verify_flags=*/0, url_, "GET", net_log_,
|
| callback_.callback()));
|
|
|
| QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
|
| - EXPECT_EQ(QuicTime::Delta::FromSeconds(kPingTimeoutSecs),
|
| - session->connection()->ping_timeout());
|
| +
|
| + DVLOG(1) << "Created 1st session. Now trigger public reset post handshake";
|
| + session->connection()->CloseConnection(QUIC_PUBLIC_RESET, "test",
|
| + ConnectionCloseBehavior::SILENT_CLOSE);
|
| + // Need to spin the loop now to ensure that
|
| + // QuicStreamFactory::OnSessionClosed() runs.
|
| + base::RunLoop run_loop;
|
| + run_loop.RunUntilIdle();
|
| +
|
| + EXPECT_EQ(1, QuicStreamFactoryPeer::GetNumPublicResetsPostHandshake(
|
| + factory_.get()));
|
| + EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
|
| + host_port_pair_.port()));
|
| +
|
| + // Test two-in-a-row public reset post handshakes..
|
| + DVLOG(1) << "Create 2nd session and trigger public reset post handshake";
|
| + TestCompletionCallback callback2;
|
| + QuicStreamRequest request2(factory_.get());
|
| + EXPECT_EQ(OK, request2.Request(server2, privacy_mode_,
|
| + /*cert_verify_flags=*/0, url2_, "GET",
|
| + net_log_, callback2.callback()));
|
| + QuicChromiumClientSession* session2 = GetActiveSession(server2);
|
| +
|
| + session2->connection()->CloseConnection(
|
| + QUIC_PUBLIC_RESET, "test", ConnectionCloseBehavior::SILENT_CLOSE);
|
| + // Need to spin the loop now to ensure that
|
| + // QuicStreamFactory::OnSessionClosed() runs.
|
| + base::RunLoop run_loop2;
|
| + run_loop2.RunUntilIdle();
|
| + EXPECT_EQ(2, QuicStreamFactoryPeer::GetNumPublicResetsPostHandshake(
|
| + factory_.get()));
|
| + EXPECT_TRUE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
|
| + host_port_pair_.port()));
|
| + EXPECT_EQ(
|
| + QuicChromiumClientSession::QUIC_DISABLED_PUBLIC_RESET_POST_HANDSHAKE,
|
| + factory_->QuicDisabledReason(host_port_pair_.port()));
|
| +
|
| + std::unique_ptr<QuicHttpStream> stream = request.CreateStream();
|
| + EXPECT_FALSE(stream.get()); // Session is already closed.
|
| + std::unique_ptr<QuicHttpStream> stream2 = request2.CreateStream();
|
| + EXPECT_FALSE(stream2.get()); // Session is already closed.
|
| + EXPECT_TRUE(socket_data.AllReadDataConsumed());
|
| + EXPECT_TRUE(socket_data.AllWriteDataConsumed());
|
| + EXPECT_TRUE(socket_data2.AllReadDataConsumed());
|
| + EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
|
| +}
|
| +
|
| +TEST_P(QuicStreamFactoryTest, TimeoutsWithOpenStreamsTwoOfTwo) {
|
| + disable_disk_cache_ = true;
|
| + threshold_timeouts_with_open_streams_ = 2;
|
| + Initialize();
|
| + ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
|
| + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
|
| + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
|
| +
|
| + QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
|
| + EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
|
| + host_port_pair_.port()));
|
| + EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumberOfLossyConnections(
|
| + factory_.get(), host_port_pair_.port()));
|
| +
|
| + MockQuicData socket_data;
|
| + socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
|
| + socket_data.AddSocketDataToFactory(&socket_factory_);
|
| +
|
| + MockQuicData socket_data2;
|
| + socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
|
| + socket_data2.AddSocketDataToFactory(&socket_factory_);
|
| +
|
| + HostPortPair server2(kServer2HostName, kDefaultServerPort);
|
| +
|
| + crypto_client_stream_factory_.set_handshake_mode(
|
| + MockCryptoClientStream::CONFIRM_HANDSHAKE);
|
| + host_resolver_.set_synchronous_mode(true);
|
| + host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
|
| + "192.168.0.1", "");
|
| + host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
|
| +
|
| + QuicStreamRequest request(factory_.get());
|
| + EXPECT_EQ(OK, request.Request(host_port_pair_, privacy_mode_,
|
| + /*cert_verify_flags=*/0, url_, "GET", net_log_,
|
| + callback_.callback()));
|
| +
|
| + QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
|
|
|
| std::unique_ptr<QuicHttpStream> stream = request.CreateStream();
|
| EXPECT_TRUE(stream.get());
|
| @@ -3242,7 +3500,115 @@
|
| base::RunLoop run_loop;
|
| run_loop.RunUntilIdle();
|
|
|
| - EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get()));
|
| + EXPECT_EQ(
|
| + 1, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(factory_.get()));
|
| + EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
|
| + host_port_pair_.port()));
|
| +
|
| + // Test two-in-a-row timeouts with open streams.
|
| + DVLOG(1) << "Create 2nd session and timeout with open stream";
|
| + TestCompletionCallback callback2;
|
| + QuicStreamRequest request2(factory_.get());
|
| + EXPECT_EQ(OK, request2.Request(server2, privacy_mode_,
|
| + /*cert_verify_flags=*/0, url2_, "GET",
|
| + net_log_, callback2.callback()));
|
| + QuicChromiumClientSession* session2 = GetActiveSession(server2);
|
| +
|
| + std::unique_ptr<QuicHttpStream> stream2 = request2.CreateStream();
|
| + EXPECT_TRUE(stream2.get());
|
| + EXPECT_EQ(OK, stream2->InitializeStream(&request_info, DEFAULT_PRIORITY,
|
| + net_log_, CompletionCallback()));
|
| +
|
| + session2->connection()->CloseConnection(
|
| + QUIC_NETWORK_IDLE_TIMEOUT, "test", ConnectionCloseBehavior::SILENT_CLOSE);
|
| + // Need to spin the loop now to ensure that
|
| + // QuicStreamFactory::OnSessionClosed() runs.
|
| + base::RunLoop run_loop2;
|
| + run_loop2.RunUntilIdle();
|
| + EXPECT_EQ(
|
| + 2, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(factory_.get()));
|
| + EXPECT_TRUE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
|
| + host_port_pair_.port()));
|
| + EXPECT_EQ(QuicChromiumClientSession::QUIC_DISABLED_TIMEOUT_WITH_OPEN_STREAMS,
|
| + factory_->QuicDisabledReason(host_port_pair_.port()));
|
| +
|
| + // Verify that QUIC is un-disabled after a TCP job fails.
|
| + factory_->OnTcpJobCompleted(/*succeeded=*/false);
|
| + EXPECT_EQ(
|
| + 0, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(factory_.get()));
|
| + EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
|
| + host_port_pair_.port()));
|
| +
|
| + EXPECT_TRUE(socket_data.AllReadDataConsumed());
|
| + EXPECT_TRUE(socket_data.AllWriteDataConsumed());
|
| + EXPECT_TRUE(socket_data2.AllReadDataConsumed());
|
| + EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
|
| +}
|
| +
|
| +TEST_P(QuicStreamFactoryTest, ReducePingTimeoutOnConnectionTimeOutOpenStreams) {
|
| + reduced_ping_timeout_seconds_ = 10;
|
| + disable_disk_cache_ = true;
|
| + threshold_timeouts_with_open_streams_ = 2;
|
| + Initialize();
|
| + ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
|
| + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
|
| + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
|
| +
|
| + QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
|
| + EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
|
| + host_port_pair_.port()));
|
| + EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumberOfLossyConnections(
|
| + factory_.get(), host_port_pair_.port()));
|
| +
|
| + MockQuicData socket_data;
|
| + socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
|
| + socket_data.AddSocketDataToFactory(&socket_factory_);
|
| +
|
| + MockQuicData socket_data2;
|
| + socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
|
| + socket_data2.AddSocketDataToFactory(&socket_factory_);
|
| +
|
| + HostPortPair server2(kServer2HostName, kDefaultServerPort);
|
| +
|
| + crypto_client_stream_factory_.set_handshake_mode(
|
| + MockCryptoClientStream::CONFIRM_HANDSHAKE);
|
| + host_resolver_.set_synchronous_mode(true);
|
| + host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
|
| + "192.168.0.1", "");
|
| + host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
|
| +
|
| + // Quic should use default PING timeout when no previous connection times out
|
| + // with open stream.
|
| + EXPECT_EQ(QuicTime::Delta::FromSeconds(kPingTimeoutSecs),
|
| + QuicStreamFactoryPeer::GetPingTimeout(factory_.get()));
|
| + QuicStreamRequest request(factory_.get());
|
| + EXPECT_EQ(OK, request.Request(host_port_pair_, privacy_mode_,
|
| + /*cert_verify_flags=*/0, url_, "GET", net_log_,
|
| + callback_.callback()));
|
| +
|
| + QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
|
| + EXPECT_EQ(QuicTime::Delta::FromSeconds(kPingTimeoutSecs),
|
| + session->connection()->ping_timeout());
|
| +
|
| + std::unique_ptr<QuicHttpStream> stream = request.CreateStream();
|
| + EXPECT_TRUE(stream.get());
|
| + HttpRequestInfo request_info;
|
| + EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
|
| + net_log_, CompletionCallback()));
|
| +
|
| + DVLOG(1)
|
| + << "Created 1st session and initialized a stream. Now trigger timeout";
|
| + session->connection()->CloseConnection(QUIC_NETWORK_IDLE_TIMEOUT, "test",
|
| + ConnectionCloseBehavior::SILENT_CLOSE);
|
| + // Need to spin the loop now to ensure that
|
| + // QuicStreamFactory::OnSessionClosed() runs.
|
| + base::RunLoop run_loop;
|
| + run_loop.RunUntilIdle();
|
| +
|
| + EXPECT_EQ(
|
| + 1, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(factory_.get()));
|
| + EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
|
| + host_port_pair_.port()));
|
|
|
| // The first connection times out with open stream, QUIC should reduce initial
|
| // PING time for subsequent connections.
|
| @@ -3270,12 +3636,270 @@
|
| // QuicStreamFactory::OnSessionClosed() runs.
|
| base::RunLoop run_loop2;
|
| run_loop2.RunUntilIdle();
|
| - EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get()));
|
| + EXPECT_EQ(
|
| + 2, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(factory_.get()));
|
| + EXPECT_TRUE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
|
| + host_port_pair_.port()));
|
| + EXPECT_EQ(QuicChromiumClientSession::QUIC_DISABLED_TIMEOUT_WITH_OPEN_STREAMS,
|
| + factory_->QuicDisabledReason(host_port_pair_.port()));
|
| +
|
| + // Verify that QUIC is un-disabled after a TCP job fails.
|
| + factory_->OnTcpJobCompleted(/*succeeded=*/false);
|
| + EXPECT_EQ(
|
| + 0, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(factory_.get()));
|
| + EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
|
| + host_port_pair_.port()));
|
|
|
| EXPECT_TRUE(socket_data.AllReadDataConsumed());
|
| EXPECT_TRUE(socket_data.AllWriteDataConsumed());
|
| EXPECT_TRUE(socket_data2.AllReadDataConsumed());
|
| EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
|
| +}
|
| +
|
| +TEST_P(QuicStreamFactoryTest, PublicResetPostHandshakeTwoOfThree) {
|
| + disable_disk_cache_ = true;
|
| + threshold_public_resets_post_handshake_ = 2;
|
| + Initialize();
|
| + ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
|
| + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
|
| + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
|
| + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
|
| +
|
| + EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
|
| + host_port_pair_.port()));
|
| + EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumberOfLossyConnections(
|
| + factory_.get(), host_port_pair_.port()));
|
| +
|
| + MockQuicData socket_data;
|
| + socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
|
| + socket_data.AddSocketDataToFactory(&socket_factory_);
|
| +
|
| + MockQuicData socket_data2;
|
| + socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
|
| + socket_data2.AddSocketDataToFactory(&socket_factory_);
|
| +
|
| + MockQuicData socket_data3;
|
| + socket_data3.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
|
| + socket_data3.AddSocketDataToFactory(&socket_factory_);
|
| +
|
| + HostPortPair server2(kServer2HostName, kDefaultServerPort);
|
| + HostPortPair server3(kServer3HostName, kDefaultServerPort);
|
| +
|
| + crypto_client_stream_factory_.set_handshake_mode(
|
| + MockCryptoClientStream::CONFIRM_HANDSHAKE);
|
| + host_resolver_.set_synchronous_mode(true);
|
| + host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
|
| + "192.168.0.1", "");
|
| + host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
|
| + host_resolver_.rules()->AddIPLiteralRule(server3.host(), "192.168.0.1", "");
|
| +
|
| + // Test first and third out of three public reset post handshakes.
|
| + QuicStreamRequest request(factory_.get());
|
| + EXPECT_EQ(OK, request.Request(host_port_pair_, privacy_mode_,
|
| + /*cert_verify_flags=*/0, url_, "GET", net_log_,
|
| + callback_.callback()));
|
| +
|
| + QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
|
| +
|
| + DVLOG(1) << "Created 1st session. Now trigger public reset post handshake";
|
| + session->connection()->CloseConnection(QUIC_PUBLIC_RESET, "test",
|
| + ConnectionCloseBehavior::SILENT_CLOSE);
|
| + // Need to spin the loop now to ensure that
|
| + // QuicStreamFactory::OnSessionClosed() runs.
|
| + base::RunLoop run_loop;
|
| + run_loop.RunUntilIdle();
|
| +
|
| + EXPECT_EQ(1, QuicStreamFactoryPeer::GetNumPublicResetsPostHandshake(
|
| + factory_.get()));
|
| + EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
|
| + host_port_pair_.port()));
|
| +
|
| + DVLOG(1) << "Create 2nd session without disable trigger";
|
| + TestCompletionCallback callback2;
|
| + QuicStreamRequest request2(factory_.get());
|
| + EXPECT_EQ(OK, request2.Request(server2, privacy_mode_,
|
| + /*cert_verify_flags=*/0, url2_, "GET",
|
| + net_log_, callback2.callback()));
|
| + QuicChromiumClientSession* session2 = GetActiveSession(server2);
|
| +
|
| + session2->connection()->CloseConnection(
|
| + QUIC_NO_ERROR, "test", ConnectionCloseBehavior::SILENT_CLOSE);
|
| + // Need to spin the loop now to ensure that
|
| + // QuicStreamFactory::OnSessionClosed() runs.
|
| + base::RunLoop run_loop2;
|
| + run_loop2.RunUntilIdle();
|
| + EXPECT_EQ(1, QuicStreamFactoryPeer::GetNumPublicResetsPostHandshake(
|
| + factory_.get()));
|
| + EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
|
| + host_port_pair_.port()));
|
| +
|
| + DVLOG(1) << "Create 3rd session with public reset post handshake,"
|
| + << " will disable QUIC";
|
| + TestCompletionCallback callback3;
|
| + QuicStreamRequest request3(factory_.get());
|
| + EXPECT_EQ(OK, request3.Request(server3, privacy_mode_,
|
| + /*cert_verify_flags=*/0, url3_, "GET",
|
| + net_log_, callback3.callback()));
|
| + QuicChromiumClientSession* session3 = GetActiveSession(server3);
|
| +
|
| + session3->connection()->CloseConnection(
|
| + QUIC_PUBLIC_RESET, "test", ConnectionCloseBehavior::SILENT_CLOSE);
|
| + // Need to spin the loop now to ensure that
|
| + // QuicStreamFactory::OnSessionClosed() runs.
|
| + base::RunLoop run_loop3;
|
| + run_loop3.RunUntilIdle();
|
| + EXPECT_EQ(2, QuicStreamFactoryPeer::GetNumPublicResetsPostHandshake(
|
| + factory_.get()));
|
| + EXPECT_TRUE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
|
| + host_port_pair_.port()));
|
| + EXPECT_EQ(
|
| + QuicChromiumClientSession::QUIC_DISABLED_PUBLIC_RESET_POST_HANDSHAKE,
|
| + factory_->QuicDisabledReason(host_port_pair_.port()));
|
| +
|
| + std::unique_ptr<QuicHttpStream> stream = request.CreateStream();
|
| + EXPECT_FALSE(stream.get()); // Session is already closed.
|
| + std::unique_ptr<QuicHttpStream> stream2 = request2.CreateStream();
|
| + EXPECT_FALSE(stream2.get()); // Session is already closed.
|
| + std::unique_ptr<QuicHttpStream> stream3 = request3.CreateStream();
|
| + EXPECT_FALSE(stream3.get()); // Session is already closed.
|
| +
|
| + EXPECT_TRUE(socket_data.AllReadDataConsumed());
|
| + EXPECT_TRUE(socket_data.AllWriteDataConsumed());
|
| + EXPECT_TRUE(socket_data2.AllReadDataConsumed());
|
| + EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
|
| + EXPECT_TRUE(socket_data3.AllReadDataConsumed());
|
| + EXPECT_TRUE(socket_data3.AllWriteDataConsumed());
|
| +}
|
| +
|
| +TEST_P(QuicStreamFactoryTest, TimeoutsWithOpenStreamsTwoOfThree) {
|
| + disable_disk_cache_ = true;
|
| + threshold_public_resets_post_handshake_ = 2;
|
| + Initialize();
|
| + ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
|
| + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
|
| + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
|
| + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
|
| + QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
|
| +
|
| + EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
|
| + host_port_pair_.port()));
|
| + EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumberOfLossyConnections(
|
| + factory_.get(), host_port_pair_.port()));
|
| +
|
| + MockQuicData socket_data;
|
| + socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
|
| + socket_data.AddSocketDataToFactory(&socket_factory_);
|
| +
|
| + MockQuicData socket_data2;
|
| + socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
|
| + socket_data2.AddSocketDataToFactory(&socket_factory_);
|
| +
|
| + MockQuicData socket_data3;
|
| + socket_data3.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
|
| + socket_data3.AddSocketDataToFactory(&socket_factory_);
|
| +
|
| + HostPortPair server2(kServer2HostName, kDefaultServerPort);
|
| + HostPortPair server3(kServer3HostName, kDefaultServerPort);
|
| +
|
| + crypto_client_stream_factory_.set_handshake_mode(
|
| + MockCryptoClientStream::CONFIRM_HANDSHAKE);
|
| + host_resolver_.set_synchronous_mode(true);
|
| + host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
|
| + "192.168.0.1", "");
|
| + host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
|
| + host_resolver_.rules()->AddIPLiteralRule(server3.host(), "192.168.0.1", "");
|
| +
|
| + // Test first and third out of three timeouts with open streams.
|
| + QuicStreamRequest request(factory_.get());
|
| + EXPECT_EQ(OK, request.Request(host_port_pair_, privacy_mode_,
|
| + /*cert_verify_flags=*/0, url_, "GET", net_log_,
|
| + callback_.callback()));
|
| +
|
| + QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
|
| +
|
| + std::unique_ptr<QuicHttpStream> stream = request.CreateStream();
|
| + EXPECT_TRUE(stream.get());
|
| + HttpRequestInfo request_info;
|
| + EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
|
| + net_log_, CompletionCallback()));
|
| +
|
| + DVLOG(1)
|
| + << "Created 1st session and initialized a stream. Now trigger timeout";
|
| + session->connection()->CloseConnection(QUIC_NETWORK_IDLE_TIMEOUT, "test",
|
| + ConnectionCloseBehavior::SILENT_CLOSE);
|
| + // Need to spin the loop now to ensure that
|
| + // QuicStreamFactory::OnSessionClosed() runs.
|
| + base::RunLoop run_loop;
|
| + run_loop.RunUntilIdle();
|
| +
|
| + EXPECT_EQ(
|
| + 1, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(factory_.get()));
|
| + EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
|
| + host_port_pair_.port()));
|
| +
|
| + // Test two-in-a-row timeouts with open streams.
|
| + DVLOG(1) << "Create 2nd session without timeout";
|
| + TestCompletionCallback callback2;
|
| + QuicStreamRequest request2(factory_.get());
|
| + EXPECT_EQ(OK, request2.Request(server2, privacy_mode_,
|
| + /*cert_verify_flags=*/0, url2_, "GET",
|
| + net_log_, callback2.callback()));
|
| + QuicChromiumClientSession* session2 = GetActiveSession(server2);
|
| +
|
| + session2->connection()->CloseConnection(
|
| + QUIC_NO_ERROR, "test", ConnectionCloseBehavior::SILENT_CLOSE);
|
| + // Need to spin the loop now to ensure that
|
| + // QuicStreamFactory::OnSessionClosed() runs.
|
| + base::RunLoop run_loop2;
|
| + run_loop2.RunUntilIdle();
|
| + EXPECT_EQ(
|
| + 1, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(factory_.get()));
|
| + EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
|
| + host_port_pair_.port()));
|
| +
|
| + DVLOG(1) << "Create 3rd session with timeout with open streams,"
|
| + << " will disable QUIC";
|
| +
|
| + TestCompletionCallback callback3;
|
| + QuicStreamRequest request3(factory_.get());
|
| + EXPECT_EQ(OK, request3.Request(server3, privacy_mode_,
|
| + /*cert_verify_flags=*/0, url3_, "GET",
|
| + net_log_, callback3.callback()));
|
| + QuicChromiumClientSession* session3 = GetActiveSession(server3);
|
| +
|
| + std::unique_ptr<QuicHttpStream> stream3 = request3.CreateStream();
|
| + EXPECT_TRUE(stream3.get());
|
| + EXPECT_EQ(OK, stream3->InitializeStream(&request_info, DEFAULT_PRIORITY,
|
| + net_log_, CompletionCallback()));
|
| + session3->connection()->CloseConnection(
|
| + QUIC_NETWORK_IDLE_TIMEOUT, "test", ConnectionCloseBehavior::SILENT_CLOSE);
|
| + // Need to spin the loop now to ensure that
|
| + // QuicStreamFactory::OnSessionClosed() runs.
|
| + base::RunLoop run_loop3;
|
| + run_loop3.RunUntilIdle();
|
| + EXPECT_EQ(
|
| + 2, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(factory_.get()));
|
| + EXPECT_TRUE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
|
| + host_port_pair_.port()));
|
| + EXPECT_EQ(QuicChromiumClientSession::QUIC_DISABLED_TIMEOUT_WITH_OPEN_STREAMS,
|
| + factory_->QuicDisabledReason(host_port_pair_.port()));
|
| +
|
| + std::unique_ptr<QuicHttpStream> stream2 = request2.CreateStream();
|
| + EXPECT_FALSE(stream2.get()); // Session is already closed.
|
| +
|
| + // Verify that QUIC is un-disabled after a network change.
|
| + factory_->OnIPAddressChanged();
|
| + EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
|
| + host_port_pair_.port()));
|
| + EXPECT_EQ(
|
| + 0, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(factory_.get()));
|
| +
|
| + EXPECT_TRUE(socket_data.AllReadDataConsumed());
|
| + EXPECT_TRUE(socket_data.AllWriteDataConsumed());
|
| + EXPECT_TRUE(socket_data2.AllReadDataConsumed());
|
| + EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
|
| + EXPECT_TRUE(socket_data3.AllReadDataConsumed());
|
| + EXPECT_TRUE(socket_data3.AllWriteDataConsumed());
|
| }
|
|
|
| TEST_P(QuicStreamFactoryTest, DisableQuicWhenTimeoutsWithOpenStreams) {
|
| @@ -3286,7 +3910,10 @@
|
| crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
|
| QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
|
|
|
| - EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get()));
|
| + EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
|
| + host_port_pair_.port()));
|
| + EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumberOfLossyConnections(
|
| + factory_.get(), host_port_pair_.port()));
|
|
|
| MockQuicData socket_data;
|
| socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
|
| @@ -3322,18 +3949,318 @@
|
| base::RunLoop run_loop;
|
| run_loop.RunUntilIdle();
|
|
|
| - EXPECT_TRUE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get()));
|
| + EXPECT_EQ(
|
| + 1, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(factory_.get()));
|
| + EXPECT_TRUE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
|
| + host_port_pair_.port()));
|
| +
|
| + EXPECT_EQ(QuicChromiumClientSession::QUIC_DISABLED_TIMEOUT_WITH_OPEN_STREAMS,
|
| + factory_->QuicDisabledReason(host_port_pair_.port()));
|
|
|
| // Verify that QUIC is fully disabled after a TCP job succeeds.
|
| factory_->OnTcpJobCompleted(/*succeeded=*/true);
|
| - EXPECT_TRUE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get()));
|
| + EXPECT_TRUE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
|
| + host_port_pair_.port()));
|
|
|
| // Verify that QUIC stays disabled after a TCP job succeeds.
|
| factory_->OnTcpJobCompleted(/*succeeded=*/false);
|
| - EXPECT_TRUE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get()));
|
| -
|
| - EXPECT_TRUE(socket_data.AllReadDataConsumed());
|
| - EXPECT_TRUE(socket_data.AllWriteDataConsumed());
|
| + EXPECT_TRUE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
|
| + host_port_pair_.port()));
|
| +
|
| + EXPECT_TRUE(socket_data.AllReadDataConsumed());
|
| + EXPECT_TRUE(socket_data.AllWriteDataConsumed());
|
| +}
|
| +
|
| +TEST_P(QuicStreamFactoryTest, PublicResetPostHandshakeTwoOfFour) {
|
| + disable_disk_cache_ = true;
|
| + threshold_public_resets_post_handshake_ = 2;
|
| + Initialize();
|
| + ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
|
| + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
|
| + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
|
| + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
|
| + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
|
| + QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
|
| +
|
| + EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
|
| + host_port_pair_.port()));
|
| + EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumberOfLossyConnections(
|
| + factory_.get(), host_port_pair_.port()));
|
| +
|
| + MockQuicData socket_data;
|
| + socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
|
| + socket_data.AddSocketDataToFactory(&socket_factory_);
|
| +
|
| + MockQuicData socket_data2;
|
| + socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
|
| + socket_data2.AddSocketDataToFactory(&socket_factory_);
|
| +
|
| + MockQuicData socket_data3;
|
| + socket_data3.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
|
| + socket_data3.AddSocketDataToFactory(&socket_factory_);
|
| +
|
| + MockQuicData socket_data4;
|
| + socket_data4.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
|
| + socket_data4.AddSocketDataToFactory(&socket_factory_);
|
| +
|
| + HostPortPair server2(kServer2HostName, kDefaultServerPort);
|
| + HostPortPair server3(kServer3HostName, kDefaultServerPort);
|
| + HostPortPair server4(kServer4HostName, kDefaultServerPort);
|
| +
|
| + crypto_client_stream_factory_.set_handshake_mode(
|
| + MockCryptoClientStream::CONFIRM_HANDSHAKE);
|
| + host_resolver_.set_synchronous_mode(true);
|
| + host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
|
| + "192.168.0.1", "");
|
| + host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
|
| + host_resolver_.rules()->AddIPLiteralRule(server3.host(), "192.168.0.1", "");
|
| + host_resolver_.rules()->AddIPLiteralRule(server4.host(), "192.168.0.1", "");
|
| +
|
| + // Test first and fourth out of four public reset post handshakes.
|
| + QuicStreamRequest request(factory_.get());
|
| + EXPECT_EQ(OK, request.Request(host_port_pair_, privacy_mode_,
|
| + /*cert_verify_flags=*/0, url_, "GET", net_log_,
|
| + callback_.callback()));
|
| +
|
| + QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
|
| +
|
| + DVLOG(1) << "Created 1st session. Now trigger public reset post handshake";
|
| + session->connection()->CloseConnection(QUIC_PUBLIC_RESET, "test",
|
| + ConnectionCloseBehavior::SILENT_CLOSE);
|
| + // Need to spin the loop now to ensure that
|
| + // QuicStreamFactory::OnSessionClosed() runs.
|
| + base::RunLoop run_loop;
|
| + run_loop.RunUntilIdle();
|
| +
|
| + EXPECT_EQ(1, QuicStreamFactoryPeer::GetNumPublicResetsPostHandshake(
|
| + factory_.get()));
|
| + EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
|
| + host_port_pair_.port()));
|
| +
|
| + DVLOG(1) << "Create 2nd and 3rd sessions without disable trigger";
|
| + TestCompletionCallback callback2;
|
| + QuicStreamRequest request2(factory_.get());
|
| + EXPECT_EQ(OK, request2.Request(server2, privacy_mode_,
|
| + /*cert_verify_flags=*/0, url2_, "GET",
|
| + net_log_, callback2.callback()));
|
| + QuicChromiumClientSession* session2 = GetActiveSession(server2);
|
| +
|
| + session2->connection()->CloseConnection(
|
| + QUIC_NO_ERROR, "test", ConnectionCloseBehavior::SILENT_CLOSE);
|
| + // Need to spin the loop now to ensure that
|
| + // QuicStreamFactory::OnSessionClosed() runs.
|
| + base::RunLoop run_loop2;
|
| + run_loop2.RunUntilIdle();
|
| + EXPECT_EQ(1, QuicStreamFactoryPeer::GetNumPublicResetsPostHandshake(
|
| + factory_.get()));
|
| + EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
|
| + host_port_pair_.port()));
|
| +
|
| + TestCompletionCallback callback3;
|
| + QuicStreamRequest request3(factory_.get());
|
| + EXPECT_EQ(OK, request3.Request(server3, privacy_mode_,
|
| + /*cert_verify_flags=*/0, url3_, "GET",
|
| + net_log_, callback3.callback()));
|
| + QuicChromiumClientSession* session3 = GetActiveSession(server3);
|
| +
|
| + session3->connection()->CloseConnection(
|
| + QUIC_NO_ERROR, "test", ConnectionCloseBehavior::SILENT_CLOSE);
|
| + // Need to spin the loop now to ensure that
|
| + // QuicStreamFactory::OnSessionClosed() runs.
|
| + base::RunLoop run_loop3;
|
| + run_loop3.RunUntilIdle();
|
| + EXPECT_EQ(1, QuicStreamFactoryPeer::GetNumPublicResetsPostHandshake(
|
| + factory_.get()));
|
| + EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
|
| + host_port_pair_.port()));
|
| +
|
| + DVLOG(1) << "Create 4rd session with public reset post handshake,"
|
| + << " will not disable QUIC";
|
| + TestCompletionCallback callback4;
|
| + QuicStreamRequest request4(factory_.get());
|
| + EXPECT_EQ(OK, request4.Request(server4, privacy_mode_,
|
| + /*cert_verify_flags=*/0, url4_, "GET",
|
| + net_log_, callback4.callback()));
|
| + QuicChromiumClientSession* session4 = GetActiveSession(server4);
|
| +
|
| + session4->connection()->CloseConnection(
|
| + QUIC_PUBLIC_RESET, "test", ConnectionCloseBehavior::SILENT_CLOSE);
|
| + // Need to spin the loop now to ensure that
|
| + // QuicStreamFactory::OnSessionClosed() runs.
|
| + base::RunLoop run_loop4;
|
| + run_loop4.RunUntilIdle();
|
| + EXPECT_EQ(1, QuicStreamFactoryPeer::GetNumPublicResetsPostHandshake(
|
| + factory_.get()));
|
| + EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
|
| + host_port_pair_.port()));
|
| +
|
| + std::unique_ptr<QuicHttpStream> stream = request.CreateStream();
|
| + EXPECT_FALSE(stream.get()); // Session is already closed.
|
| + std::unique_ptr<QuicHttpStream> stream2 = request2.CreateStream();
|
| + EXPECT_FALSE(stream2.get()); // Session is already closed.
|
| + std::unique_ptr<QuicHttpStream> stream3 = request3.CreateStream();
|
| + EXPECT_FALSE(stream3.get()); // Session is already closed.
|
| + std::unique_ptr<QuicHttpStream> stream4 = request4.CreateStream();
|
| + EXPECT_FALSE(stream4.get()); // Session is already closed.
|
| +
|
| + EXPECT_TRUE(socket_data.AllReadDataConsumed());
|
| + EXPECT_TRUE(socket_data.AllWriteDataConsumed());
|
| + EXPECT_TRUE(socket_data2.AllReadDataConsumed());
|
| + EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
|
| + EXPECT_TRUE(socket_data3.AllReadDataConsumed());
|
| + EXPECT_TRUE(socket_data3.AllWriteDataConsumed());
|
| + EXPECT_TRUE(socket_data4.AllReadDataConsumed());
|
| + EXPECT_TRUE(socket_data4.AllWriteDataConsumed());
|
| +}
|
| +
|
| +TEST_P(QuicStreamFactoryTest, TimeoutsWithOpenStreamsTwoOfFour) {
|
| + disable_disk_cache_ = true;
|
| + threshold_public_resets_post_handshake_ = 2;
|
| + Initialize();
|
| + ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
|
| + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
|
| + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
|
| + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
|
| + crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
|
| + QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
|
| +
|
| + EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
|
| + host_port_pair_.port()));
|
| + EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumberOfLossyConnections(
|
| + factory_.get(), host_port_pair_.port()));
|
| +
|
| + MockQuicData socket_data;
|
| + socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
|
| + socket_data.AddSocketDataToFactory(&socket_factory_);
|
| +
|
| + MockQuicData socket_data2;
|
| + socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
|
| + socket_data2.AddSocketDataToFactory(&socket_factory_);
|
| +
|
| + MockQuicData socket_data3;
|
| + socket_data3.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
|
| + socket_data3.AddSocketDataToFactory(&socket_factory_);
|
| +
|
| + MockQuicData socket_data4;
|
| + socket_data4.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
|
| + socket_data4.AddSocketDataToFactory(&socket_factory_);
|
| +
|
| + HostPortPair server2(kServer2HostName, kDefaultServerPort);
|
| + HostPortPair server3(kServer3HostName, kDefaultServerPort);
|
| + HostPortPair server4(kServer4HostName, kDefaultServerPort);
|
| +
|
| + crypto_client_stream_factory_.set_handshake_mode(
|
| + MockCryptoClientStream::CONFIRM_HANDSHAKE);
|
| + host_resolver_.set_synchronous_mode(true);
|
| + host_resolver_.rules()->AddIPLiteralRule(host_port_pair_.host(),
|
| + "192.168.0.1", "");
|
| + host_resolver_.rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
|
| + host_resolver_.rules()->AddIPLiteralRule(server3.host(), "192.168.0.1", "");
|
| + host_resolver_.rules()->AddIPLiteralRule(server4.host(), "192.168.0.1", "");
|
| +
|
| + // Test first and fourth out of three timeouts with open streams.
|
| + QuicStreamRequest request(factory_.get());
|
| + EXPECT_EQ(OK, request.Request(host_port_pair_, privacy_mode_,
|
| + /*cert_verify_flags=*/0, url_, "GET", net_log_,
|
| + callback_.callback()));
|
| +
|
| + QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
|
| +
|
| + std::unique_ptr<QuicHttpStream> stream = request.CreateStream();
|
| + EXPECT_TRUE(stream.get());
|
| + HttpRequestInfo request_info;
|
| + EXPECT_EQ(OK, stream->InitializeStream(&request_info, DEFAULT_PRIORITY,
|
| + net_log_, CompletionCallback()));
|
| +
|
| + DVLOG(1)
|
| + << "Created 1st session and initialized a stream. Now trigger timeout";
|
| + session->connection()->CloseConnection(QUIC_NETWORK_IDLE_TIMEOUT, "test",
|
| + ConnectionCloseBehavior::SILENT_CLOSE);
|
| + // Need to spin the loop now to ensure that
|
| + // QuicStreamFactory::OnSessionClosed() runs.
|
| + base::RunLoop run_loop;
|
| + run_loop.RunUntilIdle();
|
| +
|
| + EXPECT_EQ(
|
| + 1, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(factory_.get()));
|
| + EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
|
| + host_port_pair_.port()));
|
| +
|
| + DVLOG(1) << "Create 2nd and 3rd sessions without timeout";
|
| + TestCompletionCallback callback2;
|
| + QuicStreamRequest request2(factory_.get());
|
| + EXPECT_EQ(OK, request2.Request(server2, privacy_mode_,
|
| + /*cert_verify_flags=*/0, url2_, "GET",
|
| + net_log_, callback2.callback()));
|
| + QuicChromiumClientSession* session2 = GetActiveSession(server2);
|
| +
|
| + session2->connection()->CloseConnection(
|
| + QUIC_NO_ERROR, "test", ConnectionCloseBehavior::SILENT_CLOSE);
|
| + // Need to spin the loop now to ensure that
|
| + // QuicStreamFactory::OnSessionClosed() runs.
|
| + base::RunLoop run_loop2;
|
| + run_loop2.RunUntilIdle();
|
| + EXPECT_EQ(
|
| + 1, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(factory_.get()));
|
| + EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
|
| + host_port_pair_.port()));
|
| +
|
| + TestCompletionCallback callback3;
|
| + QuicStreamRequest request3(factory_.get());
|
| + EXPECT_EQ(OK, request3.Request(server3, privacy_mode_,
|
| + /*cert_verify_flags=*/0, url3_, "GET",
|
| + net_log_, callback3.callback()));
|
| + QuicChromiumClientSession* session3 = GetActiveSession(server3);
|
| +
|
| + session3->connection()->CloseConnection(
|
| + QUIC_NO_ERROR, "test", ConnectionCloseBehavior::SILENT_CLOSE);
|
| + // Need to spin the loop now to ensure that
|
| + // QuicStreamFactory::OnSessionClosed() runs.
|
| + base::RunLoop run_loop3;
|
| + run_loop3.RunUntilIdle();
|
| + EXPECT_EQ(
|
| + 1, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(factory_.get()));
|
| + EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
|
| + host_port_pair_.port()));
|
| +
|
| + DVLOG(1) << "Create 4th session with timeout with open streams,"
|
| + << " will not disable QUIC";
|
| +
|
| + TestCompletionCallback callback4;
|
| + QuicStreamRequest request4(factory_.get());
|
| + EXPECT_EQ(OK, request4.Request(server4, privacy_mode_,
|
| + /*cert_verify_flags=*/0, url4_, "GET",
|
| + net_log_, callback4.callback()));
|
| + QuicChromiumClientSession* session4 = GetActiveSession(server4);
|
| +
|
| + std::unique_ptr<QuicHttpStream> stream4 = request4.CreateStream();
|
| + EXPECT_TRUE(stream4.get());
|
| + EXPECT_EQ(OK, stream4->InitializeStream(&request_info, DEFAULT_PRIORITY,
|
| + net_log_, CompletionCallback()));
|
| + session4->connection()->CloseConnection(
|
| + QUIC_NETWORK_IDLE_TIMEOUT, "test", ConnectionCloseBehavior::SILENT_CLOSE);
|
| + // Need to spin the loop now to ensure that
|
| + // QuicStreamFactory::OnSessionClosed() runs.
|
| + base::RunLoop run_loop4;
|
| + run_loop4.RunUntilIdle();
|
| + EXPECT_EQ(
|
| + 1, QuicStreamFactoryPeer::GetNumTimeoutsWithOpenStreams(factory_.get()));
|
| + EXPECT_FALSE(QuicStreamFactoryPeer::IsQuicDisabled(factory_.get(),
|
| + host_port_pair_.port()));
|
| +
|
| + std::unique_ptr<QuicHttpStream> stream2 = request2.CreateStream();
|
| + EXPECT_FALSE(stream2.get()); // Session is already closed.
|
| + std::unique_ptr<QuicHttpStream> stream3 = request3.CreateStream();
|
| + EXPECT_FALSE(stream3.get()); // Session is already closed.
|
| +
|
| + EXPECT_TRUE(socket_data.AllReadDataConsumed());
|
| + EXPECT_TRUE(socket_data.AllWriteDataConsumed());
|
| + EXPECT_TRUE(socket_data2.AllReadDataConsumed());
|
| + EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
|
| + EXPECT_TRUE(socket_data3.AllReadDataConsumed());
|
| + EXPECT_TRUE(socket_data3.AllWriteDataConsumed());
|
| + EXPECT_TRUE(socket_data4.AllReadDataConsumed());
|
| + EXPECT_TRUE(socket_data4.AllWriteDataConsumed());
|
| }
|
|
|
| TEST_P(QuicStreamFactoryTest, EnableDelayTcpRace) {
|
|
|