blob: 1f7a86f82280684af6832e3e68d40d93bee532a4 [file] [log] [blame]
[email protected]e13201d82012-12-12 05:00:321// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Ryan Hamiltona3ee93a72018-08-01 22:03:085#include "net/quic/quic_stream_factory.h"
[email protected]e13201d82012-12-12 05:00:326
avib3635452016-10-21 18:33:537#include <memory>
bnc359ed2a2016-04-29 20:43:458#include <ostream>
bnc086b39e12016-06-24 13:05:269#include <utility>
bnc359ed2a2016-04-29 20:43:4510
msramek992625ec2016-08-04 18:33:5811#include "base/bind.h"
12#include "base/callback.h"
xunjieli48e4f102017-04-11 23:06:5313#include "base/macros.h"
[email protected]e13201d82012-12-12 05:00:3214#include "base/run_loop.h"
[email protected]fc9be5802013-06-11 10:56:5115#include "base/strings/string_util.h"
Zhongyi Shic16b4102019-02-12 00:37:4016#include "base/test/simple_test_tick_clock.h"
Zhongyi Shic4823bd2018-04-27 00:49:1917#include "base/test/test_mock_time_task_runner.h"
Paul Jensen8e3c5d32018-02-19 17:06:3318#include "build/build_config.h"
mgershaf9a9232017-04-13 20:19:0319#include "net/base/mock_network_change_notifier.h"
Matt Menke26e41542019-06-05 01:09:5120#include "net/base/network_isolation_key.h"
rsleevid6de8302016-06-21 01:33:2021#include "net/cert/ct_policy_enforcer.h"
Ryan Sleevi987d2d92017-12-19 19:22:1422#include "net/cert/do_nothing_ct_verifier.h"
23#include "net/cert/mock_cert_verifier.h"
[email protected]f2cb3cf2013-03-21 01:40:5324#include "net/dns/mock_host_resolver.h"
[email protected]e13201d82012-12-12 05:00:3225#include "net/http/http_response_headers.h"
26#include "net/http/http_response_info.h"
rtenneti8332ba52015-09-17 19:33:4127#include "net/http/http_server_properties_impl.h"
[email protected]e13201d82012-12-12 05:00:3228#include "net/http/http_util.h"
[email protected]080b77932014-08-04 01:22:4629#include "net/http/transport_security_state.h"
Matt Mueller230996f12018-10-22 19:39:4430#include "net/http/transport_security_state_test_util.h"
Victor Vasilievbee79ea2019-05-15 01:25:4831#include "net/quic/address_utils.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0832#include "net/quic/crypto/proof_verifier_chromium.h"
33#include "net/quic/mock_crypto_client_stream_factory.h"
34#include "net/quic/mock_quic_data.h"
35#include "net/quic/properties_based_quic_server_info.h"
Renjiea0522f062019-04-29 18:52:2136#include "net/quic/quic_chromium_alarm_factory.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0837#include "net/quic/quic_http_stream.h"
38#include "net/quic/quic_http_utils.h"
39#include "net/quic/quic_server_info.h"
40#include "net/quic/quic_stream_factory_peer.h"
41#include "net/quic/quic_test_packet_maker.h"
42#include "net/quic/test_task_runner.h"
bnc3472afd2016-11-17 15:27:2143#include "net/socket/next_proto.h"
[email protected]e13201d82012-12-12 05:00:3244#include "net/socket/socket_test_util.h"
Bence Béky94658bf2018-05-11 19:22:5845#include "net/spdy/spdy_session_test_util.h"
46#include "net/spdy/spdy_test_util_common.h"
[email protected]eed749f92013-12-23 18:57:3847#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0148#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:4349#include "net/test/test_data_directory.h"
Bence Béky98447b12018-05-08 03:14:0150#include "net/test/test_with_scoped_task_environment.h"
Victor Vasiliev6bb59d22019-03-08 21:34:5151#include "net/third_party/quiche/src/quic/core/crypto/crypto_handshake.h"
52#include "net/third_party/quiche/src/quic/core/crypto/quic_crypto_client_config.h"
53#include "net/third_party/quiche/src/quic/core/crypto/quic_decrypter.h"
54#include "net/third_party/quiche/src/quic/core/crypto/quic_encrypter.h"
55#include "net/third_party/quiche/src/quic/core/http/quic_client_promised_info.h"
56#include "net/third_party/quiche/src/quic/core/quic_utils.h"
57#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
58#include "net/third_party/quiche/src/quic/test_tools/mock_clock.h"
59#include "net/third_party/quiche/src/quic/test_tools/mock_random.h"
60#include "net/third_party/quiche/src/quic/test_tools/quic_config_peer.h"
61#include "net/third_party/quiche/src/quic/test_tools/quic_spdy_session_peer.h"
62#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
Victor Vasiliev27cc7712019-01-24 11:50:1463#include "net/third_party/quiche/src/spdy/core/spdy_test_utils.h"
Ramin Halavati683bcaa92018-02-14 08:42:3964#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
robpercival214763f2016-07-01 23:27:0165#include "testing/gmock/include/gmock/gmock.h"
[email protected]e13201d82012-12-12 05:00:3266#include "testing/gtest/include/gtest/gtest.h"
msramek992625ec2016-08-04 18:33:5867#include "url/gurl.h"
[email protected]e13201d82012-12-12 05:00:3268
[email protected]6e12d702013-11-13 00:17:1769using std::string;
[email protected]6e12d702013-11-13 00:17:1770
[email protected]e13201d82012-12-12 05:00:3271namespace net {
jri7e636642016-01-14 06:57:0872
nharper642ae4b2016-06-30 00:40:3673namespace {
74
75class MockSSLConfigService : public SSLConfigService {
76 public:
77 MockSSLConfigService() {}
Ryan Sleevib8449e02018-07-15 04:31:0778 ~MockSSLConfigService() override {}
nharper642ae4b2016-06-30 00:40:3679
80 void GetSSLConfig(SSLConfig* config) override { *config = config_; }
81
Nick Harper89bc7212018-07-31 19:07:5782 bool CanShareConnectionWithClientCerts(
83 const std::string& hostname) const override {
84 return false;
85 }
86
nharper642ae4b2016-06-30 00:40:3687 private:
nharper642ae4b2016-06-30 00:40:3688 SSLConfig config_;
89};
90
91} // namespace
92
[email protected]e13201d82012-12-12 05:00:3293namespace test {
94
[email protected]3c772402013-12-18 21:38:1195namespace {
bnc359ed2a2016-04-29 20:43:4596
97enum DestinationType {
98 // In pooling tests with two requests for different origins to the same
99 // destination, the destination should be
100 SAME_AS_FIRST, // the same as the first origin,
101 SAME_AS_SECOND, // the same as the second origin, or
102 DIFFERENT, // different from both.
103};
104
rch6faa4d42016-01-05 20:48:43105const char kDefaultServerHostName[] = "www.example.org";
106const char kServer2HostName[] = "mail.example.org";
bnc359ed2a2016-04-29 20:43:45107const char kDifferentHostname[] = "different.example.com";
[email protected]3c772402013-12-18 21:38:11108const int kDefaultServerPort = 443;
ckrasic3865ee0f2016-02-29 22:04:56109const char kDefaultUrl[] = "https://www.example.org/";
110const char kServer2Url[] = "https://mail.example.org/";
111const char kServer3Url[] = "https://docs.example.org/";
112const char kServer4Url[] = "https://images.example.org/";
Zhongyi Shic4823bd2018-04-27 00:49:19113const int kDefaultRTTMilliSecs = 300;
114const size_t kMinRetryTimeForDefaultNetworkSecs = 1;
Zhongyi Shib1b1fa42018-06-19 23:13:47115const size_t kWaitTimeForNewNetworkSecs = 10;
Renjiea0cb4a2c2018-09-26 23:37:30116const IPAddress kCachedIPAddress = IPAddress(192, 168, 0, 2);
117const char kNonCachedIPAddress[] = "192.168.0.1";
rtenneti14abd312015-02-06 21:56:01118
bnc359ed2a2016-04-29 20:43:45119// Run QuicStreamFactoryTest instances with all value combinations of version
120// and enable_connection_racting.
rtenneti14abd312015-02-06 21:56:01121struct TestParams {
bnc359ed2a2016-04-29 20:43:45122 friend std::ostream& operator<<(std::ostream& os, const TestParams& p) {
Nick Harper23290b82019-05-02 00:02:56123 os << "{ version: " << ParsedQuicVersionToString(p.version)
Yixin Wang079ad542018-01-11 04:06:05124 << ", client_headers_include_h2_stream_dependency: "
125 << p.client_headers_include_h2_stream_dependency << " }";
rtenneti14abd312015-02-06 21:56:01126 return os;
127 }
128
Nick Harper23290b82019-05-02 00:02:56129 quic::ParsedQuicVersion version;
Yixin Wang079ad542018-01-11 04:06:05130 bool client_headers_include_h2_stream_dependency;
rtenneti14abd312015-02-06 21:56:01131};
132
rch872e00e2016-12-02 02:48:18133std::vector<TestParams> GetTestParams() {
134 std::vector<TestParams> params;
Nick Harper23290b82019-05-02 00:02:56135 quic::ParsedQuicVersionVector all_supported_versions =
Victor Vasiliev5d6cdc22019-05-28 20:37:43136 quic::AllVersionsExcept99();
Yixin Wang079ad542018-01-11 04:06:05137 for (const auto& version : all_supported_versions) {
138 params.push_back(TestParams{version, false});
139 params.push_back(TestParams{version, true});
140 }
bnc359ed2a2016-04-29 20:43:45141 return params;
142}
143
144// Run QuicStreamFactoryWithDestinationTest instances with all value
145// combinations of version, enable_connection_racting, and destination_type.
146struct PoolingTestParams {
147 friend std::ostream& operator<<(std::ostream& os,
148 const PoolingTestParams& p) {
Nick Harper23290b82019-05-02 00:02:56149 os << "{ version: " << ParsedQuicVersionToString(p.version)
bnc359ed2a2016-04-29 20:43:45150 << ", destination_type: ";
151 switch (p.destination_type) {
152 case SAME_AS_FIRST:
153 os << "SAME_AS_FIRST";
154 break;
155 case SAME_AS_SECOND:
156 os << "SAME_AS_SECOND";
157 break;
158 case DIFFERENT:
159 os << "DIFFERENT";
160 break;
161 }
Yixin Wang079ad542018-01-11 04:06:05162 os << ", client_headers_include_h2_stream_dependency: "
163 << p.client_headers_include_h2_stream_dependency;
bnc359ed2a2016-04-29 20:43:45164 os << " }";
165 return os;
166 }
167
Nick Harper23290b82019-05-02 00:02:56168 quic::ParsedQuicVersion version;
bnc359ed2a2016-04-29 20:43:45169 DestinationType destination_type;
Yixin Wang079ad542018-01-11 04:06:05170 bool client_headers_include_h2_stream_dependency;
bnc359ed2a2016-04-29 20:43:45171};
172
rch872e00e2016-12-02 02:48:18173std::vector<PoolingTestParams> GetPoolingTestParams() {
174 std::vector<PoolingTestParams> params;
Nick Harper23290b82019-05-02 00:02:56175 quic::ParsedQuicVersionVector all_supported_versions =
Victor Vasiliev5d6cdc22019-05-28 20:37:43176 quic::AllVersionsExcept99();
Nick Harper23290b82019-05-02 00:02:56177 for (const quic::ParsedQuicVersion version : all_supported_versions) {
Yixin Wang079ad542018-01-11 04:06:05178 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, false});
179 params.push_back(PoolingTestParams{version, SAME_AS_FIRST, true});
180 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, false});
181 params.push_back(PoolingTestParams{version, SAME_AS_SECOND, true});
182 params.push_back(PoolingTestParams{version, DIFFERENT, false});
183 params.push_back(PoolingTestParams{version, DIFFERENT, true});
rtenneti14abd312015-02-06 21:56:01184 }
185 return params;
186}
187
bnc912a04b2016-04-20 14:19:50188} // namespace
[email protected]3c772402013-12-18 21:38:11189
bnc359ed2a2016-04-29 20:43:45190class QuicHttpStreamPeer {
191 public:
rchf0b18c8a2017-05-05 19:31:57192 static QuicChromiumClientSession::Handle* GetSessionHandle(
193 HttpStream* stream) {
194 return static_cast<QuicHttpStream*>(stream)->quic_session();
bnc359ed2a2016-04-29 20:43:45195 }
196};
197
Zhongyi Shi5f587cc2017-11-21 23:24:17198// TestConnectionMigrationSocketFactory will vend sockets with incremental port
199// number.
200class TestConnectionMigrationSocketFactory : public MockClientSocketFactory {
201 public:
202 TestConnectionMigrationSocketFactory() : next_source_port_num_(1u) {}
203 ~TestConnectionMigrationSocketFactory() override {}
204
205 std::unique_ptr<DatagramClientSocket> CreateDatagramClientSocket(
206 DatagramSocket::BindType bind_type,
Zhongyi Shi5f587cc2017-11-21 23:24:17207 NetLog* net_log,
208 const NetLogSource& source) override {
209 SocketDataProvider* data_provider = mock_data().GetNext();
210 std::unique_ptr<MockUDPClientSocket> socket(
211 new MockUDPClientSocket(data_provider, net_log));
212 socket->set_source_port(next_source_port_num_++);
213 return std::move(socket);
214 }
215
216 private:
217 uint16_t next_source_port_num_;
218
219 DISALLOW_COPY_AND_ASSIGN(TestConnectionMigrationSocketFactory);
220};
221
Bence Béky98447b12018-05-08 03:14:01222class QuicStreamFactoryTestBase : public WithScopedTaskEnvironment {
[email protected]e13201d82012-12-12 05:00:32223 protected:
Nick Harper23290b82019-05-02 00:02:56224 QuicStreamFactoryTestBase(quic::ParsedQuicVersion version,
Yixin Wang079ad542018-01-11 04:06:05225 bool client_headers_include_h2_stream_dependency)
Renjiea0cb4a2c2018-09-26 23:37:30226 : host_resolver_(new MockHostResolver),
227 ssl_config_service_(new MockSSLConfigService),
Zhongyi Shi5f587cc2017-11-21 23:24:17228 socket_factory_(new MockClientSocketFactory),
nharper642ae4b2016-06-30 00:40:36229 random_generator_(0),
rchbf4c26d2017-04-16 23:17:55230 runner_(new TestTaskRunner(&clock_)),
bnc359ed2a2016-04-29 20:43:45231 version_(version),
David Schinazic8281052019-01-24 06:14:17232 client_maker_(
233 version_,
234 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
235 &clock_,
236 kDefaultServerHostName,
237 quic::Perspective::IS_CLIENT,
Zhongyi Shi967d2f12019-02-08 20:58:53238 client_headers_include_h2_stream_dependency),
David Schinazic8281052019-01-24 06:14:17239 server_maker_(
240 version_,
241 quic::QuicUtils::CreateRandomConnectionId(&random_generator_),
242 &clock_,
243 kDefaultServerHostName,
244 quic::Perspective::IS_SERVER,
245 false),
Ryan Sleevi987d2d92017-12-19 19:22:14246 cert_verifier_(std::make_unique<MockCertVerifier>()),
Ryan Sleevi987d2d92017-12-19 19:22:14247 cert_transparency_verifier_(std::make_unique<DoNothingCTVerifier>()),
jri7e636642016-01-14 06:57:08248 scoped_mock_network_change_notifier_(nullptr),
jri7046038f2015-10-22 00:29:26249 factory_(nullptr),
[email protected]bf4ea2f2014-03-10 22:57:53250 host_port_pair_(kDefaultServerHostName, kDefaultServerPort),
ckrasic3865ee0f2016-02-29 22:04:56251 url_(kDefaultUrl),
252 url2_(kServer2Url),
253 url3_(kServer3Url),
254 url4_(kServer4Url),
jri7046038f2015-10-22 00:29:26255 privacy_mode_(PRIVACY_MODE_DISABLED),
Zhongyi Shia6b68d112018-09-24 07:49:03256 failed_on_default_network_callback_(base::BindRepeating(
257 &QuicStreamFactoryTestBase::OnFailedOnDefaultNetwork,
258 base::Unretained(this))),
259 failed_on_default_network_(false),
Zhongyi Shi967d2f12019-02-08 20:58:53260 store_server_configs_in_properties_(false) {
261 test_params_.quic_headers_include_h2_stream_dependency =
262 client_headers_include_h2_stream_dependency;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52263 clock_.AdvanceTime(quic::QuicTime::Delta::FromSeconds(1));
bnc359ed2a2016-04-29 20:43:45264 }
265
jri7046038f2015-10-22 00:29:26266 void Initialize() {
bnc359ed2a2016-04-29 20:43:45267 DCHECK(!factory_);
jri7046038f2015-10-22 00:29:26268 factory_.reset(new QuicStreamFactory(
Renjiea0cb4a2c2018-09-26 23:37:30269 net_log_.net_log(), host_resolver_.get(), ssl_config_service_.get(),
Zhongyi Shi5f587cc2017-11-21 23:24:17270 socket_factory_.get(), &http_server_properties_, cert_verifier_.get(),
Nick Harperecf319d2018-10-16 07:58:54271 &ct_policy_enforcer_, &transport_security_state_,
272 cert_transparency_verifier_.get(),
jri7046038f2015-10-22 00:29:26273 /*SocketPerformanceWatcherFactory*/ nullptr,
rchbf4c26d2017-04-16 23:17:55274 &crypto_client_stream_factory_, &random_generator_, &clock_,
Zhongyi Shi967d2f12019-02-08 20:58:53275 test_params_.quic_max_packet_length, test_params_.quic_user_agent_id,
276 store_server_configs_in_properties_,
277 test_params_.quic_close_sessions_on_ip_change,
278 test_params_.quic_goaway_sessions_on_ip_change,
279 test_params_.mark_quic_broken_when_network_blackholes,
280 test_params_.quic_idle_connection_timeout_seconds,
281 test_params_.quic_reduced_ping_timeout_seconds,
Zhongyi Shie01f2db2019-02-22 19:53:23282 test_params_.quic_retransmittable_on_wire_timeout_milliseconds,
Zhongyi Shi967d2f12019-02-08 20:58:53283 test_params_.quic_max_time_before_crypto_handshake_seconds,
284 test_params_.quic_max_idle_time_before_crypto_handshake_seconds,
285 test_params_.quic_migrate_sessions_on_network_change_v2,
286 test_params_.quic_migrate_sessions_early_v2,
287 test_params_.quic_retry_on_alternate_network_before_handshake,
Zhongyi Shi32fe14d42019-02-28 00:25:36288 test_params_.quic_migrate_idle_sessions,
Zhongyi Shic16b4102019-02-12 00:37:40289 test_params_.quic_idle_session_migration_period,
Zhongyi Shi967d2f12019-02-08 20:58:53290 test_params_.quic_max_time_on_non_default_network,
291 test_params_.quic_max_migrations_to_non_default_network_on_write_error,
292 test_params_
293 .quic_max_migrations_to_non_default_network_on_path_degrading,
294 test_params_.quic_allow_server_migration,
295 test_params_.quic_race_stale_dns_on_connection,
296 test_params_.quic_go_away_on_path_degrading,
297 test_params_.quic_race_cert_verification,
298 test_params_.quic_estimate_initial_rtt,
299 test_params_.quic_headers_include_h2_stream_dependency,
300 test_params_.quic_connection_options,
301 test_params_.quic_client_connection_options,
Renjiea0522f062019-04-29 18:52:21302 test_params_.quic_enable_socket_recv_optimization,
303 test_params_.quic_initial_rtt_for_handshake_milliseconds));
[email protected]e13201d82012-12-12 05:00:32304 }
305
Zhongyi Shi5f587cc2017-11-21 23:24:17306 void InitializeConnectionMigrationV2Test(
307 NetworkChangeNotifier::NetworkList connected_networks) {
308 scoped_mock_network_change_notifier_.reset(
309 new ScopedMockNetworkChangeNotifier());
310 MockNetworkChangeNotifier* mock_ncn =
311 scoped_mock_network_change_notifier_->mock_network_change_notifier();
312 mock_ncn->ForceNetworkHandlesSupported();
313 mock_ncn->SetConnectedNetworksList(connected_networks);
Zhongyi Shi967d2f12019-02-08 20:58:53314 test_params_.quic_migrate_sessions_on_network_change_v2 = true;
315 test_params_.quic_migrate_sessions_early_v2 = true;
Zhongyi Shi5f587cc2017-11-21 23:24:17316 socket_factory_.reset(new TestConnectionMigrationSocketFactory);
317 Initialize();
318 }
319
Yixin Wang7891a39d2017-11-08 20:59:24320 std::unique_ptr<HttpStream> CreateStream(QuicStreamRequest* request) {
321 std::unique_ptr<QuicChromiumClientSession::Handle> session =
322 request->ReleaseSessionHandle();
323 if (!session || !session->IsConnected())
324 return nullptr;
325
326 return std::make_unique<QuicHttpStream>(std::move(session));
327 }
328
bnccb7ff3c2015-05-21 20:51:55329 bool HasActiveSession(const HostPortPair& host_port_pair) {
Ryan Hamilton4f0b26e2018-06-27 23:52:32330 quic::QuicServerId server_id(host_port_pair.host(), host_port_pair.port(),
331 false);
bnc5fdc07162016-05-23 17:36:03332 return QuicStreamFactoryPeer::HasActiveSession(factory_.get(), server_id);
bnccb7ff3c2015-05-21 20:51:55333 }
334
Renjiea0cb4a2c2018-09-26 23:37:30335 bool HasLiveSession(const HostPortPair& host_port_pair) {
336 quic::QuicServerId server_id(host_port_pair.host(), host_port_pair.port(),
337 false);
338 return QuicStreamFactoryPeer::HasLiveSession(factory_.get(), host_port_pair,
339 server_id);
340 }
341
zhongyi363c91c2017-03-23 23:16:08342 bool HasActiveJob(const HostPortPair& host_port_pair,
343 const PrivacyMode privacy_mode) {
Ryan Hamilton4f0b26e2018-06-27 23:52:32344 quic::QuicServerId server_id(host_port_pair.host(), host_port_pair.port(),
345 privacy_mode == PRIVACY_MODE_ENABLED);
zhongyi363c91c2017-03-23 23:16:08346 return QuicStreamFactoryPeer::HasActiveJob(factory_.get(), server_id);
347 }
348
Ryan Hamilton8d9ee76e2018-05-29 23:52:52349 bool HasActiveCertVerifierJob(const quic::QuicServerId& server_id) {
rtennetid073dd22016-08-04 01:58:33350 return QuicStreamFactoryPeer::HasActiveCertVerifierJob(factory_.get(),
351 server_id);
352 }
353
Zhongyi Shic1449372018-08-09 09:58:58354 // Get the pending, not activated session, if there is only one session alive.
355 QuicChromiumClientSession* GetPendingSession(
356 const HostPortPair& host_port_pair) {
357 quic::QuicServerId server_id(host_port_pair.host(), host_port_pair.port(),
358 false);
359 return QuicStreamFactoryPeer::GetPendingSession(factory_.get(), server_id,
360 host_port_pair);
361 }
362
bnc912a04b2016-04-20 14:19:50363 QuicChromiumClientSession* GetActiveSession(
364 const HostPortPair& host_port_pair) {
Ryan Hamilton4f0b26e2018-06-27 23:52:32365 quic::QuicServerId server_id(host_port_pair.host(), host_port_pair.port(),
366 false);
bnc5fdc07162016-05-23 17:36:03367 return QuicStreamFactoryPeer::GetActiveSession(factory_.get(), server_id);
bnc912a04b2016-04-20 14:19:50368 }
369
[email protected]bf4ea2f2014-03-10 22:57:53370 int GetSourcePortForNewSession(const HostPortPair& destination) {
[email protected]d8e2abf82014-03-06 10:30:10371 return GetSourcePortForNewSessionInner(destination, false);
372 }
373
rjshaded5ced072015-12-18 19:26:02374 int GetSourcePortForNewSessionAndGoAway(const HostPortPair& destination) {
[email protected]d8e2abf82014-03-06 10:30:10375 return GetSourcePortForNewSessionInner(destination, true);
376 }
377
[email protected]bf4ea2f2014-03-10 22:57:53378 int GetSourcePortForNewSessionInner(const HostPortPair& destination,
[email protected]d8e2abf82014-03-06 10:30:10379 bool goaway_received) {
[email protected]3c772402013-12-18 21:38:11380 // Should only be called if there is no active session for this destination.
bnccb7ff3c2015-05-21 20:51:55381 EXPECT_FALSE(HasActiveSession(destination));
Zhongyi Shi5f587cc2017-11-21 23:24:17382 size_t socket_count = socket_factory_->udp_client_socket_ports().size();
[email protected]3c772402013-12-18 21:38:11383
Ryan Hamiltonabad59e2019-06-06 04:02:59384 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:36385 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:43386 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:17387 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]3c772402013-12-18 21:38:11388
zhongyi98d6a9262017-05-19 02:47:45389 QuicStreamRequest request(factory_.get());
ckrasic3865ee0f2016-02-29 22:04:56390 GURL url("https://" + destination.host() + "/");
Nick Harper23290b82019-05-02 00:02:56391 EXPECT_EQ(ERR_IO_PENDING,
392 request.Request(
393 destination, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:51394 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Nick Harper23290b82019-05-02 00:02:56395 /*cert_verify_flags=*/0, url, net_log_, &net_error_details_,
396 failed_on_default_network_callback_, callback_.callback()));
[email protected]3c772402013-12-18 21:38:11397
robpercival214763f2016-07-01 23:27:01398 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:24399 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]3c772402013-12-18 21:38:11400 EXPECT_TRUE(stream.get());
401 stream.reset();
402
bnc912a04b2016-04-20 14:19:50403 QuicChromiumClientSession* session = GetActiveSession(destination);
[email protected]3c772402013-12-18 21:38:11404
Zhongyi Shi5f587cc2017-11-21 23:24:17405 if (socket_count + 1 != socket_factory_->udp_client_socket_ports().size()) {
mmenke651bae7f2015-12-18 21:26:45406 ADD_FAILURE();
[email protected]3c772402013-12-18 21:38:11407 return 0;
408 }
409
[email protected]d8e2abf82014-03-06 10:30:10410 if (goaway_received) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:52411 quic::QuicGoAwayFrame goaway(quic::kInvalidControlFrameId,
412 quic::QUIC_NO_ERROR, 1, "");
rtenneti9bd5d4b2015-08-21 05:44:52413 session->connection()->OnGoAwayFrame(goaway);
[email protected]d8e2abf82014-03-06 10:30:10414 }
[email protected]3c772402013-12-18 21:38:11415
jri7046038f2015-10-22 00:29:26416 factory_->OnSessionClosed(session);
bnccb7ff3c2015-05-21 20:51:55417 EXPECT_FALSE(HasActiveSession(destination));
rch37de576c2015-05-17 20:28:17418 EXPECT_TRUE(socket_data.AllReadDataConsumed());
419 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
Zhongyi Shi5f587cc2017-11-21 23:24:17420 return socket_factory_->udp_client_socket_ports()[socket_count];
[email protected]3c772402013-12-18 21:38:11421 }
422
Ryan Hamilton8d9ee76e2018-05-29 23:52:52423 std::unique_ptr<quic::QuicEncryptedPacket>
Fan Yangac867502019-01-28 21:10:23424 ConstructClientConnectionClosePacket(uint64_t num) {
Bin Wu5311aca2018-01-22 01:19:03425 return client_maker_.MakeConnectionClosePacket(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52426 num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
rtenneti1cd3b162015-09-29 02:58:28427 }
428
Ryan Hamilton8d9ee76e2018-05-29 23:52:52429 std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientRstPacket(
Fan Yangac867502019-01-28 21:10:23430 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52431 quic::QuicRstStreamErrorCode error_code) {
Fan Yang32c5a112018-12-10 20:06:33432 quic::QuicStreamId stream_id =
433 GetNthClientInitiatedBidirectionalStreamId(0);
fayang3bcb8b502016-12-07 21:44:37434 return client_maker_.MakeRstPacket(packet_number, true, stream_id,
Jana Iyengarba355772017-09-21 22:03:21435 error_code);
fayang3bcb8b502016-12-07 21:44:37436 }
437
bncf8bf0722015-05-19 20:04:13438 static ProofVerifyDetailsChromium DefaultProofVerifyDetails() {
rch6faa4d42016-01-05 20:48:43439 // Load a certificate that is valid for *.example.org
bncf8bf0722015-05-19 20:04:13440 scoped_refptr<X509Certificate> test_cert(
rch6faa4d42016-01-05 20:48:43441 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
bncf8bf0722015-05-19 20:04:13442 EXPECT_TRUE(test_cert.get());
443 ProofVerifyDetailsChromium verify_details;
444 verify_details.cert_verify_result.verified_cert = test_cert;
445 verify_details.cert_verify_result.is_issued_by_known_root = true;
446 return verify_details;
447 }
448
jri8c44d692015-10-23 23:53:41449 void NotifyIPAddressChanged() {
450 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
jri7e636642016-01-14 06:57:08451 // Spin the message loop so the notification is delivered.
fdoray92e35a72016-06-10 15:54:55452 base::RunLoop().RunUntilIdle();
jri8c44d692015-10-23 23:53:41453 }
454
Ryan Hamilton8d9ee76e2018-05-29 23:52:52455 std::unique_ptr<quic::QuicEncryptedPacket> ConstructGetRequestPacket(
Fan Yangac867502019-01-28 21:10:23456 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52457 quic::QuicStreamId stream_id,
jri7e636642016-01-14 06:57:08458 bool should_include_version,
459 bool fin) {
Ryan Hamilton0239aac2018-05-19 00:03:13460 spdy::SpdyHeaderBlock headers =
alyssar2adf3ac2016-05-03 17:12:58461 client_maker_.GetRequestHeaders("GET", "https", "/");
Ryan Hamilton0239aac2018-05-19 00:03:13462 spdy::SpdyPriority priority =
jri7e636642016-01-14 06:57:08463 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
464 size_t spdy_headers_frame_len;
alyssar2adf3ac2016-05-03 17:12:58465 return client_maker_.MakeRequestHeadersPacket(
jri7e636642016-01-14 06:57:08466 packet_number, stream_id, should_include_version, fin, priority,
Yixin Wang7a3f1b8d2018-01-17 21:40:48467 std::move(headers), 0, &spdy_headers_frame_len);
jri7e636642016-01-14 06:57:08468 }
469
Ryan Hamilton8d9ee76e2018-05-29 23:52:52470 std::unique_ptr<quic::QuicEncryptedPacket> ConstructGetRequestPacket(
Fan Yangac867502019-01-28 21:10:23471 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52472 quic::QuicStreamId stream_id,
Zhongyi Shi3c4c9e92018-07-02 23:16:23473 quic::QuicStreamId parent_stream_id,
fayang3bcb8b502016-12-07 21:44:37474 bool should_include_version,
475 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52476 quic::QuicStreamOffset* offset) {
Ryan Hamilton0239aac2018-05-19 00:03:13477 spdy::SpdyHeaderBlock headers =
fayang3bcb8b502016-12-07 21:44:37478 client_maker_.GetRequestHeaders("GET", "https", "/");
Ryan Hamilton0239aac2018-05-19 00:03:13479 spdy::SpdyPriority priority =
fayang3bcb8b502016-12-07 21:44:37480 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
481 size_t spdy_headers_frame_len;
482 return client_maker_.MakeRequestHeadersPacket(
483 packet_number, stream_id, should_include_version, fin, priority,
Zhongyi Shi3c4c9e92018-07-02 23:16:23484 std::move(headers), parent_stream_id, &spdy_headers_frame_len, offset);
485 }
486
487 std::unique_ptr<quic::QuicEncryptedPacket> ConstructGetRequestPacket(
Fan Yangac867502019-01-28 21:10:23488 uint64_t packet_number,
Zhongyi Shi3c4c9e92018-07-02 23:16:23489 quic::QuicStreamId stream_id,
490 bool should_include_version,
491 bool fin,
492 quic::QuicStreamOffset* offset) {
493 return ConstructGetRequestPacket(packet_number, stream_id,
494 /*parent_stream_id=*/0,
495 should_include_version, fin, offset);
fayang3bcb8b502016-12-07 21:44:37496 }
497
Ryan Hamilton8d9ee76e2018-05-29 23:52:52498 std::unique_ptr<quic::QuicEncryptedPacket> ConstructOkResponsePacket(
Fan Yangac867502019-01-28 21:10:23499 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52500 quic::QuicStreamId stream_id,
jri7e636642016-01-14 06:57:08501 bool should_include_version,
502 bool fin) {
Ryan Hamilton0239aac2018-05-19 00:03:13503 spdy::SpdyHeaderBlock headers = server_maker_.GetResponseHeaders("200 OK");
jri7e636642016-01-14 06:57:08504 size_t spdy_headers_frame_len;
alyssar2adf3ac2016-05-03 17:12:58505 return server_maker_.MakeResponseHeadersPacket(
bnc086b39e12016-06-24 13:05:26506 packet_number, stream_id, should_include_version, fin,
507 std::move(headers), &spdy_headers_frame_len);
jri7e636642016-01-14 06:57:08508 }
509
Ryan Hamilton8d9ee76e2018-05-29 23:52:52510 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket() {
rch5cb522462017-04-25 20:18:36511 return client_maker_.MakeInitialSettingsPacket(1, nullptr);
512 }
513
Ryan Hamilton8d9ee76e2018-05-29 23:52:52514 std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
Fan Yangac867502019-01-28 21:10:23515 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52516 quic::QuicStreamOffset* offset) {
rch5cb522462017-04-25 20:18:36517 return client_maker_.MakeInitialSettingsPacket(packet_number, offset);
fayang3bcb8b502016-12-07 21:44:37518 }
519
jri053fdbd2016-08-19 02:33:05520 // Helper method for server migration tests.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52521 void VerifyServerMigration(const quic::QuicConfig& config,
bnc6a0348c2017-05-22 18:56:19522 IPEndPoint expected_address) {
Zhongyi Shi967d2f12019-02-08 20:58:53523 test_params_.quic_allow_server_migration = true;
jri053fdbd2016-08-19 02:33:05524 Initialize();
525
526 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
527 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri053fdbd2016-08-19 02:33:05528 crypto_client_stream_factory_.SetConfig(config);
529
530 // Set up first socket data provider.
Ryan Hamiltonabad59e2019-06-06 04:02:59531 MockQuicData socket_data1(version_);
rcha00569732016-08-27 11:09:36532 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5f587cc2017-11-21 23:24:17533 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri053fdbd2016-08-19 02:33:05534
rcha00569732016-08-27 11:09:36535 // Set up second socket data provider that is used after
536 // migration.
Ryan Hamiltonabad59e2019-06-06 04:02:59537 MockQuicData socket_data2(version_);
rcha00569732016-08-27 11:09:36538 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:43539 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
fayang3bcb8b502016-12-07 21:44:37540 socket_data2.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:43541 SYNCHRONOUS, client_maker_.MakePingPacket(2, /*include_version=*/true));
542 socket_data2.AddWrite(
Fan Yang32c5a112018-12-10 20:06:33543 SYNCHRONOUS, client_maker_.MakeRstPacket(
544 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
545 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:17546 socket_data2.AddSocketDataToFactory(socket_factory_.get());
jri053fdbd2016-08-19 02:33:05547
548 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:45549 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:33550 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:03551 request.Request(
Nick Harper23290b82019-05-02 00:02:56552 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:51553 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:03554 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
555 failed_on_default_network_callback_, callback_.callback()));
jri053fdbd2016-08-19 02:33:05556 EXPECT_EQ(OK, callback_.WaitForResult());
bnceb9aa7112017-01-05 01:03:46557
558 // Run QuicChromiumClientSession::WriteToNewSocket()
559 // posted by QuicChromiumClientSession::MigrateToSocket().
560 base::RunLoop().RunUntilIdle();
561
Yixin Wang7891a39d2017-11-08 20:59:24562 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri053fdbd2016-08-19 02:33:05563 EXPECT_TRUE(stream.get());
564
565 // Cause QUIC stream to be created.
566 HttpRequestInfo request_info;
567 request_info.method = "GET";
568 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:39569 request_info.traffic_annotation =
570 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:27571 EXPECT_EQ(OK,
572 stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:39573 net_log_, CompletionOnceCallback()));
jri053fdbd2016-08-19 02:33:05574 // Ensure that session is alive and active.
575 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
576 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
577 EXPECT_TRUE(HasActiveSession(host_port_pair_));
578
579 IPEndPoint actual_address;
580 session->GetDefaultSocket()->GetPeerAddress(&actual_address);
581 EXPECT_EQ(actual_address, expected_address);
582 DVLOG(1) << "Socket connected to: " << actual_address.address().ToString()
583 << " " << actual_address.port();
584 DVLOG(1) << "Expected address: " << expected_address.address().ToString()
585 << " " << expected_address.port();
586
587 stream.reset();
588 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
589 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
590 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
591 }
592
tbansal3b966952016-10-25 23:25:14593 // Verifies that the QUIC stream factory is initialized correctly.
tbansal9b1cdf32017-05-10 17:28:39594 void VerifyInitialization() {
rch431dd4452017-04-19 15:22:35595 store_server_configs_in_properties_ = true;
Zhongyi Shi967d2f12019-02-08 20:58:53596 test_params_.quic_idle_connection_timeout_seconds = 500;
tbansal3b966952016-10-25 23:25:14597 Initialize();
Ryan Hamiltona12722b2017-08-12 02:23:20598 factory_->set_require_confirmation(false);
tbansal3b966952016-10-25 23:25:14599 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
600 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
rch431dd4452017-04-19 15:22:35601 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
602 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:27603 MockCryptoClientStream::ZERO_RTT);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52604 const quic::QuicConfig* config =
605 QuicStreamFactoryPeer::GetConfig(factory_.get());
ckrasic32b17dcd2016-10-31 06:15:35606 EXPECT_EQ(500, config->IdleNetworkTimeout().ToSeconds());
tbansal3b966952016-10-25 23:25:14607
608 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
609
bnc3472afd2016-11-17 15:27:21610 const AlternativeService alternative_service1(
611 kProtoQUIC, host_port_pair_.host(), host_port_pair_.port());
tbansal3b966952016-10-25 23:25:14612 AlternativeServiceInfoVector alternative_service_info_vector;
613 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
614 alternative_service_info_vector.push_back(
zhongyie537a002017-06-27 16:48:21615 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
616 alternative_service1, expiration, {version_}));
tbansal3b966952016-10-25 23:25:14617 http_server_properties_.SetAlternativeServices(
618 url::SchemeHostPort(url_), alternative_service_info_vector);
619
620 HostPortPair host_port_pair2(kServer2HostName, kDefaultServerPort);
621 url::SchemeHostPort server2("https", kServer2HostName, kDefaultServerPort);
bnc3472afd2016-11-17 15:27:21622 const AlternativeService alternative_service2(
623 kProtoQUIC, host_port_pair2.host(), host_port_pair2.port());
tbansal3b966952016-10-25 23:25:14624 AlternativeServiceInfoVector alternative_service_info_vector2;
625 alternative_service_info_vector2.push_back(
zhongyie537a002017-06-27 16:48:21626 AlternativeServiceInfo::CreateQuicAlternativeServiceInfo(
627 alternative_service2, expiration, {version_}));
tbansal9b1cdf32017-05-10 17:28:39628
629 http_server_properties_.SetAlternativeServices(
630 server2, alternative_service_info_vector2);
631 // Verify that the properties of both QUIC servers are stored in the
632 // HTTP properties map.
633 EXPECT_EQ(2U, http_server_properties_.alternative_service_map().size());
tbansal3b966952016-10-25 23:25:14634
635 http_server_properties_.SetMaxServerConfigsStoredInProperties(
Yixin Wang4a227aa22017-11-30 21:33:01636 kDefaultMaxQuicServerEntries);
tbansal3b966952016-10-25 23:25:14637
Ryan Hamilton8d9ee76e2018-05-29 23:52:52638 quic::QuicServerId quic_server_id(kDefaultServerHostName, 443,
639 PRIVACY_MODE_DISABLED);
rch431dd4452017-04-19 15:22:35640 std::unique_ptr<QuicServerInfo> quic_server_info =
Jeremy Roman0579ed62017-08-29 15:56:19641 std::make_unique<PropertiesBasedQuicServerInfo>(
rch431dd4452017-04-19 15:22:35642 quic_server_id, &http_server_properties_);
tbansal3b966952016-10-25 23:25:14643
644 // Update quic_server_info's server_config and persist it.
645 QuicServerInfo::State* state = quic_server_info->mutable_state();
646 // Minimum SCFG that passes config validation checks.
647 const char scfg[] = {// SCFG
648 0x53, 0x43, 0x46, 0x47,
649 // num entries
650 0x01, 0x00,
651 // padding
652 0x00, 0x00,
653 // EXPY
654 0x45, 0x58, 0x50, 0x59,
655 // EXPY end offset
656 0x08, 0x00, 0x00, 0x00,
657 // Value
658 '1', '2', '3', '4', '5', '6', '7', '8'};
659
660 // Create temporary strings becasue Persist() clears string data in |state|.
661 string server_config(reinterpret_cast<const char*>(&scfg), sizeof(scfg));
662 string source_address_token("test_source_address_token");
663 string cert_sct("test_cert_sct");
664 string chlo_hash("test_chlo_hash");
665 string signature("test_signature");
666 string test_cert("test_cert");
rch872e00e2016-12-02 02:48:18667 std::vector<string> certs;
tbansal3b966952016-10-25 23:25:14668 certs.push_back(test_cert);
669 state->server_config = server_config;
670 state->source_address_token = source_address_token;
671 state->cert_sct = cert_sct;
672 state->chlo_hash = chlo_hash;
673 state->server_config_sig = signature;
674 state->certs = certs;
675
676 quic_server_info->Persist();
677
Ryan Hamilton8d9ee76e2018-05-29 23:52:52678 quic::QuicServerId quic_server_id2(kServer2HostName, 443,
679 PRIVACY_MODE_DISABLED);
rch431dd4452017-04-19 15:22:35680 std::unique_ptr<QuicServerInfo> quic_server_info2 =
Jeremy Roman0579ed62017-08-29 15:56:19681 std::make_unique<PropertiesBasedQuicServerInfo>(
rch431dd4452017-04-19 15:22:35682 quic_server_id2, &http_server_properties_);
tbansal3b966952016-10-25 23:25:14683 // Update quic_server_info2's server_config and persist it.
684 QuicServerInfo::State* state2 = quic_server_info2->mutable_state();
685
686 // Minimum SCFG that passes config validation checks.
687 const char scfg2[] = {// SCFG
688 0x53, 0x43, 0x46, 0x47,
689 // num entries
690 0x01, 0x00,
691 // padding
692 0x00, 0x00,
693 // EXPY
694 0x45, 0x58, 0x50, 0x59,
695 // EXPY end offset
696 0x08, 0x00, 0x00, 0x00,
697 // Value
698 '8', '7', '3', '4', '5', '6', '2', '1'};
699
700 // Create temporary strings becasue Persist() clears string data in
701 // |state2|.
702 string server_config2(reinterpret_cast<const char*>(&scfg2), sizeof(scfg2));
703 string source_address_token2("test_source_address_token2");
704 string cert_sct2("test_cert_sct2");
705 string chlo_hash2("test_chlo_hash2");
706 string signature2("test_signature2");
707 string test_cert2("test_cert2");
rch872e00e2016-12-02 02:48:18708 std::vector<string> certs2;
tbansal3b966952016-10-25 23:25:14709 certs2.push_back(test_cert2);
710 state2->server_config = server_config2;
711 state2->source_address_token = source_address_token2;
712 state2->cert_sct = cert_sct2;
713 state2->chlo_hash = chlo_hash2;
714 state2->server_config_sig = signature2;
715 state2->certs = certs2;
716
717 quic_server_info2->Persist();
718
tbansal3b966952016-10-25 23:25:14719 // Verify the MRU order is maintained.
720 const QuicServerInfoMap& quic_server_info_map =
721 http_server_properties_.quic_server_info_map();
722 EXPECT_EQ(2u, quic_server_info_map.size());
jdoerrie22a91d8b92018-10-05 08:43:26723 auto quic_server_info_map_it = quic_server_info_map.begin();
tbansal3b966952016-10-25 23:25:14724 EXPECT_EQ(quic_server_info_map_it->first, quic_server_id2);
725 ++quic_server_info_map_it;
726 EXPECT_EQ(quic_server_info_map_it->first, quic_server_id);
727
Renjiea0cb4a2c2018-09-26 23:37:30728 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
729 "192.168.0.1", "");
rch431dd4452017-04-19 15:22:35730
731 // Create a session and verify that the cached state is loaded.
Ryan Hamiltonabad59e2019-06-06 04:02:59732 MockQuicData socket_data(version_);
rch431dd4452017-04-19 15:22:35733 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5f587cc2017-11-21 23:24:17734 socket_data.AddSocketDataToFactory(socket_factory_.get());
rch431dd4452017-04-19 15:22:35735
zhongyi98d6a9262017-05-19 02:47:45736 QuicStreamRequest request(factory_.get());
Yixin Wang247ea642017-11-15 01:15:50737 EXPECT_EQ(ERR_IO_PENDING,
Ryan Hamilton4f0b26e2018-06-27 23:52:32738 request.Request(
739 HostPortPair(quic_server_id.host(), quic_server_id.port()),
Nick Harper23290b82019-05-02 00:02:56740 version_.transport_version, privacy_mode_, DEFAULT_PRIORITY,
Matt Menke26e41542019-06-05 01:09:51741 SocketTag(), NetworkIsolationKey(),
Ryan Hamilton4f0b26e2018-06-27 23:52:32742 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
Zhongyi Shia6b68d112018-09-24 07:49:03743 failed_on_default_network_callback_, callback_.callback()));
rch431dd4452017-04-19 15:22:35744 EXPECT_THAT(callback_.WaitForResult(), IsOk());
745
tbansal3b966952016-10-25 23:25:14746 EXPECT_FALSE(QuicStreamFactoryPeer::CryptoConfigCacheIsEmpty(
747 factory_.get(), quic_server_id));
Ryan Hamilton8d9ee76e2018-05-29 23:52:52748 quic::QuicCryptoClientConfig* crypto_config =
tbansal3b966952016-10-25 23:25:14749 QuicStreamFactoryPeer::GetCryptoConfig(factory_.get());
Ryan Hamilton8d9ee76e2018-05-29 23:52:52750 quic::QuicCryptoClientConfig::CachedState* cached =
tbansal3b966952016-10-25 23:25:14751 crypto_config->LookupOrCreate(quic_server_id);
752 EXPECT_FALSE(cached->server_config().empty());
753 EXPECT_TRUE(cached->GetServerConfig());
754 EXPECT_EQ(server_config, cached->server_config());
755 EXPECT_EQ(source_address_token, cached->source_address_token());
756 EXPECT_EQ(cert_sct, cached->cert_sct());
757 EXPECT_EQ(chlo_hash, cached->chlo_hash());
758 EXPECT_EQ(signature, cached->signature());
759 ASSERT_EQ(1U, cached->certs().size());
760 EXPECT_EQ(test_cert, cached->certs()[0]);
761
rch431dd4452017-04-19 15:22:35762 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
763
764 // Create a session and verify that the cached state is loaded.
Ryan Hamiltonabad59e2019-06-06 04:02:59765 MockQuicData socket_data2(version_);
rch431dd4452017-04-19 15:22:35766 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5f587cc2017-11-21 23:24:17767 socket_data2.AddSocketDataToFactory(socket_factory_.get());
rch431dd4452017-04-19 15:22:35768
Renjiea0cb4a2c2018-09-26 23:37:30769 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
770 "192.168.0.2", "");
rch431dd4452017-04-19 15:22:35771
zhongyi98d6a9262017-05-19 02:47:45772 QuicStreamRequest request2(factory_.get());
rch431dd4452017-04-19 15:22:35773 EXPECT_EQ(ERR_IO_PENDING,
Ryan Hamilton4f0b26e2018-06-27 23:52:32774 request2.Request(
775 HostPortPair(quic_server_id2.host(), quic_server_id2.port()),
Nick Harper23290b82019-05-02 00:02:56776 version_.transport_version, privacy_mode_, DEFAULT_PRIORITY,
Matt Menke26e41542019-06-05 01:09:51777 SocketTag(), NetworkIsolationKey(),
Ryan Hamilton4f0b26e2018-06-27 23:52:32778 /*cert_verify_flags=*/0, GURL("https://mail.example.org/"),
Zhongyi Shia6b68d112018-09-24 07:49:03779 net_log_, &net_error_details_,
780 failed_on_default_network_callback_, callback_.callback()));
rch431dd4452017-04-19 15:22:35781 EXPECT_THAT(callback_.WaitForResult(), IsOk());
782
tbansal3b966952016-10-25 23:25:14783 EXPECT_FALSE(QuicStreamFactoryPeer::CryptoConfigCacheIsEmpty(
784 factory_.get(), quic_server_id2));
Ryan Hamilton8d9ee76e2018-05-29 23:52:52785 quic::QuicCryptoClientConfig::CachedState* cached2 =
tbansal3b966952016-10-25 23:25:14786 crypto_config->LookupOrCreate(quic_server_id2);
787 EXPECT_FALSE(cached2->server_config().empty());
788 EXPECT_TRUE(cached2->GetServerConfig());
789 EXPECT_EQ(server_config2, cached2->server_config());
790 EXPECT_EQ(source_address_token2, cached2->source_address_token());
791 EXPECT_EQ(cert_sct2, cached2->cert_sct());
792 EXPECT_EQ(chlo_hash2, cached2->chlo_hash());
793 EXPECT_EQ(signature2, cached2->signature());
794 ASSERT_EQ(1U, cached->certs().size());
795 EXPECT_EQ(test_cert2, cached2->certs()[0]);
796 }
797
jri5b785512016-09-13 04:29:11798 void RunTestLoopUntilIdle() {
799 while (!runner_->GetPostedTasks().empty())
800 runner_->RunNextTask();
801 }
802
Fan Yang32c5a112018-12-10 20:06:33803 quic::QuicStreamId GetNthClientInitiatedBidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:56804 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
805 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36806 }
807
Zhongyi Shi99d0cdd2019-05-21 01:18:42808 std::string ConstructDataHeader(size_t body_len) {
809 if (version_.transport_version != quic::QUIC_VERSION_99) {
810 return "";
811 }
812 quic::HttpEncoder encoder;
813 std::unique_ptr<char[]> buffer;
814 auto header_length = encoder.SerializeDataFrameHeader(body_len, &buffer);
815 return std::string(buffer.get(), header_length);
816 }
817
818 std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
819 uint64_t packet_number,
820 quic::QuicStreamId stream_id,
821 bool should_include_version,
822 bool fin,
823 quic::QuicStreamOffset offset,
824 quic::QuicStringPiece data) {
825 return server_maker_.MakeDataPacket(
826 packet_number, stream_id, should_include_version, fin, offset, data);
827 }
828
Fan Yang32c5a112018-12-10 20:06:33829 quic::QuicStreamId GetNthServerInitiatedUnidirectionalStreamId(int n) {
Nick Harper23290b82019-05-02 00:02:56830 return quic::test::GetNthServerInitiatedUnidirectionalStreamId(
831 version_.transport_version, n);
ckrasicbf2f59c2017-05-04 23:54:36832 }
833
Zhongyi Shia6b68d112018-09-24 07:49:03834 void OnFailedOnDefaultNetwork(int rv) { failed_on_default_network_ = true; }
835
jri9f303712016-09-13 01:10:22836 // Helper methods for tests of connection migration on write error.
Zhongyi Shi32fe14d42019-02-28 00:25:36837 void TestMigrationOnWriteErrorNonMigratableStream(IoMode write_error_mode,
838 bool migrate_idle_sessions);
Zhongyi Shi0439ecc72018-07-11 04:41:26839 // Migratable stream triggers write error.
840 void TestMigrationOnWriteErrorMixedStreams(IoMode write_error_mode);
841 // Non-migratable stream triggers write error.
842 void TestMigrationOnWriteErrorMixedStreams2(IoMode write_error_mode);
jri9f303712016-09-13 01:10:22843 void TestMigrationOnWriteErrorMigrationDisabled(IoMode write_error_mode);
844 void TestMigrationOnWriteError(IoMode write_error_mode);
Zhongyi Shi0439ecc72018-07-11 04:41:26845 void TestMigrationOnWriteErrorWithMultipleRequests(IoMode write_error_mode);
jri9f303712016-09-13 01:10:22846 void TestMigrationOnWriteErrorNoNewNetwork(IoMode write_error_mode);
Zhongyi Shi7f1d9212018-06-22 23:24:36847 void TestMigrationOnMultipleWriteErrors(
848 IoMode write_error_mode_on_old_network,
849 IoMode write_error_mode_on_new_network);
Zhongyi Shib24001c02018-06-18 20:01:52850 void TestMigrationOnNetworkNotificationWithWriteErrorQueuedLater(
851 bool disconnected);
Zhongyi Shi1e2bc742018-06-16 02:06:07852 void TestMigrationOnWriteErrorWithNotificationQueuedLater(bool disconnected);
Zhongyi Shi9f316b262018-06-18 22:01:16853 void TestMigrationOnNetworkDisconnected(bool async_write_before);
Zhongyi Shia0644e32018-06-21 05:19:52854 void TestMigrationOnNetworkMadeDefault(IoMode write_mode);
Zhongyi Shi22fd5f52018-06-20 17:39:09855 void TestMigrationOnPathDegrading(bool async_write_before);
Zhongyi Shib3bc982c2018-07-10 19:59:24856 void TestMigrateSessionWithDrainingStream(
857 IoMode write_mode_for_queued_packet);
jri5b785512016-09-13 04:29:11858 void TestMigrationOnWriteErrorPauseBeforeConnected(IoMode write_error_mode);
Zhongyi Shi4ac9e1f2018-06-21 05:21:47859 void TestMigrationOnWriteErrorWithMultipleNotifications(
jri5b785512016-09-13 04:29:11860 IoMode write_error_mode,
Zhongyi Shi4ac9e1f2018-06-21 05:21:47861 bool disconnect_before_connect);
Zhongyi Shi634c1882018-08-16 04:05:59862 void TestNoAlternateNetworkBeforeHandshake(quic::QuicErrorCode error);
Zhongyi Shi8de43832018-08-15 23:40:00863 void TestNewConnectionOnAlternateNetworkBeforeHandshake(
864 quic::QuicErrorCode error);
Zhongyi Shi32fe14d42019-02-28 00:25:36865 void TestOnNetworkMadeDefaultNonMigratableStream(bool migrate_idle_sessions);
866 void TestMigrateSessionEarlyNonMigratableStream(bool migrate_idle_sessions);
867 void TestOnNetworkDisconnectedNoOpenStreams(bool migrate_idle_sessions);
868 void TestOnNetworkMadeDefaultNoOpenStreams(bool migrate_idle_sessions);
869 void TestOnNetworkDisconnectedNonMigratableStream(bool migrate_idle_sessions);
jri9f303712016-09-13 01:10:22870
Jana Iyengarf6b13d82017-09-04 02:09:10871 QuicFlagSaver flags_; // Save/restore all QUIC flag values.
Renjiea0cb4a2c2018-09-26 23:37:30872 std::unique_ptr<MockHostResolverBase> host_resolver_;
Ryan Sleevib8449e02018-07-15 04:31:07873 std::unique_ptr<SSLConfigService> ssl_config_service_;
Zhongyi Shi5f587cc2017-11-21 23:24:17874 std::unique_ptr<MockClientSocketFactory> socket_factory_;
[email protected]e8ff26842013-03-22 21:02:05875 MockCryptoClientStreamFactory crypto_client_stream_factory_;
Ryan Hamilton8d9ee76e2018-05-29 23:52:52876 quic::test::MockRandom random_generator_;
877 quic::MockClock clock_;
rtenneti38f5cd52014-10-28 20:28:28878 scoped_refptr<TestTaskRunner> runner_;
Nick Harper23290b82019-05-02 00:02:56879 const quic::ParsedQuicVersion version_;
alyssar2adf3ac2016-05-03 17:12:58880 QuicTestPacketMaker client_maker_;
881 QuicTestPacketMaker server_maker_;
rtenneticcab42b2015-10-09 06:38:16882 HttpServerPropertiesImpl http_server_properties_;
danakjad1777e2016-04-16 00:56:42883 std::unique_ptr<CertVerifier> cert_verifier_;
[email protected]080b77932014-08-04 01:22:46884 TransportSecurityState transport_security_state_;
danakjad1777e2016-04-16 00:56:42885 std::unique_ptr<CTVerifier> cert_transparency_verifier_;
Ryan Sleevi8a9c9c12018-05-09 02:36:23886 DefaultCTPolicyEnforcer ct_policy_enforcer_;
danakjad1777e2016-04-16 00:56:42887 std::unique_ptr<ScopedMockNetworkChangeNotifier>
jri7e636642016-01-14 06:57:08888 scoped_mock_network_change_notifier_;
danakjad1777e2016-04-16 00:56:42889 std::unique_ptr<QuicStreamFactory> factory_;
[email protected]bf4ea2f2014-03-10 22:57:53890 HostPortPair host_port_pair_;
ckrasic3865ee0f2016-02-29 22:04:56891 GURL url_;
892 GURL url2_;
893 GURL url3_;
894 GURL url4_;
895
[email protected]9dd3ff0f2014-03-26 09:51:28896 PrivacyMode privacy_mode_;
tfarina42834112016-09-22 13:38:20897 NetLogWithSource net_log_;
[email protected]e13201d82012-12-12 05:00:32898 TestCompletionCallback callback_;
Zhongyi Shia6b68d112018-09-24 07:49:03899 const CompletionRepeatingCallback failed_on_default_network_callback_;
900 bool failed_on_default_network_;
Ryan Hamilton75f197262017-08-17 14:00:07901 NetErrorDetails net_error_details_;
jri7046038f2015-10-22 00:29:26902
903 // Variables to configure QuicStreamFactory.
Zhongyi Shi967d2f12019-02-08 20:58:53904 HttpNetworkSession::Params test_params_;
rch431dd4452017-04-19 15:22:35905 bool store_server_configs_in_properties_;
[email protected]e13201d82012-12-12 05:00:32906};
907
bnc359ed2a2016-04-29 20:43:45908class QuicStreamFactoryTest : public QuicStreamFactoryTestBase,
909 public ::testing::TestWithParam<TestParams> {
910 protected:
Yixin Wang079ad542018-01-11 04:06:05911 QuicStreamFactoryTest()
912 : QuicStreamFactoryTestBase(
913 GetParam().version,
914 GetParam().client_headers_include_h2_stream_dependency) {}
bnc359ed2a2016-04-29 20:43:45915};
916
Victor Costane635086f2019-01-27 05:20:30917INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
918 QuicStreamFactoryTest,
919 ::testing::ValuesIn(GetTestParams()));
[email protected]1e960032013-12-20 19:00:20920
[email protected]1e960032013-12-20 19:00:20921TEST_P(QuicStreamFactoryTest, Create) {
jri7046038f2015-10-22 00:29:26922 Initialize();
rch6faa4d42016-01-05 20:48:43923 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
924 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri7046038f2015-10-22 00:29:26925
Ryan Hamiltonabad59e2019-06-06 04:02:59926 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:36927 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:43928 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:17929 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]e13201d82012-12-12 05:00:32930
zhongyi98d6a9262017-05-19 02:47:45931 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:33932 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:03933 request.Request(
Nick Harper23290b82019-05-02 00:02:56934 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:51935 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:03936 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
937 failed_on_default_network_callback_, callback_.callback()));
[email protected]e13201d82012-12-12 05:00:32938
robpercival214763f2016-07-01 23:27:01939 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:24940 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]0edce6a2013-05-08 18:02:40941 EXPECT_TRUE(stream.get());
[email protected]e13201d82012-12-12 05:00:32942
Renjiea0cb4a2c2018-09-26 23:37:30943 EXPECT_EQ(DEFAULT_PRIORITY, host_resolver_->last_request_priority());
Yixin Wang247ea642017-11-15 01:15:50944
zhongyi98d6a9262017-05-19 02:47:45945 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:51946 EXPECT_EQ(OK,
947 request2.Request(
948 host_port_pair_, version_.transport_version, privacy_mode_,
949 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
950 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
951 failed_on_default_network_callback_, callback_.callback()));
rch68a80eb2017-04-25 05:24:24952 // Will reset stream 3.
Yixin Wang7891a39d2017-11-08 20:59:24953 stream = CreateStream(&request2);
rch68a80eb2017-04-25 05:24:24954
955 EXPECT_TRUE(stream.get());
956
957 // TODO(rtenneti): We should probably have a tests that HTTP and HTTPS result
958 // in streams on different sessions.
zhongyi98d6a9262017-05-19 02:47:45959 QuicStreamRequest request3(factory_.get());
Matt Menke26e41542019-06-05 01:09:51960 EXPECT_EQ(OK,
961 request3.Request(
962 host_port_pair_, version_.transport_version, privacy_mode_,
963 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
964 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
965 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:24966 stream = CreateStream(&request3); // Will reset stream 5.
Ryan Hamiltona12722b2017-08-12 02:23:20967 stream.reset(); // Will reset stream 7.
[email protected]e13201d82012-12-12 05:00:32968
rch37de576c2015-05-17 20:28:17969 EXPECT_TRUE(socket_data.AllReadDataConsumed());
970 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]e13201d82012-12-12 05:00:32971}
972
[email protected]8bd2b812014-03-26 04:01:17973TEST_P(QuicStreamFactoryTest, CreateZeroRtt) {
jri7046038f2015-10-22 00:29:26974 Initialize();
Ryan Hamiltona12722b2017-08-12 02:23:20975 factory_->set_require_confirmation(false);
rch6faa4d42016-01-05 20:48:43976 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
977 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri7046038f2015-10-22 00:29:26978
Ryan Hamiltonabad59e2019-06-06 04:02:59979 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:36980 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5f587cc2017-11-21 23:24:17981 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]8bd2b812014-03-26 04:01:17982
983 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:27984 MockCryptoClientStream::ZERO_RTT);
Renjiea0cb4a2c2018-09-26 23:37:30985 host_resolver_->set_synchronous_mode(true);
986 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
987 "192.168.0.1", "");
[email protected]8bd2b812014-03-26 04:01:17988
zhongyi98d6a9262017-05-19 02:47:45989 QuicStreamRequest request(factory_.get());
Matt Menke26e41542019-06-05 01:09:51990 EXPECT_EQ(OK,
991 request.Request(
992 host_port_pair_, version_.transport_version, privacy_mode_,
993 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
994 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
995 failed_on_default_network_callback_, callback_.callback()));
[email protected]8bd2b812014-03-26 04:01:17996
Yixin Wang7891a39d2017-11-08 20:59:24997 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]8bd2b812014-03-26 04:01:17998 EXPECT_TRUE(stream.get());
rch37de576c2015-05-17 20:28:17999 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1000 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]8bd2b812014-03-26 04:01:171001}
1002
rchd6163f32017-01-30 23:50:381003TEST_P(QuicStreamFactoryTest, DefaultInitialRtt) {
1004 Initialize();
1005 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1006 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1007
Ryan Hamiltonabad59e2019-06-06 04:02:591008 MockQuicData socket_data(version_);
rchd6163f32017-01-30 23:50:381009 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431010 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171011 socket_data.AddSocketDataToFactory(socket_factory_.get());
rchd6163f32017-01-30 23:50:381012
zhongyi98d6a9262017-05-19 02:47:451013 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331014 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031015 request.Request(
Nick Harper23290b82019-05-02 00:02:561016 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:511017 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031018 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1019 failed_on_default_network_callback_, callback_.callback()));
rchd6163f32017-01-30 23:50:381020
1021 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241022 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rchd6163f32017-01-30 23:50:381023 EXPECT_TRUE(stream.get());
1024
1025 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Ryan Hamiltona12722b2017-08-12 02:23:201026 EXPECT_TRUE(session->require_confirmation());
rchd6163f32017-01-30 23:50:381027 EXPECT_EQ(100000u, session->connection()->GetStats().srtt_us);
1028 ASSERT_FALSE(session->config()->HasInitialRoundTripTimeUsToSend());
1029}
1030
Helen Li0e823912017-09-25 19:48:301031TEST_P(QuicStreamFactoryTest, FactoryDestroyedWhenJobPending) {
1032 Initialize();
1033 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1034 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1035
Ryan Hamiltonabad59e2019-06-06 04:02:591036 MockQuicData socket_data(version_);
Helen Li0e823912017-09-25 19:48:301037 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431038 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171039 socket_data.AddSocketDataToFactory(socket_factory_.get());
Helen Li0e823912017-09-25 19:48:301040
1041 auto request = std::make_unique<QuicStreamRequest>(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331042 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031043 request->Request(
Nick Harper23290b82019-05-02 00:02:561044 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:511045 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031046 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1047 failed_on_default_network_callback_, callback_.callback()));
Helen Li0e823912017-09-25 19:48:301048 request.reset();
1049 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
1050 // Tearing down a QuicStreamFactory with a pending Job should not cause any
1051 // crash. crbug.com/768343.
1052 factory_.reset();
1053}
1054
Ryan Hamiltona12722b2017-08-12 02:23:201055TEST_P(QuicStreamFactoryTest, RequireConfirmation) {
1056 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271057 MockCryptoClientStream::ZERO_RTT);
Renjiea0cb4a2c2018-09-26 23:37:301058 host_resolver_->set_synchronous_mode(true);
1059 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
1060 "192.168.0.1", "");
Ryan Hamiltona12722b2017-08-12 02:23:201061 Initialize();
1062 factory_->set_require_confirmation(true);
1063 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1064 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1065
Ryan Hamiltonabad59e2019-06-06 04:02:591066 MockQuicData socket_data(version_);
Ryan Hamiltona12722b2017-08-12 02:23:201067 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431068 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171069 socket_data.AddSocketDataToFactory(socket_factory_.get());
Ryan Hamiltona12722b2017-08-12 02:23:201070
1071 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331072 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031073 request.Request(
Nick Harper23290b82019-05-02 00:02:561074 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:511075 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031076 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1077 failed_on_default_network_callback_, callback_.callback()));
Ryan Hamiltona12722b2017-08-12 02:23:201078
Ryan Hamilton8e32a2b2017-08-28 20:06:521079 IPAddress last_address;
1080 EXPECT_FALSE(http_server_properties_.GetSupportsQuic(&last_address));
1081
Ryan Hamiltona12722b2017-08-12 02:23:201082 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521083 quic::QuicSession::HANDSHAKE_CONFIRMED);
Ryan Hamiltona12722b2017-08-12 02:23:201084
Ryan Hamilton8e32a2b2017-08-28 20:06:521085 EXPECT_TRUE(http_server_properties_.GetSupportsQuic(&last_address));
1086
Ryan Hamiltona12722b2017-08-12 02:23:201087 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241088 std::unique_ptr<HttpStream> stream = CreateStream(&request);
Ryan Hamiltona12722b2017-08-12 02:23:201089 EXPECT_TRUE(stream.get());
1090
1091 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
1092 EXPECT_TRUE(session->require_confirmation());
1093}
1094
1095TEST_P(QuicStreamFactoryTest, DontRequireConfirmationFromSameIP) {
1096 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271097 MockCryptoClientStream::ZERO_RTT);
Renjiea0cb4a2c2018-09-26 23:37:301098 host_resolver_->set_synchronous_mode(true);
1099 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
1100 "192.168.0.1", "");
Ryan Hamiltona12722b2017-08-12 02:23:201101 Initialize();
1102 factory_->set_require_confirmation(true);
1103 http_server_properties_.SetSupportsQuic(IPAddress(192, 0, 2, 33));
1104
1105 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1106 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1107
Ryan Hamiltonabad59e2019-06-06 04:02:591108 MockQuicData socket_data(version_);
Ryan Hamiltona12722b2017-08-12 02:23:201109 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431110 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171111 socket_data.AddSocketDataToFactory(socket_factory_.get());
Ryan Hamiltona12722b2017-08-12 02:23:201112
1113 QuicStreamRequest request(factory_.get());
Zhongyi Shia6b68d112018-09-24 07:49:031114 EXPECT_THAT(request.Request(
Nick Harper23290b82019-05-02 00:02:561115 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:511116 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031117 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1118 failed_on_default_network_callback_, callback_.callback()),
Paul Jensen8e3c5d32018-02-19 17:06:331119 IsOk());
Ryan Hamiltona12722b2017-08-12 02:23:201120
Ryan Hamilton8e32a2b2017-08-28 20:06:521121 IPAddress last_address;
1122 EXPECT_FALSE(http_server_properties_.GetSupportsQuic(&last_address));
1123
Yixin Wang7891a39d2017-11-08 20:59:241124 std::unique_ptr<HttpStream> stream = CreateStream(&request);
Ryan Hamiltona12722b2017-08-12 02:23:201125 EXPECT_TRUE(stream.get());
1126
1127 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
1128 EXPECT_FALSE(session->require_confirmation());
Ryan Hamilton8e32a2b2017-08-28 20:06:521129
1130 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521131 quic::QuicSession::HANDSHAKE_CONFIRMED);
Ryan Hamilton8e32a2b2017-08-28 20:06:521132
1133 EXPECT_TRUE(http_server_properties_.GetSupportsQuic(&last_address));
Ryan Hamiltona12722b2017-08-12 02:23:201134}
1135
rchd6163f32017-01-30 23:50:381136TEST_P(QuicStreamFactoryTest, CachedInitialRtt) {
1137 ServerNetworkStats stats;
1138 stats.srtt = base::TimeDelta::FromMilliseconds(10);
1139 http_server_properties_.SetServerNetworkStats(url::SchemeHostPort(url_),
1140 stats);
Zhongyi Shi967d2f12019-02-08 20:58:531141 test_params_.quic_estimate_initial_rtt = true;
rchd6163f32017-01-30 23:50:381142
1143 Initialize();
1144 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1145 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1146
Ryan Hamiltonabad59e2019-06-06 04:02:591147 MockQuicData socket_data(version_);
rchd6163f32017-01-30 23:50:381148 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431149 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171150 socket_data.AddSocketDataToFactory(socket_factory_.get());
rchd6163f32017-01-30 23:50:381151
zhongyi98d6a9262017-05-19 02:47:451152 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331153 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031154 request.Request(
Nick Harper23290b82019-05-02 00:02:561155 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:511156 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031157 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1158 failed_on_default_network_callback_, callback_.callback()));
rchd6163f32017-01-30 23:50:381159
1160 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241161 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rchd6163f32017-01-30 23:50:381162 EXPECT_TRUE(stream.get());
1163
1164 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
1165 EXPECT_EQ(10000u, session->connection()->GetStats().srtt_us);
1166 ASSERT_TRUE(session->config()->HasInitialRoundTripTimeUsToSend());
1167 EXPECT_EQ(10000u, session->config()->GetInitialRoundTripTimeUsToSend());
1168}
1169
1170TEST_P(QuicStreamFactoryTest, 2gInitialRtt) {
1171 ScopedMockNetworkChangeNotifier notifier;
1172 notifier.mock_network_change_notifier()->SetConnectionType(
1173 NetworkChangeNotifier::CONNECTION_2G);
Zhongyi Shi967d2f12019-02-08 20:58:531174 test_params_.quic_estimate_initial_rtt = true;
rchd6163f32017-01-30 23:50:381175
1176 Initialize();
1177 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1178 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1179
Ryan Hamiltonabad59e2019-06-06 04:02:591180 MockQuicData socket_data(version_);
rchd6163f32017-01-30 23:50:381181 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431182 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171183 socket_data.AddSocketDataToFactory(socket_factory_.get());
rchd6163f32017-01-30 23:50:381184
zhongyi98d6a9262017-05-19 02:47:451185 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331186 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031187 request.Request(
Nick Harper23290b82019-05-02 00:02:561188 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:511189 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031190 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1191 failed_on_default_network_callback_, callback_.callback()));
rchd6163f32017-01-30 23:50:381192
1193 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241194 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rchd6163f32017-01-30 23:50:381195 EXPECT_TRUE(stream.get());
1196
1197 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
1198 EXPECT_EQ(1200000u, session->connection()->GetStats().srtt_us);
1199 ASSERT_TRUE(session->config()->HasInitialRoundTripTimeUsToSend());
1200 EXPECT_EQ(1200000u, session->config()->GetInitialRoundTripTimeUsToSend());
1201}
1202
1203TEST_P(QuicStreamFactoryTest, 3gInitialRtt) {
1204 ScopedMockNetworkChangeNotifier notifier;
1205 notifier.mock_network_change_notifier()->SetConnectionType(
1206 NetworkChangeNotifier::CONNECTION_3G);
Zhongyi Shi967d2f12019-02-08 20:58:531207 test_params_.quic_estimate_initial_rtt = true;
rchd6163f32017-01-30 23:50:381208
1209 Initialize();
1210 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1211 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1212
Ryan Hamiltonabad59e2019-06-06 04:02:591213 MockQuicData socket_data(version_);
rchd6163f32017-01-30 23:50:381214 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431215 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171216 socket_data.AddSocketDataToFactory(socket_factory_.get());
rchd6163f32017-01-30 23:50:381217
zhongyi98d6a9262017-05-19 02:47:451218 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331219 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031220 request.Request(
Nick Harper23290b82019-05-02 00:02:561221 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:511222 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031223 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1224 failed_on_default_network_callback_, callback_.callback()));
rchd6163f32017-01-30 23:50:381225
1226 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241227 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rchd6163f32017-01-30 23:50:381228 EXPECT_TRUE(stream.get());
1229
1230 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
1231 EXPECT_EQ(400000u, session->connection()->GetStats().srtt_us);
1232 ASSERT_TRUE(session->config()->HasInitialRoundTripTimeUsToSend());
1233 EXPECT_EQ(400000u, session->config()->GetInitialRoundTripTimeUsToSend());
1234}
1235
rch68955482015-09-24 00:14:391236TEST_P(QuicStreamFactoryTest, GoAway) {
jri7046038f2015-10-22 00:29:261237 Initialize();
rch6faa4d42016-01-05 20:48:431238 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1239 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri7046038f2015-10-22 00:29:261240
Ryan Hamiltonabad59e2019-06-06 04:02:591241 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:361242 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431243 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171244 socket_data.AddSocketDataToFactory(socket_factory_.get());
rch68955482015-09-24 00:14:391245
zhongyi98d6a9262017-05-19 02:47:451246 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331247 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031248 request.Request(
Nick Harper23290b82019-05-02 00:02:561249 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:511250 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031251 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1252 failed_on_default_network_callback_, callback_.callback()));
rch68955482015-09-24 00:14:391253
robpercival214763f2016-07-01 23:27:011254 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241255 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rch68955482015-09-24 00:14:391256 EXPECT_TRUE(stream.get());
1257
bnc912a04b2016-04-20 14:19:501258 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
rch68955482015-09-24 00:14:391259
Ryan Hamilton8d9ee76e2018-05-29 23:52:521260 session->OnGoAway(quic::QuicGoAwayFrame());
rch68955482015-09-24 00:14:391261
bnc912a04b2016-04-20 14:19:501262 EXPECT_FALSE(HasActiveSession(host_port_pair_));
rch68955482015-09-24 00:14:391263
1264 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1265 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1266}
1267
zhongyi6b5a3892016-03-12 04:46:201268TEST_P(QuicStreamFactoryTest, GoAwayForConnectionMigrationWithPortOnly) {
1269 Initialize();
1270 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1271 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1272
Ryan Hamiltonabad59e2019-06-06 04:02:591273 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:361274 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431275 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171276 socket_data.AddSocketDataToFactory(socket_factory_.get());
zhongyi6b5a3892016-03-12 04:46:201277
zhongyi98d6a9262017-05-19 02:47:451278 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331279 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031280 request.Request(
Nick Harper23290b82019-05-02 00:02:561281 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:511282 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031283 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1284 failed_on_default_network_callback_, callback_.callback()));
zhongyi6b5a3892016-03-12 04:46:201285
robpercival214763f2016-07-01 23:27:011286 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241287 std::unique_ptr<HttpStream> stream = CreateStream(&request);
zhongyi6b5a3892016-03-12 04:46:201288 EXPECT_TRUE(stream.get());
1289
bnc912a04b2016-04-20 14:19:501290 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
zhongyi6b5a3892016-03-12 04:46:201291
Ryan Hamilton8d9ee76e2018-05-29 23:52:521292 session->OnGoAway(quic::QuicGoAwayFrame(
1293 quic::kInvalidControlFrameId, quic::QUIC_ERROR_MIGRATING_PORT, 0,
1294 "peer connection migration due to port change only"));
zhongyi6b5a3892016-03-12 04:46:201295 NetErrorDetails details;
1296 EXPECT_FALSE(details.quic_port_migration_detected);
1297 session->PopulateNetErrorDetails(&details);
1298 EXPECT_TRUE(details.quic_port_migration_detected);
1299 details.quic_port_migration_detected = false;
1300 stream->PopulateNetErrorDetails(&details);
1301 EXPECT_TRUE(details.quic_port_migration_detected);
1302
bnc912a04b2016-04-20 14:19:501303 EXPECT_FALSE(HasActiveSession(host_port_pair_));
zhongyi6b5a3892016-03-12 04:46:201304
1305 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1306 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1307}
1308
[email protected]5db452202014-08-19 05:22:151309TEST_P(QuicStreamFactoryTest, Pooling) {
jri7046038f2015-10-22 00:29:261310 Initialize();
rch6faa4d42016-01-05 20:48:431311 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1312 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri7046038f2015-10-22 00:29:261313
Ryan Hamiltonabad59e2019-06-06 04:02:591314 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:361315 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431316 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171317 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]eed749f92013-12-23 18:57:381318
rch6faa4d42016-01-05 20:48:431319 HostPortPair server2(kServer2HostName, kDefaultServerPort);
Renjiea0cb4a2c2018-09-26 23:37:301320 host_resolver_->set_synchronous_mode(true);
1321 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
1322 "192.168.0.1", "");
1323 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
[email protected]eed749f92013-12-23 18:57:381324
zhongyi98d6a9262017-05-19 02:47:451325 QuicStreamRequest request(factory_.get());
Matt Menke26e41542019-06-05 01:09:511326 EXPECT_EQ(OK,
1327 request.Request(
1328 host_port_pair_, version_.transport_version, privacy_mode_,
1329 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
1330 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1331 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241332 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]eed749f92013-12-23 18:57:381333 EXPECT_TRUE(stream.get());
1334
1335 TestCompletionCallback callback;
zhongyi98d6a9262017-05-19 02:47:451336 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:511337 EXPECT_EQ(OK,
1338 request2.Request(
1339 server2, version_.transport_version, privacy_mode_,
1340 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
1341 /*cert_verify_flags=*/0, url2_, net_log_, &net_error_details_,
1342 failed_on_default_network_callback_, callback.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241343 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
[email protected]eed749f92013-12-23 18:57:381344 EXPECT_TRUE(stream2.get());
1345
bnc912a04b2016-04-20 14:19:501346 EXPECT_EQ(GetActiveSession(host_port_pair_), GetActiveSession(server2));
[email protected]eed749f92013-12-23 18:57:381347
rch37de576c2015-05-17 20:28:171348 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1349 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]eed749f92013-12-23 18:57:381350}
1351
jri94ddc3142016-08-26 01:32:431352TEST_P(QuicStreamFactoryTest, PoolingWithServerMigration) {
1353 // Set up session to migrate.
Renjiea0cb4a2c2018-09-26 23:37:301354 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
1355 "192.168.0.1", "");
jri94ddc3142016-08-26 01:32:431356 IPEndPoint alt_address = IPEndPoint(IPAddress(1, 2, 3, 4), 443);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521357 quic::QuicConfig config;
Victor Vasiliev4f6fb892019-05-31 16:58:311358 config.SetAlternateServerAddressToSend(ToQuicSocketAddress(alt_address));
jri94ddc3142016-08-26 01:32:431359
1360 VerifyServerMigration(config, alt_address);
1361
1362 // Close server-migrated session.
1363 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Renjieba55fae2018-09-20 03:05:161364 session->CloseSessionOnError(0u, quic::QUIC_NO_ERROR,
1365 quic::ConnectionCloseBehavior::SILENT_CLOSE);
jri94ddc3142016-08-26 01:32:431366
1367 // Set up server IP, socket, proof, and config for new session.
1368 HostPortPair server2(kServer2HostName, kDefaultServerPort);
Renjiea0cb4a2c2018-09-26 23:37:301369 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
jri94ddc3142016-08-26 01:32:431370
1371 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:521372 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:361373 client_maker_.MakeInitialSettingsPacket(1, nullptr));
bnceb9aa7112017-01-05 01:03:461374 MockWrite writes[] = {MockWrite(SYNCHRONOUS, settings_packet->data(),
1375 settings_packet->length(), 1)};
fayang3bcb8b502016-12-07 21:44:371376
Ryan Sleevib8d7ea02018-05-07 20:01:011377 SequencedSocketData socket_data(reads, writes);
Zhongyi Shi5f587cc2017-11-21 23:24:171378 socket_factory_->AddSocketDataProvider(&socket_data);
jri94ddc3142016-08-26 01:32:431379
1380 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1381 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521382 quic::QuicConfig config2;
jri94ddc3142016-08-26 01:32:431383 crypto_client_stream_factory_.SetConfig(config2);
1384
1385 // Create new request to cause new session creation.
1386 TestCompletionCallback callback;
zhongyi98d6a9262017-05-19 02:47:451387 QuicStreamRequest request2(factory_.get());
jri94ddc3142016-08-26 01:32:431388 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031389 request2.Request(
Nick Harper23290b82019-05-02 00:02:561390 server2, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:511391 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031392 /*cert_verify_flags=*/0, url2_, net_log_, &net_error_details_,
1393 failed_on_default_network_callback_, callback.callback()));
jri94ddc3142016-08-26 01:32:431394 EXPECT_EQ(OK, callback.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:241395 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
jri94ddc3142016-08-26 01:32:431396 EXPECT_TRUE(stream2.get());
1397
1398 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1399 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1400 // EXPECT_EQ(GetActiveSession(host_port_pair_), GetActiveSession(server2));
1401}
1402
[email protected]eed749f92013-12-23 18:57:381403TEST_P(QuicStreamFactoryTest, NoPoolingAfterGoAway) {
jri7046038f2015-10-22 00:29:261404 Initialize();
rch6faa4d42016-01-05 20:48:431405 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1406 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1407 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri7046038f2015-10-22 00:29:261408
Ryan Hamiltonabad59e2019-06-06 04:02:591409 MockQuicData socket_data1(version_);
rcha00569732016-08-27 11:09:361410 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431411 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171412 socket_data1.AddSocketDataToFactory(socket_factory_.get());
Ryan Hamiltonabad59e2019-06-06 04:02:591413 MockQuicData socket_data2(version_);
rcha00569732016-08-27 11:09:361414 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431415 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171416 socket_data2.AddSocketDataToFactory(socket_factory_.get());
[email protected]eed749f92013-12-23 18:57:381417
rch6faa4d42016-01-05 20:48:431418 HostPortPair server2(kServer2HostName, kDefaultServerPort);
Renjiea0cb4a2c2018-09-26 23:37:301419 host_resolver_->set_synchronous_mode(true);
1420 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
1421 "192.168.0.1", "");
1422 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
[email protected]eed749f92013-12-23 18:57:381423
zhongyi98d6a9262017-05-19 02:47:451424 QuicStreamRequest request(factory_.get());
Matt Menke26e41542019-06-05 01:09:511425 EXPECT_EQ(OK,
1426 request.Request(
1427 host_port_pair_, version_.transport_version, privacy_mode_,
1428 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
1429 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1430 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241431 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]eed749f92013-12-23 18:57:381432 EXPECT_TRUE(stream.get());
1433
1434 TestCompletionCallback callback;
zhongyi98d6a9262017-05-19 02:47:451435 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:511436 EXPECT_EQ(OK,
1437 request2.Request(
1438 server2, version_.transport_version, privacy_mode_,
1439 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
1440 /*cert_verify_flags=*/0, url2_, net_log_, &net_error_details_,
1441 failed_on_default_network_callback_, callback.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241442 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
[email protected]eed749f92013-12-23 18:57:381443 EXPECT_TRUE(stream2.get());
1444
bnc912a04b2016-04-20 14:19:501445 factory_->OnSessionGoingAway(GetActiveSession(host_port_pair_));
1446 EXPECT_FALSE(HasActiveSession(host_port_pair_));
1447 EXPECT_FALSE(HasActiveSession(server2));
[email protected]eed749f92013-12-23 18:57:381448
1449 TestCompletionCallback callback3;
zhongyi98d6a9262017-05-19 02:47:451450 QuicStreamRequest request3(factory_.get());
Matt Menke26e41542019-06-05 01:09:511451 EXPECT_EQ(OK,
1452 request3.Request(
1453 server2, version_.transport_version, privacy_mode_,
1454 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
1455 /*cert_verify_flags=*/0, url2_, net_log_, &net_error_details_,
1456 failed_on_default_network_callback_, callback3.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241457 std::unique_ptr<HttpStream> stream3 = CreateStream(&request3);
[email protected]eed749f92013-12-23 18:57:381458 EXPECT_TRUE(stream3.get());
1459
bnc912a04b2016-04-20 14:19:501460 EXPECT_TRUE(HasActiveSession(server2));
[email protected]eed749f92013-12-23 18:57:381461
rch37de576c2015-05-17 20:28:171462 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
1463 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
1464 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
1465 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
[email protected]eed749f92013-12-23 18:57:381466}
1467
[email protected]5db452202014-08-19 05:22:151468TEST_P(QuicStreamFactoryTest, HttpsPooling) {
jri7046038f2015-10-22 00:29:261469 Initialize();
rch6faa4d42016-01-05 20:48:431470
Ryan Hamiltonabad59e2019-06-06 04:02:591471 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:361472 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431473 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171474 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]eed749f92013-12-23 18:57:381475
rch6faa4d42016-01-05 20:48:431476 HostPortPair server1(kDefaultServerHostName, 443);
1477 HostPortPair server2(kServer2HostName, 443);
[email protected]eed749f92013-12-23 18:57:381478
bncf8bf0722015-05-19 20:04:131479 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
bnc20daf9a2015-05-15 17:11:011480 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
[email protected]eed749f92013-12-23 18:57:381481
Renjiea0cb4a2c2018-09-26 23:37:301482 host_resolver_->set_synchronous_mode(true);
1483 host_resolver_->rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", "");
1484 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
[email protected]eed749f92013-12-23 18:57:381485
zhongyi98d6a9262017-05-19 02:47:451486 QuicStreamRequest request(factory_.get());
Matt Menke26e41542019-06-05 01:09:511487 EXPECT_EQ(OK,
1488 request.Request(
1489 server1, version_.transport_version, privacy_mode_,
1490 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
1491 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1492 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241493 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]eed749f92013-12-23 18:57:381494 EXPECT_TRUE(stream.get());
1495
1496 TestCompletionCallback callback;
zhongyi98d6a9262017-05-19 02:47:451497 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:511498 EXPECT_EQ(OK,
1499 request2.Request(
1500 server2, version_.transport_version, privacy_mode_,
1501 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
1502 /*cert_verify_flags=*/0, url2_, net_log_, &net_error_details_,
1503 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241504 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
[email protected]eed749f92013-12-23 18:57:381505 EXPECT_TRUE(stream2.get());
1506
bnc912a04b2016-04-20 14:19:501507 EXPECT_EQ(GetActiveSession(server1), GetActiveSession(server2));
[email protected]eed749f92013-12-23 18:57:381508
rch37de576c2015-05-17 20:28:171509 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1510 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]eed749f92013-12-23 18:57:381511}
1512
[email protected]5db452202014-08-19 05:22:151513TEST_P(QuicStreamFactoryTest, HttpsPoolingWithMatchingPins) {
jri7046038f2015-10-22 00:29:261514 Initialize();
Ryan Hamiltonabad59e2019-06-06 04:02:591515 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:361516 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431517 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171518 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]5db452202014-08-19 05:22:151519
rch6faa4d42016-01-05 20:48:431520 HostPortPair server1(kDefaultServerHostName, 443);
1521 HostPortPair server2(kServer2HostName, 443);
Matt Mueller230996f12018-10-22 19:39:441522 transport_security_state_.EnableStaticPinsForTesting();
1523 ScopedTransportSecurityStateSource scoped_security_state_source;
[email protected]5db452202014-08-19 05:22:151524
Matt Mueller230996f12018-10-22 19:39:441525 HashValue primary_pin(HASH_VALUE_SHA256);
1526 EXPECT_TRUE(primary_pin.FromString(
1527 "sha256/Nn8jk5By4Vkq6BeOVZ7R7AC6XUUBZsWmUbJR1f1Y5FY="));
bncf8bf0722015-05-19 20:04:131528 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
Matt Mueller230996f12018-10-22 19:39:441529 verify_details.cert_verify_result.public_key_hashes.push_back(primary_pin);
bnc20daf9a2015-05-15 17:11:011530 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
[email protected]5db452202014-08-19 05:22:151531
Renjiea0cb4a2c2018-09-26 23:37:301532 host_resolver_->set_synchronous_mode(true);
1533 host_resolver_->rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", "");
1534 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
[email protected]5db452202014-08-19 05:22:151535
zhongyi98d6a9262017-05-19 02:47:451536 QuicStreamRequest request(factory_.get());
Matt Menke26e41542019-06-05 01:09:511537 EXPECT_EQ(OK,
1538 request.Request(
1539 server1, version_.transport_version, privacy_mode_,
1540 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
1541 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1542 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241543 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]5db452202014-08-19 05:22:151544 EXPECT_TRUE(stream.get());
1545
1546 TestCompletionCallback callback;
zhongyi98d6a9262017-05-19 02:47:451547 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:511548 EXPECT_EQ(OK,
1549 request2.Request(
1550 server2, version_.transport_version, privacy_mode_,
1551 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
1552 /*cert_verify_flags=*/0, url2_, net_log_, &net_error_details_,
1553 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241554 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
[email protected]5db452202014-08-19 05:22:151555 EXPECT_TRUE(stream2.get());
1556
bnc912a04b2016-04-20 14:19:501557 EXPECT_EQ(GetActiveSession(server1), GetActiveSession(server2));
[email protected]5db452202014-08-19 05:22:151558
rch37de576c2015-05-17 20:28:171559 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1560 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]5db452202014-08-19 05:22:151561}
1562
1563TEST_P(QuicStreamFactoryTest, NoHttpsPoolingWithDifferentPins) {
jri7046038f2015-10-22 00:29:261564 Initialize();
rcha00569732016-08-27 11:09:361565
Ryan Hamiltonabad59e2019-06-06 04:02:591566 MockQuicData socket_data1(version_);
rcha00569732016-08-27 11:09:361567 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431568 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171569 socket_data1.AddSocketDataToFactory(socket_factory_.get());
Ryan Hamiltonabad59e2019-06-06 04:02:591570 MockQuicData socket_data2(version_);
rcha00569732016-08-27 11:09:361571 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431572 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171573 socket_data2.AddSocketDataToFactory(socket_factory_.get());
[email protected]5db452202014-08-19 05:22:151574
rch6faa4d42016-01-05 20:48:431575 HostPortPair server1(kDefaultServerHostName, 443);
1576 HostPortPair server2(kServer2HostName, 443);
Matt Mueller230996f12018-10-22 19:39:441577 transport_security_state_.EnableStaticPinsForTesting();
1578 ScopedTransportSecurityStateSource scoped_security_state_source;
[email protected]5db452202014-08-19 05:22:151579
bncf8bf0722015-05-19 20:04:131580 ProofVerifyDetailsChromium verify_details1 = DefaultProofVerifyDetails();
Matt Mueller230996f12018-10-22 19:39:441581 uint8_t bad_pin = 3;
bnc20daf9a2015-05-15 17:11:011582 verify_details1.cert_verify_result.public_key_hashes.push_back(
1583 test::GetTestHashValue(bad_pin));
1584 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
1585
Matt Mueller230996f12018-10-22 19:39:441586 HashValue primary_pin(HASH_VALUE_SHA256);
1587 EXPECT_TRUE(primary_pin.FromString(
1588 "sha256/Nn8jk5By4Vkq6BeOVZ7R7AC6XUUBZsWmUbJR1f1Y5FY="));
bncf8bf0722015-05-19 20:04:131589 ProofVerifyDetailsChromium verify_details2 = DefaultProofVerifyDetails();
Matt Mueller230996f12018-10-22 19:39:441590 verify_details2.cert_verify_result.public_key_hashes.push_back(primary_pin);
bnc20daf9a2015-05-15 17:11:011591 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
[email protected]5db452202014-08-19 05:22:151592
Renjiea0cb4a2c2018-09-26 23:37:301593 host_resolver_->set_synchronous_mode(true);
1594 host_resolver_->rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", "");
1595 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
[email protected]5db452202014-08-19 05:22:151596
zhongyi98d6a9262017-05-19 02:47:451597 QuicStreamRequest request(factory_.get());
Matt Menke26e41542019-06-05 01:09:511598 EXPECT_EQ(OK,
1599 request.Request(
1600 server1, version_.transport_version, privacy_mode_,
1601 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
1602 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1603 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241604 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]5db452202014-08-19 05:22:151605 EXPECT_TRUE(stream.get());
1606
1607 TestCompletionCallback callback;
zhongyi98d6a9262017-05-19 02:47:451608 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:511609 EXPECT_EQ(OK,
1610 request2.Request(
1611 server2, version_.transport_version, privacy_mode_,
1612 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
1613 /*cert_verify_flags=*/0, url2_, net_log_, &net_error_details_,
1614 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241615 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
[email protected]5db452202014-08-19 05:22:151616 EXPECT_TRUE(stream2.get());
1617
bnc912a04b2016-04-20 14:19:501618 EXPECT_NE(GetActiveSession(server1), GetActiveSession(server2));
[email protected]5db452202014-08-19 05:22:151619
rch37de576c2015-05-17 20:28:171620 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
1621 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
1622 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
1623 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
[email protected]5db452202014-08-19 05:22:151624}
1625
[email protected]1e960032013-12-20 19:00:201626TEST_P(QuicStreamFactoryTest, Goaway) {
jri7046038f2015-10-22 00:29:261627 Initialize();
rch6faa4d42016-01-05 20:48:431628 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1629 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1630 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1631
Ryan Hamiltonabad59e2019-06-06 04:02:591632 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:361633 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431634 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171635 socket_data.AddSocketDataToFactory(socket_factory_.get());
Ryan Hamiltonabad59e2019-06-06 04:02:591636 MockQuicData socket_data2(version_);
rcha00569732016-08-27 11:09:361637 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431638 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171639 socket_data2.AddSocketDataToFactory(socket_factory_.get());
[email protected]4d283b32013-10-17 12:57:271640
zhongyi98d6a9262017-05-19 02:47:451641 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331642 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031643 request.Request(
Nick Harper23290b82019-05-02 00:02:561644 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:511645 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031646 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1647 failed_on_default_network_callback_, callback_.callback()));
[email protected]4d283b32013-10-17 12:57:271648
robpercival214763f2016-07-01 23:27:011649 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241650 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]4d283b32013-10-17 12:57:271651 EXPECT_TRUE(stream.get());
1652
1653 // Mark the session as going away. Ensure that while it is still alive
1654 // that it is no longer active.
bnc912a04b2016-04-20 14:19:501655 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri7046038f2015-10-22 00:29:261656 factory_->OnSessionGoingAway(session);
1657 EXPECT_EQ(true,
1658 QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
bnc912a04b2016-04-20 14:19:501659 EXPECT_FALSE(HasActiveSession(host_port_pair_));
[email protected]4d283b32013-10-17 12:57:271660
1661 // Create a new request for the same destination and verify that a
1662 // new session is created.
zhongyi98d6a9262017-05-19 02:47:451663 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331664 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031665 request2.Request(
Nick Harper23290b82019-05-02 00:02:561666 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:511667 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031668 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1669 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:011670 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241671 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
[email protected]4d283b32013-10-17 12:57:271672 EXPECT_TRUE(stream2.get());
1673
bnc912a04b2016-04-20 14:19:501674 EXPECT_TRUE(HasActiveSession(host_port_pair_));
1675 EXPECT_NE(session, GetActiveSession(host_port_pair_));
jri7046038f2015-10-22 00:29:261676 EXPECT_EQ(true,
1677 QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
[email protected]4d283b32013-10-17 12:57:271678
1679 stream2.reset();
1680 stream.reset();
1681
rch37de576c2015-05-17 20:28:171682 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1683 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1684 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
1685 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
[email protected]4d283b32013-10-17 12:57:271686}
1687
[email protected]1e960032013-12-20 19:00:201688TEST_P(QuicStreamFactoryTest, MaxOpenStream) {
jri7046038f2015-10-22 00:29:261689 Initialize();
rch6faa4d42016-01-05 20:48:431690 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1691 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1692
Fan Yang32c5a112018-12-10 20:06:331693 quic::QuicStreamId stream_id = GetNthClientInitiatedBidirectionalStreamId(0);
Ryan Hamiltonabad59e2019-06-06 04:02:591694 MockQuicData socket_data(version_);
Zhongyi Shi32f2fd02018-04-16 18:23:431695 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Nick Harper23290b82019-05-02 00:02:561696 if (version_.transport_version == quic::QUIC_VERSION_99) {
David Schinazicc1bc592019-04-24 19:40:311697 socket_data.AddWrite(SYNCHRONOUS, client_maker_.MakeStreamsBlockedPacket(
Ryan Hamilton4aeec562019-05-17 21:22:521698 2, true, 51,
David Schinazicc1bc592019-04-24 19:40:311699 /*unidirectional=*/false));
Frank Kastenholzc9b9bea2018-12-03 20:13:471700 socket_data.AddWrite(
1701 SYNCHRONOUS, client_maker_.MakeRstPacket(3, true, stream_id,
1702 quic::QUIC_STREAM_CANCELLED));
1703 socket_data.AddRead(
1704 ASYNC, server_maker_.MakeRstPacket(1, false, stream_id,
1705 quic::QUIC_STREAM_CANCELLED));
Fan Yang32c5a112018-12-10 20:06:331706 socket_data.AddRead(
Ryan Hamilton4aeec562019-05-17 21:22:521707 ASYNC, server_maker_.MakeMaxStreamsPacket(4, true, 52,
David Schinazicc1bc592019-04-24 19:40:311708 /*unidirectional=*/false));
Frank Kastenholzc9b9bea2018-12-03 20:13:471709 } else {
1710 socket_data.AddWrite(
1711 SYNCHRONOUS, client_maker_.MakeRstPacket(2, true, stream_id,
1712 quic::QUIC_STREAM_CANCELLED));
1713 socket_data.AddRead(
1714 ASYNC, server_maker_.MakeRstPacket(1, false, stream_id,
1715 quic::QUIC_STREAM_CANCELLED));
Frank Kastenholz878763bf2018-11-28 19:14:481716 }
rcha00569732016-08-27 11:09:361717 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5f587cc2017-11-21 23:24:171718 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]0b2294d32013-08-02 00:46:361719
1720 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:391721 request_info.traffic_annotation =
1722 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
1723
xunjieli1d2b4272017-04-25 22:37:171724 std::vector<std::unique_ptr<HttpStream>> streams;
Ryan Hamilton9835e662018-08-02 05:36:271725 // The MockCryptoClientStream sets max_open_streams to be
Ryan Hamilton8d9ee76e2018-05-29 23:52:521726 // quic::kDefaultMaxStreamsPerConnection / 2.
1727 for (size_t i = 0; i < quic::kDefaultMaxStreamsPerConnection / 2; i++) {
zhongyi98d6a9262017-05-19 02:47:451728 QuicStreamRequest request(factory_.get());
Zhongyi Shia6b68d112018-09-24 07:49:031729 int rv = request.Request(
Nick Harper23290b82019-05-02 00:02:561730 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:511731 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031732 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1733 failed_on_default_network_callback_, callback_.callback());
[email protected]0b2294d32013-08-02 00:46:361734 if (i == 0) {
robpercival214763f2016-07-01 23:27:011735 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1736 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]0b2294d32013-08-02 00:46:361737 } else {
robpercival214763f2016-07-01 23:27:011738 EXPECT_THAT(rv, IsOk());
[email protected]0b2294d32013-08-02 00:46:361739 }
Yixin Wang7891a39d2017-11-08 20:59:241740 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]0b2294d32013-08-02 00:46:361741 EXPECT_TRUE(stream);
Steven Valdezb4ff0412018-01-18 22:39:271742 EXPECT_EQ(OK,
1743 stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:391744 net_log_, CompletionOnceCallback()));
avib3635452016-10-21 18:33:531745 streams.push_back(std::move(stream));
[email protected]0b2294d32013-08-02 00:46:361746 }
1747
zhongyi98d6a9262017-05-19 02:47:451748 QuicStreamRequest request(factory_.get());
Matt Menke26e41542019-06-05 01:09:511749 EXPECT_EQ(OK,
1750 request.Request(
1751 host_port_pair_, version_.transport_version, privacy_mode_,
1752 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
1753 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1754 failed_on_default_network_callback_, CompletionOnceCallback()));
Yixin Wang7891a39d2017-11-08 20:59:241755 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]0b2294d32013-08-02 00:46:361756 EXPECT_TRUE(stream);
rjshaded5ced072015-12-18 19:26:021757 EXPECT_EQ(ERR_IO_PENDING,
Steven Valdezb4ff0412018-01-18 22:39:271758 stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
1759 net_log_, callback_.callback()));
[email protected]0b2294d32013-08-02 00:46:361760
1761 // Close the first stream.
1762 streams.front()->Close(false);
ckrasicea295fe2015-10-31 05:03:271763 // Trigger exchange of RSTs that in turn allow progress for the last
1764 // stream.
Frank Kastenholz878763bf2018-11-28 19:14:481765 base::RunLoop().RunUntilIdle();
robpercival214763f2016-07-01 23:27:011766 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]0b2294d32013-08-02 00:46:361767
rch37de576c2015-05-17 20:28:171768 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1769 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
ckrasicea295fe2015-10-31 05:03:271770
1771 // Force close of the connection to suppress the generation of RST
1772 // packets when streams are torn down, which wouldn't be relevant to
1773 // this test anyway.
bnc912a04b2016-04-20 14:19:501774 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521775 session->connection()->CloseConnection(
1776 quic::QUIC_PUBLIC_RESET, "test",
1777 quic::ConnectionCloseBehavior::SILENT_CLOSE);
[email protected]0b2294d32013-08-02 00:46:361778}
1779
[email protected]1e960032013-12-20 19:00:201780TEST_P(QuicStreamFactoryTest, ResolutionErrorInCreate) {
jri7046038f2015-10-22 00:29:261781 Initialize();
Ryan Hamiltonabad59e2019-06-06 04:02:591782 MockQuicData socket_data(version_);
Zhongyi Shi5f587cc2017-11-21 23:24:171783 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]e13201d82012-12-12 05:00:321784
Renjiea0cb4a2c2018-09-26 23:37:301785 host_resolver_->rules()->AddSimulatedFailure(kDefaultServerHostName);
[email protected]e13201d82012-12-12 05:00:321786
zhongyi98d6a9262017-05-19 02:47:451787 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331788 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031789 request.Request(
Nick Harper23290b82019-05-02 00:02:561790 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:511791 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031792 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1793 failed_on_default_network_callback_, callback_.callback()));
[email protected]e13201d82012-12-12 05:00:321794
robpercival214763f2016-07-01 23:27:011795 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_NAME_NOT_RESOLVED));
[email protected]e13201d82012-12-12 05:00:321796
rch37de576c2015-05-17 20:28:171797 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1798 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]e13201d82012-12-12 05:00:321799}
1800
[email protected]1e960032013-12-20 19:00:201801TEST_P(QuicStreamFactoryTest, ConnectErrorInCreate) {
jri7046038f2015-10-22 00:29:261802 Initialize();
rcha00569732016-08-27 11:09:361803
Ryan Hamiltonabad59e2019-06-06 04:02:591804 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:361805 socket_data.AddConnect(SYNCHRONOUS, ERR_ADDRESS_IN_USE);
Zhongyi Shi5f587cc2017-11-21 23:24:171806 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]3c772402013-12-18 21:38:111807
zhongyi98d6a9262017-05-19 02:47:451808 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331809 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031810 request.Request(
Nick Harper23290b82019-05-02 00:02:561811 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:511812 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031813 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1814 failed_on_default_network_callback_, callback_.callback()));
[email protected]3c772402013-12-18 21:38:111815
robpercival214763f2016-07-01 23:27:011816 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_ADDRESS_IN_USE));
[email protected]3c772402013-12-18 21:38:111817
rch37de576c2015-05-17 20:28:171818 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1819 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]3c772402013-12-18 21:38:111820}
1821
[email protected]1e960032013-12-20 19:00:201822TEST_P(QuicStreamFactoryTest, CancelCreate) {
jri7046038f2015-10-22 00:29:261823 Initialize();
Ryan Hamiltonabad59e2019-06-06 04:02:591824 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:361825 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431826 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171827 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]e13201d82012-12-12 05:00:321828 {
zhongyi98d6a9262017-05-19 02:47:451829 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331830 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031831 request.Request(
Nick Harper23290b82019-05-02 00:02:561832 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:511833 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031834 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1835 failed_on_default_network_callback_, callback_.callback()));
[email protected]e13201d82012-12-12 05:00:321836 }
1837
mmenke651bae7f2015-12-18 21:26:451838 base::RunLoop().RunUntilIdle();
[email protected]e13201d82012-12-12 05:00:321839
zhongyi98d6a9262017-05-19 02:47:451840 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:511841 EXPECT_EQ(OK,
1842 request2.Request(
1843 host_port_pair_, version_.transport_version, privacy_mode_,
1844 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
1845 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1846 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:241847 std::unique_ptr<HttpStream> stream = CreateStream(&request2);
rch68a80eb2017-04-25 05:24:241848
[email protected]e13201d82012-12-12 05:00:321849 EXPECT_TRUE(stream.get());
1850 stream.reset();
1851
rch37de576c2015-05-17 20:28:171852 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1853 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
[email protected]e13201d82012-12-12 05:00:321854}
1855
[email protected]1e960032013-12-20 19:00:201856TEST_P(QuicStreamFactoryTest, CloseAllSessions) {
jri7046038f2015-10-22 00:29:261857 Initialize();
rch6faa4d42016-01-05 20:48:431858 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1859 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1860 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
1861
Ryan Hamiltonabad59e2019-06-06 04:02:591862 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:361863 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431864 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Ryan Hamilton8d9ee76e2018-05-29 23:52:521865 socket_data.AddWrite(
1866 SYNCHRONOUS, ConstructClientRstPacket(2, quic::QUIC_RST_ACKNOWLEDGEMENT));
Renjieba55fae2018-09-20 03:05:161867 socket_data.AddWrite(SYNCHRONOUS,
1868 client_maker_.MakeConnectionClosePacket(
1869 3, true, quic::QUIC_INTERNAL_ERROR, "net error"));
Zhongyi Shi5f587cc2017-11-21 23:24:171870 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]56dfb902013-01-03 23:17:551871
Ryan Hamiltonabad59e2019-06-06 04:02:591872 MockQuicData socket_data2(version_);
rcha00569732016-08-27 11:09:361873 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431874 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171875 socket_data2.AddSocketDataToFactory(socket_factory_.get());
[email protected]56dfb902013-01-03 23:17:551876
zhongyi98d6a9262017-05-19 02:47:451877 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331878 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031879 request.Request(
Nick Harper23290b82019-05-02 00:02:561880 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:511881 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031882 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1883 failed_on_default_network_callback_, callback_.callback()));
[email protected]56dfb902013-01-03 23:17:551884
robpercival214763f2016-07-01 23:27:011885 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241886 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]0b2294d32013-08-02 00:46:361887 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:391888 request_info.traffic_annotation =
1889 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:271890 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:391891 net_log_, CompletionOnceCallback()));
[email protected]56dfb902013-01-03 23:17:551892
1893 // Close the session and verify that stream saw the error.
Ryan Hamilton8d9ee76e2018-05-29 23:52:521894 factory_->CloseAllSessions(ERR_INTERNET_DISCONNECTED,
1895 quic::QUIC_INTERNAL_ERROR);
[email protected]56dfb902013-01-03 23:17:551896 EXPECT_EQ(ERR_INTERNET_DISCONNECTED,
1897 stream->ReadResponseHeaders(callback_.callback()));
1898
1899 // Now attempting to request a stream to the same origin should create
1900 // a new session.
1901
zhongyi98d6a9262017-05-19 02:47:451902 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331903 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031904 request2.Request(
Nick Harper23290b82019-05-02 00:02:561905 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:511906 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031907 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1908 failed_on_default_network_callback_, callback_.callback()));
[email protected]56dfb902013-01-03 23:17:551909
robpercival214763f2016-07-01 23:27:011910 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:241911 stream = CreateStream(&request2);
[email protected]56dfb902013-01-03 23:17:551912 stream.reset(); // Will reset stream 3.
1913
rch37de576c2015-05-17 20:28:171914 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1915 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1916 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
1917 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
[email protected]56dfb902013-01-03 23:17:551918}
1919
zhongyi363c91c2017-03-23 23:16:081920// Regression test for crbug.com/700617. Test a write error during the
1921// crypto handshake will not hang QuicStreamFactory::Job and should
1922// report QUIC_HANDSHAKE_FAILED to upper layers. Subsequent
1923// QuicStreamRequest should succeed without hanging.
1924TEST_P(QuicStreamFactoryTest,
1925 WriteErrorInCryptoConnectWithAsyncHostResolution) {
1926 Initialize();
1927 // Use unmocked crypto stream to do crypto connect.
1928 crypto_client_stream_factory_.set_handshake_mode(
Zhongyi Shi879659422018-08-02 17:58:251929 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
zhongyi363c91c2017-03-23 23:16:081930
Ryan Hamiltonabad59e2019-06-06 04:02:591931 MockQuicData socket_data(version_);
zhongyi363c91c2017-03-23 23:16:081932 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1933 // Trigger PACKET_WRITE_ERROR when sending packets in crypto connect.
1934 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:171935 socket_data.AddSocketDataToFactory(socket_factory_.get());
zhongyi363c91c2017-03-23 23:16:081936
1937 // Create request, should fail after the write of the CHLO fails.
zhongyi98d6a9262017-05-19 02:47:451938 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331939 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031940 request.Request(
Nick Harper23290b82019-05-02 00:02:561941 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:511942 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031943 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1944 failed_on_default_network_callback_, callback_.callback()));
zhongyi363c91c2017-03-23 23:16:081945 EXPECT_EQ(ERR_QUIC_HANDSHAKE_FAILED, callback_.WaitForResult());
1946 EXPECT_FALSE(HasActiveSession(host_port_pair_));
1947 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
1948
1949 // Verify new requests can be sent normally without hanging.
1950 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:271951 MockCryptoClientStream::COLD_START);
zhongyi363c91c2017-03-23 23:16:081952 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
1953 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
Ryan Hamiltonabad59e2019-06-06 04:02:591954 MockQuicData socket_data2(version_);
zhongyi363c91c2017-03-23 23:16:081955 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:431956 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:171957 socket_data2.AddSocketDataToFactory(socket_factory_.get());
zhongyi363c91c2017-03-23 23:16:081958
zhongyi98d6a9262017-05-19 02:47:451959 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:331960 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:031961 request2.Request(
Nick Harper23290b82019-05-02 00:02:561962 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:511963 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:031964 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
1965 failed_on_default_network_callback_, callback_.callback()));
zhongyi363c91c2017-03-23 23:16:081966 EXPECT_FALSE(HasActiveSession(host_port_pair_));
1967 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
1968 // Run the message loop to complete host resolution.
1969 base::RunLoop().RunUntilIdle();
1970
1971 // Complete handshake. QuicStreamFactory::Job should complete and succeed.
1972 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:521973 quic::QuicSession::HANDSHAKE_CONFIRMED);
zhongyi363c91c2017-03-23 23:16:081974 EXPECT_THAT(callback_.WaitForResult(), IsOk());
1975 EXPECT_TRUE(HasActiveSession(host_port_pair_));
1976 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
1977
1978 // Create QuicHttpStream.
Yixin Wang7891a39d2017-11-08 20:59:241979 std::unique_ptr<HttpStream> stream = CreateStream(&request2);
zhongyi363c91c2017-03-23 23:16:081980 EXPECT_TRUE(stream.get());
1981 stream.reset();
1982 EXPECT_TRUE(socket_data.AllReadDataConsumed());
1983 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
1984 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
1985 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
1986}
1987
1988TEST_P(QuicStreamFactoryTest, WriteErrorInCryptoConnectWithSyncHostResolution) {
1989 Initialize();
1990 // Use unmocked crypto stream to do crypto connect.
1991 crypto_client_stream_factory_.set_handshake_mode(
Zhongyi Shi879659422018-08-02 17:58:251992 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
Renjiea0cb4a2c2018-09-26 23:37:301993 host_resolver_->set_synchronous_mode(true);
1994 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
1995 "192.168.0.1", "");
zhongyi363c91c2017-03-23 23:16:081996
Ryan Hamiltonabad59e2019-06-06 04:02:591997 MockQuicData socket_data(version_);
zhongyi363c91c2017-03-23 23:16:081998 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
1999 // Trigger PACKET_WRITE_ERROR when sending packets in crypto connect.
2000 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:172001 socket_data.AddSocketDataToFactory(socket_factory_.get());
zhongyi363c91c2017-03-23 23:16:082002
2003 // Create request, should fail immediately.
zhongyi98d6a9262017-05-19 02:47:452004 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332005 EXPECT_EQ(ERR_QUIC_HANDSHAKE_FAILED,
Zhongyi Shia6b68d112018-09-24 07:49:032006 request.Request(
Nick Harper23290b82019-05-02 00:02:562007 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:512008 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032009 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2010 failed_on_default_network_callback_, callback_.callback()));
zhongyi363c91c2017-03-23 23:16:082011 // Check no active session, or active jobs left for this server.
2012 EXPECT_FALSE(HasActiveSession(host_port_pair_));
2013 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
2014
2015 // Verify new requests can be sent normally without hanging.
2016 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:272017 MockCryptoClientStream::COLD_START);
zhongyi363c91c2017-03-23 23:16:082018 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2019 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
Ryan Hamiltonabad59e2019-06-06 04:02:592020 MockQuicData socket_data2(version_);
zhongyi363c91c2017-03-23 23:16:082021 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432022 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:172023 socket_data2.AddSocketDataToFactory(socket_factory_.get());
zhongyi363c91c2017-03-23 23:16:082024
zhongyi98d6a9262017-05-19 02:47:452025 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332026 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032027 request2.Request(
Nick Harper23290b82019-05-02 00:02:562028 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:512029 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032030 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2031 failed_on_default_network_callback_, callback_.callback()));
zhongyi363c91c2017-03-23 23:16:082032 EXPECT_FALSE(HasActiveSession(host_port_pair_));
2033 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
2034
2035 // Complete handshake.
2036 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
Ryan Hamilton8d9ee76e2018-05-29 23:52:522037 quic::QuicSession::HANDSHAKE_CONFIRMED);
zhongyi363c91c2017-03-23 23:16:082038 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2039 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2040 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
2041
2042 // Create QuicHttpStream.
Yixin Wang7891a39d2017-11-08 20:59:242043 std::unique_ptr<HttpStream> stream = CreateStream(&request2);
zhongyi363c91c2017-03-23 23:16:082044 EXPECT_TRUE(stream.get());
2045 stream.reset();
2046 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2047 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2048 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
2049 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
2050}
2051
Zhongyi Shi63574b72018-06-01 20:22:252052TEST_P(QuicStreamFactoryTest, CloseSessionsOnIPAddressChanged) {
Zhongyi Shi967d2f12019-02-08 20:58:532053 test_params_.quic_close_sessions_on_ip_change = true;
jri7046038f2015-10-22 00:29:262054 Initialize();
rch6faa4d42016-01-05 20:48:432055 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2056 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2057 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri8c44d692015-10-23 23:53:412058
Ryan Hamiltonabad59e2019-06-06 04:02:592059 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:362060 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432061 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Ryan Hamilton8d9ee76e2018-05-29 23:52:522062 socket_data.AddWrite(
2063 SYNCHRONOUS, ConstructClientRstPacket(2, quic::QUIC_RST_ACKNOWLEDGEMENT));
Renjieba55fae2018-09-20 03:05:162064 socket_data.AddWrite(
2065 SYNCHRONOUS, client_maker_.MakeConnectionClosePacket(
2066 3, true, quic::QUIC_IP_ADDRESS_CHANGED, "net error"));
Zhongyi Shi5f587cc2017-11-21 23:24:172067 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]f698a012013-05-06 20:18:592068
Ryan Hamiltonabad59e2019-06-06 04:02:592069 MockQuicData socket_data2(version_);
rcha00569732016-08-27 11:09:362070 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432071 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:172072 socket_data2.AddSocketDataToFactory(socket_factory_.get());
[email protected]f698a012013-05-06 20:18:592073
zhongyi98d6a9262017-05-19 02:47:452074 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332075 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032076 request.Request(
Nick Harper23290b82019-05-02 00:02:562077 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:512078 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032079 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2080 failed_on_default_network_callback_, callback_.callback()));
[email protected]f698a012013-05-06 20:18:592081
robpercival214763f2016-07-01 23:27:012082 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242083 std::unique_ptr<HttpStream> stream = CreateStream(&request);
[email protected]0b2294d32013-08-02 00:46:362084 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:392085 request_info.traffic_annotation =
2086 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272087 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392088 net_log_, CompletionOnceCallback()));
[email protected]f698a012013-05-06 20:18:592089
Zhongyi Shi63574b72018-06-01 20:22:252090 // Check an active session exisits for the destination.
2091 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2092 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
2093 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2094
Ryan Hamilton8e32a2b2017-08-28 20:06:522095 IPAddress last_address;
2096 EXPECT_TRUE(http_server_properties_.GetSupportsQuic(&last_address));
Zhongyi Shi63574b72018-06-01 20:22:252097 // Change the IP address and verify that stream saw the error and the active
2098 // session is closed.
jri8c44d692015-10-23 23:53:412099 NotifyIPAddressChanged();
[email protected]f698a012013-05-06 20:18:592100 EXPECT_EQ(ERR_NETWORK_CHANGED,
2101 stream->ReadResponseHeaders(callback_.callback()));
jri7046038f2015-10-22 00:29:262102 EXPECT_TRUE(factory_->require_confirmation());
Ryan Hamilton8e32a2b2017-08-28 20:06:522103 EXPECT_FALSE(http_server_properties_.GetSupportsQuic(&last_address));
Zhongyi Shi63574b72018-06-01 20:22:252104 // Check no active session exists for the destination.
2105 EXPECT_FALSE(HasActiveSession(host_port_pair_));
[email protected]f698a012013-05-06 20:18:592106
2107 // Now attempting to request a stream to the same origin should create
2108 // a new session.
zhongyi98d6a9262017-05-19 02:47:452109 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332110 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032111 request2.Request(
Nick Harper23290b82019-05-02 00:02:562112 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:512113 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032114 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2115 failed_on_default_network_callback_, callback_.callback()));
[email protected]f698a012013-05-06 20:18:592116
robpercival214763f2016-07-01 23:27:012117 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242118 stream = CreateStream(&request2);
[email protected]f698a012013-05-06 20:18:592119
Zhongyi Shi63574b72018-06-01 20:22:252120 // Check a new active session exisits for the destination and the old session
2121 // is no longer live.
2122 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2123 QuicChromiumClientSession* session2 = GetActiveSession(host_port_pair_);
2124 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2));
2125
2126 stream.reset(); // Will reset stream 3.
rch37de576c2015-05-17 20:28:172127 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2128 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2129 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
2130 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
[email protected]f698a012013-05-06 20:18:592131}
2132
Zhongyi Shi63574b72018-06-01 20:22:252133// Test that if goaway_session_on_ip_change is set, old sessions will be marked
2134// as going away on IP address change instead of being closed. New requests will
2135// go to a new connection.
2136TEST_P(QuicStreamFactoryTest, GoAwaySessionsOnIPAddressChanged) {
Zhongyi Shi967d2f12019-02-08 20:58:532137 test_params_.quic_goaway_sessions_on_ip_change = true;
Zhongyi Shi63574b72018-06-01 20:22:252138 Initialize();
2139 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2140 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2141 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2142
Ryan Hamiltonabad59e2019-06-06 04:02:592143 MockQuicData quic_data1(version_);
Zhongyi Shi63574b72018-06-01 20:22:252144 quic::QuicStreamOffset header_stream_offset = 0;
2145 quic_data1.AddWrite(SYNCHRONOUS,
2146 ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:332147 quic_data1.AddWrite(
2148 SYNCHRONOUS, ConstructGetRequestPacket(
2149 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
2150 true, &header_stream_offset));
Zhongyi Shi63574b72018-06-01 20:22:252151 quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause
2152 quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:332153 ASYNC,
2154 ConstructOkResponsePacket(
2155 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true));
Zhongyi Shi63574b72018-06-01 20:22:252156 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
2157 quic_data1.AddSocketDataToFactory(socket_factory_.get());
2158
Ryan Hamiltonabad59e2019-06-06 04:02:592159 MockQuicData quic_data2(version_);
Zhongyi Shi63574b72018-06-01 20:22:252160 quic::QuicStreamOffset header_stream_offset2 = 0;
2161 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
2162 quic_data2.AddWrite(
2163 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset2));
2164 quic_data2.AddSocketDataToFactory(socket_factory_.get());
2165
2166 // Create request and QuicHttpStream.
2167 QuicStreamRequest request(factory_.get());
2168 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032169 request.Request(
Nick Harper23290b82019-05-02 00:02:562170 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:512171 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032172 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2173 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi63574b72018-06-01 20:22:252174 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2175 std::unique_ptr<HttpStream> stream = CreateStream(&request);
2176 EXPECT_TRUE(stream.get());
2177
2178 // Cause QUIC stream to be created.
2179 HttpRequestInfo request_info;
2180 request_info.method = "GET";
2181 request_info.url = url_;
2182 request_info.traffic_annotation =
2183 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2184 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
2185 net_log_, CompletionOnceCallback()));
2186
2187 // Ensure that session is alive and active.
2188 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
2189 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2190 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2191
2192 // Send GET request on stream.
2193 HttpResponseInfo response;
2194 HttpRequestHeaders request_headers;
2195 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
2196 callback_.callback()));
2197
2198 // Receive an IP address change notification.
2199 NotifyIPAddressChanged();
2200
2201 // The connection should still be alive, but marked as going away.
2202 EXPECT_FALSE(HasActiveSession(host_port_pair_));
2203 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2204 EXPECT_EQ(1u, session->GetNumActiveStreams());
2205
2206 // Resume the data, response should be read from the original connection.
2207 quic_data1.Resume();
2208 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
2209 EXPECT_EQ(200, response.headers->response_code());
2210 EXPECT_EQ(0u, session->GetNumActiveStreams());
2211
2212 // Second request should be sent on a new connection.
2213 QuicStreamRequest request2(factory_.get());
2214 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032215 request2.Request(
Nick Harper23290b82019-05-02 00:02:562216 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:512217 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032218 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2219 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi63574b72018-06-01 20:22:252220 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2221 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
2222 EXPECT_TRUE(stream2.get());
2223
2224 // Check an active session exisits for the destination.
2225 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2226 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2227 QuicChromiumClientSession* session2 = GetActiveSession(host_port_pair_);
2228 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2));
2229
2230 stream.reset();
2231 stream2.reset();
2232 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
2233 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
2234 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
2235 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
2236}
2237
Jana Iyengarba355772017-09-21 22:03:212238TEST_P(QuicStreamFactoryTest, OnIPAddressChangedWithConnectionMigration) {
Zhongyi Shi1a054612018-06-14 04:59:082239 InitializeConnectionMigrationV2Test(
Jana Iyengarba355772017-09-21 22:03:212240 {kDefaultNetworkForTests, kNewNetworkForTests});
2241 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2242 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2243 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2244
Ryan Hamiltonabad59e2019-06-06 04:02:592245 MockQuicData socket_data(version_);
Jana Iyengarba355772017-09-21 22:03:212246 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432247 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Ryan Hamilton8d9ee76e2018-05-29 23:52:522248 socket_data.AddWrite(
2249 SYNCHRONOUS, ConstructClientRstPacket(2, quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:172250 socket_data.AddSocketDataToFactory(socket_factory_.get());
Jana Iyengarba355772017-09-21 22:03:212251
2252 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332253 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032254 request.Request(
Nick Harper23290b82019-05-02 00:02:562255 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:512256 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032257 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2258 failed_on_default_network_callback_, callback_.callback()));
Jana Iyengarba355772017-09-21 22:03:212259
2260 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242261 std::unique_ptr<HttpStream> stream = CreateStream(&request);
Jana Iyengarba355772017-09-21 22:03:212262 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:392263 request_info.traffic_annotation =
2264 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272265 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392266 net_log_, CompletionOnceCallback()));
Jana Iyengarba355772017-09-21 22:03:212267
2268 IPAddress last_address;
2269 EXPECT_TRUE(http_server_properties_.GetSupportsQuic(&last_address));
2270
2271 // Change the IP address and verify that the connection is unaffected.
2272 NotifyIPAddressChanged();
2273 EXPECT_FALSE(factory_->require_confirmation());
2274 EXPECT_TRUE(http_server_properties_.GetSupportsQuic(&last_address));
2275
2276 // Attempting a new request to the same origin uses the same connection.
2277 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:512278 EXPECT_EQ(OK,
2279 request2.Request(
2280 host_port_pair_, version_.transport_version, privacy_mode_,
2281 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
2282 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2283 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:242284 stream = CreateStream(&request2);
Jana Iyengarba355772017-09-21 22:03:212285
2286 stream.reset();
2287 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2288 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2289}
2290
Zhongyi Shia0644e32018-06-21 05:19:522291TEST_P(QuicStreamFactoryTest, MigrateOnNetworkMadeDefaultWithSynchronousWrite) {
2292 TestMigrationOnNetworkMadeDefault(SYNCHRONOUS);
jri9f303712016-09-13 01:10:222293}
2294
Zhongyi Shia0644e32018-06-21 05:19:522295TEST_P(QuicStreamFactoryTest, MigrateOnNetworkMadeDefaultWithAsyncWrite) {
2296 TestMigrationOnNetworkMadeDefault(ASYNC);
jri9f303712016-09-13 01:10:222297}
2298
Zhongyi Shia0644e32018-06-21 05:19:522299// Sets up a test which attempts connection migration successfully after probing
2300// when a new network is made as default and the old default is still available.
2301// |write_mode| specifies the write mode for the last write before
2302// OnNetworkMadeDefault is delivered to session.
2303void QuicStreamFactoryTestBase::TestMigrationOnNetworkMadeDefault(
2304 IoMode write_mode) {
2305 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jri7e636642016-01-14 06:57:082306 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2307 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2308 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2309
Zhongyi Shia0644e32018-06-21 05:19:522310 // Using a testing task runner so that we can control time.
2311 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
2312 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
2313
2314 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2315 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
2316
Ryan Hamiltonabad59e2019-06-06 04:02:592317 MockQuicData quic_data1(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:522318 quic::QuicStreamOffset header_stream_offset = 0;
Zhongyi Shia0644e32018-06-21 05:19:522319 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging Read.
2320 quic_data1.AddWrite(SYNCHRONOUS,
2321 ConstructInitialSettingsPacket(1, &header_stream_offset));
2322 quic_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:332323 write_mode, ConstructGetRequestPacket(
2324 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
2325 true, &header_stream_offset));
Zhongyi Shia0644e32018-06-21 05:19:522326 quic_data1.AddSocketDataToFactory(socket_factory_.get());
2327
2328 // Set up the second socket data provider that is used after migration.
2329 // The response to the earlier request is read on the new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:592330 MockQuicData quic_data2(version_);
Zhongyi Shia0644e32018-06-21 05:19:522331 // Connectivity probe to be sent on the new path.
Zhongyi Shi879659422018-08-02 17:58:252332 quic_data2.AddWrite(SYNCHRONOUS,
2333 client_maker_.MakeConnectivityProbingPacket(3, true));
Zhongyi Shia0644e32018-06-21 05:19:522334 quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause
2335 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:252336 quic_data2.AddRead(ASYNC,
2337 server_maker_.MakeConnectivityProbingPacket(1, false));
Zhongyi Shia0644e32018-06-21 05:19:522338 // Ping packet to send after migration is completed.
2339 quic_data2.AddWrite(ASYNC,
2340 client_maker_.MakeAckAndPingPacket(4, false, 1, 1, 1));
2341 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:332342 ASYNC,
2343 ConstructOkResponsePacket(
2344 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shia0644e32018-06-21 05:19:522345 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:332346 quic_data2.AddWrite(
2347 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
2348 5, false, GetNthClientInitiatedBidirectionalStreamId(0),
2349 quic::QUIC_STREAM_CANCELLED, 2, 2, 1, true));
Zhongyi Shia0644e32018-06-21 05:19:522350 quic_data2.AddSocketDataToFactory(socket_factory_.get());
jri7e636642016-01-14 06:57:082351
2352 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:452353 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332354 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032355 request.Request(
Nick Harper23290b82019-05-02 00:02:562356 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:512357 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032358 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2359 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:012360 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242361 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri7e636642016-01-14 06:57:082362 EXPECT_TRUE(stream.get());
2363
2364 // Cause QUIC stream to be created.
2365 HttpRequestInfo request_info;
2366 request_info.method = "GET";
bnc3d9035b32016-06-30 18:18:482367 request_info.url = url_;
Ramin Halavati683bcaa92018-02-14 08:42:392368 request_info.traffic_annotation =
2369 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272370 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392371 net_log_, CompletionOnceCallback()));
jri7e636642016-01-14 06:57:082372
2373 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:502374 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri7e636642016-01-14 06:57:082375 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2376 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2377
2378 // Send GET request on stream.
2379 HttpResponseInfo response;
2380 HttpRequestHeaders request_headers;
2381 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
2382 callback_.callback()));
2383
Zhongyi Shia0644e32018-06-21 05:19:522384 // Deliver a signal that a alternate network is connected now, this should
2385 // cause the connection to start early migration on path degrading.
2386 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2387 ->SetConnectedNetworksList(
2388 {kDefaultNetworkForTests, kNewNetworkForTests});
2389 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2390 ->NotifyNetworkConnected(kNewNetworkForTests);
jri9f303712016-09-13 01:10:222391
Zhongyi Shia0644e32018-06-21 05:19:522392 // Cause the connection to report path degrading to the session.
2393 // Due to lack of alternate network, session will not mgirate connection.
2394 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
jri7e636642016-01-14 06:57:082395 scoped_mock_network_change_notifier_->mock_network_change_notifier()
jrie2661982016-08-20 08:24:342396 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
jri7e636642016-01-14 06:57:082397
Zhongyi Shia0644e32018-06-21 05:19:522398 // A task will be posted to migrate to the new default network.
2399 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
2400 EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay());
2401
2402 // Execute the posted task to migrate back to the default network.
2403 task_runner->RunUntilIdle();
2404 // Another task to try send a new connectivity probe is posted. And a task to
2405 // retry migrate back to default network is scheduled.
2406 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
2407 // Next connectivity probe is scheduled to be sent in 2 *
2408 // kDefaultRTTMilliSecs.
2409 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
2410 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
2411 next_task_delay);
2412
2413 // The connection should still be alive, and not marked as going away.
jri7e636642016-01-14 06:57:082414 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia0644e32018-06-21 05:19:522415 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2416 EXPECT_EQ(1u, session->GetNumActiveStreams());
2417 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
2418
2419 // Resume quic data and a connectivity probe response will be read on the new
2420 // socket, declare probing as successful. And a new task to WriteToNewSocket
2421 // will be posted to complete migration.
2422 quic_data2.Resume();
2423
2424 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2425 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri7e636642016-01-14 06:57:082426 EXPECT_EQ(1u, session->GetNumActiveStreams());
2427
Zhongyi Shia0644e32018-06-21 05:19:522428 // There should be three pending tasks, the nearest one will complete
2429 // migration to the new network.
2430 EXPECT_EQ(3u, task_runner->GetPendingTaskCount());
2431 next_task_delay = task_runner->NextPendingTaskDelay();
2432 EXPECT_EQ(base::TimeDelta(), next_task_delay);
2433 task_runner->FastForwardBy(next_task_delay);
2434
2435 // Response headers are received over the new network.
2436 EXPECT_THAT(callback_.WaitForResult(), IsOk());
jri7e636642016-01-14 06:57:082437 EXPECT_EQ(200, response.headers->response_code());
2438
Zhongyi Shia0644e32018-06-21 05:19:522439 // Now there are two pending tasks, the nearest one was to send connectivity
2440 // probe and has been cancelled due to successful migration.
2441 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
2442 next_task_delay = task_runner->NextPendingTaskDelay();
2443 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
2444 next_task_delay);
2445 task_runner->FastForwardBy(next_task_delay);
jri7e636642016-01-14 06:57:082446
Zhongyi Shia0644e32018-06-21 05:19:522447 // There's one more task to mgirate back to the default network in 0.4s, which
2448 // is also cancelled due to the success migration on the previous trial.
2449 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
2450 next_task_delay = task_runner->NextPendingTaskDelay();
2451 base::TimeDelta expected_delay =
2452 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) -
2453 base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs);
2454 EXPECT_EQ(expected_delay, next_task_delay);
2455 task_runner->FastForwardBy(next_task_delay);
2456 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
jri7e636642016-01-14 06:57:082457
Zhongyi Shia0644e32018-06-21 05:19:522458 // Verify that the session is still alive.
jri7e636642016-01-14 06:57:082459 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia0644e32018-06-21 05:19:522460 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri7e636642016-01-14 06:57:082461
Zhongyi Shia0644e32018-06-21 05:19:522462 stream.reset();
2463 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
2464 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
2465 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
2466 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
jri7e636642016-01-14 06:57:082467}
2468
Zhongyi Shib3bc982c2018-07-10 19:59:242469// Regression test for http://859674.
2470// This test veries that a writer will not attempt to write packets until being
2471// unblocked on both socket level and network level. In this test, a probing
2472// writer is used to send two connectivity probes to the peer: where the first
2473// one completes successfully, while a connectivity response is received before
2474// completes sending the second one. The connection migration attempt will
2475// proceed while the probing writer is blocked at the socket level, which will
2476// block the writer on the network level. Once connection migration completes
2477// successfully, the probing writer will be unblocked on the network level, it
2478// will not attempt to write new packets until the socket level is unblocked.
2479TEST_P(QuicStreamFactoryTest, MigratedToBlockedSocketAfterProbing) {
2480 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
2481 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2482 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2483 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2484
2485 // Using a testing task runner so that we can control time.
2486 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
2487 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
2488
2489 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2490 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
2491
Ryan Hamiltonabad59e2019-06-06 04:02:592492 MockQuicData quic_data1(version_);
Zhongyi Shib3bc982c2018-07-10 19:59:242493 quic::QuicStreamOffset header_stream_offset = 0;
2494 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging Read.
2495 quic_data1.AddWrite(SYNCHRONOUS,
2496 ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:332497 quic_data1.AddWrite(
2498 SYNCHRONOUS, ConstructGetRequestPacket(
2499 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
2500 true, &header_stream_offset));
Zhongyi Shib3bc982c2018-07-10 19:59:242501 quic_data1.AddSocketDataToFactory(socket_factory_.get());
2502
2503 // Set up the second socket data provider that is used after migration.
2504 // The response to the earlier request is read on the new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:592505 MockQuicData quic_data2(version_);
Zhongyi Shib3bc982c2018-07-10 19:59:242506 // First connectivity probe to be sent on the new path.
Zhongyi Shi879659422018-08-02 17:58:252507 quic_data2.AddWrite(SYNCHRONOUS,
2508 client_maker_.MakeConnectivityProbingPacket(3, true));
Zhongyi Shib3bc982c2018-07-10 19:59:242509 quic_data2.AddRead(ASYNC,
2510 ERR_IO_PENDING); // Pause so that we can control time.
2511 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:252512 quic_data2.AddRead(ASYNC,
2513 server_maker_.MakeConnectivityProbingPacket(1, false));
Zhongyi Shib3bc982c2018-07-10 19:59:242514 // Second connectivity probe which will complete asynchronously.
Zhongyi Shi879659422018-08-02 17:58:252515 quic_data2.AddWrite(ASYNC,
2516 client_maker_.MakeConnectivityProbingPacket(4, true));
Zhongyi Shib3bc982c2018-07-10 19:59:242517 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:332518 ASYNC,
2519 ConstructOkResponsePacket(
2520 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shib3bc982c2018-07-10 19:59:242521 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2522 quic_data2.AddWrite(ASYNC,
2523 client_maker_.MakeAckAndPingPacket(5, false, 1, 1, 1));
Fan Yang32c5a112018-12-10 20:06:332524 quic_data2.AddWrite(
2525 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
2526 6, false, GetNthClientInitiatedBidirectionalStreamId(0),
2527 quic::QUIC_STREAM_CANCELLED, 2, 2, 1, true));
Zhongyi Shib3bc982c2018-07-10 19:59:242528
2529 quic_data2.AddSocketDataToFactory(socket_factory_.get());
2530
2531 // Create request and QuicHttpStream.
2532 QuicStreamRequest request(factory_.get());
2533 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032534 request.Request(
Nick Harper23290b82019-05-02 00:02:562535 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:512536 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032537 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2538 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shib3bc982c2018-07-10 19:59:242539 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2540 std::unique_ptr<HttpStream> stream = CreateStream(&request);
2541 EXPECT_TRUE(stream.get());
2542
2543 // Cause QUIC stream to be created.
2544 HttpRequestInfo request_info;
2545 request_info.method = "GET";
2546 request_info.url = url_;
2547 request_info.traffic_annotation =
2548 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
2549 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
2550 net_log_, CompletionOnceCallback()));
2551
2552 // Ensure that session is alive and active.
2553 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
2554 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2555 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2556
2557 // Send GET request on stream.
2558 HttpResponseInfo response;
2559 HttpRequestHeaders request_headers;
2560 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
2561 callback_.callback()));
2562
2563 // Deliver a signal that a alternate network is connected now, this should
2564 // cause the connection to start early migration on path degrading.
2565 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2566 ->SetConnectedNetworksList(
2567 {kDefaultNetworkForTests, kNewNetworkForTests});
2568 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2569 ->NotifyNetworkConnected(kNewNetworkForTests);
2570
2571 // Cause the connection to report path degrading to the session.
2572 // Due to lack of alternate network, session will not mgirate connection.
2573 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
2574 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2575 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
2576
2577 // A task will be posted to migrate to the new default network.
2578 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
2579 EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay());
2580
2581 // Execute the posted task to migrate back to the default network.
2582 task_runner->RunUntilIdle();
2583 // Another task to resend a new connectivity probe is posted. And a task to
2584 // retry migrate back to default network is scheduled.
2585 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
2586 // Next connectivity probe is scheduled to be sent in 2 *
2587 // kDefaultRTTMilliSecs.
2588 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
2589 base::TimeDelta expected_delay =
2590 base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs);
2591 EXPECT_EQ(expected_delay, next_task_delay);
2592
2593 // Fast forward to send the second connectivity probe. The write will be
2594 // asynchronous and complete after the read completes.
2595 task_runner->FastForwardBy(next_task_delay);
2596
2597 // Resume quic data and a connectivity probe response will be read on the new
2598 // socket, declare probing as successful.
2599 quic_data2.Resume();
2600
2601 // The connection should still be alive, and not marked as going away.
2602 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2603 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2604 EXPECT_EQ(1u, session->GetNumActiveStreams());
2605 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
2606
2607 // There should be three pending tasks, the nearest one will complete
2608 // migration to the new network. Second task will retry migrate back to
2609 // default but cancelled, and the third task will retry send connectivity
2610 // probe but also cancelled.
2611 EXPECT_EQ(3u, task_runner->GetPendingTaskCount());
2612 EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay());
2613 task_runner->RunUntilIdle();
2614
2615 // Response headers are received over the new network.
2616 EXPECT_THAT(callback_.WaitForResult(), IsOk());
2617 EXPECT_EQ(200, response.headers->response_code());
2618
2619 // Run the message loop to complete the asynchronous write of ack and ping.
2620 base::RunLoop().RunUntilIdle();
2621
2622 // Now there are two pending tasks, the nearest one was to retry migrate back
2623 // to default network and has been cancelled due to successful migration.
2624 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
2625 expected_delay =
2626 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) -
2627 expected_delay;
2628 next_task_delay = task_runner->NextPendingTaskDelay();
2629 EXPECT_EQ(expected_delay, next_task_delay);
2630 task_runner->FastForwardBy(next_task_delay);
2631
2632 // There's one more task to retry sending connectivity probe in 0.4s and has
2633 // also been cancelled due to the successful probing.
2634 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
2635 next_task_delay = task_runner->NextPendingTaskDelay();
2636 expected_delay =
2637 base::TimeDelta::FromMilliseconds(3 * 2 * kDefaultRTTMilliSecs) -
2638 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs);
2639 EXPECT_EQ(expected_delay, next_task_delay);
2640 task_runner->FastForwardBy(next_task_delay);
2641 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
2642
2643 // Verify that the session is still alive.
2644 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2645 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2646
2647 stream.reset();
2648 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
2649 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
2650 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
2651 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
2652}
2653
Zhongyi Shib1b1fa42018-06-19 23:13:472654// This test verifies that session times out connection migration attempt
2655// with signals delivered in the following order (no alternate network is
2656// available):
2657// - default network disconnected is delivered: session attempts connection
2658// migration but found not alternate network. Session waits for a new network
Zhongyi Shie01f2db2019-02-22 19:53:232659// comes up in the next kWaitTimeForNewNetworkSecs seconds.
Zhongyi Shib1b1fa42018-06-19 23:13:472660// - no new network is connected, migration times out. Session is closed.
2661TEST_P(QuicStreamFactoryTest, MigrationTimeoutWithNoNewNetwork) {
2662 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jri7e636642016-01-14 06:57:082663 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2664 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2665
Zhongyi Shib1b1fa42018-06-19 23:13:472666 // Using a testing task runner so that we can control time.
2667 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
2668 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
jri5b785512016-09-13 04:29:112669
Ryan Hamiltonabad59e2019-06-06 04:02:592670 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:362671 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432672 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:172673 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri7e636642016-01-14 06:57:082674
2675 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:452676 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332677 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032678 request.Request(
Nick Harper23290b82019-05-02 00:02:562679 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:512680 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032681 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2682 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:012683 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242684 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri7e636642016-01-14 06:57:082685 EXPECT_TRUE(stream.get());
2686
2687 // Cause QUIC stream to be created.
2688 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:392689 request_info.traffic_annotation =
2690 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272691 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392692 net_log_, CompletionOnceCallback()));
jri7e636642016-01-14 06:57:082693
2694 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:502695 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri7e636642016-01-14 06:57:082696 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2697 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2698
2699 // Trigger connection migration. Since there are no networks
jri5b785512016-09-13 04:29:112700 // to migrate to, this should cause the session to wait for a new network.
jri7e636642016-01-14 06:57:082701 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2702 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
2703
jri5b785512016-09-13 04:29:112704 // The migration will not fail until the migration alarm timeout.
2705 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shib1b1fa42018-06-19 23:13:472706 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri5b785512016-09-13 04:29:112707 EXPECT_EQ(1u, session->GetNumActiveStreams());
2708 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
2709 EXPECT_EQ(true, session->connection()->writer()->IsWriteBlocked());
2710
Zhongyi Shib1b1fa42018-06-19 23:13:472711 // Migration will be timed out after kWaitTimeForNewNetwokSecs.
2712 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
2713 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
2714 EXPECT_EQ(base::TimeDelta::FromSeconds(kWaitTimeForNewNetworkSecs),
2715 next_task_delay);
2716 task_runner->FastForwardBy(next_task_delay);
jri5b785512016-09-13 04:29:112717
2718 // The connection should now be closed. A request for response
2719 // headers should fail.
jri7e636642016-01-14 06:57:082720 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2721 EXPECT_FALSE(HasActiveSession(host_port_pair_));
jri5b785512016-09-13 04:29:112722 EXPECT_EQ(ERR_NETWORK_CHANGED, callback_.WaitForResult());
jri7e636642016-01-14 06:57:082723
2724 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2725 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2726}
2727
Zhongyi Shi21e99532018-07-17 22:23:072728// This test verifies that connectivity probes will be sent even if there is
2729// a non-migratable stream. However, when connection migrates to the
Zhongyi Shic16b4102019-02-12 00:37:402730// successfully probed path, any non-migratable streams will be reset.
Zhongyi Shi32fe14d42019-02-28 00:25:362731TEST_P(QuicStreamFactoryTest,
2732 OnNetworkMadeDefaultNonMigratableStream_MigrateIdleSessions) {
2733 TestOnNetworkMadeDefaultNonMigratableStream(true);
2734}
2735
2736// This test verifies that connectivity probes will be sent even if there is
2737// a non-migratable stream. However, when connection migrates to the
2738// successfully probed path, any non-migratable stream will be reset. And if
2739// the connection becomes idle then, close the connection.
2740TEST_P(QuicStreamFactoryTest,
2741 OnNetworkMadeDefaultNonMigratableStream_DoNotMigrateIdleSessions) {
2742 TestOnNetworkMadeDefaultNonMigratableStream(false);
2743}
2744
2745void QuicStreamFactoryTestBase::TestOnNetworkMadeDefaultNonMigratableStream(
2746 bool migrate_idle_sessions) {
2747 test_params_.quic_migrate_idle_sessions = migrate_idle_sessions;
Zhongyi Shi5f587cc2017-11-21 23:24:172748 InitializeConnectionMigrationV2Test(
2749 {kDefaultNetworkForTests, kNewNetworkForTests});
2750 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2751 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2752
Ryan Hamiltonabad59e2019-06-06 04:02:592753 MockQuicData socket_data(version_);
Zhongyi Shi5f587cc2017-11-21 23:24:172754 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432755 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi32fe14d42019-02-28 00:25:362756 if (!migrate_idle_sessions) {
2757 socket_data.AddWrite(
2758 SYNCHRONOUS,
2759 client_maker_.MakeRstAckAndConnectionClosePacket(
2760 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
2761 quic::QUIC_STREAM_CANCELLED,
2762 quic::QuicTime::Delta::FromMilliseconds(0), 1, 1, 1,
2763 quic::QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS,
2764 "net error"));
2765 }
Renjieba55fae2018-09-20 03:05:162766
Zhongyi Shi5f587cc2017-11-21 23:24:172767 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri231c2972016-03-08 19:50:112768
Zhongyi Shi21e99532018-07-17 22:23:072769 // Set up the second socket data provider that is used for probing.
Ryan Hamiltonabad59e2019-06-06 04:02:592770 MockQuicData quic_data1(version_);
Zhongyi Shi21e99532018-07-17 22:23:072771 // Connectivity probe to be sent on the new path.
Zhongyi Shi879659422018-08-02 17:58:252772 quic_data1.AddWrite(SYNCHRONOUS,
2773 client_maker_.MakeConnectivityProbingPacket(2, true));
Zhongyi Shi21e99532018-07-17 22:23:072774 quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause
2775 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:252776 quic_data1.AddRead(ASYNC,
2777 server_maker_.MakeConnectivityProbingPacket(1, false));
Zhongyi Shi32fe14d42019-02-28 00:25:362778 if (migrate_idle_sessions) {
2779 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
2780 // A RESET will be sent to the peer to cancel the non-migratable stream.
2781 quic_data1.AddWrite(
2782 SYNCHRONOUS,
2783 client_maker_.MakeRstPacket(
2784 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
2785 quic::QUIC_STREAM_CANCELLED));
2786 // Ping packet to send after migration is completed.
2787 quic_data1.AddWrite(SYNCHRONOUS,
2788 client_maker_.MakeAckAndPingPacket(4, false, 1, 1, 1));
2789 }
Zhongyi Shi21e99532018-07-17 22:23:072790 quic_data1.AddSocketDataToFactory(socket_factory_.get());
2791
jri231c2972016-03-08 19:50:112792 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:452793 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332794 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032795 request.Request(
Nick Harper23290b82019-05-02 00:02:562796 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:512797 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032798 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2799 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:012800 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242801 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri231c2972016-03-08 19:50:112802 EXPECT_TRUE(stream.get());
2803
2804 // Cause QUIC stream to be created, but marked as non-migratable.
2805 HttpRequestInfo request_info;
Zhongyi Shibb28b1f2018-07-18 02:41:262806 request_info.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
Ramin Halavati683bcaa92018-02-14 08:42:392807 request_info.traffic_annotation =
2808 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272809 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392810 net_log_, CompletionOnceCallback()));
jri231c2972016-03-08 19:50:112811
2812 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:502813 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri231c2972016-03-08 19:50:112814 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2815 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2816
Zhongyi Shi21e99532018-07-17 22:23:072817 // Trigger connection migration. Session will start to probe the alternative
2818 // network. Although there is a non-migratable stream, session will still be
2819 // active until probing is declared as successful.
jri231c2972016-03-08 19:50:112820 scoped_mock_network_change_notifier_->mock_network_change_notifier()
jrie2661982016-08-20 08:24:342821 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
jri231c2972016-03-08 19:50:112822
2823 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shi21e99532018-07-17 22:23:072824 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri231c2972016-03-08 19:50:112825 EXPECT_EQ(1u, session->GetNumActiveStreams());
2826
Zhongyi Shi21e99532018-07-17 22:23:072827 // Resume data to read a connectivity probing response, which will cause
Zhongyi Shic16b4102019-02-12 00:37:402828 // non-migtable streams to be closed.
Zhongyi Shi21e99532018-07-17 22:23:072829 quic_data1.Resume();
2830 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shi32fe14d42019-02-28 00:25:362831 EXPECT_EQ(migrate_idle_sessions, HasActiveSession(host_port_pair_));
Zhongyi Shi21e99532018-07-17 22:23:072832 EXPECT_EQ(0u, session->GetNumActiveStreams());
jri231c2972016-03-08 19:50:112833
Zhongyi Shic16b4102019-02-12 00:37:402834 base::RunLoop().RunUntilIdle();
2835
Zhongyi Shi21e99532018-07-17 22:23:072836 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
2837 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
jri231c2972016-03-08 19:50:112838 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2839 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2840}
2841
jri9f303712016-09-13 01:10:222842TEST_P(QuicStreamFactoryTest, OnNetworkMadeDefaultConnectionMigrationDisabled) {
Zhongyi Shi5f587cc2017-11-21 23:24:172843 InitializeConnectionMigrationV2Test(
2844 {kDefaultNetworkForTests, kNewNetworkForTests});
2845 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2846 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2847
Ryan Hamiltonabad59e2019-06-06 04:02:592848 MockQuicData socket_data(version_);
Zhongyi Shi5f587cc2017-11-21 23:24:172849 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:432850 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
2851 socket_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:332852 SYNCHRONOUS, client_maker_.MakeRstPacket(
2853 2, true, GetNthClientInitiatedBidirectionalStreamId(0),
2854 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:172855 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9c541572016-03-29 17:51:482856
2857 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:452858 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332859 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032860 request.Request(
Nick Harper23290b82019-05-02 00:02:562861 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:512862 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032863 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2864 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:012865 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242866 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9c541572016-03-29 17:51:482867 EXPECT_TRUE(stream.get());
2868
2869 // Cause QUIC stream to be created.
2870 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:392871 request_info.traffic_annotation =
2872 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272873 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392874 net_log_, CompletionOnceCallback()));
jri9c541572016-03-29 17:51:482875
2876 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:502877 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri9c541572016-03-29 17:51:482878 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2879 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2880
2881 // Set session config to have connection migration disabled.
Ryan Hamilton8d9ee76e2018-05-29 23:52:522882 quic::test::QuicConfigPeer::SetReceivedDisableConnectionMigration(
2883 session->config());
jri9c541572016-03-29 17:51:482884 EXPECT_TRUE(session->config()->DisableConnectionMigration());
2885
2886 // Trigger connection migration. Since there is a non-migratable stream,
2887 // this should cause session to continue but be marked as going away.
2888 scoped_mock_network_change_notifier_->mock_network_change_notifier()
jrie2661982016-08-20 08:24:342889 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
jri9c541572016-03-29 17:51:482890
2891 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2892 EXPECT_FALSE(HasActiveSession(host_port_pair_));
2893 EXPECT_EQ(1u, session->GetNumActiveStreams());
2894
2895 stream.reset();
2896
2897 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2898 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2899}
2900
Zhongyi Shi32fe14d42019-02-28 00:25:362901TEST_P(QuicStreamFactoryTest,
2902 OnNetworkDisconnectedNonMigratableStream_DoNotMigrateIdleSessions) {
2903 TestOnNetworkDisconnectedNonMigratableStream(false);
2904}
2905
2906TEST_P(QuicStreamFactoryTest,
2907 OnNetworkDisconnectedNonMigratableStream_MigrateIdleSessions) {
2908 TestOnNetworkDisconnectedNonMigratableStream(true);
2909}
2910
2911void QuicStreamFactoryTestBase::TestOnNetworkDisconnectedNonMigratableStream(
2912 bool migrate_idle_sessions) {
2913 test_params_.quic_migrate_idle_sessions = migrate_idle_sessions;
Zhongyi Shi5f587cc2017-11-21 23:24:172914 InitializeConnectionMigrationV2Test(
2915 {kDefaultNetworkForTests, kNewNetworkForTests});
2916 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
2917 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2918
Ryan Hamiltonabad59e2019-06-06 04:02:592919 MockQuicData failed_socket_data(version_);
2920 MockQuicData socket_data(version_);
Zhongyi Shi32fe14d42019-02-28 00:25:362921 if (migrate_idle_sessions) {
2922 quic::QuicStreamOffset header_stream_offset = 0;
2923 failed_socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2924 failed_socket_data.AddWrite(
2925 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
2926 // A RESET will be sent to the peer to cancel the non-migratable stream.
2927 failed_socket_data.AddWrite(
2928 SYNCHRONOUS, client_maker_.MakeRstPacket(
2929 2, true, GetNthClientInitiatedBidirectionalStreamId(0),
2930 quic::QUIC_STREAM_CANCELLED));
2931 failed_socket_data.AddSocketDataToFactory(socket_factory_.get());
2932
2933 // Set up second socket data provider that is used after migration.
2934 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
2935 // Ping packet to send after migration.
2936 socket_data.AddWrite(
2937 SYNCHRONOUS, client_maker_.MakePingPacket(3, /*include_version=*/true));
2938 socket_data.AddSocketDataToFactory(socket_factory_.get());
2939 } else {
2940 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
2941 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
2942 socket_data.AddWrite(
2943 SYNCHRONOUS, client_maker_.MakeRstPacket(
2944 2, true, GetNthClientInitiatedBidirectionalStreamId(0),
2945 quic::QUIC_STREAM_CANCELLED));
2946 socket_data.AddSocketDataToFactory(socket_factory_.get());
2947 }
jri231c2972016-03-08 19:50:112948
2949 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:452950 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:332951 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:032952 request.Request(
Nick Harper23290b82019-05-02 00:02:562953 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:512954 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:032955 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
2956 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:012957 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:242958 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri231c2972016-03-08 19:50:112959 EXPECT_TRUE(stream.get());
2960
2961 // Cause QUIC stream to be created, but marked as non-migratable.
2962 HttpRequestInfo request_info;
Zhongyi Shibb28b1f2018-07-18 02:41:262963 request_info.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
Ramin Halavati683bcaa92018-02-14 08:42:392964 request_info.traffic_annotation =
2965 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:272966 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:392967 net_log_, CompletionOnceCallback()));
jri231c2972016-03-08 19:50:112968
2969 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:502970 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri231c2972016-03-08 19:50:112971 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2972 EXPECT_TRUE(HasActiveSession(host_port_pair_));
2973
2974 // Trigger connection migration. Since there is a non-migratable stream,
2975 // this should cause a RST_STREAM frame to be emitted with
Zhongyi Shic16b4102019-02-12 00:37:402976 // quic::QUIC_STREAM_CANCELLED error code.
Zhongyi Shi32fe14d42019-02-28 00:25:362977 // If migate idle session, the connection will then be migrated to the
2978 // alternate network. Otherwise, the connection will be closed.
jri231c2972016-03-08 19:50:112979 scoped_mock_network_change_notifier_->mock_network_change_notifier()
2980 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
2981
Zhongyi Shi32fe14d42019-02-28 00:25:362982 EXPECT_EQ(migrate_idle_sessions,
2983 QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
2984 EXPECT_EQ(migrate_idle_sessions, HasActiveSession(host_port_pair_));
jri231c2972016-03-08 19:50:112985
Zhongyi Shi32fe14d42019-02-28 00:25:362986 if (migrate_idle_sessions) {
2987 EXPECT_EQ(0u, session->GetNumActiveStreams());
2988 base::RunLoop().RunUntilIdle();
Zhongyi Shic16b4102019-02-12 00:37:402989
Zhongyi Shi32fe14d42019-02-28 00:25:362990 EXPECT_TRUE(failed_socket_data.AllReadDataConsumed());
2991 EXPECT_TRUE(failed_socket_data.AllWriteDataConsumed());
2992 }
jri231c2972016-03-08 19:50:112993 EXPECT_TRUE(socket_data.AllReadDataConsumed());
2994 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
2995}
2996
jri9c541572016-03-29 17:51:482997TEST_P(QuicStreamFactoryTest,
jri9f303712016-09-13 01:10:222998 OnNetworkDisconnectedConnectionMigrationDisabled) {
Zhongyi Shi5f587cc2017-11-21 23:24:172999 InitializeConnectionMigrationV2Test(
3000 {kDefaultNetworkForTests, kNewNetworkForTests});
3001 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3002 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3003
Ryan Hamiltonabad59e2019-06-06 04:02:593004 MockQuicData socket_data(version_);
Zhongyi Shi5f587cc2017-11-21 23:24:173005 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:433006 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
3007 socket_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:333008 SYNCHRONOUS, client_maker_.MakeRstPacket(
3009 2, true, GetNthClientInitiatedBidirectionalStreamId(0),
3010 quic::QUIC_RST_ACKNOWLEDGEMENT));
Zhongyi Shi5f587cc2017-11-21 23:24:173011 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9c541572016-03-29 17:51:483012
3013 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:453014 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:333015 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:033016 request.Request(
Nick Harper23290b82019-05-02 00:02:563017 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:513018 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:033019 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
3020 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:013021 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:243022 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9c541572016-03-29 17:51:483023 EXPECT_TRUE(stream.get());
3024
3025 // Cause QUIC stream to be created.
3026 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:393027 request_info.traffic_annotation =
3028 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:273029 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:393030 net_log_, CompletionOnceCallback()));
jri9c541572016-03-29 17:51:483031
3032 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:503033 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri9c541572016-03-29 17:51:483034 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3035 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3036
3037 // Set session config to have connection migration disabled.
Ryan Hamilton8d9ee76e2018-05-29 23:52:523038 quic::test::QuicConfigPeer::SetReceivedDisableConnectionMigration(
3039 session->config());
jri9c541572016-03-29 17:51:483040 EXPECT_TRUE(session->config()->DisableConnectionMigration());
3041
3042 // Trigger connection migration. Since there is a non-migratable stream,
3043 // this should cause a RST_STREAM frame to be emitted with
Ryan Hamilton8d9ee76e2018-05-29 23:52:523044 // quic::QUIC_RST_ACKNOWLEDGEMENT error code, and the session will be closed.
jri9c541572016-03-29 17:51:483045 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3046 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
3047
3048 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3049 EXPECT_FALSE(HasActiveSession(host_port_pair_));
3050
3051 EXPECT_TRUE(socket_data.AllReadDataConsumed());
3052 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
3053}
3054
Zhongyi Shi32fe14d42019-02-28 00:25:363055TEST_P(QuicStreamFactoryTest,
3056 OnNetworkMadeDefaultNoOpenStreams_DoNotMigrateIdleSessions) {
3057 TestOnNetworkMadeDefaultNoOpenStreams(false);
3058}
3059
3060TEST_P(QuicStreamFactoryTest,
3061 OnNetworkMadeDefaultNoOpenStreams_MigrateIdleSessions) {
3062 TestOnNetworkMadeDefaultNoOpenStreams(true);
3063}
3064
3065void QuicStreamFactoryTestBase::TestOnNetworkMadeDefaultNoOpenStreams(
3066 bool migrate_idle_sessions) {
3067 test_params_.quic_migrate_idle_sessions = migrate_idle_sessions;
Zhongyi Shi5f587cc2017-11-21 23:24:173068 InitializeConnectionMigrationV2Test(
3069 {kDefaultNetworkForTests, kNewNetworkForTests});
3070 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3071 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3072
Ryan Hamiltonabad59e2019-06-06 04:02:593073 MockQuicData socket_data(version_);
Zhongyi Shi5f587cc2017-11-21 23:24:173074 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:433075 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi32fe14d42019-02-28 00:25:363076 if (!migrate_idle_sessions) {
3077 socket_data.AddWrite(
3078 SYNCHRONOUS,
3079 client_maker_.MakeConnectionClosePacket(
3080 2, true, quic::QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS,
3081 "net error"));
3082 }
Zhongyi Shi5f587cc2017-11-21 23:24:173083 socket_data.AddSocketDataToFactory(socket_factory_.get());
3084
Ryan Hamiltonabad59e2019-06-06 04:02:593085 MockQuicData quic_data1(version_);
Zhongyi Shi32fe14d42019-02-28 00:25:363086 if (migrate_idle_sessions) {
3087 // Set up the second socket data provider that is used for probing.
3088 // Connectivity probe to be sent on the new path.
3089 quic_data1.AddWrite(SYNCHRONOUS,
3090 client_maker_.MakeConnectivityProbingPacket(2, true));
3091 quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3092 // Connectivity probe to receive from the server.
3093 quic_data1.AddRead(ASYNC,
3094 server_maker_.MakeConnectivityProbingPacket(1, false));
3095 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
3096 // Ping packet to send after migration is completed.
3097 quic_data1.AddWrite(SYNCHRONOUS,
3098 client_maker_.MakeAckAndPingPacket(3, false, 1, 1, 1));
3099 quic_data1.AddSocketDataToFactory(socket_factory_.get());
3100 }
Zhongyi Shic16b4102019-02-12 00:37:403101
Zhongyi Shi5f587cc2017-11-21 23:24:173102 // Create request and QuicHttpStream.
3103 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:333104 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:033105 request.Request(
Nick Harper23290b82019-05-02 00:02:563106 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:513107 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:033108 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
3109 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi5f587cc2017-11-21 23:24:173110 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3111 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3112 EXPECT_TRUE(stream.get());
3113
3114 // Ensure that session is alive and active.
3115 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3116 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3117 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shic16b4102019-02-12 00:37:403118 EXPECT_EQ(0u, session->GetNumActiveStreams());
3119 EXPECT_EQ(0u, session->GetNumDrainingStreams());
Zhongyi Shi5f587cc2017-11-21 23:24:173120
3121 // Trigger connection migration.
3122 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3123 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
Zhongyi Shi32fe14d42019-02-28 00:25:363124 EXPECT_EQ(migrate_idle_sessions, HasActiveSession(host_port_pair_));
Zhongyi Shi5f587cc2017-11-21 23:24:173125
Zhongyi Shi32fe14d42019-02-28 00:25:363126 if (migrate_idle_sessions) {
3127 quic_data1.Resume();
3128 base::RunLoop().RunUntilIdle();
3129 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
3130 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
3131 }
Zhongyi Shi5f587cc2017-11-21 23:24:173132 EXPECT_TRUE(socket_data.AllReadDataConsumed());
3133 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
3134}
3135
Zhongyi Shi32fe14d42019-02-28 00:25:363136TEST_P(QuicStreamFactoryTest,
3137 OnNetworkDisconnectedNoOpenStreams_DoNotMigateIdleSessions) {
3138 TestOnNetworkDisconnectedNoOpenStreams(false);
3139}
3140
3141TEST_P(QuicStreamFactoryTest,
3142 OnNetworkDisconnectedNoOpenStreams_MigateIdleSessions) {
3143 TestOnNetworkDisconnectedNoOpenStreams(true);
3144}
3145
3146void QuicStreamFactoryTestBase::TestOnNetworkDisconnectedNoOpenStreams(
3147 bool migrate_idle_sessions) {
3148 test_params_.quic_migrate_idle_sessions = migrate_idle_sessions;
Zhongyi Shi5f587cc2017-11-21 23:24:173149 InitializeConnectionMigrationV2Test(
3150 {kDefaultNetworkForTests, kNewNetworkForTests});
3151 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3152 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3153
Ryan Hamiltonabad59e2019-06-06 04:02:593154 MockQuicData default_socket_data(version_);
Zhongyi Shic16b4102019-02-12 00:37:403155 default_socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
3156 default_socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
3157 default_socket_data.AddSocketDataToFactory(socket_factory_.get());
3158
Ryan Hamiltonabad59e2019-06-06 04:02:593159 MockQuicData alternate_socket_data(version_);
Zhongyi Shi32fe14d42019-02-28 00:25:363160 if (migrate_idle_sessions) {
3161 // Set up second socket data provider that is used after migration.
3162 alternate_socket_data.AddRead(SYNCHRONOUS,
3163 ERR_IO_PENDING); // Hanging read.
3164 // Ping packet to send after migration.
3165 alternate_socket_data.AddWrite(
3166 SYNCHRONOUS, client_maker_.MakePingPacket(2, /*include_version=*/true));
3167 alternate_socket_data.AddSocketDataToFactory(socket_factory_.get());
3168 }
Zhongyi Shi5f587cc2017-11-21 23:24:173169
3170 // Create request and QuicHttpStream.
3171 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:333172 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:033173 request.Request(
Nick Harper23290b82019-05-02 00:02:563174 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:513175 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:033176 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
3177 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi5f587cc2017-11-21 23:24:173178 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3179 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3180 EXPECT_TRUE(stream.get());
3181
Zhongyi Shic16b4102019-02-12 00:37:403182 // Ensure that session is active.
Zhongyi Shi5f587cc2017-11-21 23:24:173183 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3184
3185 // Trigger connection migration. Since there are no active streams,
3186 // the session will be closed.
3187 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3188 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
3189
Zhongyi Shi32fe14d42019-02-28 00:25:363190 EXPECT_EQ(migrate_idle_sessions, HasActiveSession(host_port_pair_));
Zhongyi Shi5f587cc2017-11-21 23:24:173191
Zhongyi Shic16b4102019-02-12 00:37:403192 EXPECT_TRUE(default_socket_data.AllReadDataConsumed());
3193 EXPECT_TRUE(default_socket_data.AllWriteDataConsumed());
Zhongyi Shi32fe14d42019-02-28 00:25:363194 if (migrate_idle_sessions) {
3195 EXPECT_TRUE(alternate_socket_data.AllReadDataConsumed());
3196 EXPECT_TRUE(alternate_socket_data.AllWriteDataConsumed());
3197 }
Zhongyi Shi5f587cc2017-11-21 23:24:173198}
3199
Zhongyi Shi9f316b262018-06-18 22:01:163200// This test verifies session migrates to the alternate network immediately when
3201// default network disconnects with a synchronous write before migration.
3202TEST_P(QuicStreamFactoryTest, MigrateOnDefaultNetworkDisconnectedSync) {
3203 TestMigrationOnNetworkDisconnected(/*async_write_before*/ false);
3204}
3205
3206// This test verifies session migrates to the alternate network immediately when
3207// default network disconnects with an asynchronously write before migration.
3208TEST_P(QuicStreamFactoryTest, MigrateOnDefaultNetworkDisconnectedAsync) {
3209 TestMigrationOnNetworkDisconnected(/*async_write_before*/ true);
3210}
3211
3212void QuicStreamFactoryTestBase::TestMigrationOnNetworkDisconnected(
3213 bool async_write_before) {
3214 InitializeConnectionMigrationV2Test(
3215 {kDefaultNetworkForTests, kNewNetworkForTests});
3216 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3217 ->NotifyNetworkMadeDefault(kDefaultNetworkForTests);
3218 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3219 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3220 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3221
3222 // Use the test task runner.
3223 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
3224
3225 int packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:593226 MockQuicData socket_data(version_);
Zhongyi Shi9f316b262018-06-18 22:01:163227 quic::QuicStreamOffset header_stream_offset = 0;
3228 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
3229 socket_data.AddWrite(
3230 SYNCHRONOUS,
3231 ConstructInitialSettingsPacket(packet_number++, &header_stream_offset));
3232 socket_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:333233 SYNCHRONOUS,
3234 ConstructGetRequestPacket(packet_number++,
3235 GetNthClientInitiatedBidirectionalStreamId(0),
3236 true, true, &header_stream_offset));
Zhongyi Shi9f316b262018-06-18 22:01:163237 if (async_write_before) {
3238 socket_data.AddWrite(ASYNC, OK);
3239 packet_number++;
3240 }
3241 socket_data.AddSocketDataToFactory(socket_factory_.get());
3242
3243 // Create request and QuicHttpStream.
3244 QuicStreamRequest request(factory_.get());
3245 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:033246 request.Request(
Nick Harper23290b82019-05-02 00:02:563247 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:513248 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:033249 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
3250 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi9f316b262018-06-18 22:01:163251 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3252 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3253 EXPECT_TRUE(stream.get());
3254
3255 // Cause QUIC stream to be created.
3256 HttpRequestInfo request_info;
3257 request_info.method = "GET";
3258 request_info.url = url_;
3259 request_info.traffic_annotation =
3260 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3261 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
3262 net_log_, CompletionOnceCallback()));
3263
3264 // Ensure that session is alive and active.
3265 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3266 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3267 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3268
3269 // Send GET request on stream.
3270 HttpResponseInfo response;
3271 HttpRequestHeaders request_headers;
3272 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3273 callback_.callback()));
3274
Zhongyi Shi22fd5f52018-06-20 17:39:093275 if (async_write_before)
Zhongyi Shi9f316b262018-06-18 22:01:163276 session->SendPing();
Zhongyi Shi9f316b262018-06-18 22:01:163277
3278 // Set up second socket data provider that is used after migration.
3279 // The response to the earlier request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:593280 MockQuicData socket_data1(version_);
Zhongyi Shi9f316b262018-06-18 22:01:163281 socket_data1.AddWrite(
3282 SYNCHRONOUS,
3283 client_maker_.MakePingPacket(packet_number++, /*include_version=*/true));
3284 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:333285 ASYNC,
3286 ConstructOkResponsePacket(
3287 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shi9f316b262018-06-18 22:01:163288 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
3289 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:333290 SYNCHRONOUS,
3291 client_maker_.MakeAckAndRstPacket(
3292 packet_number++, false, GetNthClientInitiatedBidirectionalStreamId(0),
3293 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi9f316b262018-06-18 22:01:163294 socket_data1.AddSocketDataToFactory(socket_factory_.get());
3295
3296 // Trigger connection migration.
3297 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3298 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
3299
3300 // The connection should still be alive, not marked as going away.
3301 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3302 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3303 EXPECT_EQ(1u, session->GetNumActiveStreams());
3304 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
3305
3306 // Ensure that the session is still alive.
3307 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3308 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3309 EXPECT_EQ(1u, session->GetNumActiveStreams());
3310
3311 // Run the message loop so that data queued in the new socket is read by the
3312 // packet reader.
3313 runner_->RunNextTask();
3314
3315 // Response headers are received over the new network.
3316 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3317 EXPECT_EQ(200, response.headers->response_code());
3318
3319 // Check that the session is still alive.
3320 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3321 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3322
3323 // There should be posted tasks not executed, which is to migrate back to
3324 // default network.
3325 EXPECT_FALSE(runner_->GetPostedTasks().empty());
3326
3327 // Receive signal to mark new network as default.
3328 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3329 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3330
3331 stream.reset();
3332 EXPECT_TRUE(socket_data.AllReadDataConsumed());
3333 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
3334 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
3335 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
3336}
3337
Zhongyi Shi5f587cc2017-11-21 23:24:173338// This test receives NCN signals in the following order:
3339// - default network disconnected
3340// - after a pause, new network is connected.
3341// - new network is made default.
3342TEST_P(QuicStreamFactoryTest, NewNetworkConnectedAfterNoNetwork) {
3343 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
3344 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3345 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3346 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3347
3348 // Use the test task runner.
3349 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
3350
Ryan Hamiltonabad59e2019-06-06 04:02:593351 MockQuicData socket_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:523352 quic::QuicStreamOffset header_stream_offset = 0;
Zhongyi Shi5f587cc2017-11-21 23:24:173353 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
3354 socket_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:433355 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:333356 socket_data.AddWrite(
3357 SYNCHRONOUS, ConstructGetRequestPacket(
3358 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
3359 true, &header_stream_offset));
Zhongyi Shi5f587cc2017-11-21 23:24:173360 socket_data.AddSocketDataToFactory(socket_factory_.get());
3361
3362 // Create request and QuicHttpStream.
3363 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:333364 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:033365 request.Request(
Nick Harper23290b82019-05-02 00:02:563366 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:513367 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:033368 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
3369 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi5f587cc2017-11-21 23:24:173370 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3371 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3372 EXPECT_TRUE(stream.get());
3373
3374 // Cause QUIC stream to be created.
3375 HttpRequestInfo request_info;
3376 request_info.method = "GET";
3377 request_info.url = url_;
Ramin Halavati683bcaa92018-02-14 08:42:393378 request_info.traffic_annotation =
3379 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:273380 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:393381 net_log_, CompletionOnceCallback()));
Zhongyi Shi5f587cc2017-11-21 23:24:173382
3383 // Ensure that session is alive and active.
3384 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3385 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3386 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3387
3388 // Send GET request on stream.
3389 HttpResponseInfo response;
3390 HttpRequestHeaders request_headers;
3391 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3392 callback_.callback()));
3393
3394 // Trigger connection migration. Since there are no networks
3395 // to migrate to, this should cause the session to wait for a new network.
3396 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3397 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
3398
3399 // The connection should still be alive, not marked as going away.
3400 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3401 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3402 EXPECT_EQ(1u, session->GetNumActiveStreams());
3403 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
3404
3405 // Set up second socket data provider that is used after migration.
3406 // The response to the earlier request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:593407 MockQuicData socket_data1(version_);
Zhongyi Shi5f587cc2017-11-21 23:24:173408 socket_data1.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:433409 SYNCHRONOUS, client_maker_.MakePingPacket(3, /*include_version=*/true));
3410 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:333411 ASYNC,
3412 ConstructOkResponsePacket(
3413 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shi5f587cc2017-11-21 23:24:173414 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:333415 socket_data1.AddWrite(
3416 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
3417 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
3418 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:173419 socket_data1.AddSocketDataToFactory(socket_factory_.get());
3420
3421 // Add a new network and notify the stream factory of a new connected network.
3422 // This causes a PING packet to be sent over the new network.
3423 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3424 ->SetConnectedNetworksList({kNewNetworkForTests});
3425 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3426 ->NotifyNetworkConnected(kNewNetworkForTests);
3427
3428 // Ensure that the session is still alive.
3429 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3430 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3431 EXPECT_EQ(1u, session->GetNumActiveStreams());
3432
3433 // Run the message loop so that data queued in the new socket is read by the
3434 // packet reader.
3435 runner_->RunNextTask();
3436
3437 // Response headers are received over the new network.
3438 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3439 EXPECT_EQ(200, response.headers->response_code());
3440
3441 // Check that the session is still alive.
3442 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3443 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3444
3445 // There should posted tasks not executed, which is to migrate back to default
3446 // network.
3447 EXPECT_FALSE(runner_->GetPostedTasks().empty());
3448
3449 // Receive signal to mark new network as default.
3450 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3451 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3452
3453 stream.reset();
3454 EXPECT_TRUE(socket_data.AllReadDataConsumed());
3455 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
3456 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
3457 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
3458}
3459
Zhongyi Shid3d5f502018-08-10 00:22:223460// Regression test for http://crbug.com/872011.
3461// This test verifies that migrate to the probing socket will not trigger
3462// new packets being read synchronously and generate ACK frame while
3463// processing the initial connectivity probe response, which may cause a
3464// connection being closed with INTERNAL_ERROR as pending ACK frame is not
3465// allowed when processing a new packet.
Zhongyi Shi6a7323b2018-12-07 01:26:323466TEST_P(QuicStreamFactoryTest, MigrateToProbingSocket) {
Zhongyi Shid3d5f502018-08-10 00:22:223467 InitializeConnectionMigrationV2Test(
3468 {kDefaultNetworkForTests, kNewNetworkForTests});
3469 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3470 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3471 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3472
3473 // Using a testing task runner so that we can control time.
3474 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
3475 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
3476
3477 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3478 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
3479
3480 int packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:593481 MockQuicData quic_data1(version_);
Zhongyi Shid3d5f502018-08-10 00:22:223482 quic::QuicStreamOffset header_stream_offset = 0;
3483 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging Read.
3484 quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
3485 packet_number++, &header_stream_offset));
3486 quic_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:333487 SYNCHRONOUS,
3488 ConstructGetRequestPacket(packet_number++,
3489 GetNthClientInitiatedBidirectionalStreamId(0),
3490 true, true, &header_stream_offset));
Zhongyi Shid3d5f502018-08-10 00:22:223491 quic_data1.AddSocketDataToFactory(socket_factory_.get());
3492
3493 // Set up the second socket data provider that is used for probing on the
3494 // alternate network.
Ryan Hamiltonabad59e2019-06-06 04:02:593495 MockQuicData quic_data2(version_);
Zhongyi Shid3d5f502018-08-10 00:22:223496 // Connectivity probe to be sent on the new path.
3497 quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectivityProbingPacket(
3498 packet_number++, true));
3499 quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3500 // First connectivity probe to receive from the server, which will complete
3501 // connection migraiton on path degrading.
3502 quic_data2.AddRead(ASYNC,
3503 server_maker_.MakeConnectivityProbingPacket(1, false));
3504 // Read multiple connectivity probes synchronously.
3505 quic_data2.AddRead(SYNCHRONOUS,
3506 server_maker_.MakeConnectivityProbingPacket(2, false));
3507 quic_data2.AddRead(SYNCHRONOUS,
3508 server_maker_.MakeConnectivityProbingPacket(3, false));
3509 quic_data2.AddRead(SYNCHRONOUS,
3510 server_maker_.MakeConnectivityProbingPacket(4, false));
3511 quic_data2.AddWrite(
3512 ASYNC, client_maker_.MakeAckPacket(packet_number++, 1, 4, 1, 1, true));
3513 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:333514 ASYNC,
3515 ConstructOkResponsePacket(
3516 5, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shid3d5f502018-08-10 00:22:223517 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
3518 quic_data2.AddWrite(
Fan Yang32c5a112018-12-10 20:06:333519 SYNCHRONOUS,
3520 client_maker_.MakeAckAndRstPacket(
3521 packet_number++, false, GetNthClientInitiatedBidirectionalStreamId(0),
3522 quic::QUIC_STREAM_CANCELLED, 5, 1, 1, true));
Zhongyi Shid3d5f502018-08-10 00:22:223523 quic_data2.AddSocketDataToFactory(socket_factory_.get());
3524
3525 // Create request and QuicHttpStream.
3526 QuicStreamRequest request(factory_.get());
3527 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:033528 request.Request(
Nick Harper23290b82019-05-02 00:02:563529 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:513530 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:033531 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
3532 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shid3d5f502018-08-10 00:22:223533 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3534 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3535 EXPECT_TRUE(stream.get());
3536
3537 // Cause QUIC stream to be created.
3538 HttpRequestInfo request_info;
3539 request_info.method = "GET";
3540 request_info.url = url_;
3541 request_info.traffic_annotation =
3542 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3543 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
3544 net_log_, CompletionOnceCallback()));
3545
3546 // Ensure that session is alive and active.
3547 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3548 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3549 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3550
3551 // Send GET request on stream.
3552 HttpResponseInfo response;
3553 HttpRequestHeaders request_headers;
3554 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3555 callback_.callback()));
3556
3557 // Cause the connection to report path degrading to the session.
3558 // Session will start to probe the alternate network.
3559 session->connection()->OnPathDegradingTimeout();
3560
3561 // Next connectivity probe is scheduled to be sent in 2 *
3562 // kDefaultRTTMilliSecs.
3563 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
3564 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
3565 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
3566 next_task_delay);
3567
3568 // The connection should still be alive, and not marked as going away.
3569 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3570 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3571 EXPECT_EQ(1u, session->GetNumActiveStreams());
3572 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
3573
3574 // Resume quic data and a connectivity probe response will be read on the new
3575 // socket.
3576 quic_data2.Resume();
3577
3578 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3579 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3580 EXPECT_EQ(1u, session->GetNumActiveStreams());
3581
3582 // There should be three pending tasks, the nearest one will complete
3583 // migration to the new network.
3584 EXPECT_EQ(3u, task_runner->GetPendingTaskCount());
3585 next_task_delay = task_runner->NextPendingTaskDelay();
3586 EXPECT_EQ(base::TimeDelta(), next_task_delay);
3587 task_runner->FastForwardBy(next_task_delay);
3588
3589 // Response headers are received over the new network.
3590 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3591 EXPECT_EQ(200, response.headers->response_code());
3592
3593 // Now there are two pending tasks, the nearest one was to send connectivity
3594 // probe and has been cancelled due to successful migration.
3595 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
3596 next_task_delay = task_runner->NextPendingTaskDelay();
3597 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
3598 next_task_delay);
3599 task_runner->FastForwardBy(next_task_delay);
3600
3601 // There's one more task to mgirate back to the default network in 0.4s.
3602 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
3603 next_task_delay = task_runner->NextPendingTaskDelay();
3604 base::TimeDelta expected_delay =
3605 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) -
3606 base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs);
3607 EXPECT_EQ(expected_delay, next_task_delay);
3608
3609 // Deliver a signal that the alternate network now becomes default to session,
3610 // this will cancel mgirate back to default network timer.
3611 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3612 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3613
3614 task_runner->FastForwardBy(next_task_delay);
3615 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
3616
3617 // Verify that the session is still alive.
3618 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3619 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3620
3621 stream.reset();
3622 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
3623 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
3624 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
3625 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
3626}
3627
Zhongyi Shic4823bd2018-04-27 00:49:193628// This test verifies that the connection migrates to the alternate network
Zhongyi Shi22fd5f52018-06-20 17:39:093629// early when path degrading is detected with an ASYNCHRONOUS write before
3630// migration.
3631TEST_P(QuicStreamFactoryTest, MigrateEarlyOnPathDegradingAysnc) {
3632 TestMigrationOnPathDegrading(/*async_write_before_migration*/ true);
3633}
3634
3635// This test verifies that the connection migrates to the alternate network
3636// early when path degrading is detected with a SYNCHRONOUS write before
3637// migration.
3638TEST_P(QuicStreamFactoryTest, MigrateEarlyOnPathDegradingSync) {
3639 TestMigrationOnPathDegrading(/*async_write_before_migration*/ false);
3640}
3641
3642void QuicStreamFactoryTestBase::TestMigrationOnPathDegrading(
3643 bool async_write_before) {
Zhongyi Shic4823bd2018-04-27 00:49:193644 InitializeConnectionMigrationV2Test(
3645 {kDefaultNetworkForTests, kNewNetworkForTests});
3646 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3647 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3648 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3649
3650 // Using a testing task runner so that we can control time.
3651 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
3652 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
3653
3654 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3655 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
3656
Zhongyi Shi22fd5f52018-06-20 17:39:093657 int packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:593658 MockQuicData quic_data1(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:523659 quic::QuicStreamOffset header_stream_offset = 0;
Zhongyi Shic4823bd2018-04-27 00:49:193660 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging Read.
Zhongyi Shi22fd5f52018-06-20 17:39:093661 quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
3662 packet_number++, &header_stream_offset));
3663 quic_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:333664 SYNCHRONOUS,
3665 ConstructGetRequestPacket(packet_number++,
3666 GetNthClientInitiatedBidirectionalStreamId(0),
3667 true, true, &header_stream_offset));
Zhongyi Shi22fd5f52018-06-20 17:39:093668 if (async_write_before) {
3669 quic_data1.AddWrite(ASYNC, OK);
3670 packet_number++;
3671 }
Zhongyi Shic4823bd2018-04-27 00:49:193672 quic_data1.AddSocketDataToFactory(socket_factory_.get());
3673
3674 // Set up the second socket data provider that is used after migration.
3675 // The response to the earlier request is read on the new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:593676 MockQuicData quic_data2(version_);
Zhongyi Shic4823bd2018-04-27 00:49:193677 // Connectivity probe to be sent on the new path.
Zhongyi Shi22fd5f52018-06-20 17:39:093678 quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectivityProbingPacket(
Zhongyi Shi879659422018-08-02 17:58:253679 packet_number++, true));
Zhongyi Shic4823bd2018-04-27 00:49:193680 quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3681 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:253682 quic_data2.AddRead(ASYNC,
3683 server_maker_.MakeConnectivityProbingPacket(1, false));
Zhongyi Shic4823bd2018-04-27 00:49:193684 // Ping packet to send after migration is completed.
Zhongyi Shi22fd5f52018-06-20 17:39:093685 quic_data2.AddWrite(ASYNC, client_maker_.MakeAckAndPingPacket(
3686 packet_number++, false, 1, 1, 1));
Ryan Hamiltona3ee93a72018-08-01 22:03:083687 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:333688 ASYNC,
3689 ConstructOkResponsePacket(
3690 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shic4823bd2018-04-27 00:49:193691 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi22fd5f52018-06-20 17:39:093692 quic_data2.AddWrite(
Fan Yang32c5a112018-12-10 20:06:333693 SYNCHRONOUS,
3694 client_maker_.MakeAckAndRstPacket(
3695 packet_number++, false, GetNthClientInitiatedBidirectionalStreamId(0),
3696 quic::QUIC_STREAM_CANCELLED, 2, 2, 1, true));
Zhongyi Shic4823bd2018-04-27 00:49:193697 quic_data2.AddSocketDataToFactory(socket_factory_.get());
3698
3699 // Create request and QuicHttpStream.
3700 QuicStreamRequest request(factory_.get());
3701 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:033702 request.Request(
Nick Harper23290b82019-05-02 00:02:563703 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:513704 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:033705 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
3706 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shic4823bd2018-04-27 00:49:193707 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3708 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3709 EXPECT_TRUE(stream.get());
3710
3711 // Cause QUIC stream to be created.
3712 HttpRequestInfo request_info;
3713 request_info.method = "GET";
3714 request_info.url = url_;
3715 request_info.traffic_annotation =
3716 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3717 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
3718 net_log_, CompletionOnceCallback()));
3719
3720 // Ensure that session is alive and active.
3721 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3722 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3723 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3724
3725 // Send GET request on stream.
3726 HttpResponseInfo response;
3727 HttpRequestHeaders request_headers;
3728 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3729 callback_.callback()));
3730
Zhongyi Shi22fd5f52018-06-20 17:39:093731 if (async_write_before)
3732 session->SendPing();
3733
Zhongyi Shiaba4a832018-04-30 20:29:083734 // Cause the connection to report path degrading to the session.
3735 // Session will start to probe the alternate network.
3736 session->connection()->OnPathDegradingTimeout();
3737
3738 // Next connectivity probe is scheduled to be sent in 2 *
3739 // kDefaultRTTMilliSecs.
3740 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
3741 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
3742 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
3743 next_task_delay);
3744
3745 // The connection should still be alive, and not marked as going away.
3746 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3747 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3748 EXPECT_EQ(1u, session->GetNumActiveStreams());
3749 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
3750
3751 // Resume quic data and a connectivity probe response will be read on the new
3752 // socket.
3753 quic_data2.Resume();
3754
3755 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3756 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3757 EXPECT_EQ(1u, session->GetNumActiveStreams());
3758
3759 // There should be three pending tasks, the nearest one will complete
3760 // migration to the new network.
3761 EXPECT_EQ(3u, task_runner->GetPendingTaskCount());
3762 next_task_delay = task_runner->NextPendingTaskDelay();
3763 EXPECT_EQ(base::TimeDelta(), next_task_delay);
3764 task_runner->FastForwardBy(next_task_delay);
3765
3766 // Response headers are received over the new network.
3767 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3768 EXPECT_EQ(200, response.headers->response_code());
3769
3770 // Now there are two pending tasks, the nearest one was to send connectivity
3771 // probe and has been cancelled due to successful migration.
3772 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
3773 next_task_delay = task_runner->NextPendingTaskDelay();
3774 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
3775 next_task_delay);
3776 task_runner->FastForwardBy(next_task_delay);
3777
3778 // There's one more task to mgirate back to the default network in 0.4s.
3779 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
3780 next_task_delay = task_runner->NextPendingTaskDelay();
3781 base::TimeDelta expected_delay =
3782 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) -
3783 base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs);
3784 EXPECT_EQ(expected_delay, next_task_delay);
3785
3786 // Deliver a signal that the alternate network now becomes default to session,
3787 // this will cancel mgirate back to default network timer.
3788 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3789 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
3790
3791 task_runner->FastForwardBy(next_task_delay);
3792 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
3793
3794 // Verify that the session is still alive.
3795 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3796 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3797
3798 stream.reset();
3799 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
3800 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
3801 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
3802 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
3803}
3804
Renjiea5722ccf2018-08-10 00:18:493805// This test verifies that the session marks itself GOAWAY on path degrading
3806// and it does not receive any new request
3807TEST_P(QuicStreamFactoryTest, GoawayOnPathDegrading) {
Zhongyi Shi967d2f12019-02-08 20:58:533808 test_params_.quic_go_away_on_path_degrading = true;
Renjiea5722ccf2018-08-10 00:18:493809 Initialize();
3810 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3811 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3812 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3813
Ryan Hamiltonabad59e2019-06-06 04:02:593814 MockQuicData quic_data1(version_);
Renjiea5722ccf2018-08-10 00:18:493815 quic::QuicStreamOffset header_stream_offset = 0;
3816 quic_data1.AddWrite(SYNCHRONOUS,
3817 ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:333818 quic_data1.AddWrite(
3819 SYNCHRONOUS, ConstructGetRequestPacket(
3820 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
3821 true, &header_stream_offset));
Renjiea5722ccf2018-08-10 00:18:493822 quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3823 quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:333824 ASYNC,
3825 ConstructOkResponsePacket(
3826 1, GetNthClientInitiatedBidirectionalStreamId(0), false, true));
Renjiea5722ccf2018-08-10 00:18:493827 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
3828 quic_data1.AddSocketDataToFactory(socket_factory_.get());
3829
Ryan Hamiltonabad59e2019-06-06 04:02:593830 MockQuicData quic_data2(version_);
Renjiea5722ccf2018-08-10 00:18:493831 quic::QuicStreamOffset header_stream_offset2 = 0;
3832 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
3833 quic_data2.AddWrite(
3834 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset2));
3835 quic_data2.AddSocketDataToFactory(socket_factory_.get());
3836
3837 // Creat request and QuicHttpStream.
3838 QuicStreamRequest request(factory_.get());
3839 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:033840 request.Request(
Nick Harper23290b82019-05-02 00:02:563841 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:513842 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:033843 /*cerf_verify_flags=*/0, url_, net_log_, &net_error_details_,
3844 failed_on_default_network_callback_, callback_.callback()));
Renjiea5722ccf2018-08-10 00:18:493845 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3846 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3847 EXPECT_TRUE(stream.get());
3848
3849 // Cause QUIC stream to be created.
3850 HttpRequestInfo request_info;
3851 request_info.method = "GET";
3852 request_info.url = url_;
3853 request_info.traffic_annotation =
3854 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3855 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
3856 net_log_, CompletionOnceCallback()));
3857
3858 // Ensure that session is alive and active.
3859 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3860 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3861 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3862
3863 // Send GET request on stream.
3864 HttpResponseInfo response;
3865 HttpRequestHeaders request_headers;
3866 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3867 callback_.callback()));
3868
3869 // Trigger the connection to report path degrading to the session.
3870 // Session will mark itself GOAWAY.
3871 session->connection()->OnPathDegradingTimeout();
3872
3873 // The connection should still be alive, but marked as going away.
3874 EXPECT_FALSE(HasActiveSession(host_port_pair_));
3875 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3876 EXPECT_EQ(1u, session->GetNumActiveStreams());
3877
3878 // Second request should be sent on a new connection.
3879 QuicStreamRequest request2(factory_.get());
3880 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:033881 request2.Request(
Nick Harper23290b82019-05-02 00:02:563882 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:513883 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:033884 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
3885 failed_on_default_network_callback_, callback_.callback()));
Renjiea5722ccf2018-08-10 00:18:493886 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3887 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
3888 EXPECT_TRUE(stream2.get());
3889
3890 // Resume the data, verify old request can read response on the old session
3891 // successfully.
3892 quic_data1.Resume();
3893 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
3894 EXPECT_EQ(200, response.headers->response_code());
3895 EXPECT_EQ(0U, session->GetNumActiveStreams());
3896
3897 // Check an active session exists for the destination.
3898 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3899 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3900 QuicChromiumClientSession* session2 = GetActiveSession(host_port_pair_);
3901 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2));
3902 EXPECT_NE(session, session2);
3903
3904 stream.reset();
3905 stream2.reset();
3906 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
3907 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
3908 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
3909 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
3910}
3911
Zhongyi Shibb770d92018-06-16 02:07:003912// This test verifies that the connection will not migrate to a bad socket
3913// when path degrading is detected.
3914TEST_P(QuicStreamFactoryTest, DoNotMigrateToBadSocketOnPathDegrading) {
3915 InitializeConnectionMigrationV2Test(
3916 {kDefaultNetworkForTests, kNewNetworkForTests});
3917 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
3918 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3919 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
3920
3921 // Using a testing task runner so that we can control time.
3922 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
3923 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
3924
3925 scoped_mock_network_change_notifier_->mock_network_change_notifier()
3926 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
3927
Ryan Hamiltonabad59e2019-06-06 04:02:593928 MockQuicData quic_data(version_);
Zhongyi Shibb770d92018-06-16 02:07:003929 quic::QuicStreamOffset header_stream_offset = 0;
3930 quic_data.AddWrite(SYNCHRONOUS,
3931 ConstructInitialSettingsPacket(1, &header_stream_offset));
Zhongyi Shibb770d92018-06-16 02:07:003932 quic_data.AddWrite(SYNCHRONOUS,
Fan Yang32c5a112018-12-10 20:06:333933 ConstructGetRequestPacket(
3934 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
3935 true, &header_stream_offset));
3936 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
3937 quic_data.AddRead(ASYNC, ConstructOkResponsePacket(
3938 1, GetNthClientInitiatedBidirectionalStreamId(0),
3939 false, false));
3940 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
3941 quic_data.AddWrite(
3942 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
3943 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
3944 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shibb770d92018-06-16 02:07:003945 quic_data.AddSocketDataToFactory(socket_factory_.get());
3946
3947 // Set up second socket that will immediately return disconnected.
3948 // The stream factory will abort probe the alternate network.
3949 MockConnect bad_connect = MockConnect(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
3950 SequencedSocketData socket_data(bad_connect, base::span<MockRead>(),
3951 base::span<MockWrite>());
3952 socket_factory_->AddSocketDataProvider(&socket_data);
3953
3954 // Create request and QuicHttpStream.
3955 QuicStreamRequest request(factory_.get());
3956 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:033957 request.Request(
Nick Harper23290b82019-05-02 00:02:563958 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:513959 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:033960 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
3961 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shibb770d92018-06-16 02:07:003962 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3963 std::unique_ptr<HttpStream> stream = CreateStream(&request);
3964 EXPECT_TRUE(stream.get());
3965
3966 // Cause QUIC stream to be created.
3967 HttpRequestInfo request_info;
3968 request_info.method = "GET";
3969 request_info.url = url_;
3970 request_info.traffic_annotation =
3971 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
3972 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
3973 net_log_, CompletionOnceCallback()));
3974
3975 // Ensure that session is alive and active.
3976 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
3977 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3978 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3979
3980 // Send GET request on stream.
3981 HttpResponseInfo response;
3982 HttpRequestHeaders request_headers;
3983 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
3984 callback_.callback()));
3985
3986 // Cause the connection to report path degrading to the session.
3987 // Session will start to probe the alternate network.
3988 session->connection()->OnPathDegradingTimeout();
3989
3990 // The connection should still be alive, and not marked as going away.
3991 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
3992 EXPECT_TRUE(HasActiveSession(host_port_pair_));
3993 EXPECT_EQ(1u, session->GetNumActiveStreams());
3994 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
3995
3996 // Resume the data, and response header is received over the original network.
3997 quic_data.Resume();
3998 EXPECT_THAT(callback_.WaitForResult(), IsOk());
3999 EXPECT_EQ(200, response.headers->response_code());
4000
4001 // Verify there is no pending task as probing alternate network is halted.
4002 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4003
4004 // Verify that the session is still alive.
4005 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4006 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4007
4008 stream.reset();
4009 EXPECT_TRUE(quic_data.AllReadDataConsumed());
4010 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
4011}
4012
Zhongyi Shif5cc30392018-05-30 18:25:154013// Regression test for http://crbug.com/847569.
4014// This test verifies that the connection migrates to the alternate network
4015// early when there is no active stream but a draining stream.
Zhongyi Shib3bc982c2018-07-10 19:59:244016// The first packet being written after migration is a synchrnous write, which
4017// will cause a PING packet being sent.
4018TEST_P(QuicStreamFactoryTest, MigrateSessionWithDrainingStreamSync) {
4019 TestMigrateSessionWithDrainingStream(SYNCHRONOUS);
4020}
4021
4022// Regression test for http://crbug.com/847569.
4023// This test verifies that the connection migrates to the alternate network
4024// early when there is no active stream but a draining stream.
4025// The first packet being written after migration is an asynchronous write, no
4026// PING packet will be sent.
4027TEST_P(QuicStreamFactoryTest, MigrateSessionWithDrainingStreamAsync) {
4028 TestMigrateSessionWithDrainingStream(ASYNC);
4029}
4030
4031void QuicStreamFactoryTestBase::TestMigrateSessionWithDrainingStream(
4032 IoMode write_mode_for_queued_packet) {
Zhongyi Shif5cc30392018-05-30 18:25:154033 InitializeConnectionMigrationV2Test(
4034 {kDefaultNetworkForTests, kNewNetworkForTests});
4035 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4036 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4037 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4038
4039 // Using a testing task runner so that we can control time.
4040 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
4041 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
4042
4043 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4044 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
4045
Zhongyi Shib3bc982c2018-07-10 19:59:244046 int packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:594047 MockQuicData quic_data1(version_);
Zhongyi Shif5cc30392018-05-30 18:25:154048 quic::QuicStreamOffset header_stream_offset = 0;
Zhongyi Shib3bc982c2018-07-10 19:59:244049 quic_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(
4050 packet_number++, &header_stream_offset));
4051 quic_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334052 SYNCHRONOUS,
4053 ConstructGetRequestPacket(packet_number++,
4054 GetNthClientInitiatedBidirectionalStreamId(0),
4055 true, true, &header_stream_offset));
Zhongyi Shif5cc30392018-05-30 18:25:154056 // Read an out of order packet with FIN to drain the stream.
4057 quic_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:334058 ASYNC, ConstructOkResponsePacket(
4059 2, GetNthClientInitiatedBidirectionalStreamId(0), false,
4060 true)); // keep sending version.
Fan Yang0da2282f72019-04-25 21:06:574061 if (!GetQuicRestartFlag(quic_enable_accept_random_ipn)) {
4062 // Packet 2 is considered as out of order packet and an ACK will be sent
4063 // immediately.
4064 quic_data1.AddWrite(SYNCHRONOUS, client_maker_.MakeAckPacket(
4065 packet_number++, 2, 2, 2, 1, true));
4066 }
Zhongyi Shif5cc30392018-05-30 18:25:154067 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4068 quic_data1.AddSocketDataToFactory(socket_factory_.get());
4069
4070 // Set up the second socket data provider that is used after migration.
Ryan Hamiltonabad59e2019-06-06 04:02:594071 MockQuicData quic_data2(version_);
Zhongyi Shif5cc30392018-05-30 18:25:154072 // Connectivity probe to be sent on the new path.
Zhongyi Shib3bc982c2018-07-10 19:59:244073 quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeConnectivityProbingPacket(
Zhongyi Shi879659422018-08-02 17:58:254074 packet_number++, false));
Zhongyi Shif5cc30392018-05-30 18:25:154075 quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause
4076 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:254077 quic_data2.AddRead(ASYNC,
4078 server_maker_.MakeConnectivityProbingPacket(3, false));
Zhongyi Shif5cc30392018-05-30 18:25:154079 // Ping packet to send after migration is completed.
Zhongyi Shib3bc982c2018-07-10 19:59:244080 quic_data2.AddWrite(
4081 write_mode_for_queued_packet,
4082 client_maker_.MakeAckPacket(packet_number++, 2, 3, 3, 1, true));
4083 if (write_mode_for_queued_packet == SYNCHRONOUS) {
4084 quic_data2.AddWrite(ASYNC,
4085 client_maker_.MakePingPacket(packet_number++, false));
4086 }
Zhongyi Shif5cc30392018-05-30 18:25:154087 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:334088 ASYNC,
4089 ConstructOkResponsePacket(
4090 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shib3bc982c2018-07-10 19:59:244091 quic_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeAckPacket(
4092 packet_number++, 1, 3, 1, 1, true));
Zhongyi Shif5cc30392018-05-30 18:25:154093 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4094 quic_data2.AddSocketDataToFactory(socket_factory_.get());
4095
4096 // Create request and QuicHttpStream.
4097 QuicStreamRequest request(factory_.get());
4098 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:034099 request.Request(
Nick Harper23290b82019-05-02 00:02:564100 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:514101 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:034102 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
4103 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shif5cc30392018-05-30 18:25:154104 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4105 std::unique_ptr<HttpStream> stream = CreateStream(&request);
4106 EXPECT_TRUE(stream.get());
4107
4108 // Cause QUIC stream to be created.
4109 HttpRequestInfo request_info;
4110 request_info.method = "GET";
4111 request_info.url = url_;
4112 request_info.traffic_annotation =
4113 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4114 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
4115 net_log_, CompletionOnceCallback()));
4116
4117 // Ensure that session is alive and active.
4118 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
4119 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4120 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4121
4122 // Send GET request on stream.
4123 HttpResponseInfo response;
4124 HttpRequestHeaders request_headers;
4125 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
4126 callback_.callback()));
4127
4128 // Run the message loop to receive the out of order packet which contains a
4129 // FIN and drains the stream.
4130 base::RunLoop().RunUntilIdle();
4131 EXPECT_EQ(0u, session->GetNumActiveStreams());
4132
4133 // Cause the connection to report path degrading to the session.
4134 // Session should still start to probe the alternate network.
4135 session->connection()->OnPathDegradingTimeout();
4136 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4137
4138 // Next connectivity probe is scheduled to be sent in 2 *
4139 // kDefaultRTTMilliSecs.
4140 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4141 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
4142 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
4143 next_task_delay);
4144
4145 // The connection should still be alive, and not marked as going away.
4146 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shif5cc30392018-05-30 18:25:154147
4148 // Resume quic data and a connectivity probe response will be read on the new
4149 // socket.
4150 quic_data2.Resume();
4151
4152 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4153 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi0439ecc72018-07-11 04:41:264154 EXPECT_EQ(0u, session->GetNumActiveStreams());
4155 EXPECT_EQ(1u, session->GetNumDrainingStreams());
Zhongyi Shif5cc30392018-05-30 18:25:154156
4157 // There should be three pending tasks, the nearest one will complete
4158 // migration to the new network.
4159 EXPECT_EQ(3u, task_runner->GetPendingTaskCount());
4160 next_task_delay = task_runner->NextPendingTaskDelay();
4161 EXPECT_EQ(base::TimeDelta(), next_task_delay);
4162 task_runner->FastForwardBy(next_task_delay);
4163
4164 // Now there are two pending tasks, the nearest one was to send connectivity
4165 // probe and has been cancelled due to successful migration.
4166 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
4167 next_task_delay = task_runner->NextPendingTaskDelay();
4168 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
4169 next_task_delay);
4170 task_runner->FastForwardBy(next_task_delay);
4171
4172 // There's one more task to mgirate back to the default network in 0.4s.
4173 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4174 next_task_delay = task_runner->NextPendingTaskDelay();
4175 base::TimeDelta expected_delay =
4176 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) -
4177 base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs);
4178 EXPECT_EQ(expected_delay, next_task_delay);
4179
Zhongyi Shib3bc982c2018-07-10 19:59:244180 base::RunLoop().RunUntilIdle();
4181
Zhongyi Shif5cc30392018-05-30 18:25:154182 // Deliver a signal that the alternate network now becomes default to session,
4183 // this will cancel mgirate back to default network timer.
4184 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4185 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
4186
4187 task_runner->FastForwardBy(next_task_delay);
4188 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4189
4190 // Verify that the session is still alive.
4191 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4192 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi0439ecc72018-07-11 04:41:264193 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
Zhongyi Shif5cc30392018-05-30 18:25:154194
4195 stream.reset();
4196 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
4197 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
4198 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
4199 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
4200}
4201
Zhongyi Shiaba4a832018-04-30 20:29:084202// Regression test for http://crbug.com/835444.
4203// This test verifies that the connection migrates to the alternate network
4204// when the alternate network is connected after path has been degrading.
4205TEST_P(QuicStreamFactoryTest, MigrateOnNewNetworkConnectAfterPathDegrading) {
4206 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
4207 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4208 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4209 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4210
4211 // Using a testing task runner so that we can control time.
4212 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
4213 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
4214
4215 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4216 ->QueueNetworkMadeDefault(kDefaultNetworkForTests);
4217
Ryan Hamiltonabad59e2019-06-06 04:02:594218 MockQuicData quic_data1(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:524219 quic::QuicStreamOffset header_stream_offset = 0;
Zhongyi Shiaba4a832018-04-30 20:29:084220 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging Read.
4221 quic_data1.AddWrite(SYNCHRONOUS,
4222 ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:334223 quic_data1.AddWrite(
4224 SYNCHRONOUS, ConstructGetRequestPacket(
4225 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
4226 true, &header_stream_offset));
Zhongyi Shiaba4a832018-04-30 20:29:084227 quic_data1.AddSocketDataToFactory(socket_factory_.get());
4228
4229 // Set up the second socket data provider that is used after migration.
4230 // The response to the earlier request is read on the new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:594231 MockQuicData quic_data2(version_);
Zhongyi Shiaba4a832018-04-30 20:29:084232 // Connectivity probe to be sent on the new path.
Zhongyi Shi879659422018-08-02 17:58:254233 quic_data2.AddWrite(SYNCHRONOUS,
4234 client_maker_.MakeConnectivityProbingPacket(3, true));
Zhongyi Shiaba4a832018-04-30 20:29:084235 quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause
4236 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:254237 quic_data2.AddRead(ASYNC,
4238 server_maker_.MakeConnectivityProbingPacket(1, false));
Zhongyi Shiaba4a832018-04-30 20:29:084239 // Ping packet to send after migration is completed.
4240 quic_data2.AddWrite(ASYNC,
4241 client_maker_.MakeAckAndPingPacket(4, false, 1, 1, 1));
4242 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:334243 ASYNC,
4244 ConstructOkResponsePacket(
4245 2, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shiaba4a832018-04-30 20:29:084246 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:334247 quic_data2.AddWrite(
4248 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
4249 5, false, GetNthClientInitiatedBidirectionalStreamId(0),
4250 quic::QUIC_STREAM_CANCELLED, 2, 2, 1, true));
Zhongyi Shiaba4a832018-04-30 20:29:084251 quic_data2.AddSocketDataToFactory(socket_factory_.get());
4252
4253 // Create request and QuicHttpStream.
4254 QuicStreamRequest request(factory_.get());
4255 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:034256 request.Request(
Nick Harper23290b82019-05-02 00:02:564257 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:514258 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:034259 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
4260 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shiaba4a832018-04-30 20:29:084261 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4262 std::unique_ptr<HttpStream> stream = CreateStream(&request);
4263 EXPECT_TRUE(stream.get());
4264
4265 // Cause QUIC stream to be created.
4266 HttpRequestInfo request_info;
4267 request_info.method = "GET";
4268 request_info.url = url_;
4269 request_info.traffic_annotation =
4270 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4271 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
4272 net_log_, CompletionOnceCallback()));
4273
4274 // Ensure that session is alive and active.
4275 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
4276 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4277 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4278
4279 // Send GET request on stream.
4280 HttpResponseInfo response;
4281 HttpRequestHeaders request_headers;
4282 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
4283 callback_.callback()));
4284
4285 // Cause the connection to report path degrading to the session.
4286 // Due to lack of alternate network, session will not mgirate connection.
4287 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4288 session->connection()->OnPathDegradingTimeout();
4289 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4290
4291 // Deliver a signal that a alternate network is connected now, this should
4292 // cause the connection to start early migration on path degrading.
4293 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4294 ->SetConnectedNetworksList(
4295 {kDefaultNetworkForTests, kNewNetworkForTests});
4296 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4297 ->NotifyNetworkConnected(kNewNetworkForTests);
Zhongyi Shic4823bd2018-04-27 00:49:194298
4299 // Next connectivity probe is scheduled to be sent in 2 *
4300 // kDefaultRTTMilliSecs.
4301 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4302 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
4303 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
4304 next_task_delay);
4305
4306 // The connection should still be alive, and not marked as going away.
4307 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4308 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4309 EXPECT_EQ(1u, session->GetNumActiveStreams());
4310 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
4311
4312 // Resume quic data and a connectivity probe response will be read on the new
4313 // socket.
4314 quic_data2.Resume();
4315
4316 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4317 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4318 EXPECT_EQ(1u, session->GetNumActiveStreams());
4319
4320 // There should be three pending tasks, the nearest one will complete
4321 // migration to the new network.
4322 EXPECT_EQ(3u, task_runner->GetPendingTaskCount());
4323 next_task_delay = task_runner->NextPendingTaskDelay();
4324 EXPECT_EQ(base::TimeDelta(), next_task_delay);
4325 task_runner->FastForwardBy(next_task_delay);
4326
4327 // Response headers are received over the new network.
4328 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4329 EXPECT_EQ(200, response.headers->response_code());
4330
4331 // Now there are two pending tasks, the nearest one was to send connectivity
4332 // probe and has been cancelled due to successful migration.
4333 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
4334 next_task_delay = task_runner->NextPendingTaskDelay();
4335 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
4336 next_task_delay);
4337 task_runner->FastForwardBy(next_task_delay);
4338
4339 // There's one more task to mgirate back to the default network in 0.4s.
4340 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4341 next_task_delay = task_runner->NextPendingTaskDelay();
4342 base::TimeDelta expected_delay =
4343 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs) -
4344 base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs);
4345 EXPECT_EQ(expected_delay, next_task_delay);
4346
4347 // Deliver a signal that the alternate network now becomes default to session,
4348 // this will cancel mgirate back to default network timer.
4349 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4350 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
4351
4352 task_runner->FastForwardBy(next_task_delay);
4353 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4354
4355 // Verify that the session is still alive.
4356 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4357 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4358
4359 stream.reset();
4360 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
4361 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
4362 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
4363 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
4364}
4365
Zhongyi Shi28f6e352018-06-20 21:15:434366// This test verifies that multiple sessions are migrated on connection
4367// migration signal.
jrie3d187c2016-09-16 14:29:174368TEST_P(QuicStreamFactoryTest,
Zhongyi Shi28f6e352018-06-20 21:15:434369 MigrateMultipleSessionsToBadSocketsAfterDisconnected) {
4370 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jrie3d187c2016-09-16 14:29:174371
Ryan Hamiltonabad59e2019-06-06 04:02:594372 MockQuicData socket_data1(version_);
jrie3d187c2016-09-16 14:29:174373 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:434374 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
jrie3d187c2016-09-16 14:29:174375 socket_data1.AddWrite(ASYNC, OK);
Zhongyi Shi5f587cc2017-11-21 23:24:174376 socket_data1.AddSocketDataToFactory(socket_factory_.get());
Ryan Hamiltonabad59e2019-06-06 04:02:594377 MockQuicData socket_data2(version_);
jrie3d187c2016-09-16 14:29:174378 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:434379 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
jrie3d187c2016-09-16 14:29:174380 socket_data2.AddWrite(ASYNC, OK);
Zhongyi Shi5f587cc2017-11-21 23:24:174381 socket_data2.AddSocketDataToFactory(socket_factory_.get());
jrie3d187c2016-09-16 14:29:174382
4383 HostPortPair server1(kDefaultServerHostName, 443);
4384 HostPortPair server2(kServer2HostName, 443);
4385
4386 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4387 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4388 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4389
Renjiea0cb4a2c2018-09-26 23:37:304390 host_resolver_->set_synchronous_mode(true);
4391 host_resolver_->rules()->AddIPLiteralRule(server1.host(), "192.168.0.1", "");
4392 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.2", "");
jrie3d187c2016-09-16 14:29:174393
4394 // Create request and QuicHttpStream to create session1.
zhongyi98d6a9262017-05-19 02:47:454395 QuicStreamRequest request1(factory_.get());
Matt Menke26e41542019-06-05 01:09:514396 EXPECT_EQ(OK,
4397 request1.Request(
4398 server1, version_.transport_version, privacy_mode_,
4399 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
4400 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
4401 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:244402 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
jrie3d187c2016-09-16 14:29:174403 EXPECT_TRUE(stream1.get());
4404
4405 // Create request and QuicHttpStream to create session2.
zhongyi98d6a9262017-05-19 02:47:454406 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:514407 EXPECT_EQ(OK,
4408 request2.Request(
4409 server2, version_.transport_version, privacy_mode_,
4410 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
4411 /*cert_verify_flags=*/0, url2_, net_log_, &net_error_details_,
4412 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:244413 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
jrie3d187c2016-09-16 14:29:174414 EXPECT_TRUE(stream2.get());
4415
4416 QuicChromiumClientSession* session1 = GetActiveSession(server1);
4417 QuicChromiumClientSession* session2 = GetActiveSession(server2);
4418 EXPECT_NE(session1, session2);
4419
4420 // Cause QUIC stream to be created and send GET so session1 has an open
4421 // stream.
4422 HttpRequestInfo request_info1;
4423 request_info1.method = "GET";
4424 request_info1.url = url_;
Ramin Halavati683bcaa92018-02-14 08:42:394425 request_info1.traffic_annotation =
4426 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:274427 EXPECT_EQ(OK,
4428 stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:394429 net_log_, CompletionOnceCallback()));
jrie3d187c2016-09-16 14:29:174430 HttpResponseInfo response1;
4431 HttpRequestHeaders request_headers1;
4432 EXPECT_EQ(OK, stream1->SendRequest(request_headers1, &response1,
4433 callback_.callback()));
4434
4435 // Cause QUIC stream to be created and send GET so session2 has an open
4436 // stream.
4437 HttpRequestInfo request_info2;
4438 request_info2.method = "GET";
4439 request_info2.url = url_;
Ramin Halavati683bcaa92018-02-14 08:42:394440 request_info2.traffic_annotation =
4441 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:274442 EXPECT_EQ(OK,
4443 stream2->InitializeStream(&request_info2, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:394444 net_log_, CompletionOnceCallback()));
jrie3d187c2016-09-16 14:29:174445 HttpResponseInfo response2;
4446 HttpRequestHeaders request_headers2;
4447 EXPECT_EQ(OK, stream2->SendRequest(request_headers2, &response2,
4448 callback_.callback()));
4449
4450 // Cause both sessions to be paused due to DISCONNECTED.
4451 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4452 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
4453
4454 // Ensure that both sessions are paused but alive.
4455 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session1));
4456 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2));
4457
Zhongyi Shi28f6e352018-06-20 21:15:434458 // Add new sockets to use post migration. Those are bad sockets and will cause
4459 // migration to fail.
jrie3d187c2016-09-16 14:29:174460 MockConnect connect_result =
4461 MockConnect(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED);
Ryan Sleevib8d7ea02018-05-07 20:01:014462 SequencedSocketData socket_data3(connect_result, base::span<MockRead>(),
4463 base::span<MockWrite>());
Zhongyi Shi5f587cc2017-11-21 23:24:174464 socket_factory_->AddSocketDataProvider(&socket_data3);
Ryan Sleevib8d7ea02018-05-07 20:01:014465 SequencedSocketData socket_data4(connect_result, base::span<MockRead>(),
4466 base::span<MockWrite>());
Zhongyi Shi5f587cc2017-11-21 23:24:174467 socket_factory_->AddSocketDataProvider(&socket_data4);
jrie3d187c2016-09-16 14:29:174468
Zhongyi Shi28f6e352018-06-20 21:15:434469 // Connect the new network and cause migration to bad sockets, causing
4470 // sessions to close.
jrie3d187c2016-09-16 14:29:174471 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4472 ->SetConnectedNetworksList({kNewNetworkForTests});
4473 scoped_mock_network_change_notifier_->mock_network_change_notifier()
4474 ->NotifyNetworkConnected(kNewNetworkForTests);
4475
4476 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session1));
4477 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2));
4478
4479 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
4480 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
4481 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
4482 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
4483}
4484
Zhongyi Shi6ec9b36e2018-06-20 20:32:544485// This test verifies that session attempts connection migration with signals
4486// delivered in the following order (no alternate network is available):
4487// - path degrading is detected: session attempts connection migration but no
4488// alternate network is available, session caches path degrading signal in
4489// connection and stays on the original network.
4490// - original network backs up, request is served in the orignal network,
4491// session is not marked as going away.
4492TEST_P(QuicStreamFactoryTest, MigrateOnPathDegradingWithNoNewNetwork) {
4493 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jrid36ada62016-02-06 02:42:084494 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4495 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4496
Ryan Hamiltonabad59e2019-06-06 04:02:594497 MockQuicData quic_data(version_);
Zhongyi Shi6ec9b36e2018-06-20 20:32:544498 quic::QuicStreamOffset header_stream_offset = 0;
4499 quic_data.AddWrite(SYNCHRONOUS,
4500 ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:334501 quic_data.AddWrite(SYNCHRONOUS,
4502 ConstructGetRequestPacket(
4503 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
4504 true, &header_stream_offset));
Zhongyi Shi6ec9b36e2018-06-20 20:32:544505 quic_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause for path degrading signal.
4506
4507 // The rest of the data will still flow in the original socket as there is no
4508 // new network after path degrading.
Fan Yang32c5a112018-12-10 20:06:334509 quic_data.AddRead(ASYNC, ConstructOkResponsePacket(
4510 1, GetNthClientInitiatedBidirectionalStreamId(0),
4511 false, false));
Zhongyi Shi6ec9b36e2018-06-20 20:32:544512 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:334513 quic_data.AddWrite(
4514 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
4515 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
4516 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi6ec9b36e2018-06-20 20:32:544517 quic_data.AddSocketDataToFactory(socket_factory_.get());
jrid36ada62016-02-06 02:42:084518
4519 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:454520 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:334521 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:034522 request.Request(
Nick Harper23290b82019-05-02 00:02:564523 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:514524 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:034525 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
4526 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:014527 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:244528 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jrid36ada62016-02-06 02:42:084529 EXPECT_TRUE(stream.get());
4530
4531 // Cause QUIC stream to be created.
4532 HttpRequestInfo request_info;
Zhongyi Shi6ec9b36e2018-06-20 20:32:544533 request_info.method = "GET";
4534 request_info.url = url_;
Ramin Halavati683bcaa92018-02-14 08:42:394535 request_info.traffic_annotation =
4536 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Zhongyi Shi6ec9b36e2018-06-20 20:32:544537 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:394538 net_log_, CompletionOnceCallback()));
jrid36ada62016-02-06 02:42:084539
4540 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:504541 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jrid36ada62016-02-06 02:42:084542 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4543 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4544
Zhongyi Shi6ec9b36e2018-06-20 20:32:544545 // Send GET request on stream.
4546 HttpResponseInfo response;
4547 HttpRequestHeaders request_headers;
4548 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
4549 callback_.callback()));
jrid36ada62016-02-06 02:42:084550
Zhongyi Shi6ec9b36e2018-06-20 20:32:544551 // Trigger connection migration on path degrading. Since there are no networks
4552 // to migrate to, the session will remain on the original network, not marked
4553 // as going away.
4554 session->connection()->OnPathDegradingTimeout();
4555 EXPECT_TRUE(session->connection()->IsPathDegrading());
4556
4557 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4558 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4559 EXPECT_EQ(1u, session->GetNumActiveStreams());
4560 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
4561
4562 // Resume so that rest of the data will flow in the original socket.
4563 quic_data.Resume();
jrid36ada62016-02-06 02:42:084564
4565 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4566 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4567 EXPECT_EQ(1u, session->GetNumActiveStreams());
4568
4569 stream.reset();
Zhongyi Shi6ec9b36e2018-06-20 20:32:544570 EXPECT_TRUE(quic_data.AllReadDataConsumed());
4571 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
jrid36ada62016-02-06 02:42:084572}
4573
Zhongyi Shi21e99532018-07-17 22:23:074574// This test verifies that session with non-migratable stream will probe the
4575// alternate network on path degrading, and close the non-migratable streams
4576// when probe is successful.
Zhongyi Shi32fe14d42019-02-28 00:25:364577TEST_P(QuicStreamFactoryTest,
4578 MigrateSessionEarlyNonMigratableStream_DoNotMigrateIdleSessions) {
4579 TestMigrateSessionEarlyNonMigratableStream(false);
4580}
4581
4582TEST_P(QuicStreamFactoryTest,
4583 MigrateSessionEarlyNonMigratableStream_MigrateIdleSessions) {
4584 TestMigrateSessionEarlyNonMigratableStream(true);
4585}
4586
4587void QuicStreamFactoryTestBase::TestMigrateSessionEarlyNonMigratableStream(
4588 bool migrate_idle_sessions) {
4589 test_params_.quic_migrate_idle_sessions = migrate_idle_sessions;
Zhongyi Shi1a054612018-06-14 04:59:084590 InitializeConnectionMigrationV2Test(
jri231c2972016-03-08 19:50:114591 {kDefaultNetworkForTests, kNewNetworkForTests});
4592 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4593 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4594
Ryan Hamiltonabad59e2019-06-06 04:02:594595 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:364596 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:434597 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi32fe14d42019-02-28 00:25:364598 if (!migrate_idle_sessions) {
4599 socket_data.AddWrite(
4600 SYNCHRONOUS,
4601 client_maker_.MakeRstAckAndConnectionClosePacket(
4602 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
4603 quic::QUIC_STREAM_CANCELLED,
4604 quic::QuicTime::Delta::FromMilliseconds(0), 1, 1, 1,
4605 quic::QUIC_CONNECTION_MIGRATION_NO_MIGRATABLE_STREAMS,
4606 "net error"));
4607 }
Zhongyi Shi5f587cc2017-11-21 23:24:174608 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri231c2972016-03-08 19:50:114609
Zhongyi Shi21e99532018-07-17 22:23:074610 // Set up the second socket data provider that is used for probing.
Ryan Hamiltonabad59e2019-06-06 04:02:594611 MockQuicData quic_data1(version_);
Zhongyi Shi21e99532018-07-17 22:23:074612 // Connectivity probe to be sent on the new path.
Zhongyi Shi879659422018-08-02 17:58:254613 quic_data1.AddWrite(SYNCHRONOUS,
4614 client_maker_.MakeConnectivityProbingPacket(2, true));
Zhongyi Shi21e99532018-07-17 22:23:074615 quic_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause
4616 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:254617 quic_data1.AddRead(ASYNC,
4618 server_maker_.MakeConnectivityProbingPacket(1, false));
Zhongyi Shi32fe14d42019-02-28 00:25:364619 if (migrate_idle_sessions) {
4620 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
4621 // A RESET will be sent to the peer to cancel the non-migratable stream.
4622 quic_data1.AddWrite(
4623 SYNCHRONOUS,
4624 client_maker_.MakeRstPacket(
4625 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
4626 quic::QUIC_STREAM_CANCELLED));
4627 // Ping packet to send after migration is completed.
4628 quic_data1.AddWrite(SYNCHRONOUS,
4629 client_maker_.MakeAckAndPingPacket(4, false, 1, 1, 1));
4630 }
Zhongyi Shi21e99532018-07-17 22:23:074631 quic_data1.AddSocketDataToFactory(socket_factory_.get());
4632
jri231c2972016-03-08 19:50:114633 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:454634 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:334635 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:034636 request.Request(
Nick Harper23290b82019-05-02 00:02:564637 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:514638 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:034639 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
4640 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:014641 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:244642 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri231c2972016-03-08 19:50:114643 EXPECT_TRUE(stream.get());
4644
4645 // Cause QUIC stream to be created, but marked as non-migratable.
4646 HttpRequestInfo request_info;
Zhongyi Shibb28b1f2018-07-18 02:41:264647 request_info.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
Ramin Halavati683bcaa92018-02-14 08:42:394648 request_info.traffic_annotation =
4649 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:274650 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:394651 net_log_, CompletionOnceCallback()));
jri231c2972016-03-08 19:50:114652
4653 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:504654 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri231c2972016-03-08 19:50:114655 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4656 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4657
4658 // Trigger connection migration. Since there is a non-migratable stream,
Zhongyi Shic16b4102019-02-12 00:37:404659 // this should cause session to migrate.
jri231c2972016-03-08 19:50:114660 session->OnPathDegrading();
4661
4662 // Run the message loop so that data queued in the new socket is read by the
4663 // packet reader.
4664 base::RunLoop().RunUntilIdle();
4665
jri231c2972016-03-08 19:50:114666 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4667 EXPECT_EQ(1u, session->GetNumActiveStreams());
4668
Zhongyi Shi21e99532018-07-17 22:23:074669 // Resume the data to read the connectivity probing response to declare probe
4670 // as successful. Non-migratable streams will be closed.
4671 quic_data1.Resume();
Zhongyi Shi32fe14d42019-02-28 00:25:364672 if (migrate_idle_sessions)
4673 base::RunLoop().RunUntilIdle();
Zhongyi Shic16b4102019-02-12 00:37:404674
Zhongyi Shi32fe14d42019-02-28 00:25:364675 EXPECT_EQ(migrate_idle_sessions, HasActiveSession(host_port_pair_));
Zhongyi Shi21e99532018-07-17 22:23:074676 EXPECT_EQ(0u, session->GetNumActiveStreams());
jri231c2972016-03-08 19:50:114677
Zhongyi Shi21e99532018-07-17 22:23:074678 EXPECT_TRUE(quic_data1.AllReadDataConsumed());
4679 EXPECT_TRUE(quic_data1.AllWriteDataConsumed());
jri231c2972016-03-08 19:50:114680 EXPECT_TRUE(socket_data.AllReadDataConsumed());
4681 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
4682}
4683
jri9c541572016-03-29 17:51:484684TEST_P(QuicStreamFactoryTest, MigrateSessionEarlyConnectionMigrationDisabled) {
Zhongyi Shi1a054612018-06-14 04:59:084685 InitializeConnectionMigrationV2Test(
jri9c541572016-03-29 17:51:484686 {kDefaultNetworkForTests, kNewNetworkForTests});
4687 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4688 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4689
Ryan Hamiltonabad59e2019-06-06 04:02:594690 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:364691 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:434692 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
4693 socket_data.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334694 SYNCHRONOUS, client_maker_.MakeRstPacket(
4695 2, true, GetNthClientInitiatedBidirectionalStreamId(0),
4696 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:174697 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9c541572016-03-29 17:51:484698
4699 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:454700 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:334701 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:034702 request.Request(
Nick Harper23290b82019-05-02 00:02:564703 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:514704 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:034705 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
4706 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:014707 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:244708 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9c541572016-03-29 17:51:484709 EXPECT_TRUE(stream.get());
4710
4711 // Cause QUIC stream to be created.
4712 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:394713 request_info.traffic_annotation =
4714 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:274715 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:394716 net_log_, CompletionOnceCallback()));
jri9c541572016-03-29 17:51:484717
4718 // Ensure that session is alive and active.
bnc912a04b2016-04-20 14:19:504719 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
jri9c541572016-03-29 17:51:484720 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4721 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4722
4723 // Set session config to have connection migration disabled.
Ryan Hamilton8d9ee76e2018-05-29 23:52:524724 quic::test::QuicConfigPeer::SetReceivedDisableConnectionMigration(
4725 session->config());
jri9c541572016-03-29 17:51:484726 EXPECT_TRUE(session->config()->DisableConnectionMigration());
4727
4728 // Trigger connection migration. Since there is a non-migratable stream,
4729 // this should cause session to be continue without migrating.
4730 session->OnPathDegrading();
4731
4732 // Run the message loop so that data queued in the new socket is read by the
4733 // packet reader.
4734 base::RunLoop().RunUntilIdle();
4735
4736 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4737 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4738 EXPECT_EQ(1u, session->GetNumActiveStreams());
4739
4740 stream.reset();
4741
4742 EXPECT_TRUE(socket_data.AllReadDataConsumed());
4743 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
4744}
4745
Zhongyi Shi3c4c9e92018-07-02 23:16:234746// Regression test for http://crbug.com/791886.
4747// This test verifies that the old packet writer which encountered an
4748// asynchronous write error will be blocked during migration on write error. New
4749// packets would not be written until the one with write error is rewritten on
4750// the new network.
4751TEST_P(QuicStreamFactoryTest, MigrateSessionOnAysncWriteError) {
4752 InitializeConnectionMigrationV2Test(
4753 {kDefaultNetworkForTests, kNewNetworkForTests});
4754 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4755 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4756 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4757
4758 // Using a testing task runner so that we can control time.
4759 // base::RunLoop() controls mocked socket writes and reads.
4760 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
4761 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
4762
Ryan Hamiltonabad59e2019-06-06 04:02:594763 MockQuicData socket_data(version_);
Zhongyi Shi3c4c9e92018-07-02 23:16:234764 quic::QuicStreamOffset header_stream_offset = 0;
4765 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4766 socket_data.AddWrite(
4767 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4768 socket_data.AddWrite(ASYNC, ERR_ADDRESS_UNREACHABLE);
4769 socket_data.AddSocketDataToFactory(socket_factory_.get());
4770
4771 // Set up second socket data provider that is used after
4772 // migration. The request is rewritten to this new socket, and the
4773 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:594774 MockQuicData socket_data1(version_);
Zhongyi Shi3c4c9e92018-07-02 23:16:234775 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:334776 SYNCHRONOUS, ConstructGetRequestPacket(
4777 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
4778 true, &header_stream_offset));
4779 socket_data1.AddWrite(SYNCHRONOUS,
4780 ConstructGetRequestPacket(
4781 3, GetNthClientInitiatedBidirectionalStreamId(1),
4782 GetNthClientInitiatedBidirectionalStreamId(0), true,
4783 true, &header_stream_offset));
4784 socket_data1.AddRead(
4785 ASYNC,
4786 ConstructOkResponsePacket(
4787 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
4788 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4789 socket_data1.AddWrite(
4790 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
4791 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
4792 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
4793 socket_data1.AddWrite(
4794 SYNCHRONOUS, client_maker_.MakeRstPacket(
4795 5, false, GetNthClientInitiatedBidirectionalStreamId(1),
Frank Kastenholz684ea412019-02-13 18:48:184796 quic::QUIC_STREAM_CANCELLED, 0,
4797 /*include_stop_sending_if_v99=*/true));
Zhongyi Shi3c4c9e92018-07-02 23:16:234798
4799 socket_data1.AddSocketDataToFactory(socket_factory_.get());
4800
4801 // Create request #1 and QuicHttpStream.
4802 QuicStreamRequest request1(factory_.get());
4803 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:034804 request1.Request(
Nick Harper23290b82019-05-02 00:02:564805 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:514806 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:034807 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
4808 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi3c4c9e92018-07-02 23:16:234809 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4810 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
4811 EXPECT_TRUE(stream1.get());
4812
4813 HttpRequestInfo request_info1;
4814 request_info1.method = "GET";
4815 request_info1.url = GURL("https://www.example.org/");
4816 request_info1.traffic_annotation =
4817 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4818 EXPECT_EQ(OK,
4819 stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
4820 net_log_, CompletionOnceCallback()));
4821
4822 // Request #2 returns synchronously because it pools to existing session.
4823 TestCompletionCallback callback2;
4824 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:514825 EXPECT_EQ(OK,
4826 request2.Request(
4827 host_port_pair_, version_.transport_version, privacy_mode_,
4828 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
4829 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
4830 failed_on_default_network_callback_, callback2.callback()));
Zhongyi Shi3c4c9e92018-07-02 23:16:234831 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
4832 EXPECT_TRUE(stream2.get());
4833
4834 HttpRequestInfo request_info2;
4835 request_info2.method = "GET";
4836 request_info2.url = GURL("https://www.example.org/");
4837 request_info2.traffic_annotation =
4838 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4839 EXPECT_EQ(OK,
4840 stream2->InitializeStream(&request_info2, true, DEFAULT_PRIORITY,
4841 net_log_, CompletionOnceCallback()));
4842
4843 // Ensure that session is alive and active.
4844 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
4845 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4846 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4847 EXPECT_EQ(2u, session->GetNumActiveStreams());
4848
4849 // Send GET request on stream1. This should cause an async write error.
4850 HttpResponseInfo response;
4851 HttpRequestHeaders request_headers;
4852 EXPECT_EQ(OK, stream1->SendRequest(request_headers, &response,
4853 callback_.callback()));
4854 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4855
4856 // Run the message loop so that asynchronous write completes and a connection
4857 // migration on write error attempt is posted in QuicStreamFactory's task
4858 // runner.
4859 base::RunLoop().RunUntilIdle();
4860 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4861
4862 // Send GET request on stream. This will cause another write attempt before
4863 // migration on write error is exectued.
4864 HttpResponseInfo response2;
4865 HttpRequestHeaders request_headers2;
4866 EXPECT_EQ(OK, stream2->SendRequest(request_headers2, &response2,
4867 callback2.callback()));
4868
4869 // Run the task runner so that migration on write error is finally executed.
4870 task_runner->RunUntilIdle();
4871
Zhongyi Shia7dd46b2018-07-12 22:59:294872 // Verify the session is still alive and not marked as going away.
Zhongyi Shi3c4c9e92018-07-02 23:16:234873 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:294874 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi3c4c9e92018-07-02 23:16:234875 EXPECT_EQ(2u, session->GetNumActiveStreams());
Zhongyi Shia7dd46b2018-07-12 22:59:294876 // There should be one task posted to migrate back to the default network in
4877 // kMinRetryTimeForDefaultNetworkSecs.
4878 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4879 EXPECT_EQ(base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs),
4880 task_runner->NextPendingTaskDelay());
Zhongyi Shi3c4c9e92018-07-02 23:16:234881
4882 // Verify that response headers on the migrated socket were delivered to the
4883 // stream.
4884 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
4885 EXPECT_EQ(200, response.headers->response_code());
4886
4887 stream1.reset();
4888 stream2.reset();
4889
4890 EXPECT_TRUE(socket_data.AllReadDataConsumed());
4891 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
4892 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
4893 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
4894}
4895
Zhongyi Shia7dd46b2018-07-12 22:59:294896// Verify session is not marked as going away after connection migration on
4897// write error and migrate back to default network logic is applied to bring the
4898// migrated session back to the default network. Migration singals delivered
4899// in the following order (alternate network is always availabe):
4900// - session on the default network encountered a write error;
4901// - session successfully migrated to the non-default network;
4902// - session attempts to migrate back to default network post migration;
4903// - migration back to the default network is successful.
4904TEST_P(QuicStreamFactoryTest, MigrateBackToDefaultPostMigrationOnWriteError) {
4905 InitializeConnectionMigrationV2Test(
4906 {kDefaultNetworkForTests, kNewNetworkForTests});
4907 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
4908 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4909 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
4910
4911 // Using a testing task runner so that we can control time.
4912 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
4913 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
4914
Ryan Hamiltonabad59e2019-06-06 04:02:594915 MockQuicData socket_data(version_);
Zhongyi Shia7dd46b2018-07-12 22:59:294916 quic::QuicStreamOffset header_stream_offset = 0;
4917 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4918 socket_data.AddWrite(
4919 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
4920 socket_data.AddWrite(ASYNC, ERR_ADDRESS_UNREACHABLE);
4921 socket_data.AddSocketDataToFactory(socket_factory_.get());
4922
4923 // Set up second socket data provider that is used after
4924 // migration. The request is rewritten to this new socket, and the
4925 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:594926 MockQuicData quic_data2(version_);
Fan Yang32c5a112018-12-10 20:06:334927 quic_data2.AddWrite(
4928 SYNCHRONOUS, ConstructGetRequestPacket(
4929 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
4930 true, &header_stream_offset));
Zhongyi Shia7dd46b2018-07-12 22:59:294931 quic_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:334932 ASYNC,
4933 ConstructOkResponsePacket(
4934 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shia7dd46b2018-07-12 22:59:294935 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
4936 quic_data2.AddSocketDataToFactory(socket_factory_.get());
4937
4938 // Create request QuicHttpStream.
4939 QuicStreamRequest request1(factory_.get());
4940 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:034941 request1.Request(
Nick Harper23290b82019-05-02 00:02:564942 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:514943 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:034944 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
4945 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shia7dd46b2018-07-12 22:59:294946 EXPECT_THAT(callback_.WaitForResult(), IsOk());
4947 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
4948 EXPECT_TRUE(stream1.get());
4949
4950 HttpRequestInfo request_info1;
4951 request_info1.method = "GET";
4952 request_info1.url = GURL("https://www.example.org/");
4953 request_info1.traffic_annotation =
4954 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
4955 EXPECT_EQ(OK,
4956 stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
4957 net_log_, CompletionOnceCallback()));
4958
4959 // Ensure that session is alive and active.
4960 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
4961 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4962 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4963 EXPECT_EQ(1u, session->GetNumActiveStreams());
4964
4965 // Send GET request. This should cause an async write error.
4966 HttpResponseInfo response;
4967 HttpRequestHeaders request_headers;
4968 EXPECT_EQ(OK, stream1->SendRequest(request_headers, &response,
4969 callback_.callback()));
4970 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
4971
4972 // Run the message loop so that asynchronous write completes and a connection
4973 // migration on write error attempt is posted in QuicStreamFactory's task
4974 // runner.
4975 base::RunLoop().RunUntilIdle();
4976 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4977
4978 // Run the task runner so that migration on write error is finally executed.
4979 task_runner->RunUntilIdle();
4980
4981 // Verify the session is still alive and not marked as going away.
4982 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
4983 EXPECT_TRUE(HasActiveSession(host_port_pair_));
4984 EXPECT_EQ(1u, session->GetNumActiveStreams());
4985 // There should be one task posted to migrate back to the default network in
4986 // kMinRetryTimeForDefaultNetworkSecs.
4987 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
4988 base::TimeDelta expected_delay =
4989 base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs);
4990 EXPECT_EQ(expected_delay, task_runner->NextPendingTaskDelay());
4991
4992 // Verify that response headers on the migrated socket were delivered to the
4993 // stream.
4994 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
4995 EXPECT_EQ(200, response.headers->response_code());
4996
4997 // Set up the third socket data provider for migrate back to default network.
Ryan Hamiltonabad59e2019-06-06 04:02:594998 MockQuicData quic_data3(version_);
Zhongyi Shia7dd46b2018-07-12 22:59:294999 // Connectivity probe to be sent on the new path.
Zhongyi Shi879659422018-08-02 17:58:255000 quic_data3.AddWrite(SYNCHRONOUS,
5001 client_maker_.MakeConnectivityProbingPacket(3, false));
Zhongyi Shia7dd46b2018-07-12 22:59:295002 // Connectivity probe to receive from the server.
Zhongyi Shi879659422018-08-02 17:58:255003 quic_data3.AddRead(ASYNC,
5004 server_maker_.MakeConnectivityProbingPacket(2, false));
Zhongyi Shia7dd46b2018-07-12 22:59:295005 quic_data3.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5006 quic_data3.AddWrite(ASYNC, client_maker_.MakeAckPacket(4, 1, 2, 1, 1, true));
5007 quic_data3.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335008 SYNCHRONOUS, client_maker_.MakeRstPacket(
5009 5, false, GetNthClientInitiatedBidirectionalStreamId(0),
Frank Kastenholz684ea412019-02-13 18:48:185010 quic::QUIC_STREAM_CANCELLED, 0,
5011 /*include_stop_sending_if_v99=*/true));
Zhongyi Shia7dd46b2018-07-12 22:59:295012 quic_data3.AddSocketDataToFactory(socket_factory_.get());
5013
5014 // Fast forward to fire the migrate back timer and verify the session
5015 // successfully migrates back to the default network.
5016 task_runner->FastForwardBy(expected_delay);
5017
5018 // Verify the session is still alive and not marked as going away.
5019 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5020 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5021 EXPECT_EQ(1u, session->GetNumActiveStreams());
5022
5023 // There should be one task posted to one will resend a connectivity probe and
5024 // the other will retry migrate back, both are cancelled.
5025 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
5026 task_runner->FastForwardBy(
5027 base::TimeDelta::FromSeconds(2 * kMinRetryTimeForDefaultNetworkSecs));
5028 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
5029
5030 stream1.reset();
5031 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5032 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5033 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
5034 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
5035 EXPECT_TRUE(quic_data3.AllReadDataConsumed());
5036 EXPECT_TRUE(quic_data3.AllWriteDataConsumed());
5037}
5038
Zhongyi Shic1449372018-08-09 09:58:585039// This test verifies that the connection will not attempt connection migration
5040// (send connectivity probes on alternate path) when path degrading is detected
5041// and handshake is not confirmed.
5042TEST_P(QuicStreamFactoryTest,
5043 NoMigrationOnPathDegradingBeforeHandshakeConfirmed) {
5044 InitializeConnectionMigrationV2Test(
5045 {kDefaultNetworkForTests, kNewNetworkForTests});
5046
5047 // Using a testing task runner.
5048 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
5049 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
5050
5051 // Use cold start mode to send crypto message for handshake.
5052 crypto_client_stream_factory_.set_handshake_mode(
5053 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
5054
Ryan Hamiltonabad59e2019-06-06 04:02:595055 MockQuicData socket_data(version_);
Zhongyi Shic1449372018-08-09 09:58:585056 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5057 socket_data.AddWrite(ASYNC, client_maker_.MakeDummyCHLOPacket(1));
5058 socket_data.AddSocketDataToFactory(socket_factory_.get());
5059
5060 // Create request and QuicHttpStream.
5061 QuicStreamRequest request(factory_.get());
5062 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:035063 request.Request(
Nick Harper23290b82019-05-02 00:02:565064 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:515065 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:035066 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5067 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shic1449372018-08-09 09:58:585068
5069 base::RunLoop().RunUntilIdle();
5070
5071 // Ensure that session is alive but not active.
5072 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5073 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
5074 QuicChromiumClientSession* session = GetPendingSession(host_port_pair_);
5075 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5076 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
5077
5078 // Cause the connection to report path degrading to the session.
5079 // Session will ignore the signal as handshake is not completed.
5080 session->connection()->OnPathDegradingTimeout();
5081 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
5082
5083 EXPECT_FALSE(HasActiveSession(host_port_pair_));
Zhongyi Shi8de43832018-08-15 23:40:005084 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
Zhongyi Shic1449372018-08-09 09:58:585085 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5086 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5087}
5088
Zhongyi Shi634c1882018-08-16 04:05:595089// This test verifies that if a connection is closed with
5090// QUIC_NETWORK_IDLE_TIMEOUT before handshake is completed and there is no
5091// alternate network, no new connection will be created.
5092TEST_P(QuicStreamFactoryTest, NoAlternateNetworkBeforeHandshakeOnIdleTimeout) {
5093 TestNoAlternateNetworkBeforeHandshake(quic::QUIC_NETWORK_IDLE_TIMEOUT);
5094}
5095
5096// This test verifies that if a connection is closed with QUIC_HANDSHAKE_TIMEOUT
5097// and there is no alternate network, no new connection will be created.
5098TEST_P(QuicStreamFactoryTest, NoAlternateNetworkOnHandshakeTimeout) {
5099 TestNoAlternateNetworkBeforeHandshake(quic::QUIC_HANDSHAKE_TIMEOUT);
5100}
5101
5102void QuicStreamFactoryTestBase::TestNoAlternateNetworkBeforeHandshake(
5103 quic::QuicErrorCode quic_error) {
5104 DCHECK(quic_error == quic::QUIC_NETWORK_IDLE_TIMEOUT ||
5105 quic_error == quic::QUIC_HANDSHAKE_TIMEOUT);
5106 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
5107
5108 // Using a testing task runner.
5109 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
5110 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
5111
5112 // Use cold start mode to send crypto message for handshake.
5113 crypto_client_stream_factory_.set_handshake_mode(
5114 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
5115
Ryan Hamiltonabad59e2019-06-06 04:02:595116 MockQuicData socket_data(version_);
Zhongyi Shi634c1882018-08-16 04:05:595117 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5118 socket_data.AddWrite(ASYNC, client_maker_.MakeDummyCHLOPacket(1));
5119 socket_data.AddSocketDataToFactory(socket_factory_.get());
5120
5121 // Create request.
5122 QuicStreamRequest request(factory_.get());
5123 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:035124 request.Request(
Nick Harper23290b82019-05-02 00:02:565125 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:515126 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:035127 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5128 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi634c1882018-08-16 04:05:595129
5130 base::RunLoop().RunUntilIdle();
5131
5132 // Ensure that session is alive but not active.
5133 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5134 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
5135 QuicChromiumClientSession* session = GetPendingSession(host_port_pair_);
5136 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5137 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
5138
5139 // Cause the connection to report path degrading to the session.
5140 // Session will ignore the signal as handshake is not completed.
5141 session->connection()->OnPathDegradingTimeout();
5142 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
5143 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5144 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
5145
5146 // Cause the connection to close due to |quic_error| before handshake.
Victor Vasiliev076657c2019-03-12 02:46:435147 std::string error_details;
Zhongyi Shi634c1882018-08-16 04:05:595148 if (quic_error == quic::QUIC_NETWORK_IDLE_TIMEOUT) {
5149 error_details = "No recent network activity.";
5150 } else {
5151 error_details = "Handshake timeout expired.";
5152 }
5153 session->connection()->CloseConnection(
5154 quic_error, error_details, quic::ConnectionCloseBehavior::SILENT_CLOSE);
5155
5156 // A task will be posted to clean up the session in the factory.
5157 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
5158 task_runner->FastForwardUntilNoTasksRemain();
5159
5160 // No new session should be created as there is no alternate network.
5161 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5162 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
5163 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5164 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5165}
5166
Zhongyi Shi8de43832018-08-15 23:40:005167TEST_P(QuicStreamFactoryTest, NewConnectionBeforeHandshakeAfterIdleTimeout) {
5168 TestNewConnectionOnAlternateNetworkBeforeHandshake(
5169 quic::QUIC_NETWORK_IDLE_TIMEOUT);
5170}
5171
5172TEST_P(QuicStreamFactoryTest, NewConnectionAfterHandshakeTimeout) {
5173 TestNewConnectionOnAlternateNetworkBeforeHandshake(
5174 quic::QUIC_HANDSHAKE_TIMEOUT);
5175}
5176
Zhongyi Shif3fcbbe62018-08-16 22:52:085177// Sets up a test to verify that a new connection will be created on the
5178// alternate network after the initial connection fails before handshake with
5179// signals delivered in the following order (alternate network is available):
5180// - the default network is not able to complete crypto handshake;
5181// - the original connection is closed with |quic_error|;
5182// - a new connection is created on the alternate network and is able to finish
5183// crypto handshake;
5184// - the new session on the alternate network attempts to migrate back to the
5185// default network by sending probes;
5186// - default network being disconnected is delivered: session will stop probing
5187// the original network.
5188// - alternate network is made by default.
Zhongyi Shi8de43832018-08-15 23:40:005189void QuicStreamFactoryTestBase::
5190 TestNewConnectionOnAlternateNetworkBeforeHandshake(
5191 quic::QuicErrorCode quic_error) {
5192 DCHECK(quic_error == quic::QUIC_NETWORK_IDLE_TIMEOUT ||
5193 quic_error == quic::QUIC_HANDSHAKE_TIMEOUT);
Zhongyi Shi967d2f12019-02-08 20:58:535194 test_params_.quic_retry_on_alternate_network_before_handshake = true;
Zhongyi Shi8de43832018-08-15 23:40:005195 InitializeConnectionMigrationV2Test(
5196 {kDefaultNetworkForTests, kNewNetworkForTests});
5197
5198 // Using a testing task runner.
5199 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
5200 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
5201
5202 // Use cold start mode to send crypto message for handshake.
5203 crypto_client_stream_factory_.set_handshake_mode(
5204 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
5205
5206 // Socket data for connection on the default network.
Ryan Hamiltonabad59e2019-06-06 04:02:595207 MockQuicData socket_data(version_);
Zhongyi Shi8de43832018-08-15 23:40:005208 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5209 socket_data.AddWrite(ASYNC, client_maker_.MakeDummyCHLOPacket(1));
5210 socket_data.AddSocketDataToFactory(socket_factory_.get());
5211
5212 // Socket data for connection on the alternate network.
Ryan Hamiltonabad59e2019-06-06 04:02:595213 MockQuicData socket_data2(version_);
Zhongyi Shi8de43832018-08-15 23:40:005214 quic::QuicStreamOffset header_stream_offset = 0;
5215 socket_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
5216 socket_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
5217 // Change the encryption level after handshake is confirmed.
5218 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5219 socket_data2.AddWrite(
5220 ASYNC, ConstructInitialSettingsPacket(2, &header_stream_offset));
5221 socket_data2.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335222 ASYNC, ConstructGetRequestPacket(
5223 3, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
5224 &header_stream_offset));
Zhongyi Shi8de43832018-08-15 23:40:005225 socket_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:335226 ASYNC,
5227 ConstructOkResponsePacket(
5228 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shi8de43832018-08-15 23:40:005229 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:335230 socket_data2.AddWrite(
5231 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
5232 5, false, GetNthClientInitiatedBidirectionalStreamId(0),
5233 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi8de43832018-08-15 23:40:005234 socket_data2.AddSocketDataToFactory(socket_factory_.get());
5235
Zhongyi Shif3fcbbe62018-08-16 22:52:085236 // Socket data for probing on the default network.
Ryan Hamiltonabad59e2019-06-06 04:02:595237 MockQuicData probing_data(version_);
Zhongyi Shif3fcbbe62018-08-16 22:52:085238 probing_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
5239 probing_data.AddWrite(SYNCHRONOUS,
5240 client_maker_.MakeConnectivityProbingPacket(4, false));
5241 probing_data.AddSocketDataToFactory(socket_factory_.get());
5242
Zhongyi Shi8de43832018-08-15 23:40:005243 // Create request and QuicHttpStream.
5244 QuicStreamRequest request(factory_.get());
5245 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:035246 request.Request(
Nick Harper23290b82019-05-02 00:02:565247 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:515248 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:035249 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5250 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi8de43832018-08-15 23:40:005251
5252 base::RunLoop().RunUntilIdle();
5253
5254 // Ensure that session is alive but not active.
5255 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5256 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
5257 QuicChromiumClientSession* session = GetPendingSession(host_port_pair_);
5258 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5259 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
Zhongyi Shia6b68d112018-09-24 07:49:035260 EXPECT_FALSE(failed_on_default_network_);
Zhongyi Shi8de43832018-08-15 23:40:005261
Victor Vasiliev076657c2019-03-12 02:46:435262 std::string error_details;
Zhongyi Shi8de43832018-08-15 23:40:005263 if (quic_error == quic::QUIC_NETWORK_IDLE_TIMEOUT) {
5264 error_details = "No recent network activity.";
5265 } else {
5266 error_details = "Handshake timeout expired.";
5267 }
5268 session->connection()->CloseConnection(
5269 quic_error, error_details, quic::ConnectionCloseBehavior::SILENT_CLOSE);
5270
5271 // A task will be posted to clean up the session in the factory.
5272 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
5273 task_runner->FastForwardUntilNoTasksRemain();
5274
5275 // Verify a new session is created on the alternate network.
5276 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
5277 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5278 QuicChromiumClientSession* session2 = GetPendingSession(host_port_pair_);
5279 EXPECT_NE(session, session2);
Zhongyi Shia6b68d112018-09-24 07:49:035280 EXPECT_TRUE(failed_on_default_network_);
Zhongyi Shi8de43832018-08-15 23:40:005281
5282 // Confirm the handshake on the alternate network.
5283 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5284 quic::QuicSession::HANDSHAKE_CONFIRMED);
5285 EXPECT_THAT(callback_.WaitForResult(), IsOk());
5286 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5287 // Resume the data now so that data can be sent and read.
5288 socket_data2.Resume();
5289
5290 // Create the stream.
5291 std::unique_ptr<HttpStream> stream = CreateStream(&request);
5292 EXPECT_TRUE(stream.get());
5293 HttpRequestInfo request_info;
5294 request_info.method = "GET";
5295 request_info.url = GURL("https://www.example.org/");
5296 request_info.traffic_annotation =
5297 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5298 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
5299 net_log_, CompletionOnceCallback()));
5300 // Send the request.
5301 HttpResponseInfo response;
5302 HttpRequestHeaders request_headers;
5303 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
5304 callback_.callback()));
5305 // Run the message loop to finish asynchronous mock write.
5306 base::RunLoop().RunUntilIdle();
5307 // Read the response.
5308 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
5309 EXPECT_EQ(200, response.headers->response_code());
5310
Zhongyi Shif3fcbbe62018-08-16 22:52:085311 // There should be a new task posted to migrate back to the default network.
5312 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
5313 base::TimeDelta next_task_delay = task_runner->NextPendingTaskDelay();
5314 EXPECT_EQ(base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs),
5315 next_task_delay);
5316 task_runner->FastForwardBy(next_task_delay);
5317
5318 // There should be two tasks posted. One will retry probing and the other
5319 // will retry migrate back.
5320 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
5321 next_task_delay = task_runner->NextPendingTaskDelay();
5322 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2 * kDefaultRTTMilliSecs),
5323 next_task_delay);
5324
5325 // Deliver the signal that the default network is disconnected.
5326 scoped_mock_network_change_notifier_->mock_network_change_notifier()
5327 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
5328 // Verify no connectivity probes will be sent as probing will be cancelled.
5329 task_runner->FastForwardUntilNoTasksRemain();
5330 // Deliver the signal that the alternate network is made default.
5331 scoped_mock_network_change_notifier_->mock_network_change_notifier()
5332 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
5333 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
5334
Zhongyi Shi8de43832018-08-15 23:40:005335 stream.reset();
5336 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5337 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5338 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
5339 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
5340}
5341
Zhongyi Shi247d6322018-07-24 07:03:355342// Test that connection will be closed with PACKET_WRITE_ERROR if a write error
5343// is triggered before handshake is confirmed and connection migration is turned
5344// on.
5345TEST_P(QuicStreamFactoryTest, MigrationOnWriteErrorBeforeHandshakeConfirmed) {
Zhongyi Shi967d2f12019-02-08 20:58:535346 DCHECK(!test_params_.quic_retry_on_alternate_network_before_handshake);
Zhongyi Shi247d6322018-07-24 07:03:355347 InitializeConnectionMigrationV2Test(
5348 {kDefaultNetworkForTests, kNewNetworkForTests});
5349
5350 // Use unmocked crypto stream to do crypto connect.
5351 crypto_client_stream_factory_.set_handshake_mode(
Zhongyi Shi879659422018-08-02 17:58:255352 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
Zhongyi Shi247d6322018-07-24 07:03:355353
Ryan Hamiltonabad59e2019-06-06 04:02:595354 MockQuicData socket_data(version_);
Zhongyi Shi247d6322018-07-24 07:03:355355 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5356 // Trigger PACKET_WRITE_ERROR when sending packets in crypto connect.
5357 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
5358 socket_data.AddSocketDataToFactory(socket_factory_.get());
5359
5360 // Create request, should fail after the write of the CHLO fails.
5361 QuicStreamRequest request(factory_.get());
5362 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:035363 request.Request(
Nick Harper23290b82019-05-02 00:02:565364 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:515365 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:035366 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5367 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi247d6322018-07-24 07:03:355368 EXPECT_EQ(ERR_QUIC_HANDSHAKE_FAILED, callback_.WaitForResult());
5369 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5370 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
5371
5372 // Verify new requests can be sent normally.
5373 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:275374 MockCryptoClientStream::COLD_START);
Zhongyi Shi247d6322018-07-24 07:03:355375 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5376 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
Ryan Hamiltonabad59e2019-06-06 04:02:595377 MockQuicData socket_data2(version_);
Zhongyi Shi247d6322018-07-24 07:03:355378 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5379 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
5380 socket_data2.AddSocketDataToFactory(socket_factory_.get());
5381
5382 QuicStreamRequest request2(factory_.get());
5383 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:035384 request2.Request(
Nick Harper23290b82019-05-02 00:02:565385 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:515386 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:035387 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5388 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi247d6322018-07-24 07:03:355389 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5390 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
5391 // Run the message loop to complete host resolution.
5392 base::RunLoop().RunUntilIdle();
5393
5394 // Complete handshake. QuicStreamFactory::Job should complete and succeed.
5395 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5396 quic::QuicSession::HANDSHAKE_CONFIRMED);
5397 EXPECT_THAT(callback_.WaitForResult(), IsOk());
5398 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5399 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
5400
5401 // Create QuicHttpStream.
5402 std::unique_ptr<HttpStream> stream = CreateStream(&request2);
5403 EXPECT_TRUE(stream.get());
5404 stream.reset();
5405 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5406 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5407 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
5408 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
5409}
5410
Zhongyi Shif2524bf2019-01-27 07:44:035411// Test that if the original connection is closed with QUIC_PACKET_WRITE_ERROR
5412// before handshake is confirmed and new connection before handshake is turned
5413// on, a new connection will be retried on the alternate network.
5414TEST_P(QuicStreamFactoryTest,
5415 RetryConnectionOnWriteErrorBeforeHandshakeConfirmed) {
Zhongyi Shi967d2f12019-02-08 20:58:535416 test_params_.quic_retry_on_alternate_network_before_handshake = true;
Zhongyi Shif2524bf2019-01-27 07:44:035417 InitializeConnectionMigrationV2Test(
5418 {kDefaultNetworkForTests, kNewNetworkForTests});
5419
5420 // Use unmocked crypto stream to do crypto connect.
5421 crypto_client_stream_factory_.set_handshake_mode(
5422 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
5423
5424 // Socket data for connection on the default network.
Ryan Hamiltonabad59e2019-06-06 04:02:595425 MockQuicData socket_data(version_);
Zhongyi Shif2524bf2019-01-27 07:44:035426 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5427 // Trigger PACKET_WRITE_ERROR when sending packets in crypto connect.
5428 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
5429 socket_data.AddSocketDataToFactory(socket_factory_.get());
5430
5431 // Socket data for connection on the alternate network.
Ryan Hamiltonabad59e2019-06-06 04:02:595432 MockQuicData socket_data2(version_);
Zhongyi Shif2524bf2019-01-27 07:44:035433 quic::QuicStreamOffset header_stream_offset = 0;
5434 socket_data2.AddWrite(SYNCHRONOUS, client_maker_.MakeDummyCHLOPacket(1));
5435 socket_data2.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
5436 // Change the encryption level after handshake is confirmed.
5437 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
5438 socket_data2.AddWrite(
5439 ASYNC, ConstructInitialSettingsPacket(2, &header_stream_offset));
5440 socket_data2.AddWrite(
5441 ASYNC, ConstructGetRequestPacket(
5442 3, GetNthClientInitiatedBidirectionalStreamId(0), true, true,
5443 &header_stream_offset));
5444 socket_data2.AddRead(
5445 ASYNC,
5446 ConstructOkResponsePacket(
5447 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
5448 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5449 socket_data2.AddWrite(
5450 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
5451 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
5452 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
5453 socket_data2.AddSocketDataToFactory(socket_factory_.get());
5454
5455 // Create request, should fail after the write of the CHLO fails.
5456 QuicStreamRequest request(factory_.get());
5457 EXPECT_EQ(ERR_IO_PENDING,
5458 request.Request(
Nick Harper23290b82019-05-02 00:02:565459 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:515460 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shif2524bf2019-01-27 07:44:035461 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5462 failed_on_default_network_callback_, callback_.callback()));
5463 // Ensure that the session is alive but not active.
5464 EXPECT_FALSE(HasActiveSession(host_port_pair_));
5465 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
5466 base::RunLoop().RunUntilIdle();
5467 QuicChromiumClientSession* session = GetPendingSession(host_port_pair_);
5468 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5469
5470 // Confirm the handshake on the alternate network.
5471 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
5472 quic::QuicSession::HANDSHAKE_CONFIRMED);
5473 EXPECT_THAT(callback_.WaitForResult(), IsOk());
5474 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5475
5476 // Resume the data now so that data can be sent and read.
5477 socket_data2.Resume();
5478
5479 // Create the stream.
5480 std::unique_ptr<HttpStream> stream = CreateStream(&request);
5481 EXPECT_TRUE(stream.get());
5482 HttpRequestInfo request_info;
5483 request_info.method = "GET";
5484 request_info.url = GURL("https://www.example.org/");
5485 request_info.traffic_annotation =
5486 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5487 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
5488 net_log_, CompletionOnceCallback()));
5489 // Send the request.
5490 HttpResponseInfo response;
5491 HttpRequestHeaders request_headers;
5492 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
5493 callback_.callback()));
5494 // Run the message loop to finish asynchronous mock write.
5495 base::RunLoop().RunUntilIdle();
5496 // Read the response.
5497 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
5498 EXPECT_EQ(200, response.headers->response_code());
5499
5500 stream.reset();
5501 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5502 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5503 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
5504 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
5505}
5506
jri9f303712016-09-13 01:10:225507void QuicStreamFactoryTestBase::TestMigrationOnWriteError(
5508 IoMode write_error_mode) {
Zhongyi Shi1a054612018-06-14 04:59:085509 InitializeConnectionMigrationV2Test(
jri9f303712016-09-13 01:10:225510 {kDefaultNetworkForTests, kNewNetworkForTests});
5511 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5512 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5513 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5514
Zhongyi Shi3c4c9e92018-07-02 23:16:235515 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
5516
Ryan Hamiltonabad59e2019-06-06 04:02:595517 MockQuicData socket_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:525518 quic::QuicStreamOffset header_stream_offset = 0;
jri9f303712016-09-13 01:10:225519 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
rch5cb522462017-04-25 20:18:365520 socket_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:435521 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
jri9f303712016-09-13 01:10:225522 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:175523 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:225524
5525 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:455526 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:335527 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:035528 request.Request(
Nick Harper23290b82019-05-02 00:02:565529 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:515530 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:035531 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5532 failed_on_default_network_callback_, callback_.callback()));
jri9f303712016-09-13 01:10:225533 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:245534 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9f303712016-09-13 01:10:225535 EXPECT_TRUE(stream.get());
5536
5537 // Cause QUIC stream to be created.
5538 HttpRequestInfo request_info;
5539 request_info.method = "GET";
5540 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:395541 request_info.traffic_annotation =
5542 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:275543 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:395544 net_log_, CompletionOnceCallback()));
jri9f303712016-09-13 01:10:225545
5546 // Ensure that session is alive and active.
5547 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
5548 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5549 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5550
5551 // Set up second socket data provider that is used after
5552 // migration. The request is rewritten to this new socket, and the
5553 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:595554 MockQuicData socket_data1(version_);
Fan Yang32c5a112018-12-10 20:06:335555 socket_data1.AddWrite(
5556 SYNCHRONOUS, ConstructGetRequestPacket(
5557 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
5558 true, &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:435559 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:335560 ASYNC,
5561 ConstructOkResponsePacket(
5562 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
jri9f303712016-09-13 01:10:225563 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:335564 socket_data1.AddWrite(
5565 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
5566 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
5567 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:175568 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:225569
5570 // Send GET request on stream. This should cause a write error, which triggers
5571 // a connection migration attempt.
5572 HttpResponseInfo response;
5573 HttpRequestHeaders request_headers;
5574 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
5575 callback_.callback()));
5576
5577 // Run the message loop so that the migration attempt is executed and
5578 // data queued in the new socket is read by the packet reader.
5579 base::RunLoop().RunUntilIdle();
5580
Zhongyi Shia7dd46b2018-07-12 22:59:295581 // Verify that session is alive and not marked as going awya.
jri9f303712016-09-13 01:10:225582 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:295583 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri9f303712016-09-13 01:10:225584 EXPECT_EQ(1u, session->GetNumActiveStreams());
5585
5586 // Verify that response headers on the migrated socket were delivered to the
5587 // stream.
5588 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
5589 EXPECT_EQ(200, response.headers->response_code());
5590
5591 stream.reset();
5592
5593 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5594 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5595 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
5596 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
5597}
5598
5599TEST_P(QuicStreamFactoryTest, MigrateSessionOnWriteErrorSynchronous) {
5600 TestMigrationOnWriteError(SYNCHRONOUS);
5601}
5602
5603TEST_P(QuicStreamFactoryTest, MigrateSessionOnWriteErrorAsync) {
5604 TestMigrationOnWriteError(ASYNC);
5605}
5606
5607void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorNoNewNetwork(
5608 IoMode write_error_mode) {
Zhongyi Shi1a054612018-06-14 04:59:085609 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jri9f303712016-09-13 01:10:225610 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5611 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5612
jri5b785512016-09-13 04:29:115613 // Use the test task runner, to force the migration alarm timeout later.
5614 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
5615
Ryan Hamiltonabad59e2019-06-06 04:02:595616 MockQuicData socket_data(version_);
jri9f303712016-09-13 01:10:225617 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:435618 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
jri9f303712016-09-13 01:10:225619 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:175620 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:225621
5622 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:455623 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:335624 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:035625 request.Request(
Nick Harper23290b82019-05-02 00:02:565626 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:515627 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:035628 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5629 failed_on_default_network_callback_, callback_.callback()));
jri9f303712016-09-13 01:10:225630 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:245631 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9f303712016-09-13 01:10:225632 EXPECT_TRUE(stream.get());
5633
5634 // Cause QUIC stream to be created.
5635 HttpRequestInfo request_info;
5636 request_info.method = "GET";
5637 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:395638 request_info.traffic_annotation =
5639 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:275640 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:395641 net_log_, CompletionOnceCallback()));
jri9f303712016-09-13 01:10:225642
5643 // Ensure that session is alive and active.
5644 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
5645 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5646 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5647
jri5b785512016-09-13 04:29:115648 // Send GET request on stream. This causes a write error, which triggers
5649 // a connection migration attempt. Since there are no networks
5650 // to migrate to, this causes the session to wait for a new network.
jri9f303712016-09-13 01:10:225651 HttpResponseInfo response;
5652 HttpRequestHeaders request_headers;
5653 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
5654 callback_.callback()));
jri5b785512016-09-13 04:29:115655
5656 // Complete any pending writes. Pending async MockQuicData writes
5657 // are run on the message loop, not on the test runner.
jri9f303712016-09-13 01:10:225658 base::RunLoop().RunUntilIdle();
jri5b785512016-09-13 04:29:115659
5660 // Write error causes migration task to be posted. Spin the loop.
5661 if (write_error_mode == ASYNC)
5662 runner_->RunNextTask();
5663
5664 // Migration has not yet failed. The session should be alive and active.
5665 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5666 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5667 EXPECT_EQ(1u, session->GetNumActiveStreams());
5668 EXPECT_TRUE(session->connection()->writer()->IsWriteBlocked());
5669
5670 // The migration will not fail until the migration alarm timeout.
5671 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5672 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5673 EXPECT_EQ(1u, session->GetNumActiveStreams());
5674 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
5675
5676 // Force migration alarm timeout to run.
5677 RunTestLoopUntilIdle();
5678
5679 // The connection should be closed. A request for response headers
5680 // should fail.
jri9f303712016-09-13 01:10:225681 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5682 EXPECT_FALSE(HasActiveSession(host_port_pair_));
jri5b785512016-09-13 04:29:115683 EXPECT_EQ(ERR_NETWORK_CHANGED, callback_.WaitForResult());
5684 EXPECT_EQ(ERR_NETWORK_CHANGED,
5685 stream->ReadResponseHeaders(callback_.callback()));
jri9f303712016-09-13 01:10:225686
Zhongyi Shi59aaf072019-01-17 03:32:135687 NetErrorDetails error_details;
5688 stream->PopulateNetErrorDetails(&error_details);
5689 EXPECT_EQ(error_details.quic_connection_error,
5690 quic::QUIC_CONNECTION_MIGRATION_NO_NEW_NETWORK);
5691
jri9f303712016-09-13 01:10:225692 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5693 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5694}
5695
5696TEST_P(QuicStreamFactoryTest,
5697 MigrateSessionOnWriteErrorNoNewNetworkSynchronous) {
5698 TestMigrationOnWriteErrorNoNewNetwork(SYNCHRONOUS);
5699}
5700
5701TEST_P(QuicStreamFactoryTest, MigrateSessionOnWriteErrorNoNewNetworkAsync) {
5702 TestMigrationOnWriteErrorNoNewNetwork(ASYNC);
5703}
5704
Zhongyi Shi0439ecc72018-07-11 04:41:265705TEST_P(QuicStreamFactoryTest,
5706 MigrateSessionOnWriteErrorWithMultipleRequestsSync) {
5707 TestMigrationOnWriteErrorWithMultipleRequests(SYNCHRONOUS);
5708}
5709
5710TEST_P(QuicStreamFactoryTest,
5711 MigrateSessionOnWriteErrorWithMultipleRequestsAsync) {
5712 TestMigrationOnWriteErrorWithMultipleRequests(ASYNC);
5713}
5714
5715// Sets up a test which verifies that connection migration on write error can
5716// eventually succeed and rewrite the packet on the new network with *multiple*
5717// migratable streams.
5718void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorWithMultipleRequests(
5719 IoMode write_error_mode) {
5720 InitializeConnectionMigrationV2Test(
5721 {kDefaultNetworkForTests, kNewNetworkForTests});
5722 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5723 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5724 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5725
Ryan Hamiltonabad59e2019-06-06 04:02:595726 MockQuicData socket_data(version_);
Zhongyi Shi0439ecc72018-07-11 04:41:265727 quic::QuicStreamOffset header_stream_offset = 0;
5728 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5729 socket_data.AddWrite(
5730 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
5731 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
5732 socket_data.AddSocketDataToFactory(socket_factory_.get());
5733
5734 // Set up second socket data provider that is used after
5735 // migration. The request is rewritten to this new socket, and the
5736 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:595737 MockQuicData socket_data1(version_);
Zhongyi Shi0439ecc72018-07-11 04:41:265738 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335739 SYNCHRONOUS, ConstructGetRequestPacket(
5740 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
5741 true, &header_stream_offset));
5742 socket_data1.AddRead(
5743 ASYNC,
5744 ConstructOkResponsePacket(
5745 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
5746 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5747 socket_data1.AddWrite(
5748 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
5749 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
5750 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
5751 socket_data1.AddWrite(
5752 SYNCHRONOUS, client_maker_.MakeRstPacket(
5753 4, false, GetNthClientInitiatedBidirectionalStreamId(1),
Frank Kastenholz684ea412019-02-13 18:48:185754 quic::QUIC_STREAM_CANCELLED, 0,
5755 /*include_stop_sending_if_v99=*/true));
Zhongyi Shi0439ecc72018-07-11 04:41:265756
5757 socket_data1.AddSocketDataToFactory(socket_factory_.get());
5758
5759 // Create request #1 and QuicHttpStream.
5760 QuicStreamRequest request1(factory_.get());
5761 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:035762 request1.Request(
Nick Harper23290b82019-05-02 00:02:565763 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:515764 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:035765 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5766 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi0439ecc72018-07-11 04:41:265767 EXPECT_THAT(callback_.WaitForResult(), IsOk());
5768 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
5769 EXPECT_TRUE(stream1.get());
5770
5771 HttpRequestInfo request_info1;
5772 request_info1.method = "GET";
5773 request_info1.url = GURL("https://www.example.org/");
5774 request_info1.traffic_annotation =
5775 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5776 EXPECT_EQ(OK,
5777 stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
5778 net_log_, CompletionOnceCallback()));
5779
5780 // Second request returns synchronously because it pools to existing session.
5781 TestCompletionCallback callback2;
5782 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:515783 EXPECT_EQ(OK,
5784 request2.Request(
5785 host_port_pair_, version_.transport_version, privacy_mode_,
5786 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
5787 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5788 failed_on_default_network_callback_, callback2.callback()));
Zhongyi Shi0439ecc72018-07-11 04:41:265789 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
5790 EXPECT_TRUE(stream2.get());
5791 HttpRequestInfo request_info2;
5792 request_info2.method = "GET";
5793 request_info2.url = GURL("https://www.example.org/");
5794 request_info2.traffic_annotation =
5795 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5796 EXPECT_EQ(OK,
5797 stream2->InitializeStream(&request_info2, true, DEFAULT_PRIORITY,
5798 net_log_, CompletionOnceCallback()));
5799
5800 // Ensure that session is alive and active.
5801 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
5802 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5803 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5804 EXPECT_EQ(2u, session->GetNumActiveStreams());
5805
5806 // Send GET request on stream. This should cause a write error, which triggers
5807 // a connection migration attempt.
5808 HttpResponseInfo response;
5809 HttpRequestHeaders request_headers;
5810 EXPECT_EQ(OK, stream1->SendRequest(request_headers, &response,
5811 callback_.callback()));
5812
5813 // Run the message loop so that the migration attempt is executed and
5814 // data queued in the new socket is read by the packet reader.
5815 base::RunLoop().RunUntilIdle();
5816
Zhongyi Shia7dd46b2018-07-12 22:59:295817 // Verify session is still alive and not marked as going away.
Zhongyi Shi0439ecc72018-07-11 04:41:265818 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:295819 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi0439ecc72018-07-11 04:41:265820 EXPECT_EQ(2u, session->GetNumActiveStreams());
5821
5822 // Verify that response headers on the migrated socket were delivered to the
5823 // stream.
5824 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
5825 EXPECT_EQ(200, response.headers->response_code());
5826
5827 stream1.reset();
5828 stream2.reset();
5829
5830 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5831 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5832 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
5833 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
5834}
5835
5836TEST_P(QuicStreamFactoryTest, MigrateOnWriteErrorWithMixedRequestsSync) {
5837 TestMigrationOnWriteErrorMixedStreams(SYNCHRONOUS);
5838}
5839
5840TEST_P(QuicStreamFactoryTest, MigrateOnWriteErrorWithMixedRequestsAsync) {
5841 TestMigrationOnWriteErrorMixedStreams(ASYNC);
5842}
5843
5844// Sets up a test that verifies connection migration manages to migrate to
5845// alternate network after encountering a SYNC/ASYNC write error based on
5846// |write_error_mode| on the original network.
5847// Note there are mixed types of unfinished requests before migration: one
5848// migratable and one non-migratable. The *migratable* one triggers write
5849// error.
5850void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorMixedStreams(
5851 IoMode write_error_mode) {
5852 InitializeConnectionMigrationV2Test(
5853 {kDefaultNetworkForTests, kNewNetworkForTests});
5854 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5855 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5856 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5857
5858 int packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:595859 MockQuicData socket_data(version_);
Zhongyi Shi0439ecc72018-07-11 04:41:265860 quic::QuicStreamOffset header_stream_offset = 0;
5861 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5862 socket_data.AddWrite(
5863 SYNCHRONOUS,
5864 ConstructInitialSettingsPacket(packet_number++, &header_stream_offset));
5865 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
5866 socket_data.AddSocketDataToFactory(socket_factory_.get());
5867
5868 // Set up second socket data provider that is used after
5869 // migration. The request is rewritten to this new socket, and the
5870 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:595871 MockQuicData socket_data1(version_);
Zhongyi Shi0439ecc72018-07-11 04:41:265872 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335873 SYNCHRONOUS,
5874 ConstructGetRequestPacket(packet_number++,
5875 GetNthClientInitiatedBidirectionalStreamId(0),
5876 true, true, &header_stream_offset));
Zhongyi Shi0439ecc72018-07-11 04:41:265877 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335878 SYNCHRONOUS,
5879 client_maker_.MakeRstPacket(packet_number++, true,
5880 GetNthClientInitiatedBidirectionalStreamId(1),
Frank Kastenholz684ea412019-02-13 18:48:185881 quic::QUIC_STREAM_CANCELLED, 0,
5882 /*include_stop_sending_if_v99=*/true));
Zhongyi Shi0439ecc72018-07-11 04:41:265883 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:335884 ASYNC,
5885 ConstructOkResponsePacket(
5886 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shi0439ecc72018-07-11 04:41:265887 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
5888 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:335889 SYNCHRONOUS,
5890 client_maker_.MakeAckAndRstPacket(
5891 packet_number++, false, GetNthClientInitiatedBidirectionalStreamId(0),
5892 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi0439ecc72018-07-11 04:41:265893 socket_data1.AddSocketDataToFactory(socket_factory_.get());
5894
5895 // Create request #1 and QuicHttpStream.
5896 QuicStreamRequest request1(factory_.get());
5897 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:035898 request1.Request(
Nick Harper23290b82019-05-02 00:02:565899 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:515900 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:035901 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5902 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi0439ecc72018-07-11 04:41:265903 EXPECT_THAT(callback_.WaitForResult(), IsOk());
5904 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
5905 EXPECT_TRUE(stream1.get());
5906
5907 HttpRequestInfo request_info1;
5908 request_info1.method = "GET";
5909 request_info1.url = GURL("https://www.example.org/");
5910 request_info1.traffic_annotation =
5911 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5912 EXPECT_EQ(OK,
5913 stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
5914 net_log_, CompletionOnceCallback()));
5915
5916 // Second request returns synchronously because it pools to existing session.
5917 TestCompletionCallback callback2;
5918 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:515919 EXPECT_EQ(OK,
5920 request2.Request(
5921 host_port_pair_, version_.transport_version, privacy_mode_,
5922 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
5923 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
5924 failed_on_default_network_callback_, callback2.callback()));
Zhongyi Shi0439ecc72018-07-11 04:41:265925 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
5926 EXPECT_TRUE(stream2.get());
5927
5928 HttpRequestInfo request_info2;
5929 request_info2.method = "GET";
Zhongyi Shibb28b1f2018-07-18 02:41:265930 request_info2.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
Zhongyi Shi0439ecc72018-07-11 04:41:265931 request_info2.url = GURL("https://www.example.org/");
5932 request_info2.traffic_annotation =
5933 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
5934 EXPECT_EQ(OK,
5935 stream2->InitializeStream(&request_info2, true, DEFAULT_PRIORITY,
5936 net_log_, CompletionOnceCallback()));
5937
5938 // Ensure that session is alive and active.
5939 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
5940 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
5941 EXPECT_TRUE(HasActiveSession(host_port_pair_));
5942 EXPECT_EQ(2u, session->GetNumActiveStreams());
5943
5944 // Send GET request on stream 1. This should cause a write error, which
5945 // triggers a connection migration attempt.
5946 HttpResponseInfo response;
5947 HttpRequestHeaders request_headers;
5948 EXPECT_EQ(OK, stream1->SendRequest(request_headers, &response,
5949 callback_.callback()));
5950
5951 // Run the message loop so that the migration attempt is executed and
5952 // data queued in the new socket is read by the packet reader.
5953 base::RunLoop().RunUntilIdle();
5954
Zhongyi Shia7dd46b2018-07-12 22:59:295955 // Verify that the session is still alive and not marked as going away.
5956 // Non-migratable stream should be closed due to migration.
Zhongyi Shi0439ecc72018-07-11 04:41:265957 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:295958 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi0439ecc72018-07-11 04:41:265959 EXPECT_EQ(1u, session->GetNumActiveStreams());
5960
5961 // Verify that response headers on the migrated socket were delivered to the
5962 // stream.
5963 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
5964 EXPECT_EQ(200, response.headers->response_code());
5965
5966 stream1.reset();
5967
5968 EXPECT_TRUE(socket_data.AllReadDataConsumed());
5969 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
5970 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
5971 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
5972}
5973
5974TEST_P(QuicStreamFactoryTest, MigrateOnWriteErrorWithMixedRequests2Sync) {
5975 TestMigrationOnWriteErrorMixedStreams2(SYNCHRONOUS);
5976}
5977
5978TEST_P(QuicStreamFactoryTest, MigrateOnWriteErrorWithMixedRequests2Async) {
5979 TestMigrationOnWriteErrorMixedStreams2(ASYNC);
5980}
5981
5982// The one triggers write error is a non-migratable stream.
5983// Sets up a test that verifies connection migration manages to migrate to
5984// alternate network after encountering a SYNC/ASYNC write error based on
5985// |write_error_mode| on the original network.
5986// Note there are mixed types of unfinished requests before migration: one
5987// migratable and one non-migratable. The *non-migratable* one triggers write
5988// error.
5989void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorMixedStreams2(
5990 IoMode write_error_mode) {
5991 InitializeConnectionMigrationV2Test(
5992 {kDefaultNetworkForTests, kNewNetworkForTests});
5993 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
5994 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5995 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
5996
5997 int packet_number = 1;
Ryan Hamiltonabad59e2019-06-06 04:02:595998 MockQuicData socket_data(version_);
Zhongyi Shi0439ecc72018-07-11 04:41:265999 quic::QuicStreamOffset header_stream_offset = 0;
6000 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6001 socket_data.AddWrite(
6002 SYNCHRONOUS,
6003 ConstructInitialSettingsPacket(packet_number++, &header_stream_offset));
6004 socket_data.AddWrite(write_error_mode,
6005 ERR_ADDRESS_UNREACHABLE); // Write error.
6006 socket_data.AddSocketDataToFactory(socket_factory_.get());
6007
6008 // Set up second socket data provider that is used after
6009 // migration. The request is rewritten to this new socket, and the
6010 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:596011 MockQuicData socket_data1(version_);
Zhongyi Shi0439ecc72018-07-11 04:41:266012 // The packet triggered writer error will be sent anyway even if the stream
6013 // will be cancelled later.
6014 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:336015 SYNCHRONOUS,
6016 ConstructGetRequestPacket(packet_number++,
6017 GetNthClientInitiatedBidirectionalStreamId(1),
6018 true, true, &header_stream_offset));
Zhongyi Shi0439ecc72018-07-11 04:41:266019 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:336020 SYNCHRONOUS,
6021 client_maker_.MakeRstPacket(packet_number++, true,
6022 GetNthClientInitiatedBidirectionalStreamId(1),
Frank Kastenholz684ea412019-02-13 18:48:186023 quic::QUIC_STREAM_CANCELLED, 0,
6024 /*include_stop_sending_if_v99=*/true));
Zhongyi Shi0439ecc72018-07-11 04:41:266025 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:336026 SYNCHRONOUS,
6027 ConstructGetRequestPacket(packet_number++,
6028 GetNthClientInitiatedBidirectionalStreamId(0),
6029 true, true, &header_stream_offset));
Zhongyi Shi0439ecc72018-07-11 04:41:266030 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:336031 ASYNC,
6032 ConstructOkResponsePacket(
6033 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shi0439ecc72018-07-11 04:41:266034 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6035 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:336036 SYNCHRONOUS,
6037 client_maker_.MakeAckAndRstPacket(
6038 packet_number++, false, GetNthClientInitiatedBidirectionalStreamId(0),
6039 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi0439ecc72018-07-11 04:41:266040 socket_data1.AddSocketDataToFactory(socket_factory_.get());
6041
6042 // Create request #1 and QuicHttpStream.
6043 QuicStreamRequest request1(factory_.get());
6044 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:036045 request1.Request(
Nick Harper23290b82019-05-02 00:02:566046 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:516047 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:036048 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6049 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi0439ecc72018-07-11 04:41:266050 EXPECT_THAT(callback_.WaitForResult(), IsOk());
6051 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
6052 EXPECT_TRUE(stream1.get());
6053
6054 HttpRequestInfo request_info1;
6055 request_info1.method = "GET";
6056 request_info1.url = GURL("https://www.example.org/");
6057 request_info1.traffic_annotation =
6058 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6059 EXPECT_EQ(OK,
6060 stream1->InitializeStream(&request_info1, true, DEFAULT_PRIORITY,
6061 net_log_, CompletionOnceCallback()));
6062
6063 // Second request returns synchronously because it pools to existing session.
6064 TestCompletionCallback callback2;
6065 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:516066 EXPECT_EQ(OK,
6067 request2.Request(
6068 host_port_pair_, version_.transport_version, privacy_mode_,
6069 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
6070 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6071 failed_on_default_network_callback_, callback2.callback()));
Zhongyi Shi0439ecc72018-07-11 04:41:266072 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
6073 EXPECT_TRUE(stream2.get());
6074
6075 HttpRequestInfo request_info2;
6076 request_info2.method = "GET";
Zhongyi Shibb28b1f2018-07-18 02:41:266077 request_info2.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
Zhongyi Shi0439ecc72018-07-11 04:41:266078 request_info2.url = GURL("https://www.example.org/");
6079 request_info2.traffic_annotation =
6080 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6081 EXPECT_EQ(OK,
6082 stream2->InitializeStream(&request_info2, true, DEFAULT_PRIORITY,
6083 net_log_, CompletionOnceCallback()));
6084
6085 // Ensure that session is alive and active.
6086 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6087 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6088 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6089 EXPECT_EQ(2u, session->GetNumActiveStreams());
6090
6091 // Send GET request on stream 2 which is non-migratable. This should cause a
6092 // write error, which triggers a connection migration attempt.
6093 HttpResponseInfo response2;
6094 HttpRequestHeaders request_headers2;
6095 EXPECT_EQ(OK, stream2->SendRequest(request_headers2, &response2,
6096 callback2.callback()));
6097
6098 // Run the message loop so that the migration attempt is executed and
Zhongyi Shia7dd46b2018-07-12 22:59:296099 // data queued in the new socket is read by the packet reader. Session is
6100 // still alive and not marked as going away, non-migratable stream will be
6101 // closed.
Zhongyi Shi0439ecc72018-07-11 04:41:266102 base::RunLoop().RunUntilIdle();
6103 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:296104 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi0439ecc72018-07-11 04:41:266105 EXPECT_EQ(1u, session->GetNumActiveStreams());
6106
6107 // Send GET request on stream 1.
6108 HttpResponseInfo response;
6109 HttpRequestHeaders request_headers;
6110 EXPECT_EQ(OK, stream1->SendRequest(request_headers, &response,
6111 callback_.callback()));
6112
6113 base::RunLoop().RunUntilIdle();
6114
6115 // Verify that response headers on the migrated socket were delivered to the
6116 // stream.
6117 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback()));
6118 EXPECT_EQ(200, response.headers->response_code());
6119
6120 stream1.reset();
6121
6122 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6123 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6124 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6125 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
6126}
6127
Zhongyi Shic16b4102019-02-12 00:37:406128// This test verifies that when a connection encounters a packet write error, it
6129// will cancel non-migratable streams, and migrate to the alternate network.
jri9f303712016-09-13 01:10:226130void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorNonMigratableStream(
Zhongyi Shi32fe14d42019-02-28 00:25:366131 IoMode write_error_mode,
6132 bool migrate_idle_sessions) {
Zhongyi Shic16b4102019-02-12 00:37:406133 DVLOG(1) << "Write error mode: "
jri9f303712016-09-13 01:10:226134 << ((write_error_mode == SYNCHRONOUS) ? "SYNCHRONOUS" : "ASYNC");
Zhongyi Shi32fe14d42019-02-28 00:25:366135 DVLOG(1) << "Migrate idle sessions: " << migrate_idle_sessions;
6136 test_params_.quic_migrate_idle_sessions = migrate_idle_sessions;
Zhongyi Shi1a054612018-06-14 04:59:086137 InitializeConnectionMigrationV2Test(
jri9f303712016-09-13 01:10:226138 {kDefaultNetworkForTests, kNewNetworkForTests});
6139 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6140 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6141
Ryan Hamiltonabad59e2019-06-06 04:02:596142 MockQuicData failed_socket_data(version_);
6143 MockQuicData socket_data(version_);
Zhongyi Shi32fe14d42019-02-28 00:25:366144 if (migrate_idle_sessions) {
6145 quic::QuicStreamOffset header_stream_offset = 0;
6146 // The socket data provider for the original socket before migration.
6147 failed_socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6148 failed_socket_data.AddWrite(
6149 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
6150 failed_socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
6151 failed_socket_data.AddSocketDataToFactory(socket_factory_.get());
6152
6153 // Set up second socket data provider that is used after migration.
6154 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
6155 // Although the write error occurs when writing a packet for the
6156 // non-migratable stream and the stream will be cancelled during migration,
6157 // the packet will still be retransimitted at the connection level.
6158 socket_data.AddWrite(
6159 SYNCHRONOUS, ConstructGetRequestPacket(
6160 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6161 true, &header_stream_offset));
6162 // A RESET will be sent to the peer to cancel the non-migratable stream.
6163 socket_data.AddWrite(
6164 SYNCHRONOUS, client_maker_.MakeRstPacket(
6165 3, true, GetNthClientInitiatedBidirectionalStreamId(0),
6166 quic::QUIC_STREAM_CANCELLED));
6167 socket_data.AddSocketDataToFactory(socket_factory_.get());
6168 } else {
6169 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6170 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
6171 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
6172 socket_data.AddSocketDataToFactory(socket_factory_.get());
6173 }
jri9f303712016-09-13 01:10:226174
6175 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:456176 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:336177 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:036178 request.Request(
Nick Harper23290b82019-05-02 00:02:566179 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:516180 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:036181 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6182 failed_on_default_network_callback_, callback_.callback()));
jri9f303712016-09-13 01:10:226183 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:246184 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9f303712016-09-13 01:10:226185 EXPECT_TRUE(stream.get());
6186
6187 // Cause QUIC stream to be created, but marked as non-migratable.
6188 HttpRequestInfo request_info;
Zhongyi Shibb28b1f2018-07-18 02:41:266189 request_info.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION_TO_CELLULAR;
jri9f303712016-09-13 01:10:226190 request_info.method = "GET";
6191 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:396192 request_info.traffic_annotation =
6193 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:276194 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:396195 net_log_, CompletionOnceCallback()));
jri9f303712016-09-13 01:10:226196
6197 // Ensure that session is alive and active.
6198 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6199 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6200 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6201
6202 // Send GET request on stream. This should cause a write error, which triggers
6203 // a connection migration attempt.
6204 HttpResponseInfo response;
6205 HttpRequestHeaders request_headers;
6206 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6207 callback_.callback()));
6208
6209 // Run message loop to execute migration attempt.
6210 base::RunLoop().RunUntilIdle();
6211
Zhongyi Shi32fe14d42019-02-28 00:25:366212 // Migration closes the non-migratable stream and:
6213 // if migrate idle session is enabled, it migrates to the alternate network
6214 // successfully; otherwise the connection is closed.
6215 EXPECT_EQ(migrate_idle_sessions,
6216 QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6217 EXPECT_EQ(migrate_idle_sessions, HasActiveSession(host_port_pair_));
jri9f303712016-09-13 01:10:226218
Zhongyi Shi32fe14d42019-02-28 00:25:366219 if (migrate_idle_sessions) {
6220 EXPECT_TRUE(failed_socket_data.AllReadDataConsumed());
6221 EXPECT_TRUE(failed_socket_data.AllWriteDataConsumed());
6222 }
jri9f303712016-09-13 01:10:226223 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6224 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6225}
6226
Zhongyi Shi32fe14d42019-02-28 00:25:366227TEST_P(
6228 QuicStreamFactoryTest,
6229 MigrateSessionOnWriteErrorNonMigratableStreamSync_DoNotMigrateIdleSessions) {
6230 TestMigrationOnWriteErrorNonMigratableStream(SYNCHRONOUS, false);
6231}
6232
6233TEST_P(
6234 QuicStreamFactoryTest,
6235 MigrateSessionOnWriteErrorNonMigratableStreamAsync_DoNotMigrateIdleSessions) {
6236 TestMigrationOnWriteErrorNonMigratableStream(ASYNC, false);
jri9f303712016-09-13 01:10:226237}
6238
6239TEST_P(QuicStreamFactoryTest,
Zhongyi Shi32fe14d42019-02-28 00:25:366240 MigrateSessionOnWriteErrorNonMigratableStreamSync_MigrateIdleSessions) {
6241 TestMigrationOnWriteErrorNonMigratableStream(SYNCHRONOUS, true);
6242}
6243
6244TEST_P(QuicStreamFactoryTest,
6245 MigrateSessionOnWriteErrorNonMigratableStreamAsync_MigrateIdleSessions) {
6246 TestMigrationOnWriteErrorNonMigratableStream(ASYNC, true);
jri9f303712016-09-13 01:10:226247}
6248
6249void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorMigrationDisabled(
6250 IoMode write_error_mode) {
Zhongyi Shi1a054612018-06-14 04:59:086251 InitializeConnectionMigrationV2Test(
jri9f303712016-09-13 01:10:226252 {kDefaultNetworkForTests, kNewNetworkForTests});
6253 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6254 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6255
Ryan Hamiltonabad59e2019-06-06 04:02:596256 MockQuicData socket_data(version_);
jri9f303712016-09-13 01:10:226257 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:436258 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
jri9f303712016-09-13 01:10:226259 socket_data.AddWrite(write_error_mode, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:176260 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:226261
6262 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:456263 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:336264 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:036265 request.Request(
Nick Harper23290b82019-05-02 00:02:566266 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:516267 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:036268 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6269 failed_on_default_network_callback_, callback_.callback()));
jri9f303712016-09-13 01:10:226270 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:246271 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9f303712016-09-13 01:10:226272 EXPECT_TRUE(stream.get());
6273
6274 // Cause QUIC stream to be created.
6275 HttpRequestInfo request_info;
6276 request_info.method = "GET";
6277 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:396278 request_info.traffic_annotation =
6279 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:276280 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:396281 net_log_, CompletionOnceCallback()));
jri9f303712016-09-13 01:10:226282
6283 // Ensure that session is alive and active.
6284 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6285 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6286 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6287
6288 // Set session config to have connection migration disabled.
Ryan Hamilton8d9ee76e2018-05-29 23:52:526289 quic::test::QuicConfigPeer::SetReceivedDisableConnectionMigration(
6290 session->config());
jri9f303712016-09-13 01:10:226291 EXPECT_TRUE(session->config()->DisableConnectionMigration());
6292
6293 // Send GET request on stream. This should cause a write error, which triggers
6294 // a connection migration attempt.
6295 HttpResponseInfo response;
6296 HttpRequestHeaders request_headers;
6297 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6298 callback_.callback()));
6299 // Run message loop to execute migration attempt.
6300 base::RunLoop().RunUntilIdle();
6301 // Migration fails, and session is closed and deleted.
6302 EXPECT_FALSE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6303 EXPECT_FALSE(HasActiveSession(host_port_pair_));
6304 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6305 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6306}
6307
6308TEST_P(QuicStreamFactoryTest,
6309 MigrateSessionOnWriteErrorMigrationDisabledSynchronous) {
6310 TestMigrationOnWriteErrorMigrationDisabled(SYNCHRONOUS);
6311}
6312
6313TEST_P(QuicStreamFactoryTest,
6314 MigrateSessionOnWriteErrorMigrationDisabledAsync) {
6315 TestMigrationOnWriteErrorMigrationDisabled(ASYNC);
6316}
6317
Zhongyi Shi7f1d9212018-06-22 23:24:366318// Sets up a test which verifies that connection migration on write error can
6319// eventually succeed and rewrite the packet on the new network with singals
6320// delivered in the following order (alternate network is always availabe):
6321// - original network encounters a SYNC/ASYNC write error based on
6322// |write_error_mode_on_old_network|, the packet failed to be written is
6323// cached, session migrates immediately to the alternate network.
6324// - an immediate SYNC/ASYNC write error based on
6325// |write_error_mode_on_new_network| is encountered after migration to the
6326// alternate network, session migrates immediately to the original network.
6327// - an immediate SYNC/ASYNC write error based on
6328// |write_error_mode_on_old_network| is encountered after migration to the
6329// original network, session migrates immediately to the alternate network.
6330// - finally, session successfully sends the packet and reads the response on
6331// the alternate network.
6332// TODO(zhongyi): once https://crbug.com/855666 is fixed, this test should be
6333// modified to test that session is closed early if hopping between networks
6334// with consecutive write errors is detected.
jri9f303712016-09-13 01:10:226335void QuicStreamFactoryTestBase::TestMigrationOnMultipleWriteErrors(
Zhongyi Shi7f1d9212018-06-22 23:24:366336 IoMode write_error_mode_on_old_network,
6337 IoMode write_error_mode_on_new_network) {
6338 InitializeConnectionMigrationV2Test(
jri9f303712016-09-13 01:10:226339 {kDefaultNetworkForTests, kNewNetworkForTests});
6340 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6341 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6342 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6343
Zhongyi Shi7f1d9212018-06-22 23:24:366344 // Set up the socket data used by the original network, which encounters a
6345 // write erorr.
Ryan Hamiltonabad59e2019-06-06 04:02:596346 MockQuicData socket_data1(version_);
Zhongyi Shi7f1d9212018-06-22 23:24:366347 quic::QuicStreamOffset header_stream_offset = 0;
6348 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6349 socket_data1.AddWrite(
6350 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
6351 socket_data1.AddWrite(write_error_mode_on_old_network,
6352 ERR_ADDRESS_UNREACHABLE); // Write Error
6353 socket_data1.AddSocketDataToFactory(socket_factory_.get());
6354
6355 // Set up the socket data used by the alternate network, which also
6356 // encounters a write error.
Ryan Hamiltonabad59e2019-06-06 04:02:596357 MockQuicData failed_quic_data2(version_);
Zhongyi Shi7f1d9212018-06-22 23:24:366358 failed_quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6359 failed_quic_data2.AddWrite(write_error_mode_on_new_network, ERR_FAILED);
6360 failed_quic_data2.AddSocketDataToFactory(socket_factory_.get());
6361
6362 // Set up the third socket data used by original network, which encounters a
6363 // write error again.
Ryan Hamiltonabad59e2019-06-06 04:02:596364 MockQuicData failed_quic_data1(version_);
Zhongyi Shi7f1d9212018-06-22 23:24:366365 failed_quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6366 failed_quic_data1.AddWrite(write_error_mode_on_old_network, ERR_FAILED);
6367 failed_quic_data1.AddSocketDataToFactory(socket_factory_.get());
6368
6369 // Set up the last socket data used by the alternate network, which will
6370 // finish migration successfully. The request is rewritten to this new socket,
6371 // and the response to the request is read on this socket.
Ryan Hamiltonabad59e2019-06-06 04:02:596372 MockQuicData socket_data2(version_);
Fan Yang32c5a112018-12-10 20:06:336373 socket_data2.AddWrite(
6374 SYNCHRONOUS, ConstructGetRequestPacket(
6375 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6376 true, &header_stream_offset));
Zhongyi Shi7f1d9212018-06-22 23:24:366377 socket_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:336378 ASYNC,
6379 ConstructOkResponsePacket(
6380 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shi7f1d9212018-06-22 23:24:366381 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:336382 socket_data2.AddWrite(
6383 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
6384 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
6385 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi7f1d9212018-06-22 23:24:366386 socket_data2.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:226387
6388 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:456389 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:336390 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:036391 request.Request(
Nick Harper23290b82019-05-02 00:02:566392 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:516393 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:036394 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6395 failed_on_default_network_callback_, callback_.callback()));
jri9f303712016-09-13 01:10:226396 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:246397 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri9f303712016-09-13 01:10:226398 EXPECT_TRUE(stream.get());
6399
6400 // Cause QUIC stream to be created.
6401 HttpRequestInfo request_info;
6402 request_info.method = "GET";
6403 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:396404 request_info.traffic_annotation =
6405 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:276406 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:396407 net_log_, CompletionOnceCallback()));
jri9f303712016-09-13 01:10:226408
6409 // Ensure that session is alive and active.
6410 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6411 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6412 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6413
Zhongyi Shi7f1d9212018-06-22 23:24:366414 // Send GET request on stream.
6415 // This should encounter a write error on network 1,
6416 // then migrate to network 2, which encounters another write error,
6417 // and migrate again to network 1, which encoutners one more write error.
6418 // Finally the session migrates to network 2 successfully.
jri9f303712016-09-13 01:10:226419 HttpResponseInfo response;
6420 HttpRequestHeaders request_headers;
6421 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6422 callback_.callback()));
jri9f303712016-09-13 01:10:226423
jri9f303712016-09-13 01:10:226424 base::RunLoop().RunUntilIdle();
Zhongyi Shi7f1d9212018-06-22 23:24:366425 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6426 EXPECT_EQ(1u, session->GetNumActiveStreams());
jri9f303712016-09-13 01:10:226427
Zhongyi Shi7f1d9212018-06-22 23:24:366428 // Verify that response headers on the migrated socket were delivered to the
6429 // stream.
6430 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
6431 EXPECT_EQ(200, response.headers->response_code());
jri9f303712016-09-13 01:10:226432
6433 stream.reset();
Zhongyi Shi7f1d9212018-06-22 23:24:366434 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6435 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
6436 EXPECT_TRUE(failed_quic_data2.AllReadDataConsumed());
6437 EXPECT_TRUE(failed_quic_data2.AllWriteDataConsumed());
6438 EXPECT_TRUE(failed_quic_data1.AllReadDataConsumed());
6439 EXPECT_TRUE(failed_quic_data1.AllWriteDataConsumed());
6440 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
6441 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
jri9f303712016-09-13 01:10:226442}
6443
6444TEST_P(QuicStreamFactoryTest, MigrateSessionOnMultipleWriteErrorsSyncSync) {
Zhongyi Shi7f1d9212018-06-22 23:24:366445 TestMigrationOnMultipleWriteErrors(
6446 /*write_error_mode_on_old_network*/ SYNCHRONOUS,
6447 /*write_error_mode_on_new_network*/ SYNCHRONOUS);
jri9f303712016-09-13 01:10:226448}
6449
6450TEST_P(QuicStreamFactoryTest, MigrateSessionOnMultipleWriteErrorsSyncAsync) {
Zhongyi Shi7f1d9212018-06-22 23:24:366451 TestMigrationOnMultipleWriteErrors(
6452 /*write_error_mode_on_old_network*/ SYNCHRONOUS,
6453 /*write_error_mode_on_new_network*/ ASYNC);
jri9f303712016-09-13 01:10:226454}
6455
6456TEST_P(QuicStreamFactoryTest, MigrateSessionOnMultipleWriteErrorsAsyncSync) {
Zhongyi Shi7f1d9212018-06-22 23:24:366457 TestMigrationOnMultipleWriteErrors(
6458 /*write_error_mode_on_old_network*/ ASYNC,
6459 /*write_error_mode_on_new_network*/ SYNCHRONOUS);
jri9f303712016-09-13 01:10:226460}
6461
6462TEST_P(QuicStreamFactoryTest, MigrateSessionOnMultipleWriteErrorsAsyncAsync) {
Zhongyi Shi7f1d9212018-06-22 23:24:366463 TestMigrationOnMultipleWriteErrors(
6464 /*write_error_mode_on_old_network*/ ASYNC,
6465 /*write_error_mode_on_new_network*/ ASYNC);
jri9f303712016-09-13 01:10:226466}
6467
Zhongyi Shi6abe33812018-07-24 19:43:116468// Verifies that a connection is closed when connection migration is triggered
6469// on network being disconnected and the handshake is not confirmed.
6470TEST_P(QuicStreamFactoryTest, NoMigrationBeforeHandshakeOnNetworkDisconnected) {
6471 InitializeConnectionMigrationV2Test(
6472 {kDefaultNetworkForTests, kNewNetworkForTests});
6473
Zhongyi Shi879659422018-08-02 17:58:256474 // Use cold start mode to do crypto connect, and send CHLO packet on wire.
Zhongyi Shi6abe33812018-07-24 19:43:116475 crypto_client_stream_factory_.set_handshake_mode(
Zhongyi Shi879659422018-08-02 17:58:256476 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
Zhongyi Shi6abe33812018-07-24 19:43:116477
Ryan Hamiltonabad59e2019-06-06 04:02:596478 MockQuicData socket_data(version_);
Zhongyi Shi879659422018-08-02 17:58:256479 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5068bb02018-08-03 02:44:096480 socket_data.AddWrite(ASYNC, client_maker_.MakeDummyCHLOPacket(1));
Zhongyi Shi6abe33812018-07-24 19:43:116481 socket_data.AddSocketDataToFactory(socket_factory_.get());
6482
6483 // Create request and QuicHttpStream.
6484 QuicStreamRequest request(factory_.get());
6485 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:036486 request.Request(
Nick Harper23290b82019-05-02 00:02:566487 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:516488 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:036489 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6490 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shi6abe33812018-07-24 19:43:116491 // Deliver the network notification, which should cause the connection to be
6492 // closed.
6493 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6494 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
6495 EXPECT_EQ(ERR_NETWORK_CHANGED, callback_.WaitForResult());
Zhongyi Shi4293b142018-07-25 00:33:576496
Zhongyi Shi6abe33812018-07-24 19:43:116497 EXPECT_FALSE(HasActiveSession(host_port_pair_));
6498 EXPECT_FALSE(HasActiveJob(host_port_pair_, privacy_mode_));
Zhongyi Shi4293b142018-07-25 00:33:576499 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6500 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
Zhongyi Shi6abe33812018-07-24 19:43:116501}
6502
Zhongyi Shib24001c02018-06-18 20:01:526503// Sets up the connection migration test where network change notification is
6504// queued BEFORE connection migration attempt on write error is posted.
6505void QuicStreamFactoryTestBase::
6506 TestMigrationOnNetworkNotificationWithWriteErrorQueuedLater(
6507 bool disconnected) {
6508 InitializeConnectionMigrationV2Test(
jried79618b2016-07-02 03:18:526509 {kDefaultNetworkForTests, kNewNetworkForTests});
6510 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6511 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6512 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6513
Ryan Hamiltonabad59e2019-06-06 04:02:596514 MockQuicData socket_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:526515 quic::QuicStreamOffset header_stream_offset = 0;
rcha00569732016-08-27 11:09:366516 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
rch5cb522462017-04-25 20:18:366517 socket_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436518 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
rcha00569732016-08-27 11:09:366519 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:176520 socket_data.AddSocketDataToFactory(socket_factory_.get());
jried79618b2016-07-02 03:18:526521
6522 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:456523 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:336524 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:036525 request.Request(
Nick Harper23290b82019-05-02 00:02:566526 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:516527 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:036528 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6529 failed_on_default_network_callback_, callback_.callback()));
jried79618b2016-07-02 03:18:526530 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:246531 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jried79618b2016-07-02 03:18:526532 EXPECT_TRUE(stream.get());
6533
6534 // Cause QUIC stream to be created.
6535 HttpRequestInfo request_info;
6536 request_info.method = "GET";
6537 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:396538 request_info.traffic_annotation =
6539 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:276540 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:396541 net_log_, CompletionOnceCallback()));
jried79618b2016-07-02 03:18:526542
6543 // Ensure that session is alive and active.
6544 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6545 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6546 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6547
6548 // Set up second socket data provider that is used after
6549 // migration. The request is rewritten to this new socket, and the
6550 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:596551 MockQuicData socket_data1(version_);
Fan Yang32c5a112018-12-10 20:06:336552 socket_data1.AddWrite(
6553 SYNCHRONOUS, ConstructGetRequestPacket(
6554 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6555 true, &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436556 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:336557 ASYNC,
6558 ConstructOkResponsePacket(
6559 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
rcha00569732016-08-27 11:09:366560 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:336561 socket_data1.AddWrite(
6562 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
6563 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
6564 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:176565 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jried79618b2016-07-02 03:18:526566
jri9f303712016-09-13 01:10:226567 // First queue a network change notification in the message loop.
6568 if (disconnected) {
6569 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6570 ->QueueNetworkDisconnected(kDefaultNetworkForTests);
6571 } else {
6572 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6573 ->QueueNetworkMadeDefault(kNewNetworkForTests);
6574 }
6575 // Send GET request on stream. This should cause a write error,
6576 // which triggers a connection migration attempt. This will queue a
6577 // migration attempt behind the notification in the message loop.
jried79618b2016-07-02 03:18:526578 HttpResponseInfo response;
6579 HttpRequestHeaders request_headers;
6580 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6581 callback_.callback()));
6582
jried79618b2016-07-02 03:18:526583 base::RunLoop().RunUntilIdle();
Zhongyi Shia7dd46b2018-07-12 22:59:296584 // Verify the session is still alive and not marked as going away post
6585 // migration.
jried79618b2016-07-02 03:18:526586 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:296587 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jried79618b2016-07-02 03:18:526588 EXPECT_EQ(1u, session->GetNumActiveStreams());
6589
6590 // Verify that response headers on the migrated socket were delivered to the
6591 // stream.
6592 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
6593 EXPECT_EQ(200, response.headers->response_code());
6594
6595 stream.reset();
6596
6597 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6598 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6599 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6600 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
6601}
6602
Zhongyi Shib24001c02018-06-18 20:01:526603// This test verifies that session attempts connection migration successfully
6604// with signals delivered in the following order (alternate network is always
6605// available):
6606// - a notification that default network is disconnected is queued.
6607// - write error is triggered: session posts a task to attempt connection
6608// migration, |migration_pending_| set to true.
6609// - default network disconnected is delivered: session immediately migrates to
6610// the alternate network, |migration_pending_| set to false.
Zhongyi Shif3d6cddb2018-07-11 03:30:026611// - connection migration on write error attempt aborts: writer encountered
6612// error is no longer in active use.
jri9f303712016-09-13 01:10:226613TEST_P(QuicStreamFactoryTest,
Zhongyi Shib24001c02018-06-18 20:01:526614 MigrateOnNetworkDisconnectedWithWriteErrorQueuedLater) {
6615 TestMigrationOnNetworkNotificationWithWriteErrorQueuedLater(
6616 /*disconnected=*/true);
jri9f303712016-09-13 01:10:226617}
6618
Zhongyi Shib24001c02018-06-18 20:01:526619// This test verifies that session attempts connection migration successfully
6620// with signals delivered in the following order (alternate network is always
6621// available):
6622// - a notification that alternate network is made default is queued.
6623// - write error is triggered: session posts a task to attempt connection
6624// migration, block future migrations.
6625// - new default notification is delivered: migrate back timer spins and task is
6626// posted to migrate to the new default network.
6627// - connection migration on write error attempt proceeds successfully: session
6628// is
6629// marked as going away, future migrations unblocked.
6630// - migrate back to default network task executed: session is already on the
6631// default network, no-op.
jri9f303712016-09-13 01:10:226632TEST_P(QuicStreamFactoryTest,
Zhongyi Shib24001c02018-06-18 20:01:526633 MigrateOnWriteErrorWithNetworkMadeDefaultQueuedEarlier) {
6634 TestMigrationOnNetworkNotificationWithWriteErrorQueuedLater(
6635 /*disconnected=*/false);
jri9f303712016-09-13 01:10:226636}
6637
Zhongyi Shi1e2bc742018-06-16 02:06:076638// Sets up the connection migration test where network change notification is
6639// queued AFTER connection migration attempt on write error is posted.
6640void QuicStreamFactoryTestBase::
6641 TestMigrationOnWriteErrorWithNotificationQueuedLater(bool disconnected) {
Zhongyi Shi1a054612018-06-14 04:59:086642 InitializeConnectionMigrationV2Test(
jri9f303712016-09-13 01:10:226643 {kDefaultNetworkForTests, kNewNetworkForTests});
jried79618b2016-07-02 03:18:526644 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6645 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri9f303712016-09-13 01:10:226646 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jried79618b2016-07-02 03:18:526647
Ryan Hamiltonabad59e2019-06-06 04:02:596648 MockQuicData socket_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:526649 quic::QuicStreamOffset header_stream_offset = 0;
rcha00569732016-08-27 11:09:366650 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
rch5cb522462017-04-25 20:18:366651 socket_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436652 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
rcha00569732016-08-27 11:09:366653 socket_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
Zhongyi Shi5f587cc2017-11-21 23:24:176654 socket_data.AddSocketDataToFactory(socket_factory_.get());
jried79618b2016-07-02 03:18:526655
6656 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:456657 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:336658 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:036659 request.Request(
Nick Harper23290b82019-05-02 00:02:566660 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:516661 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:036662 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6663 failed_on_default_network_callback_, callback_.callback()));
jried79618b2016-07-02 03:18:526664 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:246665 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jried79618b2016-07-02 03:18:526666 EXPECT_TRUE(stream.get());
6667
6668 // Cause QUIC stream to be created.
6669 HttpRequestInfo request_info;
6670 request_info.method = "GET";
6671 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:396672 request_info.traffic_annotation =
6673 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:276674 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:396675 net_log_, CompletionOnceCallback()));
jried79618b2016-07-02 03:18:526676
6677 // Ensure that session is alive and active.
6678 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6679 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6680 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6681
jri9f303712016-09-13 01:10:226682 // Set up second socket data provider that is used after
6683 // migration. The request is rewritten to this new socket, and the
6684 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:596685 MockQuicData socket_data1(version_);
Fan Yang32c5a112018-12-10 20:06:336686 socket_data1.AddWrite(
6687 SYNCHRONOUS, ConstructGetRequestPacket(
6688 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6689 true, &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436690 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:336691 ASYNC,
6692 ConstructOkResponsePacket(
6693 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
jri9f303712016-09-13 01:10:226694 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:336695 socket_data1.AddWrite(
6696 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
6697 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
6698 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:176699 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri9f303712016-09-13 01:10:226700
6701 // Send GET request on stream. This should cause a write error,
6702 // which triggers a connection migration attempt. This will queue a
6703 // migration attempt in the message loop.
jried79618b2016-07-02 03:18:526704 HttpResponseInfo response;
6705 HttpRequestHeaders request_headers;
jri9f303712016-09-13 01:10:226706 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6707 callback_.callback()));
jried79618b2016-07-02 03:18:526708
jri9f303712016-09-13 01:10:226709 // Now queue a network change notification in the message loop behind
6710 // the migration attempt.
6711 if (disconnected) {
6712 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6713 ->QueueNetworkDisconnected(kDefaultNetworkForTests);
6714 } else {
6715 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6716 ->QueueNetworkMadeDefault(kNewNetworkForTests);
6717 }
6718
6719 base::RunLoop().RunUntilIdle();
Zhongyi Shia7dd46b2018-07-12 22:59:296720 // Verify session is still alive and not marked as going away.
jri9f303712016-09-13 01:10:226721 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:296722 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri9f303712016-09-13 01:10:226723 EXPECT_EQ(1u, session->GetNumActiveStreams());
6724
6725 // Verify that response headers on the migrated socket were delivered to the
6726 // stream.
6727 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
6728 EXPECT_EQ(200, response.headers->response_code());
6729
6730 stream.reset();
jried79618b2016-07-02 03:18:526731
6732 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6733 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
jri9f303712016-09-13 01:10:226734 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6735 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
jried79618b2016-07-02 03:18:526736}
6737
Zhongyi Shi1e2bc742018-06-16 02:06:076738// This test verifies that session attempts connection migration successfully
6739// with signals delivered in the following order (alternate network is always
6740// available):
6741// - write error is triggered: session posts a task to complete connection
6742// migration.
6743// - a notification that alternate network is made default is queued.
6744// - connection migration attempt proceeds successfully, session is marked as
6745// going away.
6746// - new default notification is delivered after connection migration has been
6747// completed.
jri9f303712016-09-13 01:10:226748TEST_P(QuicStreamFactoryTest,
Zhongyi Shi1e2bc742018-06-16 02:06:076749 MigrateOnWriteErrorWithNetworkMadeDefaultQueuedLater) {
6750 TestMigrationOnWriteErrorWithNotificationQueuedLater(/*disconnected=*/false);
jried79618b2016-07-02 03:18:526751}
6752
Zhongyi Shi1e2bc742018-06-16 02:06:076753// This test verifies that session attempts connection migration successfully
6754// with signals delivered in the following order (alternate network is always
6755// available):
6756// - write error is triggered: session posts a task to complete connection
6757// migration.
6758// - a notification that default network is diconnected is queued.
6759// - connection migration attempt proceeds successfully, session is marked as
6760// going away.
6761// - disconnect notification is delivered after connection migration has been
6762// completed.
jri9f303712016-09-13 01:10:226763TEST_P(QuicStreamFactoryTest,
Zhongyi Shi1e2bc742018-06-16 02:06:076764 MigrateOnWriteErrorWithNetworkDisconnectedQueuedLater) {
6765 TestMigrationOnWriteErrorWithNotificationQueuedLater(/*disconnected=*/true);
jried79618b2016-07-02 03:18:526766}
6767
Zhongyi Shia3810c52018-06-15 23:07:196768// This tests connection migration on write error with signals delivered in the
6769// following order:
6770// - a synchronous/asynchronous write error is triggered base on
Zhongyi Shif3d6cddb2018-07-11 03:30:026771// |write_error_mode|: connection migration attempt is posted.
6772// - old default network disconnects, migration waits for a new network.
Zhongyi Shia3810c52018-06-15 23:07:196773// - after a pause, new network is connected: session will migrate to new
6774// network immediately.
Zhongyi Shif3d6cddb2018-07-11 03:30:026775// - migration on writer error is exectued and aborts as writer passed in is no
6776// longer active in use.
Zhongyi Shia3810c52018-06-15 23:07:196777// - new network is made default.
jri5b785512016-09-13 04:29:116778void QuicStreamFactoryTestBase::TestMigrationOnWriteErrorPauseBeforeConnected(
6779 IoMode write_error_mode) {
Zhongyi Shia3810c52018-06-15 23:07:196780 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jri5b785512016-09-13 04:29:116781 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6782 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6783 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6784
Zhongyi Shia3810c52018-06-15 23:07:196785 // Use the test task runner.
6786 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
6787
Ryan Hamiltonabad59e2019-06-06 04:02:596788 MockQuicData socket_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:526789 quic::QuicStreamOffset header_stream_offset = 0;
Zhongyi Shia3810c52018-06-15 23:07:196790 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
rch5cb522462017-04-25 20:18:366791 socket_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:436792 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Zhongyi Shia3810c52018-06-15 23:07:196793 socket_data.AddWrite(write_error_mode, ERR_FAILED);
Zhongyi Shi5f587cc2017-11-21 23:24:176794 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri5b785512016-09-13 04:29:116795
6796 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:456797 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:336798 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:036799 request.Request(
Nick Harper23290b82019-05-02 00:02:566800 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:516801 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:036802 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6803 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shia3810c52018-06-15 23:07:196804 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:246805 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri5b785512016-09-13 04:29:116806 EXPECT_TRUE(stream.get());
6807
6808 // Cause QUIC stream to be created.
6809 HttpRequestInfo request_info;
6810 request_info.method = "GET";
Zhongyi Shia3810c52018-06-15 23:07:196811 request_info.url = url_;
Ramin Halavati683bcaa92018-02-14 08:42:396812 request_info.traffic_annotation =
6813 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:276814 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:396815 net_log_, CompletionOnceCallback()));
jri5b785512016-09-13 04:29:116816
6817 // Ensure that session is alive and active.
6818 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6819 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6820 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6821
Zhongyi Shia3810c52018-06-15 23:07:196822 // Send GET request on stream.
jri5b785512016-09-13 04:29:116823 HttpResponseInfo response;
6824 HttpRequestHeaders request_headers;
6825 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6826 callback_.callback()));
6827
Zhongyi Shia3810c52018-06-15 23:07:196828 // The connection should still be alive, not marked as going away.
jri5b785512016-09-13 04:29:116829 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6830 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6831 EXPECT_EQ(1u, session->GetNumActiveStreams());
6832 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
6833
Zhongyi Shia3810c52018-06-15 23:07:196834 // Set up second socket data provider that is used after migration.
6835 // The response to the earlier request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:596836 MockQuicData socket_data1(version_);
Fan Yang32c5a112018-12-10 20:06:336837 socket_data1.AddWrite(
6838 SYNCHRONOUS, ConstructGetRequestPacket(
6839 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
6840 true, &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:436841 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:336842 ASYNC,
6843 ConstructOkResponsePacket(
6844 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
jri5b785512016-09-13 04:29:116845 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:336846 socket_data1.AddWrite(
6847 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
6848 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
6849 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:176850 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri5b785512016-09-13 04:29:116851
Zhongyi Shia3810c52018-06-15 23:07:196852 // On a DISCONNECTED notification, nothing happens.
6853 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6854 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
6855 // Add a new network and notify the stream factory of a new connected network.
6856 // This causes a PING packet to be sent over the new network.
jri5b785512016-09-13 04:29:116857 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6858 ->SetConnectedNetworksList({kNewNetworkForTests});
6859 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6860 ->NotifyNetworkConnected(kNewNetworkForTests);
6861
Zhongyi Shia3810c52018-06-15 23:07:196862 // Ensure that the session is still alive.
jri5b785512016-09-13 04:29:116863 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia3810c52018-06-15 23:07:196864 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri5b785512016-09-13 04:29:116865 EXPECT_EQ(1u, session->GetNumActiveStreams());
6866
Zhongyi Shia3810c52018-06-15 23:07:196867 // Run the message loop migration for write error can finish.
6868 runner_->RunUntilIdle();
6869
6870 // Response headers are received over the new network.
jri5b785512016-09-13 04:29:116871 EXPECT_THAT(callback_.WaitForResult(), IsOk());
6872 EXPECT_EQ(200, response.headers->response_code());
6873
Zhongyi Shia3810c52018-06-15 23:07:196874 // Check that the session is still alive.
6875 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
jri5b785512016-09-13 04:29:116876 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shia3810c52018-06-15 23:07:196877
6878 // There should be no posted tasks not executed, no way to migrate back to
6879 // default network.
6880 EXPECT_TRUE(runner_->GetPostedTasks().empty());
6881
6882 // Receive signal to mark new network as default.
6883 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6884 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
jri5b785512016-09-13 04:29:116885
6886 stream.reset();
jri5b785512016-09-13 04:29:116887 EXPECT_TRUE(socket_data.AllReadDataConsumed());
6888 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
6889 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
6890 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
jri5b785512016-09-13 04:29:116891}
6892
6893TEST_P(QuicStreamFactoryTest,
Zhongyi Shia3810c52018-06-15 23:07:196894 MigrateSessionOnSyncWriteErrorPauseBeforeConnected) {
jri5b785512016-09-13 04:29:116895 TestMigrationOnWriteErrorPauseBeforeConnected(SYNCHRONOUS);
6896}
6897
6898TEST_P(QuicStreamFactoryTest,
Zhongyi Shia3810c52018-06-15 23:07:196899 MigrateSessionOnAsyncWriteErrorPauseBeforeConnected) {
jri5b785512016-09-13 04:29:116900 TestMigrationOnWriteErrorPauseBeforeConnected(ASYNC);
6901}
6902
Zhongyi Shif3d6cddb2018-07-11 03:30:026903// This test verifies that when session successfully migrate to the alternate
6904// network, packet write error on the old writer will be ignored and will not
6905// trigger connection migration on write error.
6906TEST_P(QuicStreamFactoryTest, IgnoreWriteErrorFromOldWriterAfterMigration) {
6907 InitializeConnectionMigrationV2Test(
6908 {kDefaultNetworkForTests, kNewNetworkForTests});
6909 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
6910 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6911 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
6912
6913 // Using a testing task runner so that we can verify whether the migrate on
6914 // write error task is posted.
6915 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
6916 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
6917
Ryan Hamiltonabad59e2019-06-06 04:02:596918 MockQuicData socket_data(version_);
Zhongyi Shif3d6cddb2018-07-11 03:30:026919 quic::QuicStreamOffset header_stream_offset = 0;
6920 socket_data.AddWrite(
6921 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
6922 socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
6923 socket_data.AddWrite(ASYNC, ERR_ADDRESS_UNREACHABLE);
6924 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
6925 socket_data.AddSocketDataToFactory(socket_factory_.get());
6926
6927 // Create request and QuicHttpStream.
6928 QuicStreamRequest request(factory_.get());
6929 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:036930 request.Request(
Nick Harper23290b82019-05-02 00:02:566931 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:516932 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:036933 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
6934 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shif3d6cddb2018-07-11 03:30:026935 EXPECT_EQ(OK, callback_.WaitForResult());
6936 std::unique_ptr<HttpStream> stream = CreateStream(&request);
6937 EXPECT_TRUE(stream.get());
6938
6939 // Cause QUIC stream to be created.
6940 HttpRequestInfo request_info;
6941 request_info.method = "GET";
6942 request_info.url = GURL("https://www.example.org/");
6943 request_info.traffic_annotation =
6944 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
6945 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
6946 net_log_, CompletionOnceCallback()));
6947
6948 // Ensure that session is alive and active.
6949 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
6950 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6951 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6952
6953 // Set up second socket data provider that is used after
6954 // migration. The response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:596955 MockQuicData socket_data1(version_);
Zhongyi Shif3d6cddb2018-07-11 03:30:026956 socket_data1.AddWrite(
6957 SYNCHRONOUS, client_maker_.MakePingPacket(3, /*include_version=*/true));
6958 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:336959 ASYNC,
6960 ConstructOkResponsePacket(
6961 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shif3d6cddb2018-07-11 03:30:026962 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:336963 socket_data1.AddWrite(
6964 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
6965 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
6966 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shif3d6cddb2018-07-11 03:30:026967 socket_data1.AddSocketDataToFactory(socket_factory_.get());
6968
6969 // Send GET request on stream.
6970 HttpResponseInfo response;
6971 HttpRequestHeaders request_headers;
6972 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
6973 callback_.callback()));
6974
6975 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
6976 // Now notify network is disconnected, cause the migration to complete
6977 // immediately.
6978 scoped_mock_network_change_notifier_->mock_network_change_notifier()
6979 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
6980 // There will be two pending task, one will complete migration with no delay
6981 // and the other will attempt to migrate back to the default network with
6982 // delay.
6983 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
6984
6985 // Complete migration.
6986 task_runner->RunUntilIdle();
6987 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
6988
6989 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
6990 EXPECT_TRUE(HasActiveSession(host_port_pair_));
6991 EXPECT_EQ(1u, session->GetNumActiveStreams());
6992
6993 // Verify that response headers on the migrated socket were delivered to the
6994 // stream.
6995 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
6996 EXPECT_EQ(200, response.headers->response_code());
6997
6998 // Resume the old socket data, a write error will be delivered to the old
6999 // packet writer. Verify no additional task is posted.
7000 socket_data.Resume();
7001 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
7002
7003 stream.reset();
7004 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
7005 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
7006 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
7007}
7008
7009// This test verifies that when session successfully migrate to the alternate
7010// network, packet read error on the old reader will be ignored and will not
7011// close the connection.
7012TEST_P(QuicStreamFactoryTest, IgnoreReadErrorFromOldReaderAfterMigration) {
7013 InitializeConnectionMigrationV2Test(
7014 {kDefaultNetworkForTests, kNewNetworkForTests});
7015 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7016 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7017 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7018
7019 // Using a testing task runner.
7020 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
7021 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
7022
Ryan Hamiltonabad59e2019-06-06 04:02:597023 MockQuicData socket_data(version_);
Zhongyi Shif3d6cddb2018-07-11 03:30:027024 quic::QuicStreamOffset header_stream_offset = 0;
7025 socket_data.AddWrite(
7026 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
7027 socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
7028 socket_data.AddRead(ASYNC, ERR_ADDRESS_UNREACHABLE);
7029 socket_data.AddSocketDataToFactory(socket_factory_.get());
7030
7031 // Create request and QuicHttpStream.
7032 QuicStreamRequest request(factory_.get());
7033 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:037034 request.Request(
Nick Harper23290b82019-05-02 00:02:567035 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:517036 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:037037 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
7038 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shif3d6cddb2018-07-11 03:30:027039 EXPECT_EQ(OK, callback_.WaitForResult());
7040 std::unique_ptr<HttpStream> stream = CreateStream(&request);
7041 EXPECT_TRUE(stream.get());
7042
7043 // Cause QUIC stream to be created.
7044 HttpRequestInfo request_info;
7045 request_info.method = "GET";
7046 request_info.url = GURL("https://www.example.org/");
7047 request_info.traffic_annotation =
7048 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7049 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
7050 net_log_, CompletionOnceCallback()));
7051
7052 // Ensure that session is alive and active.
7053 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
7054 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7055 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7056
7057 // Set up second socket data provider that is used after
7058 // migration. The request is written to this new socket, and the
7059 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:597060 MockQuicData socket_data1(version_);
Zhongyi Shif3d6cddb2018-07-11 03:30:027061 socket_data1.AddWrite(
7062 SYNCHRONOUS, client_maker_.MakePingPacket(2, /*include_version=*/true));
Fan Yang32c5a112018-12-10 20:06:337063 socket_data1.AddWrite(
7064 SYNCHRONOUS, ConstructGetRequestPacket(
7065 3, GetNthClientInitiatedBidirectionalStreamId(0), true,
7066 true, &header_stream_offset));
Zhongyi Shif3d6cddb2018-07-11 03:30:027067 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337068 ASYNC,
7069 ConstructOkResponsePacket(
7070 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shif3d6cddb2018-07-11 03:30:027071 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:337072 socket_data1.AddWrite(
7073 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
7074 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
7075 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shif3d6cddb2018-07-11 03:30:027076 socket_data1.AddSocketDataToFactory(socket_factory_.get());
7077
7078 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
7079 // Now notify network is disconnected, cause the migration to complete
7080 // immediately.
7081 scoped_mock_network_change_notifier_->mock_network_change_notifier()
7082 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
7083 // There will be two pending task, one will complete migration with no delay
7084 // and the other will attempt to migrate back to the default network with
7085 // delay.
7086 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
7087
7088 // Complete migration.
7089 task_runner->RunUntilIdle();
7090 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
7091
7092 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7093 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7094 EXPECT_EQ(1u, session->GetNumActiveStreams());
7095
7096 // Send GET request on stream.
7097 HttpResponseInfo response;
7098 HttpRequestHeaders request_headers;
7099 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
7100 callback_.callback()));
7101
7102 // Verify that response headers on the migrated socket were delivered to the
7103 // stream.
7104 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
7105 EXPECT_EQ(OK, callback_.WaitForResult());
7106 EXPECT_EQ(200, response.headers->response_code());
7107
7108 // Resume the old socket data, a read error will be delivered to the old
7109 // packet reader. Verify that the session is not affected.
7110 socket_data.Resume();
7111 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
7112 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7113 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7114 EXPECT_EQ(1u, session->GetNumActiveStreams());
7115
7116 stream.reset();
7117 EXPECT_TRUE(socket_data.AllReadDataConsumed());
7118 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
7119 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
7120 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
7121}
7122
7123// This test verifies that after migration on network is executed, packet
7124// read error on the old reader will be ignored and will not close the
7125// connection.
7126TEST_P(QuicStreamFactoryTest, IgnoreReadErrorOnOldReaderDuringMigration) {
7127 InitializeConnectionMigrationV2Test(
7128 {kDefaultNetworkForTests, kNewNetworkForTests});
7129 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7130 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7131 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7132
7133 // Using a testing task runner.
7134 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
7135 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
7136
Ryan Hamiltonabad59e2019-06-06 04:02:597137 MockQuicData socket_data(version_);
Zhongyi Shif3d6cddb2018-07-11 03:30:027138 quic::QuicStreamOffset header_stream_offset = 0;
7139 socket_data.AddWrite(
7140 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
7141 socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
7142 socket_data.AddRead(ASYNC, ERR_ADDRESS_UNREACHABLE);
7143 socket_data.AddSocketDataToFactory(socket_factory_.get());
7144
7145 // Create request and QuicHttpStream.
7146 QuicStreamRequest request(factory_.get());
7147 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:037148 request.Request(
Nick Harper23290b82019-05-02 00:02:567149 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:517150 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:037151 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
7152 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shif3d6cddb2018-07-11 03:30:027153 EXPECT_EQ(OK, callback_.WaitForResult());
7154 std::unique_ptr<HttpStream> stream = CreateStream(&request);
7155 EXPECT_TRUE(stream.get());
7156
7157 // Cause QUIC stream to be created.
7158 HttpRequestInfo request_info;
7159 request_info.method = "GET";
7160 request_info.url = GURL("https://www.example.org/");
7161 request_info.traffic_annotation =
7162 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7163 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
7164 net_log_, CompletionOnceCallback()));
7165
7166 // Ensure that session is alive and active.
7167 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
7168 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7169 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7170
7171 // Set up second socket data provider that is used after
7172 // migration. The request is written to this new socket, and the
7173 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:597174 MockQuicData socket_data1(version_);
Zhongyi Shif3d6cddb2018-07-11 03:30:027175 socket_data1.AddWrite(
7176 SYNCHRONOUS, client_maker_.MakePingPacket(2, /*include_version=*/true));
Fan Yang32c5a112018-12-10 20:06:337177 socket_data1.AddWrite(
7178 SYNCHRONOUS, ConstructGetRequestPacket(
7179 3, GetNthClientInitiatedBidirectionalStreamId(0), true,
7180 true, &header_stream_offset));
Zhongyi Shif3d6cddb2018-07-11 03:30:027181 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:337182 ASYNC,
7183 ConstructOkResponsePacket(
7184 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shif3d6cddb2018-07-11 03:30:027185 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:337186 socket_data1.AddWrite(
7187 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
7188 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
7189 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shif3d6cddb2018-07-11 03:30:027190 socket_data1.AddSocketDataToFactory(socket_factory_.get());
7191
7192 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
7193 // Now notify network is disconnected, cause the migration to complete
7194 // immediately.
7195 scoped_mock_network_change_notifier_->mock_network_change_notifier()
7196 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
7197 // There will be two pending task, one will complete migration with no delay
7198 // and the other will attempt to migrate back to the default network with
7199 // delay.
7200 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
7201
7202 // Resume the old socket data, a read error will be delivered to the old
7203 // packet reader. Verify that the session is not affected.
7204 socket_data.Resume();
7205 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
7206 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7207 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7208 EXPECT_EQ(1u, session->GetNumActiveStreams());
7209
7210 // Complete migration.
7211 task_runner->RunUntilIdle();
7212 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
7213
7214 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7215 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7216 EXPECT_EQ(1u, session->GetNumActiveStreams());
7217
7218 // Send GET request on stream.
7219 HttpResponseInfo response;
7220 HttpRequestHeaders request_headers;
7221 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
7222 callback_.callback()));
7223
7224 // Verify that response headers on the migrated socket were delivered to the
7225 // stream.
7226 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
7227 EXPECT_EQ(OK, callback_.WaitForResult());
7228 EXPECT_EQ(200, response.headers->response_code());
7229
7230 stream.reset();
Zhongyi Shi99d0cdd2019-05-21 01:18:427231 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
7232 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
7233 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
7234}
7235
7236// This test verifies that when connection migration on path degrading is
7237// enabled, and no custom retransmittable on wire timeout is specified, the
7238// default value is used.
7239TEST_P(QuicStreamFactoryTest, DefaultRetransmittableOnWireTimeoutForMigration) {
7240 InitializeConnectionMigrationV2Test(
7241 {kDefaultNetworkForTests, kNewNetworkForTests});
7242 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7243 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7244 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7245
7246 // Using a testing task runner.
7247 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
7248 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
7249 QuicStreamFactoryPeer::SetAlarmFactory(
7250 factory_.get(),
7251 std::make_unique<QuicChromiumAlarmFactory>(task_runner.get(), &clock_));
7252
Ryan Hamiltonabad59e2019-06-06 04:02:597253 MockQuicData socket_data(version_);
Zhongyi Shi99d0cdd2019-05-21 01:18:427254 quic::QuicStreamOffset header_stream_offset = 0;
7255 socket_data.AddWrite(
7256 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
7257 socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
7258 socket_data.AddRead(ASYNC, ERR_ADDRESS_UNREACHABLE);
7259 socket_data.AddSocketDataToFactory(socket_factory_.get());
7260
7261 // Set up second socket data provider that is used after
7262 // migration. The request is written to this new socket, and the
7263 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:597264 MockQuicData socket_data1(version_);
Zhongyi Shi99d0cdd2019-05-21 01:18:427265 // The PING packet sent post migration.
7266 socket_data1.AddWrite(SYNCHRONOUS, client_maker_.MakePingPacket(2, true));
7267 socket_data1.AddWrite(
7268 SYNCHRONOUS, ConstructGetRequestPacket(
7269 3, GetNthClientInitiatedBidirectionalStreamId(0), true,
7270 true, &header_stream_offset));
7271 socket_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
7272 // Read two packets so that client will send ACK immedaitely.
7273 spdy::SpdyHeaderBlock response_headers =
7274 server_maker_.GetResponseHeaders("200 OK");
7275 response_headers["key1"] = std::string(2000, 'A');
7276 spdy::SpdyHeadersIR headers_frame(
7277 GetNthClientInitiatedBidirectionalStreamId(0),
7278 std::move(response_headers));
7279 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
7280 spdy::SpdySerializedFrame spdy_frame =
7281 response_framer.SerializeFrame(headers_frame);
7282 size_t chunk_size = 1200;
7283 unsigned int packet_number = 1;
7284 for (size_t offset = 0; offset < spdy_frame.size(); offset += chunk_size) {
7285 size_t len = std::min(chunk_size, spdy_frame.size() - offset);
7286 socket_data1.AddRead(
7287 ASYNC,
7288 server_maker_.MakeDataPacket(
7289 packet_number++,
7290 quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
7291 false, false, offset,
7292 base::StringPiece(spdy_frame.data() + offset, len)));
7293 }
7294 // Read an ACK from server which acks all client data.
7295 socket_data1.AddRead(SYNCHRONOUS,
7296 server_maker_.MakeAckPacket(3, 3, 1, 1, false));
7297 socket_data1.AddWrite(ASYNC, client_maker_.MakeAckPacket(4, 2, 1, 1, false));
7298 // The PING packet sent for retransmittable on wire.
7299 socket_data1.AddWrite(SYNCHRONOUS, client_maker_.MakePingPacket(5, false));
7300 socket_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
7301 std::string header = ConstructDataHeader(6);
7302 socket_data1.AddRead(
7303 ASYNC, ConstructServerDataPacket(
7304 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
7305 0, header + "hello!"));
7306 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read.
7307 socket_data1.AddWrite(
7308 SYNCHRONOUS, client_maker_.MakeRstPacket(
7309 6, false, GetNthClientInitiatedBidirectionalStreamId(0),
7310 quic::QUIC_STREAM_CANCELLED));
7311 socket_data1.AddSocketDataToFactory(socket_factory_.get());
7312
7313 // Create request and QuicHttpStream.
7314 QuicStreamRequest request(factory_.get());
7315 EXPECT_EQ(ERR_IO_PENDING,
7316 request.Request(
7317 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:517318 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shi99d0cdd2019-05-21 01:18:427319 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
7320 failed_on_default_network_callback_, callback_.callback()));
7321 EXPECT_EQ(OK, callback_.WaitForResult());
7322 std::unique_ptr<HttpStream> stream = CreateStream(&request);
7323 EXPECT_TRUE(stream.get());
7324
7325 // Cause QUIC stream to be created.
7326 HttpRequestInfo request_info;
7327 request_info.method = "GET";
7328 request_info.url = GURL("https://www.example.org/");
7329 request_info.traffic_annotation =
7330 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7331 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
7332 net_log_, CompletionOnceCallback()));
7333
7334 // Ensure that session is alive and active.
7335 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
7336 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7337
7338 // Now notify network is disconnected, cause the migration to complete
7339 // immediately.
7340 scoped_mock_network_change_notifier_->mock_network_change_notifier()
7341 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
7342
7343 // Complete migration.
7344 task_runner->RunUntilIdle();
7345 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7346 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7347 EXPECT_EQ(1u, session->GetNumActiveStreams());
7348
7349 // Send GET request on stream.
7350 HttpResponseInfo response;
7351 HttpRequestHeaders request_headers;
7352 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
7353 callback_.callback()));
7354 socket_data1.Resume();
7355 // Spin up the message loop to read incoming data from server till the ACK.
7356 base::RunLoop().RunUntilIdle();
7357
7358 // Ack delay time.
7359 int delay = task_runner->NextPendingTaskDelay().InMilliseconds();
7360 EXPECT_GT(kDefaultRetransmittableOnWireTimeoutMillisecs, delay);
7361 // Fire the ack alarm, since ack has been sent, no ack will be sent.
7362 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(delay));
7363 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7364
7365 // Fire the ping alarm with retransmittable-on-wire timeout, send PING.
7366 delay = kDefaultRetransmittableOnWireTimeoutMillisecs - delay;
7367 EXPECT_EQ(base::TimeDelta::FromMilliseconds(delay),
7368 task_runner->NextPendingTaskDelay());
7369 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(delay));
7370 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7371
7372 socket_data1.Resume();
7373
7374 // Verify that response headers on the migrated socket were delivered to the
7375 // stream.
7376 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
7377 EXPECT_EQ(200, response.headers->response_code());
7378
7379 // Resume the old socket data, a read error will be delivered to the old
7380 // packet reader. Verify that the session is not affected.
7381 socket_data.Resume();
7382 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7383 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7384 EXPECT_EQ(1u, session->GetNumActiveStreams());
7385
7386 stream.reset();
Zhongyi Shif3d6cddb2018-07-11 03:30:027387 EXPECT_TRUE(socket_data.AllReadDataConsumed());
7388 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
7389 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
7390 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
7391}
7392
Zhongyi Shi99d0cdd2019-05-21 01:18:427393// This test verifies that when connection migration on path degrading is
7394// enabled, and a custom retransmittable on wire timeout is specified, the
7395// custom value is used.
7396TEST_P(QuicStreamFactoryTest, CustomRetransmittableOnWireTimeoutForMigration) {
7397 int custom_timeout_value = 200;
7398 test_params_.quic_retransmittable_on_wire_timeout_milliseconds =
7399 custom_timeout_value;
7400 InitializeConnectionMigrationV2Test(
7401 {kDefaultNetworkForTests, kNewNetworkForTests});
7402 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7403 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7404 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7405
7406 // Using a testing task runner.
7407 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
7408 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
7409 QuicStreamFactoryPeer::SetAlarmFactory(
7410 factory_.get(),
7411 std::make_unique<QuicChromiumAlarmFactory>(task_runner.get(), &clock_));
7412
Ryan Hamiltonabad59e2019-06-06 04:02:597413 MockQuicData socket_data(version_);
Zhongyi Shi99d0cdd2019-05-21 01:18:427414 quic::QuicStreamOffset header_stream_offset = 0;
7415 socket_data.AddWrite(
7416 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
7417 socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
7418 socket_data.AddRead(ASYNC, ERR_ADDRESS_UNREACHABLE);
7419 socket_data.AddSocketDataToFactory(socket_factory_.get());
7420
7421 // Set up second socket data provider that is used after
7422 // migration. The request is written to this new socket, and the
7423 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:597424 MockQuicData socket_data1(version_);
Zhongyi Shi99d0cdd2019-05-21 01:18:427425 // The PING packet sent post migration.
7426 socket_data1.AddWrite(SYNCHRONOUS, client_maker_.MakePingPacket(2, true));
7427 socket_data1.AddWrite(
7428 SYNCHRONOUS, ConstructGetRequestPacket(
7429 3, GetNthClientInitiatedBidirectionalStreamId(0), true,
7430 true, &header_stream_offset));
7431 socket_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
7432 // Read two packets so that client will send ACK immedaitely.
7433 spdy::SpdyHeaderBlock response_headers =
7434 server_maker_.GetResponseHeaders("200 OK");
7435 response_headers["key1"] = std::string(2000, 'A');
7436 spdy::SpdyHeadersIR headers_frame(
7437 GetNthClientInitiatedBidirectionalStreamId(0),
7438 std::move(response_headers));
7439 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
7440 spdy::SpdySerializedFrame spdy_frame =
7441 response_framer.SerializeFrame(headers_frame);
7442 size_t chunk_size = 1200;
7443 unsigned int packet_number = 1;
7444 for (size_t offset = 0; offset < spdy_frame.size(); offset += chunk_size) {
7445 size_t len = std::min(chunk_size, spdy_frame.size() - offset);
7446 socket_data1.AddRead(
7447 ASYNC,
7448 server_maker_.MakeDataPacket(
7449 packet_number++,
7450 quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
7451 false, false, offset,
7452 base::StringPiece(spdy_frame.data() + offset, len)));
7453 }
7454 // Read an ACK from server which acks all client data.
7455 socket_data1.AddRead(SYNCHRONOUS,
7456 server_maker_.MakeAckPacket(3, 3, 1, 1, false));
7457 socket_data1.AddWrite(ASYNC, client_maker_.MakeAckPacket(4, 2, 1, 1, false));
7458 // The PING packet sent for retransmittable on wire.
7459 socket_data1.AddWrite(SYNCHRONOUS, client_maker_.MakePingPacket(5, false));
7460 socket_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
7461 std::string header = ConstructDataHeader(6);
7462 socket_data1.AddRead(
7463 ASYNC, ConstructServerDataPacket(
7464 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
7465 0, header + "hello!"));
7466 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read.
7467 socket_data1.AddWrite(
7468 SYNCHRONOUS, client_maker_.MakeRstPacket(
7469 6, false, GetNthClientInitiatedBidirectionalStreamId(0),
7470 quic::QUIC_STREAM_CANCELLED));
7471 socket_data1.AddSocketDataToFactory(socket_factory_.get());
7472
7473 // Create request and QuicHttpStream.
7474 QuicStreamRequest request(factory_.get());
7475 EXPECT_EQ(ERR_IO_PENDING,
7476 request.Request(
7477 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:517478 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shi99d0cdd2019-05-21 01:18:427479 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
7480 failed_on_default_network_callback_, callback_.callback()));
7481 EXPECT_EQ(OK, callback_.WaitForResult());
7482 std::unique_ptr<HttpStream> stream = CreateStream(&request);
7483 EXPECT_TRUE(stream.get());
7484
7485 // Cause QUIC stream to be created.
7486 HttpRequestInfo request_info;
7487 request_info.method = "GET";
7488 request_info.url = GURL("https://www.example.org/");
7489 request_info.traffic_annotation =
7490 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7491 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
7492 net_log_, CompletionOnceCallback()));
7493
7494 // Ensure that session is alive and active.
7495 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
7496 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7497
7498 // Now notify network is disconnected, cause the migration to complete
7499 // immediately.
7500 scoped_mock_network_change_notifier_->mock_network_change_notifier()
7501 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
7502
7503 // Complete migration.
7504 task_runner->RunUntilIdle();
7505 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7506 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7507 EXPECT_EQ(1u, session->GetNumActiveStreams());
7508
7509 // Send GET request on stream.
7510 HttpResponseInfo response;
7511 HttpRequestHeaders request_headers;
7512 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
7513 callback_.callback()));
7514 socket_data1.Resume();
7515 // Spin up the message loop to read incoming data from server till the ACK.
7516 base::RunLoop().RunUntilIdle();
7517
7518 // Ack delay time.
7519 int delay = task_runner->NextPendingTaskDelay().InMilliseconds();
7520 EXPECT_GT(custom_timeout_value, delay);
7521 // Fire the ack alarm, since ack has been sent, no ack will be sent.
7522 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(delay));
7523 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7524
7525 // Fire the ping alarm with retransmittable-on-wire timeout, send PING.
7526 delay = custom_timeout_value - delay;
7527 EXPECT_EQ(base::TimeDelta::FromMilliseconds(delay),
7528 task_runner->NextPendingTaskDelay());
7529 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(delay));
7530 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7531
7532 socket_data1.Resume();
7533
7534 // Verify that response headers on the migrated socket were delivered to the
7535 // stream.
7536 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
7537 EXPECT_EQ(200, response.headers->response_code());
7538
7539 // Resume the old socket data, a read error will be delivered to the old
7540 // packet reader. Verify that the session is not affected.
7541 socket_data.Resume();
7542 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7543 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7544 EXPECT_EQ(1u, session->GetNumActiveStreams());
7545
7546 stream.reset();
7547 EXPECT_TRUE(socket_data.AllReadDataConsumed());
7548 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
7549 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
7550 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
7551}
7552
7553// This test verifies that when no migration is enabled, but a custom value for
7554// retransmittable-on-wire timeout is specified, the ping alarm is set up to
7555// send retransmittable pings with the custom value.
7556TEST_P(QuicStreamFactoryTest, CustomRetransmittableOnWireTimeout) {
7557 int custom_timeout_value = 200;
7558 test_params_.quic_retransmittable_on_wire_timeout_milliseconds =
7559 custom_timeout_value;
7560 Initialize();
7561 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7562 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7563 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7564
7565 // Using a testing task runner.
7566 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
7567 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
7568 QuicStreamFactoryPeer::SetAlarmFactory(
7569 factory_.get(),
7570 std::make_unique<QuicChromiumAlarmFactory>(task_runner.get(), &clock_));
7571
Ryan Hamiltonabad59e2019-06-06 04:02:597572 MockQuicData socket_data1(version_);
Zhongyi Shi99d0cdd2019-05-21 01:18:427573 quic::QuicStreamOffset header_stream_offset = 0;
7574 socket_data1.AddWrite(
7575 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
7576 socket_data1.AddWrite(
7577 SYNCHRONOUS, ConstructGetRequestPacket(
7578 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7579 true, &header_stream_offset));
7580 socket_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
7581 // Read two packets so that client will send ACK immedaitely.
7582 spdy::SpdyHeaderBlock response_headers =
7583 server_maker_.GetResponseHeaders("200 OK");
7584 response_headers["key1"] = std::string(2000, 'A');
7585 spdy::SpdyHeadersIR headers_frame(
7586 GetNthClientInitiatedBidirectionalStreamId(0),
7587 std::move(response_headers));
7588 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
7589 spdy::SpdySerializedFrame spdy_frame =
7590 response_framer.SerializeFrame(headers_frame);
7591 size_t chunk_size = 1200;
7592 unsigned int packet_number = 1;
7593 for (size_t offset = 0; offset < spdy_frame.size(); offset += chunk_size) {
7594 size_t len = std::min(chunk_size, spdy_frame.size() - offset);
7595 socket_data1.AddRead(
7596 ASYNC,
7597 server_maker_.MakeDataPacket(
7598 packet_number++,
7599 quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
7600 false, false, offset,
7601 base::StringPiece(spdy_frame.data() + offset, len)));
7602 }
7603 // Read an ACK from server which acks all client data.
7604 socket_data1.AddRead(SYNCHRONOUS,
7605 server_maker_.MakeAckPacket(3, 2, 1, 1, false));
7606 socket_data1.AddWrite(ASYNC, client_maker_.MakeAckPacket(3, 2, 1, 1, false));
7607 // The PING packet sent for retransmittable on wire.
7608 socket_data1.AddWrite(SYNCHRONOUS, client_maker_.MakePingPacket(4, false));
7609 socket_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
7610 std::string header = ConstructDataHeader(6);
7611 socket_data1.AddRead(
7612 ASYNC, ConstructServerDataPacket(
7613 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
7614 0, header + "hello!"));
7615 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read.
7616 socket_data1.AddWrite(
7617 SYNCHRONOUS, client_maker_.MakeRstPacket(
7618 5, false, GetNthClientInitiatedBidirectionalStreamId(0),
7619 quic::QUIC_STREAM_CANCELLED));
7620 socket_data1.AddSocketDataToFactory(socket_factory_.get());
7621
7622 // Create request and QuicHttpStream.
7623 QuicStreamRequest request(factory_.get());
7624 EXPECT_EQ(ERR_IO_PENDING,
7625 request.Request(
7626 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:517627 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shi99d0cdd2019-05-21 01:18:427628 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
7629 failed_on_default_network_callback_, callback_.callback()));
7630 EXPECT_EQ(OK, callback_.WaitForResult());
7631 std::unique_ptr<HttpStream> stream = CreateStream(&request);
7632 EXPECT_TRUE(stream.get());
7633
7634 // Cause QUIC stream to be created.
7635 HttpRequestInfo request_info;
7636 request_info.method = "GET";
7637 request_info.url = GURL("https://www.example.org/");
7638 request_info.traffic_annotation =
7639 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7640 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
7641 net_log_, CompletionOnceCallback()));
7642
7643 // Ensure that session is alive and active.
7644 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
7645 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7646
7647 // Complete migration.
7648 task_runner->RunUntilIdle();
7649 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7650 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7651 EXPECT_EQ(1u, session->GetNumActiveStreams());
7652
7653 // Send GET request on stream.
7654 HttpResponseInfo response;
7655 HttpRequestHeaders request_headers;
7656 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
7657 callback_.callback()));
7658 socket_data1.Resume();
7659 // Spin up the message loop to read incoming data from server till the ACK.
7660 base::RunLoop().RunUntilIdle();
7661
7662 // Ack delay time.
7663 int delay = task_runner->NextPendingTaskDelay().InMilliseconds();
7664 EXPECT_GT(custom_timeout_value, delay);
7665 // Fire the ack alarm, since ack has been sent, no ack will be sent.
7666 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(delay));
7667 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7668
7669 // Fire the ping alarm with retransmittable-on-wire timeout, send PING.
7670 delay = custom_timeout_value - delay;
7671 EXPECT_EQ(base::TimeDelta::FromMilliseconds(delay),
7672 task_runner->NextPendingTaskDelay());
7673 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(delay));
7674 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7675
7676 socket_data1.Resume();
7677
7678 // Verify that response headers on the migrated socket were delivered to the
7679 // stream.
7680 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
7681 EXPECT_EQ(200, response.headers->response_code());
7682
7683 // Resume the old socket data, a read error will be delivered to the old
7684 // packet reader. Verify that the session is not affected.
7685 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7686 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7687 EXPECT_EQ(1u, session->GetNumActiveStreams());
7688
7689 stream.reset();
7690 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
7691 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
7692}
7693
7694// This test verifies that when no migration is enabled, and no custom value
7695// for retransmittable-on-wire timeout is specified, the ping alarm will not
7696// send any retransmittable pings.
7697TEST_P(QuicStreamFactoryTest, NoRetransmittableOnWireTimeout) {
7698 Initialize();
7699 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7700 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7701 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7702
7703 // Using a testing task runner.
7704 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
7705 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
7706 QuicStreamFactoryPeer::SetAlarmFactory(
7707 factory_.get(),
7708 std::make_unique<QuicChromiumAlarmFactory>(task_runner.get(), &clock_));
7709
Ryan Hamiltonabad59e2019-06-06 04:02:597710 MockQuicData socket_data1(version_);
Zhongyi Shi99d0cdd2019-05-21 01:18:427711 quic::QuicStreamOffset header_stream_offset = 0;
7712 socket_data1.AddWrite(
7713 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
7714 socket_data1.AddWrite(
7715 SYNCHRONOUS, ConstructGetRequestPacket(
7716 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7717 true, &header_stream_offset));
7718 socket_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
7719 // Read two packets so that client will send ACK immedaitely.
7720 spdy::SpdyHeaderBlock response_headers =
7721 server_maker_.GetResponseHeaders("200 OK");
7722 response_headers["key1"] = std::string(2000, 'A');
7723 spdy::SpdyHeadersIR headers_frame(
7724 GetNthClientInitiatedBidirectionalStreamId(0),
7725 std::move(response_headers));
7726 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
7727 spdy::SpdySerializedFrame spdy_frame =
7728 response_framer.SerializeFrame(headers_frame);
7729 size_t chunk_size = 1200;
7730 unsigned int packet_number = 1;
7731 for (size_t offset = 0; offset < spdy_frame.size(); offset += chunk_size) {
7732 size_t len = std::min(chunk_size, spdy_frame.size() - offset);
7733 socket_data1.AddRead(
7734 ASYNC,
7735 server_maker_.MakeDataPacket(
7736 packet_number++,
7737 quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
7738 false, false, offset,
7739 base::StringPiece(spdy_frame.data() + offset, len)));
7740 }
7741 // Read an ACK from server which acks all client data.
7742 socket_data1.AddRead(SYNCHRONOUS,
7743 server_maker_.MakeAckPacket(3, 2, 1, 1, false));
7744 socket_data1.AddWrite(ASYNC, client_maker_.MakeAckPacket(3, 2, 1, 1, false));
7745 std::string header = ConstructDataHeader(6);
7746 socket_data1.AddRead(
7747 ASYNC, ConstructServerDataPacket(
7748 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
7749 0, header + "hello!"));
7750 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read.
7751 socket_data1.AddWrite(
7752 SYNCHRONOUS, client_maker_.MakeRstPacket(
7753 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
7754 quic::QUIC_STREAM_CANCELLED));
7755 socket_data1.AddSocketDataToFactory(socket_factory_.get());
7756
7757 // Create request and QuicHttpStream.
7758 QuicStreamRequest request(factory_.get());
7759 EXPECT_EQ(ERR_IO_PENDING,
7760 request.Request(
7761 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:517762 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shi99d0cdd2019-05-21 01:18:427763 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
7764 failed_on_default_network_callback_, callback_.callback()));
7765 EXPECT_EQ(OK, callback_.WaitForResult());
7766 std::unique_ptr<HttpStream> stream = CreateStream(&request);
7767 EXPECT_TRUE(stream.get());
7768
7769 // Cause QUIC stream to be created.
7770 HttpRequestInfo request_info;
7771 request_info.method = "GET";
7772 request_info.url = GURL("https://www.example.org/");
7773 request_info.traffic_annotation =
7774 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7775 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
7776 net_log_, CompletionOnceCallback()));
7777
7778 // Ensure that session is alive and active.
7779 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
7780 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7781
7782 // Complete migration.
7783 task_runner->RunUntilIdle();
7784 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7785 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7786 EXPECT_EQ(1u, session->GetNumActiveStreams());
7787
7788 // Send GET request on stream.
7789 HttpResponseInfo response;
7790 HttpRequestHeaders request_headers;
7791 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
7792 callback_.callback()));
7793 socket_data1.Resume();
7794 // Spin up the message loop to read incoming data from server till the ACK.
7795 base::RunLoop().RunUntilIdle();
7796
7797 // Ack delay time.
7798 int delay = task_runner->NextPendingTaskDelay().InMilliseconds();
7799 EXPECT_GT(kDefaultRetransmittableOnWireTimeoutMillisecs, delay);
7800 // Fire the ack alarm, since ack has been sent, no ack will be sent.
7801 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(delay));
7802 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7803
7804 // Verify that the ping alarm is not set with any default value.
7805 int wrong_delay = kDefaultRetransmittableOnWireTimeoutMillisecs - delay;
7806 delay = task_runner->NextPendingTaskDelay().InMilliseconds();
7807 EXPECT_NE(wrong_delay, delay);
7808 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(delay));
7809 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7810
7811 // Verify that response headers on the migrated socket were delivered to the
7812 // stream.
7813 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
7814 EXPECT_EQ(200, response.headers->response_code());
7815
7816 // Resume the old socket data, a read error will be delivered to the old
7817 // packet reader. Verify that the session is not affected.
7818 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7819 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7820 EXPECT_EQ(1u, session->GetNumActiveStreams());
7821
7822 stream.reset();
7823 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
7824 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
7825}
7826
7827// This test verifies that when only migration on network change is enabled, and
7828// a custom value for retransmittable-on-wire is specified, the ping alarm will
7829// send retransmittable pings to the peer with custom value.
7830TEST_P(QuicStreamFactoryTest,
7831 CustomeRetransmittableOnWireTimeoutWithMigrationOnNetworkChangeOnly) {
7832 int custom_timeout_value = 200;
7833 test_params_.quic_retransmittable_on_wire_timeout_milliseconds =
7834 custom_timeout_value;
7835 test_params_.quic_migrate_sessions_on_network_change_v2 = true;
7836 Initialize();
7837 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7838 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7839 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7840
7841 // Using a testing task runner.
7842 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
7843 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
7844 QuicStreamFactoryPeer::SetAlarmFactory(
7845 factory_.get(),
7846 std::make_unique<QuicChromiumAlarmFactory>(task_runner.get(), &clock_));
7847
Ryan Hamiltonabad59e2019-06-06 04:02:597848 MockQuicData socket_data1(version_);
Zhongyi Shi99d0cdd2019-05-21 01:18:427849 quic::QuicStreamOffset header_stream_offset = 0;
7850 socket_data1.AddWrite(
7851 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
7852 socket_data1.AddWrite(
7853 SYNCHRONOUS, ConstructGetRequestPacket(
7854 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7855 true, &header_stream_offset));
7856 socket_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
7857 // Read two packets so that client will send ACK immedaitely.
7858 spdy::SpdyHeaderBlock response_headers =
7859 server_maker_.GetResponseHeaders("200 OK");
7860 response_headers["key1"] = std::string(2000, 'A');
7861 spdy::SpdyHeadersIR headers_frame(
7862 GetNthClientInitiatedBidirectionalStreamId(0),
7863 std::move(response_headers));
7864 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
7865 spdy::SpdySerializedFrame spdy_frame =
7866 response_framer.SerializeFrame(headers_frame);
7867 size_t chunk_size = 1200;
7868 unsigned int packet_number = 1;
7869 for (size_t offset = 0; offset < spdy_frame.size(); offset += chunk_size) {
7870 size_t len = std::min(chunk_size, spdy_frame.size() - offset);
7871 socket_data1.AddRead(
7872 ASYNC,
7873 server_maker_.MakeDataPacket(
7874 packet_number++,
7875 quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
7876 false, false, offset,
7877 base::StringPiece(spdy_frame.data() + offset, len)));
7878 }
7879 // Read an ACK from server which acks all client data.
7880 socket_data1.AddRead(SYNCHRONOUS,
7881 server_maker_.MakeAckPacket(3, 2, 1, 1, false));
7882 socket_data1.AddWrite(ASYNC, client_maker_.MakeAckPacket(3, 2, 1, 1, false));
7883 // The PING packet sent for retransmittable on wire.
7884 socket_data1.AddWrite(SYNCHRONOUS, client_maker_.MakePingPacket(4, false));
7885 socket_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
7886 std::string header = ConstructDataHeader(6);
7887 socket_data1.AddRead(
7888 ASYNC, ConstructServerDataPacket(
7889 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
7890 0, header + "hello!"));
7891 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read.
7892 socket_data1.AddWrite(
7893 SYNCHRONOUS, client_maker_.MakeRstPacket(
7894 5, false, GetNthClientInitiatedBidirectionalStreamId(0),
7895 quic::QUIC_STREAM_CANCELLED));
7896 socket_data1.AddSocketDataToFactory(socket_factory_.get());
7897
7898 // Create request and QuicHttpStream.
7899 QuicStreamRequest request(factory_.get());
7900 EXPECT_EQ(ERR_IO_PENDING,
7901 request.Request(
7902 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:517903 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shi99d0cdd2019-05-21 01:18:427904 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
7905 failed_on_default_network_callback_, callback_.callback()));
7906 EXPECT_EQ(OK, callback_.WaitForResult());
7907 std::unique_ptr<HttpStream> stream = CreateStream(&request);
7908 EXPECT_TRUE(stream.get());
7909
7910 // Cause QUIC stream to be created.
7911 HttpRequestInfo request_info;
7912 request_info.method = "GET";
7913 request_info.url = GURL("https://www.example.org/");
7914 request_info.traffic_annotation =
7915 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
7916 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
7917 net_log_, CompletionOnceCallback()));
7918
7919 // Ensure that session is alive and active.
7920 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
7921 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7922
7923 // Complete migration.
7924 task_runner->RunUntilIdle();
7925 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7926 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7927 EXPECT_EQ(1u, session->GetNumActiveStreams());
7928
7929 // Send GET request on stream.
7930 HttpResponseInfo response;
7931 HttpRequestHeaders request_headers;
7932 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
7933 callback_.callback()));
7934 socket_data1.Resume();
7935 // Spin up the message loop to read incoming data from server till the ACK.
7936 base::RunLoop().RunUntilIdle();
7937
7938 // Ack delay time.
7939 int delay = task_runner->NextPendingTaskDelay().InMilliseconds();
7940 EXPECT_GT(custom_timeout_value, delay);
7941 // Fire the ack alarm, since ack has been sent, no ack will be sent.
7942 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(delay));
7943 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7944
7945 // Fire the ping alarm with retransmittable-on-wire timeout, send PING.
7946 delay = custom_timeout_value - delay;
7947 EXPECT_EQ(base::TimeDelta::FromMilliseconds(delay),
7948 task_runner->NextPendingTaskDelay());
7949 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(delay));
7950 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
7951
7952 socket_data1.Resume();
7953
7954 // Verify that response headers on the migrated socket were delivered to the
7955 // stream.
7956 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
7957 EXPECT_EQ(200, response.headers->response_code());
7958
7959 // Resume the old socket data, a read error will be delivered to the old
7960 // packet reader. Verify that the session is not affected.
7961 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
7962 EXPECT_TRUE(HasActiveSession(host_port_pair_));
7963 EXPECT_EQ(1u, session->GetNumActiveStreams());
7964
7965 stream.reset();
7966 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
7967 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
7968}
7969
7970// This test verifies that when only migration on network change is enabled, and
7971// no custom value for retransmittable-on-wire is specified, the ping alarm will
7972// NOT send retransmittable pings to the peer with custom value.
7973TEST_P(QuicStreamFactoryTest,
7974 NoRetransmittableOnWireTimeoutWithMigrationOnNetworkChangeOnly) {
7975 test_params_.quic_migrate_sessions_on_network_change_v2 = true;
7976 Initialize();
7977 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
7978 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7979 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
7980
7981 // Using a testing task runner.
7982 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
7983 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
7984 QuicStreamFactoryPeer::SetAlarmFactory(
7985 factory_.get(),
7986 std::make_unique<QuicChromiumAlarmFactory>(task_runner.get(), &clock_));
7987
Ryan Hamiltonabad59e2019-06-06 04:02:597988 MockQuicData socket_data1(version_);
Zhongyi Shi99d0cdd2019-05-21 01:18:427989 quic::QuicStreamOffset header_stream_offset = 0;
7990 socket_data1.AddWrite(
7991 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
7992 socket_data1.AddWrite(
7993 SYNCHRONOUS, ConstructGetRequestPacket(
7994 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
7995 true, &header_stream_offset));
7996 socket_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
7997 // Read two packets so that client will send ACK immedaitely.
7998 spdy::SpdyHeaderBlock response_headers =
7999 server_maker_.GetResponseHeaders("200 OK");
8000 response_headers["key1"] = std::string(2000, 'A');
8001 spdy::SpdyHeadersIR headers_frame(
8002 GetNthClientInitiatedBidirectionalStreamId(0),
8003 std::move(response_headers));
8004 spdy::SpdyFramer response_framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
8005 spdy::SpdySerializedFrame spdy_frame =
8006 response_framer.SerializeFrame(headers_frame);
8007 size_t chunk_size = 1200;
8008 unsigned int packet_number = 1;
8009 for (size_t offset = 0; offset < spdy_frame.size(); offset += chunk_size) {
8010 size_t len = std::min(chunk_size, spdy_frame.size() - offset);
8011 socket_data1.AddRead(
8012 ASYNC,
8013 server_maker_.MakeDataPacket(
8014 packet_number++,
8015 quic::QuicUtils::GetHeadersStreamId(version_.transport_version),
8016 false, false, offset,
8017 base::StringPiece(spdy_frame.data() + offset, len)));
8018 }
8019 // Read an ACK from server which acks all client data.
8020 socket_data1.AddRead(SYNCHRONOUS,
8021 server_maker_.MakeAckPacket(3, 2, 1, 1, false));
8022 socket_data1.AddWrite(ASYNC, client_maker_.MakeAckPacket(3, 2, 1, 1, false));
8023 std::string header = ConstructDataHeader(6);
8024 socket_data1.AddRead(
8025 ASYNC, ConstructServerDataPacket(
8026 3, GetNthClientInitiatedBidirectionalStreamId(0), false, true,
8027 0, header + "hello!"));
8028 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // No more data to read.
8029 socket_data1.AddWrite(
8030 SYNCHRONOUS, client_maker_.MakeRstPacket(
8031 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
8032 quic::QUIC_STREAM_CANCELLED));
8033 socket_data1.AddSocketDataToFactory(socket_factory_.get());
8034
8035 // Create request and QuicHttpStream.
8036 QuicStreamRequest request(factory_.get());
8037 EXPECT_EQ(ERR_IO_PENDING,
8038 request.Request(
8039 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:518040 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shi99d0cdd2019-05-21 01:18:428041 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
8042 failed_on_default_network_callback_, callback_.callback()));
8043 EXPECT_EQ(OK, callback_.WaitForResult());
8044 std::unique_ptr<HttpStream> stream = CreateStream(&request);
8045 EXPECT_TRUE(stream.get());
8046
8047 // Cause QUIC stream to be created.
8048 HttpRequestInfo request_info;
8049 request_info.method = "GET";
8050 request_info.url = GURL("https://www.example.org/");
8051 request_info.traffic_annotation =
8052 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8053 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
8054 net_log_, CompletionOnceCallback()));
8055
8056 // Ensure that session is alive and active.
8057 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
8058 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8059
8060 // Complete migration.
8061 task_runner->RunUntilIdle();
8062 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
8063 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8064 EXPECT_EQ(1u, session->GetNumActiveStreams());
8065
8066 // Send GET request on stream.
8067 HttpResponseInfo response;
8068 HttpRequestHeaders request_headers;
8069 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
8070 callback_.callback()));
8071 socket_data1.Resume();
8072 // Spin up the message loop to read incoming data from server till the ACK.
8073 base::RunLoop().RunUntilIdle();
8074
8075 // Ack delay time.
8076 int delay = task_runner->NextPendingTaskDelay().InMilliseconds();
8077 EXPECT_GT(kDefaultRetransmittableOnWireTimeoutMillisecs, delay);
8078 // Fire the ack alarm, since ack has been sent, no ack will be sent.
8079 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(delay));
8080 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
8081
8082 // Verify ping alarm is not set with default value.
8083 int wrong_delay = kDefaultRetransmittableOnWireTimeoutMillisecs - delay;
8084 delay = task_runner->NextPendingTaskDelay().InMilliseconds();
8085 EXPECT_NE(wrong_delay, delay);
8086 clock_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(delay));
8087 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
8088
8089 // Verify that response headers on the migrated socket were delivered to the
8090 // stream.
8091 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
8092 EXPECT_EQ(200, response.headers->response_code());
8093
8094 // Resume the old socket data, a read error will be delivered to the old
8095 // packet reader. Verify that the session is not affected.
8096 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
8097 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8098 EXPECT_EQ(1u, session->GetNumActiveStreams());
8099
8100 stream.reset();
8101 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
8102 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
8103}
8104
Zhongyi Shif3d6cddb2018-07-11 03:30:028105// This test verifies that after migration on write error is posted, packet
8106// read error on the old reader will be ignored and will not close the
8107// connection.
8108TEST_P(QuicStreamFactoryTest,
8109 IgnoreReadErrorOnOldReaderDuringPendingMigrationOnWriteError) {
8110 InitializeConnectionMigrationV2Test(
8111 {kDefaultNetworkForTests, kNewNetworkForTests});
8112 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8113 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8114 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8115
8116 // Using a testing task runner.
8117 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
8118 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
8119
Ryan Hamiltonabad59e2019-06-06 04:02:598120 MockQuicData socket_data(version_);
Zhongyi Shif3d6cddb2018-07-11 03:30:028121 quic::QuicStreamOffset header_stream_offset = 0;
8122 socket_data.AddWrite(
8123 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
8124 socket_data.AddWrite(ASYNC, ERR_FAILED); // Write error.
8125 socket_data.AddRead(ASYNC, ERR_ADDRESS_UNREACHABLE); // Read error.
8126 socket_data.AddSocketDataToFactory(socket_factory_.get());
8127
8128 // Create request and QuicHttpStream.
8129 QuicStreamRequest request(factory_.get());
8130 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:038131 request.Request(
Nick Harper23290b82019-05-02 00:02:568132 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:518133 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:038134 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
8135 failed_on_default_network_callback_, callback_.callback()));
Zhongyi Shif3d6cddb2018-07-11 03:30:028136 EXPECT_EQ(OK, callback_.WaitForResult());
8137 std::unique_ptr<HttpStream> stream = CreateStream(&request);
8138 EXPECT_TRUE(stream.get());
8139
8140 // Cause QUIC stream to be created.
8141 HttpRequestInfo request_info;
8142 request_info.method = "GET";
8143 request_info.url = GURL("https://www.example.org/");
8144 request_info.traffic_annotation =
8145 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
8146 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
8147 net_log_, CompletionOnceCallback()));
8148
8149 // Ensure that session is alive and active.
8150 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
8151 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
8152 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8153
8154 // Set up second socket data provider that is used after
8155 // migration. The request is written to this new socket, and the
8156 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:598157 MockQuicData socket_data1(version_);
Fan Yang32c5a112018-12-10 20:06:338158 socket_data1.AddWrite(
8159 SYNCHRONOUS, ConstructGetRequestPacket(
8160 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
8161 true, &header_stream_offset));
Zhongyi Shif3d6cddb2018-07-11 03:30:028162 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:338163 ASYNC,
8164 ConstructOkResponsePacket(
8165 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
Zhongyi Shif3d6cddb2018-07-11 03:30:028166
8167 socket_data1.AddRead(ASYNC, ERR_IO_PENDING); // Pause.
8168 socket_data1.AddRead(ASYNC, ERR_FAILED); // Read error to close connection.
8169 socket_data1.AddSocketDataToFactory(socket_factory_.get());
8170
8171 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
8172 // Send GET request on stream.
8173 HttpResponseInfo response;
8174 HttpRequestHeaders request_headers;
8175 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
8176 callback_.callback()));
8177 // Run the message loop to complete asynchronous write and read with errors.
8178 base::RunLoop().RunUntilIdle();
8179 // There will be one pending task to complete migration on write error.
8180 // Verify session is not closed with read error.
8181 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
8182 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
8183 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8184 EXPECT_EQ(1u, session->GetNumActiveStreams());
8185
8186 // Complete migration.
8187 task_runner->RunUntilIdle();
Zhongyi Shia7dd46b2018-07-12 22:59:298188 // There will be one more task posted attempting to migrate back to the
8189 // default network.
8190 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
Zhongyi Shif3d6cddb2018-07-11 03:30:028191 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shia7dd46b2018-07-12 22:59:298192 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shif3d6cddb2018-07-11 03:30:028193 EXPECT_EQ(1u, session->GetNumActiveStreams());
8194
8195 // Verify that response headers on the migrated socket were delivered to the
8196 // stream.
8197 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
8198 EXPECT_EQ(200, response.headers->response_code());
8199
8200 // Resume to consume the read error on new socket, which will close
8201 // the connection.
8202 socket_data1.Resume();
8203
8204 EXPECT_TRUE(socket_data.AllReadDataConsumed());
8205 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
8206 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
8207 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
8208}
8209
Zhongyi Shi4ac9e1f2018-06-21 05:21:478210// Migrate on asynchronous write error, old network disconnects after alternate
8211// network connects.
8212TEST_P(QuicStreamFactoryTest,
8213 MigrateSessionOnWriteErrorWithDisconnectAfterConnectAysnc) {
8214 TestMigrationOnWriteErrorWithMultipleNotifications(
8215 ASYNC, /*disconnect_before_connect*/ false);
8216}
8217
8218// Migrate on synchronous write error, old network disconnects after alternate
8219// network connects.
8220TEST_P(QuicStreamFactoryTest,
8221 MigrateSessionOnWriteErrorWithDisconnectAfterConnectSync) {
8222 TestMigrationOnWriteErrorWithMultipleNotifications(
8223 SYNCHRONOUS, /*disconnect_before_connect*/ false);
8224}
8225
8226// Migrate on asynchronous write error, old network disconnects before alternate
8227// network connects.
8228TEST_P(QuicStreamFactoryTest,
8229 MigrateSessionOnWriteErrorWithDisconnectBeforeConnectAysnc) {
8230 TestMigrationOnWriteErrorWithMultipleNotifications(
8231 ASYNC, /*disconnect_before_connect*/ true);
8232}
8233
8234// Migrate on synchronous write error, old network disconnects before alternate
8235// network connects.
8236TEST_P(QuicStreamFactoryTest,
8237 MigrateSessionOnWriteErrorWithDisconnectBeforeConnectSync) {
8238 TestMigrationOnWriteErrorWithMultipleNotifications(
8239 SYNCHRONOUS, /*disconnect_before_connect*/ true);
8240}
8241
8242// Setps up test which verifies that session successfully migrate to alternate
8243// network with signals delivered in the following order:
8244// *NOTE* Signal (A) and (B) can reverse order based on
8245// |disconnect_before_connect|.
8246// - (No alternate network is connected) session connects to
8247// kDefaultNetworkForTests.
8248// - An async/sync write error is encountered based on |write_error_mode|:
8249// session posted task to migrate session on write error.
8250// - Posted task is executed, miration moves to pending state due to lack of
8251// alternate network.
8252// - (A) An alternate network is connected, pending migration completes.
8253// - (B) Old default network disconnects, no migration will be attempted as
Zhongyi Shi329f5cbd2018-06-22 23:51:188254// session has already migrate to the alternate network.
Zhongyi Shi4ac9e1f2018-06-21 05:21:478255// - The alternate network is made default.
jri5b785512016-09-13 04:29:118256void QuicStreamFactoryTestBase::
Zhongyi Shi4ac9e1f2018-06-21 05:21:478257 TestMigrationOnWriteErrorWithMultipleNotifications(
jri5b785512016-09-13 04:29:118258 IoMode write_error_mode,
Zhongyi Shi4ac9e1f2018-06-21 05:21:478259 bool disconnect_before_connect) {
Zhongyi Shi329f5cbd2018-06-22 23:51:188260 InitializeConnectionMigrationV2Test({kDefaultNetworkForTests});
jri5b785512016-09-13 04:29:118261 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8262 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8263 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8264
Ryan Hamiltonabad59e2019-06-06 04:02:598265 MockQuicData socket_data(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528266 quic::QuicStreamOffset header_stream_offset = 0;
jri5b785512016-09-13 04:29:118267 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
rch5cb522462017-04-25 20:18:368268 socket_data.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438269 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Zhongyi Shi4ac9e1f2018-06-21 05:21:478270 socket_data.AddWrite(write_error_mode, ERR_FAILED); // Write error.
Zhongyi Shi5f587cc2017-11-21 23:24:178271 socket_data.AddSocketDataToFactory(socket_factory_.get());
jri5b785512016-09-13 04:29:118272
8273 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:458274 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338275 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:038276 request.Request(
Nick Harper23290b82019-05-02 00:02:568277 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:518278 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:038279 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
8280 failed_on_default_network_callback_, callback_.callback()));
jri5b785512016-09-13 04:29:118281 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:248282 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri5b785512016-09-13 04:29:118283 EXPECT_TRUE(stream.get());
8284
8285 // Cause QUIC stream to be created.
8286 HttpRequestInfo request_info;
8287 request_info.method = "GET";
8288 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:398289 request_info.traffic_annotation =
8290 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:278291 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:398292 net_log_, CompletionOnceCallback()));
jri5b785512016-09-13 04:29:118293
8294 // Ensure that session is alive and active.
8295 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
8296 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
8297 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8298
8299 // Send GET request on stream. This should cause a write error, which triggers
8300 // a connection migration attempt.
8301 HttpResponseInfo response;
8302 HttpRequestHeaders request_headers;
8303 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
8304 callback_.callback()));
Zhongyi Shi4ac9e1f2018-06-21 05:21:478305 // Run the message loop so that posted task to migrate to socket will be
8306 // executed. A new task will be posted to wait for a new network.
jri5b785512016-09-13 04:29:118307 base::RunLoop().RunUntilIdle();
8308
8309 // In this particular code path, the network will not yet be marked
8310 // as going away and the session will still be alive.
8311 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
8312 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8313 EXPECT_EQ(1u, session->GetNumActiveStreams());
8314 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback()));
8315
8316 // Set up second socket data provider that is used after
8317 // migration. The request is rewritten to this new socket, and the
8318 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:598319 MockQuicData socket_data1(version_);
Fan Yang32c5a112018-12-10 20:06:338320 socket_data1.AddWrite(
8321 SYNCHRONOUS, ConstructGetRequestPacket(
8322 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
8323 true, &header_stream_offset));
Zhongyi Shi32f2fd02018-04-16 18:23:438324 socket_data1.AddRead(
Fan Yang32c5a112018-12-10 20:06:338325 ASYNC,
8326 ConstructOkResponsePacket(
8327 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
jri5b785512016-09-13 04:29:118328 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:338329 socket_data1.AddWrite(
8330 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
8331 3, false, GetNthClientInitiatedBidirectionalStreamId(0),
8332 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:178333 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri5b785512016-09-13 04:29:118334
8335 scoped_mock_network_change_notifier_->mock_network_change_notifier()
8336 ->SetConnectedNetworksList(
8337 {kDefaultNetworkForTests, kNewNetworkForTests});
Zhongyi Shi4ac9e1f2018-06-21 05:21:478338 if (disconnect_before_connect) {
8339 // Now deliver a DISCONNECT notification.
jri5b785512016-09-13 04:29:118340 scoped_mock_network_change_notifier_->mock_network_change_notifier()
8341 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
Zhongyi Shi4ac9e1f2018-06-21 05:21:478342
8343 // Now deliver a CONNECTED notification and completes migration.
jri5b785512016-09-13 04:29:118344 scoped_mock_network_change_notifier_->mock_network_change_notifier()
Zhongyi Shi4ac9e1f2018-06-21 05:21:478345 ->NotifyNetworkConnected(kNewNetworkForTests);
8346 } else {
8347 // Now deliver a CONNECTED notification and completes migration.
8348 scoped_mock_network_change_notifier_->mock_network_change_notifier()
8349 ->NotifyNetworkConnected(kNewNetworkForTests);
8350
8351 // Now deliver a DISCONNECT notification.
8352 scoped_mock_network_change_notifier_->mock_network_change_notifier()
8353 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
jri5b785512016-09-13 04:29:118354 }
jri5b785512016-09-13 04:29:118355 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
Zhongyi Shi329f5cbd2018-06-22 23:51:188356 EXPECT_TRUE(HasActiveSession(host_port_pair_));
jri5b785512016-09-13 04:29:118357 EXPECT_EQ(1u, session->GetNumActiveStreams());
8358
8359 // This is the callback for the response headers that returned
8360 // pending previously, because no result was available. Check that
8361 // the result is now available due to the successful migration.
8362 EXPECT_THAT(callback_.WaitForResult(), IsOk());
8363 EXPECT_EQ(200, response.headers->response_code());
8364
Zhongyi Shi4ac9e1f2018-06-21 05:21:478365 // Deliver a MADEDEFAULT notification.
jri5b785512016-09-13 04:29:118366 scoped_mock_network_change_notifier_->mock_network_change_notifier()
Zhongyi Shi4ac9e1f2018-06-21 05:21:478367 ->NotifyNetworkMadeDefault(kNewNetworkForTests);
jri5b785512016-09-13 04:29:118368
zhongyi98d6a9262017-05-19 02:47:458369 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:518370 EXPECT_EQ(OK,
8371 request2.Request(
8372 host_port_pair_, version_.transport_version, privacy_mode_,
8373 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
8374 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
8375 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7891a39d2017-11-08 20:59:248376 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
jri5b785512016-09-13 04:29:118377 EXPECT_TRUE(stream2.get());
8378
8379 EXPECT_TRUE(HasActiveSession(host_port_pair_));
Zhongyi Shi329f5cbd2018-06-22 23:51:188380 EXPECT_EQ(session, GetActiveSession(host_port_pair_));
jri5b785512016-09-13 04:29:118381
8382 stream.reset();
8383 stream2.reset();
8384
8385 EXPECT_TRUE(socket_data.AllReadDataConsumed());
8386 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
8387 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
8388 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
jri5b785512016-09-13 04:29:118389}
8390
Zhongyi Shic16b4102019-02-12 00:37:408391// This test verifies after session migrates off the default network, it keeps
8392// retrying migrate back to the default network until successfully gets on the
8393// default network or the idle migration period threshold is exceeded.
8394// The default threshold is 30s.
8395TEST_P(QuicStreamFactoryTest, DefaultIdleMigrationPeriod) {
Zhongyi Shi32fe14d42019-02-28 00:25:368396 test_params_.quic_migrate_idle_sessions = true;
Zhongyi Shic16b4102019-02-12 00:37:408397 InitializeConnectionMigrationV2Test(
8398 {kDefaultNetworkForTests, kNewNetworkForTests});
8399 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8400 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8401
8402 // Using a testing task runner and a test tick tock.
8403 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
8404 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
8405 QuicStreamFactoryPeer::SetTickClock(factory_.get(),
8406 task_runner->GetMockTickClock());
8407
Ryan Hamiltonabad59e2019-06-06 04:02:598408 MockQuicData default_socket_data(version_);
Zhongyi Shic16b4102019-02-12 00:37:408409 default_socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
8410 default_socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
8411 default_socket_data.AddSocketDataToFactory(socket_factory_.get());
8412
8413 // Set up second socket data provider that is used after migration.
Ryan Hamiltonabad59e2019-06-06 04:02:598414 MockQuicData alternate_socket_data(version_);
Zhongyi Shic16b4102019-02-12 00:37:408415 alternate_socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8416 // Ping packet to send after migration.
8417 alternate_socket_data.AddWrite(
8418 SYNCHRONOUS, client_maker_.MakePingPacket(2, /*include_version=*/true));
8419 alternate_socket_data.AddSocketDataToFactory(socket_factory_.get());
8420
8421 // Set up probing socket for migrating back to the default network.
Ryan Hamiltonabad59e2019-06-06 04:02:598422 MockQuicData quic_data(version_); // retry count: 0.
Zhongyi Shic16b4102019-02-12 00:37:408423 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8424 quic_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
8425 quic_data.AddSocketDataToFactory(socket_factory_.get());
8426
Ryan Hamiltonabad59e2019-06-06 04:02:598427 MockQuicData quic_data1(version_); // retry count: 1
Zhongyi Shic16b4102019-02-12 00:37:408428 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8429 quic_data1.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
8430 quic_data1.AddSocketDataToFactory(socket_factory_.get());
8431
Ryan Hamiltonabad59e2019-06-06 04:02:598432 MockQuicData quic_data2(version_); // retry count: 2
Zhongyi Shic16b4102019-02-12 00:37:408433 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8434 quic_data2.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
8435 quic_data2.AddSocketDataToFactory(socket_factory_.get());
8436
Ryan Hamiltonabad59e2019-06-06 04:02:598437 MockQuicData quic_data3(version_); // retry count: 3
Zhongyi Shic16b4102019-02-12 00:37:408438 quic_data3.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8439 quic_data3.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
8440 quic_data3.AddSocketDataToFactory(socket_factory_.get());
8441
Ryan Hamiltonabad59e2019-06-06 04:02:598442 MockQuicData quic_data4(version_); // retry count: 4
Zhongyi Shic16b4102019-02-12 00:37:408443 quic_data4.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8444 quic_data4.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
8445 quic_data4.AddSocketDataToFactory(socket_factory_.get());
8446
Ryan Hamiltonabad59e2019-06-06 04:02:598447 MockQuicData quic_data5(version_); // retry count: 5
Zhongyi Shic16b4102019-02-12 00:37:408448 quic_data5.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8449 quic_data5.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
8450 quic_data5.AddSocketDataToFactory(socket_factory_.get());
8451
8452 // Create request and QuicHttpStream.
8453 QuicStreamRequest request(factory_.get());
8454 EXPECT_EQ(ERR_IO_PENDING,
8455 request.Request(
Nick Harper23290b82019-05-02 00:02:568456 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:518457 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shic16b4102019-02-12 00:37:408458 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
8459 failed_on_default_network_callback_, callback_.callback()));
8460 EXPECT_THAT(callback_.WaitForResult(), IsOk());
8461 std::unique_ptr<HttpStream> stream = CreateStream(&request);
8462 EXPECT_TRUE(stream.get());
8463
8464 // Ensure that session is active.
8465 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8466
8467 // Trigger connection migration. Since there are no active streams,
8468 // the session will be closed.
8469 scoped_mock_network_change_notifier_->mock_network_change_notifier()
8470 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
8471
8472 // The nearest task will complete migration.
8473 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
8474 EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay());
8475 task_runner->FastForwardBy(base::TimeDelta());
8476
8477 // The migrate back timer will fire. Due to default network
8478 // being disconnected, no attempt will be exercised to migrate back.
8479 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
8480 EXPECT_EQ(base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs),
8481 task_runner->NextPendingTaskDelay());
8482 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
8483 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
8484
8485 // Deliver the signal that the old default network now backs up.
8486 scoped_mock_network_change_notifier_->mock_network_change_notifier()
8487 ->NotifyNetworkMadeDefault(kDefaultNetworkForTests);
8488
8489 // A task is posted to migrate back to the default network immediately.
8490 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
8491 EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay());
8492 task_runner->FastForwardBy(base::TimeDelta());
8493
8494 // Retry migrate back in 1, 2, 4, 8, 16s.
8495 // Session will be closed due to idle migration timeout.
8496 for (int i = 0; i < 5; i++) {
8497 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8498 // A task is posted to migrate back to the default network in 2^i seconds.
8499 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
8500 EXPECT_EQ(base::TimeDelta::FromSeconds(UINT64_C(1) << i),
8501 task_runner->NextPendingTaskDelay());
8502 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
8503 }
8504
8505 EXPECT_TRUE(default_socket_data.AllReadDataConsumed());
8506 EXPECT_TRUE(default_socket_data.AllWriteDataConsumed());
8507 EXPECT_TRUE(alternate_socket_data.AllReadDataConsumed());
8508 EXPECT_TRUE(alternate_socket_data.AllWriteDataConsumed());
8509}
8510
8511TEST_P(QuicStreamFactoryTest, CustomIdleMigrationPeriod) {
8512 // The customized threshold is 15s.
Zhongyi Shi32fe14d42019-02-28 00:25:368513 test_params_.quic_migrate_idle_sessions = true;
Zhongyi Shic16b4102019-02-12 00:37:408514 test_params_.quic_idle_session_migration_period =
8515 base::TimeDelta::FromSeconds(15);
8516 InitializeConnectionMigrationV2Test(
8517 {kDefaultNetworkForTests, kNewNetworkForTests});
8518 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8519 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8520
8521 // Using a testing task runner and a test tick tock.
8522 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
8523 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
8524 QuicStreamFactoryPeer::SetTickClock(factory_.get(),
8525 task_runner->GetMockTickClock());
8526
Ryan Hamiltonabad59e2019-06-06 04:02:598527 MockQuicData default_socket_data(version_);
Zhongyi Shic16b4102019-02-12 00:37:408528 default_socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
8529 default_socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
8530 default_socket_data.AddSocketDataToFactory(socket_factory_.get());
8531
8532 // Set up second socket data provider that is used after migration.
Ryan Hamiltonabad59e2019-06-06 04:02:598533 MockQuicData alternate_socket_data(version_);
Zhongyi Shic16b4102019-02-12 00:37:408534 alternate_socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8535 // Ping packet to send after migration.
8536 alternate_socket_data.AddWrite(
8537 SYNCHRONOUS, client_maker_.MakePingPacket(2, /*include_version=*/true));
8538 alternate_socket_data.AddSocketDataToFactory(socket_factory_.get());
8539
8540 // Set up probing socket for migrating back to the default network.
Ryan Hamiltonabad59e2019-06-06 04:02:598541 MockQuicData quic_data(version_); // retry count: 0.
Zhongyi Shic16b4102019-02-12 00:37:408542 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8543 quic_data.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
8544 quic_data.AddSocketDataToFactory(socket_factory_.get());
8545
Ryan Hamiltonabad59e2019-06-06 04:02:598546 MockQuicData quic_data1(version_); // retry count: 1
Zhongyi Shic16b4102019-02-12 00:37:408547 quic_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8548 quic_data1.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
8549 quic_data1.AddSocketDataToFactory(socket_factory_.get());
8550
Ryan Hamiltonabad59e2019-06-06 04:02:598551 MockQuicData quic_data2(version_); // retry count: 2
Zhongyi Shic16b4102019-02-12 00:37:408552 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8553 quic_data2.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
8554 quic_data2.AddSocketDataToFactory(socket_factory_.get());
8555
Ryan Hamiltonabad59e2019-06-06 04:02:598556 MockQuicData quic_data3(version_); // retry count: 3
Zhongyi Shic16b4102019-02-12 00:37:408557 quic_data3.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8558 quic_data3.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
8559 quic_data3.AddSocketDataToFactory(socket_factory_.get());
8560
Ryan Hamiltonabad59e2019-06-06 04:02:598561 MockQuicData quic_data4(version_); // retry count: 4
Zhongyi Shic16b4102019-02-12 00:37:408562 quic_data4.AddRead(SYNCHRONOUS, ERR_IO_PENDING); // Hanging read.
8563 quic_data4.AddWrite(SYNCHRONOUS, ERR_ADDRESS_UNREACHABLE);
8564 quic_data4.AddSocketDataToFactory(socket_factory_.get());
8565
8566 // Create request and QuicHttpStream.
8567 QuicStreamRequest request(factory_.get());
8568 EXPECT_EQ(ERR_IO_PENDING,
8569 request.Request(
Nick Harper23290b82019-05-02 00:02:568570 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:518571 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shic16b4102019-02-12 00:37:408572 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
8573 failed_on_default_network_callback_, callback_.callback()));
8574 EXPECT_THAT(callback_.WaitForResult(), IsOk());
8575 std::unique_ptr<HttpStream> stream = CreateStream(&request);
8576 EXPECT_TRUE(stream.get());
8577
8578 // Ensure that session is active.
8579 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8580
8581 // Trigger connection migration. Since there are no active streams,
8582 // the session will be closed.
8583 scoped_mock_network_change_notifier_->mock_network_change_notifier()
8584 ->NotifyNetworkDisconnected(kDefaultNetworkForTests);
8585
8586 // The nearest task will complete migration.
8587 EXPECT_EQ(2u, task_runner->GetPendingTaskCount());
8588 EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay());
8589 task_runner->FastForwardBy(base::TimeDelta());
8590
8591 // The migrate back timer will fire. Due to default network
8592 // being disconnected, no attempt will be exercised to migrate back.
8593 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
8594 EXPECT_EQ(base::TimeDelta::FromSeconds(kMinRetryTimeForDefaultNetworkSecs),
8595 task_runner->NextPendingTaskDelay());
8596 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
8597 EXPECT_EQ(0u, task_runner->GetPendingTaskCount());
8598
8599 // Deliver the signal that the old default network now backs up.
8600 scoped_mock_network_change_notifier_->mock_network_change_notifier()
8601 ->NotifyNetworkMadeDefault(kDefaultNetworkForTests);
8602
8603 // A task is posted to migrate back to the default network immediately.
8604 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
8605 EXPECT_EQ(base::TimeDelta(), task_runner->NextPendingTaskDelay());
8606 task_runner->FastForwardBy(base::TimeDelta());
8607
8608 // Retry migrate back in 1, 2, 4, 8s.
8609 // Session will be closed due to idle migration timeout.
8610 for (int i = 0; i < 4; i++) {
8611 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8612 // A task is posted to migrate back to the default network in 2^i seconds.
8613 EXPECT_EQ(1u, task_runner->GetPendingTaskCount());
8614 EXPECT_EQ(base::TimeDelta::FromSeconds(UINT64_C(1) << i),
8615 task_runner->NextPendingTaskDelay());
8616 task_runner->FastForwardBy(task_runner->NextPendingTaskDelay());
8617 }
8618
8619 EXPECT_TRUE(default_socket_data.AllReadDataConsumed());
8620 EXPECT_TRUE(default_socket_data.AllWriteDataConsumed());
8621 EXPECT_TRUE(alternate_socket_data.AllReadDataConsumed());
8622 EXPECT_TRUE(alternate_socket_data.AllWriteDataConsumed());
8623}
8624
jri217455a12016-07-13 20:15:098625TEST_P(QuicStreamFactoryTest, ServerMigration) {
Zhongyi Shi967d2f12019-02-08 20:58:538626 test_params_.quic_allow_server_migration = true;
jri217455a12016-07-13 20:15:098627 Initialize();
8628
8629 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8630 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8631 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8632
Ryan Hamiltonabad59e2019-06-06 04:02:598633 MockQuicData socket_data1(version_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528634 quic::QuicStreamOffset header_stream_offset = 0;
rcha00569732016-08-27 11:09:368635 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
rch5cb522462017-04-25 20:18:368636 socket_data1.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438637 SYNCHRONOUS, ConstructInitialSettingsPacket(1, &header_stream_offset));
Fan Yang32c5a112018-12-10 20:06:338638 socket_data1.AddWrite(
8639 SYNCHRONOUS, ConstructGetRequestPacket(
8640 2, GetNthClientInitiatedBidirectionalStreamId(0), true,
8641 true, &header_stream_offset));
Zhongyi Shi5f587cc2017-11-21 23:24:178642 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri217455a12016-07-13 20:15:098643
8644 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:458645 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338646 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:038647 request.Request(
Nick Harper23290b82019-05-02 00:02:568648 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:518649 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:038650 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
8651 failed_on_default_network_callback_, callback_.callback()));
jri217455a12016-07-13 20:15:098652 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:248653 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri217455a12016-07-13 20:15:098654 EXPECT_TRUE(stream.get());
8655
8656 // Cause QUIC stream to be created.
8657 HttpRequestInfo request_info;
8658 request_info.method = "GET";
8659 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:398660 request_info.traffic_annotation =
8661 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:278662 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:398663 net_log_, CompletionOnceCallback()));
jri217455a12016-07-13 20:15:098664
8665 // Ensure that session is alive and active.
8666 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
8667 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
8668 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8669
8670 // Send GET request on stream.
8671 HttpResponseInfo response;
8672 HttpRequestHeaders request_headers;
8673 EXPECT_EQ(OK, stream->SendRequest(request_headers, &response,
8674 callback_.callback()));
8675
8676 IPEndPoint ip;
8677 session->GetDefaultSocket()->GetPeerAddress(&ip);
8678 DVLOG(1) << "Socket connected to: " << ip.address().ToString() << " "
8679 << ip.port();
8680
8681 // Set up second socket data provider that is used after
8682 // migration. The request is rewritten to this new socket, and the
8683 // response to the request is read on this new socket.
Ryan Hamiltonabad59e2019-06-06 04:02:598684 MockQuicData socket_data2(version_);
rcha00569732016-08-27 11:09:368685 socket_data2.AddWrite(
Zhongyi Shi32f2fd02018-04-16 18:23:438686 SYNCHRONOUS, client_maker_.MakePingPacket(3, /*include_version=*/true));
8687 socket_data2.AddRead(
Fan Yang32c5a112018-12-10 20:06:338688 ASYNC,
8689 ConstructOkResponsePacket(
8690 1, GetNthClientInitiatedBidirectionalStreamId(0), false, false));
rcha00569732016-08-27 11:09:368691 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Fan Yang32c5a112018-12-10 20:06:338692 socket_data2.AddWrite(
8693 SYNCHRONOUS, client_maker_.MakeAckAndRstPacket(
8694 4, false, GetNthClientInitiatedBidirectionalStreamId(0),
8695 quic::QUIC_STREAM_CANCELLED, 1, 1, 1, true));
Zhongyi Shi5f587cc2017-11-21 23:24:178696 socket_data2.AddSocketDataToFactory(socket_factory_.get());
jri217455a12016-07-13 20:15:098697
8698 const uint8_t kTestIpAddress[] = {1, 2, 3, 4};
8699 const uint16_t kTestPort = 123;
Zhongyi Shif124a582017-11-02 00:15:048700 session->Migrate(NetworkChangeNotifier::kInvalidNetworkHandle,
8701 IPEndPoint(IPAddress(kTestIpAddress), kTestPort), true,
8702 net_log_);
jri217455a12016-07-13 20:15:098703
8704 session->GetDefaultSocket()->GetPeerAddress(&ip);
8705 DVLOG(1) << "Socket migrated to: " << ip.address().ToString() << " "
8706 << ip.port();
8707
8708 // The session should be alive and active.
8709 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
8710 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8711 EXPECT_EQ(1u, session->GetNumActiveStreams());
8712
8713 // Run the message loop so that data queued in the new socket is read by the
8714 // packet reader.
8715 base::RunLoop().RunUntilIdle();
8716
8717 // Verify that response headers on the migrated socket were delivered to the
8718 // stream.
8719 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback()));
8720 EXPECT_EQ(200, response.headers->response_code());
8721
8722 stream.reset();
8723
8724 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
8725 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
8726 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
8727 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
8728}
8729
jri053fdbd2016-08-19 02:33:058730TEST_P(QuicStreamFactoryTest, ServerMigrationIPv4ToIPv4) {
8731 // Add alternate IPv4 server address to config.
8732 IPEndPoint alt_address = IPEndPoint(IPAddress(1, 2, 3, 4), 123);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528733 quic::QuicConfig config;
Victor Vasiliev4f6fb892019-05-31 16:58:318734 config.SetAlternateServerAddressToSend(ToQuicSocketAddress(alt_address));
jri053fdbd2016-08-19 02:33:058735 VerifyServerMigration(config, alt_address);
8736}
8737
8738TEST_P(QuicStreamFactoryTest, ServerMigrationIPv6ToIPv6) {
8739 // Add a resolver rule to make initial connection to an IPv6 address.
Renjiea0cb4a2c2018-09-26 23:37:308740 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
8741 "fe80::aebc:32ff:febb:1e33", "");
jri053fdbd2016-08-19 02:33:058742 // Add alternate IPv6 server address to config.
8743 IPEndPoint alt_address = IPEndPoint(
8744 IPAddress(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), 123);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528745 quic::QuicConfig config;
Victor Vasiliev4f6fb892019-05-31 16:58:318746 config.SetAlternateServerAddressToSend(ToQuicSocketAddress(alt_address));
jri053fdbd2016-08-19 02:33:058747 VerifyServerMigration(config, alt_address);
8748}
8749
8750TEST_P(QuicStreamFactoryTest, ServerMigrationIPv6ToIPv4) {
8751 // Add a resolver rule to make initial connection to an IPv6 address.
Renjiea0cb4a2c2018-09-26 23:37:308752 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
8753 "fe80::aebc:32ff:febb:1e33", "");
jri053fdbd2016-08-19 02:33:058754 // Add alternate IPv4 server address to config.
8755 IPEndPoint alt_address = IPEndPoint(IPAddress(1, 2, 3, 4), 123);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528756 quic::QuicConfig config;
Victor Vasiliev4f6fb892019-05-31 16:58:318757 config.SetAlternateServerAddressToSend(ToQuicSocketAddress(alt_address));
jri053fdbd2016-08-19 02:33:058758 IPEndPoint expected_address(
8759 ConvertIPv4ToIPv4MappedIPv6(alt_address.address()), alt_address.port());
8760 VerifyServerMigration(config, expected_address);
8761}
8762
8763TEST_P(QuicStreamFactoryTest, ServerMigrationIPv4ToIPv6Fails) {
Zhongyi Shi967d2f12019-02-08 20:58:538764 test_params_.quic_allow_server_migration = true;
jri053fdbd2016-08-19 02:33:058765 Initialize();
8766
8767 // Add a resolver rule to make initial connection to an IPv4 address.
Renjiea0cb4a2c2018-09-26 23:37:308768 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(), "1.2.3.4",
8769 "");
jri053fdbd2016-08-19 02:33:058770 // Add alternate IPv6 server address to config.
8771 IPEndPoint alt_address = IPEndPoint(
8772 IPAddress(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16), 123);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528773 quic::QuicConfig config;
Victor Vasiliev4f6fb892019-05-31 16:58:318774 config.SetAlternateServerAddressToSend(ToQuicSocketAddress(alt_address));
jri053fdbd2016-08-19 02:33:058775
8776 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8777 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8778 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8779
8780 crypto_client_stream_factory_.SetConfig(config);
8781
8782 // Set up only socket data provider.
Ryan Hamiltonabad59e2019-06-06 04:02:598783 MockQuicData socket_data1(version_);
rcha00569732016-08-27 11:09:368784 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:438785 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
8786 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:338787 SYNCHRONOUS, client_maker_.MakeRstPacket(
8788 2, true, GetNthClientInitiatedBidirectionalStreamId(0),
8789 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:178790 socket_data1.AddSocketDataToFactory(socket_factory_.get());
jri053fdbd2016-08-19 02:33:058791
8792 // Create request and QuicHttpStream.
zhongyi98d6a9262017-05-19 02:47:458793 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338794 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:038795 request.Request(
Nick Harper23290b82019-05-02 00:02:568796 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:518797 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:038798 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
8799 failed_on_default_network_callback_, callback_.callback()));
jri053fdbd2016-08-19 02:33:058800 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:248801 std::unique_ptr<HttpStream> stream = CreateStream(&request);
jri053fdbd2016-08-19 02:33:058802 EXPECT_TRUE(stream.get());
8803
8804 // Cause QUIC stream to be created.
8805 HttpRequestInfo request_info;
8806 request_info.method = "GET";
8807 request_info.url = GURL("https://www.example.org/");
Ramin Halavati683bcaa92018-02-14 08:42:398808 request_info.traffic_annotation =
8809 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:278810 EXPECT_EQ(OK, stream->InitializeStream(&request_info, true, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:398811 net_log_, CompletionOnceCallback()));
jri053fdbd2016-08-19 02:33:058812
8813 // Ensure that session is alive and active.
8814 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
8815 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
8816 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8817
8818 IPEndPoint actual_address;
8819 session->GetDefaultSocket()->GetPeerAddress(&actual_address);
8820 // No migration should have happened.
8821 IPEndPoint expected_address =
8822 IPEndPoint(IPAddress(1, 2, 3, 4), kDefaultServerPort);
8823 EXPECT_EQ(actual_address, expected_address);
8824 DVLOG(1) << "Socket connected to: " << actual_address.address().ToString()
8825 << " " << actual_address.port();
8826 DVLOG(1) << "Expected address: " << expected_address.address().ToString()
8827 << " " << expected_address.port();
8828
8829 stream.reset();
8830 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
8831 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
8832}
8833
rsleevi17784692016-10-12 01:36:208834TEST_P(QuicStreamFactoryTest, OnCertDBChanged) {
jri7046038f2015-10-22 00:29:268835 Initialize();
rch6faa4d42016-01-05 20:48:438836 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8837 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8838 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8839
Ryan Hamiltonabad59e2019-06-06 04:02:598840 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:368841 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:438842 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:178843 socket_data.AddSocketDataToFactory(socket_factory_.get());
[email protected]d7d1e50b2013-11-25 22:08:098844
Ryan Hamiltonabad59e2019-06-06 04:02:598845 MockQuicData socket_data2(version_);
rcha00569732016-08-27 11:09:368846 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:438847 socket_data2.AddWrite(SYNCHRONOUS,
8848 ConstructInitialSettingsPacket(1, nullptr));
Zhongyi Shi5f587cc2017-11-21 23:24:178849 socket_data2.AddSocketDataToFactory(socket_factory_.get());
[email protected]d7d1e50b2013-11-25 22:08:098850
zhongyi98d6a9262017-05-19 02:47:458851 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338852 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:038853 request.Request(
Nick Harper23290b82019-05-02 00:02:568854 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:518855 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:038856 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
8857 failed_on_default_network_callback_, callback_.callback()));
[email protected]d7d1e50b2013-11-25 22:08:098858
robpercival214763f2016-07-01 23:27:018859 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:248860 std::unique_ptr<HttpStream> stream = CreateStream(&request);
Charles 'Buck' Krasic71763c9f2018-02-16 02:37:288861 EXPECT_TRUE(stream);
8862 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
[email protected]d7d1e50b2013-11-25 22:08:098863
8864 // Change the CA cert and verify that stream saw the event.
mattmfd05a1f2017-02-18 06:18:448865 factory_->OnCertDBChanged();
Charles 'Buck' Krasic71763c9f2018-02-16 02:37:288866
jri7046038f2015-10-22 00:29:268867 EXPECT_FALSE(factory_->require_confirmation());
Charles 'Buck' Krasic71763c9f2018-02-16 02:37:288868 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
8869 EXPECT_FALSE(HasActiveSession(host_port_pair_));
[email protected]d7d1e50b2013-11-25 22:08:098870
8871 // Now attempting to request a stream to the same origin should create
8872 // a new session.
8873
zhongyi98d6a9262017-05-19 02:47:458874 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:338875 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:038876 request2.Request(
Nick Harper23290b82019-05-02 00:02:568877 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:518878 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:038879 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
8880 failed_on_default_network_callback_, callback_.callback()));
[email protected]d7d1e50b2013-11-25 22:08:098881
robpercival214763f2016-07-01 23:27:018882 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Charles 'Buck' Krasic71763c9f2018-02-16 02:37:288883 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
8884 EXPECT_TRUE(stream2);
8885 QuicChromiumClientSession* session2 = GetActiveSession(host_port_pair_);
8886 EXPECT_TRUE(HasActiveSession(host_port_pair_));
8887 EXPECT_NE(session, session2);
8888 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session));
8889 EXPECT_TRUE(QuicStreamFactoryPeer::IsLiveSession(factory_.get(), session2));
8890
8891 stream2.reset();
8892 stream.reset();
[email protected]d7d1e50b2013-11-25 22:08:098893
rch37de576c2015-05-17 20:28:178894 EXPECT_TRUE(socket_data.AllReadDataConsumed());
8895 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
8896 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
8897 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
[email protected]d7d1e50b2013-11-25 22:08:098898}
8899
[email protected]1e960032013-12-20 19:00:208900TEST_P(QuicStreamFactoryTest, SharedCryptoConfig) {
jri7046038f2015-10-22 00:29:268901 Initialize();
rch6faa4d42016-01-05 20:48:438902
rch872e00e2016-12-02 02:48:188903 std::vector<string> cannoncial_suffixes;
[email protected]6e12d702013-11-13 00:17:178904 cannoncial_suffixes.push_back(string(".c.youtube.com"));
8905 cannoncial_suffixes.push_back(string(".googlevideo.com"));
[email protected]c49ff182013-09-28 08:33:268906
[email protected]6e12d702013-11-13 00:17:178907 for (unsigned i = 0; i < cannoncial_suffixes.size(); ++i) {
8908 string r1_host_name("r1");
8909 string r2_host_name("r2");
8910 r1_host_name.append(cannoncial_suffixes[i]);
8911 r2_host_name.append(cannoncial_suffixes[i]);
[email protected]b70fdb792013-10-25 19:04:148912
[email protected]bf4ea2f2014-03-10 22:57:538913 HostPortPair host_port_pair1(r1_host_name, 80);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528914 quic::QuicCryptoClientConfig* crypto_config =
jri7046038f2015-10-22 00:29:268915 QuicStreamFactoryPeer::GetCryptoConfig(factory_.get());
Ryan Hamilton4f0b26e2018-06-27 23:52:328916 quic::QuicServerId server_id1(host_port_pair1.host(),
8917 host_port_pair1.port(), privacy_mode_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528918 quic::QuicCryptoClientConfig::CachedState* cached1 =
[email protected]257f24f2014-04-01 09:15:378919 crypto_config->LookupOrCreate(server_id1);
[email protected]6e12d702013-11-13 00:17:178920 EXPECT_FALSE(cached1->proof_valid());
8921 EXPECT_TRUE(cached1->source_address_token().empty());
8922
8923 // Mutate the cached1 to have different data.
8924 // TODO(rtenneti): mutate other members of CachedState.
8925 cached1->set_source_address_token(r1_host_name);
8926 cached1->SetProofValid();
8927
[email protected]bf4ea2f2014-03-10 22:57:538928 HostPortPair host_port_pair2(r2_host_name, 80);
Ryan Hamilton4f0b26e2018-06-27 23:52:328929 quic::QuicServerId server_id2(host_port_pair2.host(),
8930 host_port_pair2.port(), privacy_mode_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528931 quic::QuicCryptoClientConfig::CachedState* cached2 =
[email protected]257f24f2014-04-01 09:15:378932 crypto_config->LookupOrCreate(server_id2);
[email protected]6e12d702013-11-13 00:17:178933 EXPECT_EQ(cached1->source_address_token(), cached2->source_address_token());
8934 EXPECT_TRUE(cached2->proof_valid());
8935 }
[email protected]b70fdb792013-10-25 19:04:148936}
8937
[email protected]1e960032013-12-20 19:00:208938TEST_P(QuicStreamFactoryTest, CryptoConfigWhenProofIsInvalid) {
jri7046038f2015-10-22 00:29:268939 Initialize();
rch872e00e2016-12-02 02:48:188940 std::vector<string> cannoncial_suffixes;
[email protected]6e12d702013-11-13 00:17:178941 cannoncial_suffixes.push_back(string(".c.youtube.com"));
8942 cannoncial_suffixes.push_back(string(".googlevideo.com"));
[email protected]b70fdb792013-10-25 19:04:148943
[email protected]6e12d702013-11-13 00:17:178944 for (unsigned i = 0; i < cannoncial_suffixes.size(); ++i) {
8945 string r3_host_name("r3");
8946 string r4_host_name("r4");
8947 r3_host_name.append(cannoncial_suffixes[i]);
8948 r4_host_name.append(cannoncial_suffixes[i]);
[email protected]b70fdb792013-10-25 19:04:148949
[email protected]bf4ea2f2014-03-10 22:57:538950 HostPortPair host_port_pair1(r3_host_name, 80);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528951 quic::QuicCryptoClientConfig* crypto_config =
jri7046038f2015-10-22 00:29:268952 QuicStreamFactoryPeer::GetCryptoConfig(factory_.get());
Ryan Hamilton4f0b26e2018-06-27 23:52:328953 quic::QuicServerId server_id1(host_port_pair1.host(),
8954 host_port_pair1.port(), privacy_mode_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528955 quic::QuicCryptoClientConfig::CachedState* cached1 =
[email protected]257f24f2014-04-01 09:15:378956 crypto_config->LookupOrCreate(server_id1);
[email protected]6e12d702013-11-13 00:17:178957 EXPECT_FALSE(cached1->proof_valid());
8958 EXPECT_TRUE(cached1->source_address_token().empty());
8959
8960 // Mutate the cached1 to have different data.
8961 // TODO(rtenneti): mutate other members of CachedState.
8962 cached1->set_source_address_token(r3_host_name);
8963 cached1->SetProofInvalid();
8964
[email protected]bf4ea2f2014-03-10 22:57:538965 HostPortPair host_port_pair2(r4_host_name, 80);
Ryan Hamilton4f0b26e2018-06-27 23:52:328966 quic::QuicServerId server_id2(host_port_pair2.host(),
8967 host_port_pair2.port(), privacy_mode_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:528968 quic::QuicCryptoClientConfig::CachedState* cached2 =
[email protected]257f24f2014-04-01 09:15:378969 crypto_config->LookupOrCreate(server_id2);
[email protected]6e12d702013-11-13 00:17:178970 EXPECT_NE(cached1->source_address_token(), cached2->source_address_token());
8971 EXPECT_TRUE(cached2->source_address_token().empty());
8972 EXPECT_FALSE(cached2->proof_valid());
8973 }
[email protected]c49ff182013-09-28 08:33:268974}
8975
rtenneti34dffe752015-02-24 23:27:328976TEST_P(QuicStreamFactoryTest, EnableNotLoadFromDiskCache) {
jri7046038f2015-10-22 00:29:268977 Initialize();
Ryan Hamiltona12722b2017-08-12 02:23:208978 factory_->set_require_confirmation(false);
rch6faa4d42016-01-05 20:48:438979 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
8980 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
8981
jri7046038f2015-10-22 00:29:268982 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
rtenneti34dffe752015-02-24 23:27:328983
Ryan Hamiltonabad59e2019-06-06 04:02:598984 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:368985 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi5f587cc2017-11-21 23:24:178986 socket_data.AddSocketDataToFactory(socket_factory_.get());
rtenneti34dffe752015-02-24 23:27:328987
8988 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:278989 MockCryptoClientStream::ZERO_RTT);
Renjiea0cb4a2c2018-09-26 23:37:308990 host_resolver_->set_synchronous_mode(true);
8991 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
8992 "192.168.0.1", "");
rtenneti34dffe752015-02-24 23:27:328993
zhongyi98d6a9262017-05-19 02:47:458994 QuicStreamRequest request(factory_.get());
Matt Menke26e41542019-06-05 01:09:518995 EXPECT_EQ(OK,
8996 request.Request(
8997 host_port_pair_, version_.transport_version, privacy_mode_,
8998 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
8999 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9000 failed_on_default_network_callback_, callback_.callback()));
rtenneti34dffe752015-02-24 23:27:329001
9002 // If we are waiting for disk cache, we would have posted a task. Verify that
9003 // the CancelWaitForDataReady task hasn't been posted.
9004 ASSERT_EQ(0u, runner_->GetPostedTasks().size());
9005
Yixin Wang7891a39d2017-11-08 20:59:249006 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rtenneti34dffe752015-02-24 23:27:329007 EXPECT_TRUE(stream.get());
rch37de576c2015-05-17 20:28:179008 EXPECT_TRUE(socket_data.AllReadDataConsumed());
9009 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
rtenneti34dffe752015-02-24 23:27:329010}
9011
dmurph44ca4f42016-09-09 20:39:099012TEST_P(QuicStreamFactoryTest, ReducePingTimeoutOnConnectionTimeOutOpenStreams) {
Zhongyi Shi967d2f12019-02-08 20:58:539013 test_params_.quic_reduced_ping_timeout_seconds = 10;
dmurph44ca4f42016-09-09 20:39:099014 Initialize();
9015 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9016 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9017 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9018
9019 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), runner_.get());
zhongyidd1439f62016-09-02 02:02:269020
Ryan Hamiltonabad59e2019-06-06 04:02:599021 MockQuicData socket_data(version_);
zhongyidd1439f62016-09-02 02:02:269022 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:439023 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:179024 socket_data.AddSocketDataToFactory(socket_factory_.get());
zhongyidd1439f62016-09-02 02:02:269025
Ryan Hamiltonabad59e2019-06-06 04:02:599026 MockQuicData socket_data2(version_);
zhongyidd1439f62016-09-02 02:02:269027 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:439028 socket_data2.AddWrite(SYNCHRONOUS,
9029 ConstructInitialSettingsPacket(1, nullptr));
Zhongyi Shi5f587cc2017-11-21 23:24:179030 socket_data2.AddSocketDataToFactory(socket_factory_.get());
zhongyidd1439f62016-09-02 02:02:269031
9032 HostPortPair server2(kServer2HostName, kDefaultServerPort);
9033
9034 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:279035 MockCryptoClientStream::CONFIRM_HANDSHAKE);
Renjiea0cb4a2c2018-09-26 23:37:309036 host_resolver_->set_synchronous_mode(true);
9037 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
9038 "192.168.0.1", "");
9039 host_resolver_->rules()->AddIPLiteralRule(server2.host(), "192.168.0.1", "");
zhongyidd1439f62016-09-02 02:02:269040
9041 // Quic should use default PING timeout when no previous connection times out
9042 // with open stream.
Ryan Hamilton8d9ee76e2018-05-29 23:52:529043 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(quic::kPingTimeoutSecs),
zhongyidd1439f62016-09-02 02:02:269044 QuicStreamFactoryPeer::GetPingTimeout(factory_.get()));
zhongyi98d6a9262017-05-19 02:47:459045 QuicStreamRequest request(factory_.get());
Matt Menke26e41542019-06-05 01:09:519046 EXPECT_EQ(OK,
9047 request.Request(
9048 host_port_pair_, version_.transport_version, privacy_mode_,
9049 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
9050 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9051 failed_on_default_network_callback_, callback_.callback()));
zhongyidd1439f62016-09-02 02:02:269052
9053 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:529054 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(quic::kPingTimeoutSecs),
zhongyidd1439f62016-09-02 02:02:269055 session->connection()->ping_timeout());
9056
Yixin Wang7891a39d2017-11-08 20:59:249057 std::unique_ptr<HttpStream> stream = CreateStream(&request);
zhongyidd1439f62016-09-02 02:02:269058 EXPECT_TRUE(stream.get());
9059 HttpRequestInfo request_info;
Ramin Halavati683bcaa92018-02-14 08:42:399060 request_info.traffic_annotation =
9061 MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS);
Steven Valdezb4ff0412018-01-18 22:39:279062 EXPECT_EQ(OK, stream->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:399063 net_log_, CompletionOnceCallback()));
zhongyidd1439f62016-09-02 02:02:269064
9065 DVLOG(1)
9066 << "Created 1st session and initialized a stream. Now trigger timeout";
Ryan Hamilton8d9ee76e2018-05-29 23:52:529067 session->connection()->CloseConnection(
9068 quic::QUIC_NETWORK_IDLE_TIMEOUT, "test",
9069 quic::ConnectionCloseBehavior::SILENT_CLOSE);
zhongyidd1439f62016-09-02 02:02:269070 // Need to spin the loop now to ensure that
9071 // QuicStreamFactory::OnSessionClosed() runs.
9072 base::RunLoop run_loop;
9073 run_loop.RunUntilIdle();
9074
zhongyidd1439f62016-09-02 02:02:269075 // The first connection times out with open stream, QUIC should reduce initial
9076 // PING time for subsequent connections.
Ryan Hamilton8d9ee76e2018-05-29 23:52:529077 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(10),
zhongyidd1439f62016-09-02 02:02:269078 QuicStreamFactoryPeer::GetPingTimeout(factory_.get()));
9079
9080 // Test two-in-a-row timeouts with open streams.
9081 DVLOG(1) << "Create 2nd session and timeout with open stream";
9082 TestCompletionCallback callback2;
zhongyi98d6a9262017-05-19 02:47:459083 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:519084 EXPECT_EQ(OK,
9085 request2.Request(
9086 server2, version_.transport_version, privacy_mode_,
9087 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
9088 /*cert_verify_flags=*/0, url2_, net_log_, &net_error_details_,
9089 failed_on_default_network_callback_, callback2.callback()));
zhongyidd1439f62016-09-02 02:02:269090 QuicChromiumClientSession* session2 = GetActiveSession(server2);
Ryan Hamilton8d9ee76e2018-05-29 23:52:529091 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(10),
zhongyidd1439f62016-09-02 02:02:269092 session2->connection()->ping_timeout());
9093
Yixin Wang7891a39d2017-11-08 20:59:249094 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
zhongyidd1439f62016-09-02 02:02:269095 EXPECT_TRUE(stream2.get());
Steven Valdezb4ff0412018-01-18 22:39:279096 EXPECT_EQ(OK,
9097 stream2->InitializeStream(&request_info, false, DEFAULT_PRIORITY,
Bence Békya25e3f72018-02-13 21:13:399098 net_log_, CompletionOnceCallback()));
zhongyidd1439f62016-09-02 02:02:269099 session2->connection()->CloseConnection(
Ryan Hamilton8d9ee76e2018-05-29 23:52:529100 quic::QUIC_NETWORK_IDLE_TIMEOUT, "test",
9101 quic::ConnectionCloseBehavior::SILENT_CLOSE);
zhongyidd1439f62016-09-02 02:02:269102 // Need to spin the loop now to ensure that
9103 // QuicStreamFactory::OnSessionClosed() runs.
9104 base::RunLoop run_loop2;
9105 run_loop2.RunUntilIdle();
zhongyidd1439f62016-09-02 02:02:269106
9107 EXPECT_TRUE(socket_data.AllReadDataConsumed());
9108 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
9109 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
9110 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
9111}
9112
tbansal3b966952016-10-25 23:25:149113// Verifies that the QUIC stream factory is initialized correctly.
rtenneticd2aaa15b2015-10-10 20:29:339114TEST_P(QuicStreamFactoryTest, MaybeInitialize) {
tbansal9b1cdf32017-05-10 17:28:399115 VerifyInitialization();
rtenneti8a80a6dc2015-09-21 19:51:139116}
9117
rtennetid073dd22016-08-04 01:58:339118TEST_P(QuicStreamFactoryTest, StartCertVerifyJob) {
9119 Initialize();
9120
Ryan Hamiltonabad59e2019-06-06 04:02:599121 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:369122 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:439123 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:179124 socket_data.AddSocketDataToFactory(socket_factory_.get());
rtennetid073dd22016-08-04 01:58:339125
9126 // Save current state of |race_cert_verification|.
9127 bool race_cert_verification =
9128 QuicStreamFactoryPeer::GetRaceCertVerification(factory_.get());
9129
9130 // Load server config.
9131 HostPortPair host_port_pair(kDefaultServerHostName, kDefaultServerPort);
Ryan Hamilton4f0b26e2018-06-27 23:52:329132 quic::QuicServerId quic_server_id(host_port_pair_.host(),
9133 host_port_pair_.port(),
9134 privacy_mode_ == PRIVACY_MODE_ENABLED);
rtennetid073dd22016-08-04 01:58:339135 QuicStreamFactoryPeer::CacheDummyServerConfig(factory_.get(), quic_server_id);
9136
9137 QuicStreamFactoryPeer::SetRaceCertVerification(factory_.get(), true);
9138 EXPECT_FALSE(HasActiveCertVerifierJob(quic_server_id));
9139
9140 // Start CertVerifyJob.
Ryan Hamilton8d9ee76e2018-05-29 23:52:529141 quic::QuicAsyncStatus status = QuicStreamFactoryPeer::StartCertVerifyJob(
rtennetid073dd22016-08-04 01:58:339142 factory_.get(), quic_server_id, /*cert_verify_flags=*/0, net_log_);
Ryan Hamilton8d9ee76e2018-05-29 23:52:529143 if (status == quic::QUIC_PENDING) {
rtennetid073dd22016-08-04 01:58:339144 // Verify CertVerifierJob has started.
9145 EXPECT_TRUE(HasActiveCertVerifierJob(quic_server_id));
9146
9147 while (HasActiveCertVerifierJob(quic_server_id)) {
9148 base::RunLoop().RunUntilIdle();
9149 }
9150 }
9151 // Verify CertVerifierJob has finished.
9152 EXPECT_FALSE(HasActiveCertVerifierJob(quic_server_id));
9153
9154 // Start a QUIC request.
zhongyi98d6a9262017-05-19 02:47:459155 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:339156 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:039157 request.Request(
Nick Harper23290b82019-05-02 00:02:569158 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:519159 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:039160 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9161 failed_on_default_network_callback_, callback_.callback()));
rtennetid073dd22016-08-04 01:58:339162
9163 EXPECT_EQ(OK, callback_.WaitForResult());
9164
Yixin Wang7891a39d2017-11-08 20:59:249165 std::unique_ptr<HttpStream> stream = CreateStream(&request);
rtennetid073dd22016-08-04 01:58:339166 EXPECT_TRUE(stream.get());
9167
9168 // Restore |race_cert_verification|.
9169 QuicStreamFactoryPeer::SetRaceCertVerification(factory_.get(),
9170 race_cert_verification);
9171
9172 EXPECT_TRUE(socket_data.AllReadDataConsumed());
9173 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
9174
9175 // Verify there are no outstanding CertVerifierJobs after request has
9176 // finished.
9177 EXPECT_FALSE(HasActiveCertVerifierJob(quic_server_id));
9178}
9179
rtenneti1cd3b162015-09-29 02:58:289180TEST_P(QuicStreamFactoryTest, YieldAfterPackets) {
jri7046038f2015-10-22 00:29:269181 Initialize();
Ryan Hamiltona12722b2017-08-12 02:23:209182 factory_->set_require_confirmation(false);
rch6faa4d42016-01-05 20:48:439183 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9184 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
jri7046038f2015-10-22 00:29:269185 QuicStreamFactoryPeer::SetYieldAfterPackets(factory_.get(), 0);
rtenneti1cd3b162015-09-29 02:58:289186
Ryan Hamiltonabad59e2019-06-06 04:02:599187 MockQuicData socket_data(version_);
Fan Yangac867502019-01-28 21:10:239188 socket_data.AddRead(SYNCHRONOUS, ConstructClientConnectionClosePacket(1));
rcha00569732016-08-27 11:09:369189 socket_data.AddRead(ASYNC, OK);
Zhongyi Shi5f587cc2017-11-21 23:24:179190 socket_data.AddSocketDataToFactory(socket_factory_.get());
rtenneti1cd3b162015-09-29 02:58:289191
9192 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:279193 MockCryptoClientStream::ZERO_RTT);
Renjiea0cb4a2c2018-09-26 23:37:309194 host_resolver_->set_synchronous_mode(true);
9195 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
9196 "192.168.0.1", "");
rtenneti1cd3b162015-09-29 02:58:289197
rcha02807b42016-01-29 21:56:159198 // Set up the TaskObserver to verify QuicChromiumPacketReader::StartReading
9199 // posts a task.
rtenneti1cd3b162015-09-29 02:58:289200 // TODO(rtenneti): Change SpdySessionTestTaskObserver to NetTestTaskObserver??
rcha02807b42016-01-29 21:56:159201 SpdySessionTestTaskObserver observer("quic_chromium_packet_reader.cc",
9202 "StartReading");
rtenneti1cd3b162015-09-29 02:58:289203
zhongyi98d6a9262017-05-19 02:47:459204 QuicStreamRequest request(factory_.get());
Matt Menke26e41542019-06-05 01:09:519205 EXPECT_EQ(OK,
9206 request.Request(
9207 host_port_pair_, version_.transport_version, privacy_mode_,
9208 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
9209 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9210 failed_on_default_network_callback_, callback_.callback()));
rtenneti1cd3b162015-09-29 02:58:289211
rcha02807b42016-01-29 21:56:159212 // Call run_loop so that QuicChromiumPacketReader::OnReadComplete() gets
9213 // called.
rtenneti1cd3b162015-09-29 02:58:289214 base::RunLoop run_loop;
9215 run_loop.RunUntilIdle();
9216
9217 // Verify task that the observer's executed_count is 1, which indicates
rcha02807b42016-01-29 21:56:159218 // QuicChromiumPacketReader::StartReading() has posted only one task and
9219 // yielded the read.
rtenneti1cd3b162015-09-29 02:58:289220 EXPECT_EQ(1u, observer.executed_count());
9221
Yixin Wang7891a39d2017-11-08 20:59:249222 std::unique_ptr<HttpStream> stream = CreateStream(&request);
xunjieli2608f9b2016-03-14 13:39:239223 EXPECT_FALSE(stream.get()); // Session is already closed.
rtenneti1cd3b162015-09-29 02:58:289224 EXPECT_TRUE(socket_data.AllReadDataConsumed());
9225 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
9226}
9227
9228TEST_P(QuicStreamFactoryTest, YieldAfterDuration) {
jri7046038f2015-10-22 00:29:269229 Initialize();
Ryan Hamiltona12722b2017-08-12 02:23:209230 factory_->set_require_confirmation(false);
rch6faa4d42016-01-05 20:48:439231 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9232 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
rtenneti1cd3b162015-09-29 02:58:289233 QuicStreamFactoryPeer::SetYieldAfterDuration(
Ryan Hamilton8d9ee76e2018-05-29 23:52:529234 factory_.get(), quic::QuicTime::Delta::FromMilliseconds(-1));
rtenneti1cd3b162015-09-29 02:58:289235
Ryan Hamiltonabad59e2019-06-06 04:02:599236 MockQuicData socket_data(version_);
Fan Yangac867502019-01-28 21:10:239237 socket_data.AddRead(SYNCHRONOUS, ConstructClientConnectionClosePacket(1));
rcha00569732016-08-27 11:09:369238 socket_data.AddRead(ASYNC, OK);
Zhongyi Shi5f587cc2017-11-21 23:24:179239 socket_data.AddSocketDataToFactory(socket_factory_.get());
rtenneti1cd3b162015-09-29 02:58:289240
9241 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:279242 MockCryptoClientStream::ZERO_RTT);
Renjiea0cb4a2c2018-09-26 23:37:309243 host_resolver_->set_synchronous_mode(true);
9244 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
9245 "192.168.0.1", "");
rtenneti1cd3b162015-09-29 02:58:289246
rcha02807b42016-01-29 21:56:159247 // Set up the TaskObserver to verify QuicChromiumPacketReader::StartReading
9248 // posts a task.
rtenneti1cd3b162015-09-29 02:58:289249 // TODO(rtenneti): Change SpdySessionTestTaskObserver to NetTestTaskObserver??
rcha02807b42016-01-29 21:56:159250 SpdySessionTestTaskObserver observer("quic_chromium_packet_reader.cc",
9251 "StartReading");
rtenneti1cd3b162015-09-29 02:58:289252
zhongyi98d6a9262017-05-19 02:47:459253 QuicStreamRequest request(factory_.get());
Matt Menke26e41542019-06-05 01:09:519254 EXPECT_EQ(OK,
9255 request.Request(
9256 host_port_pair_, version_.transport_version, privacy_mode_,
9257 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
9258 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9259 failed_on_default_network_callback_, callback_.callback()));
rtenneti1cd3b162015-09-29 02:58:289260
rcha02807b42016-01-29 21:56:159261 // Call run_loop so that QuicChromiumPacketReader::OnReadComplete() gets
9262 // called.
rtenneti1cd3b162015-09-29 02:58:289263 base::RunLoop run_loop;
9264 run_loop.RunUntilIdle();
9265
9266 // Verify task that the observer's executed_count is 1, which indicates
rcha02807b42016-01-29 21:56:159267 // QuicChromiumPacketReader::StartReading() has posted only one task and
9268 // yielded the read.
rtenneti1cd3b162015-09-29 02:58:289269 EXPECT_EQ(1u, observer.executed_count());
9270
Yixin Wang7891a39d2017-11-08 20:59:249271 std::unique_ptr<HttpStream> stream = CreateStream(&request);
xunjieli2608f9b2016-03-14 13:39:239272 EXPECT_FALSE(stream.get()); // Session is already closed.
rtenneti1cd3b162015-09-29 02:58:289273 EXPECT_TRUE(socket_data.AllReadDataConsumed());
9274 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
9275}
9276
ckrasic3865ee0f2016-02-29 22:04:569277TEST_P(QuicStreamFactoryTest, ServerPushSessionAffinity) {
9278 Initialize();
9279 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9280 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9281
Ryan Hamiltonabad59e2019-06-06 04:02:599282 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:369283 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:439284 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:179285 socket_data.AddSocketDataToFactory(socket_factory_.get());
ckrasic3865ee0f2016-02-29 22:04:569286
zhongyi98d6a9262017-05-19 02:47:459287 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:339288 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:039289 request.Request(
Nick Harper23290b82019-05-02 00:02:569290 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:519291 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:039292 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9293 failed_on_default_network_callback_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:569294
robpercival214763f2016-07-01 23:27:019295 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:249296 std::unique_ptr<HttpStream> stream = CreateStream(&request);
ckrasic3865ee0f2016-02-29 22:04:569297 EXPECT_TRUE(stream.get());
9298
9299 EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumPushStreamsCreated(factory_.get()));
9300
bnc5fdc07162016-05-23 17:36:039301 string url = "https://www.example.org/";
ckrasic3865ee0f2016-02-29 22:04:569302
bnc912a04b2016-04-20 14:19:509303 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
ckrasic3865ee0f2016-02-29 22:04:569304
Ryan Hamilton8d9ee76e2018-05-29 23:52:529305 quic::QuicClientPromisedInfo promised(
Fan Yang32c5a112018-12-10 20:06:339306 session, GetNthServerInitiatedUnidirectionalStreamId(0), kDefaultUrl);
ckrasic3865ee0f2016-02-29 22:04:569307 (*QuicStreamFactoryPeer::GetPushPromiseIndex(factory_.get())
bnc3d9035b32016-06-30 18:18:489308 ->promised_by_url())[kDefaultUrl] = &promised;
ckrasic3865ee0f2016-02-29 22:04:569309
zhongyi98d6a9262017-05-19 02:47:459310 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:519311 EXPECT_EQ(OK,
9312 request2.Request(
9313 host_port_pair_, version_.transport_version, privacy_mode_,
9314 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
9315 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9316 failed_on_default_network_callback_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:569317
9318 EXPECT_EQ(1, QuicStreamFactoryPeer::GetNumPushStreamsCreated(factory_.get()));
9319}
9320
9321TEST_P(QuicStreamFactoryTest, ServerPushPrivacyModeMismatch) {
9322 Initialize();
9323 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9324 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9325 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9326
Ryan Hamiltonabad59e2019-06-06 04:02:599327 MockQuicData socket_data1(version_);
rcha00569732016-08-27 11:09:369328 socket_data1.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:439329 socket_data1.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
9330 socket_data1.AddWrite(
Fan Yang32c5a112018-12-10 20:06:339331 SYNCHRONOUS, client_maker_.MakeRstPacket(
9332 2, true, GetNthServerInitiatedUnidirectionalStreamId(0),
9333 quic::QUIC_STREAM_CANCELLED));
Zhongyi Shi5f587cc2017-11-21 23:24:179334 socket_data1.AddSocketDataToFactory(socket_factory_.get());
ckrasic3865ee0f2016-02-29 22:04:569335
Ryan Hamiltonabad59e2019-06-06 04:02:599336 MockQuicData socket_data2(version_);
rcha00569732016-08-27 11:09:369337 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:439338 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:179339 socket_data2.AddSocketDataToFactory(socket_factory_.get());
ckrasic3865ee0f2016-02-29 22:04:569340
zhongyi98d6a9262017-05-19 02:47:459341 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:339342 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:039343 request.Request(
Nick Harper23290b82019-05-02 00:02:569344 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:519345 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:039346 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9347 failed_on_default_network_callback_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:569348
robpercival214763f2016-07-01 23:27:019349 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:249350 std::unique_ptr<HttpStream> stream = CreateStream(&request);
ckrasic3865ee0f2016-02-29 22:04:569351 EXPECT_TRUE(stream.get());
9352
9353 EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumPushStreamsCreated(factory_.get()));
9354
bnc5fdc07162016-05-23 17:36:039355 string url = "https://www.example.org/";
bnc912a04b2016-04-20 14:19:509356 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
ckrasic3865ee0f2016-02-29 22:04:569357
Ryan Hamilton8d9ee76e2018-05-29 23:52:529358 quic::QuicClientPromisedInfo promised(
Fan Yang32c5a112018-12-10 20:06:339359 session, GetNthServerInitiatedUnidirectionalStreamId(0), kDefaultUrl);
ckrasic3865ee0f2016-02-29 22:04:569360
Ryan Hamilton8d9ee76e2018-05-29 23:52:529361 quic::QuicClientPushPromiseIndex* index =
ckrasic3865ee0f2016-02-29 22:04:569362 QuicStreamFactoryPeer::GetPushPromiseIndex(factory_.get());
9363
bnc3d9035b32016-06-30 18:18:489364 (*index->promised_by_url())[kDefaultUrl] = &promised;
9365 EXPECT_EQ(index->GetPromised(kDefaultUrl), &promised);
ckrasic3865ee0f2016-02-29 22:04:569366
9367 // Doing the request should not use the push stream, but rather
9368 // cancel it because the privacy modes do not match.
zhongyi98d6a9262017-05-19 02:47:459369 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:519370 EXPECT_EQ(
9371 ERR_IO_PENDING,
9372 request2.Request(
9373 host_port_pair_, version_.transport_version, PRIVACY_MODE_ENABLED,
9374 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
9375 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9376 failed_on_default_network_callback_, callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:569377
9378 EXPECT_EQ(0, QuicStreamFactoryPeer::GetNumPushStreamsCreated(factory_.get()));
bnc3d9035b32016-06-30 18:18:489379 EXPECT_EQ(index->GetPromised(kDefaultUrl), nullptr);
ckrasic3865ee0f2016-02-29 22:04:569380
robpercival214763f2016-07-01 23:27:019381 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:249382 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
ckrasic3865ee0f2016-02-29 22:04:569383 EXPECT_TRUE(stream2.get());
9384
9385 EXPECT_TRUE(socket_data1.AllReadDataConsumed());
9386 EXPECT_TRUE(socket_data1.AllWriteDataConsumed());
9387 EXPECT_TRUE(socket_data2.AllReadDataConsumed());
9388 EXPECT_TRUE(socket_data2.AllWriteDataConsumed());
9389}
9390
Ryan Hamilton8d9ee76e2018-05-29 23:52:529391// Pool to existing session with matching quic::QuicServerId
bnc359ed2a2016-04-29 20:43:459392// even if destination is different.
9393TEST_P(QuicStreamFactoryTest, PoolByOrigin) {
9394 Initialize();
9395
9396 HostPortPair destination1("first.example.com", 443);
9397 HostPortPair destination2("second.example.com", 443);
9398
9399 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9400 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9401
Ryan Hamiltonabad59e2019-06-06 04:02:599402 MockQuicData socket_data(version_);
rcha00569732016-08-27 11:09:369403 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:439404 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:179405 socket_data.AddSocketDataToFactory(socket_factory_.get());
bnc359ed2a2016-04-29 20:43:459406
zhongyi98d6a9262017-05-19 02:47:459407 QuicStreamRequest request1(factory_.get());
Nick Harper23290b82019-05-02 00:02:569408 EXPECT_EQ(ERR_IO_PENDING,
9409 request1.Request(
9410 destination1, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:519411 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Nick Harper23290b82019-05-02 00:02:569412 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9413 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:019414 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:249415 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
bnc359ed2a2016-04-29 20:43:459416 EXPECT_TRUE(stream1.get());
9417 EXPECT_TRUE(HasActiveSession(host_port_pair_));
9418
9419 // Second request returns synchronously because it pools to existing session.
9420 TestCompletionCallback callback2;
zhongyi98d6a9262017-05-19 02:47:459421 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:519422 EXPECT_EQ(OK,
9423 request2.Request(
9424 destination2, version_.transport_version, privacy_mode_,
9425 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
9426 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9427 failed_on_default_network_callback_, callback2.callback()));
Yixin Wang7891a39d2017-11-08 20:59:249428 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
bnc359ed2a2016-04-29 20:43:459429 EXPECT_TRUE(stream2.get());
9430
rchf0b18c8a2017-05-05 19:31:579431 QuicChromiumClientSession::Handle* session1 =
9432 QuicHttpStreamPeer::GetSessionHandle(stream1.get());
9433 QuicChromiumClientSession::Handle* session2 =
9434 QuicHttpStreamPeer::GetSessionHandle(stream2.get());
9435 EXPECT_TRUE(session1->SharesSameSession(*session2));
Ryan Hamilton4f0b26e2018-06-27 23:52:329436 EXPECT_EQ(quic::QuicServerId(host_port_pair_.host(), host_port_pair_.port(),
9437 privacy_mode_ == PRIVACY_MODE_ENABLED),
bnc359ed2a2016-04-29 20:43:459438 session1->server_id());
9439
9440 EXPECT_TRUE(socket_data.AllReadDataConsumed());
9441 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
9442}
9443
9444class QuicStreamFactoryWithDestinationTest
9445 : public QuicStreamFactoryTestBase,
9446 public ::testing::TestWithParam<PoolingTestParams> {
9447 protected:
9448 QuicStreamFactoryWithDestinationTest()
Yixin Wang079ad542018-01-11 04:06:059449 : QuicStreamFactoryTestBase(
9450 GetParam().version,
9451 GetParam().client_headers_include_h2_stream_dependency),
bnc359ed2a2016-04-29 20:43:459452 destination_type_(GetParam().destination_type),
9453 hanging_read_(SYNCHRONOUS, ERR_IO_PENDING, 0) {}
9454
9455 HostPortPair GetDestination() {
9456 switch (destination_type_) {
9457 case SAME_AS_FIRST:
9458 return origin1_;
9459 case SAME_AS_SECOND:
9460 return origin2_;
9461 case DIFFERENT:
9462 return HostPortPair(kDifferentHostname, 443);
9463 default:
9464 NOTREACHED();
9465 return HostPortPair();
9466 }
9467 }
9468
9469 void AddHangingSocketData() {
9470 std::unique_ptr<SequencedSocketData> sequenced_socket_data(
Ryan Sleevib8d7ea02018-05-07 20:01:019471 new SequencedSocketData(base::make_span(&hanging_read_, 1),
9472 base::span<MockWrite>()));
Zhongyi Shi5f587cc2017-11-21 23:24:179473 socket_factory_->AddSocketDataProvider(sequenced_socket_data.get());
bnc359ed2a2016-04-29 20:43:459474 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data));
9475 }
9476
9477 bool AllDataConsumed() {
9478 for (const auto& socket_data_ptr : sequenced_socket_data_vector_) {
9479 if (!socket_data_ptr->AllReadDataConsumed() ||
9480 !socket_data_ptr->AllWriteDataConsumed()) {
9481 return false;
9482 }
9483 }
9484 return true;
9485 }
9486
9487 DestinationType destination_type_;
9488 HostPortPair origin1_;
9489 HostPortPair origin2_;
9490 MockRead hanging_read_;
rch872e00e2016-12-02 02:48:189491 std::vector<std::unique_ptr<SequencedSocketData>>
9492 sequenced_socket_data_vector_;
bnc359ed2a2016-04-29 20:43:459493};
9494
Victor Costane635086f2019-01-27 05:20:309495INSTANTIATE_TEST_SUITE_P(VersionIncludeStreamDependencySequence,
9496 QuicStreamFactoryWithDestinationTest,
9497 ::testing::ValuesIn(GetPoolingTestParams()));
bnc359ed2a2016-04-29 20:43:459498
9499// A single QUIC request fails because the certificate does not match the origin
9500// hostname, regardless of whether it matches the alternative service hostname.
9501TEST_P(QuicStreamFactoryWithDestinationTest, InvalidCertificate) {
9502 if (destination_type_ == DIFFERENT)
9503 return;
9504
9505 Initialize();
9506
9507 GURL url("https://mail.example.com/");
9508 origin1_ = HostPortPair::FromURL(url);
9509
9510 // Not used for requests, but this provides a test case where the certificate
9511 // is valid for the hostname of the alternative service.
9512 origin2_ = HostPortPair("mail.example.org", 433);
9513
9514 HostPortPair destination = GetDestination();
9515
9516 scoped_refptr<X509Certificate> cert(
9517 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:249518 ASSERT_FALSE(cert->VerifyNameMatch(origin1_.host()));
9519 ASSERT_TRUE(cert->VerifyNameMatch(origin2_.host()));
bnc359ed2a2016-04-29 20:43:459520
9521 ProofVerifyDetailsChromium verify_details;
9522 verify_details.cert_verify_result.verified_cert = cert;
9523 verify_details.cert_verify_result.is_issued_by_known_root = true;
9524 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9525
9526 AddHangingSocketData();
9527
zhongyi98d6a9262017-05-19 02:47:459528 QuicStreamRequest request(factory_.get());
Nick Harper23290b82019-05-02 00:02:569529 EXPECT_EQ(ERR_IO_PENDING,
9530 request.Request(
9531 destination, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:519532 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Nick Harper23290b82019-05-02 00:02:569533 /*cert_verify_flags=*/0, url, net_log_, &net_error_details_,
9534 failed_on_default_network_callback_, callback_.callback()));
bnc359ed2a2016-04-29 20:43:459535
robpercival214763f2016-07-01 23:27:019536 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_QUIC_HANDSHAKE_FAILED));
bnc359ed2a2016-04-29 20:43:459537
9538 EXPECT_TRUE(AllDataConsumed());
9539}
9540
9541// QuicStreamRequest is pooled based on |destination| if certificate matches.
9542TEST_P(QuicStreamFactoryWithDestinationTest, SharedCertificate) {
9543 Initialize();
9544
9545 GURL url1("https://www.example.org/");
9546 GURL url2("https://mail.example.org/");
9547 origin1_ = HostPortPair::FromURL(url1);
9548 origin2_ = HostPortPair::FromURL(url2);
9549
9550 HostPortPair destination = GetDestination();
9551
9552 scoped_refptr<X509Certificate> cert(
9553 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:249554 ASSERT_TRUE(cert->VerifyNameMatch(origin1_.host()));
9555 ASSERT_TRUE(cert->VerifyNameMatch(origin2_.host()));
9556 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:459557
9558 ProofVerifyDetailsChromium verify_details;
9559 verify_details.cert_verify_result.verified_cert = cert;
9560 verify_details.cert_verify_result.is_issued_by_known_root = true;
9561 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9562
fayang3bcb8b502016-12-07 21:44:379563 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:529564 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:369565 client_maker_.MakeInitialSettingsPacket(1, nullptr));
bnceb9aa7112017-01-05 01:03:469566 MockWrite writes[] = {MockWrite(SYNCHRONOUS, settings_packet->data(),
9567 settings_packet->length(), 1)};
fayang3bcb8b502016-12-07 21:44:379568 std::unique_ptr<SequencedSocketData> sequenced_socket_data(
Ryan Sleevib8d7ea02018-05-07 20:01:019569 new SequencedSocketData(reads, writes));
Zhongyi Shi5f587cc2017-11-21 23:24:179570 socket_factory_->AddSocketDataProvider(sequenced_socket_data.get());
fayang3bcb8b502016-12-07 21:44:379571 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data));
bnc359ed2a2016-04-29 20:43:459572
zhongyi98d6a9262017-05-19 02:47:459573 QuicStreamRequest request1(factory_.get());
Nick Harper23290b82019-05-02 00:02:569574 EXPECT_EQ(ERR_IO_PENDING,
9575 request1.Request(
9576 destination, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:519577 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Nick Harper23290b82019-05-02 00:02:569578 /*cert_verify_flags=*/0, url1, net_log_, &net_error_details_,
9579 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:019580 EXPECT_THAT(callback_.WaitForResult(), IsOk());
fayang3bcb8b502016-12-07 21:44:379581
Yixin Wang7891a39d2017-11-08 20:59:249582 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
bnc359ed2a2016-04-29 20:43:459583 EXPECT_TRUE(stream1.get());
9584 EXPECT_TRUE(HasActiveSession(origin1_));
9585
9586 // Second request returns synchronously because it pools to existing session.
9587 TestCompletionCallback callback2;
zhongyi98d6a9262017-05-19 02:47:459588 QuicStreamRequest request2(factory_.get());
Matt Menke26e41542019-06-05 01:09:519589 EXPECT_EQ(OK,
9590 request2.Request(
9591 destination, version_.transport_version, privacy_mode_,
9592 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
9593 /*cert_verify_flags=*/0, url2, net_log_, &net_error_details_,
9594 failed_on_default_network_callback_, callback2.callback()));
Yixin Wang7891a39d2017-11-08 20:59:249595 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
bnc359ed2a2016-04-29 20:43:459596 EXPECT_TRUE(stream2.get());
9597
rchf0b18c8a2017-05-05 19:31:579598 QuicChromiumClientSession::Handle* session1 =
9599 QuicHttpStreamPeer::GetSessionHandle(stream1.get());
9600 QuicChromiumClientSession::Handle* session2 =
9601 QuicHttpStreamPeer::GetSessionHandle(stream2.get());
9602 EXPECT_TRUE(session1->SharesSameSession(*session2));
bnc359ed2a2016-04-29 20:43:459603
Ryan Hamilton4f0b26e2018-06-27 23:52:329604 EXPECT_EQ(quic::QuicServerId(origin1_.host(), origin1_.port(),
9605 privacy_mode_ == PRIVACY_MODE_ENABLED),
9606 session1->server_id());
bnc359ed2a2016-04-29 20:43:459607
9608 EXPECT_TRUE(AllDataConsumed());
9609}
9610
bnc47eba7d2016-07-01 00:43:389611// QuicStreamRequest is not pooled if PrivacyMode differs.
9612TEST_P(QuicStreamFactoryWithDestinationTest, DifferentPrivacyMode) {
9613 Initialize();
9614
9615 GURL url1("https://www.example.org/");
9616 GURL url2("https://mail.example.org/");
9617 origin1_ = HostPortPair::FromURL(url1);
9618 origin2_ = HostPortPair::FromURL(url2);
9619
9620 HostPortPair destination = GetDestination();
9621
9622 scoped_refptr<X509Certificate> cert(
9623 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:249624 ASSERT_TRUE(cert->VerifyNameMatch(origin1_.host()));
9625 ASSERT_TRUE(cert->VerifyNameMatch(origin2_.host()));
9626 ASSERT_FALSE(cert->VerifyNameMatch(kDifferentHostname));
bnc47eba7d2016-07-01 00:43:389627
9628 ProofVerifyDetailsChromium verify_details1;
9629 verify_details1.cert_verify_result.verified_cert = cert;
9630 verify_details1.cert_verify_result.is_issued_by_known_root = true;
9631 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
9632
9633 ProofVerifyDetailsChromium verify_details2;
9634 verify_details2.cert_verify_result.verified_cert = cert;
9635 verify_details2.cert_verify_result.is_issued_by_known_root = true;
9636 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
9637
fayang3bcb8b502016-12-07 21:44:379638 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:529639 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:369640 client_maker_.MakeInitialSettingsPacket(1, nullptr));
bnceb9aa7112017-01-05 01:03:469641 MockWrite writes[] = {MockWrite(SYNCHRONOUS, settings_packet->data(),
9642 settings_packet->length(), 1)};
fayang3bcb8b502016-12-07 21:44:379643 std::unique_ptr<SequencedSocketData> sequenced_socket_data(
Ryan Sleevib8d7ea02018-05-07 20:01:019644 new SequencedSocketData(reads, writes));
Zhongyi Shi5f587cc2017-11-21 23:24:179645 socket_factory_->AddSocketDataProvider(sequenced_socket_data.get());
fayang3bcb8b502016-12-07 21:44:379646 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data));
9647 std::unique_ptr<SequencedSocketData> sequenced_socket_data1(
Ryan Sleevib8d7ea02018-05-07 20:01:019648 new SequencedSocketData(reads, writes));
Zhongyi Shi5f587cc2017-11-21 23:24:179649 socket_factory_->AddSocketDataProvider(sequenced_socket_data1.get());
fayang3bcb8b502016-12-07 21:44:379650 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data1));
bnc47eba7d2016-07-01 00:43:389651
zhongyi98d6a9262017-05-19 02:47:459652 QuicStreamRequest request1(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:339653 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:039654 request1.Request(
Nick Harper23290b82019-05-02 00:02:569655 destination, version_.transport_version, PRIVACY_MODE_DISABLED,
Matt Menke26e41542019-06-05 01:09:519656 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:039657 /*cert_verify_flags=*/0, url1, net_log_, &net_error_details_,
9658 failed_on_default_network_callback_, callback_.callback()));
bnc47eba7d2016-07-01 00:43:389659 EXPECT_EQ(OK, callback_.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:249660 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
bnc47eba7d2016-07-01 00:43:389661 EXPECT_TRUE(stream1.get());
9662 EXPECT_TRUE(HasActiveSession(origin1_));
9663
9664 TestCompletionCallback callback2;
zhongyi98d6a9262017-05-19 02:47:459665 QuicStreamRequest request2(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:339666 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:039667 request2.Request(
Nick Harper23290b82019-05-02 00:02:569668 destination, version_.transport_version, PRIVACY_MODE_ENABLED,
Matt Menke26e41542019-06-05 01:09:519669 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:039670 /*cert_verify_flags=*/0, url2, net_log_, &net_error_details_,
9671 failed_on_default_network_callback_, callback2.callback()));
bnc47eba7d2016-07-01 00:43:389672 EXPECT_EQ(OK, callback2.WaitForResult());
Yixin Wang7891a39d2017-11-08 20:59:249673 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
bnc47eba7d2016-07-01 00:43:389674 EXPECT_TRUE(stream2.get());
9675
9676 // |request2| does not pool to the first session, because PrivacyMode does not
9677 // match. Instead, another session is opened to the same destination, but
Ryan Hamilton8d9ee76e2018-05-29 23:52:529678 // with a different quic::QuicServerId.
rchf0b18c8a2017-05-05 19:31:579679 QuicChromiumClientSession::Handle* session1 =
9680 QuicHttpStreamPeer::GetSessionHandle(stream1.get());
9681 QuicChromiumClientSession::Handle* session2 =
9682 QuicHttpStreamPeer::GetSessionHandle(stream2.get());
9683 EXPECT_FALSE(session1->SharesSameSession(*session2));
bnc47eba7d2016-07-01 00:43:389684
Ryan Hamilton4f0b26e2018-06-27 23:52:329685 EXPECT_EQ(quic::QuicServerId(origin1_.host(), origin1_.port(), false),
bnc47eba7d2016-07-01 00:43:389686 session1->server_id());
Ryan Hamilton4f0b26e2018-06-27 23:52:329687 EXPECT_EQ(quic::QuicServerId(origin2_.host(), origin2_.port(), true),
bnc47eba7d2016-07-01 00:43:389688 session2->server_id());
9689
9690 EXPECT_TRUE(AllDataConsumed());
9691}
9692
bnc359ed2a2016-04-29 20:43:459693// QuicStreamRequest is not pooled if certificate does not match its origin.
9694TEST_P(QuicStreamFactoryWithDestinationTest, DisjointCertificate) {
9695 Initialize();
9696
9697 GURL url1("https://news.example.org/");
9698 GURL url2("https://mail.example.com/");
9699 origin1_ = HostPortPair::FromURL(url1);
9700 origin2_ = HostPortPair::FromURL(url2);
9701
9702 HostPortPair destination = GetDestination();
9703
9704 scoped_refptr<X509Certificate> cert1(
9705 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
Ryan Sleevidef35f62018-01-23 21:12:249706 ASSERT_TRUE(cert1->VerifyNameMatch(origin1_.host()));
9707 ASSERT_FALSE(cert1->VerifyNameMatch(origin2_.host()));
9708 ASSERT_FALSE(cert1->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:459709
9710 ProofVerifyDetailsChromium verify_details1;
9711 verify_details1.cert_verify_result.verified_cert = cert1;
9712 verify_details1.cert_verify_result.is_issued_by_known_root = true;
9713 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details1);
9714
9715 scoped_refptr<X509Certificate> cert2(
9716 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
Ryan Sleevidef35f62018-01-23 21:12:249717 ASSERT_TRUE(cert2->VerifyNameMatch(origin2_.host()));
9718 ASSERT_FALSE(cert2->VerifyNameMatch(kDifferentHostname));
bnc359ed2a2016-04-29 20:43:459719
9720 ProofVerifyDetailsChromium verify_details2;
9721 verify_details2.cert_verify_result.verified_cert = cert2;
9722 verify_details2.cert_verify_result.is_issued_by_known_root = true;
9723 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details2);
9724
fayang3bcb8b502016-12-07 21:44:379725 MockRead reads[] = {MockRead(SYNCHRONOUS, ERR_IO_PENDING, 0)};
Ryan Hamilton8d9ee76e2018-05-29 23:52:529726 std::unique_ptr<quic::QuicEncryptedPacket> settings_packet(
rch5cb522462017-04-25 20:18:369727 client_maker_.MakeInitialSettingsPacket(1, nullptr));
bnceb9aa7112017-01-05 01:03:469728 MockWrite writes[] = {MockWrite(SYNCHRONOUS, settings_packet->data(),
9729 settings_packet->length(), 1)};
fayang3bcb8b502016-12-07 21:44:379730 std::unique_ptr<SequencedSocketData> sequenced_socket_data(
Ryan Sleevib8d7ea02018-05-07 20:01:019731 new SequencedSocketData(reads, writes));
Zhongyi Shi5f587cc2017-11-21 23:24:179732 socket_factory_->AddSocketDataProvider(sequenced_socket_data.get());
fayang3bcb8b502016-12-07 21:44:379733 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data));
9734 std::unique_ptr<SequencedSocketData> sequenced_socket_data1(
Ryan Sleevib8d7ea02018-05-07 20:01:019735 new SequencedSocketData(reads, writes));
Zhongyi Shi5f587cc2017-11-21 23:24:179736 socket_factory_->AddSocketDataProvider(sequenced_socket_data1.get());
fayang3bcb8b502016-12-07 21:44:379737 sequenced_socket_data_vector_.push_back(std::move(sequenced_socket_data1));
bnc359ed2a2016-04-29 20:43:459738
zhongyi98d6a9262017-05-19 02:47:459739 QuicStreamRequest request1(factory_.get());
Nick Harper23290b82019-05-02 00:02:569740 EXPECT_EQ(ERR_IO_PENDING,
9741 request1.Request(
9742 destination, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:519743 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Nick Harper23290b82019-05-02 00:02:569744 /*cert_verify_flags=*/0, url1, net_log_, &net_error_details_,
9745 failed_on_default_network_callback_, callback_.callback()));
robpercival214763f2016-07-01 23:27:019746 EXPECT_THAT(callback_.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:249747 std::unique_ptr<HttpStream> stream1 = CreateStream(&request1);
bnc359ed2a2016-04-29 20:43:459748 EXPECT_TRUE(stream1.get());
9749 EXPECT_TRUE(HasActiveSession(origin1_));
9750
9751 TestCompletionCallback callback2;
zhongyi98d6a9262017-05-19 02:47:459752 QuicStreamRequest request2(factory_.get());
Nick Harper23290b82019-05-02 00:02:569753 EXPECT_EQ(ERR_IO_PENDING,
9754 request2.Request(
9755 destination, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:519756 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Nick Harper23290b82019-05-02 00:02:569757 /*cert_verify_flags=*/0, url2, net_log_, &net_error_details_,
9758 failed_on_default_network_callback_, callback2.callback()));
robpercival214763f2016-07-01 23:27:019759 EXPECT_THAT(callback2.WaitForResult(), IsOk());
Yixin Wang7891a39d2017-11-08 20:59:249760 std::unique_ptr<HttpStream> stream2 = CreateStream(&request2);
bnc359ed2a2016-04-29 20:43:459761 EXPECT_TRUE(stream2.get());
9762
9763 // |request2| does not pool to the first session, because the certificate does
9764 // not match. Instead, another session is opened to the same destination, but
Ryan Hamilton8d9ee76e2018-05-29 23:52:529765 // with a different quic::QuicServerId.
rchf0b18c8a2017-05-05 19:31:579766 QuicChromiumClientSession::Handle* session1 =
9767 QuicHttpStreamPeer::GetSessionHandle(stream1.get());
9768 QuicChromiumClientSession::Handle* session2 =
9769 QuicHttpStreamPeer::GetSessionHandle(stream2.get());
9770 EXPECT_FALSE(session1->SharesSameSession(*session2));
bnc359ed2a2016-04-29 20:43:459771
Ryan Hamilton4f0b26e2018-06-27 23:52:329772 EXPECT_EQ(quic::QuicServerId(origin1_.host(), origin1_.port(),
9773 privacy_mode_ == PRIVACY_MODE_ENABLED),
9774 session1->server_id());
9775 EXPECT_EQ(quic::QuicServerId(origin2_.host(), origin2_.port(),
9776 privacy_mode_ == PRIVACY_MODE_ENABLED),
9777 session2->server_id());
bnc359ed2a2016-04-29 20:43:459778
9779 EXPECT_TRUE(AllDataConsumed());
9780}
9781
msramek992625ec2016-08-04 18:33:589782// This test verifies that QuicStreamFactory::ClearCachedStatesInCryptoConfig
9783// correctly transform an origin filter to a ServerIdFilter. Whether the
9784// deletion itself works correctly is tested in QuicCryptoClientConfigTest.
9785TEST_P(QuicStreamFactoryTest, ClearCachedStatesInCryptoConfig) {
9786 Initialize();
Ryan Hamilton8d9ee76e2018-05-29 23:52:529787 quic::QuicCryptoClientConfig* crypto_config =
msramek992625ec2016-08-04 18:33:589788 QuicStreamFactoryPeer::GetCryptoConfig(factory_.get());
9789
9790 struct TestCase {
9791 TestCase(const std::string& host,
9792 int port,
9793 PrivacyMode privacy_mode,
Ryan Hamilton8d9ee76e2018-05-29 23:52:529794 quic::QuicCryptoClientConfig* crypto_config)
msramek992625ec2016-08-04 18:33:589795 : server_id(host, port, privacy_mode),
9796 state(crypto_config->LookupOrCreate(server_id)) {
rch872e00e2016-12-02 02:48:189797 std::vector<string> certs(1);
msramek992625ec2016-08-04 18:33:589798 certs[0] = "cert";
9799 state->SetProof(certs, "cert_sct", "chlo_hash", "signature");
9800 state->set_source_address_token("TOKEN");
9801 state->SetProofValid();
9802
9803 EXPECT_FALSE(state->certs().empty());
9804 }
9805
Ryan Hamilton8d9ee76e2018-05-29 23:52:529806 quic::QuicServerId server_id;
9807 quic::QuicCryptoClientConfig::CachedState* state;
msramek992625ec2016-08-04 18:33:589808 } test_cases[] = {
9809 TestCase("www.google.com", 443, privacy_mode_, crypto_config),
9810 TestCase("www.example.com", 443, privacy_mode_, crypto_config),
9811 TestCase("www.example.com", 4433, privacy_mode_, crypto_config)};
9812
9813 // Clear cached states for the origin https://www.example.com:4433.
9814 GURL origin("https://www.example.com:4433");
csharrisonebeca8e2016-10-18 02:35:369815 factory_->ClearCachedStatesInCryptoConfig(base::Bind(
9816 static_cast<bool (*)(const GURL&, const GURL&)>(::operator==), origin));
msramek992625ec2016-08-04 18:33:589817 EXPECT_FALSE(test_cases[0].state->certs().empty());
9818 EXPECT_FALSE(test_cases[1].state->certs().empty());
9819 EXPECT_TRUE(test_cases[2].state->certs().empty());
9820
9821 // Clear all cached states.
9822 factory_->ClearCachedStatesInCryptoConfig(
9823 base::Callback<bool(const GURL&)>());
9824 EXPECT_TRUE(test_cases[0].state->certs().empty());
9825 EXPECT_TRUE(test_cases[1].state->certs().empty());
9826 EXPECT_TRUE(test_cases[2].state->certs().empty());
9827}
9828
Yixin Wang46a425f2017-08-10 23:02:209829// Passes connection options and client connection options to QuicStreamFactory,
Ryan Hamilton8d9ee76e2018-05-29 23:52:529830// then checks that its internal quic::QuicConfig is correct.
Yixin Wang46a425f2017-08-10 23:02:209831TEST_P(QuicStreamFactoryTest, ConfigConnectionOptions) {
Zhongyi Shi967d2f12019-02-08 20:58:539832 test_params_.quic_connection_options.push_back(quic::kTIME);
9833 test_params_.quic_connection_options.push_back(quic::kTBBR);
9834 test_params_.quic_connection_options.push_back(quic::kREJ);
Yixin Wang46a425f2017-08-10 23:02:209835
Zhongyi Shi967d2f12019-02-08 20:58:539836 test_params_.quic_client_connection_options.push_back(quic::kTBBR);
9837 test_params_.quic_client_connection_options.push_back(quic::k1RTT);
Yixin Wang46a425f2017-08-10 23:02:209838
9839 Initialize();
9840
Ryan Hamilton8d9ee76e2018-05-29 23:52:529841 const quic::QuicConfig* config =
9842 QuicStreamFactoryPeer::GetConfig(factory_.get());
Zhongyi Shi967d2f12019-02-08 20:58:539843 EXPECT_EQ(test_params_.quic_connection_options,
9844 config->SendConnectionOptions());
Yixin Wang46a425f2017-08-10 23:02:209845 EXPECT_TRUE(config->HasClientRequestedIndependentOption(
Ryan Hamilton8d9ee76e2018-05-29 23:52:529846 quic::kTBBR, quic::Perspective::IS_CLIENT));
Yixin Wang46a425f2017-08-10 23:02:209847 EXPECT_TRUE(config->HasClientRequestedIndependentOption(
Ryan Hamilton8d9ee76e2018-05-29 23:52:529848 quic::k1RTT, quic::Perspective::IS_CLIENT));
Yixin Wang46a425f2017-08-10 23:02:209849}
9850
Yixin Wang247ea642017-11-15 01:15:509851// Verifies that the host resolver uses the request priority passed to
9852// QuicStreamRequest::Request().
9853TEST_P(QuicStreamFactoryTest, HostResolverUsesRequestPriority) {
9854 Initialize();
9855 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9856 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9857
Ryan Hamiltonabad59e2019-06-06 04:02:599858 MockQuicData socket_data(version_);
Yixin Wang247ea642017-11-15 01:15:509859 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:439860 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Zhongyi Shi5f587cc2017-11-21 23:24:179861 socket_data.AddSocketDataToFactory(socket_factory_.get());
Yixin Wang247ea642017-11-15 01:15:509862
9863 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:339864 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:039865 request.Request(
Nick Harper23290b82019-05-02 00:02:569866 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:519867 MAXIMUM_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:039868 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9869 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang247ea642017-11-15 01:15:509870
9871 EXPECT_THAT(callback_.WaitForResult(), IsOk());
9872 std::unique_ptr<HttpStream> stream = CreateStream(&request);
9873 EXPECT_TRUE(stream.get());
9874
Renjiea0cb4a2c2018-09-26 23:37:309875 EXPECT_EQ(MAXIMUM_PRIORITY, host_resolver_->last_request_priority());
Yixin Wang247ea642017-11-15 01:15:509876
9877 EXPECT_TRUE(socket_data.AllReadDataConsumed());
9878 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
9879}
9880
Lily Chenf11e1292018-11-29 16:42:099881TEST_P(QuicStreamFactoryTest, HostResolverRequestReprioritizedOnSetPriority) {
9882 Initialize();
9883 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9884 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9885
Ryan Hamiltonabad59e2019-06-06 04:02:599886 MockQuicData socket_data(version_);
Lily Chenf11e1292018-11-29 16:42:099887 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
9888 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
9889 socket_data.AddSocketDataToFactory(socket_factory_.get());
9890
9891 QuicStreamRequest request(factory_.get());
9892 EXPECT_EQ(ERR_IO_PENDING,
9893 request.Request(
Nick Harper23290b82019-05-02 00:02:569894 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:519895 MAXIMUM_PRIORITY, SocketTag(), NetworkIsolationKey(),
Lily Chenf11e1292018-11-29 16:42:099896 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9897 failed_on_default_network_callback_, callback_.callback()));
9898
9899 EXPECT_EQ(MAXIMUM_PRIORITY, host_resolver_->last_request_priority());
9900 EXPECT_EQ(MAXIMUM_PRIORITY, host_resolver_->request_priority(1));
9901
9902 QuicStreamRequest request2(factory_.get());
9903 EXPECT_EQ(ERR_IO_PENDING,
9904 request2.Request(
Nick Harper23290b82019-05-02 00:02:569905 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:519906 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Lily Chenf11e1292018-11-29 16:42:099907 /*cert_verify_flags=*/0, url2_, net_log_, &net_error_details_,
9908 failed_on_default_network_callback_, callback_.callback()));
9909 EXPECT_EQ(DEFAULT_PRIORITY, host_resolver_->last_request_priority());
9910 EXPECT_EQ(DEFAULT_PRIORITY, host_resolver_->request_priority(2));
9911
9912 request.SetPriority(LOWEST);
9913 EXPECT_EQ(LOWEST, host_resolver_->request_priority(1));
9914 EXPECT_EQ(DEFAULT_PRIORITY, host_resolver_->request_priority(2));
9915}
9916
Zhongyi Shi967d2f12019-02-08 20:58:539917// Passes |quic_max_time_before_crypto_handshake_seconds| and
9918// |quic_max_idle_time_before_crypto_handshake_seconds| to QuicStreamFactory,
Ryan Hamilton8d9ee76e2018-05-29 23:52:529919// checks that its internal quic::QuicConfig is correct.
Yixin Wang469da562017-11-15 21:34:589920TEST_P(QuicStreamFactoryTest, ConfigMaxTimeBeforeCryptoHandshake) {
Zhongyi Shi967d2f12019-02-08 20:58:539921 test_params_.quic_max_time_before_crypto_handshake_seconds = 11;
9922 test_params_.quic_max_idle_time_before_crypto_handshake_seconds = 13;
Yixin Wang469da562017-11-15 21:34:589923 Initialize();
9924
Ryan Hamilton8d9ee76e2018-05-29 23:52:529925 const quic::QuicConfig* config =
9926 QuicStreamFactoryPeer::GetConfig(factory_.get());
9927 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(11),
Yixin Wang469da562017-11-15 21:34:589928 config->max_time_before_crypto_handshake());
Ryan Hamilton8d9ee76e2018-05-29 23:52:529929 EXPECT_EQ(quic::QuicTime::Delta::FromSeconds(13),
Yixin Wang469da562017-11-15 21:34:589930 config->max_idle_time_before_crypto_handshake());
9931}
9932
Yixin Wang7c5d11a82017-12-21 02:40:009933// Verify ResultAfterHostResolutionCallback behavior when host resolution
9934// succeeds asynchronously, then crypto handshake fails synchronously.
9935TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackAsyncSync) {
9936 Initialize();
9937 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9938 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9939
Renjiea0cb4a2c2018-09-26 23:37:309940 host_resolver_->set_ondemand_mode(true);
Yixin Wang7c5d11a82017-12-21 02:40:009941
Ryan Hamiltonabad59e2019-06-06 04:02:599942 MockQuicData socket_data(version_);
Yixin Wang7c5d11a82017-12-21 02:40:009943 socket_data.AddRead(SYNCHRONOUS, ERR_FAILED);
9944 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
9945 socket_data.AddSocketDataToFactory(socket_factory_.get());
9946
9947 QuicStreamRequest request(factory_.get());
9948 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:039949 request.Request(
Nick Harper23290b82019-05-02 00:02:569950 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:519951 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:039952 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
9953 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7c5d11a82017-12-21 02:40:009954
9955 TestCompletionCallback host_resolution_callback;
9956 EXPECT_TRUE(
9957 request.WaitForHostResolution(host_resolution_callback.callback()));
9958
9959 // |host_resolver_| has not finished host resolution at this point, so
9960 // |host_resolution_callback| should not have a result.
9961 base::RunLoop().RunUntilIdle();
9962 EXPECT_FALSE(host_resolution_callback.have_result());
9963
9964 // Allow |host_resolver_| to finish host resolution.
9965 // Since the request fails immediately after host resolution (getting
9966 // ERR_FAILED from socket reads/writes), |host_resolution_callback| should be
9967 // called with ERR_QUIC_PROTOCOL_ERROR since that's the next result in
9968 // forming the connection.
Renjiea0cb4a2c2018-09-26 23:37:309969 host_resolver_->ResolveAllPending();
Yixin Wang7c5d11a82017-12-21 02:40:009970 base::RunLoop().RunUntilIdle();
9971 EXPECT_TRUE(host_resolution_callback.have_result());
9972 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, host_resolution_callback.WaitForResult());
9973
9974 // Calling WaitForHostResolution() a second time should return
9975 // false since host resolution has finished already.
9976 EXPECT_FALSE(
9977 request.WaitForHostResolution(host_resolution_callback.callback()));
9978
9979 EXPECT_TRUE(callback_.have_result());
9980 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback_.WaitForResult());
9981}
9982
9983// Verify ResultAfterHostResolutionCallback behavior when host resolution
9984// succeeds asynchronously, then crypto handshake fails asynchronously.
9985TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackAsyncAsync) {
9986 Initialize();
9987 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
9988 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
9989
Renjiea0cb4a2c2018-09-26 23:37:309990 host_resolver_->set_ondemand_mode(true);
Yixin Wang7c5d11a82017-12-21 02:40:009991 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:279992 MockCryptoClientStream::ZERO_RTT);
Yixin Wang7c5d11a82017-12-21 02:40:009993 factory_->set_require_confirmation(true);
9994
Ryan Hamiltonabad59e2019-06-06 04:02:599995 MockQuicData socket_data(version_);
Yixin Wang7c5d11a82017-12-21 02:40:009996 socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
9997 socket_data.AddRead(ASYNC, ERR_FAILED);
9998 socket_data.AddWrite(ASYNC, ERR_FAILED);
9999 socket_data.AddSocketDataToFactory(socket_factory_.get());
10000
10001 QuicStreamRequest request(factory_.get());
10002 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:0310003 request.Request(
Nick Harper23290b82019-05-02 00:02:5610004 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:5110005 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:0310006 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10007 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7c5d11a82017-12-21 02:40:0010008
10009 TestCompletionCallback host_resolution_callback;
10010 EXPECT_TRUE(
10011 request.WaitForHostResolution(host_resolution_callback.callback()));
10012
10013 // |host_resolver_| has not finished host resolution at this point, so
10014 // |host_resolution_callback| should not have a result.
10015 base::RunLoop().RunUntilIdle();
10016 EXPECT_FALSE(host_resolution_callback.have_result());
10017
10018 // Allow |host_resolver_| to finish host resolution. Since crypto handshake
10019 // will hang after host resolution, |host_resolution_callback| should run with
10020 // ERR_IO_PENDING since that's the next result in forming the connection.
Renjiea0cb4a2c2018-09-26 23:37:3010021 host_resolver_->ResolveAllPending();
Yixin Wang7c5d11a82017-12-21 02:40:0010022 base::RunLoop().RunUntilIdle();
10023 EXPECT_TRUE(host_resolution_callback.have_result());
10024 EXPECT_EQ(ERR_IO_PENDING, host_resolution_callback.WaitForResult());
10025
10026 // Calling WaitForHostResolution() a second time should return
10027 // false since host resolution has finished already.
10028 EXPECT_FALSE(
10029 request.WaitForHostResolution(host_resolution_callback.callback()));
10030
10031 EXPECT_FALSE(callback_.have_result());
10032 socket_data.GetSequencedSocketData()->Resume();
10033 base::RunLoop().RunUntilIdle();
10034 EXPECT_TRUE(callback_.have_result());
10035 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback_.WaitForResult());
10036}
10037
10038// Verify ResultAfterHostResolutionCallback behavior when host resolution
10039// succeeds synchronously, then crypto handshake fails synchronously.
10040TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackSyncSync) {
10041 Initialize();
10042 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10043 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10044
Renjiea0cb4a2c2018-09-26 23:37:3010045 host_resolver_->set_synchronous_mode(true);
Yixin Wang7c5d11a82017-12-21 02:40:0010046
Ryan Hamiltonabad59e2019-06-06 04:02:5910047 MockQuicData socket_data(version_);
Yixin Wang7c5d11a82017-12-21 02:40:0010048 socket_data.AddRead(SYNCHRONOUS, ERR_FAILED);
10049 socket_data.AddWrite(SYNCHRONOUS, ERR_FAILED);
10050 socket_data.AddSocketDataToFactory(socket_factory_.get());
10051
10052 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:3310053 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR,
Zhongyi Shia6b68d112018-09-24 07:49:0310054 request.Request(
Nick Harper23290b82019-05-02 00:02:5610055 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:5110056 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:0310057 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10058 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7c5d11a82017-12-21 02:40:0010059
10060 // WaitForHostResolution() should return false since host
10061 // resolution has finished already.
10062 TestCompletionCallback host_resolution_callback;
10063 EXPECT_FALSE(
10064 request.WaitForHostResolution(host_resolution_callback.callback()));
10065 base::RunLoop().RunUntilIdle();
10066 EXPECT_FALSE(host_resolution_callback.have_result());
10067 EXPECT_FALSE(callback_.have_result());
10068}
10069
10070// Verify ResultAfterHostResolutionCallback behavior when host resolution
10071// succeeds synchronously, then crypto handshake fails asynchronously.
10072TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackSyncAsync) {
10073 Initialize();
10074 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10075 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10076
10077 // Host resolution will succeed synchronously, but Request() as a whole
10078 // will fail asynchronously.
Renjiea0cb4a2c2018-09-26 23:37:3010079 host_resolver_->set_synchronous_mode(true);
Yixin Wang7c5d11a82017-12-21 02:40:0010080 crypto_client_stream_factory_.set_handshake_mode(
Ryan Hamilton9835e662018-08-02 05:36:2710081 MockCryptoClientStream::ZERO_RTT);
Yixin Wang7c5d11a82017-12-21 02:40:0010082 factory_->set_require_confirmation(true);
10083
Ryan Hamiltonabad59e2019-06-06 04:02:5910084 MockQuicData socket_data(version_);
Yixin Wang7c5d11a82017-12-21 02:40:0010085 socket_data.AddRead(ASYNC, ERR_IO_PENDING); // Pause
10086 socket_data.AddRead(ASYNC, ERR_FAILED);
10087 socket_data.AddWrite(ASYNC, ERR_FAILED);
10088 socket_data.AddSocketDataToFactory(socket_factory_.get());
10089
10090 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:3310091 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:0310092 request.Request(
Nick Harper23290b82019-05-02 00:02:5610093 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:5110094 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:0310095 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10096 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7c5d11a82017-12-21 02:40:0010097
10098 // WaitForHostResolution() should return false since host
10099 // resolution has finished already.
10100 TestCompletionCallback host_resolution_callback;
10101 EXPECT_FALSE(
10102 request.WaitForHostResolution(host_resolution_callback.callback()));
10103 base::RunLoop().RunUntilIdle();
10104 EXPECT_FALSE(host_resolution_callback.have_result());
10105
10106 EXPECT_FALSE(callback_.have_result());
10107 socket_data.GetSequencedSocketData()->Resume();
10108 base::RunLoop().RunUntilIdle();
10109 EXPECT_TRUE(callback_.have_result());
10110 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, callback_.WaitForResult());
10111}
10112
10113// Verify ResultAfterHostResolutionCallback behavior when host resolution fails
10114// synchronously.
10115TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackFailSync) {
10116 Initialize();
10117 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10118 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10119
10120 // Host resolution will fail synchronously.
Renjiea0cb4a2c2018-09-26 23:37:3010121 host_resolver_->rules()->AddSimulatedFailure(host_port_pair_.host());
10122 host_resolver_->set_synchronous_mode(true);
Yixin Wang7c5d11a82017-12-21 02:40:0010123
10124 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:3310125 EXPECT_EQ(ERR_NAME_NOT_RESOLVED,
Zhongyi Shia6b68d112018-09-24 07:49:0310126 request.Request(
Nick Harper23290b82019-05-02 00:02:5610127 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:5110128 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:0310129 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10130 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7c5d11a82017-12-21 02:40:0010131
10132 // WaitForHostResolution() should return false since host
10133 // resolution has failed already.
10134 TestCompletionCallback host_resolution_callback;
10135 EXPECT_FALSE(
10136 request.WaitForHostResolution(host_resolution_callback.callback()));
10137 base::RunLoop().RunUntilIdle();
10138 EXPECT_FALSE(host_resolution_callback.have_result());
10139}
10140
10141// Verify ResultAfterHostResolutionCallback behavior when host resolution fails
10142// asynchronously.
10143TEST_P(QuicStreamFactoryTest, ResultAfterHostResolutionCallbackFailAsync) {
10144 Initialize();
10145 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10146 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10147
Renjiea0cb4a2c2018-09-26 23:37:3010148 host_resolver_->rules()->AddSimulatedFailure(host_port_pair_.host());
Yixin Wang7c5d11a82017-12-21 02:40:0010149
10150 QuicStreamRequest request(factory_.get());
Paul Jensen8e3c5d32018-02-19 17:06:3310151 EXPECT_EQ(ERR_IO_PENDING,
Zhongyi Shia6b68d112018-09-24 07:49:0310152 request.Request(
Nick Harper23290b82019-05-02 00:02:5610153 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:5110154 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:0310155 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10156 failed_on_default_network_callback_, callback_.callback()));
Yixin Wang7c5d11a82017-12-21 02:40:0010157
10158 TestCompletionCallback host_resolution_callback;
10159 EXPECT_TRUE(
10160 request.WaitForHostResolution(host_resolution_callback.callback()));
10161
10162 // Allow |host_resolver_| to fail host resolution. |host_resolution_callback|
10163 // Should run with ERR_NAME_NOT_RESOLVED since that's the error host
10164 // resolution failed with.
10165 base::RunLoop().RunUntilIdle();
10166 EXPECT_TRUE(host_resolution_callback.have_result());
10167 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, host_resolution_callback.WaitForResult());
10168
10169 EXPECT_TRUE(callback_.have_result());
10170 EXPECT_EQ(ERR_NAME_NOT_RESOLVED, callback_.WaitForResult());
10171}
10172
Renjiea0cb4a2c2018-09-26 23:37:3010173// With dns race experiment turned on, and DNS resolve succeeds synchronously,
10174// the final connection is established through the resolved DNS. No racing
10175// connection.
10176TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceAndHostResolutionSync) {
Zhongyi Shi967d2f12019-02-08 20:58:5310177 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010178 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10179 Initialize();
10180 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10181 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10182
10183 // Set an address in resolver for synchronous return.
10184 host_resolver_->set_synchronous_mode(true);
10185 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10186 kNonCachedIPAddress, "");
10187
10188 // Set up a different address in stale resolver cache.
10189 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10190 HostCache::Entry entry(OK,
10191 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10192 HostCache::Entry::SOURCE_DNS);
10193 base::TimeDelta zero;
10194 HostCache* cache = host_resolver_->GetHostCache();
10195 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10196 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810197 cache->Invalidate();
Renjie8d2d8d91b2018-09-29 00:29:0310198
Ryan Hamiltonabad59e2019-06-06 04:02:5910199 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010200 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10201 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
10202 quic_data.AddSocketDataToFactory(socket_factory_.get());
10203
10204 QuicStreamRequest request(factory_.get());
10205 EXPECT_THAT(request.Request(
Nick Harper23290b82019-05-02 00:02:5610206 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:5110207 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010208 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10209 failed_on_default_network_callback_, callback_.callback()),
10210 IsOk());
10211 std::unique_ptr<HttpStream> stream = CreateStream(&request);
10212 EXPECT_TRUE(stream.get());
10213 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Victor Vasilievbee79ea2019-05-15 01:25:4810214 EXPECT_EQ(session->peer_address().host().ToString(), kNonCachedIPAddress);
Renjiea0cb4a2c2018-09-26 23:37:3010215
10216 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10217 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
10218}
10219
10220// With dns race experiment on, DNS resolve returns async, no matching cache in
10221// host resolver, connection should be successful and through resolved DNS. No
10222// racing connection.
10223TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceAndHostResolutionAsync) {
Renjiea0cb4a2c2018-09-26 23:37:3010224 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10225 Initialize();
10226 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10227 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10228
10229 // Set an address in resolver for asynchronous return.
10230 host_resolver_->set_ondemand_mode(true);
10231 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10232 kNonCachedIPAddress, "");
10233
Ryan Hamiltonabad59e2019-06-06 04:02:5910234 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010235 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10236 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
10237 quic_data.AddSocketDataToFactory(socket_factory_.get());
10238
10239 QuicStreamRequest request(factory_.get());
10240 EXPECT_EQ(ERR_IO_PENDING,
10241 request.Request(
Nick Harper23290b82019-05-02 00:02:5610242 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:5110243 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010244 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10245 failed_on_default_network_callback_, callback_.callback()));
10246 TestCompletionCallback host_resolution_callback;
10247 EXPECT_TRUE(
10248 request.WaitForHostResolution(host_resolution_callback.callback()));
10249 base::RunLoop().RunUntilIdle();
10250 EXPECT_FALSE(host_resolution_callback.have_result());
10251
10252 // Cause the host resolution to return.
10253 host_resolver_->ResolveAllPending();
10254 EXPECT_THAT(host_resolution_callback.WaitForResult(), IsOk());
10255 EXPECT_THAT(callback_.WaitForResult(), IsOk());
10256
10257 std::unique_ptr<HttpStream> stream = CreateStream(&request);
10258 EXPECT_TRUE(stream.get());
10259 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
10260
Victor Vasilievbee79ea2019-05-15 01:25:4810261 EXPECT_EQ(session->peer_address().host().ToString(), kNonCachedIPAddress);
Renjiea0cb4a2c2018-09-26 23:37:3010262
10263 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10264 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
10265}
10266
10267// With dns race experiment on, DNS resolve returns async, stale dns used,
10268// connects synchrounously, and then the resolved DNS matches.
10269TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceHostResolveAsyncStaleMatch) {
Zhongyi Shi967d2f12019-02-08 20:58:5310270 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010271 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10272 Initialize();
10273 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10274 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10275
10276 // Set an address in resolver for asynchronous return.
10277 host_resolver_->set_ondemand_mode(true);
10278 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10279 kCachedIPAddress.ToString(), "");
10280
10281 // Set up the same address in the stale resolver cache.
10282 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10283 HostCache::Entry entry(OK,
10284 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10285 HostCache::Entry::SOURCE_DNS);
10286 base::TimeDelta zero;
10287 HostCache* cache = host_resolver_->GetHostCache();
10288 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10289 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810290 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010291
Ryan Hamiltonabad59e2019-06-06 04:02:5910292 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010293 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10294 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
10295 quic_data.AddSocketDataToFactory(socket_factory_.get());
10296
10297 QuicStreamRequest request(factory_.get());
10298 EXPECT_EQ(ERR_IO_PENDING,
10299 request.Request(
Nick Harper23290b82019-05-02 00:02:5610300 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:5110301 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010302 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10303 failed_on_default_network_callback_, callback_.callback()));
10304
10305 // Check that the racing job is running.
10306 EXPECT_TRUE(HasLiveSession(host_port_pair_));
10307 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
10308
10309 // Resolve dns and return.
10310 host_resolver_->ResolveAllPending();
10311 EXPECT_THAT(callback_.WaitForResult(), IsOk());
10312 std::unique_ptr<HttpStream> stream = CreateStream(&request);
10313 EXPECT_TRUE(stream.get());
10314
10315 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
10316
Victor Vasilievbee79ea2019-05-15 01:25:4810317 EXPECT_EQ(session->peer_address().host().ToString(),
10318 kCachedIPAddress.ToString());
Renjiea0cb4a2c2018-09-26 23:37:3010319
10320 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10321 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
10322}
10323
10324// With dns race experiment on, dns resolve async, stale dns used, connect
10325// async, and then the result matches.
10326TEST_P(QuicStreamFactoryTest,
10327 ResultAfterDNSRaceHostResolveAsyncConnectAsyncStaleMatch) {
Zhongyi Shi967d2f12019-02-08 20:58:5310328 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010329 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10330 Initialize();
10331 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10332 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10333
10334 // Set an address in resolver for asynchronous return.
10335 host_resolver_->set_ondemand_mode(true);
10336 factory_->set_require_confirmation(true);
10337 crypto_client_stream_factory_.set_handshake_mode(
10338 MockCryptoClientStream::ZERO_RTT);
10339 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10340 kCachedIPAddress.ToString(), "");
10341
10342 // Set up the same address in the stale resolver cache.
10343 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10344 HostCache::Entry entry(OK,
10345 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10346 HostCache::Entry::SOURCE_DNS);
10347 base::TimeDelta zero;
10348 HostCache* cache = host_resolver_->GetHostCache();
10349 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10350 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810351 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010352
Ryan Hamiltonabad59e2019-06-06 04:02:5910353 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010354 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10355 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
10356 quic_data.AddSocketDataToFactory(socket_factory_.get());
10357
10358 QuicStreamRequest request(factory_.get());
10359 EXPECT_EQ(ERR_IO_PENDING,
10360 request.Request(
Nick Harper23290b82019-05-02 00:02:5610361 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:5110362 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010363 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10364 failed_on_default_network_callback_, callback_.callback()));
10365
10366 // Send Crypto handshake so connect will call back.
10367 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
10368 quic::QuicSession::HANDSHAKE_CONFIRMED);
10369 base::RunLoop().RunUntilIdle();
10370
10371 // Check that the racing job is running.
10372 EXPECT_TRUE(HasLiveSession(host_port_pair_));
10373 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
10374
10375 // Resolve dns and call back, make sure job finishes.
10376 host_resolver_->ResolveAllPending();
10377 EXPECT_THAT(callback_.WaitForResult(), IsOk());
10378
10379 std::unique_ptr<HttpStream> stream = CreateStream(&request);
10380 EXPECT_TRUE(stream.get());
10381
10382 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
10383
Victor Vasilievbee79ea2019-05-15 01:25:4810384 EXPECT_EQ(session->peer_address().host().ToString(),
10385 kCachedIPAddress.ToString());
Renjiea0cb4a2c2018-09-26 23:37:3010386
10387 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10388 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
10389}
10390
10391// With dns race experiment on, dns resolve async, stale dns used, dns resolve
10392// return, then connection finishes and matches with the result.
10393TEST_P(QuicStreamFactoryTest,
10394 ResultAfterDNSRaceHostResolveAsyncStaleMatchConnectAsync) {
Zhongyi Shi967d2f12019-02-08 20:58:5310395 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010396 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10397 Initialize();
10398 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10399 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10400
10401 // Set an address in resolver for asynchronous return.
10402 host_resolver_->set_ondemand_mode(true);
10403 factory_->set_require_confirmation(true);
10404 crypto_client_stream_factory_.set_handshake_mode(
10405 MockCryptoClientStream::ZERO_RTT);
10406 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10407 kCachedIPAddress.ToString(), "");
10408
10409 // Set up the same address in the stale resolver cache.
10410 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10411 HostCache::Entry entry(OK,
10412 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10413 HostCache::Entry::SOURCE_DNS);
10414 base::TimeDelta zero;
10415 HostCache* cache = host_resolver_->GetHostCache();
10416 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10417 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810418 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010419
Ryan Hamiltonabad59e2019-06-06 04:02:5910420 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010421 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10422 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
10423 quic_data.AddSocketDataToFactory(socket_factory_.get());
10424
10425 QuicStreamRequest request(factory_.get());
10426 EXPECT_EQ(ERR_IO_PENDING,
10427 request.Request(
Nick Harper23290b82019-05-02 00:02:5610428 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:5110429 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010430 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10431 failed_on_default_network_callback_, callback_.callback()));
10432
10433 // Finish dns async, check we still need to wait for stale connection async.
10434 host_resolver_->ResolveAllPending();
10435 base::RunLoop().RunUntilIdle();
10436 EXPECT_FALSE(callback_.have_result());
10437
10438 // Finish stale connection async, and the stale connection should pass dns
10439 // validation.
10440 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
10441 quic::QuicSession::HANDSHAKE_CONFIRMED);
10442 EXPECT_THAT(callback_.WaitForResult(), IsOk());
10443 std::unique_ptr<HttpStream> stream = CreateStream(&request);
10444 EXPECT_TRUE(stream.get());
10445
10446 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Victor Vasilievbee79ea2019-05-15 01:25:4810447 EXPECT_EQ(session->peer_address().host().ToString(),
10448 kCachedIPAddress.ToString());
Renjiea0cb4a2c2018-09-26 23:37:3010449
10450 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10451 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
10452}
10453
10454// With dns race experiment on, dns resolve async, stale used and connects
10455// sync, but dns no match
10456TEST_P(QuicStreamFactoryTest,
10457 ResultAfterDNSRaceHostResolveAsyncStaleSyncNoMatch) {
Zhongyi Shi967d2f12019-02-08 20:58:5310458 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010459 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10460 Initialize();
10461 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10462 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10463
10464 // Set an address in resolver for asynchronous return.
10465 host_resolver_->set_ondemand_mode(true);
10466 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10467 kNonCachedIPAddress, "");
10468
10469 // Set up a different address in the stale resolver cache.
10470 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10471 HostCache::Entry entry(OK,
10472 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10473 HostCache::Entry::SOURCE_DNS);
10474 base::TimeDelta zero;
10475 HostCache* cache = host_resolver_->GetHostCache();
10476 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10477 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810478 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010479
10480 // Socket for the stale connection which will invoke connection closure.
Ryan Hamiltonabad59e2019-06-06 04:02:5910481 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010482 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10483 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
10484 quic_data.AddWrite(
Renjief5fcb172019-02-05 01:59:3310485 SYNCHRONOUS,
10486 client_maker_.MakeConnectionClosePacket(
10487 2, true, quic::QUIC_STALE_CONNECTION_CANCELLED, "net error"));
Renjiea0cb4a2c2018-09-26 23:37:3010488 quic_data.AddSocketDataToFactory(socket_factory_.get());
10489
10490 // Socket for the new connection.
Ryan Hamiltonabad59e2019-06-06 04:02:5910491 MockQuicData quic_data2(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010492 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10493 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
10494 quic_data2.AddSocketDataToFactory(socket_factory_.get());
10495
10496 QuicStreamRequest request(factory_.get());
10497 EXPECT_EQ(ERR_IO_PENDING,
10498 request.Request(
Nick Harper23290b82019-05-02 00:02:5610499 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:5110500 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010501 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10502 failed_on_default_network_callback_, callback_.callback()));
10503
10504 // Check the stale connection is running.
10505 EXPECT_TRUE(HasLiveSession(host_port_pair_));
10506 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
10507
10508 // Finish dns resolution and check the job has finished.
10509 host_resolver_->ResolveAllPending();
10510 EXPECT_THAT(callback_.WaitForResult(), IsOk());
10511
10512 std::unique_ptr<HttpStream> stream = CreateStream(&request);
10513 EXPECT_TRUE(stream.get());
10514
10515 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
10516
Victor Vasilievbee79ea2019-05-15 01:25:4810517 EXPECT_EQ(session->peer_address().host().ToString(), kNonCachedIPAddress);
Renjiea0cb4a2c2018-09-26 23:37:3010518
10519 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10520 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
10521 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
10522 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
10523}
10524
10525// With dns race experiment on, dns resolve async, stale used and connects
10526// async, finishes before dns, but no match
10527TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceStaleAsyncResolveAsyncNoMatch) {
Zhongyi Shi967d2f12019-02-08 20:58:5310528 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010529 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10530 Initialize();
10531 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10532 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10533
10534 // Set an address in resolver for asynchronous return.
10535 host_resolver_->set_ondemand_mode(true);
10536 factory_->set_require_confirmation(true);
10537 crypto_client_stream_factory_.set_handshake_mode(
10538 MockCryptoClientStream::ZERO_RTT);
10539 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10540 kNonCachedIPAddress, "");
10541
10542 // Set up a different address in the stale resolvercache.
10543 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10544 HostCache::Entry entry(OK,
10545 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10546 HostCache::Entry::SOURCE_DNS);
10547 base::TimeDelta zero;
10548 HostCache* cache = host_resolver_->GetHostCache();
10549 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10550 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810551 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010552
Ryan Hamiltonabad59e2019-06-06 04:02:5910553 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010554 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10555 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
10556 quic_data.AddWrite(
Renjief5fcb172019-02-05 01:59:3310557 SYNCHRONOUS,
10558 client_maker_.MakeConnectionClosePacket(
10559 2, true, quic::QUIC_STALE_CONNECTION_CANCELLED, "net error"));
Renjiea0cb4a2c2018-09-26 23:37:3010560 quic_data.AddSocketDataToFactory(socket_factory_.get());
10561
Ryan Hamiltonabad59e2019-06-06 04:02:5910562 MockQuicData quic_data2(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010563 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10564 quic_data2.AddSocketDataToFactory(socket_factory_.get());
10565
10566 QuicStreamRequest request(factory_.get());
10567 EXPECT_EQ(ERR_IO_PENDING,
10568 request.Request(
Nick Harper23290b82019-05-02 00:02:5610569 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:5110570 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010571 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10572 failed_on_default_network_callback_, callback_.callback()));
10573
10574 // Finish the stale connection.
10575 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
10576 quic::QuicSession::HANDSHAKE_CONFIRMED);
10577 base::RunLoop().RunUntilIdle();
10578 EXPECT_TRUE(HasLiveSession(host_port_pair_));
10579 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
10580
10581 // Finish host resolution and check the job is done.
10582 host_resolver_->ResolveAllPending();
10583 EXPECT_THAT(callback_.WaitForResult(), IsOk());
10584
10585 std::unique_ptr<HttpStream> stream = CreateStream(&request);
10586 EXPECT_TRUE(stream.get());
10587
10588 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Victor Vasilievbee79ea2019-05-15 01:25:4810589 EXPECT_EQ(session->peer_address().host().ToString(), kNonCachedIPAddress);
Renjiea0cb4a2c2018-09-26 23:37:3010590
10591 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10592 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
10593 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
10594 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
10595}
10596
10597// With dns race experiment on, dns resolve async, stale used and connects
10598// async, dns finishes first, but no match
10599TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceResolveAsyncStaleAsyncNoMatch) {
Zhongyi Shi967d2f12019-02-08 20:58:5310600 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010601 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10602 Initialize();
10603 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10604 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10605
10606 // Set an address in resolver for asynchronous return.
10607 host_resolver_->set_ondemand_mode(true);
10608 factory_->set_require_confirmation(true);
10609 crypto_client_stream_factory_.set_handshake_mode(
10610 MockCryptoClientStream::ZERO_RTT);
10611 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10612 kNonCachedIPAddress, "");
10613
10614 // Set up a different address in the stale resolver cache.
10615 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10616 HostCache::Entry entry(OK,
10617 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10618 HostCache::Entry::SOURCE_DNS);
10619 base::TimeDelta zero;
10620 HostCache* cache = host_resolver_->GetHostCache();
10621 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10622 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810623 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010624
Ryan Hamiltonabad59e2019-06-06 04:02:5910625 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010626 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Michael Warres167db3e2019-03-01 21:38:0310627 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Renjiea0cb4a2c2018-09-26 23:37:3010628 quic_data.AddWrite(
Renjief5fcb172019-02-05 01:59:3310629 SYNCHRONOUS,
10630 client_maker_.MakeConnectionClosePacket(
10631 1, true, quic::QUIC_STALE_CONNECTION_CANCELLED, "net error"));
Renjiea0cb4a2c2018-09-26 23:37:3010632 quic_data.AddSocketDataToFactory(socket_factory_.get());
10633
Ryan Hamiltonabad59e2019-06-06 04:02:5910634 MockQuicData quic_data2(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010635 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Renjie8d2d8d91b2018-09-29 00:29:0310636 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
10637 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Renjiea0cb4a2c2018-09-26 23:37:3010638 quic_data2.AddSocketDataToFactory(socket_factory_.get());
10639
10640 QuicStreamRequest request(factory_.get());
10641 EXPECT_EQ(ERR_IO_PENDING,
10642 request.Request(
Nick Harper23290b82019-05-02 00:02:5610643 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:5110644 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010645 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10646 failed_on_default_network_callback_, callback_.callback()));
10647 // Finish dns resolution, but need to wait for stale connection.
10648 host_resolver_->ResolveAllPending();
Renjie8d2d8d91b2018-09-29 00:29:0310649 base::RunLoop().RunUntilIdle();
Renjiea0cb4a2c2018-09-26 23:37:3010650 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
10651 quic::QuicSession::HANDSHAKE_CONFIRMED);
10652 EXPECT_THAT(callback_.WaitForResult(), IsOk());
10653
10654 std::unique_ptr<HttpStream> stream = CreateStream(&request);
10655 EXPECT_TRUE(stream.get());
10656
10657 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
Victor Vasilievbee79ea2019-05-15 01:25:4810658 EXPECT_EQ(session->peer_address().host().ToString(), kNonCachedIPAddress);
Renjiea0cb4a2c2018-09-26 23:37:3010659
10660 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10661 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
10662 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
10663 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
10664}
10665
10666// With dns race experiment on, dns resolve returns error sync, same behavior
10667// as experiment is not on
10668TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceHostResolveError) {
Zhongyi Shi967d2f12019-02-08 20:58:5310669 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010670 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10671 Initialize();
10672 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10673 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10674
10675 // Set synchronous failure in resolver.
10676 host_resolver_->set_synchronous_mode(true);
10677 host_resolver_->rules()->AddSimulatedFailure(host_port_pair_.host());
10678
Ryan Hamiltonabad59e2019-06-06 04:02:5910679 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010680 quic_data.AddSocketDataToFactory(socket_factory_.get());
10681 QuicStreamRequest request(factory_.get());
10682
10683 EXPECT_EQ(ERR_NAME_NOT_RESOLVED,
10684 request.Request(
Nick Harper23290b82019-05-02 00:02:5610685 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:5110686 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010687 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10688 failed_on_default_network_callback_, callback_.callback()));
10689}
10690
10691// With dns race experiment on, no cache available, dns resolve returns error
10692// async
10693TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceHostResolveAsyncError) {
Zhongyi Shi967d2f12019-02-08 20:58:5310694 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010695 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10696 Initialize();
10697 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10698 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10699
10700 // Set asynchronous failure in resolver.
10701 host_resolver_->set_ondemand_mode(true);
10702 host_resolver_->rules()->AddSimulatedFailure(host_port_pair_.host());
10703
Ryan Hamiltonabad59e2019-06-06 04:02:5910704 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010705 quic_data.AddSocketDataToFactory(socket_factory_.get());
10706 QuicStreamRequest request(factory_.get());
10707
10708 EXPECT_EQ(ERR_IO_PENDING,
10709 request.Request(
Nick Harper23290b82019-05-02 00:02:5610710 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:5110711 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010712 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10713 failed_on_default_network_callback_, callback_.callback()));
10714
10715 // Resolve and expect result that shows the resolution error.
10716 host_resolver_->ResolveAllPending();
10717 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_NAME_NOT_RESOLVED));
10718}
10719
10720// With dns race experiment on, dns resolve async, staled used and connects
10721// sync, dns returns error and no connection is established.
10722TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceStaleSyncHostResolveError) {
Zhongyi Shi967d2f12019-02-08 20:58:5310723 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010724 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10725 Initialize();
10726 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10727 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10728
10729 // Set asynchronous failure in resolver.
10730 host_resolver_->set_ondemand_mode(true);
10731 host_resolver_->rules()->AddSimulatedFailure(host_port_pair_.host());
10732
10733 // Set up an address in the stale cache.
10734 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10735 HostCache::Entry entry(OK,
10736 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10737 HostCache::Entry::SOURCE_DNS);
10738 base::TimeDelta zero;
10739 HostCache* cache = host_resolver_->GetHostCache();
10740 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10741 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810742 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010743
10744 // Socket for the stale connection which is supposed to disconnect.
Ryan Hamiltonabad59e2019-06-06 04:02:5910745 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010746 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10747 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
10748 quic_data.AddWrite(
Renjief5fcb172019-02-05 01:59:3310749 SYNCHRONOUS,
10750 client_maker_.MakeConnectionClosePacket(
10751 2, true, quic::QUIC_STALE_CONNECTION_CANCELLED, "net error"));
Renjiea0cb4a2c2018-09-26 23:37:3010752 quic_data.AddSocketDataToFactory(socket_factory_.get());
10753
10754 QuicStreamRequest request(factory_.get());
10755 EXPECT_EQ(ERR_IO_PENDING,
10756 request.Request(
Nick Harper23290b82019-05-02 00:02:5610757 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:5110758 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010759 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10760 failed_on_default_network_callback_, callback_.callback()));
10761
10762 // Check that the stale connection is running.
10763 EXPECT_TRUE(HasLiveSession(host_port_pair_));
10764 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
10765
10766 // Finish host resolution.
10767 host_resolver_->ResolveAllPending();
10768 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_NAME_NOT_RESOLVED));
10769
Renjiea0cb4a2c2018-09-26 23:37:3010770 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10771 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
10772}
10773
10774// With dns race experiment on, dns resolve async, stale used and connection
Renjie99ec24b2019-04-26 17:44:3410775// return error, then dns matches.
10776// This serves as a regression test for crbug.com/956374.
Renjiea0cb4a2c2018-09-26 23:37:3010777TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceStaleErrorDNSMatches) {
Zhongyi Shi967d2f12019-02-08 20:58:5310778 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010779 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10780 Initialize();
10781 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10782 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10783
10784 // Set an address in host resolver for asynchronous return.
10785 host_resolver_->set_ondemand_mode(true);
10786 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10787 kCachedIPAddress.ToString(), "");
10788
10789 // Set up the same address in the stale resolver cache.
10790 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10791 HostCache::Entry entry(OK,
10792 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10793 HostCache::Entry::SOURCE_DNS);
10794 base::TimeDelta zero;
10795 HostCache* cache = host_resolver_->GetHostCache();
10796 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10797 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810798 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010799
10800 // Simulate synchronous connect failure.
Ryan Hamiltonabad59e2019-06-06 04:02:5910801 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010802 quic_data.AddConnect(SYNCHRONOUS, ERR_ADDRESS_IN_USE);
10803 quic_data.AddSocketDataToFactory(socket_factory_.get());
10804
Ryan Hamiltonabad59e2019-06-06 04:02:5910805 MockQuicData quic_data2(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010806 quic_data2.AddConnect(SYNCHRONOUS, ERR_ADDRESS_IN_USE);
10807 quic_data2.AddSocketDataToFactory(socket_factory_.get());
10808
10809 QuicStreamRequest request(factory_.get());
10810 EXPECT_EQ(ERR_IO_PENDING,
10811 request.Request(
Nick Harper23290b82019-05-02 00:02:5610812 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:5110813 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010814 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10815 failed_on_default_network_callback_, callback_.callback()));
10816 EXPECT_FALSE(HasLiveSession(host_port_pair_));
10817 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
10818
10819 host_resolver_->ResolveAllPending();
10820 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_ADDRESS_IN_USE));
10821}
10822
10823// With dns race experiment on, dns resolve async, stale used and connection
10824// returns error, dns no match, new connection is established
10825TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceStaleErrorDNSNoMatch) {
Zhongyi Shi967d2f12019-02-08 20:58:5310826 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010827 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10828 Initialize();
10829 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10830 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10831
10832 // Set an address in host resolver.
10833 host_resolver_->set_ondemand_mode(true);
10834 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10835 kNonCachedIPAddress, "");
10836
10837 // Set up a different address in stale resolver cache.
10838 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10839 HostCache::Entry entry(OK,
10840 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10841 HostCache::Entry::SOURCE_DNS);
10842 base::TimeDelta zero;
10843 HostCache* cache = host_resolver_->GetHostCache();
10844 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10845 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810846 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010847
10848 // Add failure for the stale connection.
Ryan Hamiltonabad59e2019-06-06 04:02:5910849 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010850 quic_data.AddConnect(SYNCHRONOUS, ERR_ADDRESS_IN_USE);
10851 quic_data.AddSocketDataToFactory(socket_factory_.get());
10852
Ryan Hamiltonabad59e2019-06-06 04:02:5910853 MockQuicData quic_data2(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010854 quic_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
10855 quic_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
10856 quic_data2.AddSocketDataToFactory(socket_factory_.get());
10857
10858 QuicStreamRequest request(factory_.get());
10859 EXPECT_EQ(ERR_IO_PENDING,
10860 request.Request(
Nick Harper23290b82019-05-02 00:02:5610861 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:5110862 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010863 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10864 failed_on_default_network_callback_, callback_.callback()));
10865
10866 // Check that the stale connection fails.
10867 EXPECT_FALSE(HasLiveSession(host_port_pair_));
10868 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
10869
10870 // Finish host resolution and check the job finishes ok.
10871 host_resolver_->ResolveAllPending();
10872 EXPECT_THAT(callback_.WaitForResult(), IsOk());
10873
10874 std::unique_ptr<HttpStream> stream = CreateStream(&request);
10875 EXPECT_TRUE(stream.get());
10876
10877 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
10878
Victor Vasilievbee79ea2019-05-15 01:25:4810879 EXPECT_EQ(session->peer_address().host().ToString(), kNonCachedIPAddress);
Renjiea0cb4a2c2018-09-26 23:37:3010880
10881 EXPECT_TRUE(quic_data2.AllReadDataConsumed());
10882 EXPECT_TRUE(quic_data2.AllWriteDataConsumed());
10883}
10884
10885// With dns race experiment on, dns resolve async, stale used and connection
10886// returns error, dns no match, new connection error
10887TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceStaleErrorDNSNoMatchError) {
Zhongyi Shi967d2f12019-02-08 20:58:5310888 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010889 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10890 Initialize();
10891 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10892 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10893
10894 // Set an address in host resolver asynchronously.
10895 host_resolver_->set_ondemand_mode(true);
10896 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
10897 kNonCachedIPAddress, "");
10898
10899 // Set up a different address in the stale cache.
10900 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10901 HostCache::Entry entry(OK,
10902 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10903 HostCache::Entry::SOURCE_DNS);
10904 base::TimeDelta zero;
10905 HostCache* cache = host_resolver_->GetHostCache();
10906 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10907 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810908 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010909
10910 // Add failure for stale connection.
Ryan Hamiltonabad59e2019-06-06 04:02:5910911 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010912 quic_data.AddConnect(SYNCHRONOUS, ERR_ADDRESS_IN_USE);
10913 quic_data.AddSocketDataToFactory(socket_factory_.get());
10914
10915 // Add failure for resolved dns connection.
Ryan Hamiltonabad59e2019-06-06 04:02:5910916 MockQuicData quic_data2(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010917 quic_data2.AddConnect(SYNCHRONOUS, ERR_ADDRESS_IN_USE);
10918 quic_data2.AddSocketDataToFactory(socket_factory_.get());
10919
10920 QuicStreamRequest request(factory_.get());
10921 EXPECT_EQ(ERR_IO_PENDING,
10922 request.Request(
Nick Harper23290b82019-05-02 00:02:5610923 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:5110924 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010925 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10926 failed_on_default_network_callback_, callback_.callback()));
10927
10928 // Check the stale connection fails.
10929 EXPECT_FALSE(HasLiveSession(host_port_pair_));
10930 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
10931
10932 // Check the resolved dns connection fails.
10933 host_resolver_->ResolveAllPending();
10934 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_ADDRESS_IN_USE));
10935}
10936
10937// With dns race experiment on, dns resolve async and stale connect async, dns
10938// resolve returns error and then preconnect finishes
10939TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceResolveAsyncErrorStaleAsync) {
Zhongyi Shi967d2f12019-02-08 20:58:5310940 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010941 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10942 Initialize();
10943 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10944 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10945
10946 // Add asynchronous failure in host resolver.
10947 host_resolver_->set_ondemand_mode(true);
10948 host_resolver_->rules()->AddSimulatedFailure(host_port_pair_.host());
10949 factory_->set_require_confirmation(true);
10950 crypto_client_stream_factory_.set_handshake_mode(
10951 MockCryptoClientStream::ZERO_RTT);
10952
10953 // Set up an address in stale resolver cache.
10954 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
10955 HostCache::Entry entry(OK,
10956 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
10957 HostCache::Entry::SOURCE_DNS);
10958 base::TimeDelta zero;
10959 HostCache* cache = host_resolver_->GetHostCache();
10960 cache->Set(key, entry, base::TimeTicks::Now(), zero);
10961 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2810962 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3010963
10964 // Socket data for stale connection which is supposed to disconnect.
Ryan Hamiltonabad59e2019-06-06 04:02:5910965 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3010966 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Michael Warres167db3e2019-03-01 21:38:0310967 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Renjiea0cb4a2c2018-09-26 23:37:3010968 quic_data.AddWrite(
Renjief5fcb172019-02-05 01:59:3310969 SYNCHRONOUS,
10970 client_maker_.MakeConnectionClosePacket(
10971 1, true, quic::QUIC_STALE_CONNECTION_CANCELLED, "net error"));
Renjiea0cb4a2c2018-09-26 23:37:3010972 quic_data.AddSocketDataToFactory(socket_factory_.get());
10973
10974 QuicStreamRequest request(factory_.get());
10975 EXPECT_EQ(ERR_IO_PENDING,
10976 request.Request(
Nick Harper23290b82019-05-02 00:02:5610977 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:5110978 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3010979 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
10980 failed_on_default_network_callback_, callback_.callback()));
10981
10982 // host resolution returned but stale connection hasn't finished yet.
10983 host_resolver_->ResolveAllPending();
10984 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_NAME_NOT_RESOLVED));
10985
10986 EXPECT_TRUE(quic_data.AllReadDataConsumed());
10987 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
10988}
10989
10990// With dns race experiment on, dns resolve async and stale connect async, dns
Renjiea0cb4a2c2018-09-26 23:37:3010991// resolve returns error and then preconnect fails.
10992TEST_P(QuicStreamFactoryTest,
10993 ResultAfterDNSRaceResolveAsyncErrorStaleAsyncError) {
Zhongyi Shi967d2f12019-02-08 20:58:5310994 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3010995 host_resolver_ = std::make_unique<MockCachingHostResolver>();
10996 Initialize();
10997 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
10998 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
10999
11000 // Add asynchronous failure to host resolver.
11001 host_resolver_->set_ondemand_mode(true);
11002 factory_->set_require_confirmation(true);
11003 crypto_client_stream_factory_.set_handshake_mode(
11004 MockCryptoClientStream::ZERO_RTT);
11005 host_resolver_->rules()->AddSimulatedFailure(host_port_pair_.host());
11006
11007 // Set up an address in stale resolver cache.
11008 HostCache::Key key(host_port_pair_.host(), ADDRESS_FAMILY_UNSPECIFIED, 0);
11009 HostCache::Entry entry(OK,
11010 AddressList::CreateFromIPAddress(kCachedIPAddress, 0),
11011 HostCache::Entry::SOURCE_DNS);
11012 base::TimeDelta zero;
11013 HostCache* cache = host_resolver_->GetHostCache();
11014 cache->Set(key, entry, base::TimeTicks::Now(), zero);
11015 // Expire the cache
Eric Orth37b18192019-04-22 19:09:2811016 cache->Invalidate();
Renjiea0cb4a2c2018-09-26 23:37:3011017
Ryan Hamiltonabad59e2019-06-06 04:02:5911018 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3011019 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Michael Warres167db3e2019-03-01 21:38:0311020 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_ZERO_RTT);
Renjiea0cb4a2c2018-09-26 23:37:3011021 quic_data.AddWrite(
Renjief5fcb172019-02-05 01:59:3311022 SYNCHRONOUS,
11023 client_maker_.MakeConnectionClosePacket(
11024 1, true, quic::QUIC_STALE_CONNECTION_CANCELLED, "net error"));
Renjiea0cb4a2c2018-09-26 23:37:3011025 quic_data.AddSocketDataToFactory(socket_factory_.get());
11026
11027 QuicStreamRequest request(factory_.get());
11028 EXPECT_EQ(ERR_IO_PENDING,
11029 request.Request(
Nick Harper23290b82019-05-02 00:02:5611030 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:5111031 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3011032 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
11033 failed_on_default_network_callback_, callback_.callback()));
11034
11035 // Host Resolution returns failure but stale connection hasn't finished.
11036 host_resolver_->ResolveAllPending();
11037
11038 // Check that the final error is on resolution failure.
11039 EXPECT_THAT(callback_.WaitForResult(), IsError(ERR_NAME_NOT_RESOLVED));
11040
11041 EXPECT_TRUE(quic_data.AllReadDataConsumed());
11042}
11043
11044// With dns race experiment on, test that host resolution callback behaves
11045// normal as experiment is not on
11046TEST_P(QuicStreamFactoryTest, ResultAfterDNSRaceHostResolveAsync) {
Zhongyi Shi967d2f12019-02-08 20:58:5311047 test_params_.quic_race_stale_dns_on_connection = true;
Renjiea0cb4a2c2018-09-26 23:37:3011048 host_resolver_ = std::make_unique<MockCachingHostResolver>();
11049 Initialize();
11050 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
11051 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
11052
11053 host_resolver_->set_ondemand_mode(true);
11054 host_resolver_->rules()->AddIPLiteralRule(host_port_pair_.host(),
11055 kNonCachedIPAddress, "");
11056
Ryan Hamiltonabad59e2019-06-06 04:02:5911057 MockQuicData quic_data(version_);
Renjiea0cb4a2c2018-09-26 23:37:3011058 quic_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
11059 quic_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
11060 quic_data.AddSocketDataToFactory(socket_factory_.get());
11061
11062 QuicStreamRequest request(factory_.get());
11063 EXPECT_EQ(ERR_IO_PENDING,
11064 request.Request(
Nick Harper23290b82019-05-02 00:02:5611065 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:5111066 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Renjiea0cb4a2c2018-09-26 23:37:3011067 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
11068 failed_on_default_network_callback_, callback_.callback()));
11069
11070 // Check that expect_on_host_resolution_ is properlly set.
11071 TestCompletionCallback host_resolution_callback;
11072 EXPECT_TRUE(
11073 request.WaitForHostResolution(host_resolution_callback.callback()));
11074 base::RunLoop().RunUntilIdle();
11075 EXPECT_FALSE(host_resolution_callback.have_result());
11076
11077 host_resolver_->ResolveAllPending();
11078 EXPECT_THAT(host_resolution_callback.WaitForResult(), IsOk());
11079
11080 // Check that expect_on_host_resolution_ is flipped back.
11081 EXPECT_FALSE(
11082 request.WaitForHostResolution(host_resolution_callback.callback()));
11083
11084 EXPECT_TRUE(quic_data.AllReadDataConsumed());
11085 EXPECT_TRUE(quic_data.AllWriteDataConsumed());
11086}
11087
Renjiea0522f062019-04-29 18:52:2111088TEST_P(QuicStreamFactoryTest, ConfigInitialRttForHandshake) {
11089 int kInitialRtt = 400;
11090 test_params_.quic_initial_rtt_for_handshake_milliseconds = kInitialRtt;
11091 crypto_client_stream_factory_.set_handshake_mode(
11092 MockCryptoClientStream::COLD_START_WITH_CHLO_SENT);
11093 Initialize();
11094 factory_->set_require_confirmation(true);
11095 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
11096 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
11097
11098 // Using a testing task runner so that we can control time.
11099 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
11100
11101 QuicStreamFactoryPeer::SetTaskRunner(factory_.get(), task_runner.get());
11102 QuicStreamFactoryPeer::SetAlarmFactory(
11103 factory_.get(),
11104 std::make_unique<QuicChromiumAlarmFactory>(task_runner.get(), &clock_));
11105
Ryan Hamiltonabad59e2019-06-06 04:02:5911106 MockQuicData socket_data(version_);
Renjiea0522f062019-04-29 18:52:2111107 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
11108 socket_data.AddWrite(ASYNC, client_maker_.MakeDummyCHLOPacket(1));
11109 socket_data.AddWrite(ASYNC, client_maker_.MakeDummyCHLOPacket(2));
11110 client_maker_.SetEncryptionLevel(quic::ENCRYPTION_FORWARD_SECURE);
11111 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket(3, 0));
11112 socket_data.AddSocketDataToFactory(socket_factory_.get());
11113
11114 QuicStreamRequest request(factory_.get());
11115 EXPECT_EQ(ERR_IO_PENDING,
11116 request.Request(
Nick Harper23290b82019-05-02 00:02:5611117 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:5111118 DEFAULT_PRIORITY, SocketTag(), NetworkIsolationKey(),
Renjiea0522f062019-04-29 18:52:2111119 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
11120 failed_on_default_network_callback_, callback_.callback()));
11121 base::RunLoop().RunUntilIdle();
11122
11123 EXPECT_FALSE(HasActiveSession(host_port_pair_));
11124 EXPECT_TRUE(HasActiveJob(host_port_pair_, privacy_mode_));
11125
11126 // The pending task is scheduled for handshake timeout retransmission,
11127 // which is 2 * 400ms for v99 and 1.5 * 400ms for others.
Nick Harper23290b82019-05-02 00:02:5611128 int handshake_timeout = version_.transport_version == quic::QUIC_VERSION_99
11129 ? 2 * kInitialRtt
11130 : 1.5 * kInitialRtt;
Renjiea0522f062019-04-29 18:52:2111131 EXPECT_EQ(base::TimeDelta::FromMilliseconds(handshake_timeout),
11132 task_runner->NextPendingTaskDelay());
11133
11134 // The alarm factory dependes on |clock_|, so clock is advanced to trigger
11135 // retransmission alarm.
11136 clock_.AdvanceTime(
11137 quic::QuicTime::Delta::FromMilliseconds(handshake_timeout));
11138 task_runner->FastForwardBy(
11139 base::TimeDelta::FromMilliseconds(handshake_timeout));
11140
11141 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
11142 quic::QuicSession::HANDSHAKE_CONFIRMED);
11143
11144 EXPECT_THAT(callback_.WaitForResult(), IsOk());
11145
11146 QuicChromiumClientSession* session = GetActiveSession(host_port_pair_);
11147 EXPECT_EQ(400000u, session->config()->GetInitialRoundTripTimeUsToSend());
11148 EXPECT_TRUE(socket_data.AllReadDataConsumed());
11149 EXPECT_TRUE(socket_data.AllWriteDataConsumed());
11150}
11151
Paul Jensen8e3c5d32018-02-19 17:06:3311152// Test that QuicStreamRequests with similar and different tags results in
11153// reused and unique QUIC streams using appropriately tagged sockets.
11154TEST_P(QuicStreamFactoryTest, Tag) {
11155 MockTaggingClientSocketFactory* socket_factory =
11156 new MockTaggingClientSocketFactory();
11157 socket_factory_.reset(socket_factory);
11158 Initialize();
11159 ProofVerifyDetailsChromium verify_details = DefaultProofVerifyDetails();
11160 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
11161
11162 // Prepare to establish two QUIC sessions.
Ryan Hamiltonabad59e2019-06-06 04:02:5911163 MockQuicData socket_data(version_);
Paul Jensen8e3c5d32018-02-19 17:06:3311164 socket_data.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:4311165 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Paul Jensen8e3c5d32018-02-19 17:06:3311166 socket_data.AddSocketDataToFactory(socket_factory_.get());
Ryan Hamiltonabad59e2019-06-06 04:02:5911167 MockQuicData socket_data2(version_);
Paul Jensen8e3c5d32018-02-19 17:06:3311168 socket_data2.AddRead(SYNCHRONOUS, ERR_IO_PENDING);
Zhongyi Shi32f2fd02018-04-16 18:23:4311169 socket_data2.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
Paul Jensen8e3c5d32018-02-19 17:06:3311170 socket_data2.AddSocketDataToFactory(socket_factory_.get());
11171
11172#if defined(OS_ANDROID)
11173 SocketTag tag1(SocketTag::UNSET_UID, 0x12345678);
11174 SocketTag tag2(getuid(), 0x87654321);
11175#else
11176 // On non-Android platforms we can only use the default constructor.
11177 SocketTag tag1, tag2;
11178#endif
11179
11180 // Request a stream with |tag1|.
11181 QuicStreamRequest request1(factory_.get());
Zhongyi Shia6b68d112018-09-24 07:49:0311182 int rv = request1.Request(
Nick Harper23290b82019-05-02 00:02:5611183 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:5111184 DEFAULT_PRIORITY, tag1, NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:0311185 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
11186 failed_on_default_network_callback_, callback_.callback());
Paul Jensen8e3c5d32018-02-19 17:06:3311187 EXPECT_THAT(callback_.GetResult(rv), IsOk());
11188 EXPECT_EQ(socket_factory->GetLastProducedUDPSocket()->tag(), tag1);
11189 EXPECT_TRUE(socket_factory->GetLastProducedUDPSocket()
11190 ->tagged_before_data_transferred());
11191 std::unique_ptr<QuicChromiumClientSession::Handle> stream1 =
11192 request1.ReleaseSessionHandle();
11193 EXPECT_TRUE(stream1);
11194 EXPECT_TRUE(stream1->IsConnected());
11195
11196 // Request a stream with |tag1| and verify underlying session is reused.
11197 QuicStreamRequest request2(factory_.get());
Zhongyi Shia6b68d112018-09-24 07:49:0311198 rv = request2.Request(
Nick Harper23290b82019-05-02 00:02:5611199 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:5111200 DEFAULT_PRIORITY, tag1, NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:0311201 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
11202 failed_on_default_network_callback_, callback_.callback());
Paul Jensen8e3c5d32018-02-19 17:06:3311203 EXPECT_THAT(callback_.GetResult(rv), IsOk());
11204 std::unique_ptr<QuicChromiumClientSession::Handle> stream2 =
11205 request2.ReleaseSessionHandle();
11206 EXPECT_TRUE(stream2);
11207 EXPECT_TRUE(stream2->IsConnected());
11208 EXPECT_TRUE(stream2->SharesSameSession(*stream1));
11209
11210 // Request a stream with |tag2| and verify a new session is created.
11211 QuicStreamRequest request3(factory_.get());
Zhongyi Shia6b68d112018-09-24 07:49:0311212 rv = request3.Request(
Nick Harper23290b82019-05-02 00:02:5611213 host_port_pair_, version_.transport_version, privacy_mode_,
Matt Menke26e41542019-06-05 01:09:5111214 DEFAULT_PRIORITY, tag2, NetworkIsolationKey(),
Zhongyi Shia6b68d112018-09-24 07:49:0311215 /*cert_verify_flags=*/0, url_, net_log_, &net_error_details_,
11216 failed_on_default_network_callback_, callback_.callback());
Paul Jensen8e3c5d32018-02-19 17:06:3311217 EXPECT_THAT(callback_.GetResult(rv), IsOk());
11218 EXPECT_EQ(socket_factory->GetLastProducedUDPSocket()->tag(), tag2);
11219 EXPECT_TRUE(socket_factory->GetLastProducedUDPSocket()
11220 ->tagged_before_data_transferred());
11221 std::unique_ptr<QuicChromiumClientSession::Handle> stream3 =
11222 request3.ReleaseSessionHandle();
11223 EXPECT_TRUE(stream3);
11224 EXPECT_TRUE(stream3->IsConnected());
11225#if defined(OS_ANDROID)
11226 EXPECT_FALSE(stream3->SharesSameSession(*stream1));
11227#else
11228 // Same tag should reuse session.
11229 EXPECT_TRUE(stream3->SharesSameSession(*stream1));
11230#endif
11231}
11232
[email protected]e13201d82012-12-12 05:00:3211233} // namespace test
[email protected]e13201d82012-12-12 05:00:3211234} // namespace net